UNPKG

extjs-gpl

Version:

GPL licensed version of Sencha Ext JS

1,203 lines (1,015 loc) 215 kB
describe("Ext.data.Session", function() { function completeRequest(data, requestId) { Ext.Ajax.mockComplete({ status: 200, responseText: Ext.encode(data) }, requestId); } var session; function idSort(a, b) { if (Ext.isObject(a)) { a = a.id; b = b.id; } return a - b; } var adminGroup, peonGroup; var rufusGroups, billGroups, tedGroups; var adminUsers, peonUsers; var userRufus, userBill, userTed; function getAndComplete(type, id, theSession, data) { theSession = theSession || session; data = data || {}; var rec = theSession.getRecord(type, id); data.id = data.id || id; completeRequest(data); return rec; } beforeEach(function() { MockAjaxManager.addMethods(); adminGroup = { id: 42, name: 'Admins' }; peonGroup = { id: 427, name: 'Peons' }; userRufus = { id: 10, name: 'Rufus' }; userBill = { id: 20, name: 'Bill' }; userTed = { id: 30, name: 'Ted' }; rufusGroups = [ adminGroup, peonGroup ]; billGroups = [ peonGroup ]; tedGroups = [ peonGroup ]; adminUsers = [ userRufus ]; peonUsers = [ userBill, userTed, userRufus ]; }); afterEach(function() { MockAjaxManager.removeMethods(); session = Ext.destroy(session); }); describe("record access", function() { var User, parent, rec; beforeEach(function() { Ext.data.Model.schema.setNamespace('spec'); User = Ext.define('spec.User', { extend: 'Ext.data.Model', fields: ['name', { name: 'addressId', reference: 'Address', unique: true }], manyToMany: 'Group' }); parent = new Ext.data.Session(); session = new Ext.data.Session(); }); afterEach(function() { parent.destroy(); User = rec = parent = null; Ext.undefine('spec.User'); Ext.data.Model.schema.clear(true); }); describe("adopt", function() { it("should cache the record into the session", function() { rec = new User({ id: 1 }); session.adopt(rec); expect(session.peekRecord('User', 1)).toBe(rec); }); it("should put the session on the record", function() { rec = new User({ id: 1 }); session.adopt(rec); expect(rec.session).toBe(session); }); it("should not throw an error if a record already in the session is adopted", function() { rec = getAndComplete('User', 1); expect(function() { session.adopt(rec); }).not.toThrow(); }); describe("invalid conditions", function() { it("should not allow a record attached to another session", function() { var other = new Ext.data.Session(), rec = getAndComplete('User', 1, other); expect(function() { session.adopt(rec); }).toThrow(); other.destroy(); }); it("should raise an error if add a model the schema does not know about", function() { var customSchema = new Ext.data.schema.Schema(); Ext.define('spec.CustomModel', { extend: 'Ext.data.Model', schema: customSchema }); rec = new spec.CustomModel({ id: 1 }); expect(function() { session.adopt(rec); }).toThrow(); }); it("should raise an error if adding an existing record", function() { rec = getAndComplete('User', 1); expect(function() { session.adopt(new User({ id: 1 })); }).toThrow(); }); }); describe("associations", function() { describe("many to one", function() { var user; beforeEach(function() { Ext.define('spec.Post', { extend: 'Ext.data.Model', fields: ['content', { name: 'userId', reference: 'User' }] }); }); afterEach(function() { Ext.undefine('spec.Post'); user = null; }); function makeUser(id) { user = new User({ id: id }); } describe("the many", function() { it("should not attempt to load the owner", function() { var post = new spec.Post({ id: 101, userId: 1 }); var spy = spyOn(User.getProxy(), 'read'); session.adopt(post); expect(spy).not.toHaveBeenCalled(); }); it("should also adopt the owner", function() { var post = new spec.Post({ id: 101, userId: 1 }); makeUser(1); post.setUser(user); session.adopt(post); expect(user.session).toBe(session); }); }); describe("the one", function() { it("should not load the store", function() { makeUser(1); user.posts(); var spy = spyOn(User.getProxy(), 'read'); session.adopt(user); expect(spy).not.toHaveBeenCalled(); }); it("should set the session onto the store", function() { makeUser(1); var posts = user.posts(); session.adopt(user); expect(posts.getSession()).toBe(session); }); it("should adopt existing children", function() { makeUser(1); var posts = user.posts(); posts.add({id: 101}, {id: 102}, {id: 103}); session.adopt(user); expect(posts.getAt(0).session).toBe(session); expect(posts.getAt(1).session).toBe(session); expect(posts.getAt(2).session).toBe(session); }); it("should adopt any newly loaded items after adopting", function() { makeUser(1); var posts = user.posts(); session.adopt(user); posts.load(); completeRequest([{id: 101, userId: 1}, {id: 102, userId: 1}, {id: 103, userId: 1}]); expect(posts.getAt(0).session).toBe(session); expect(posts.getAt(1).session).toBe(session); expect(posts.getAt(2).session).toBe(session); }); }); }); describe("one to one", function() { beforeEach(function() { Ext.define('spec.Address', { extend: 'Ext.data.Model', fields: ['city'] }); }); afterEach(function() { Ext.undefine('spec.Address'); }); describe("the key holder", function() { it("should not attempt to load the non key holder", function() { var user = new User({ id: 1, addressId: 101 }); var spy = spyOn(spec.Address.getProxy(), 'read'); session.adopt(user); expect(spy).not.toHaveBeenCalled(); }); it("should adopt the non key holder", function() { var address = new spec.Address({ id: 101 }); var user = new User({ id: 1 }); user.setAddress(address); session.adopt(user); expect(address.session).toBe(session); }); }); describe("the non key holder", function() { it("should not attempt to load the key holder", function() { var address = new spec.Address({ id: 101 }); var spy = spyOn(User.getProxy(), 'read'); session.adopt(address); expect(spy).not.toHaveBeenCalled(); }); it("should also adopt the key holder", function() { var address = new spec.Address({ id: 101 }); var user = new User({ id: 1 }); address.setUser(user); session.adopt(address); expect(user.session).toBe(session); }); }); }); describe("many to many", function() { var Group; beforeEach(function() { Group = Ext.define('spec.Group', { extend: 'Ext.data.Model', fields: ['name'] }); }); afterEach(function() { Ext.undefine('spec.Group'); Group = null; }); describe("the left", function() { it("should not load the store", function() { var group = new Group({id: 1}); group.users(); var spy = spyOn(Group.getProxy(), 'read'); session.adopt(group); expect(spy).not.toHaveBeenCalled(); }); it("should set the session onto the store", function() { var group = new Group({id: 1}), users = group.users(); session.adopt(group); expect(users.getSession()).toBe(session); }); it("should adopt existing children", function() { var group = new Group({id: 1}), users = group.users(); users.add({id: 101}, {id: 102}, {id: 103}); session.adopt(group); expect(users.getAt(0).session).toBe(session); expect(users.getAt(1).session).toBe(session); expect(users.getAt(2).session).toBe(session); }); it("should adopt any newly loaded items after adopting", function() { var group = new Group({id: 1}), users = group.users(); session.adopt(group); users.load(); completeRequest([{id: 101}, {id: 102}, {id: 103}]); expect(users.getAt(0).session).toBe(session); expect(users.getAt(1).session).toBe(session); expect(users.getAt(2).session).toBe(session); }); }); describe("the right", function() { it("should not load the store", function() { var user = new User({id: 1}); user.groups(); var spy = spyOn(Group.getProxy(), 'read'); session.adopt(user); expect(spy).not.toHaveBeenCalled(); }); it("should set the session onto the store", function() { var user = new User({id: 1}), groups = user.groups(); session.adopt(user); expect(groups.getSession()).toBe(session); }); it("should adopt existing children", function() { var user = new User({id: 1}), groups = user.groups(); groups.add({id: 101}, {id: 102}, {id: 103}); session.adopt(user); expect(groups.getAt(0).session).toBe(session); expect(groups.getAt(1).session).toBe(session); expect(groups.getAt(2).session).toBe(session); }); it("should adopt any newly loaded items after adopting", function() { var user = new User({id: 1}), groups = user.groups(); session.adopt(user); groups.load(); completeRequest([{id: 101}, {id: 102}, {id: 103}]); expect(groups.getAt(0).session).toBe(session); expect(groups.getAt(1).session).toBe(session); expect(groups.getAt(2).session).toBe(session); }); }); }); describe("nested", function() { beforeEach(function() { Ext.define('spec.Order', { extend: 'Ext.data.Model', fields: [{ name: 'userId', reference: 'User' }, { name: 'addressId', reference: 'Address', unique: true }] }); Ext.define('spec.OrderItem', { extend: 'Ext.data.Model', fields: [{ name: 'orderId', reference: 'Order' }] }); Ext.define('spec.Address', { extend: 'Ext.data.Model', fields: ['city'] }); }); afterEach(function() { Ext.undefine('spec.Address'); Ext.undefine('spec.OrderItem'); Ext.undefine('spec.Order'); }); it("should adopt data deeply", function() { var user = User.load(1); completeRequest({ id: 1, orders: [{ id: 101, userId: 1, address: { id: 201 }, orderItems: [{ id: 301, orderId: 101 }, { id: 302, orderId: 101 }] }, { id: 102, userId: 1, address: { id: 202 }, orderItems: [{ id: 303, orderId: 102 }, { id: 304, orderId: 102 }] }] }); session.adopt(user); var order = user.orders().getAt(0); expect(order.session).toBe(session); expect(order.getAddress().session).toBe(session); expect(order.orderItems().getAt(0).session).toBe(session); expect(order.orderItems().getAt(1).session).toBe(session); order = user.orders().getAt(1); expect(order.session).toBe(session); expect(order.getAddress().session).toBe(session); expect(order.orderItems().getAt(0).session).toBe(session); expect(order.orderItems().getAt(1).session).toBe(session); }); }); }); }); describe("createRecord", function() { it("should accept the entity name", function() { rec = session.createRecord('User', { name: 'Foo' }); expect(rec.$className).toBe('spec.User'); expect(rec.get('name')).toBe('Foo'); }); it("should accept the entity class", function() { rec = session.createRecord(spec.User, { name: 'Foo' }); expect(rec.$className).toBe('spec.User'); expect(rec.get('name')).toBe('Foo'); }); it("should throw an exception with an unrecognized model name", function() { expect(function() { session.createRecord('Luser', {}); }).toThrow(); }); it("should throw an exception creating an anonymous model", function() { var Model = Ext.define(null, { extend: 'Ext.data.Model', fields: ['name'] }); expect(function() { session.createRecord(Model, {}); }).toThrow(); }); it("should cache the record in the session", function() { rec = session.createRecord('User', { }); expect(session.getRecord('User', rec.getId())).toBe(rec); }); it("should set the session on the instance", function() { rec = session.createRecord('User', { }); expect(rec.session).toBe(session); }); it("should throw an exception if the record exists in the session", function() { getAndComplete('User', 1); expect(function() { rec = session.createRecord('User', { id: 1 }).toThrow(); }); }); it("should be able to create a phantom with no data", function() { var rec; expect(function() { rec = session.createRecord('User'); }).not.toThrow(); expect(rec.phantom).toBe(true); }); it("should become dirty", function() { rec = session.createRecord('User', { name: 'Foo' }); expect(session.isDirty()).toBe(true); }); describe("with a parent", function() { beforeEach(function() { session.setParent(parent); }); it("should not create the record in the parent session", function() { getAndComplete('User', 1); expect(parent.peekRecord('User', 1)).toBeNull(); }); it("should raise an exception if the record exists in the parent", function() { getAndComplete('User', 1, parent); expect(function() { session.createRecord('User', { id: 1 }); }).toThrow(); }); it("should be able to create a phantom with no data", function() { var rec; expect(function() { rec = session.createRecord('User'); }).not.toThrow(); expect(rec.phantom).toBe(true); }); }); }); describe("getRecord", function() { it("should throw an exception with an unrecognized model name", function() { expect(function() { session.getRecord('Luser', 1); }).toThrow(); }); it("should throw an exception creating an anonymous model", function() { var Model = Ext.define(null, { extend: 'Ext.data.Model', fields: ['name'] }); expect(function() { session.getRecord(Model, 1); }).toThrow(); }); describe("with no record", function() { it("should accept the entity name", function() { rec = session.getRecord('User', 1); expect(rec.getId()).toBe(1); expect(rec.$className).toBe('spec.User'); }); it("should accept the entity class", function() { rec = session.getRecord(spec.User, 1); expect(rec.getId()).toBe(1); expect(rec.$className).toBe('spec.User'); }); it("should accept an existing record and adopt it", function() { rec = new spec.User({ id: 1 }); expect(session.getRecord(rec)).toBe(rec); expect(rec.session).toBe(session); }); it("should create a new record and track it in the session", function() { rec = session.getRecord('User', 1); expect(session.peekRecord('User', 1)).toBe(rec); }); it("should set the session on the record", function() { rec = session.getRecord('User', 1); expect(rec.session).toBe(session); }); describe("autoLoad", function() { it("should autoLoad by default", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord('User', 1); expect(spy).toHaveBeenCalled(); }); it("should not autoLoad when passed: false", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord('User', 1, false); expect(spy).not.toHaveBeenCalled(); }); it("should pass parameters to load", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord('User', 1, { params: { someId: 1 } }); expect(spy.mostRecentCall.args[0].getParams()).toEqual({ someId: 1 }); }); }); describe("with parent session", function() { beforeEach(function() { session.setParent(parent); }); describe("record exists in the parent", function() { beforeEach(function() { rec = getAndComplete('User', 1, parent, {name: 'Foo'}); }); describe("with type/id", function() { it("should return an existing record from the parent", function() { var child = session.getRecord('User', 1); expect(child.get('name')).toBe('Foo'); expect(child.$className).toBe('spec.User'); }); it("should return a copy, not the same instance", function() { var child = session.getRecord('User', 1); expect(child).not.toBe(rec); }); it("should set the session to be the child session", function() { var child = session.getRecord('User', 1); expect(child.session).toBe(session); }); it("should not trigger a load", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord('User', 1); expect(spy).not.toHaveBeenCalled(); }); it("should not update the parent record when the child changes", function() { var child = session.getRecord('User', 1); child.set('name', 'Bar'); expect(rec.get('name')).toBe('Foo'); }); it("should not update the child record when the parent changes", function() { var child = session.getRecord('User', 1); rec.set('name', 'Bar'); expect(child.get('name')).toBe('Foo'); }); it("should not copy the record if the parent is loading", function() { rec = parent.getRecord('User', 2); var child = session.getRecord('User', 2); completeRequest({name: 'Foo'}); expect(rec.get('name')).toBe('Foo'); expect(child.isLoading()).toBe(true); expect(child.get('name')).toBeUndefined(); }); }); describe("with parent instance", function() { it("should return an existing record from the parent", function() { var child = session.getRecord(rec); expect(child.get('name')).toBe('Foo'); expect(child.$className).toBe('spec.User'); }); it("should return a copy, not the same instance", function() { var child = session.getRecord(rec); expect(child).not.toBe(rec); }); it("should set the session to be the child session", function() { var child = session.getRecord(rec); expect(child.session).toBe(session); }); it("should not trigger a load", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord(rec); expect(spy).not.toHaveBeenCalled(); }); it("should not update the parent record when the child changes", function() { var child = session.getRecord(rec); child.set('name', 'Bar'); expect(rec.get('name')).toBe('Foo'); }); it("should not update the child record when the parent changes", function() { var child = session.getRecord(rec); rec.set('name', 'Bar'); expect(child.get('name')).toBe('Foo'); }); it("should not copy the record if the parent is loading", function() { rec = parent.getRecord('User', 2); var child = session.getRecord(rec); completeRequest({name: 'Foo'}); expect(rec.get('name')).toBe('Foo'); expect(child.isLoading()).toBe(true); expect(child.get('name')).toBeUndefined(); }); }); }); describe("record does not exist in the parent", function() { describe("with type/id", function() { it("should create an instance", function() { rec = session.getRecord('User', 1); expect(rec.getId()).toBe(1); expect(rec.$className).toBe('spec.User'); }); it("not push the instance into the parent", function() { session.getRecord('User', 1); expect(parent.peekRecord('User', 1)).toBeNull(); }); }); describe("with an instance", function() { it("should use the passed instance", function() { rec = new spec.User({id: 1}); expect(session.getRecord(rec)).toBe(rec); expect(rec.session).toBe(session); }); it("not push the instance into the parent", function() { rec = new spec.User({id: 1}); session.getRecord(rec); expect(parent.peekRecord('User', 1)).toBeNull(); }); }); }); }); }); describe("with an existing record", function() { beforeEach(function() { rec = getAndComplete('User', 1); }); it("should accept the entity name", function() { expect(session.getRecord('User', 1)).toBe(rec); }); it("should accept the entity class", function() { expect(session.getRecord(spec.User, 1)).toBe(rec); }); it("should return the same instance", function() { expect(session.getRecord(rec)).toBe(rec); }); it("should return the existing record", function() { expect(session.getRecord('User', 1)).toBe(rec); }); it("should not attempt to load the record", function() { var spy = spyOn(spec.User.getProxy(), 'read'); session.getRecord('User', 1); expect(spy).not.toHaveBeenCalled(); }); }); }); describe("peekRecord", function() { beforeEach(function() { rec = getAndComplete('User', 1); }); it("should accept the entity name", function() { expect(session.peekRecord('User', 1)).toBe(rec); }); it("should accept the entity class", function() { expect(session.peekRecord(spec.User, 1)).toBe(rec); }); it("should throw an exception with an unrecognized model name", function() { expect(function() { session.peekRecord('Luser', 1); }).toThrow(); }); it("should throw an exception creating an anonymous model", function() { var Model = Ext.define(null, { extend: 'Ext.data.Model', fields: ['name'] }); expect(function() { session.peekRecord(Model, 1); }).toThrow(); }); it("should return the model instance", function() { var result = session.peekRecord('User', 1); expect(result.isModel).toBe(true); expect(result).toBe(rec); }); it("should return null if the record does not exist", function() { expect(session.peekRecord('User', 12)).toBeNull(); }); describe("parent", function() { it("should not return a record from a parent without deep=true", function() { session.setParent(parent); getAndComplete('User', 2, parent); expect(session.peekRecord('User', 2)).toBeNull(); }); it("should find a record in the parent session if we pass deep=true", function() { session.setParent(parent); rec = getAndComplete('User', 2, parent); expect(session.peekRecord('User', 2, true)).toBe(rec); }); it("should favour a record in the child", function() { session.setParent(parent); getAndComplete('User', 2, parent); rec = session.getRecord('User', 2); expect(session.peekRecord('User', 2, true)).toBe(rec); }); it("should not consider a parent if we pass deep=true and there is no parent", function() { expect(session.peekRecord('User', 1000, true)).toBeNull(); }); }); }); describe("associations", function() { describe("many to one", function() { beforeEach(function() { Ext.define('spec.Post', { extend: 'Ext.data.Model', fields: ['content', { name: 'userId', reference: 'User' }] }); }); function makePost(id, userId, data) { data = data || {}; data.id = id; data.userId = userId; return getAndComplete('Post', id, session, data); } function makeUser(id, data) { data = data || {}; data.id = id; return getAndComplete('User', id, session, data); } afterEach(function() { Ext.undefine('spec.Post'); }); describe("the one", function() { it("should use an existing record instance from the session", function() { var user = makeUser(1), post = makePost(17, 1); expect(post.getUser()).toBe(user); }); it("should not trigger a load when the record instance exists", function() { var user = makeUser(1), post = makePost(17, 1), spy = spyOn(spec.User.getProxy(), 'read'); post.getUser(); expect(spy).not.toHaveBeenCalled(); }); it("should request an instance it needs and put it in the session", function() { var post = makePost(17, 1), user = post.getUser(); completeRequest({ id: 1 }); expect(session.getRecord('User', 1)).toBe(user); }); }); describe("the many", function() { var user; beforeEach(function() { user = makeUser(1); }); afterEach(function() { user = null; }); it("should be empty by default and not complete", function() { var posts = user.posts(); expect(posts.getCount()).toBe(0); expect(posts.complete).toBe(false); }); it("should not trigger a load", function() { var spy = spyOn(spec.Post.getProxy(), 'read'); user.posts(); expect(spy).not.toHaveBeenCalled(); }); it("should create records on loading", function() { var posts = user.posts(); posts.load(); completeRequest([{id: 101, userId: 1}, {id: 102, userId: 1}, {id: 103, userId: 1}]); expect(posts.getAt(0)).toBe(session.peekRecord('Post', 101)); expect(posts.getAt(1)).toBe(session.peekRecord('Post', 102)); expect(posts.getAt(2)).toBe(session.peekRecord('Post', 103)); }); it("should set the complete flag on loading", function() { var posts = user.posts(); posts.load(); completeRequest([]); expect(posts.complete).toBe(true); }); describe("local modifications", function() { it("should add items with a matching foreign key on creation, but not be complete", function() { // post1 & post3 exist in the session with a matching FK, as soon as the // store is spun up they should exist in the store var post1 = makePost(101, 1), post3 = makePost(103, 1), posts = user.posts(); expect(posts.getCount()).toBe(2); expect(posts.getAt(0)).toBe(post1); expect(posts.getAt(1)).toBe(post3); expect(posts.complete).toBe(false); }); it("should respect the server order when loading with existing items", function() { // Although we have the records, maintain the order the server sent. var post1 = makePost(101, 1), post2 = makePost(102, 1), post3 = makePost(103, 1), posts = user.posts(); posts.load(); completeRequest([{id: 103, userId: 1}, {id: 102, userId: 1}, {id: 101, userId: 1}]); expect(posts.getAt(0)).toBe(post3); expect(posts.getAt(1)).toBe(post2); expect(posts.getAt(2)).toBe(post1); }); it("should add matching FK items to the end when loading", function() { // We have a record with a matching key before the store is created. // Once we load the store we should include it in the active set var post2 = makePost(102, 1), posts = user.posts(); posts.load(); completeRequest([{id: 103, userId: 1}, {id: 101, userId: 1}]); expect(posts.getAt(0)).toBe(session.peekRecord('Post', 103)); expect(posts.getAt(1)).toBe(session.peekRecord('Post', 101)); expect(posts.getAt(2)).toBe(session.peekRecord('Post', 102)); }); it("should remove no-longer matching FK items when loading", function() { // We had a record with a matching key which was subsequently changed. // Reject it from the server load since the local copy is correct. var post2 = makePost(102, 1); post2.set('userId', null); var posts = user.posts(); posts.load(); completeRequest([{id: 101, userId: 1}, {id: 102, userId: 1}, {id: 103, userId: 1}]); expect(posts.getCount()).toBe(2); expect(posts.getAt(0)).toBe(session.peekRecord('Post', 101)); expect(posts.getAt(1)).toBe(session.peekRecord('Post', 103)); }); }); }); }); describe("one to one", function() { beforeEach(function() { Ext.define('spec.Address', { extend: 'Ext.data.Model', fields: ['city'] }); }); function makeAddress(id, data) { data = data || {}; data.id = id; return getAndComplete('Address', id, session, data); } function makeUser(id, addressId, data) { data = data || {}; data.id = id; data.addressId = addressId; return getAndComplete('User', id, session, data); } afterEach(function() { Ext.undefine('spec.Address'); }); describe("the key holder", function() { it("should use an existing record instance from the session", function() { var address = makeAddress(1), user = makeUser(17, 1); expect(user.getAddress()).toBe(address); }); it("should not trigger a load when the record instance exists", function() { var address = makeAddress(1), user = makeUser(17, 1), spy = spyOn(spec.User.getProxy(), 'read'); user.getAddress(); expect(spy).not.toHaveBeenCalled(); }); it("should request an instance it needs and put it in the session", function() { var user = makeUser(17, 1), address = user.getAddress(); completeRequest({ id: 1 }); expect(session.getRecord('Address', 1)).toBe(address); }); }); }); describe("many to many", function() { beforeEach(function() { Ext.define('spec.Group', { extend: 'Ext.data.Model', fields: ['name'] }); }); function makeUser(id) { return getAndComplete('User', id, session); } function makeGroup(id) { return getAndComplete('Group', id, session); } afterEach(function() { Ext.undefine('spec.Group'); }); describe("the left", function() { var user; beforeEach(function() { user = makeUser(1); }); afterEach(function() { user = null; }); it("should be empty by default and not complete", function() { var groups = user.groups(); expect(groups.getCount()).toBe(0); expect(groups.complete).toBe(false); }); it("should not trigger a load", function() { var spy = spyOn(spec.Group.getProxy(), 'read'); user.groups(); expect(spy).not.toHaveBeenCalled(); }); it("should create records on loading", function() { var groups = user.groups(); groups.load(); completeRequest([{id: 101}, {id: 102}, {id: 103}]); expect(groups.getAt(0)).toBe(session.peekRecord('Group', 101)); expect(groups.getAt(1)).toBe(session.peekRecord('Group', 102)); expect(groups.getAt(2)).toBe(session.peekRecord('Group', 103)); }); it("should set the complete flag on loading", function() { var groups = user.groups(); groups.load(); completeRequest([]); expect(groups.complete).toBe(true); }); describe("local modifications", function() { it("should respect the load order when loading with existing items", function() { var group2 = makeGroup(102), groups = user.groups(); groups.add(group2); groups.load(); completeRequest([{id: 103}, {id: 102}, {id: 101}]); expect(groups.getAt(0)).toBe(session.peekRecord('Group', 103)); expect(groups.getAt(1)).toBe(group2); expect(groups.getAt(2)).toBe(session.peekRecord('Group', 101)); }); it("should add matching FK items to the end when loading", function() { var group2 = makeGroup(102), groups = user.groups(); groups.add(group2); groups.load(); completeRequest([{id: 103}, {id: 101}]); expect(groups.getAt(0)).toBe(session.peekRecord('Group', 103)); expect(groups.getAt(1)).toBe(session.peekRecord('Group', 101)); expect(groups.getAt(2)).toBe(group2); }); }); }); describe("the right", function() { var group; beforeEach(function() { group = makeGroup(1); }); afterEach(function() { group = null; }); it("should be empty by default and not complete", function() { var users = group.users(); expect(users.getCount()