window.TodoList = { Models: {} }; TodoList.Models.Task = Backbone.Model.extend({ url: function() { if (this.isNew()) { return '/tasks.json'; } else { return '/tasks/' + this.getId() + '.json'; } }, toJSON: function() { return { task: this.attributes }; }, defaults: { name: '', complete: false }, getId: function() { return this.id; }, getName: function() { return this.get('name'); }, getComplete: function() { return this.get('complete'); } }); describe('TodoList.Models.Task', function() { it('should be defined', function() { expect(TodoList.Models.Task).toBeDefined(); }); it('can be instantiated', function() { var task = new TodoList.Models.Task(); expect(task).not.toBeNull(); }); beforeEach(function() { this.task = new TodoList.Models.Task(); }); describe('default values', function() { it('should have default value for the .name attribute', function() { expect(this.task.get('name')).toEqual(''); }); it('should have default value for the .complete attribute', function() { expect(this.task.get('complete')).toBeFalsy(); }); }); describe('getters', function() { describe('#getId', function() { it('should be defined', function() { expect(this.task.getId).toBeDefined(); }); it('returns undefined if id is not defined', function() { expect(this.task.getId()).toBeUndefined(); }); it("otherwise returns model's id", function() { this.task.id = 66; expect(this.task.getId()).toEqual(66); }); }); describe('#getName', function() { it('should be defined', function() { expect(this.task.getName).toBeDefined(); }); it('returns value for the name attribute', function() { var stub = sinon.stub(this.task, 'get').returns('Task name'); expect(this.task.getName()).toEqual('Task name'); expect(stub.calledWith('name')).toBeTruthy(); }); }); describe('#getComplete', function() { it('should be defined', function() { expect(this.task.getComplete).toBeDefined(); }); it('returns value for the complete attribute', function() { var stub = sinon.stub(this.task, 'get').returns(false); expect(this.task.getComplete()).toBeFalsy(); expect(stub.calledWith('complete')).toBeTruthy(); }); }); }); describe('#toJSON', function() { it("return all model's attributes wrapped in task attbite", function() { this.task.set({ name: 'Buy a milk', complete: true }); var params = this.task.toJSON(); expect(params.task).toBeDefined(); expect(params.task.name).toEqual('Buy a milk'); expect(params.task.complete).toBeTruthy(); }); }); describe('#save', function() { beforeEach(function() { this.server = sinon.fakeServer.create(); }); afterEach(function() { this.server.restore(); }); it('sends valid data to the server', function() { this.task.save({ name: 'A new task to do' }); var request = this.server.requests[0]; var params = JSON.parse(request.requestBody); expect(params.task).toBeDefined(); expect(params.task.name).toEqual('A new task to do'); expect(params.task.complete).toBeFalsy(); }); describe('request', function() { describe('on create', function() { beforeEach(function() { this.task.id = null; this.task.save(); this.request = this.server.requests[0]; }); it('should be POST', function() { expect(this.request.method).toEqual('POST'); }); it('should be async', function() { expect(this.request.async).toBeTruthy(); }); it('should have valid url', function() { expect(this.request.url).toEqual('/tasks.json'); }); }); describe('on update', function() { beforeEach(function() { this.task.id = 66; this.task.save(); this.request = this.server.requests[0]; }); it('should be PUT', function() { expect(this.request.method).toEqual('PUT'); }); it('should be async', function() { expect(this.request.async).toBeTruthy(); }); it('should have valid url', function() { expect(this.request.url).toEqual('/tasks/66.json'); }); }); }); }); }); execJasmine();