Skip to content

Commit ef5537d

Browse files
committed
Implementation of Serialize for update/create + unit test for Destroy
1 parent 1a6c64e commit ef5537d

File tree

4 files changed

+108
-14
lines changed

4 files changed

+108
-14
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ This adapter just add a light serialize and deserialize layer over DSHttpAdapter
2121

2222
## Compatibility
2323

24+
| package | requirement |
25+
| ------------ | ------------- |
2426
| js-data | >= 3.0.0-rc.7 |
2527
| js-data-http | >= 3.0.0-rc.2 |
2628

src/main.ts

+55-14
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,40 @@ export class JsonApiAdapter extends HttpAdapter{
5252
return;
5353
}
5454

55-
public jsonApiSerialize(resourceConfig:Mapper, data:any){
56-
// console.log('Serialize: ', resourceConfig, res);
55+
public jsonApiSerialize(mapper:any, data:any){
56+
let id:any = data[mapper.idAttribute];
57+
delete data[mapper.idAttribute];
5758

58-
console.log('lol', data)
59+
// Just cache a pointer to relations for the Resource
60+
this.mapperCacheRelationByField(mapper);
61+
62+
let relationships:any = {}
63+
64+
for (let key in data) {
65+
let relation:any = mapper.relationByFieldId[key];
66+
if (relation) {
67+
relationships[relation.localField] = {
68+
data: {
69+
type: relation.relation,
70+
id: data[key]
71+
}
72+
}
73+
delete data[key]
74+
}
75+
}
5976

60-
return data;
77+
let output:any = {
78+
data: {
79+
type: mapper.name,
80+
attributes: data
81+
}
82+
}
83+
84+
// Work for update or create, if an id is given, server should accept it
85+
if (id) output.data.id = id;
86+
if (Object.keys(relationships)) output.data.relationships = relationships;
87+
88+
return output;
6189
}
6290

6391
public jsonApiDeserialize(mapper:Mapper, res:any, opts:any){
@@ -93,14 +121,7 @@ export class JsonApiAdapter extends HttpAdapter{
93121
if (!resource) { this.warn(`Can\'t find resource '${type}'`); continue; }
94122

95123
// Just cache a pointer to relations for the Resource
96-
if (!resource.relationByFields) {
97-
resource.relationByFields = {};
98-
for (let i = 0, l = (resource.relationList || []).length; i < l; i++ ) {
99-
let field:string = resource.relationList[i].localField;
100-
if (!field) { this.warn('localField missing'); continue; }
101-
resource.relationByFields[field] = resource.relationList[i];
102-
}
103-
}
124+
this.mapperCacheRelationByField(resource);
104125

105126
for (let id in itemsIndexed[type]) {
106127
let item:any = itemsIndexed[type][id];
@@ -109,7 +130,7 @@ export class JsonApiAdapter extends HttpAdapter{
109130
if (!item.relationships || !Object.keys(item.relationships)) continue;
110131

111132
for (let relationField in (item.relationships || {})) {
112-
let relation:any = resource.relationByFields[relationField]
133+
let relation:any = resource.relationByField[relationField]
113134
if (!relation || !item.relationships[relationField] || !item.relationships[relationField].data) {
114135
continue;
115136
}
@@ -165,6 +186,27 @@ export class JsonApiAdapter extends HttpAdapter{
165186
};
166187
}
167188

189+
private mapperCacheRelationByField(mapper:any):void {
190+
if (!mapper.relationByField || !mapper.relationByFieldId) {
191+
mapper.relationByField = {};
192+
mapper.relationByFieldId = {};
193+
for (let i = 0, l = (mapper.relationList || []).length; i < l; i++ ) {
194+
let field:string = mapper.relationList[i].localField;
195+
let key:string = mapper.relationList[i].localKey;
196+
197+
if (key) {
198+
mapper.relationByFieldId[key] = mapper.relationList[i];
199+
}
200+
201+
if (field) {
202+
mapper.relationByField[field] = mapper.relationList[i];
203+
} else {
204+
this.warn('localField missing'); continue;
205+
}
206+
}
207+
}
208+
}
209+
168210
private handleResponse (opts?:any) { return function (response:any): Promise<any> {
169211
if (opts && opts.raw) {
170212
response.meta = response.data.meta;
@@ -185,7 +227,6 @@ export class JsonApiAdapter extends HttpAdapter{
185227
}
186228

187229
public create(mapper: Mapper, props: any, opts?: any): Promise<any> {
188-
console.log('create')
189230
return super.create(mapper, props, opts).then(this.handleResponse(opts))
190231
}
191232

test/unit/crud/destroy.spec.ts

+49
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,55 @@ describe('DESTROY', () => {
1818
server.restore();
1919
})
2020

21+
describe('when destroying a simple object', () => {
22+
const
23+
MAPPER_NAME:string = 'Article',
24+
ID:string = '99633a09-9047-41bf-955f-4a8d72a38d58',
25+
RESPONSE:any = {
26+
data: {
27+
id: ID,
28+
type: MAPPER_NAME,
29+
attributes: {
30+
title: 'Test',
31+
content: 'Lorem ipsum'
32+
}
33+
}
34+
}
35+
36+
let data:any = null;
37+
let reqFind:any = null;
38+
let reqDelete:any = null;
39+
40+
beforeEach(() => {
41+
reqFind = server.answer(`GET articles/${ID}`, RESPONSE);
42+
reqDelete = server.answer(`DELETE articles/${ID}`, {});
43+
44+
return Promise.resolve().then(() => {
45+
return store.find('Article', ID)
46+
}).then((record) => {
47+
expect(store.getAll('Article')).to.have.lengthOf(1);
48+
}).then(() => {
49+
return store.destroy('Article', ID)
50+
}).then((_data) => {
51+
data = _data
52+
})
53+
})
54+
55+
afterEach(() => {
56+
data = reqFind = reqDelete = null;
57+
})
58+
59+
it('should destroy an object', () => {
60+
expect(reqDelete.method).to.equal('DELETE');
61+
expect(reqDelete.url).to.equal(`api/articles/${ID}.json`);
62+
expect(reqDelete.body).to.equal(null);
63+
});
64+
65+
it('should remove it from the store', () => {
66+
expect(store.getAll('Article')).to.have.lengthOf(0);
67+
});
68+
})
69+
2170
describe('when use of unsupported methods', () => {
2271
it('should throw an error when using destroyAll', () => {
2372
return store.destroyAll('Article', [{},{}]).then(() => {

test/unit/crud/lib.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export function respondJson(route: string, content?: any, statusCode?: number):
77
try { body = JSON.parse(request.requestBody); } catch (e) {}
88
reqPointer.body = body;
99
reqPointer.headers = request.requestHeaders;
10+
reqPointer.url = request.url;
11+
reqPointer.method = request.method;
1012

1113
request.respond(
1214
statusCode || 200,

0 commit comments

Comments
 (0)