|  | define([ | 
        
          |  | 'postal', | 
        
          |  | 'app/shared/baseViewModel', | 
        
          |  | 'jquery', | 
        
          |  | 'app/customBindings/logger'], | 
        
          |  | function (postal, ViewModel, $, logger) { | 
        
          |  |  | 
        
          |  | logger(); | 
        
          |  |  | 
        
          |  | module('Base view model', { | 
        
          |  | setup: function () { | 
        
          |  | } | 
        
          |  | }); | 
        
          |  | test('should have an extend method', function () { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | name: 'TestViewModel', | 
        
          |  | foo: 'bar', | 
        
          |  | init: function () {} | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var inst = new TestViewModel(); | 
        
          |  | ok(inst.foo, 'Should have set the foo property'); | 
        
          |  | equal(typeof inst.init, 'function', 'Should have set the foo property'); | 
        
          |  | equal(inst.toString(), 'TestViewModel', 'Should return name of object'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('the view model should have default options', function () { | 
        
          |  | var DefaultViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | firstName: 'Tyson', | 
        
          |  | latName: 'Cadenhead', | 
        
          |  | interests: ['javascript', 'jquery', 'urmom'] | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var inst = new DefaultViewModel(); | 
        
          |  | equal(inst.firstName(), 'Tyson', 'Should have set tyson as the default first name'); | 
        
          |  | equal(inst.interests()[0], 'javascript', 'Should have set an array'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should fire an initialize method', function () { | 
        
          |  | var initCalled = false, | 
        
          |  | TestViewModel = ViewModel.extend({ | 
        
          |  | foo: 'bar', | 
        
          |  | initialize: function () { | 
        
          |  | initCalled = true; | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | new TestViewModel(); | 
        
          |  |  | 
        
          |  | ok(initCalled, 'The initialize method should be called'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should set up inheritance', function () { | 
        
          |  | var initCalled; | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | foo: 'bar', | 
        
          |  | initialize: function () { | 
        
          |  | initCalled = true; | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var InheritedViewModel = TestViewModel.extend({}); | 
        
          |  |  | 
        
          |  | ok(new InheritedViewModel().foo, "foo should be inherited from the base model"); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should set up templates', function () { | 
        
          |  | var dfd = new $.Deferred(); | 
        
          |  | expect(1); | 
        
          |  |  | 
        
          |  | sinon.stub(jQuery, 'ajax').returns(dfd.promise()); | 
        
          |  |  | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | templates: { | 
        
          |  | 'channel/foo': 'fooLoaded' | 
        
          |  | }, | 
        
          |  | fooLoaded: function (html) { | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var model = new TestViewModel(); | 
        
          |  | model.template('channel/foo'); | 
        
          |  |  | 
        
          |  | ok(jQuery.ajax.calledOnce, 'should call jQuery ajax'); | 
        
          |  |  | 
        
          |  | jQuery.ajax.restore(); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should cache templates', function () { | 
        
          |  | var dfd = new $.Deferred(); | 
        
          |  |  | 
        
          |  | sinon.stub(jQuery, 'ajax').returns(dfd.promise()); | 
        
          |  |  | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | templates: { | 
        
          |  | 'channel/foo': 'fooLoaded' | 
        
          |  | }, | 
        
          |  | fooLoaded: function (html) { | 
        
          |  | equal(html, 'something', 'should get cached result'); | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var model = new TestViewModel(); | 
        
          |  |  | 
        
          |  | var callback = sinon.spy(); | 
        
          |  | model.template('channel/foo', callback); | 
        
          |  |  | 
        
          |  | dfd.resolve('something'); | 
        
          |  |  | 
        
          |  | model.template('channel/foo'); | 
        
          |  |  | 
        
          |  | ok(callback.called, 'should have called the callback'); | 
        
          |  | ok(jQuery.ajax.calledOnce, 'should call jQuery ajax'); | 
        
          |  |  | 
        
          |  | jQuery.ajax.restore(); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should create ko.computed if a function is set', function () { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam', | 
        
          |  | foo: function () { | 
        
          |  | return this.bar(); | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | equal(typeof viewModel.foo, 'function', 'should create a function'); | 
        
          |  | equal(viewModel.foo(), 'bam', 'should set up correct context'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('should use options passed in creation to set observables', function () { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam' | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel({ | 
        
          |  | bar: 'boom' | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | equal(viewModel.bar(), 'boom', 'should set the value on the observable'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  |  | 
        
          |  | module('viewModel validation'); | 
        
          |  | test('when a viewModel has validation rules', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam' | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | required: true | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | viewModel.on('error', function(prop) { | 
        
          |  | ok(prop, 'it should trigger an error'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | viewModel.bar(''); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should have an isValid method'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has many validation rules', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 0 | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | required: true, | 
        
          |  | type: 'number' | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | viewModel.on('error', function(prop) { | 
        
          |  | ok(prop, 'it should trigger an error'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | viewModel.bar(42); | 
        
          |  |  | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has type boolean', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: true | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | type: 'boolean' | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has a greater than validation', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 60 | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | greaterThan: 50 | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  |  | 
        
          |  | viewModel.bar(40); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should not be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has a greater than equal validation', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 60 | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | greaterThanEqual: 60 | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  |  | 
        
          |  | viewModel.bar(40); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should not be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has a less than validation', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 20 | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | lessThan: 50 | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  |  | 
        
          |  | viewModel.bar(60); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should not be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has a less equal to than validation', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 50 | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | lessThanEqual: 50 | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  | ok(viewModel.isValid(), 'should be valid'); | 
        
          |  |  | 
        
          |  | viewModel.bar(60); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should not be valid'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel has custom validation rules', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam' | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | custom: function(value) { | 
        
          |  | equal(value, 'boom', 'should pass value to the custom validator'); | 
        
          |  | return value === 'foo' ? null : "An error"; | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | viewModel.on('error', function(prop) { | 
        
          |  | ok(prop, 'should trigger an error'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | viewModel.bar('boom'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when a viewModel disposes its validation', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam' | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | custom: function(value) { | 
        
          |  | equal(value, 'boom', 'should pass value to the custom validator'); | 
        
          |  | return value === 'foo' ? null : "An error"; | 
        
          |  | } | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | ok(viewModel._koSubscriptions, 'it should have a koSubscriptions member'); | 
        
          |  | equal(viewModel._koSubscriptions.length, 1, 'it should have added a new subscription'); | 
        
          |  |  | 
        
          |  | viewModel._resetValidation(); | 
        
          |  |  | 
        
          |  | equal(viewModel._koSubscriptions.length, 0, 'it should have removed subscriptions'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | test('when there are errors in a viewModel', function() { | 
        
          |  | var TestViewModel = ViewModel.extend({ | 
        
          |  | defaults: { | 
        
          |  | bar: 'bam' | 
        
          |  | }, | 
        
          |  | validation: { | 
        
          |  | bar: { | 
        
          |  | required: true | 
        
          |  | } | 
        
          |  | } | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | var viewModel = new TestViewModel(); | 
        
          |  |  | 
        
          |  | viewModel.on('error', function(prop) { | 
        
          |  | equal(prop.errors[0].message, 'This value is required'); | 
        
          |  | ok(prop, 'it should trigger an error'); | 
        
          |  | }); | 
        
          |  |  | 
        
          |  | viewModel.bar(''); | 
        
          |  |  | 
        
          |  | ok(!viewModel.isValid(), 'should have an isValid method'); | 
        
          |  |  | 
        
          |  | equal(viewModel.bar.errors()[0], 'This value is required'); | 
        
          |  | equal(viewModel.errors()[0], 'This value is required'); | 
        
          |  | }); | 
        
          |  | }); |