Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: Keep PageField with previous page data when filtering formFields by pageNumber. #422

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading