Skip to content

Commit c669c31

Browse files
Provided a pushMirageIntoStore import for tests and standalone
1 parent 37d91a4 commit c669c31

File tree

5 files changed

+346
-0
lines changed

5 files changed

+346
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { getContext } from '@ember/test-helpers';
2+
3+
import { pushMirageIntoStore as _pushMirageIntoStore } from 'ember-cli-mirage';
4+
5+
/**
6+
* This utility pushes the mirage store into the ember store
7+
*
8+
* If you call this method with no parameters, it will push the entire mirage store into ember store
9+
*
10+
* You may also call this method with an array of resource names. ['accounts', 'accountTypes']. These must
11+
* be the resource names camelized.
12+
*
13+
* You may also call it with a hash. This hash will have the resource names as the keys and the values will either
14+
* be true (push all records for that resource) or a where hash or function that will be applied to the that resource.
15+
* {
16+
* accounts: true,
17+
* accountTypes: { state: 'OH' }
18+
* users: item => item.name.includes("Joe")
19+
* }
20+
*
21+
* @param config undefined means push all resources
22+
* An array will push only the resources in the array
23+
* hash in the form of resource=value Value may be true, all records, or a where hash or function
24+
*/
25+
let pushMirageIntoStore = function (config) {
26+
let context = getContext();
27+
let store = context.owner.lookup('service:store');
28+
29+
_pushMirageIntoStore(context.server, store, config);
30+
};
31+
32+
export { pushMirageIntoStore };

addon/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export {
33
applyEmberDataSerializers,
44
} from './ember-data';
55
export { default as EmberDataSerializer } from 'ember-cli-mirage/serializers/ember-data-serializer';
6+
export * from './utils/push-mirage-into-store';
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { run } from '@ember/runloop';
2+
import assert from '../assert';
3+
4+
let pushMirageRecordsIntoStore = function (store, server, resource, where) {
5+
let models = server.schema[resource].all();
6+
let modelName = models.modelName;
7+
if (typeof where === 'object' || typeof where === 'function') {
8+
models = server.schema[resource].where(where);
9+
}
10+
11+
if (models.length > 0) {
12+
let serializer = server.serializerOrRegistry.serializerFor(modelName);
13+
14+
let originalAlwaysIncludeLinkageData = serializer.alwaysIncludeLinkageData;
15+
serializer.alwaysIncludeLinkageData = true;
16+
17+
let json = serializer.serialize(models);
18+
19+
serializer.alwaysIncludeLinkageData = originalAlwaysIncludeLinkageData;
20+
run(() => {
21+
store.pushPayload(modelName, json);
22+
});
23+
}
24+
25+
return models;
26+
};
27+
28+
/**
29+
* This utility pushes the mirage store into the ember store
30+
*
31+
* If you call this method passing no parameters, it will push the entire mirage store into ember store
32+
*
33+
* You may also call this method with an array of resource names. ['accounts', 'accountTypes']. These must
34+
* be the resource names camelized.
35+
*
36+
* You may also call it with a hash. This hash will have the resource names as the keys and the values will either
37+
* be true (push all records for that resource) or a where hash or function that will be applied to the that resource.
38+
* {
39+
* accounts: true,
40+
* accountTypes: { state: 'OH' }
41+
* users: item => item.name.includes("Joe")
42+
* }
43+
*
44+
* @param server The mirage server
45+
* @param store the store you wish mirage to push to
46+
* @param config undefined means push all resources
47+
* An array will push only the resources in the array
48+
* hash in the form of resource=value Value may be true, all records, or a where hash or function
49+
*/
50+
let pushMirageIntoStore = function (server, store, config) {
51+
assert(store, 'You must supply a store to pushMirageIntoStore');
52+
assert(server, 'You must supply a mirage server to pushMirageIntoStore');
53+
54+
let resources = Object.keys(server.schema).filter(
55+
(key) => server.schema[key].all !== undefined
56+
); // Get the resources
57+
58+
let where = {};
59+
60+
if (config) {
61+
let includes;
62+
if (Array.isArray(config)) {
63+
includes = config;
64+
} else {
65+
includes = Object.keys(config);
66+
where = config;
67+
}
68+
69+
resources = includes.filter((item) => {
70+
let found = resources.includes(item);
71+
assert(
72+
found,
73+
`Model of type '${item}' does not exist for push mirage into store.`
74+
);
75+
return found;
76+
});
77+
}
78+
79+
resources.forEach((resource) => {
80+
pushMirageRecordsIntoStore(store, server, resource, where[resource]);
81+
});
82+
};
83+
84+
export { pushMirageIntoStore, pushMirageRecordsIntoStore };

