Skip to content

Commit 22b31ac

Browse files
authored
fix!: Keep PageField with previous page data when filtering formFields by pageNumber. (#422)
1 parent b70ef41 commit 22b31ac

File tree

4 files changed

+223
-46
lines changed

4 files changed

+223
-46
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- feat!: Implement `FormField` model and `DataLoader`, and refactor `FormFieldsConnectionResolver` to extend `AbstractConnectionResolver`.
66
- feat!: Refactor `FormsConnectionResolver` and `EntriesConnectionResolver` for compatibility with WPGraphQL v1.26.0 improvements.
77
- feat!: Narrow `FormField.choices` and `FormField.inputs` field types to their implementations.
8+
- fix!: Keep `PageField` with previous page data when filtering `formFields` by `pageNumber`. H/t @SamuelHadsall .
89
- fix: Handle RadioField submission values when using a custom "other" choice. H/t @Gytjarek .
910
- dev: Use `FormFieldsDataLoader` to resolve fields instead of instantiating a new `Model`.
1011
- chore: Add iterable type hints.

src/Data/Connection/FormFieldsConnectionResolver.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,17 @@ static function ( \GF_Field $field ) use ( $query_args, &$has_page_number ) {
215215
// Set the flag to true if the page number is found.
216216
$has_page_number = true;
217217

218+
// PageFields use the next page number.
219+
if ( $field instanceof \GF_Field_Page ) {
220+
return $field->pageNumber === $query_args['pageNumber'] + 1;
221+
}
222+
218223
return $query_args['pageNumber'] === (int) $field->pageNumber;
219224
}
220225
);
221226

222-
// Dont use filtered fileds if the form isnt paged.
223-
if ( $has_page_number || 1 < $query_args['pageNumber'] ) {
227+
// Dont use filtered filds if the form isnt paged.
228+
if ( $has_page_number ) {
224229
$fields = $filtered_fields;
225230
}
226231
}
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
<?php
2+
/**
3+
* Test GraphQL FormFieldConnection Queries.
4+
*
5+
* @package .
6+
*/
7+
8+
use Helper\GFHelpers\GFHelpers;
9+
use Tests\WPGraphQL\GF\TestCase\GFGraphQLTestCase;
10+
use WPGraphQL\GF\Type\Enum\FormFieldTypeEnum;
11+
12+
/**
13+
* Class - FormFieldConnectionPageFilterTest
14+
*/
15+
class FormFieldConnectionPageFilterTest extends GFGraphQLTestCase {
16+
private $form_id;
17+
private $fields;
18+
19+
/**
20+
* run before each test.
21+
*/
22+
public function setUp(): void {
23+
// Before...
24+
parent::setUp();
25+
26+
wp_set_current_user( $this->admin->ID );
27+
28+
$this->fields = $this->generate_form_pages( 3 );
29+
$this->form_id = $this->factory->form->create(
30+
array_merge(
31+
[ 'fields' => $this->fields ],
32+
$this->tester->getFormDefaultArgs()
33+
)
34+
);
35+
36+
$this->clearSchema();
37+
}
38+
39+
/**
40+
* Run after each test.
41+
*/
42+
public function tearDown(): void {
43+
// Your tear down methods here.
44+
$this->factory->form->delete( $this->form_id );
45+
46+
// Then...
47+
parent::tearDown();
48+
}
49+
50+
private function generate_form_pages( int $count = 1 ): array {
51+
$fields = [];
52+
$field_id = 1;
53+
54+
for ( $i = 0; $i < $count; $i++ ) {
55+
// Fields should cycle between text, number, and radio fields.
56+
$property_helper_type = '';
57+
58+
switch ( $i % 3 ) {
59+
case 1:
60+
$property_helper_type = 'NumberField';
61+
break;
62+
case 2:
63+
$property_helper_type = 'RadioField';
64+
break;
65+
case 0:
66+
default:
67+
$property_helper_type = 'TextField';
68+
break;
69+
}
70+
71+
// Add the form field.
72+
$fields[] = $this->factory->field->create(
73+
array_merge(
74+
$this->tester->getPropertyHelper( $property_helper_type )->values,
75+
[
76+
'id' => $field_id++,
77+
'pageNumber' => $i + 1,
78+
]
79+
)
80+
);
81+
82+
// Add a page field if we are not on the last page.
83+
if ( $i < $count ) {
84+
$fields[] = $this->factory->field->create(
85+
array_merge(
86+
$this->tester->getPropertyHelper( 'PageField' )->values,
87+
[
88+
'id' => $field_id++,
89+
'pageNumber' => $i + 2,
90+
]
91+
)
92+
);
93+
}
94+
}
95+
96+
return $fields;
97+
}
98+
99+
public function getQuery(): string {
100+
return '
101+
query FormFields($formId: ID!, $pageNumber: Int!) {
102+
gfForm(id: $formId, idType: DATABASE_ID) {
103+
formFields(
104+
where: {
105+
pageNumber: $pageNumber
106+
}
107+
) {
108+
pageInfo {
109+
hasNextPage
110+
hasPreviousPage
111+
}
112+
nodes {
113+
id
114+
databaseId
115+
type
116+
pageNumber
117+
... on PageField {
118+
nextButton{
119+
text
120+
}
121+
previousButton{
122+
text
123+
}
124+
}
125+
}
126+
}
127+
}
128+
}
129+
';
130+
}
131+
132+
public function testFilterByPageNumber(): void {
133+
$query = $this->getQuery();
134+
135+
$form = GFAPI::get_form( $this->form_id );
136+
$wp_query = $form['fields'];
137+
138+
error_log( print_r( $wp_query, true ) );
139+
140+
/**
141+
* Test with empty offset.
142+
*/
143+
$variables = [
144+
'formId' => $this->form_id,
145+
'pageNumber' => 0,
146+
];
147+
148+
$expected = $wp_query;
149+
$actual = $this->graphql( compact( 'query', 'variables' ) );
150+
151+
$this->assertResponseIsValid( $actual );
152+
$this->assertArrayNotHasKey( 'errors', $actual );
153+
$this->assertCount( 6, $actual['data']['gfForm']['formFields']['nodes'] );
154+
155+
// Set the variables to use in the GraphQL query.
156+
$variables['pageNumber'] = 1;
157+
158+
// Run the GraphQL Query.
159+
$expected = array_slice( $wp_query, 0, 2, false );
160+
$actual = $this->graphql( compact( 'query', 'variables' ) );
161+
162+
$this->assertValidPageFields( $expected, $actual );
163+
164+
/**
165+
* Test the next two results.
166+
*/
167+
168+
// Set the variables to use in the GraphQL query.
169+
$variables['pageNumber'] = 2;
170+
171+
// Run the GraphQL Query.
172+
$expected = array_slice( $wp_query, 2, 2, false );
173+
$actual = $this->graphql( compact( 'query', 'variables' ) );
174+
175+
$this->assertValidPageFields( $expected, $actual );
176+
177+
178+
/**
179+
* Test the last two results.
180+
*/
181+
182+
// Set the variables to use in the GraphQL query.
183+
$variables['pageNumber'] = 3;
184+
185+
// Run the GraphQL Query.
186+
$expected = array_slice( $wp_query, 4, 2, false );
187+
$actual = $this->graphql( compact( 'query', 'variables' ) );
188+
189+
$this->assertValidPageFields( $expected, $actual );
190+
}
191+
192+
/**
193+
* Common assertions for testing pagination.
194+
*
195+
* @param array $expected Expected results from GFAPI.
196+
* @param array $actual Actual results from GraphQL.
197+
*/
198+
private function assertValidPageFields( array $expected, array $actual ): void {
199+
$this->assertResponseIsValid( $actual );
200+
$this->assertArrayNotHasKey( 'errors', $actual );
201+
202+
$this->assertArrayHasKey( 'data', $actual );
203+
$this->assertCount( 2, $actual['data']['gfForm']['formFields']['nodes'] );
204+
205+
206+
$this->assertEquals( $expected[0]['id'], $actual['data']['gfForm']['formFields']['nodes'][0]['databaseId'] );
207+
$this->assertEquals( $expected[0]['pageNumber'], $actual['data']['gfForm']['formFields']['nodes'][0]['pageNumber'] );
208+
$this->assertEquals( $expected[1]['id'], $actual['data']['gfForm']['formFields']['nodes'][1]['databaseId'] );
209+
$this->assertEquals( $expected[1]['pageNumber'], $actual['data']['gfForm']['formFields']['nodes'][1]['pageNumber'] );
210+
$this->assertEquals( GFHelpers::get_enum_for_value( FormFieldTypeEnum::$type, $expected[1]['type'] ), $actual['data']['gfForm']['formFields']['nodes'][1]['type'] );
211+
$this->assertEquals( $expected[1]['nextButton']['text'], $actual['data']['gfForm']['formFields']['nodes'][1]['nextButton']['text'] );
212+
$this->assertEquals(
213+
$expected[1]['previousButton']['text'], $actual['data']['gfForm']['formFields']['nodes'][1]['previousButton']['text'] );
214+
}
215+
}

