Skip to content

Commit

Permalink
fix!: Keep PageField with previous page data when filtering `formFi…
Browse files Browse the repository at this point in the history
…elds` by `pageNumber`. (#422)
  • Loading branch information
justlevine authored Jun 8, 2024
1 parent b70ef41 commit 22b31ac
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 46 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- feat!: Implement `FormField` model and `DataLoader`, and refactor `FormFieldsConnectionResolver` to extend `AbstractConnectionResolver`.
- feat!: Refactor `FormsConnectionResolver` and `EntriesConnectionResolver` for compatibility with WPGraphQL v1.26.0 improvements.
- feat!: Narrow `FormField.choices` and `FormField.inputs` field types to their implementations.
- fix!: Keep `PageField` with previous page data when filtering `formFields` by `pageNumber`. H/t @SamuelHadsall .
- fix: Handle RadioField submission values when using a custom "other" choice. H/t @Gytjarek .
- dev: Use `FormFieldsDataLoader` to resolve fields instead of instantiating a new `Model`.
- chore: Add iterable type hints.
Expand Down
9 changes: 7 additions & 2 deletions src/Data/Connection/FormFieldsConnectionResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,12 +215,17 @@ static function ( \GF_Field $field ) use ( $query_args, &$has_page_number ) {
// Set the flag to true if the page number is found.
$has_page_number = true;

// PageFields use the next page number.
if ( $field instanceof \GF_Field_Page ) {
return $field->pageNumber === $query_args['pageNumber'] + 1;
}

return $query_args['pageNumber'] === (int) $field->pageNumber;
}
);

// Dont use filtered fileds if the form isnt paged.
if ( $has_page_number || 1 < $query_args['pageNumber'] ) {
// Dont use filtered filds if the form isnt paged.
if ( $has_page_number ) {
$fields = $filtered_fields;
}
}
Expand Down
215 changes: 215 additions & 0 deletions tests/wpunit/FormFieldConnectionPageFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
<?php
/**
* Test GraphQL FormFieldConnection Queries.
*
* @package .
*/

use Helper\GFHelpers\GFHelpers;
use Tests\WPGraphQL\GF\TestCase\GFGraphQLTestCase;
use WPGraphQL\GF\Type\Enum\FormFieldTypeEnum;

/**
* Class - FormFieldConnectionPageFilterTest
*/
class FormFieldConnectionPageFilterTest extends GFGraphQLTestCase {
private $form_id;
private $fields;

/**
* run before each test.
*/
public function setUp(): void {
// Before...
parent::setUp();

wp_set_current_user( $this->admin->ID );

$this->fields = $this->generate_form_pages( 3 );
$this->form_id = $this->factory->form->create(
array_merge(
[ 'fields' => $this->fields ],
$this->tester->getFormDefaultArgs()
)
);

$this->clearSchema();
}

/**
* Run after each test.
*/
public function tearDown(): void {
// Your tear down methods here.
$this->factory->form->delete( $this->form_id );

// Then...
parent::tearDown();
}

private function generate_form_pages( int $count = 1 ): array {
$fields = [];
$field_id = 1;

for ( $i = 0; $i < $count; $i++ ) {
// Fields should cycle between text, number, and radio fields.
$property_helper_type = '';

switch ( $i % 3 ) {
case 1:
$property_helper_type = 'NumberField';
break;
case 2:
$property_helper_type = 'RadioField';
break;
case 0:
default:
$property_helper_type = 'TextField';
break;
}

// Add the form field.
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( $property_helper_type )->values,
[
'id' => $field_id++,
'pageNumber' => $i + 1,
]
)
);

// Add a page field if we are not on the last page.
if ( $i < $count ) {
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( 'PageField' )->values,
[
'id' => $field_id++,
'pageNumber' => $i + 2,
]
)
);
}
}

return $fields;
}

public function getQuery(): string {
return '
query FormFields($formId: ID!, $pageNumber: Int!) {
gfForm(id: $formId, idType: DATABASE_ID) {
formFields(
where: {
pageNumber: $pageNumber
}
) {
pageInfo {
hasNextPage
hasPreviousPage
}
nodes {
id
databaseId
type
pageNumber
... on PageField {
nextButton{
text
}
previousButton{
text
}
}
}
}
}
}
';
}

