From 16fff713121faa84dd831318ceb62422ed6bf5b3 Mon Sep 17 00:00:00 2001 From: Jordan Walsh Date: Mon, 27 Feb 2017 16:41:47 +1100 Subject: [PATCH] Added attachment Tests but these aren't currently working It seems the original author of the OAuth libraries has decided to push the content through as application/x-www-form-urlencoded which means that raw data is not being processed correctly. I need to modify the library here to implement correct content-types. --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + lib/application.js | 1 + lib/entities/attachment.js | 59 ++++---- lib/entities/user.js | 18 --- lib/entity_helpers/attachments.js | 38 ++--- lib/entity_helpers/users.js | 44 +++--- lib/oauth/oauth.js | 1 + oauth_test/sample_app.js | 243 ++++++++++++------------------ oauth_test/server.js | 54 +++---- test/accountingtests.js | 117 +++++++++----- 11 files changed, 278 insertions(+), 298 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 1ad899dbcdc748036dd701eacb0ec11e243703d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyJ`bL3>+mc4$`I(2Sbbi#2M3J zT*oXyY@Q(Y!ZDE|1kgGlC+ZoQs7@HV6)|Fx!@~RZ=JlH_u58Z)4k@C?#6Xc7@{2$qaAbO f?f5y0vab1>=e=-D3_9~cC+cUwb&*MdzgFN1-fR_w diff --git a/.gitignore b/.gitignore index 7852b784..413a6b09 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /cert /coverage .nyc_output/ +.DS_Store diff --git a/lib/application.js b/lib/application.js index be1c5353..bf822d99 100644 --- a/lib/application.js +++ b/lib/application.js @@ -107,6 +107,7 @@ _.extend(Application.prototype, { var url = this.options.baseUrl + endPointUrl + path; if (!_.isEmpty(params)) url += '?' + querystring.stringify(params); + this.oa[method](url, this.options.accessToken, this.options.accessSecret, { xml: body }, function(err, data, res) { if (err && data && data.indexOf('oauth_problem') >= 0) { diff --git a/lib/entities/attachment.js b/lib/entities/attachment.js index 601d21e7..3c219a92 100644 --- a/lib/entities/attachment.js +++ b/lib/entities/attachment.js @@ -1,48 +1,53 @@ -var _ = require('lodash') - , Entity = require('./entity') - , logger = require('../logger') - , dateformat = require('dateformat') - , fs = require('fs') +var _ = require('lodash'), + Entity = require('./entity'), + logger = require('../logger'), + dateformat = require('dateformat'), + fs = require('fs') var AttachmentSchema = new Entity.SchemaObject({ AttachmentID: { type: String, toObject: 'never' }, - FileName: {type: String, toObject: 'always'}, - Url: {type: String, toObject:'always'}, - MimeType: {type: String, toObject: 'always'}, - ContentLength: {type: Number, toObject:'always'} + FileName: { type: String, toObject: 'always' }, + Url: { type: String, toObject: 'always' }, + MimeType: { type: String, toObject: 'always' }, + ContentLength: { type: Number, toObject: 'always' } }); var Attachment = Entity.extend(AttachmentSchema, { - constructor: function (application, data, options) - { + constructor: function(application, data, options) { logger.debug('Attachment::constructor'); this.Entity.apply(this, arguments); }, - initialize: function (data, options) - { - }, - getContent:function(ownerPath) - { + initialize: function(data, options) {}, + getContent: function(ownerPath) { return this.application.core.attachments.getContent(ownerPath, this.FileName); }, - save:function(ownerPath, streamOrFilePath) - { + save: function(ownerPath, streamOrFilePath) { var self = this; var path = ownerPath + '/Attachments/' + this.FileName; - var stream; - if (_.isString(streamOrFilePath)) - stream = fs.createReadStream(streamOrFilePath); - else - stream = streamOrFilePath; - return this.application.putEntity(path, stream) - .then(function(ret) - { + + var base64string = base64_encode(streamOrFilePath); + console.log(base64string); + console.log(path); + + return this.application.postEntity(path, base64string, { type: this.MimeType }) + .then(function(ret) { + console.log(ret); return ret.response.Attachments.Attachment; }) + .fail(function(err) { + console.log(err); + }) + + function base64_encode(file) { + // read binary data + var bitmap = fs.readFileSync(file); + // convert binary data to base64 encoded string + return new Buffer(bitmap).toString('base64'); + } } }); module.exports = Attachment; -module.exports.AttachmentSchema = AttachmentSchema; +module.exports.AttachmentSchema = AttachmentSchema; \ No newline at end of file diff --git a/lib/entities/user.js b/lib/entities/user.js index cddca51b..cc5e1ec5 100644 --- a/lib/entities/user.js +++ b/lib/entities/user.js @@ -45,24 +45,6 @@ var User = Entity.extend(UserSchema, { toXml: function() { var user = _.omit(this.toObject()); return this.application.js2xml(user, 'User'); - }, - save: function(options) { - var self = this; - var xml = '' + this.toXml() + ''; - var path, method; - if (this.UserID) { - path = 'Users/' + this.UserID; - method = 'post' - } else { - path = 'Users'; - method = 'put' - } - return this.application.putOrPostEntity(method, path, xml, { - entityPath: 'Users.User', - entityConstructor: function(data) { - return self.application.core.users.newUser(data) - } - }); } }); diff --git a/lib/entity_helpers/attachments.js b/lib/entity_helpers/attachments.js index 4374b760..35cb6f4a 100644 --- a/lib/entity_helpers/attachments.js +++ b/lib/entity_helpers/attachments.js @@ -1,35 +1,29 @@ -var _ = require('lodash') - , logger = require('../logger') - , EntityHelper = require('./entity_helper') - , Attachment = require('../entities/attachment') - , p = require('../misc/promise') - , util = require('util') +var _ = require('lodash'), + logger = require('../logger'), + EntityHelper = require('./entity_helper'), + Attachment = require('../entities/attachment'), + p = require('../misc/promise'), + util = require('util') var Attachments = EntityHelper.extend({ - constructor: function (application, options) - { - EntityHelper.call(this, application, _.extend({ entityName:'Attachment', entityPlural:'Attachments'}, options)); + constructor: function(application, options) { + EntityHelper.call(this, application, _.extend({ entityName: 'Attachment', entityPlural: 'Attachments' }, options)); }, - newAttachment: function (data, options) - { + newAttachment: function(data, options) { return new Attachment(this.application, data, options) }, - getContent: function (ownerPath, fileName) - { + getContent: function(ownerPath, fileName) { var path = ownerPath + '/Attachments/' + fileName; - return this.application.getRaw({ id: id, modifiedAfter: modifiedAfter}) - .then(function (attachments) - { + return this.application.getRaw({ id: id, modifiedAfter: modifiedAfter }) + .then(function(attachments) { return _.first(attachments); }) }, - getAttachments: function (ownerPath, options) - { - var clonedOptions = _.extend({},options, { path:ownerPath + '/Attachments'}) ; - clonedOptions.entityConstructor = function(data) { return self.newAttachment(data)}; + getAttachments: function(ownerPath, options) { + var clonedOptions = _.extend({}, options, { path: ownerPath + '/Attachments' }); + clonedOptions.entityConstructor = function(data) { return self.newAttachment(data) }; return this.getEntities(clonedOptions); } }) -module.exports = Attachments; - +module.exports = Attachments; \ No newline at end of file diff --git a/lib/entity_helpers/users.js b/lib/entity_helpers/users.js index eb70f957..c9a87e9d 100644 --- a/lib/entity_helpers/users.js +++ b/lib/entity_helpers/users.js @@ -1,38 +1,34 @@ -var _ = require('lodash') - , logger = require('../logger') - , EntityHelper = require('./entity_helper') - , User = require('../entities/user') - , p = require('../misc/promise') - , util = require('util') +var _ = require('lodash'), + logger = require('../logger'), + EntityHelper = require('./entity_helper'), + User = require('../entities/user'), + p = require('../misc/promise'), + util = require('util') var Users = EntityHelper.extend({ - constructor: function (application, options) - { - EntityHelper.call(this, application, _.extend({ entityName:'User', entityPlural:'Users'}, options)); + constructor: function(application, options) { + EntityHelper.call(this, application, _.extend({ entityName: 'User', entityPlural: 'Users' }, options)); }, - newUser: function (data, options) - { + newUser: function(data, options) { return new User(this.application, data, options) }, - getUser: function (id, modifiedAfter) - { - return this.getUsers({ id: id, modifiedAfter: modifiedAfter}) - .then(function (users) - { + getUser: function(id, modifiedAfter) { + return this.getUsers({ id: id, modifiedAfter: modifiedAfter }) + .then(function(users) { return _.first(users); }) }, - saveUsers: function (users, options) - { - return this.saveEntities(users, options) - }, - getUsers: function (options) - { + // JWalsh 27 February 2017 - commented as user save is not supported by the v2.0 API. + // saveUsers: function(users, options) { + // return this.saveEntities(users, options) + // }, + getUsers: function(options) { var self = this; var clonedOptions = _.clone(options || {}); - clonedOptions.entityConstructor = function(data) { return self.newUser(data)}; + clonedOptions.entityPath = 'Users.User'; + clonedOptions.entityConstructor = function(data) { return self.newUser(data) }; return this.getEntities(clonedOptions) } }) -module.exports = Users; +module.exports = Users; \ No newline at end of file diff --git a/lib/oauth/oauth.js b/lib/oauth/oauth.js index 69757b22..81c05314 100644 --- a/lib/oauth/oauth.js +++ b/lib/oauth/oauth.js @@ -504,6 +504,7 @@ exports.OAuth.prototype._putOrPost = function(method, url, oauth_token, oauth_to extra_params = post_body; post_body = null; } + return this._performSecureRequest(oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback); } diff --git a/oauth_test/sample_app.js b/oauth_test/sample_app.js index 8feb047b..f258d77a 100644 --- a/oauth_test/sample_app.js +++ b/oauth_test/sample_app.js @@ -6,23 +6,22 @@ var express = require('express'), nodemailer = require('nodemailer') -function getXeroApp(session) -{ - var config={ authorizeCallbackUrl: 'http://localhost:3100/access', - consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', - consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K' }; - - - if (session) - { - if (session.oauthAccessToken && session.oauthAccessSecret) - { - config.accessToken=session.oauthAccessToken; - config.accessSecret=session.oauthAccessSecret; +function getXeroApp(session) { + var config = { + authorizeCallbackUrl: 'http://localhost:3100/access', + consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', + consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K' + }; + + + if (session) { + if (session.oauthAccessToken && session.oauthAccessSecret) { + config.accessToken = session.oauthAccessToken; + config.accessSecret = session.oauthAccessSecret; } } return new xero.PublicApplication(config); -} +} var app = express(); @@ -39,22 +38,19 @@ swig.setDefaults({ cache: false }); app.use(express.logger()); app.use(express.bodyParser()); app.use(express.cookieParser()); -app.use(express.session({ secret: '123456'})); +app.use(express.session({ secret: '123456' })); // app.use(express.cookieSession({ secret: 'sfsdfsdfsdfsdf234234234fd', cookie: { maxAge: 123467654456 } })); -function authorizeRedirect(req,res,returnTo) -{ - var xeroApp = getXeroApp(null,returnTo); - xeroApp.getRequestToken(function (err, token, secret) - { +function authorizeRedirect(req, res, returnTo) { + var xeroApp = getXeroApp(null, returnTo); + xeroApp.getRequestToken(function(err, token, secret) { if (!err) { req.session.oauthRequestToken = token; req.session.oauthRequestSecret = secret; req.session.returnto = returnTo; var authoriseUrl = xeroApp.buildAuthorizeUrl(token, { scope: 'payroll.employees,payroll.payitems,payroll.timesheets' }); res.redirect(authoriseUrl); - } - else { + } else { res.redirect('/error'); } }) @@ -63,32 +59,26 @@ function authorizeRedirect(req,res,returnTo) var cache = LRU(); -function authorizedOperation(req,res,returnTo, callback) -{ - if (req.session.oauthAccessToken) - { +function authorizedOperation(req, res, returnTo, callback) { + if (req.session.oauthAccessToken) { var xeroApp = getXeroApp(req.session); callback(xeroApp); - } - else - authorizeRedirect(req,res,returnTo); + } else + authorizeRedirect(req, res, returnTo); } // Home Page -app.get('/', function (req, res) -{ +app.get('/', function(req, res) { res.render('index.html'); }); // Redirected from xero with oauth results -app.get('/access', function (req, res) -{ +app.get('/access', function(req, res) { var xeroApp = getXeroApp(); if (req.query.oauth_verifier && req.query.oauth_token == req.session.oauthRequestToken) { xeroApp.getAccessToken(req.session.oauthRequestToken, req.session.oauthRequestSecret, req.query.oauth_verifier, - function (err, accessToken, accessSecret, results) - { + function(err, accessToken, accessSecret, results) { req.session.oauthAccessToken = accessToken; req.session.oauthAccessSecret = accessSecret; var returnTo = req.session.returnto; @@ -98,92 +88,75 @@ app.get('/access', function (req, res) } }); -app.get('/employees', function (req, res) -{ - authorizedOperation(req,res,'/employees', function(xeroApp) - { +app.get('/employees', function(req, res) { + authorizedOperation(req, res, '/employees', function(xeroApp) { var employees = []; - xeroApp.payroll.employees.getEmployees({ pager: { callback: pagerCallback}}) - .then(function() - { - res.render('employees.html', { employees: employees}); + xeroApp.payroll.employees.getEmployees({ pager: { callback: pagerCallback } }) + .then(function() { + res.render('employees.html', { employees: employees }); }) - .fail(function(err) - { + .fail(function(err) { console.log(err); - res.render('employees.html', { error: err}); + res.render('employees.html', { error: err }); }) - function pagerCallback(err,response, cb) - { - employees.push.apply(employees,response.data); + function pagerCallback(err, response, cb) { + employees.push.apply(employees, response.data); cb() } }) }); -app.get('/error', function(req,res) -{ - res.render('error.html', { error: req.query.error}); +app.get('/error', function(req, res) { + res.render('error.html', { error: req.query.error }); }) -app.get('/contacts', function (req, res) -{ - authorizedOperation(req,res,'/contacts', function(xeroApp) - { +app.get('/contacts', function(req, res) { + authorizedOperation(req, res, '/contacts', function(xeroApp) { var contacts = []; - xeroApp.core.contacts.getContacts({ pager: { callback: pagerCallback}}) - .then(function() - { - res.render('contacts.html', { contacts: contacts}); + xeroApp.core.contacts.getContacts({ pager: { callback: pagerCallback } }) + .then(function() { + res.render('contacts.html', { contacts: contacts }); }) - function pagerCallback(err,response, cb) - { - contacts.push.apply(contacts,response.data); + function pagerCallback(err, response, cb) { + contacts.push.apply(contacts, response.data); cb() } }) }); -app.get('/timesheets', function (req, res) -{ - authorizedOperation(req,res,'/timesheets', function(xeroApp) - { +app.get('/timesheets', function(req, res) { + authorizedOperation(req, res, '/timesheets', function(xeroApp) { xeroApp.payroll.timesheets.getTimesheets() - .then(function(timesheets) - { - res.render('timesheets.html', { timesheets: timesheets}); + .then(function(timesheets) { + res.render('timesheets.html', { timesheets: timesheets }); }) }) }); -app.use('/createtimesheet', function (req, res) -{ - if (req.method == 'GET') - { +app.use('/createtimesheet', function(req, res) { + if (req.method == 'GET') { return res.render('createtimesheet.html'); - } - else if (req.method == 'POST') { - authorizedOperation(req, res, '/createtimesheet', function (xeroApp) - { + } else if (req.method == 'POST') { + authorizedOperation(req, res, '/createtimesheet', function(xeroApp) { var timesheet = xeroApp.payroll.timesheets.newTimesheet({ EmployeeID: '065a115c-ba9c-4c03-b8e3-44c551ed8f21', - StartDate: new Date(2014,8,23), - EndDate: new Date(2014,8,29), + StartDate: new Date(2014, 8, 23), + EndDate: new Date(2014, 8, 29), Status: 'Draft', - TimesheetLines: [ { EarningsTypeID: 'a9ab82bf-c421-4840-b245-1df307c2127a', - NumberOfUnits: [5,0,0,0,0,0,0]}] + TimesheetLines: [{ + EarningsTypeID: 'a9ab82bf-c421-4840-b245-1df307c2127a', + NumberOfUnits: [5, 0, 0, 0, 0, 0, 0] + }] }); timesheet.save() - .then(function (ret) - { - res.render('createtimesheet.html', { timesheets: ret.entities}) + .then(function(ret) { + res.render('createtimesheet.html', { timesheets: ret.entities }) }) - .fail(function (err) - { - res.render('createtimesheet.html', { err: err}) + .fail(function(err) { + res.render('createtimesheet.html', { err: err }) }) }) @@ -191,86 +164,66 @@ app.use('/createtimesheet', function (req, res) }); -app.get('/invoices', function (req, res) -{ - authorizedOperation(req,res,'/invoices', function(xeroApp) - { +app.get('/invoices', function(req, res) { + authorizedOperation(req, res, '/invoices', function(xeroApp) { xeroApp.core.invoices.getInvoices() - .then(function(invoices) - { - res.render('invoices.html', { invoices: invoices}); + .then(function(invoices) { + res.render('invoices.html', { invoices: invoices }); }) }) }); -app.get('/items', function (req, res) -{ - authorizedOperation(req,res,'/items', function(xeroApp) - { +app.get('/items', function(req, res) { + authorizedOperation(req, res, '/items', function(xeroApp) { xeroApp.core.items.getItems() - .then(function(items) - { - res.render('items.html', { items: items}); + .then(function(items) { + res.render('items.html', { items: items }); }) }) }); -app.use('/createinvoice', function (req, res) -{ - if (req.method == 'GET') - { +app.use('/createinvoice', function(req, res) { + if (req.method == 'GET') { return res.render('createinvoice.html'); - } - else if (req.method == 'POST') { - authorizedOperation(req, res, '/createinvoice', function (xeroApp) - { + } else if (req.method == 'POST') { + authorizedOperation(req, res, '/createinvoice', function(xeroApp) { var invoice = xeroApp.core.invoices.newInvoice({ Type: req.body.Type, Contact: { Name: req.body.Contact }, DueDate: '2014-10-01', - LineItems: [ - { - Description: req.body.Description, - Quantity: req.body.Quantity, - UnitAmount: req.body.Amount, - AccountCode: 400, - ItemCode: 'ABC123' - } - ], + LineItems: [{ + Description: req.body.Description, + Quantity: req.body.Quantity, + UnitAmount: req.body.Amount, + AccountCode: 400, + ItemCode: 'ABC123' + }], Status: 'DRAFT' }); invoice.save() - .then(function (ret) - { - res.render('createinvoice.html', { outcome: 'Invoice created', id: ret.entities[0].InvoiceID}) + .then(function(ret) { + res.render('createinvoice.html', { outcome: 'Invoice created', id: ret.entities[0].InvoiceID }) }) - .fail(function (err) - { - res.render('createinvoice.html', { outcome: 'Error', err: err}) + .fail(function(err) { + res.render('createinvoice.html', { outcome: 'Error', err: err }) }) }) } }); -app.use('/emailinvoice', function (req, res) -{ - if (req.method == 'GET' && !req.query.a) - { - res.render('emailinvoice.html', { id: req.query.id}); - } - else - { - authorizedOperation(req,res,'/emailinvoice?id=' + req.query.id + '&a=1&email=' + encodeURIComponent(req.body.Email), function(xeroApp) - { - var file = fs.createWriteStream(__dirname + '/invoice.pdf', { encoding: 'binary'}); - xeroApp.core.invoices.streamInvoice(req.query.id,'pdf',file); - file.on('finish', function() - { +app.use('/emailinvoice', function(req, res) { + if (req.method == 'GET' && !req.query.a) { + res.render('emailinvoice.html', { id: req.query.id }); + } else { + authorizedOperation(req, res, '/emailinvoice?id=' + req.query.id + '&a=1&email=' + encodeURIComponent(req.body.Email), function(xeroApp) { + var file = fs.createWriteStream(__dirname + '/invoice.pdf', { encoding: 'binary' }); + xeroApp.core.invoices.streamInvoice(req.query.id, 'pdf', file); + file.on('finish', function() { var transporter = nodemailer.createTransport(); // Direct var mailOptions = { from: 'test@gmail.com', @@ -279,15 +232,14 @@ app.use('/emailinvoice', function (req, res) text: 'Email text', html: 'This is a xero invoice', attachments: [ - { filename: 'invoice.pdf', path: __dirname + '/invoice.pdf'} + { filename: 'invoice.pdf', path: __dirname + '/invoice.pdf' } ] }; - transporter.sendMail(mailOptions, function(err,info) - { + transporter.sendMail(mailOptions, function(err, info) { if (err) - res.render('emailinvoice.html', { outcome: 'Error', err: err, id: req.query.id}); + res.render('emailinvoice.html', { outcome: 'Error', err: err, id: req.query.id }); else - res.render('emailinvoice.html', { outcome: 'Email sent', id: req.query.id}); + res.render('emailinvoice.html', { outcome: 'Email sent', id: req.query.id }); }) }) @@ -296,8 +248,7 @@ app.use('/emailinvoice', function (req, res) } }); -app.use(function(req,res,next) -{ +app.use(function(req, res, next) { if (req.session) delete req.session.returnto; }) diff --git a/oauth_test/server.js b/oauth_test/server.js index 51263502..cd0fafd3 100644 --- a/oauth_test/server.js +++ b/oauth_test/server.js @@ -8,45 +8,44 @@ app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.cookieSession({ secret: 'sfsdfsdfsdfsdf234234234fd', cookie: { maxAge: 123467654456 } })); // Home Page -app.get('/', function (req, res) -{ +app.get('/', function(req, res) { if (!req.session.authorized) { res.redirect("/request"); - } - else { + } else { res.redirect("/organisations"); } }); // Request an OAuth Request Token, and redirects the user to authorize it -app.get('/request', function (req, res) -{ - var xeroApp = new xero.PublicApplication({ authorizeCallbackUrl: 'http://localhost:3100/access', - consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K'}) - xeroApp.getRequestToken(function (err, token, secret) - { +app.get('/request', function(req, res) { + var xeroApp = new xero.PublicApplication({ + authorizeCallbackUrl: 'http://localhost:3100/access', + consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', + consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K' + }) + xeroApp.getRequestToken(function(err, token, secret) { if (!err) { req.session.oauthRequestToken = token; req.session.oauthRequestSecret = secret; var authoriseUrl = xeroApp.buildAuthorizeUrl(token); res.redirect(authoriseUrl); - } - else { + } else { } }) }); -app.get('/access', function (req, res) -{ - var xeroApp = new xero.PublicApplication({ authorizeCallbackUrl: 'http://localhost:3100/access', - consumerKey: 'RPUOKBYW6KZGS37GE7S4ULR72W58B1', consumerSecret: 'Q4XQU3S7TNBKREMUTOFCI3LESYBGZT'}) +app.get('/access', function(req, res) { + var xeroApp = new xero.PublicApplication({ + authorizeCallbackUrl: 'http://localhost:3100/access', + consumerKey: 'RPUOKBYW6KZGS37GE7S4ULR72W58B1', + consumerSecret: 'Q4XQU3S7TNBKREMUTOFCI3LESYBGZT' + }) if (req.query.oauth_verifier && req.query.oauth_token == req.session.oauthRequestToken) { xeroApp.getAccessToken(req.session.oauthRequestToken, req.session.oauthRequestSecret, req.query.oauth_verifier, - function (err, accessToken, accessSecret, results) - { + function(err, accessToken, accessSecret, results) { req.session.oauthAccessToken = accessToken; req.session.oauthAccessSecret = accessSecret; res.redirect('/organisations'); @@ -56,21 +55,22 @@ app.get('/access', function (req, res) }); // Callback for the authorization page -app.get('/organisations', function (req, res) -{ +app.get('/organisations', function(req, res) { if (req.session.oauthAccessToken) { - var xeroApp = new xero.PublicApplication({ authorizeCallbackUrl: 'http://localhost:3100/access', - consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K', - accessToken: req.session.oauthAccessToken, accessSecret: req.session.oauthAccessSecret}); + var xeroApp = new xero.PublicApplication({ + authorizeCallbackUrl: 'http://localhost:3100/access', + consumerKey: 'XPKXXEIXBO4PSYDEWB9GEKCKTOJGOC', + consumerSecret: 'LHAFA1V6FW9NTRVKUW8OVMGKWI4N2K', + accessToken: req.session.oauthAccessToken, + accessSecret: req.session.oauthAccessSecret + }); xeroApp.core.organisations.getOrganisation() - .then(function(organisation) - { + .then(function(organisation) { console.log(organisation); res.end(); }) - } - else + } else res.redirect('/request'); }); diff --git a/test/accountingtests.js b/test/accountingtests.js index 1751aeea..78a059dc 100644 --- a/test/accountingtests.js +++ b/test/accountingtests.js @@ -11,33 +11,9 @@ process.on('uncaughtException', function(err) { }) var currentApp; - -/** - * Application Tests - * - * Accounting API Tests covered: - * - Accounts (GET, POST, PUT, DELETE) - * - Invoices (GET, PUT, POST) - * - Payments (GET, PUT, POST) - * - BankTransactions (GET, POST, PUT) - * - Attachments (GET, POST, PUT) - * - BankTransfers (GET, PUT) - * - Contacts (GET, PUT, POST) - * - Items (GET, PUT, POST, DELETE) - * - Journals (GET) - * - Organisations (GET) - * - Tracking Categories (GET, PUT, POST, DELETE) - * - Users (GET) - * - * Payroll Tests Covered - * - Pay Items (GET, POST) - * - Payroll Employees (GET, POST) - * - Timesheets (GET, POST) - */ - var organisationCountry = ""; -var APPTYPE = "PRIVATE"; +var APPTYPE = "PUBLIC"; var privateConfigFile = "/Users/jordan.walsh/.xero/private_app_config.json"; var publicConfigFile = "/Users/jordan.walsh/.xero/public_app_config.json"; var configFile = ""; @@ -238,7 +214,7 @@ describe('regression tests', function() { var InvoiceID = ""; var PaymentID = ""; - describe.skip('organisations', function() { + describe('organisations', function() { it('get', function(done) { this.timeout(10000); currentApp.core.organisations.getOrganisation() @@ -259,7 +235,7 @@ describe('regression tests', function() { }) }) - describe.skip('accounts', function() { + describe('accounts', function() { //Accounts supporting data var accountClasses = ["ASSET", "EQUITY", "EXPENSE", "LIABILITY", "REVENUE"]; @@ -456,7 +432,7 @@ describe('regression tests', function() { }); - describe.skip('invoices', function() { + describe('invoices', function() { it('create invoice', function(done) { this.timeout(10000); @@ -556,7 +532,7 @@ describe('regression tests', function() { }) }); - describe.skip('payments', function() { + describe('payments', function() { /* Please note that this test pays an invoice created in the previous tests */ this.timeout(10000); it('Create Payment', function(done) { @@ -644,7 +620,7 @@ describe('regression tests', function() { }); - describe.skip('bank transactions', function() { + describe('bank transactions', function() { var sharedTransaction; @@ -711,7 +687,7 @@ describe('regression tests', function() { }); }); - describe.skip('bank transfers', function() { + describe('bank transfers', function() { this.timeout(20000); @@ -935,7 +911,7 @@ describe('regression tests', function() { }); }); - describe.skip('items', function() { + describe('items', function() { this.timeout(10000); var sampleItem = { @@ -1044,7 +1020,7 @@ describe('regression tests', function() { }); }); - describe.skip('contacts', function() { + describe('contacts', function() { var sampleContact = { Name: 'Johnnies Coffee' + Math.random(), FirstName: 'John', @@ -1233,7 +1209,7 @@ describe('regression tests', function() { }); }) - describe.skip('journals', function() { + describe('journals', function() { this.timeout(10000); var sampleJournalId = ""; @@ -1314,6 +1290,79 @@ describe('regression tests', function() { }) }); }); + + describe('users', function() { + this.timeout(20000); + + it('retrieves a list of users', function(done) { + + currentApp.core.users.getUsers() + .then(function(users) { + done(); + }) + .fail(function(err) { + console.log(err) + done(wrapError(err)); + }); + }); + }); + + //These tests aren't currently working. Attachments are not yet supported. + describe.skip('attachments', function() { + this.timeout(20000); + + it('creates an attachment on an invoice', function(done) { + + /** + * Attachments should work on the following endpoints: + * Invoices + * Receipts + * Credit Notes + * Repeating Invoices + * Bank Transactions + * Bank Transfers + * Contacts + * Accounts + * Manual Journals + */ + + var attachmentData = { + FileName: "myimage.png", + MimeType: "application/png" + }; + + var rawDataFile = __dirname + "/testdata/test-attachment.png"; + + var attachmentPlaceholder = currentApp.core.attachments.newAttachment(attachmentData); + + currentApp.core.bankTransactions.getBankTransactions() + .then(function(bankTransactions) { + + expect(bankTransactions).to.have.length.greaterThan(0); + + var sampleTransaction = bankTransactions[0]; + + attachmentPlaceholder.save("banktransactions/" + sampleTransaction.BankTransactionID, rawDataFile) + .then(function(response) { + console.log(response); + done(); + }) + .fail(function(err) { + console.log(err) + done(wrapError(err)); + }) + + done(); + }) + .fail(function(err) { + console.log(err) + done(wrapError(err)); + }) + + + + }); + }); }); function wrapError(err) {