tests/wpunit/FormFieldConnectionQueriesTest.php

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -79,50 +79,6 @@ private function generate_fields( int $count = 1 ): array {
7979
return $fields;
8080
}
8181

82-
private function create_fields_for_paged_form( int $pages = 1 ): array {
83-
$fields = [];
84-
$field_count = 0;
85-
for ( $i = 0; $i < $pages; $i++ ) {
86-
$fields[] = $this->factory->field->create(
87-
array_merge(
88-
$this->tester->getPropertyHelper( 'TextField' )->values,
89-
[
90-
'id' => ++$field_count,
91-
]
92-
)
93-
);
94-
$fields[] = $this->factory->field->create(
95-
array_merge(
96-
$this->tester->getPropertyHelper( 'NumberField' )->values,
97-
[
98-
'id' => ++$field_count,
99-
]
100-
)
101-
);
102-
$fields[] = $this->factory->field->create(
103-
array_merge(
104-
$this->tester->getPropertyHelper( 'RadioField' )->values,
105-
[
106-
'id' => ++$field_count,
107-
]
108-
)
109-
);
110-
111-
// Add a page field if we are not on the last page.
112-
if ( $i < $pages - 1 ) {
113-
$fields[] = $this->factory->field->create(
114-
array_merge(
115-
$this->tester->getPropertyHelper( 'PageField' )->values,
116-
[
117-
'id' => ++$field_count,
118-
]
119-
)
120-
);
121-
}
122-
}
123-
return $fields;
124-
}
125-
12682
public function getQuery(): string {
12783
return '
12884
query FormFields($formId: ID!, $first: Int, $last: Int, $after: String, $before: String, $where: GfFormToFormFieldConnectionWhereArgs) {

0 commit comments

Comments
 (0)