]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | describe("Ext.data.proxy.WebStorage", function() {\r |
2 | var proxy, config;\r | |
3 | \r | |
4 | var fakeStorageObject = {\r | |
5 | items: {},\r | |
6 | getItem: function(key) {\r | |
7 | return this.items[key] || null;\r | |
8 | },\r | |
9 | setItem: function(key, value) {\r | |
10 | this.items[key] = value + '';\r | |
11 | },\r | |
12 | removeItem: function(key) {\r | |
13 | delete this.items[key];\r | |
14 | },\r | |
15 | clear: function() {\r | |
16 | this.items = {};\r | |
17 | }\r | |
18 | };\r | |
19 | \r | |
20 | beforeEach(function() {\r | |
21 | Ext.define('spec.User', {\r | |
22 | extend: 'Ext.data.Model',\r | |
23 | fields: [\r | |
24 | {name: 'id', type: 'int'},\r | |
25 | {name: 'name', type: 'string'},\r | |
26 | {name: 'age', type: 'int'}\r | |
27 | ]\r | |
28 | });\r | |
29 | \r | |
30 | Ext.define('spec.Storage', {\r | |
31 | extend: 'Ext.data.proxy.WebStorage',\r | |
32 | getStorageObject: function() {\r | |
33 | return fakeStorageObject;\r | |
34 | } \r | |
35 | });\r | |
36 | });\r | |
37 | \r | |
38 | afterEach(function(){\r | |
39 | fakeStorageObject.clear();\r | |
40 | Ext.undefine('spec.User');\r | |
41 | Ext.undefine('spec.Storage');\r | |
42 | Ext.data.Model.schema.clear();\r | |
43 | });\r | |
44 | \r | |
45 | describe("getIds", function() {\r | |
46 | \r | |
47 | beforeEach(function() {\r | |
48 | spyOn(fakeStorageObject, 'getItem').andCallThrough();\r | |
49 | \r | |
50 | fakeStorageObject.setItem('wsId', "1,2,3");\r | |
51 | \r | |
52 | proxy = new spec.Storage({\r | |
53 | id: 'wsId',\r | |
54 | model: spec.User\r | |
55 | });\r | |
56 | });\r | |
57 | \r | |
58 | it("should retrieve the list of ids from the storage object", function() {\r | |
59 | expect(fakeStorageObject.getItem).toHaveBeenCalledWith('wsId');\r | |
60 | });\r | |
61 | \r | |
62 | it("should return an array", function() {\r | |
63 | expect(Ext.isArray(proxy.getIds())).toBe(true);\r | |
64 | });\r | |
65 | \r | |
66 | describe("if the id field is is not a string field", function() {\r | |
67 | it("should return each array item as a number", function() {\r | |
68 | var ids = proxy.getIds(),\r | |
69 | length = ids.length,\r | |
70 | i;\r | |
71 | \r | |
72 | for (i = 0; i < length; i++) {\r | |
73 | expect(typeof ids[i] === 'number').toBe(true);\r | |
74 | }\r | |
75 | });\r | |
76 | });\r | |
77 | \r | |
78 | describe("if the id field is a string field", function() {\r | |
79 | beforeEach(function() {\r | |
80 | spec.User = Ext.define(null, {\r | |
81 | extend: 'Ext.data.Model',\r | |
82 | fields: [\r | |
83 | {name: 'id', type: 'string'}\r | |
84 | ]\r | |
85 | });\r | |
86 | \r | |
87 | proxy = new spec.Storage({\r | |
88 | id: 'wsId',\r | |
89 | model: spec.User\r | |
90 | });\r | |
91 | });\r | |
92 | it("should return each array item as a string", function() {\r | |
93 | var ids = proxy.getIds(),\r | |
94 | length = ids.length,\r | |
95 | i;\r | |
96 | \r | |
97 | for (i = 0; i < length; i++) {\r | |
98 | expect(typeof ids[i] === 'string').toBe(true);\r | |
99 | }\r | |
100 | });\r | |
101 | });\r | |
102 | });\r | |
103 | \r | |
104 | describe("getNextId", function() {\r | |
105 | beforeEach(function() {\r | |
106 | fakeStorageObject.setItem(proxy.getRecordCounterKey(), "3");\r | |
107 | \r | |
108 | proxy = new spec.Storage({\r | |
109 | id: 'wsId',\r | |
110 | model: spec.User\r | |
111 | });\r | |
112 | });\r | |
113 | \r | |
114 | it("should increment the counter in the storage object", function() {\r | |
115 | proxy.getNextId();\r | |
116 | \r | |
117 | expect(fakeStorageObject.getItem(proxy.getRecordCounterKey())).toEqual('4');\r | |
118 | });\r | |
119 | \r | |
120 | describe("if the id field is is not a string field", function() {\r | |
121 | it("should return an incremented id as a number", function() {\r | |
122 | expect(proxy.getNextId()).toEqual(4);\r | |
123 | });\r | |
124 | });\r | |
125 | \r | |
126 | describe("when the id field is a string field", function() {\r | |
127 | beforeEach(function() {\r | |
128 | spec.User = Ext.define(null, {\r | |
129 | extend: 'Ext.data.Model',\r | |
130 | fields: [\r | |
131 | {name: 'id', type: 'string'}\r | |
132 | ]\r | |
133 | });\r | |
134 | \r | |
135 | proxy = new spec.Storage({\r | |
136 | id: 'wsId',\r | |
137 | model: spec.User\r | |
138 | });\r | |
139 | });\r | |
140 | \r | |
141 | it("should return a string", function() {\r | |
142 | expect(proxy.getNextId()).toEqual('4');\r | |
143 | });\r | |
144 | });\r | |
145 | });\r | |
146 | \r | |
147 | describe("instantiation with id configuration option and methods", function() {\r | |
148 | config = {\r | |
149 | id: 'User'\r | |
150 | };\r | |
151 | \r | |
152 | beforeEach(function() {\r | |
153 | proxy = new spec.Storage(config);\r | |
154 | });\r | |
155 | \r | |
156 | describe("instantiation", function(){\r | |
157 | it("should set id", function() {\r | |
158 | expect(proxy.getId()).toEqual('User');\r | |
159 | });\r | |
160 | \r | |
161 | it("should extend Ext.data.proxy.Client", function() {\r | |
162 | expect(proxy.superclass.superclass).toEqual(Ext.data.proxy.Client.prototype);\r | |
163 | });\r | |
164 | \r | |
165 | \r | |
166 | it("should test getStorageObject in constructor", function() {\r | |
167 | expect(proxy.getStorageObject()).toBe(fakeStorageObject); \r | |
168 | });\r | |
169 | });\r | |
170 | \r | |
171 | describe("methods", function() {\r | |
172 | describe("getRecordKey", function() {\r | |
173 | var nicolas;\r | |
174 | \r | |
175 | beforeEach(function() {\r | |
176 | Ext.define('spec.Human', {\r | |
177 | extend: 'Ext.data.Model',\r | |
178 | fields: [\r | |
179 | {name: 'name', type: 'string'},\r | |
180 | {name: 'age', type: 'int'},\r | |
181 | {name: 'planet', type: 'string', defaultValue: 'Earth'}\r | |
182 | ]\r | |
183 | });\r | |
184 | nicolas = new spec.Human({\r | |
185 | id: 1,\r | |
186 | name: 'Nicolas',\r | |
187 | age : 27\r | |
188 | });\r | |
189 | });\r | |
190 | \r | |
191 | afterEach(function() {\r | |
192 | Ext.undefine('spec.Human');\r | |
193 | });\r | |
194 | \r | |
195 | it("should return a unique string with a string given", function() {\r | |
196 | expect(proxy.getRecordKey("33")).toEqual("User-33");\r | |
197 | });\r | |
198 | \r | |
199 | it("should return a unique string with a model given", function() {\r | |
200 | expect(proxy.getRecordKey(nicolas)).toEqual("User-1");\r | |
201 | });\r | |
202 | \r | |
203 | });\r | |
204 | \r | |
205 | describe("getRecordCounterKey", function() {\r | |
206 | it("should return the unique key used to store the current record counter for this proxy", function () {\r | |
207 | expect(proxy.getRecordCounterKey()).toEqual("User-counter");\r | |
208 | });\r | |
209 | });\r | |
210 | \r | |
211 | describe("getTreeKey", function() {\r | |
212 | it("should return the unique key used to store the tree indicator for this proxy", function () {\r | |
213 | expect(proxy.getTreeKey()).toEqual("User-tree");\r | |
214 | });\r | |
215 | });\r | |
216 | \r | |
217 | describe("getStorageObject", function(){\r | |
218 | it("should throw an error on getStorageObject", function() {\r | |
219 | expect(Ext.data.proxy.WebStorage.prototype.getStorageObject).toRaiseExtError();\r | |
220 | });\r | |
221 | });\r | |
222 | });\r | |
223 | });\r | |
224 | \r | |
225 | describe("instantiation with tree-indicator set in storage object", function() {\r | |
226 | var config = {\r | |
227 | id: 'tree-test'\r | |
228 | };\r | |
229 | \r | |
230 | beforeEach(function() {\r | |
231 | fakeStorageObject.setItem(config.id + '-tree', true);\r | |
232 | proxy = new spec.Storage(config);\r | |
233 | });\r | |
234 | \r | |
235 | it("should set the isHierarchical flag", function() {\r | |
236 | expect(proxy.isHierarchical).toEqual(true);\r | |
237 | });\r | |
238 | });\r | |
239 | \r | |
240 | describe("destroying records after they have been added", function() {\r | |
241 | var store;\r | |
242 | \r | |
243 | beforeEach(function() {\r | |
244 | proxy = new spec.Storage({\r | |
245 | id : 'lsTest'\r | |
246 | });\r | |
247 | \r | |
248 | store = new Ext.data.Store({\r | |
249 | model: spec.User,\r | |
250 | proxy: proxy\r | |
251 | });\r | |
252 | \r | |
253 | store.add({name: 'Ed'}, {name: 'Abe'}, {name: 'Aaron'}, {name: 'Tommy'});\r | |
254 | store.sync();\r | |
255 | });\r | |
256 | \r | |
257 | it("should remove a single record", function() {\r | |
258 | var count = store.getCount();\r | |
259 | \r | |
260 | store.remove(store.getAt(1));\r | |
261 | store.sync();\r | |
262 | \r | |
263 | expect(store.getCount()).toEqual(count - 1);\r | |
264 | \r | |
265 | expect(store.getAt(0).get('name')).toEqual('Ed');\r | |
266 | expect(store.getAt(1).get('name')).toEqual('Aaron');\r | |
267 | });\r | |
268 | \r | |
269 | it("should remove an array of records", function() {\r | |
270 | var count = store.getCount();\r | |
271 | \r | |
272 | store.remove([store.getAt(1), store.getAt(2)]);\r | |
273 | store.sync();\r | |
274 | \r | |
275 | expect(store.getCount()).toEqual(count - 2);\r | |
276 | \r | |
277 | expect(store.getAt(0).get('name')).toEqual('Ed');\r | |
278 | expect(store.getAt(1).get('name')).toEqual('Tommy');\r | |
279 | });\r | |
280 | \r | |
281 | it("should remove the records ids from storage", function() {\r | |
282 | store.remove([store.getAt(1), store.getAt(2)]);\r | |
283 | store.sync();\r | |
284 | \r | |
285 | expect(proxy.getIds()).toEqual([1,4]);\r | |
286 | });\r | |
287 | });\r | |
288 | \r | |
289 | describe("destroying a tree node", function() {\r | |
290 | var store, node1, node2, node3, node4, node5, node6;\r | |
291 | \r | |
292 | beforeEach(function() {\r | |
293 | proxy = new spec.Storage({\r | |
294 | id : 'tree-test'\r | |
295 | });\r | |
296 | \r | |
297 | spec.User = Ext.define(null, {\r | |
298 | extend: 'Ext.data.TreeModel',\r | |
299 | fields: [\r | |
300 | {name: 'id', type: 'int'},\r | |
301 | {name: 'name', type: 'string'}\r | |
302 | ],\r | |
303 | proxy: proxy\r | |
304 | });\r | |
305 | \r | |
306 | Ext.data.NodeInterface.decorate(spec.User);\r | |
307 | \r | |
308 | store = new Ext.data.TreeStore({\r | |
309 | model: spec.User,\r | |
310 | proxy: proxy,\r | |
311 | root: {\r | |
312 | name: 'Users',\r | |
313 | expanded: true,\r | |
314 | id: 42\r | |
315 | }\r | |
316 | });\r | |
317 | \r | |
318 | node1 = new spec.User({name: 'Abe'});\r | |
319 | node2 = new spec.User({name: 'Sue'});\r | |
320 | node3 = new spec.User({name: 'Phil'});\r | |
321 | node4 = new spec.User({name: 'Don'});\r | |
322 | node5 = new spec.User({name: 'Ed'});\r | |
323 | node6 = new spec.User({name: 'Nico'});\r | |
324 | node2.appendChild([node3, node4]);\r | |
325 | node1.appendChild([node2, node5]);\r | |
326 | \r | |
327 | store.getRoot().appendChild(node1);\r | |
328 | store.getRoot().appendChild(node6);\r | |
329 | store.sync();\r | |
330 | });\r | |
331 | \r | |
332 | it("should recursively remove the node and all of its descendants", function() {\r | |
333 | spyOn(proxy, 'removeRecord').andCallThrough();\r | |
334 | node1.erase();\r | |
335 | \r | |
336 | expect(proxy.removeRecord).toHaveBeenCalledWith(node1);\r | |
337 | expect(proxy.removeRecord).toHaveBeenCalledWith(node2);\r | |
338 | expect(proxy.removeRecord).toHaveBeenCalledWith(node3);\r | |
339 | expect(proxy.removeRecord).toHaveBeenCalledWith(node4);\r | |
340 | expect(proxy.removeRecord).toHaveBeenCalledWith(node5);\r | |
341 | });\r | |
342 | \r | |
343 | it("should remove the node and its descendants from the storage object", function() {\r | |
344 | node1.erase();\r | |
345 | \r | |
346 | expect(proxy.getRecord(1)).toBeNull();\r | |
347 | expect(proxy.getRecord(2)).toBeNull();\r | |
348 | expect(proxy.getRecord(3)).toBeNull();\r | |
349 | expect(proxy.getRecord(4)).toBeNull();\r | |
350 | expect(proxy.getRecord(5)).toBeNull();\r | |
351 | });\r | |
352 | \r | |
353 | it("should remove the ids for the node and its descendants", function() {\r | |
354 | node1.erase();\r | |
355 | \r | |
356 | // make sure the ids array just has one id (the record that was not part of node1's hierarchy)\r | |
357 | expect(proxy.getIds()).toEqual([6]);\r | |
358 | });\r | |
359 | \r | |
360 | it("should remove the node and its descendants from the cache", function() {\r | |
361 | node1.erase();\r | |
362 | \r | |
363 | expect(proxy.cache[1]).toBeUndefined();\r | |
364 | expect(proxy.cache[2]).toBeUndefined();\r | |
365 | expect(proxy.cache[3]).toBeUndefined();\r | |
366 | expect(proxy.cache[4]).toBeUndefined();\r | |
367 | expect(proxy.cache[5]).toBeUndefined();\r | |
368 | });\r | |
369 | });\r | |
370 | \r | |
371 | describe("adding records to the storage object", function() {\r | |
372 | var record, operation;\r | |
373 | \r | |
374 | beforeEach(function() {\r | |
375 | proxy = new spec.Storage({\r | |
376 | model: spec.User,\r | |
377 | id: 'someId'\r | |
378 | });\r | |
379 | \r | |
380 | spyOn(proxy, 'getNextId').andReturn(10);\r | |
381 | spyOn(proxy, 'setIds').andCallThrough();\r | |
382 | spyOn(proxy, 'getIds').andReturn([]);\r | |
383 | spyOn(proxy, 'setRecord').andCallThrough();\r | |
384 | });\r | |
385 | \r | |
386 | var createOperation = function() {\r | |
387 | operation = new Ext.data.operation.Create({\r | |
388 | records: [record]\r | |
389 | });\r | |
390 | \r | |
391 | spyOn(operation, 'setCompleted').andCallThrough();\r | |
392 | spyOn(operation, 'setSuccessful').andCallThrough();\r | |
393 | };\r | |
394 | \r | |
395 | describe("if the records are phantoms", function() {\r | |
396 | \r | |
397 | beforeEach(function() {\r | |
398 | record = new spec.User({name: 'Ed'});\r | |
399 | createOperation();\r | |
400 | });\r | |
401 | \r | |
402 | it("should assign the next id to the record", function() {\r | |
403 | proxy.create(operation);\r | |
404 | \r | |
405 | expect(record.getId()).toEqual(10);\r | |
406 | });\r | |
407 | \r | |
408 | it("should retain an id if using a UUID", function() {\r | |
409 | var uniqueModel = Ext.define(null, {\r | |
410 | extend: 'Ext.data.Model',\r | |
411 | fields: ['id'],\r | |
412 | identifier: "uuid"\r | |
413 | });\r | |
414 | \r | |
415 | proxy = new spec.Storage({\r | |
416 | model: uniqueModel,\r | |
417 | id: 'someId'\r | |
418 | });\r | |
419 | \r | |
420 | record = new uniqueModel();\r | |
421 | var id = record.getId();\r | |
422 | createOperation();\r | |
423 | proxy.create(operation);\r | |
424 | expect(record.getId()).toBe(id);\r | |
425 | });\r | |
426 | \r | |
427 | it("should mark the Operation as completed", function() {\r | |
428 | proxy.create(operation);\r | |
429 | \r | |
430 | expect(operation.setCompleted).toHaveBeenCalled();\r | |
431 | });\r | |
432 | \r | |
433 | it("should mark the Operation as successful", function() {\r | |
434 | proxy.create(operation);\r | |
435 | \r | |
436 | expect(operation.setSuccessful).toHaveBeenCalled();\r | |
437 | });\r | |
438 | \r | |
439 | it("should add the id to the set of all ids", function() {\r | |
440 | proxy.create(operation);\r | |
441 | \r | |
442 | expect(proxy.setIds).toHaveBeenCalledWith([10]);\r | |
443 | });\r | |
444 | \r | |
445 | it("should add the record to the storage object", function() {\r | |
446 | proxy.create(operation);\r | |
447 | \r | |
448 | expect(proxy.setRecord).toHaveBeenCalledWith(record, 10);\r | |
449 | });\r | |
450 | \r | |
451 | it("should call commit on the record", function() {\r | |
452 | spyOn(record, 'commit').andCallThrough();\r | |
453 | \r | |
454 | proxy.create(operation);\r | |
455 | \r | |
456 | expect(record.commit).toHaveBeenCalled();\r | |
457 | });\r | |
458 | \r | |
459 | it("should call the callback function with the records and operation", function() {\r | |
460 | var theOperation, records;\r | |
461 | \r | |
462 | operation.setCallback(function(recs, op) {\r | |
463 | records = recs;\r | |
464 | theOperation = op;\r | |
465 | });\r | |
466 | \r | |
467 | proxy.create(operation);\r | |
468 | \r | |
469 | expect(theOperation).toEqual(operation);\r | |
470 | expect(records).toEqual(operation.getRecords());\r | |
471 | });\r | |
472 | \r | |
473 | it("should call the callback function with the correct scope", function() {\r | |
474 | var theScope;\r | |
475 | \r | |
476 | operation.setCallback(function() {\r | |
477 | theScope = this;\r | |
478 | });\r | |
479 | \r | |
480 | operation.setScope(fakeScope);\r | |
481 | \r | |
482 | proxy.create(operation);\r | |
483 | \r | |
484 | expect(theScope).toBe(fakeScope);\r | |
485 | });\r | |
486 | });\r | |
487 | \r | |
488 | describe("if the records are not phantoms", function() {\r | |
489 | beforeEach(function() {\r | |
490 | record = new spec.User({id: 20, name: 'Ed'});\r | |
491 | createOperation();\r | |
492 | });\r | |
493 | \r | |
494 | it("should add the id to the set of all ids", function() {\r | |
495 | proxy.create(operation);\r | |
496 | \r | |
497 | expect(proxy.setIds).toHaveBeenCalledWith([20]);\r | |
498 | });\r | |
499 | \r | |
500 | it("should not generate the next id", function() {\r | |
501 | proxy.create(operation);\r | |
502 | \r | |
503 | expect(proxy.getNextId).not.toHaveBeenCalled();\r | |
504 | });\r | |
505 | \r | |
506 | it("should add the record to the storage object", function() {\r | |
507 | proxy.create(operation);\r | |
508 | \r | |
509 | expect(proxy.setRecord).toHaveBeenCalledWith(record, 20);\r | |
510 | });\r | |
511 | });\r | |
512 | \r | |
513 | describe("if the records are decorated with NodeInterface", function() {\r | |
514 | beforeEach(function() {\r | |
515 | Ext.data.NodeInterface.decorate(spec.User);\r | |
516 | record = new spec.User({name: 'Phil'});\r | |
517 | createOperation();\r | |
518 | });\r | |
519 | \r | |
520 | it("should set the tree indicator in the storage object the first time a record is created", function() {\r | |
521 | proxy.create(operation);\r | |
522 | \r | |
523 | expect(proxy.getStorageObject().getItem(proxy.getTreeKey())).toEqual('true');\r | |
524 | });\r | |
525 | \r | |
526 | it("should set the isHierarchical flag on the proxy the first time a record is created", function() {\r | |
527 | proxy.create(operation);\r | |
528 | \r | |
529 | expect(proxy.isHierarchical).toEqual(true);\r | |
530 | });\r | |
531 | });\r | |
532 | });\r | |
533 | \r | |
534 | describe("updating existing records", function() {\r | |
535 | var operation, record;\r | |
536 | \r | |
537 | beforeEach(function() {\r | |
538 | proxy = new spec.Storage({\r | |
539 | model: spec.User,\r | |
540 | id: 'someId'\r | |
541 | });\r | |
542 | \r | |
543 | spyOn(proxy, 'setRecord').andCallThrough();\r | |
544 | \r | |
545 | \r | |
546 | record = new spec.User({id: 100, name: 'Ed'});\r | |
547 | \r | |
548 | operation = new Ext.data.operation.Update({\r | |
549 | records: [record]\r | |
550 | });\r | |
551 | \r | |
552 | spyOn(operation, 'setCompleted').andCallThrough();\r | |
553 | spyOn(operation, 'setSuccessful').andCallThrough();\r | |
554 | });\r | |
555 | \r | |
556 | it("should mark the Operation as completed", function() {\r | |
557 | proxy.update(operation);\r | |
558 | \r | |
559 | expect(operation.setCompleted).toHaveBeenCalled();\r | |
560 | });\r | |
561 | \r | |
562 | it("should mark the Operation as successful", function() {\r | |
563 | proxy.update(operation);\r | |
564 | \r | |
565 | expect(operation.setSuccessful).toHaveBeenCalled();\r | |
566 | });\r | |
567 | \r | |
568 | it("should add the record to the storage object", function() {\r | |
569 | proxy.update(operation);\r | |
570 | \r | |
571 | expect(proxy.setRecord).toHaveBeenCalledWith(record);\r | |
572 | });\r | |
573 | \r | |
574 | it("should call commit on the record", function() {\r | |
575 | spyOn(record, 'commit').andCallThrough();\r | |
576 | \r | |
577 | proxy.update(operation);\r | |
578 | \r | |
579 | expect(record.commit).toHaveBeenCalled();\r | |
580 | });\r | |
581 | \r | |
582 | it("should call the callback function with the records and operation", function() {\r | |
583 | var theOperation, records;\r | |
584 | \r | |
585 | operation.setCallback(function(recs, op) {\r | |
586 | records = recs;\r | |
587 | theOperation = op;\r | |
588 | });\r | |
589 | \r | |
590 | proxy.update(operation);\r | |
591 | \r | |
592 | expect(theOperation).toEqual(operation);\r | |
593 | expect(records).toEqual(operation.getRecords());\r | |
594 | });\r | |
595 | \r | |
596 | it("should call the callback function with the correct scope", function() {\r | |
597 | var theScope;\r | |
598 | \r | |
599 | operation.setCallback(function() {\r | |
600 | theScope = this;\r | |
601 | });\r | |
602 | \r | |
603 | operation.setScope(fakeScope);\r | |
604 | \r | |
605 | proxy.update(operation);\r | |
606 | \r | |
607 | expect(theScope).toBe(fakeScope);\r | |
608 | });\r | |
609 | \r | |
610 | describe("if the record is not already in the storage object", function() {\r | |
611 | it("should add the record's id to the set of ids", function() {\r | |
612 | spyOn(proxy, 'setIds').andCallThrough();\r | |
613 | \r | |
614 | proxy.update(operation);\r | |
615 | \r | |
616 | expect(proxy.setIds).toHaveBeenCalledWith([100]);\r | |
617 | });\r | |
618 | });\r | |
619 | });\r | |
620 | \r | |
621 | describe("setRecord", function() {\r | |
622 | var record, recordKey, encodedData;\r | |
623 | \r | |
624 | beforeEach(function() {\r | |
625 | \r | |
626 | spyOn(fakeStorageObject, 'setItem').andReturn();\r | |
627 | spyOn(fakeStorageObject, 'removeItem').andReturn();\r | |
628 | \r | |
629 | proxy = new spec.Storage({\r | |
630 | model: spec.User,\r | |
631 | id: 'someId'\r | |
632 | });\r | |
633 | \r | |
634 | record = new spec.User({id: 100, name: 'Ed'});\r | |
635 | recordKey = 'someId-100';\r | |
636 | encodedData = 'some encoded data';\r | |
637 | \r | |
638 | spyOn(Ext, 'encode').andReturn(encodedData);\r | |
639 | \r | |
640 | spyOn(record, 'set').andCallThrough();\r | |
641 | spyOn(proxy, 'getRecordKey').andReturn(recordKey);\r | |
642 | });\r | |
643 | \r | |
644 | describe("if a new id is passed", function() {\r | |
645 | it("should set the id on the record", function() {\r | |
646 | proxy.setRecord(record, 20);\r | |
647 | \r | |
648 | expect(record.set).toHaveBeenCalledWith('id', 20, { commit: true });\r | |
649 | });\r | |
650 | });\r | |
651 | \r | |
652 | describe("if a new id is not passed", function() {\r | |
653 | it("should get the id from the record", function() {\r | |
654 | spyOn(record, 'getId').andCallThrough();\r | |
655 | \r | |
656 | proxy.setRecord(record);\r | |
657 | \r | |
658 | expect(record.getId).toHaveBeenCalled();\r | |
659 | });\r | |
660 | });\r | |
661 | \r | |
662 | it("should get the record key for the model instance", function() {\r | |
663 | proxy.setRecord(record);\r | |
664 | \r | |
665 | expect(proxy.getRecordKey).toHaveBeenCalledWith(100);\r | |
666 | });\r | |
667 | \r | |
668 | it("should remove the item from the storage object before adding it again", function() {\r | |
669 | proxy.setRecord(record);\r | |
670 | \r | |
671 | expect(fakeStorageObject.removeItem).toHaveBeenCalledWith(recordKey);\r | |
672 | });\r | |
673 | \r | |
674 | it("should add the item to the storage object", function() {\r | |
675 | proxy.setRecord(record);\r | |
676 | \r | |
677 | expect(fakeStorageObject.setItem).toHaveBeenCalledWith(recordKey, encodedData);\r | |
678 | });\r | |
679 | \r | |
680 | it("should json encode the data", function() {\r | |
681 | var data = Ext.clone(record.data);\r | |
682 | \r | |
683 | proxy.setRecord(record);\r | |
684 | \r | |
685 | delete data.id;\r | |
686 | \r | |
687 | expect(Ext.encode).toHaveBeenCalledWith(data);\r | |
688 | });\r | |
689 | });\r | |
690 | \r | |
691 | describe("reading", function() {\r | |
692 | var f, operation;\r | |
693 | \r | |
694 | beforeEach(function() { \r | |
695 | config = {\r | |
696 | id: 'User',\r | |
697 | model: spec.User\r | |
698 | };\r | |
699 | \r | |
700 | proxy = new spec.Storage(config);\r | |
701 | });\r | |
702 | \r | |
703 | describe("via the model", function() {\r | |
704 | it("should load the data", function() {\r | |
705 | spec.User.setProxy(proxy);\r | |
706 | \r | |
707 | var rec = new spec.User({\r | |
708 | id: 1,\r | |
709 | name: 'Foo'\r | |
710 | });\r | |
711 | rec.save();\r | |
712 | \r | |
713 | var user = spec.User.load(1);\r | |
714 | expect(user.getId()).toBe(1);\r | |
715 | expect(user.get('name')).toBe('Foo');\r | |
716 | });\r | |
717 | });\r | |
718 | \r | |
719 | describe("if passed an id", function() {\r | |
720 | var fakeRecord;\r | |
721 | \r | |
722 | beforeEach(function() {\r | |
723 | fakeRecord = {id: 100, name: 'Phil'};\r | |
724 | \r | |
725 | spyOn(proxy, 'getRecord').andReturn(fakeRecord);\r | |
726 | \r | |
727 | operation = new Ext.data.operation.Read({\r | |
728 | id: 100\r | |
729 | });\r | |
730 | });\r | |
731 | \r | |
732 | it("should attempt to get the record for the given id", function() {\r | |
733 | proxy.read(operation);\r | |
734 | \r | |
735 | expect(proxy.getRecord).toHaveBeenCalledWith(100);\r | |
736 | });\r | |
737 | \r | |
738 | it("should mark the operation successful", function() {\r | |
739 | spyOn(operation, 'setSuccessful').andCallThrough();\r | |
740 | \r | |
741 | proxy.read(operation);\r | |
742 | \r | |
743 | expect(operation.setSuccessful).toHaveBeenCalled();\r | |
744 | });\r | |
745 | \r | |
746 | it("should mark the operation completed", function() {\r | |
747 | spyOn(operation, 'setCompleted').andCallThrough();\r | |
748 | \r | |
749 | proxy.read(operation);\r | |
750 | \r | |
751 | expect(operation.setCompleted).toHaveBeenCalled();\r | |
752 | });\r | |
753 | \r | |
754 | describe("the resultSet", function() {\r | |
755 | var resultSet;\r | |
756 | \r | |
757 | beforeEach(function() {\r | |
758 | operation.setCallback(function(recs, op) {\r | |
759 | resultSet = op.getResultSet();\r | |
760 | });\r | |
761 | proxy.read(operation);\r | |
762 | });\r | |
763 | \r | |
764 | it("should contain the loaded record", function() {\r | |
765 | expect(resultSet.getRecords()[0].getId()).toEqual(100);\r | |
766 | expect(resultSet.getRecords()[0].get('name')).toEqual('Phil');\r | |
767 | });\r | |
768 | \r | |
769 | it("should set the correct total number of records", function() {\r | |
770 | expect(resultSet.getTotal()).toEqual(1);\r | |
771 | });\r | |
772 | \r | |
773 | it("should mark itself as loaded", function() {\r | |
774 | expect(resultSet.getLoaded()).toBe(true);\r | |
775 | });\r | |
776 | });\r | |
777 | \r | |
778 | it("should call the recordCreator function to create the record", function() {\r | |
779 | var recordCreator = jasmine.createSpy();\r | |
780 | operation.setRecordCreator(recordCreator);\r | |
781 | \r | |
782 | proxy.read(operation);\r | |
783 | \r | |
784 | expect(recordCreator).toHaveBeenCalledWith({\r | |
785 | id: 100,\r | |
786 | name: 'Phil'\r | |
787 | }, spec.User);\r | |
788 | });\r | |
789 | });\r | |
790 | \r | |
791 | describe("if not passed an id", function() {\r | |
792 | var fakeRecords;\r | |
793 | \r | |
794 | beforeEach(function() {\r | |
795 | fakeStorageObject.setItem('User', '1,2,3,4');\r | |
796 | fakeStorageObject.setItem('User-1', '{"firstName":"Bob","lastName":"Smith","age":"2"}');\r | |
797 | fakeStorageObject.setItem('User-2', '{"firstName":"Joe","lastName":"Smith","age":"50"}');\r | |
798 | fakeStorageObject.setItem('User-3', '{"firstName":"Tim","lastName":"Jones","age":"41"}');\r | |
799 | fakeStorageObject.setItem('User-4', '{"firstName":"Jim","lastName":"Smith","age":"33"}');\r | |
800 | \r | |
801 | operation = new Ext.data.operation.Read();\r | |
802 | });\r | |
803 | \r | |
804 | it("should mark the operation successful", function() {\r | |
805 | spyOn(operation, 'setSuccessful').andCallThrough();\r | |
806 | \r | |
807 | proxy.read(operation);\r | |
808 | \r | |
809 | expect(operation.setSuccessful).toHaveBeenCalled();\r | |
810 | });\r | |
811 | \r | |
812 | it("should mark the operation completed", function() {\r | |
813 | spyOn(operation, 'setCompleted').andCallThrough();\r | |
814 | \r | |
815 | proxy.read(operation);\r | |
816 | \r | |
817 | expect(operation.setCompleted).toHaveBeenCalled();\r | |
818 | });\r | |
819 | \r | |
820 | it("should call the recordCreator function to create the records", function() {\r | |
821 | var recordCreator = jasmine.createSpy();\r | |
822 | operation.setRecordCreator(recordCreator);\r | |
823 | \r | |
824 | proxy.read(operation);\r | |
825 | \r | |
826 | expect(recordCreator.callCount).toBe(4);\r | |
827 | \r | |
828 | expect(recordCreator.calls[0].args).toEqual([{\r | |
829 | id: 1,\r | |
830 | firstName: 'Bob',\r | |
831 | lastName: 'Smith',\r | |
832 | age: '2'\r | |
833 | }, spec.User]);\r | |
834 | \r | |
835 | expect(recordCreator.calls[1].args).toEqual([{\r | |
836 | id: 2,\r | |
837 | firstName: 'Joe',\r | |
838 | lastName: 'Smith',\r | |
839 | age: '50'\r | |
840 | }, spec.User]);\r | |
841 | \r | |
842 | expect(recordCreator.calls[2].args).toEqual([{\r | |
843 | id: 3,\r | |
844 | firstName: 'Tim',\r | |
845 | lastName: 'Jones',\r | |
846 | age: '41'\r | |
847 | }, spec.User]);\r | |
848 | \r | |
849 | expect(recordCreator.calls[3].args).toEqual([{\r | |
850 | id: 4,\r | |
851 | firstName: 'Jim',\r | |
852 | lastName: 'Smith',\r | |
853 | age: '33'\r | |
854 | }, spec.User]);\r | |
855 | });\r | |
856 | \r | |
857 | describe("the resultSet", function() {\r | |
858 | var resultSet;\r | |
859 | \r | |
860 | beforeEach(function() {\r | |
861 | operation.setCallback(function(recs, op) {\r | |
862 | resultSet = op.getResultSet();\r | |
863 | });\r | |
864 | proxy.read(operation);\r | |
865 | });\r | |
866 | \r | |
867 | it("should contain the loaded records", function() {\r | |
868 | expect(resultSet.getRecords()[0].get('firstName')).toBe('Bob');\r | |
869 | expect(resultSet.getRecords()[1].get('firstName')).toBe('Joe');\r | |
870 | expect(resultSet.getRecords()[2].get('firstName')).toBe('Tim');\r | |
871 | expect(resultSet.getRecords()[3].get('firstName')).toBe('Jim');\r | |
872 | });\r | |
873 | \r | |
874 | it("should contain the correct number of loaded records", function() {\r | |
875 | expect(resultSet.getRecords().length).toBe(4);\r | |
876 | });\r | |
877 | \r | |
878 | it("should set the correct total number of records", function() {\r | |
879 | expect(resultSet.getTotal()).toEqual(4);\r | |
880 | });\r | |
881 | \r | |
882 | it("should mark itself as loaded", function() {\r | |
883 | expect(resultSet.getLoaded()).toBe(true);\r | |
884 | });\r | |
885 | \r | |
886 | it("should cache the records", function() {\r | |
887 | expect(proxy.cache[1].firstName).toBe('Bob');\r | |
888 | expect(proxy.cache[2].firstName).toBe('Joe');\r | |
889 | expect(proxy.cache[3].firstName).toBe('Tim');\r | |
890 | expect(proxy.cache[4].firstName).toBe('Jim');\r | |
891 | });\r | |
892 | });\r | |
893 | \r | |
894 | it("should respect filters on the Operation", function() {\r | |
895 | var records;\r | |
896 | \r | |
897 | operation = new Ext.data.operation.Read({\r | |
898 | filters: [\r | |
899 | new Ext.util.Filter({\r | |
900 | property: 'lastName',\r | |
901 | value: 'Smith'\r | |
902 | }),\r | |
903 | new Ext.util.Filter({\r | |
904 | filterFn: function(record) {\r | |
905 | return record.get('age') < 40;\r | |
906 | }\r | |
907 | })\r | |
908 | ],\r | |
909 | callback: function(r) {\r | |
910 | records = r;\r | |
911 | }\r | |
912 | });\r | |
913 | \r | |
914 | proxy.read(operation);\r | |
915 | \r | |
916 | expect(records.length).toBe(2);\r | |
917 | expect(records[0].get('firstName')).toBe('Bob');\r | |
918 | expect(records[1].get('firstName')).toBe('Jim');\r | |
919 | });\r | |
920 | \r | |
921 | it("should respect start and limit on the Operation", function() {\r | |
922 | var records;\r | |
923 | \r | |
924 | operation = new Ext.data.operation.Read({\r | |
925 | start: 1,\r | |
926 | limit: 2,\r | |
927 | callback: function(r) {\r | |
928 | records = r;\r | |
929 | }\r | |
930 | });\r | |
931 | \r | |
932 | proxy.read(operation);\r | |
933 | \r | |
934 | expect(records.length).toBe(2);\r | |
935 | expect(records[0].get('firstName')).toBe('Joe');\r | |
936 | expect(records[1].get('firstName')).toBe('Tim');\r | |
937 | });\r | |
938 | \r | |
939 | it("should respect sorters on the Operation", function() {\r | |
940 | var records;\r | |
941 | \r | |
942 | operation = new Ext.data.operation.Read({\r | |
943 | sorters: [\r | |
944 | new Ext.util.Sorter({\r | |
945 | property: 'lastName',\r | |
946 | root: 'data'\r | |
947 | }),\r | |
948 | new Ext.util.Sorter({\r | |
949 | sorterFn: function(record1, record2) {\r | |
950 | return record1.get('age') - record2.get('age');\r | |
951 | }\r | |
952 | })\r | |
953 | ],\r | |
954 | callback: function(r) {\r | |
955 | records = r;\r | |
956 | }\r | |
957 | });\r | |
958 | \r | |
959 | proxy.read(operation);\r | |
960 | \r | |
961 | expect(records.length).toBe(4);\r | |
962 | expect(records[0].get('firstName')).toBe('Tim');\r | |
963 | expect(records[1].get('firstName')).toBe('Bob');\r | |
964 | expect(records[2].get('firstName')).toBe('Jim');\r | |
965 | expect(records[3].get('firstName')).toBe('Joe');\r | |
966 | });\r | |
967 | \r | |
968 | it("should apply sorters before filters", function() {\r | |
969 | var records;\r | |
970 | \r | |
971 | operation = new Ext.data.operation.Read({\r | |
972 | sorters: [\r | |
973 | new Ext.util.Sorter({\r | |
974 | property: 'lastName',\r | |
975 | root: 'data'\r | |
976 | }),\r | |
977 | new Ext.util.Sorter({\r | |
978 | sorterFn: function(record1, record2) {\r | |
979 | return record1.get('age') - record2.get('age');\r | |
980 | }\r | |
981 | })\r | |
982 | ],\r | |
983 | filters: [\r | |
984 | new Ext.util.Filter({\r | |
985 | property: 'lastName',\r | |
986 | value: 'Smith'\r | |
987 | }),\r | |
988 | new Ext.util.Filter({\r | |
989 | filterFn: function(record) {\r | |
990 | return record.get('age') < 40;\r | |
991 | }\r | |
992 | })\r | |
993 | ],\r | |
994 | callback: function(r) {\r | |
995 | records = r;\r | |
996 | }\r | |
997 | });\r | |
998 | \r | |
999 | proxy.read(operation);\r | |
1000 | \r | |
1001 | expect(records.length).toBe(2);\r | |
1002 | expect(records[0].get('firstName')).toBe('Bob');\r | |
1003 | expect(records[1].get('firstName')).toBe('Jim');\r | |
1004 | });\r | |
1005 | \r | |
1006 | it("should apply sorters before start and limit", function() {\r | |
1007 | var records;\r | |
1008 | \r | |
1009 | operation = new Ext.data.operation.Read({\r | |
1010 | sorters: [\r | |
1011 | new Ext.util.Sorter({\r | |
1012 | property: 'lastName',\r | |
1013 | root: 'data'\r | |
1014 | }),\r | |
1015 | new Ext.util.Sorter({\r | |
1016 | sorterFn: function(record1, record2) {\r | |
1017 | return record1.get('age') - record2.get('age');\r | |
1018 | }\r | |
1019 | })\r | |
1020 | ],\r | |
1021 | start: 1,\r | |
1022 | limit: 2,\r | |
1023 | callback: function(r) {\r | |
1024 | records = r;\r | |
1025 | }\r | |
1026 | });\r | |
1027 | \r | |
1028 | proxy.read(operation);\r | |
1029 | \r | |
1030 | expect(records.length).toBe(2);\r | |
1031 | expect(records[0].get('firstName')).toBe('Bob');\r | |
1032 | expect(records[1].get('firstName')).toBe('Jim');\r | |
1033 | });\r | |
1034 | });\r | |
1035 | \r | |
1036 | describe("the tree indicator flag is set", function() {\r | |
1037 | beforeEach(function() {\r | |
1038 | proxy = new spec.Storage({\r | |
1039 | model: spec.User,\r | |
1040 | id: 'tree-test'\r | |
1041 | });\r | |
1042 | \r | |
1043 | Ext.data.NodeInterface.decorate(spec.User);\r | |
1044 | \r | |
1045 | proxy.isHierarchical = true;\r | |
1046 | \r | |
1047 | operation = new Ext.data.operation.Read({\r | |
1048 | });\r | |
1049 | \r | |
1050 | });\r | |
1051 | it("should get tree data", function() {\r | |
1052 | spyOn(proxy, 'getTreeData').andReturn([new spec.User({id: 1, name: 'Phil'})]);\r | |
1053 | \r | |
1054 | proxy.read(operation);\r | |
1055 | \r | |
1056 | expect(proxy.getTreeData).toHaveBeenCalled();\r | |
1057 | });\r | |
1058 | });\r | |
1059 | \r | |
1060 | describe("getting tree data from the storage object", function() {\r | |
1061 | var records;\r | |
1062 | \r | |
1063 | beforeEach(function() {\r | |
1064 | proxy = new spec.Storage({\r | |
1065 | model: spec.User,\r | |
1066 | id: 'tree-test'\r | |
1067 | });\r | |
1068 | \r | |
1069 | Ext.data.NodeInterface.decorate(spec.User);\r | |
1070 | \r | |
1071 | // fake out some data in the storage object\r | |
1072 | fakeStorageObject.setItem('tree-test', '1,2,3,4,5,6');\r | |
1073 | fakeStorageObject.setItem('tree-test-tree', true);\r | |
1074 | fakeStorageObject.setItem('tree-test-counter', '6');\r | |
1075 | fakeStorageObject.setItem('tree-test-1', '{"name":"Phil","index":2,"leaf":true}');\r | |
1076 | fakeStorageObject.setItem('tree-test-2', '{"name":"Don","index":1,"leaf":false}');\r | |
1077 | fakeStorageObject.setItem('tree-test-3', '{"name":"Evan","parentId":2,"index":1,"leaf":true}');\r | |
1078 | fakeStorageObject.setItem('tree-test-4', '{"name":"Nige","parentId":2,"index":0,"leaf":false}');\r | |
1079 | fakeStorageObject.setItem('tree-test-5', '{"name":"Thomas","parentId":4,"index":0,"leaf":false}');\r | |
1080 | fakeStorageObject.setItem('tree-test-6', '{"name":"Brian","index":0,"leaf":false}');\r | |
1081 | });\r | |
1082 | it("should return an array of records", function() {\r | |
1083 | records = proxy.getTreeData();\r | |
1084 | \r | |
1085 | expect(Ext.isArray(records)).toBe(true);\r | |
1086 | });\r | |
1087 | \r | |
1088 | it("should return 3 records", function() {\r | |
1089 | records = proxy.getTreeData();\r | |
1090 | \r | |
1091 | expect(records.length).toBe(3);\r | |
1092 | });\r | |
1093 | \r | |
1094 | it("should have the correct root level nodes", function() {\r | |
1095 | records = proxy.getTreeData();\r | |
1096 | \r | |
1097 | expect(records[0].get('name')).toEqual('Phil');\r | |
1098 | expect(records[1].get('name')).toEqual('Don');\r | |
1099 | expect(records[2].get('name')).toEqual('Brian');\r | |
1100 | });\r | |
1101 | \r | |
1102 | it("should call getRecord with each record id", function() {\r | |
1103 | spyOn(proxy, 'getRecord').andCallThrough();\r | |
1104 | \r | |
1105 | proxy.getTreeData();\r | |
1106 | \r | |
1107 | expect(proxy.getRecord).toHaveBeenCalledWith(1);\r | |
1108 | expect(proxy.getRecord).toHaveBeenCalledWith(2);\r | |
1109 | expect(proxy.getRecord).toHaveBeenCalledWith(3);\r | |
1110 | expect(proxy.getRecord).toHaveBeenCalledWith(4);\r | |
1111 | expect(proxy.getRecord).toHaveBeenCalledWith(5);\r | |
1112 | expect(proxy.getRecord).toHaveBeenCalledWith(6);\r | |
1113 | });\r | |
1114 | \r | |
1115 | it("should convert the records into a heirarchical structure", function() {\r | |
1116 | records = proxy.getTreeData();\r | |
1117 | \r | |
1118 | expect(records[1].data.children[0].name).toEqual('Evan');\r | |
1119 | expect(records[1].data.children[1].name).toEqual('Nige');\r | |
1120 | expect(records[1].data.children[1].children[0].name).toEqual('Thomas');\r | |
1121 | });\r | |
1122 | \r | |
1123 | it("should cache the records", function() {\r | |
1124 | proxy.getTreeData();\r | |
1125 | \r | |
1126 | expect(proxy.cache[1].name).toEqual('Phil');\r | |
1127 | expect(proxy.cache[2].name).toEqual('Don');\r | |
1128 | expect(proxy.cache[3].name).toEqual('Evan');\r | |
1129 | expect(proxy.cache[4].name).toEqual('Nige');\r | |
1130 | expect(proxy.cache[5].name).toEqual('Thomas');\r | |
1131 | expect(proxy.cache[6].name).toEqual('Brian');\r | |
1132 | });\r | |
1133 | \r | |
1134 | it("should set loaded to true on non-leaf nodes that have no children", function() {\r | |
1135 | expect(records[2].isLoaded()).toBe(true);\r | |
1136 | expect(records[1].data.children[1].children[0].loaded).toBe(true);\r | |
1137 | });\r | |
1138 | });\r | |
1139 | \r | |
1140 | });\r | |
1141 | \r | |
1142 | describe("clearing", function() {\r | |
1143 | beforeEach(function() {\r | |
1144 | proxy = new spec.Storage({\r | |
1145 | model: spec.User,\r | |
1146 | id: 'clear-test'\r | |
1147 | });\r | |
1148 | \r | |
1149 | fakeStorageObject.setItem('clear-test', '1,2,3');\r | |
1150 | fakeStorageObject.setItem('clear-test-tree', true);\r | |
1151 | fakeStorageObject.setItem('clear-test-counter', '6');\r | |
1152 | fakeStorageObject.setItem('clear-test-1', '{"name":"Phil"}');\r | |
1153 | fakeStorageObject.setItem('clear-test-2', '{"name":"Thomas"}');\r | |
1154 | fakeStorageObject.setItem('clear-test-3', '{"name":"Don"}');\r | |
1155 | \r | |
1156 | proxy.clear();\r | |
1157 | });\r | |
1158 | \r | |
1159 | it("should remove all the records", function() {\r | |
1160 | expect(fakeStorageObject.getItem('clear-test-1')).toBeNull();\r | |
1161 | expect(fakeStorageObject.getItem('clear-test-2')).toBeNull();\r | |
1162 | expect(fakeStorageObject.getItem('clear-test-3')).toBeNull();\r | |
1163 | });\r | |
1164 | \r | |
1165 | it("should remove the record counter", function() {\r | |
1166 | expect(fakeStorageObject.getItem('clear-test-counter')).toBeNull();\r | |
1167 | });\r | |
1168 | \r | |
1169 | it("should remove the tree flag", function() {\r | |
1170 | expect(fakeStorageObject.getItem('clear-test-tree')).toBeNull();\r | |
1171 | });\r | |
1172 | \r | |
1173 | it("should remove the ids", function() {\r | |
1174 | expect(fakeStorageObject.getItem('clear-test')).toBeNull();\r | |
1175 | });\r | |
1176 | \r | |
1177 | it("should clear the cache", function() {\r | |
1178 | expect(proxy.cache).toEqual({});\r | |
1179 | });\r | |
1180 | });\r | |
1181 | });\r |