//product.model.js (function () { 'use strict'; angular .module('conta') .factory('Product', ProductModel); /** * @ngdoc factory * @name ProductModel */ function ProductModel() { /** * Defaults */ var defaults = { taxRate: 15 }; /** * Product Constructor. * * @param {Object} properties * @constructor */ function Product(properties) { // should set model on the product if (properties) { angular.forEach(properties, function (value, key) { this[key] = value; }, this); } } /** * Public */ angular.extend(Product.prototype, { getPriceIncVat: getPriceIncVat, setTaxRate: setTaxRate, taxRate: defaults.taxRate }); /** * Return constructor */ return Product; /** * Get price incl. vat. * * @returns {Number} */ function getPriceIncVat() { return Number.parseFloat((this.price + (this.price * this.taxRate / 100)).toFixed(2)); } /** * Set taxRate * * @param {Number} newTaxRate * @returns {Number} newTaxRate */ function setTaxRate(newTaxRate) { this.taxRate = Number.parseFloat((newTaxRate).toFixed(3)); return this.taxRate; } } }()); //product.model.spec.js describe('Model: Product', function () { var product, model, Product; beforeEach(function () { module('conta'); inject(function ($injector) { Product = $injector.get('Product'); }); model = { name: 'Beer', taxRate: 8.975, price: 19.99 }; product = new Product(model); }); it('should be an instance of Product', function () { expect(product instanceof Product).toBeTruthy(); }); describe('on initialization', function () { it('should set default values on an empty product', function () { product = new Product(); expect(product.taxRate).toBe(15); }); it('should set model on the product', function () { expect(product.name).toBe('Beer'); expect(product.price).toBe(19.99); expect(product.taxRate).toBe(8.975); }); it('should override any default values', function () { model = {taxRate: 55}; product = new Product(model); expect(product.taxRate).toBe(55); }); it('should set default values on the product if they are missing', function () { model = {name: 'Beer'}; product = new Product(model); expect(product.name).toBe(model.name); expect(product.taxRate).toBe(15); }); describe('filed "taxRate" should be', function () { it('a number or higher than 0 and lower than 100', function () { product = new Product(); product.setTaxRate(12.33); expect(product.taxRate).toEqual(jasmine.any(Number)); expect(product.taxRate).toBeGreaterThan(0); expect(product.taxRate).not.toBeGreaterThan(100); }); it('maximum with three decimals', function () { product.setTaxRate(7.12345678); expect(product.taxRate).toBe(7.123); }); }); }); describe('getPriceIncVat()', function () { it('should return the price incl. VAT with two decimals', function () { expect(product.getPriceIncVat()).toBe(21.78); }); }); });