-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2dab199
commit df4f143
Showing
14 changed files
with
574 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { assert } from '@ember/debug'; | ||
|
||
export function withBulkActions(StoreClass) { | ||
return class StoreWithBulkActions extends StoreClass { | ||
async bulkCreate(records) { | ||
assert( | ||
'All records must be new', | ||
records.every(record => record.isNew) | ||
); | ||
|
||
const serializedRecords = records.map(record => record.serialize()); | ||
|
||
assert( | ||
'All records must be the same type', | ||
serializedRecords.every(record => record.data.type === serializedRecords[0].data.type) | ||
); | ||
|
||
const { modelName } = records[0]._internalModel.createSnapshot(); | ||
const adapter = this.adapterFor(modelName); | ||
|
||
const url = adapter.urlForCreateRecord(modelName); | ||
const payload = { | ||
data: serializedRecords.map(record => record.data) | ||
}; | ||
|
||
records.forEach(record => { | ||
record._internalModel.adapterWillCommit(); | ||
}); | ||
|
||
const response = await adapter.ajax(url, 'POST', { data: payload }); | ||
const responseData = response.data; | ||
|
||
records.forEach((record, index) => { | ||
const { data } = this.normalize(modelName, responseData[index]); | ||
|
||
this.didSaveRecord(record._internalModel, { data }, 'createRecord'); | ||
}); | ||
|
||
return records; | ||
} | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import td from 'testdouble'; | ||
import QUnit from 'qunit'; | ||
import installAssertion from 'testdouble-qunit'; | ||
|
||
installAssertion(QUnit, td); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import JSONAPIAdapter from '@ember-data/adapter/json-api'; | ||
|
||
export default class ApplicationAdapter extends JSONAPIAdapter {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import Model, { attr } from '@ember-data/model'; | ||
|
||
export default class PostModel extends Model { | ||
@attr('string') title; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import JSONAPISerializer from '@ember-data/serializer/json-api'; | ||
|
||
export default class ApplicationSerializer extends JSONAPISerializer {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import Store from '@ember-data/store'; | ||
import { withBulkActions } from 'ember-data-json-api-bulk-ext'; | ||
|
||
@withBulkActions | ||
export default class CustomStore extends Store {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import Pretender from 'pretender'; | ||
|
||
export default function setupPretender(hooks) { | ||
hooks.beforeEach(function() { | ||
this.server = new Pretender(); | ||
}); | ||
|
||
hooks.afterEach(function() { | ||
this.server.shutdown(); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import td from 'testdouble'; | ||
import { isEqual } from 'lodash-es'; | ||
|
||
export const payload = td.matchers.create({ | ||
name: 'payload', | ||
matches([payload], { requestBody }) { | ||
const body = typeof requestBody === 'string' ? JSON.parse(requestBody) : requestBody; | ||
|
||
return isEqual(payload, body); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { module, test } from 'qunit'; | ||
import { setupTest } from 'ember-qunit'; | ||
import td from 'testdouble'; | ||
import setupPretender from '../../helpers/setup-pretender'; | ||
import { payload as payloadMatches } from '../../matchers/pretender'; | ||
|
||
module('Unit | Service | store', function(hooks) { | ||
setupTest(hooks); | ||
setupPretender(hooks); | ||
|
||
hooks.beforeEach(function() { | ||
this.store = this.owner.lookup('service:store'); | ||
|
||
this.postsHandler = td.function(); | ||
this.server.post('/posts', this.postsHandler); | ||
}); | ||
|
||
test('it does not interfere with normal creation', async function(assert) { | ||
td.when( | ||
this.postsHandler( | ||
payloadMatches({ data: { type: 'posts', attributes: { title: 'First Post' } } }) | ||
) | ||
).thenReturn([ | ||
201, | ||
{}, | ||
JSON.stringify({ | ||
data: { | ||
type: 'posts', | ||
id: 1, | ||
attributes: { | ||
title: 'First Post' | ||
} | ||
} | ||
}) | ||
]); | ||
|
||
const first = this.store.createRecord('post', { title: 'First Post' }); | ||
|
||
await first.save(); | ||
|
||
assert.equal(first.id, 1, 'Recieved an ID from the API'); | ||
}); | ||
|
||
test('it can create multiple models at once', async function(assert) { | ||
td.when( | ||
this.postsHandler( | ||
payloadMatches({ | ||
data: [ | ||
{ type: 'posts', attributes: { title: 'First Post' } }, | ||
{ type: 'posts', attributes: { title: 'Second Post' } } | ||
] | ||
}) | ||
) | ||
).thenReturn([ | ||
201, | ||
{}, | ||
JSON.stringify({ | ||
data: [ | ||
{ | ||
type: 'posts', | ||
id: 1, | ||
attributes: { | ||
title: 'First Post' | ||
} | ||
}, | ||
{ | ||
type: 'posts', | ||
id: 2, | ||
attributes: { | ||
title: 'Second Post' | ||
} | ||
} | ||
] | ||
}) | ||
]); | ||
|
||
const first = this.store.createRecord('post', { title: 'First Post' }); | ||
const second = this.store.createRecord('post', { title: 'Second Post' }); | ||
|
||
const result = await this.store.bulkCreate([first, second]); | ||
|
||
assert.equal(first.id, 1, 'The first record is updated with an ID'); | ||
assert.equal(second.id, 2, 'The second record is updated with an ID'); | ||
assert.deepEqual(result, [first, second], 'Returns the created records'); | ||
|
||
assert.equal( | ||
this.store.peekAll('post').length, | ||
2, | ||
'It does not add additional records to the Ember Data store' | ||
); | ||
}); | ||
}); |
Oops, something went wrong.