diff --git a/lib/app.js b/lib/app.js index 2761143..b1d91d3 100644 --- a/lib/app.js +++ b/lib/app.js @@ -25,7 +25,7 @@ app.dynamicHelpers({ }); app.configure(function(){ - app.use(express.logger('dev')); + // app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); app.use(express.cookieParser()); diff --git a/lib/entities/activity.js b/lib/entities/activity.js index 095eb0b..d436f04 100644 --- a/lib/entities/activity.js +++ b/lib/entities/activity.js @@ -19,7 +19,7 @@ var activitySchema = new Schema({ }); activitySchema.methods.addPerformedWork = function(date, hours) { - var i = 0; + var i = 0, length; for (i = 0, length = this.performedWork.length; i= 0.10.2", + "should" : ">= 0.5.1", "request" : ">= 2.1.0" } } diff --git a/spec/db/mongoose_helper.js b/spec/db/mongoose_helper.js deleted file mode 100644 index fddb9ef..0000000 --- a/spec/db/mongoose_helper.js +++ /dev/null @@ -1,25 +0,0 @@ -beforeEach(function() { - this.addMatchers((function() { - var toHaveValidationErrorFor = function(err, validatorName, propertyName) { - if (!err) { return false; } - if (err.name !== 'ValidationError') { return false; } - var value = err.errors[propertyName]; - if (!value) { return false; } - return (value.message === 'Validator "' + validatorName + '" failed for path ' + propertyName); - }; - - return { - toHaveRequiredValidationErrorFor : function(propertyName) { - return toHaveValidationErrorFor(this.actual, 'required', propertyName); - }, - - toHaveMaxValidationErrorFor: function(propertyName) { - return toHaveValidationErrorFor(this.actual, 'max', propertyName); - }, - - toHaveMinValidationErrorFor: function(propertyName) { - return toHaveValidationErrorFor(this.actual, 'min', propertyName); - } - }; - }())); -}); \ No newline at end of file diff --git a/spec/helper_functions.js b/spec/helper_functions.js deleted file mode 100644 index 054451e..0000000 --- a/spec/helper_functions.js +++ /dev/null @@ -1,78 +0,0 @@ -module.exports = { - addressesShouldBeEqual: function(address1, address2) { - if (address1 === null && address2 === null) { return; } - if (address1 !== null) { expect(address2).not.toBeNull(); } - if (address2 !== null) { expect(address1).not.toBeNull(); } - expect(address1.street).toEqual(address2.street); - expect(address1.city).toEqual(address2.city); - expect(address1.postalCode).toEqual(address2.postalCode); - expect(address1.country).toEqual(address2.country); - }, - - contactsShouldBeEqual: function(contact1, contact2) { - if (contact1 === null && contact2 === null) { return; } - if (contact1 !== null) { expect(contact2).not.toBeNull(); } - if (contact2 !== null) { expect(contact1).not.toBeNull(); } - expect(contact1.name).toEqual(contact2.name); - expect(contact1.email).toEqual(contact2.email); - }, - - customersShouldBeEqual: function(customer1, customer2) { - expect(customer1.name).toEqual(customer2.name); - expect(customer1.vatNumber).toEqual(customer2.vatNumber); - expect(customer1.phoneNumber).toEqual(customer2.phoneNumber); - expect(customer1.includeContactOnInvoice).toEqual(customer2.includeContactOnInvoice); - this.addressesShouldBeEqual(customer1.address, customer2.address); - this.contactsShouldBeEqual(customer1.contact, customer2.contact); - }, - - performedWorkShouldBeEqual: function(performedWorkArray1, performedWorkArray2) { - var i, lenght; - expect(performedWorkArray1.length).toEqual(performedWorkArray2.length); - for (i = 0, length = performedWorkArray1.length; i < length; i++) { - expect(performedWorkArray1[i].date).toEqual(performedWorkArray2[i].date); - expect(performedWorkArray1[i].hours).toEqual(performedWorkArray2[i].hours); - } - }, - - activitiesShouldBeEqual: function(activity1, activity2) { - expect(activity1.customerId).toEqual(activity2.customerId); - expect(activity1.description).toEqual(activity2.description); - expect(activity1.billed).toEqual(activity2.billed); - expect(activity1.hourlyRate.toFixed()).toEqual(activity2.hourlyRate.toFixed()); - this.performedWorkShouldBeEqual(activity1.performedWork, activity2.performedWork); - }, - - companiesShouldBeEqual: function(company1, company2) { - expect(company1.name).toEqual(company2.name); - expect(company1.phoneNumber).toEqual(company2.phoneNumber); - expect(company1.email).toEqual(company2.email); - expect(company1.vatNumber).toEqual(company2.vatNumber); - expect(company1.bankAccount).toEqual(company2.bankAccount); - expect(company1.iban).toEqual(company2.iban); - expect(company1.bic).toEqual(company2.bic); - this.addressesShouldBeEqual(company1.address, company2.address); - }, - - invoicesShouldBeEqual: function(invoice1, invoice2) { - expect(invoice1.customerId).toEqual(invoice2.customerId); - expect(invoice1.companyId).toEqual(invoice2.companyId); - expect(invoice1.invoiceNumber).toEqual(invoice2.invoiceNumber); - expect(invoice1.date).toEqual(invoice2.date); - expect(invoice1.dueDate).toEqual(invoice2.dueDate); - expect(invoice1.paid).toEqual(invoice2.paid); - expect(invoice1.activityId).toEqual(invoice2.activityId); - expect(invoice1.totalHours.toFixed()).toEqual(invoice2.totalHours.toFixed()); - expect(invoice1.hourlyRate.toFixed()).toEqual(invoice2.hourlyRate.toFixed()); - expect(invoice1.totalExcludingVat.toFixed()).toEqual(invoice2.totalExcludingVat.toFixed()); - expect(invoice1.vat.toFixed()).toEqual(invoice2.vat.toFixed()); - expect(invoice1.totalIncludingVat.toFixed()).toEqual(invoice2.totalIncludingVat.toFixed()); - }, - - usersShouldBeEqual: function(user1, user2) { - expect(user1.name).toEqual(user2.name); - expect(user1.email).toEqual(user2.email); - expect(user1.salt).toEqual(user2.salt); - expect(user1.passwdHash).toEqual(user2.passwdHash); - } -}; \ No newline at end of file diff --git a/spec/rest_api/request_helper.js b/spec/rest_api/request_helper.js deleted file mode 100644 index f868e03..0000000 --- a/spec/rest_api/request_helper.js +++ /dev/null @@ -1,21 +0,0 @@ -var request = require('request'); - -function getUrlFor(route) { - return 'http://localhost:3000' + route; -} - -function sendRequest(method, route, body, callback) { - request[method]({ url: getUrlFor(route), json: body }, function(err, res, b) { - callback(err, res); - }); -} - -module.exports = { - post: function(route, body, callback) { - sendRequest('post', route, body, callback); - }, - - get: function(route, callback) { - sendRequest('get', route, null, callback); - } -}; \ No newline at end of file diff --git a/test.sh b/test.sh index 6083f7c..46aeb03 100755 --- a/test.sh +++ b/test.sh @@ -1 +1,2 @@ -node_modules/jasmine-node/bin/jasmine-node spec +node_modules/mocha/bin/mocha $(find test -name "*Spec.js") $@ + diff --git a/spec/builders/activity_builder.js b/test/builders/activity_builder.js similarity index 100% rename from spec/builders/activity_builder.js rename to test/builders/activity_builder.js diff --git a/spec/builders/company_builder.js b/test/builders/company_builder.js similarity index 100% rename from spec/builders/company_builder.js rename to test/builders/company_builder.js diff --git a/spec/builders/customer_builder.js b/test/builders/customer_builder.js similarity index 100% rename from spec/builders/customer_builder.js rename to test/builders/customer_builder.js diff --git a/spec/builders/invoice_builder.js b/test/builders/invoice_builder.js similarity index 100% rename from spec/builders/invoice_builder.js rename to test/builders/invoice_builder.js diff --git a/spec/builders/user_builder.js b/test/builders/user_builder.js similarity index 100% rename from spec/builders/user_builder.js rename to test/builders/user_builder.js diff --git a/spec/db/README b/test/db/README similarity index 100% rename from spec/db/README rename to test/db/README diff --git a/spec/db/activitySpec.js b/test/db/activitySpec.js similarity index 65% rename from spec/db/activitySpec.js rename to test/db/activitySpec.js index f634447..520317e 100644 --- a/spec/db/activitySpec.js +++ b/test/db/activitySpec.js @@ -4,7 +4,9 @@ var mongoose = require('mongoose'), ActivityBuilder = require('../builders/activity_builder.js'), CustomerBuilder = require('../builders/customer_builder.js'), mongooseTestHelper = require('./persistence_spec_functions.js'), - helper = require('../helper_functions.js'); + validationHelper = require('./mongoose_validation_helper.js'), + equalityHelper = require('../equality_functions.js'), + should = require('should'); mongoose.connect('mongodb://localhost/therabbithole_test'); mongoose.connection.collection('activities').drop(); @@ -20,44 +22,41 @@ describe('given a new activity', function() { describe('when it is saved with none of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { activity = new Activity(); // the activity reference by default points to a properly filled in instance activity.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should fail with validation errors for each required field', function() { - expect(error).not.toBeNull(); - expect(error).toHaveRequiredValidationErrorFor('customer'); - expect(error).toHaveRequiredValidationErrorFor('description'); - expect(error).toHaveRequiredValidationErrorFor('hourlyRate'); + should.exist(error); + validationHelper.checkRequiredValidationErrorFor(error, 'customer'); + validationHelper.checkRequiredValidationErrorFor(error, 'description'); + validationHelper.checkRequiredValidationErrorFor(error, 'hourlyRate'); }); }); describe('when it is saved with all of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { activity.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); - it('should contain a default false value for billed', function() { + it('should contain a default false value for billed', function(done) { Activity.findById(activity.id, function(err, result) { - expect(result.billed).toBe(false); - asyncSpecDone(); + result.billed.should.be.false; + done(); }); - asyncSpecWait(); }); }); @@ -68,64 +67,60 @@ describe('given a new activity', function() { yesterday = new Date(); yesterday.setDate(yesterday.getDate() -1); - beforeEach(function() { + beforeEach(function(done) { activity.addPerformedWork(yesterday, 8); activity.addPerformedWork(today, 6); activity.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not cause validation errors', function() { - expect(error).toBeNull(); + should.not.exist(error); }); - it('the performed work should be inserted in the database as well', function() { + it('the performed work should be inserted in the database as well', function(done) { Activity.findById(activity.id, function(err, result) { - expect(result.performedWork.length).toBe(2); - expect(result.performedWork[0].date).toEqual(yesterday); - expect(result.performedWork[0].hours).toEqual(8); - expect(result.performedWork[1].date).toEqual(today); - expect(result.performedWork[1].hours).toEqual(6); - asyncSpecDone(); + result.performedWork.length.should.equal(2); + result.performedWork[0].date.valueOf().should.equal(yesterday.valueOf()); + result.performedWork[0].hours.valueOf().should.equal(8); + result.performedWork[1].date.valueOf().should.equal(today.valueOf()); + result.performedWork[1].hours.valueOf().should.equal(6); + done(); }); - asyncSpecWait(); }); }); describe('when it is saved with too much performed work added to it', function() { - beforeEach(function() { + beforeEach(function(done) { activity.addPerformedWork(new Date(), 17); // max value is set at 16; activity.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should cause a max value validation error if the number of hours is too large', function() { - expect(error).toHaveMaxValidationErrorFor('hours'); + validationHelper.checkMaxValidationErrorFor('hours'); }); }); describe('when it is saved with too little performed work added to it', function() { - beforeEach(function() { + beforeEach(function(done) { activity.addPerformedWork(new Date(), 0); // min value is 1 activity.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should cause a min value validation error if the number of hours is too small', function() { - expect(error).toHaveMinValidationErrorFor('hours'); + validationHelper.checkMinValidationErrorFor('hours'); }); }); @@ -140,9 +135,7 @@ describe('given a new activity', function() { return activity; }, entityModel: Activity, - equalityFn: function(instance1, instance2) { - helper.customersShouldBeEqual(instance1, instance2); - }, + equalityFn: equalityHelper.customersShouldBeEqual }); }); @@ -151,77 +144,71 @@ describe('given an existing activity', function() { var activity = null; - beforeEach(function() { + beforeEach(function(done) { activity = new ActivityBuilder() .asBilled() .build(); activity.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); describe('when it is retrieved from the database', function() { var retrievedActivity = null; - beforeEach(function() { + beforeEach(function(done) { Activity.findById(activity.id, function(err, result) { - expect(err).toBeNull(); + should.not.exist(err); retrievedActivity = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should contain the same values that have been inserted', function() { - helper.activitiesShouldBeEqual(retrievedActivity, activity); + equalityHelper.activitiesShouldBeEqual(retrievedActivity, activity); }); }); describe('when it is modified and updated', function() { - beforeEach(function() { + beforeEach(function(done) { activity.customer = '4e25937456436de850000007'; activity.description = 'some other cool project'; activity.hourlyRate = 77; activity.billed = false; activity.performedWork = []; activity.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('contains the updated values in the database', function() { + it('contains the updated values in the database', function(done) { Activity.findById(activity.id, function(err, result) { - helper.activitiesShouldBeEqual(result, activity); - asyncSpecDone(); + equalityHelper.activitiesShouldBeEqual(result, activity); + done(); }); - asyncSpecWait(); }); }); describe('when it is deleted', function() { - beforeEach(function() { + beforeEach(function(done) { activity.remove(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('can no longer be retrieved', function() { + it('can no longer be retrieved', function(done) { Activity.findById(activity.id, function(err, result) { - expect(result).toBeNull(); - asyncSpecDone(); + should.not.exist(result); + done(); }); - asyncSpecWait(); }); }); diff --git a/spec/db/companySpec.js b/test/db/companySpec.js similarity index 57% rename from spec/db/companySpec.js rename to test/db/companySpec.js index c82ba6b..f7ea6bf 100644 --- a/spec/db/companySpec.js +++ b/test/db/companySpec.js @@ -1,7 +1,9 @@ var mongoose = require('mongoose'), Company = require('../../lib/entities').Company, CompanyBuilder = require('../builders/company_builder.js'), - helper = require('../helper_functions.js'); + should = require('should'), + validationHelper = require('./mongoose_validation_helper.js'), + equalityHelper = require('../equality_functions.js'); mongoose.connect('mongodb://localhost/therabbithole_test'); mongoose.connection.collection('companies').drop(); @@ -17,43 +19,41 @@ describe('given a new company', function() { describe('when it is saved with none of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { company = new Company(); // the company reference by default points to a properly filled in instance company.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should fail with validation errors for each required field', function() { - expect(error).not.toBeNull(); - expect(error).toHaveRequiredValidationErrorFor('name'); - expect(error).toHaveRequiredValidationErrorFor('address.street'); - expect(error).toHaveRequiredValidationErrorFor('address.postalCode'); - expect(error).toHaveRequiredValidationErrorFor('address.city'); - expect(error).toHaveRequiredValidationErrorFor('phoneNumber'); - expect(error).toHaveRequiredValidationErrorFor('email'); - expect(error).toHaveRequiredValidationErrorFor('vatNumber'); - expect(error).toHaveRequiredValidationErrorFor('bankAccount'); - expect(error).toHaveRequiredValidationErrorFor('iban'); - expect(error).toHaveRequiredValidationErrorFor('bic'); + should.exist(error); + validationHelper.checkRequiredValidationErrorFor(error, 'name'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.street'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.postalCode'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.city'); + validationHelper.checkRequiredValidationErrorFor(error, 'phoneNumber'); + validationHelper.checkRequiredValidationErrorFor(error, 'email'); + validationHelper.checkRequiredValidationErrorFor(error, 'vatNumber'); + validationHelper.checkRequiredValidationErrorFor(error, 'bankAccount'); + validationHelper.checkRequiredValidationErrorFor(error, 'iban'); + validationHelper.checkRequiredValidationErrorFor(error, 'bic'); }); }); describe('when it is saved with all of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { company.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); }); @@ -64,37 +64,35 @@ describe('given an existing company', function() { var company = null; - beforeEach(function() { + beforeEach(function(done) { company = new CompanyBuilder().build(); company.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); describe('when it is retrieved from the database', function() { var retrievedCompany = null; - beforeEach(function() { + beforeEach(function(done) { Company.findById(company.id, function(err, result) { - expect(err).toBeNull(); + should.not.exist(err); retrievedCompany = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should contain the same values that have been inserted', function() { - helper.companiesShouldBeEqual(retrievedCompany, company); + equalityHelper.companiesShouldBeEqual(retrievedCompany, company); }); }); describe('when it is modified and updated', function() { - beforeEach(function() { + beforeEach(function(done) { company.name = 'some other company'; company.address = { street: 'some other street', @@ -110,38 +108,34 @@ describe('given an existing company', function() { company.bic = 'bic'; company.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('contains the updated values in the database', function() { + it('contains the updated values in the database', function(done) { Company.findById(company.id, function(err, result) { - helper.companiesShouldBeEqual(result, company); - asyncSpecDone(); + equalityHelper.companiesShouldBeEqual(result, company); + done(); }); - asyncSpecWait(); }); }); describe('when it is deleted', function() { - beforeEach(function() { + beforeEach(function(done) { company.remove(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('can no longer be retrieved', function() { + it('can no longer be retrieved', function(done) { Company.findById(company.id, function(err, result) { - expect(result).toBeNull(); - asyncSpecDone(); + should.not.exist(result); + done(); }); - asyncSpecWait(); }); }); diff --git a/spec/db/customerSpec.js b/test/db/customerSpec.js similarity index 62% rename from spec/db/customerSpec.js rename to test/db/customerSpec.js index 3c11b60..4718d78 100644 --- a/spec/db/customerSpec.js +++ b/test/db/customerSpec.js @@ -1,7 +1,9 @@ var mongoose = require('mongoose'), Customer = require('../../lib/entities').Customer, CustomerBuilder = require('../builders/customer_builder.js'), - helper = require('../helper_functions.js'); + should = require('should'), + validationHelper = require('./mongoose_validation_helper.js'), + equalityHelper = require('../equality_functions.js'); mongoose.connect('mongodb://localhost/therabbithole_test'); mongoose.connection.collection('customers').drop(); @@ -17,46 +19,43 @@ describe('given a new customer', function() { describe('when it is saved with none of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { customer = new Customer(); // the customer reference by default points to a properly filled in instance customer.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should fail with validation errors for each required field', function() { - expect(error).not.toBeNull(); - expect(error).toHaveRequiredValidationErrorFor('name'); - expect(error).toHaveRequiredValidationErrorFor('vatNumber'); - expect(error).toHaveRequiredValidationErrorFor('address.street'); - expect(error).toHaveRequiredValidationErrorFor('address.postalCode'); - expect(error).toHaveRequiredValidationErrorFor('address.city'); + should.exist(error); + validationHelper.checkRequiredValidationErrorFor(error, 'name'); + validationHelper.checkRequiredValidationErrorFor(error, 'vatNumber'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.street'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.postalCode'); + validationHelper.checkRequiredValidationErrorFor(error, 'address.city'); }); }); describe('when it is saved with all of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { customer.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); - it('should contain a default false value for includeContactOnInvoice', function() { + it('should contain a default false value for includeContactOnInvoice', function(done) { Customer.findById(customer.id, function(err, result) { - expect(result.includeContactOnInvoice).toBe(false); - asyncSpecDone(); + result.includeContactOnInvoice.should.be.false; + done(); }); - asyncSpecWait(); }); }); @@ -67,40 +66,38 @@ describe('given an existing customer', function() { var customer = null; - beforeEach(function(err) { + beforeEach(function(done) { customer = new CustomerBuilder() .withIncludeContactOnInvoice() .build(); customer.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); describe('when it is retrieved from the database', function() { var retrievedCustomer = null; - beforeEach(function() { + beforeEach(function(done) { Customer.findById(customer.id, function(err, result) { - expect(err).toBeNull(); + should.not.exist(err); retrievedCustomer = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should contain the same values that have been inserted', function() { - helper.customersShouldBeEqual(retrievedCustomer, customer); + equalityHelper.customersShouldBeEqual(retrievedCustomer, customer); }); }); describe('when it is modified and updated', function() { - beforeEach(function() { + beforeEach(function(done) { customer.name = 'some other customer'; customer.vatNumber = '0456.876.235'; customer.address = { @@ -114,38 +111,34 @@ describe('given an existing customer', function() { email: 'some_email@hotmail.com' }; customer.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('contains the updated values in the database', function() { + it('contains the updated values in the database', function(done) { Customer.findById(customer.id, function(err, result) { - helper.customersShouldBeEqual(result, customer); - asyncSpecDone(); + equalityHelper.customersShouldBeEqual(result, customer); + done(); }); - asyncSpecWait(); }); }); describe('when it is deleted', function() { - beforeEach(function() { + beforeEach(function(done) { customer.remove(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('can no longer be retrieved', function() { + it('can no longer be retrieved', function(done) { Customer.findById(customer.id, function(err, result) { - expect(result).toBeNull(); - asyncSpecDone(); + should.not.exist(result); + done(); }); - asyncSpecWait(); }); }); diff --git a/spec/db/invoiceSpec.js b/test/db/invoiceSpec.js similarity index 64% rename from spec/db/invoiceSpec.js rename to test/db/invoiceSpec.js index 95458f5..75af350 100644 --- a/spec/db/invoiceSpec.js +++ b/test/db/invoiceSpec.js @@ -7,8 +7,10 @@ var mongoose = require('mongoose'), CompanyBuilder = require('../builders/company_builder.js'), Activity = require('../../lib/entities').Activity, ActivityBuilder = require('../builders/activity_builder.js'), + should = require('should'), mongooseTestHelper = require('./persistence_spec_functions.js'), - helper = require('../helper_functions.js'); + validationHelper = require('./mongoose_validation_helper.js'), + equalityHelper = require('../equality_functions.js'); mongoose.connect('mongodb://localhost/therabbithole_test'); mongoose.connection.collection('invoices').drop(); @@ -24,61 +26,57 @@ describe('given a new invoice', function() { describe('when it is saved with none of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { invoice = new Invoice(); // the invoice reference by default points to a properly filled in instance invoice.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should fail with validation errors for each required field', function() { - expect(error).not.toBeNull(); - expect(error).toHaveRequiredValidationErrorFor('company'); - expect(error).toHaveRequiredValidationErrorFor('customer'); - expect(error).toHaveRequiredValidationErrorFor('invoiceNumber'); - expect(error).toHaveRequiredValidationErrorFor('date'); - expect(error).toHaveRequiredValidationErrorFor('dueDate'); - expect(error).toHaveRequiredValidationErrorFor('activity'); - expect(error).toHaveRequiredValidationErrorFor('totalHours'); - expect(error).toHaveRequiredValidationErrorFor('hourlyRate'); - expect(error).toHaveRequiredValidationErrorFor('totalExcludingVat'); - expect(error).toHaveRequiredValidationErrorFor('vat'); - expect(error).toHaveRequiredValidationErrorFor('totalIncludingVat'); + should.exist(error); + validationHelper.checkRequiredValidationErrorFor(error, 'company'); + validationHelper.checkRequiredValidationErrorFor(error, 'customer'); + validationHelper.checkRequiredValidationErrorFor(error, 'invoiceNumber'); + validationHelper.checkRequiredValidationErrorFor(error, 'date'); + validationHelper.checkRequiredValidationErrorFor(error, 'dueDate'); + validationHelper.checkRequiredValidationErrorFor(error, 'activity'); + validationHelper.checkRequiredValidationErrorFor(error, 'totalHours'); + validationHelper.checkRequiredValidationErrorFor(error, 'hourlyRate'); + validationHelper.checkRequiredValidationErrorFor(error, 'totalExcludingVat'); + validationHelper.checkRequiredValidationErrorFor(error, 'vat'); + validationHelper.checkRequiredValidationErrorFor(error, 'totalIncludingVat'); }); }); describe('when it is saved with all of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { invoice.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); - afterEach(function() { + afterEach(function(done) { // there's a unique index on invoice.invoiceNumber, if we don't remove it after // each spec, the next insert fails invoice.remove(function(err) { - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); - it('should contain a default false value for paid', function() { + it('should contain a default false value for paid', function(done) { Invoice.findById(invoice.id, function(err, result) { - expect(result.paid).toBe(false); - asyncSpecDone(); + result.paid.should.be.false; + done(); }); - asyncSpecWait(); }); }); @@ -93,9 +91,7 @@ describe('given a new invoice', function() { return invoice; }, entityModel: Invoice, - equalityFn: function(instance1, instance2) { - helper.customersShouldBeEqual(instance1, instance2); - }, + equalityFn: equalityHelper.customersShouldBeEqual, remove_entity_in_afterEach: true }); @@ -109,9 +105,7 @@ describe('given a new invoice', function() { return invoice; }, entityModel: Invoice, - equalityFn: function(instance1, instance2) { - helper.companiesShouldBeEqual(instance1, instance2); - }, + equalityFn: equalityHelper.companiesShouldBeEqual, remove_entity_in_afterEach: true }); @@ -125,9 +119,7 @@ describe('given a new invoice', function() { return invoice; }, entityModel: Invoice, - equalityFn: function(instance1, instance2) { - helper.activitiesShouldBeEqual(instance1, instance2); - }, + equalityFn: equalityHelper.activitiesShouldBeEqual, remove_entity_in_afterEach: true }); @@ -137,45 +129,42 @@ describe('given an existing invoice', function() { var invoice = null; - beforeEach(function() { + beforeEach(function(done) { invoice = new InvoiceBuilder().asPaid().build(); invoice.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - afterEach(function() { - if (invoice.removed) { return; } + afterEach(function(done) { + if (invoice.removed) { done(); } invoice.remove(function(err) { - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); describe('when it is retrieved from the database', function() { var retrievedInvoice = null; - beforeEach(function() { + beforeEach(function(done) { Invoice.findById(invoice.id, function(err, result) { - expect(err).toBeNull(); + should.not.exist(err); retrievedInvoice = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should contain the same values that have been inserted', function() { - helper.invoicesShouldBeEqual(retrievedInvoice, invoice); + equalityHelper.invoicesShouldBeEqual(retrievedInvoice, invoice); }); }); describe('when it is modified and updated', function() { - beforeEach(function() { + beforeEach(function(done) { invoice.company = '4e25937456436de850000009'; invoice.customer = '4e25937456436de850000008'; invoice.activity = '4e25937456436de850000007'; @@ -188,38 +177,34 @@ describe('given an existing invoice', function() { invoice.paid = false; invoice.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('contains the updated values in the database', function() { + it('contains the updated values in the database', function(done) { Invoice.findById(invoice.id, function(err, result) { - helper.invoicesShouldBeEqual(result, invoice); - asyncSpecDone(); + equalityHelper.invoicesShouldBeEqual(result, invoice); + done(); }); - asyncSpecWait(); }); }); describe('when it is deleted', function() { - beforeEach(function() { + beforeEach(function(done) { invoice.remove(function(err) { invoice.removed = true; // HACK: to avoid double removal in afterEach of parent suite - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('can no longer be retrieved', function() { + it('can no longer be retrieved', function(done) { Invoice.findById(invoice.id, function(err, result) { - expect(result).toBeNull(); - asyncSpecDone(); + should.not.exist(result); + done(); }); - asyncSpecWait(); }); }); diff --git a/test/db/mongoose_validation_helper.js b/test/db/mongoose_validation_helper.js new file mode 100644 index 0000000..56bcf3c --- /dev/null +++ b/test/db/mongoose_validation_helper.js @@ -0,0 +1,19 @@ +var checkValidationErrorFor = function(err, validatorName, propertyName) { + if (!err) { return false; } + if (err.name !== 'ValidationError') { return false; } + var value = err.errors[propertyName]; + if (!value) { return false; } + return (value.message === 'Validator "' + validatorName + '" failed for path ' + propertyName); +}; + +exports.checkRequiredValidationErrorFor = function(error, propertyName) { + return checkValidationErrorFor(error, 'required', propertyName); +}; + +exports.checkMaxValidationErrorFor = function(error, propertyName) { + return checkValidationErrorFor(error, 'max', propertyName); +}; + +exports.checkMinValidationErrorFor = function(error, propertyName) { + return checkValidationErrorFor(error, 'min', propertyName); +}; \ No newline at end of file diff --git a/spec/db/persistence_spec_functions.js b/test/db/persistence_spec_functions.js similarity index 77% rename from spec/db/persistence_spec_functions.js rename to test/db/persistence_spec_functions.js index aa5d2ec..f21a98a 100644 --- a/spec/db/persistence_spec_functions.js +++ b/test/db/persistence_spec_functions.js @@ -1,47 +1,47 @@ +var should = require('should'); + function create_entity_with_reference_and_check_populate(data) { describe('when ' + data.entityName + ' is saved with a reference to an existing ' + data.referenceName, function() { var referencedEntity = null, entity = null; - beforeEach(function() { + beforeEach(function(done) { entity = data.getEntityFn(); referencedEntity = data.buildReferenceEntityFn(); referencedEntity.save(function(err) { - expect(err).toBeNull(); + should.not.exist(err); entity[data.referenceName] = referencedEntity.id; entity.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); }); - asyncSpecWait(); }); if (data.remove_entity_in_afterEach) { - afterEach(function() { + afterEach(function(done) { entity.remove(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); } describe('when we specify that ' + data.referenceName + ' should be populated when we retrieve ' + data.entityName, function() { - var retrievedEntity = null; + var retrievedEntity = null, + error = null; - beforeEach(function() { + beforeEach(function(done) { data.entityModel.findById(entity.id).populate(data.referenceName).run(function(err, result) { error = err; retrievedEntity = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); it('should populate the ' + data.referenceName + ' property in the returned ' + data.entityName, function() { diff --git a/spec/db/userSpec.js b/test/db/userSpec.js similarity index 61% rename from spec/db/userSpec.js rename to test/db/userSpec.js index 6f9b245..08aae98 100644 --- a/spec/db/userSpec.js +++ b/test/db/userSpec.js @@ -1,7 +1,9 @@ var mongoose = require('mongoose'), User = require('../../lib/entities').User, UserBuilder = require('../builders/user_builder.js'), - helper = require('../helper_functions.js'); + should = require('should'), + validationHelper = require('./mongoose_validation_helper.js'), + equalityHelper = require('../equality_functions.js'); mongoose.connect('mongodb://localhost/therabbithole_test'); mongoose.connection.collection('users').drop(); @@ -17,46 +19,43 @@ describe('given a new user', function() { describe('when it is saved with none of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { user = new User(); // the user reference by default points to a properly filled in instance user.salt = null; // to avoid the default value user.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should fail with validation errors for each required field', function() { - expect(error).not.toBeNull(); - expect(error).toHaveRequiredValidationErrorFor('name'); - expect(error).toHaveRequiredValidationErrorFor('email'); - expect(error).toHaveRequiredValidationErrorFor('salt'); - expect(error).toHaveRequiredValidationErrorFor('passwdHash'); + should.exist(error); + validationHelper.checkRequiredValidationErrorFor(error, 'name'); + validationHelper.checkRequiredValidationErrorFor(error, 'email'); + validationHelper.checkRequiredValidationErrorFor(error, 'salt'); + validationHelper.checkRequiredValidationErrorFor(error, 'passwdHash'); }); }); describe('when it is saved with all of its required fields filled in', function() { - beforeEach(function() { + beforeEach(function(done) { user.save(function(err) { error = err; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); - afterEach(function() { + afterEach(function(done) { // there's a unique index on user.name, if we don't remove it after each spec, the next insert fails user.remove(function(err) { - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should not fail', function() { - expect(error).toBeNull(); + should.not.exist(error); }); }); @@ -67,83 +66,76 @@ describe('given an existing user', function() { var user = null; - beforeEach(function(err) { + beforeEach(function(done) { user = new UserBuilder().build(); user.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - afterEach(function() { - if (user.removed) { return; } + afterEach(function(done) { + if (user.removed) { done(); } user.remove(function(err) { - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); describe('when it is retrieved from the database', function() { var retrievedUser = null; - beforeEach(function() { + beforeEach(function(done) { User.findById(user.id, function(err, result) { - expect(err).toBeNull(); + should.not.exist(err); retrievedUser = result; - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should contain the same values that have been inserted', function() { - helper.usersShouldBeEqual(retrievedUser, user); + equalityHelper.usersShouldBeEqual(retrievedUser, user); }); }); describe('when it is modified and updated', function() { - beforeEach(function() { + beforeEach(function(done) { user.name = "some user name"; user.email = "some email"; user.salt = "some salt value"; user.passwdHash = "some passwd hash"; user.save(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('contains the updated values in the database', function() { + it('contains the updated values in the database', function(done) { User.findById(user.id, function(err, result) { - helper.usersShouldBeEqual(result, user); - asyncSpecDone(); + equalityHelper.usersShouldBeEqual(result, user); + done(); }); - asyncSpecWait(); }); }); describe('when it is deleted', function() { - beforeEach(function() { + beforeEach(function(done) { user.remove(function(err) { user.removed = true; // HACK: to avoid double removal in afterEach of parent suite - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); - it('can no longer be retrieved', function() { + it('can no longer be retrieved', function(done) { User.findById(user.id, function(err, result) { - expect(result).toBeNull(); - asyncSpecDone(); + should.not.exist(result); + done(); }); - asyncSpecWait(); }); }); diff --git a/spec/entities/activitySpec.js b/test/entities/activitySpec.js similarity index 69% rename from spec/entities/activitySpec.js rename to test/entities/activitySpec.js index a9d25f9..c2259df 100644 --- a/spec/entities/activitySpec.js +++ b/test/entities/activitySpec.js @@ -1,4 +1,5 @@ -var Activity = require('../../lib/entities').Activity; +var Activity = require('../../lib/entities').Activity, + should = require('should'); describe('given an activity', function() { @@ -19,10 +20,10 @@ describe('given an activity', function() { }); it('should hold the values in the performedWork array', function() { - expect(activity.performedWork[0].date).toEqual(yesterday); - expect(activity.performedWork[0].hours).toEqual(8); - expect(activity.performedWork[1].date).toEqual(today); - expect(activity.performedWork[1].hours).toEqual(7); + activity.performedWork[0].date.should.equal(yesterday); + activity.performedWork[0].hours.valueOf().should.equal(8); + activity.performedWork[1].date.should.equal(today); + activity.performedWork[1].hours.valueOf().should.equal(7); }); }); @@ -42,11 +43,11 @@ describe('given an activity', function() { }); it('should throw an exception', function() { - expect(error).not.toBe(null); + should.exist(error); }); it('should not hold the performed work for the duplicate day', function() { - expect(activity.performedWork.length).toEqual(1); + activity.performedWork.length.should.equal(1); }); }); diff --git a/spec/entities/invoiceSpec.js b/test/entities/invoiceSpec.js similarity index 77% rename from spec/entities/invoiceSpec.js rename to test/entities/invoiceSpec.js index 507e199..6a43a09 100644 --- a/spec/entities/invoiceSpec.js +++ b/test/entities/invoiceSpec.js @@ -9,11 +9,11 @@ describe('given an invoice', function() { invoice.totalExcludingVat = 1000; it('should automatically set the vat property', function() { - expect(invoice.vat).toEqual(210); + invoice.vat.valueOf().should.equal(210); }); it('should automatically set the totalIncludingVat property', function() { - expect(invoice.totalIncludingVat).toEqual(1210); + invoice.totalIncludingVat.valueOf().should.equal(1210); }); }); @@ -24,10 +24,10 @@ describe('given an invoice created with a totalExcludingVat value', function() { var invoice = new Invoice({ totalExcludingVat: 1000 }); it('should contain the correct vat value', function() { - expect(invoice.vat).toEqual(210); + invoice.vat.valueOf().should.equal(210); }); it('should contain the correct totalIncludingVat property', function() { - expect(invoice.totalIncludingVat).toEqual(1210); + invoice.totalIncludingVat.valueOf().should.equal(1210); }); }); diff --git a/spec/entities/userSpec.js b/test/entities/userSpec.js similarity index 73% rename from spec/entities/userSpec.js rename to test/entities/userSpec.js index b41d722..3d00fbf 100644 --- a/spec/entities/userSpec.js +++ b/test/entities/userSpec.js @@ -1,4 +1,5 @@ -var User = require('../../lib/entities').User; +var User = require('../../lib/entities').User, + should = require('should'); describe('given a user', function() { @@ -9,7 +10,7 @@ describe('given a user', function() { }); it('should have a default salt value', function() { - expect(user.salt).not.toBe(null); + should.exist(user.salt); }); describe('when you create another user', function() { @@ -20,7 +21,7 @@ describe('given a user', function() { }); it('should not have the same salt value as the previous user', function() { - expect(user.salt).not.toEqual(user2.salt); + user.salt.should.not.equal(user2.salt); }); }); @@ -32,13 +33,13 @@ describe('given a user', function() { }); it('should not contain the password value in passwdHash', function() { - expect(user.passwdHash).not.toEqual('my_password'); + user.passwdHash.should.not.equal('my_password'); }); describe('when you validate the password with the correct value', function() { it('should return true', function() { - expect(user.validatePassword('my_password')).toBe(true); + user.validatePassword('my_password').should.be.true; }); }); @@ -46,7 +47,7 @@ describe('given a user', function() { describe('when you validate the password with an invalid value', function() { it('should return false', function() { - expect(user.validatePassword('something_else')).toBe(false); + user.validatePassword('something_else').should.be.false; }); }); diff --git a/test/equality_functions.js b/test/equality_functions.js new file mode 100644 index 0000000..ef5ce0f --- /dev/null +++ b/test/equality_functions.js @@ -0,0 +1,89 @@ +var should = require('should'); + +var addressesShouldBeEqual = function(address1, address2) { + if (address1 === null && address2 === null) { return; } + if (address1 !== null) { should.exist(address2); } + if (address2 !== null) { should.exist(address1); } + should.equal(address1.street, address2.street); + should.equal(address1.city, address2.city); + should.equal(address1.postalCode, address2.postalCode); + should.equal(address1.country, address2.country); +}; + +var contactsShouldBeEqual = function(contact1, contact2) { + if (contact1 === null && contact2 === null) { return; } + if (contact1 !== null) { should.exist(contact2); } + if (contact2 !== null) { should.exist(contact1); } + should.equal(contact1.name, contact2.name); + should.equal(contact1.email, contact2.email); +}; + +var customersShouldBeEqual = function(customer1, customer2) { + should.equal(customer1.name, customer2.name); + should.equal(customer1.vatNumber, customer2.vatNumber); + should.equal(customer1.phoneNumber, customer2.phoneNumber); + should.equal(customer1.includeContactOnInvoice, customer2.includeContactOnInvoice); + addressesShouldBeEqual(customer1.address, customer2.address); + contactsShouldBeEqual(customer1.contact, customer2.contact); +}; + +var performedWorkShouldBeEqual = function(performedWorkArray1, performedWorkArray2) { + var i, length; + performedWorkArray1.length.should.equal(performedWorkArray2.length); + for (i = 0, length = performedWorkArray1.length; i < length; i++) { + should.equal(performedWorkArray1[i].date, performedWorkArray2[i].date); + should.equal(performedWorkArray1[i].hours, performedWorkArray2[i].hours); + } +}; + +var activitiesShouldBeEqual = function(activity1, activity2) { + should.equal(activity1.customerId, activity2.customerId); + should.equal(activity1.description, activity2.description); + should.equal(activity1.billed, activity2.billed); + should.equal(activity1.hourlyRate.toFixed(), activity2.hourlyRate.toFixed()); + performedWorkShouldBeEqual(activity1.performedWork, activity2.performedWork); +}; + +var companiesShouldBeEqual = function(company1, company2) { + should.equal(company1.name, company2.name); + should.equal(company1.phoneNumber, company2.phoneNumber); + should.equal(company1.email, company2.email); + should.equal(company1.vatNumber, company2.vatNumber); + should.equal(company1.bankAccount, company2.bankAccount); + should.equal(company1.iban, company2.iban); + should.equal(company1.bic, company2.bic); + addressesShouldBeEqual(company1.address, company2.address); +} + +var invoicesShouldBeEqual = function(invoice1, invoice2) { + should.equal(invoice1.customerId, invoice2.customerId); + should.equal(invoice1.companyId, invoice2.companyId); + should.equal(invoice1.invoiceNumber, invoice2.invoiceNumber); + should.equal(invoice1.date.valueOf(), invoice2.date.valueOf()); + should.equal(invoice1.dueDate.valueOf(), invoice2.dueDate.valueOf()); + should.equal(invoice1.paid, invoice2.paid); + should.equal(invoice1.activityId, invoice2.activityId); + should.equal(invoice1.totalHours.toFixed(), invoice2.totalHours.toFixed()); + should.equal(invoice1.hourlyRate.toFixed(), invoice2.hourlyRate.toFixed()); + should.equal(invoice1.totalExcludingVat.toFixed(), invoice2.totalExcludingVat.toFixed()); + should.equal(invoice1.vat.toFixed(), invoice2.vat.toFixed()); + should.equal(invoice1.totalIncludingVat.toFixed(), invoice2.totalIncludingVat.toFixed()); +}; + +var usersShouldBeEqual = function(user1, user2) { + should.equal(user1.name, user2.name); + should.equal(user1.email, user2.email); + should.equal(user1.salt, user2.salt); + should.equal(user1.passwdHash, user2.passwdHash); +}; + +module.exports = { + addressesShouldBeEqual: addressesShouldBeEqual, + contactsShouldBeEqual: contactsShouldBeEqual, + customersShouldBeEqual: customersShouldBeEqual, + performedWorkShouldBeEqual: performedWorkShouldBeEqual, + activitiesShouldBeEqual: activitiesShouldBeEqual, + companiesShouldBeEqual: companiesShouldBeEqual, + invoicesShouldBeEqual: invoicesShouldBeEqual, + usersShouldBeEqual: usersShouldBeEqual +}; \ No newline at end of file diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..a14bafb --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1,4 @@ +--require should +--require assert +--reporter spec +--ui bdd \ No newline at end of file diff --git a/spec/rest_api/auth_helper.js b/test/rest_api/auth_helper.js similarity index 61% rename from spec/rest_api/auth_helper.js rename to test/rest_api/auth_helper.js index 8095c6d..fdd227f 100644 --- a/spec/rest_api/auth_helper.js +++ b/test/rest_api/auth_helper.js @@ -1,6 +1,8 @@ var User = require('../../lib/entities/user'), + mongoose = require('mongoose'), request_helper = require('./request_helper'); +mongoose.connection.collection('users').drop(); var user = new User({ name: 'test_user', @@ -9,11 +11,15 @@ var user = new User({ user.setPassword('test'); user.save(function(err, result) { + if (err) throw err; +}); + +exports.post_login = function(done) { request_helper.post('/login', { username: user.name, password: 'test' - }, function(err, result) { + }, function(err, result, done) { if (err) throw err; - }); -}); - + done(); + }, done); +}; diff --git a/spec/rest_api/customerSpec.js b/test/rest_api/customerSpec.js similarity index 62% rename from spec/rest_api/customerSpec.js rename to test/rest_api/customerSpec.js index 87a59b3..7e8bc02 100644 --- a/spec/rest_api/customerSpec.js +++ b/test/rest_api/customerSpec.js @@ -3,18 +3,23 @@ var mongooseInit = require('../../lib/mongoose_init').connect('mongodb://localho Customer = require('../../lib/entities/customer'), CustomerBuilder = require('../builders/customer_builder'), requesthelper = require('./request_helper'), - entityhelper = require('./../helper_functions'), + entityhelper = require('./../equality_functions'), + should = require('should'), response = null; -function handleResponse(err, res) { - expect(err).toBeNull(); +function handleResponse(err, res, done) { + should.not.exist(err); response = res; - asyncSpecDone(); + done(); } -require('./auth_helper.js'); +var auth = require('./auth_helper.js'); describe('post /customer', function() { + + beforeEach(function(done) { + auth.post_login(done); + }); describe('when the request contains a customer document with all required fields provided', function() { @@ -28,62 +33,58 @@ describe('post /customer', function() { vatNumber: '1234567890' }; - beforeEach(function() { - requesthelper.post('/customer', customer, handleResponse); - asyncSpecWait(); + beforeEach(function(done) { + requesthelper.post('/customer', customer, handleResponse, done); }); - afterEach(function() { + afterEach(function(done) { Customer.remove({ _id: response.body._id}, function(err) { - asyncSpecDone(); + done(); }); - asyncSpecWait(); }); it('should have a statuscode of 201', function() { - expect(response.statusCode).toBe(201); + response.statusCode.should.equal(201); }); it('should have the customer document in the response body', function() { - expect(response.body.name).toEqual(customer.name); - expect(response.body.address).toEqual(customer.address); - expect(response.body.vatNumber).toEqual(customer.vatNumber); + response.body.name.should.equal(customer.name); + entityhelper.addressesShouldBeEqual(response.body.address, customer.address); + response.body.vatNumber.should.equal(customer.vatNumber); }); - it('should have persisted the document in the database', function() { + it('should have persisted the document in the database', function(done) { Customer.findById(response.body._id, function(err, result) { - expect(err).toBeNull(); - expect(result.id).toEqual(response.body._id); - asyncSpecDone(); + should.not.exist(err); + result.id.should.equal(response.body._id); + done(); }); - asyncSpecWait(); }); it('should contain a valid Location header value pointing to the new customer', function() { - expect(response.headers.location).toBe('http://localhost:3000/customer/' + response.body._id); + response.headers.location.should.equal('http://localhost:3000/customer/' + response.body._id) }); }); describe('when the request contains a customer document with missing required fields', function() { - beforeEach(function() { - post('/customer', { name: 'some name', vatNumber: '1234567890' }, handleResponse); - asyncSpecWait(); + beforeEach(function(done) { + requesthelper.post('/customer', { name: 'some name', vatNumber: '1234567890' }, handleResponse, done); }); it('should have a statuscode of 500', function() { - expect(response.statusCode).toBe(500); + response.statusCode.should.equal(500); }); it('should have an error message in the body', function() { - expect(response.body).toEqual('Validation failed'); + response.body.should.equal('Validation failed'); }); }); describe('when the request contains a customer document that already has an id value', function() { - beforeEach(function() { - post('/customer', { + beforeEach(function(done) { + requesthelper.post('/customer', { id: '4e53dd6773a37be113000001', name: 'some name', address: { @@ -92,16 +93,15 @@ describe('post /customer', function() { city: 'some city' }, vatNumber: '1234567890' - }, handleResponse); - asyncSpecWait(); + }, handleResponse, done); }); it('should have a statuscode of 412', function() { - expect(response.statusCode).toBe(412); + response.statusCode.should.equal(412); }); it('should have an error message in the body', function() { - expect(response.body).toEqual('customer should not have an id value'); + response.body.should.equal('customer should not have an id value'); }); }); @@ -109,15 +109,18 @@ describe('post /customer', function() { describe('get /customer/:id', function() { + beforeEach(function(done) { + auth.post_login(done); + }); + describe('when the request contains an id of a non-existing customer', function() { - beforeEach(function() { - requesthelper.get('/customer/4e552df6c83e22b929999999', handleResponse); - asyncSpecWait(); + beforeEach(function(done) { + requesthelper.get('/customer/4e552df6c83e22b929999999', handleResponse, done); }); it('should have a status code of 404', function() { - expect(response.statusCode).toBe(404); + response.statusCode.should.equal(404); }); }); @@ -126,27 +129,25 @@ describe('get /customer/:id', function() { var customer = null; - beforeEach(function() { + beforeEach(function(done) { customer = new CustomerBuilder() .withContact({ name: 'some contact', email: 'some email' }) .build(); customer.save(function(err) { - expect(err).toBeNull(); - requesthelper.get('/customer/' + customer.id, handleResponse); + should.not.exist(err); + requesthelper.get('/customer/' + customer.id, handleResponse, done); }); - asyncSpecWait(); }); - afterEach(function() { + afterEach(function(done) { customer.remove(function(err) { - expect(err).toBeNull(); - asyncSpecDone(); + should.not.exist(err); + done(); }); - asyncSpecWait(); }); it('should have a statusCode of 200', function() { - expect(response.statusCode).toBe(200); + response.statusCode.should.equal(200); }); it('should have the customer document in the response body', function() { diff --git a/test/rest_api/request_helper.js b/test/rest_api/request_helper.js new file mode 100644 index 0000000..c0093d8 --- /dev/null +++ b/test/rest_api/request_helper.js @@ -0,0 +1,21 @@ +var request = require('request'); + +function getUrlFor(route) { + return 'http://localhost:3000' + route; +} + +function sendRequest(method, route, body, callback, done) { + request[method]({ url: getUrlFor(route), json: body }, function(err, res, b) { + callback(err, res, done); + }); +} + +module.exports = { + post: function(route, body, callback, done) { + sendRequest('post', route, body, callback, done); + }, + + get: function(route, callback, done) { + sendRequest('get', route, null, callback, done); + } +}; \ No newline at end of file