From de85ff658fde949c74049c9439c612e4f0c885b6 Mon Sep 17 00:00:00 2001 From: Robert Schaefer Date: Wed, 30 May 2018 23:46:49 +0200 Subject: [PATCH 1/4] Expose #344 --- tests/acceptance/user-view-test.js | 36 ++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/acceptance/user-view-test.js b/tests/acceptance/user-view-test.js index 8fad051d..4614264b 100644 --- a/tests/acceptance/user-view-test.js +++ b/tests/acceptance/user-view-test.js @@ -88,6 +88,42 @@ module('Acceptance | User View', function(hooks) { assert.dom('li.project').exists('One project shown'); }); + test("Add a project to a user with mockCreate and a custom matching function", async function(assert) { + // mockFindRecord will build a default user for the json payload + let mock = mockFindRecord('user'); + + await visit('/user/' + mock.get('id')); + + let newProjectTitle = "Gonzo Project"; + + // should be no projects + assert.dom('li.project').doesNotExist('No projects shown'); + + await fillIn('input.project-title', newProjectTitle); + + // You can also implement your own custom matching function + mockCreate('project').match((requestBody) => { + return requestBody.data.attributes.title === newProjectTitle; + }); + + /** + Let's say that clicking this a button, triggers action in the + view to create project record and looks something like this: + + actions: { + addProject: function (user) { + let title = this.$('input.project-title').val(); + let store = this.get('store'); + store.createRecord('project', {title, user}).save(); + } + } + + */ + await click('button.add-project'); + + assert.dom('li.project').exists('One project shown'); + }); + test("Request failure shows a error message", async function(assert) { let mock = mockFindRecord('user').fails({status: 404}); await visit('/user/' + mock.get('id')); From d52f6f89f35bb51f9708a7fe40da8248603b69f8 Mon Sep 17 00:00:00 2001 From: Robert Schaefer Date: Thu, 31 May 2018 00:58:13 +0200 Subject: [PATCH 2/4] Expose #344 in a unit test --- tests/unit/shared-adapter-behaviour.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/unit/shared-adapter-behaviour.js b/tests/unit/shared-adapter-behaviour.js index 859ab5ba..d2dc7f7f 100644 --- a/tests/unit/shared-adapter-behaviour.js +++ b/tests/unit/shared-adapter-behaviour.js @@ -1186,6 +1186,29 @@ SharedBehavior.mockCreateTests = function() { }); }); + test("match can take a function - supplied parameter is the json request body", async function(assert) { + assert.expect(2); + run(async () => { + let mock = mockCreate('profile'); + + mock.match(function(requestBody) { + assert.ok(true, 'matching function is called'); + const description = ( + (requestBody.description) || // DRFSerializer, RESTAdapter, JSONSerializer + (requestBody.profile && requestBody.profile.description) || // RESTSerializer, ActiveModelSerializer + (requestBody.data && requestBody.data.attributes.description) // JSONAPISerializer + ); + return description === 'match me!'; + }); + + let profile = FactoryGuy.store.createRecord('profile'); + profile.set('description', 'match me!'); + await profile.save(); + + assert.equal(mock.timesCalled, 1); + }); + }); + test("match some attributes", async function(assert) { run(async () => { let customDescription = "special description", From 33a74cc353780d0c4b8888114a2833764ba7c5d8 Mon Sep 17 00:00:00 2001 From: Robert Schaefer Date: Wed, 30 May 2018 23:57:19 +0200 Subject: [PATCH 3/4] Provide a fix for #344 and let tests pass --- addon/mocks/attribute-matcher.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/addon/mocks/attribute-matcher.js b/addon/mocks/attribute-matcher.js index 4aa5a37f..1b629a20 100644 --- a/addon/mocks/attribute-matcher.js +++ b/addon/mocks/attribute-matcher.js @@ -47,10 +47,9 @@ const AttributeMatcher = (superclass) => class extends superclass { extraRequestMatches(request) { if (this.matchArgs) { - let requestBody = JSON.parse(request.requestBody), - requestData = requestBody[this.modelName]; + let requestBody = JSON.parse(request.requestBody); if (typeof this.matchArgs === 'function') { - return this.matchArgs(requestData); + return this.matchArgs(requestBody); } else { return this.attributesMatch(requestBody); } @@ -101,4 +100,4 @@ const AttributeMatcher = (superclass) => class extends superclass { } }; -export default AttributeMatcher; \ No newline at end of file +export default AttributeMatcher; From bce1155ed851d5f2e6c09f0c603f0edd61dad946 Mon Sep 17 00:00:00 2001 From: Robert Schaefer Date: Thu, 31 May 2018 00:03:39 +0200 Subject: [PATCH 4/4] Update README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 56ddab0f..6fef5486 100644 --- a/README.md +++ b/README.md @@ -1760,7 +1760,10 @@ Usage: // using match() method to specify a matching function let profile = make('profile'); profile.set('name', "woo"); - let mock = mockUpdate(profile).match(requestData => requestData.name === "moo"); + let mock = mockUpdate(profile).match((requestBody) => { + // this example uses a JSONAPI Adapter + return requestBody.data.attributes.name === "moo" + }); profile.save(); // will not be mocked since the mock you set requires the request's top level attribute "name" to equal "moo" // either set the name to "moo" which will now be mocked correctly