From 21094b96ae8241eb3c11288da39bf1963edc23f0 Mon Sep 17 00:00:00 2001 From: Dan Gebhardt Date: Fri, 16 Jul 2021 13:27:52 -0400 Subject: [PATCH 1/2] JSONAPISource#query should always return an array of results when expressions is an array --- packages/@orbit/jsonapi/src/jsonapi-source.ts | 2 +- .../test/jsonapi-source-queryable-test.ts | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/@orbit/jsonapi/src/jsonapi-source.ts b/packages/@orbit/jsonapi/src/jsonapi-source.ts index 0fcaff4e..f39d2ec7 100644 --- a/packages/@orbit/jsonapi/src/jsonapi-source.ts +++ b/packages/@orbit/jsonapi/src/jsonapi-source.ts @@ -363,7 +363,7 @@ export class JSONAPISource< } return { - data: responses.length > 1 ? data : data[0], + data: Array.isArray(query.expressions) ? data : data[0], details, transforms }; diff --git a/packages/@orbit/jsonapi/test/jsonapi-source-queryable-test.ts b/packages/@orbit/jsonapi/test/jsonapi-source-queryable-test.ts index 995bc20c..525c2cfb 100644 --- a/packages/@orbit/jsonapi/test/jsonapi-source-queryable-test.ts +++ b/packages/@orbit/jsonapi/test/jsonapi-source-queryable-test.ts @@ -2051,5 +2051,38 @@ module('JSONAPISource - queryable', function (hooks) { assert.equal(fetchStub.callCount, 1, 'fetch called once'); }); + + test('#query - will return an array of results for a query that contains an array with a single expression', async function (assert) { + assert.expect(4); + + const data1: Resource = { + type: 'planet', + id: '12345', + attributes: { name: 'Jupiter' } + }; + + const planet1 = resourceSerializer.deserialize({ + type: 'planet', + id: '12345' + }) as InitializedRecord; + + fetchStub + .withArgs('/planets/12345') + .returns(jsonapiResponse(200, { data: data1 })); + + let records = (await source.query((q) => [ + q.findRecord({ type: 'planet', id: planet1.id }) + ])) as InitializedRecord[]; + + assert.ok(Array.isArray(records), 'multiple primary records returned'); + assert.equal(records[0].attributes?.name, 'Jupiter'); + + assert.equal(fetchStub.callCount, 1, 'fetch called once'); + assert.equal( + fetchStub.getCall(0).args[1].method, + undefined, + 'fetch called with no method (equivalent to GET)' + ); + }); }); }); From 89c2ab180117decb31ff8b9d6fb46bc60c0c331b Mon Sep 17 00:00:00 2001 From: Dan Gebhardt Date: Fri, 16 Jul 2021 13:28:22 -0400 Subject: [PATCH 2/2] JSONAPISource#update should always return an array of results when operations is an array --- packages/@orbit/jsonapi/src/jsonapi-source.ts | 2 +- .../test/jsonapi-source-updatable-test.ts | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/@orbit/jsonapi/src/jsonapi-source.ts b/packages/@orbit/jsonapi/src/jsonapi-source.ts index f39d2ec7..9ba72259 100644 --- a/packages/@orbit/jsonapi/src/jsonapi-source.ts +++ b/packages/@orbit/jsonapi/src/jsonapi-source.ts @@ -398,7 +398,7 @@ export class JSONAPISource< } return { - data: responses.length > 1 ? data : data[0], + data: Array.isArray(transform.operations) ? data : data[0], details, transforms: [transform, ...transforms] }; diff --git a/packages/@orbit/jsonapi/test/jsonapi-source-updatable-test.ts b/packages/@orbit/jsonapi/test/jsonapi-source-updatable-test.ts index c1bc0143..1dd3404b 100644 --- a/packages/@orbit/jsonapi/test/jsonapi-source-updatable-test.ts +++ b/packages/@orbit/jsonapi/test/jsonapi-source-updatable-test.ts @@ -1217,5 +1217,48 @@ module('JSONAPISource - updatable', function (hooks) { 'fetch called with expected data' ); }); + + test('#update - will return an array of results for a transform that contains a single operation', async function (assert) { + assert.expect(5); + + const planet1: InitializedRecord = { + type: 'planet', + id: 'p1', + attributes: { name: 'Jupiter' } + }; + + fetchStub.withArgs('/planets').callsFake(() => + jsonapiResponse(201, { + data: planet1 + }) + ); + + let [planet] = (await source.update((t) => [ + t.addRecord(planet1) + ])) as InitializedRecord[]; + + assert.deepEqual(planet, planet1, 'planet matches'); + + assert.equal(fetchStub.callCount, 1, 'fetch called once'); + + const firstFetchCall = fetchStub.getCall(0); + assert.equal( + firstFetchCall.args[1].method, + 'POST', + 'fetch called with expected method' + ); + assert.equal( + firstFetchCall.args[1].headers['Content-Type'], + 'application/vnd.api+json', + 'fetch called with expected content type' + ); + assert.deepEqual( + JSON.parse(firstFetchCall.args[1].body), + { + data: planet1 + }, + 'fetch called with expected data' + ); + }); }); });