tests/dummy/app/pods/docs/testing/integration-and-unit-tests/template.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,73 @@ module('Integration | Component | ArticleForm', function(hooks) {
175175
});
176176
```
177177

178+
### Helper to push Mirage's database
179+
180+
A helper has been provided to push mirage's database into the ember data store following the same name and pattern that was published below under writing your own helper. You may now import this from `ember-cli-mirage/test-suport`
181+
182+
```js
183+
import { module } from 'qunit';
184+
import { setupRenderingTest } from 'ember-qunit';
185+
import { setupMirage } from 'ember-cli-mirage/test-support';
186+
import { click, fillIn } from '@ember/test-helpers';
187+
import { pushMirageIntoStore } from 'ember-cli-mirage/test-support';
188+
189+
module('Integration | Component | ArticleForm', function(hooks) {
190+
setupRenderingTest(hooks);
191+
setupMirage(hooks);
192+
193+
test('it can edit an article', async function(assert) {
194+
// ✅ Option 2: Use the store to find the record
195+
let serverArticle = this.server.create('article', {
196+
title: 'Old title'
197+
});
198+
pushMirageIntoStore();
199+
let store = this.owner.lookup('service:store');
200+
let article = store.peekRecord('article', serverArticle.id);
201+
this.set('article', article);
202+
203+
await render(hbs`
204+
<ArticleForm @article={{article}}>
205+
`);
206+
207+
await fillIn('input', 'New title');
208+
await click('.save');
209+
210+
// assert the model was saved
211+
});
212+
});
213+
```
214+
215+
If you do not wish to push all the resources, this helper has an optional parameter to define which resources to push.
216+
217+
This parameter can be an array of all the resources in the form of `['users', 'blogs']`.
218+
219+
For a finer control, this can also be a hash
220+
```js
221+
{
222+
accounts: true, // Push all records for this resource
223+
accountTypes: { state: 'OH' } // push the matching records using mirage's hash form of where
224+
users: item => item.name.includes("Joe") // push the matching records using mirage's function form of where
225+
}
226+
```
227+
228+
The pushMirageIntoStore is imported from `ember-cli-mirage/test-support` and is only usable within ember tests. If you wish to use the pushMirageIntoStore outside of tests, another version is also importable from `ember-cli-mirage`. This version has the following signature
229+
```js
230+
import { pushMirageIntoStore } from 'ember-cli-mirage';
231+
232+
pushMirageIntoStore(
233+
mirageServer,
234+
emberDataStore,
235+
config // optional, same values as above
236+
);
237+
```
238+
239+
This version can also be used inside your tests, but you will have to supply the two required parameters.
240+
178241
### Writing a helper to push Mirage's database
179242

243+
(You no longer need to do this as one has been provided, this documentation is kept for historical purposes)
244+
180245
The second approach is to make a helper that serializers Mirage's database into JSON and pushes that JSON into your Ember Data store.
181246

182247
The actual logic might depend on the configuration of your Mirage server, but if you're following all of Mirage's conventions it should look roughly like this:
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import { module, test } from 'qunit';
2+
import { setupTest } from 'ember-qunit';
3+
import { Server, Model, JSONAPISerializer } from 'miragejs';
4+
import EDModel, { attr } from '@ember-data/model';
5+
import { pushMirageIntoStore as pushMirageIntoStoreTestSupport } from 'ember-cli-mirage/test-support';
6+
import { pushMirageIntoStore } from 'ember-cli-mirage';
7+
8+
module('Unit | Utils | Push Mirage Into Store', function (hooks) {
9+
hooks.beforeEach(function () {
10+
this.server = new Server({
11+
serializers: {
12+
application: JSONAPISerializer,
13+
},
14+
models: {
15+
user: Model,
16+
blog: Model,
17+
},
18+
});
19+
20+
this.server.create('user', {
21+
id: '1',
22+
name: 'Joe Brown',
23+
});
24+
25+
this.server.create('user', {
26+
id: '2',
27+
name: 'Joe Black',
28+
});
29+
30+
this.server.create('user', {
31+
id: '3',
32+
name: 'Jane Doe',
33+
});
34+
35+
this.server.create('blog', {
36+
id: '1',
37+
name: 'Post 1',
38+
});
39+
40+
this.server.create('blog', {
41+
id: '2',
42+
name: 'Post 2',
43+
});
44+
});
45+
46+
hooks.afterEach(function () {
47+
this.server.shutdown();
48+
});
49+
50+
module('from test support', function (hooks) {
51+
setupTest(hooks);
52+
hooks.beforeEach(function () {
53+
this.owner.register(
54+
'model:user',
55+
EDModel.extend({
56+
name: attr(),
57+
})
58+
);
59+
60+
this.owner.register(
61+
'model:blog',
62+
EDModel.extend({
63+
text: attr(),
64+
})
65+
);
66+
67+
this.store = this.owner.lookup('service:store');
68+
});
69+
70+
test('can push records all the records without a config', function (assert) {
71+
pushMirageIntoStoreTestSupport();
72+
assert.strictEqual(this.store.peekAll('user').length, 3);
73+
assert.strictEqual(this.store.peekAll('blog').length, 2);
74+
});
75+
76+
test('can push one resource as array', function (assert) {
77+
pushMirageIntoStoreTestSupport(['users']);
78+
assert.strictEqual(this.store.peekAll('user').length, 3);
79+
assert.strictEqual(this.store.peekAll('blog').length, 0);
80+
});
81+
82+
test('can push one resource as config true', function (assert) {
83+
pushMirageIntoStoreTestSupport({
84+
users: true,
85+
});
86+
assert.strictEqual(this.store.peekAll('user').length, 3);
87+
assert.strictEqual(this.store.peekAll('blog').length, 0);
88+
});
89+
90+
test('can push one resource as config where hash', function (assert) {
91+
pushMirageIntoStoreTestSupport({
92+
users: { name: 'Joe Brown' },
93+
});
94+
assert.strictEqual(this.store.peekAll('user').length, 1);
95+
assert.strictEqual(this.store.peekAll('blog').length, 0);
96+
});
97+
98+
test('can push one resource as config where function', function (assert) {
99+
pushMirageIntoStoreTestSupport({
100+
users: (item) => item.name.includes('Joe'),
101+
});
102+
assert.strictEqual(this.store.peekAll('user').length, 2);
103+
assert.strictEqual(this.store.peekAll('blog').length, 0);
104+
});
105+
});
106+
107+
module('direct import', function (hooks) {
108+
setupTest(hooks);
109+
110+
hooks.beforeEach(function () {
111+
this.owner.register(
112+
'model:user',
113+
EDModel.extend({
114+
name: attr(),
115+
})
116+
);
117+
118+
this.owner.register(
119+
'model:blog',
120+
EDModel.extend({
121+
text: attr(),
122+
})
123+
);
124+
125+
this.store = this.owner.lookup('service:store');
126+
});
127+
128+
test('can push records all the records without a config', function (assert) {
129+
pushMirageIntoStore(this.server, this.store);
130+
assert.strictEqual(this.store.peekAll('user').length, 3);
131+
assert.strictEqual(this.store.peekAll('blog').length, 2);
132+
});
133+
134+
test('can push one resource as array', function (assert) {
135+
pushMirageIntoStore(this.server, this.store, ['users']);
136+
assert.strictEqual(this.store.peekAll('user').length, 3);
137+
assert.strictEqual(this.store.peekAll('blog').length, 0);
138+
});
139+
140+
test('can push one resource as config true', function (assert) {
141+
pushMirageIntoStore(this.server, this.store, {
142+
users: true,
143+
});
144+
assert.strictEqual(this.store.peekAll('user').length, 3);
145+
assert.strictEqual(this.store.peekAll('blog').length, 0);
146+
});
147+
148+
test('can push one resource as config where hash', function (assert) {
149+
pushMirageIntoStore(this.server, this.store, {
150+
users: { name: 'Joe Brown' },
151+
});
152+
assert.strictEqual(this.store.peekAll('user').length, 1);
153+
assert.strictEqual(this.store.peekAll('blog').length, 0);
154+
});
155+
156+
test('can push one resource as config where function', function (assert) {
157+
pushMirageIntoStore(this.server, this.store, {
158+
users: (item) => item.name.includes('Joe'),
159+
});
160+
assert.strictEqual(this.store.peekAll('user').length, 2);
161+
assert.strictEqual(this.store.peekAll('blog').length, 0);
162+
});
163+
});
164+
});

0 commit comments

Comments
 (0)