@@ -184,7 +184,7 @@ private static function get_mock_response( $method, $path, $body ) {
184184 ),
185185 ),
186186 );
187- } elseif ( preg_match ( '#/v0/meta/bases/(app\d+)/tables# ' , $ path , $ matches ) ) {
187+ } elseif ( preg_match ( '#^ /v0/meta/bases/(app\d+)/tables$ # ' , $ path , $ matches ) ) {
188188 // Tables for a specific base.
189189 return array (
190190 'tables ' => array (
@@ -213,15 +213,36 @@ private static function get_mock_response( $method, $path, $body ) {
213213 'type ' => 'number ' ,
214214 ),
215215 array (
216- 'id ' => 'fld888888888 ' ,
217- 'name ' => 'Tags ' ,
218- 'type ' => 'multipleSelects ' ,
216+ 'id ' => 'fld888888888 ' ,
217+ 'name ' => 'Tags ' ,
218+ 'type ' => 'multipleSelects ' ,
219+ 'options ' => array (
220+ 'choices ' => array (
221+ array (
222+ 'name ' => 'A ' ,
223+ 'id ' => 't1 ' ,
224+ ),
225+ array (
226+ 'name ' => 'B ' ,
227+ 'id ' => 't2 ' ,
228+ ),
229+ array (
230+ 'name ' => 'C ' ,
231+ 'id ' => 't3 ' ,
232+ ),
233+ ),
234+ ),
219235 ),
220236 array (
221237 'id ' => 'fld999999999 ' ,
222238 'name ' => 'Summary ' ,
223239 'type ' => 'aiText ' ,
224240 ),
241+ array (
242+ 'id ' => 'fld2222222222 ' ,
243+ 'name ' => 'Profile Picture ' ,
244+ 'type ' => 'multipleAttachments ' ,
245+ ),
225246 ),
226247 ),
227248 array (
@@ -239,45 +260,73 @@ private static function get_mock_response( $method, $path, $body ) {
239260 ),
240261 );
241262 }
242- } elseif ( preg_match ( '#/v0/(app\d+)/([^/]+)# ' , $ path , $ matches ) ) {
263+ } elseif ( preg_match ( '#^ /v0/(app\d+)/([^/]+)$ # ' , $ path , $ matches ) ) {
243264 // Table data endpoint.
244265 if ( 'GET ' === $ method ) {
245266 // Mock field schema for GET requests.
246267 return array (
247- 'fields ' => array (
268+ 'records ' => array (
248269 array (
249- 'id ' => 'fld123456789 ' ,
250- 'name ' => 'Name ' ,
251- 'type ' => 'singleLineText ' ,
252- ),
253- array (
254- 'id ' => 'fld987654321 ' ,
255- 'name ' => 'Email ' ,
256- 'type ' => 'email ' ,
257- ),
258- array (
259- 'id ' => 'fld555555555 ' ,
260- 'name ' => 'Active ' ,
261- 'type ' => 'checkbox ' ,
262- ),
263- array (
264- 'id ' => 'fld777777777 ' ,
265- 'name ' => 'Score ' ,
266- 'type ' => 'number ' ,
267- ),
268- array (
269- 'id ' => 'fld888888888 ' ,
270- 'name ' => 'Tags ' ,
271- 'type ' => 'multipleSelects ' ,
270+ 'id ' => 'rec123456789 ' ,
271+ 'createdTime ' => '2023-01-01T00:00:00.000Z ' ,
272+ 'fields ' => array (
273+ array (
274+ 'id ' => 'fld123456789 ' ,
275+ 'name ' => 'Name ' ,
276+ 'type ' => 'singleLineText ' ,
277+ ),
278+ array (
279+ 'id ' => 'fld987654321 ' ,
280+ 'name ' => 'Email ' ,
281+ 'type ' => 'email ' ,
282+ ),
283+ array (
284+ 'id ' => 'fld555555555 ' ,
285+ 'name ' => 'Active ' ,
286+ 'type ' => 'checkbox ' ,
287+ ),
288+ array (
289+ 'id ' => 'fld777777777 ' ,
290+ 'name ' => 'Score ' ,
291+ 'type ' => 'number ' ,
292+ ),
293+ array (
294+ 'id ' => 'fld888888888 ' ,
295+ 'name ' => 'Tags ' ,
296+ 'type ' => 'multipleSelects ' ,
297+ ),
298+ ),
272299 ),
273300 ),
274301 );
275302 } elseif ( 'POST ' === $ method ) {
276303 // Mock successful record creation for POST requests.
277304 return array (
278- 'id ' => 'rec123456789 ' ,
279- 'fields ' => $ body ['records ' ][0 ]['fields ' ],
280- 'createdTime ' => '2023-01-01T00:00:00.000Z ' ,
305+ 'records ' => array (
306+ array (
307+ 'id ' => 'rec123456789 ' ,
308+ 'fields ' => $ body ['records ' ][0 ]['fields ' ],
309+ 'createdTime ' => '2023-01-01T00:00:00.000Z ' ,
310+ ),
311+ ),
312+ );
313+ }
314+ } elseif ( preg_match ( '#^/v0/(app\d+)/([^/]+)/uploadAttachment$# ' , $ path , $ matches ) ) {
315+ if ( $ method === 'POST ' ) {
316+ return array (
317+ 'createdTime ' => '2022-02-01T21:25:05.663Z ' ,
318+ 'fields ' => array (
319+ 'fld00000000000000 ' => array (
320+ array (
321+ 'filename ' => 'sample.txt ' ,
322+ 'id ' => 'att00000000000000 ' ,
323+ 'size ' => 11 ,
324+ 'type ' => 'text/plain ' ,
325+ 'url ' => 'https://v5.airtableusercontent.com/v3/u/29/29/1716940800000/ffhiecnieIwxisnIBDSAln/foDeknw_G5CdkdPW1j-U0yUCX9YSaE1EJft3wvXb85pnTY1sKZdYeFvKpsM-fqOa6Bnu5MQVPA_ApINEUXL_E3SAZn6z01VN9Pn9SluhSy4NoakZGapcvl4tuN3jktO2Dt7Ck_gh4oMdsrcV8J-t_A/53m17XmDDHsNtIqzM1PQVnRKutK6damFgNNS5WCaTbI ' ,
326+ ),
327+ ),
328+ ),
329+ 'id ' => 'rec00000000000000 ' ,
281330 );
282331 }
283332 }
@@ -372,16 +421,49 @@ public function test_post_create_record() {
372421 );
373422
374423 $ payload = array (
375- 'Name ' => 'John Doe ' ,
376- 'Email ' => 'john.doe@example.com ' ,
424+ 'Name ' => 'John Doe ' ,
425+ 'Email ' => 'john.doe@example.com ' ,
426+ 'Score ' => 99 ,
427+ 'Tags ' => array ( 'A ' , 'B ' ),
428+ 'Active ' => true ,
377429 );
378430
379431 $ response = $ bridge ->submit ( $ payload );
380432
381433 $ this ->assertFalse ( is_wp_error ( $ response ) );
382434 $ this ->assertArrayHasKey ( 'data ' , $ response );
383- $ this ->assertEquals ( 'rec123456789 ' , $ response ['data ' ]['id ' ] );
384- $ this ->assertEquals ( 'John Doe ' , $ response ['data ' ]['fields ' ]['Name ' ] );
435+ $ this ->assertEquals ( 'rec123456789 ' , $ response ['data ' ]['records ' ][0 ]['id ' ] );
436+ $ this ->assertEquals ( 'John Doe ' , $ response ['data ' ]['records ' ][0 ]['fields ' ]['Name ' ] );
437+ }
438+
439+ /**
440+ * Test POST request to create a record with uploads.
441+ */
442+ public function test_post_create_record_with_uploads () {
443+ $ bridge = new Airtable_Form_Bridge (
444+ array (
445+ 'name ' => self ::BRIDGE_NAME ,
446+ 'backend ' => self ::BACKEND_NAME ,
447+ 'endpoint ' => '/v0/app123456789/Contacts ' ,
448+ 'method ' => 'POST ' ,
449+ )
450+ );
451+
452+ $ payload = array (
453+ 'Name ' => 'John Doe ' ,
454+ 'Email ' => 'john.doe@example.com ' ,
455+ 'Score ' => 99 ,
456+ 'Tags ' => array ( 'A ' , 'B ' ),
457+ 'Active ' => true ,
458+ 'Profile Picture ' => 'file ' ,
459+ );
460+
461+ $ response = $ bridge ->submit ( $ payload );
462+
463+ $ this ->assertFalse ( is_wp_error ( $ response ) );
464+ $ this ->assertArrayHasKey ( 'data ' , $ response );
465+ $ this ->assertEquals ( 'rec123456789 ' , $ response ['data ' ]['records ' ][0 ]['id ' ] );
466+ $ this ->assertEquals ( 'John Doe ' , $ response ['data ' ]['records ' ][0 ]['fields ' ]['Name ' ] );
385467 }
386468
387469 /**
@@ -401,8 +483,10 @@ public function test_get_table_schema() {
401483
402484 $ this ->assertFalse ( is_wp_error ( $ response ) );
403485 $ this ->assertArrayHasKey ( 'data ' , $ response );
404- $ this ->assertArrayHasKey ( 'fields ' , $ response ['data ' ] );
405- $ this ->assertCount ( 5 , $ response ['data ' ]['fields ' ] );
486+ $ this ->assertArrayHasKey ( 'records ' , $ response ['data ' ] );
487+ $ this ->assertCount ( 1 , $ response ['data ' ]['records ' ] );
488+ $ this ->assertArrayHasKey ( 'fields ' , $ response ['data ' ]['records ' ][0 ] );
489+ $ this ->assertCount ( 5 , $ response ['data ' ]['records ' ][0 ]['fields ' ] );
406490 }
407491
408492 /**
@@ -474,6 +558,7 @@ public function test_addon_get_endpoint_schema_post() {
474558 $ this ->assertContains ( 'Active ' , $ field_names );
475559 $ this ->assertContains ( 'Score ' , $ field_names );
476560 $ this ->assertContains ( 'Tags ' , $ field_names );
561+ $ this ->assertContains ( 'Profile Picture ' , $ field_names );
477562
478563 // Check field types.
479564 $ schema_map = array ();
@@ -486,6 +571,7 @@ public function test_addon_get_endpoint_schema_post() {
486571 $ this ->assertEquals ( 'boolean ' , $ schema_map ['Active ' ] );
487572 $ this ->assertEquals ( 'number ' , $ schema_map ['Score ' ] );
488573 $ this ->assertEquals ( 'array ' , $ schema_map ['Tags ' ] );
574+ $ this ->assertEquals ( 'file ' , $ schema_map ['Profile Picture ' ] );
489575 }
490576
491577 /**
@@ -581,20 +667,6 @@ public function test_authorization_header_transformation() {
581667 * Test field filtering in schema - should exclude certain field types.
582668 */
583669 public function test_field_filtering_in_schema () {
584- // Add a field that should be excluded.
585- $ mock_fields = array (
586- array (
587- 'id ' => 'fld_excluded ' ,
588- 'name ' => 'ExcludedField ' ,
589- 'type ' => 'aiText ' , // This type should be excluded.
590- ),
591- array (
592- 'id ' => 'fld_included ' ,
593- 'name ' => 'IncludedField ' ,
594- 'type ' => 'singleLineText ' , // This type should be included.
595- ),
596- );
597-
598670 $ addon = Addon::addon ( 'airtable ' );
599671 $ schema = $ addon ->get_endpoint_schema (
600672 '/v0/app123456789/Contacts ' ,
@@ -606,6 +678,6 @@ public function test_field_filtering_in_schema() {
606678 $ field_names = array_column ( $ schema , 'name ' );
607679 $ this ->assertContains ( 'Name ' , $ field_names );
608680 $ this ->assertNotContains ( 'Summary ' , $ field_names );
609- $ this ->assertCount ( 5 , $ schema );
681+ $ this ->assertCount ( 6 , $ schema );
610682 }
611683}
0 commit comments