public function testFilterByPageNumber(): void {
$query = $this->getQuery();

$form = GFAPI::get_form( $this->form_id );
$wp_query = $form['fields'];

error_log( print_r( $wp_query, true ) );

/**
* Test with empty offset.
*/
$variables = [
'formId' => $this->form_id,
'pageNumber' => 0,
];

$expected = $wp_query;
$actual = $this->graphql( compact( 'query', 'variables' ) );

$this->assertResponseIsValid( $actual );
$this->assertArrayNotHasKey( 'errors', $actual );
$this->assertCount( 6, $actual['data']['gfForm']['formFields']['nodes'] );

// Set the variables to use in the GraphQL query.
$variables['pageNumber'] = 1;

// Run the GraphQL Query.
$expected = array_slice( $wp_query, 0, 2, false );
$actual = $this->graphql( compact( 'query', 'variables' ) );

$this->assertValidPageFields( $expected, $actual );

/**
* Test the next two results.
*/

// Set the variables to use in the GraphQL query.
$variables['pageNumber'] = 2;

// Run the GraphQL Query.
$expected = array_slice( $wp_query, 2, 2, false );
$actual = $this->graphql( compact( 'query', 'variables' ) );

$this->assertValidPageFields( $expected, $actual );


/**
* Test the last two results.
*/

// Set the variables to use in the GraphQL query.
$variables['pageNumber'] = 3;

// Run the GraphQL Query.
$expected = array_slice( $wp_query, 4, 2, false );
$actual = $this->graphql( compact( 'query', 'variables' ) );

$this->assertValidPageFields( $expected, $actual );
}

/**
* Common assertions for testing pagination.
*
* @param array $expected Expected results from GFAPI.
* @param array $actual Actual results from GraphQL.
*/
private function assertValidPageFields( array $expected, array $actual ): void {
$this->assertResponseIsValid( $actual );
$this->assertArrayNotHasKey( 'errors', $actual );

$this->assertArrayHasKey( 'data', $actual );
$this->assertCount( 2, $actual['data']['gfForm']['formFields']['nodes'] );


$this->assertEquals( $expected[0]['id'], $actual['data']['gfForm']['formFields']['nodes'][0]['databaseId'] );
$this->assertEquals( $expected[0]['pageNumber'], $actual['data']['gfForm']['formFields']['nodes'][0]['pageNumber'] );
$this->assertEquals( $expected[1]['id'], $actual['data']['gfForm']['formFields']['nodes'][1]['databaseId'] );
$this->assertEquals( $expected[1]['pageNumber'], $actual['data']['gfForm']['formFields']['nodes'][1]['pageNumber'] );
$this->assertEquals( GFHelpers::get_enum_for_value( FormFieldTypeEnum::$type, $expected[1]['type'] ), $actual['data']['gfForm']['formFields']['nodes'][1]['type'] );
$this->assertEquals( $expected[1]['nextButton']['text'], $actual['data']['gfForm']['formFields']['nodes'][1]['nextButton']['text'] );
$this->assertEquals(
$expected[1]['previousButton']['text'], $actual['data']['gfForm']['formFields']['nodes'][1]['previousButton']['text'] );
}
}
44 changes: 0 additions & 44 deletions tests/wpunit/FormFieldConnectionQueriesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,50 +79,6 @@ private function generate_fields( int $count = 1 ): array {
return $fields;
}

private function create_fields_for_paged_form( int $pages = 1 ): array {
$fields = [];
$field_count = 0;
for ( $i = 0; $i < $pages; $i++ ) {
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( 'TextField' )->values,
[
'id' => ++$field_count,
]
)
);
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( 'NumberField' )->values,
[
'id' => ++$field_count,
]
)
);
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( 'RadioField' )->values,
[
'id' => ++$field_count,
]
)
);

// Add a page field if we are not on the last page.
if ( $i < $pages - 1 ) {
$fields[] = $this->factory->field->create(
array_merge(
$this->tester->getPropertyHelper( 'PageField' )->values,
[
'id' => ++$field_count,
]
)
);
}
}
return $fields;
}

public function getQuery(): string {
return '
query FormFields($formId: ID!, $first: Int, $last: Int, $after: String, $before: String, $where: GfFormToFormFieldConnectionWhereArgs) {
Expand Down

0 comments on commit 22b31ac

Please sign in to comment.