Skip to content

Commit

Permalink
added various tests and updated sample app
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan Walsh committed Mar 6, 2017
1 parent 7e8a62d commit 5f719b1
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 75 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@
/coverage
.nyc_output/
.DS_Store
.vscode
49 changes: 25 additions & 24 deletions README.md
Expand Up @@ -65,7 +65,7 @@ The config file should be set up as follows:
"UserAgent" : "Tester (PUBLIC) - Application for testing Xero",
"ConsumerKey": "AAAAAAAAAAAAAAAAAA",
"ConsumerSecret": "BBBBBBBBBBBBBBBBBBBB",
"AuthorizeCallbackUrl": 'http://localhost:3100/access',
"AuthorizeCallbackUrl": 'https://www.mywebsite.com/xerocallback',
"RunscopeBucketId" : "xxxyyyzzzz"
}

Expand All @@ -74,24 +74,27 @@ The config file should be set up as follows:
"UserAgent" : "Tester (PARTNER) - Application for testing Xero",
"ConsumerKey": "AAAAAAAAAAAAAAAAAA",
"ConsumerSecret": "BBBBBBBBBBBBBBBBBBBB",
"RunscopeBucketId" : "xxxyyyzzzz",
"AuthorizeCallbackUrl": 'https://www.mywebsite.com/xerocallback',
"PrivateKeyPath" : "/some/path/to/partner_privatekey.pem",
"SSLCertPath" : "/some/path/to/partner_publickey.cer"
"SSLCertPath" : "/some/path/to/partner_publickey.cer",
"RunscopeBucketId" : "xxxyyyzzzz"
}
```

### Config Parameters

| Parameter | Description | Mandatory |
|------------------|------------------------------------------------------------------------------------------|-----------|
| UserAgent | The useragent that should be used with all calls to the Xero API | True |
| ConsumerKey | The consumer key that is required with all calls to the Xero API., | True |
| ConsumerSecret | The secret key from the developer portal that is required to authenticate your API calls | True |
| PrivateKeyPath | The filesystem path to your privatekey.pem file to sign the API calls | True |
| RunscopeBucketId | Your personal runscope bucket for debugging API calls | False |
| Parameter | Description | Mandatory |
|----------------------|------------------------------------------------------------------------------------------|-----------|
| UserAgent | The useragent that should be used with all calls to the Xero API | True |
| ConsumerKey | The consumer key that is required with all calls to the Xero API., | True |
| ConsumerSecret | The secret key from the developer portal that is required to authenticate your API calls | True |
| AuthorizeCallbackUrl | The callback that Xero should invoke when the authorization is successful. | False |
| PrivateKeyPath | The filesystem path to your privatekey.pem file to sign the API calls | False |
| SSLCertPath | The filesystem path to your publickey.pem file to sign the API calls | False |
| RunscopeBucketId | Your personal runscope bucket for debugging API calls | False |
---

`RunscopeBucketId` has been added to support debugging the SDK. Runscope is a simple tool for Testing Complex APIs. You can use Runscope to verify that the structure and content of your API calls meets your expectations.
**Note:** `RunscopeBucketId` has been added to support debugging the SDK. Runscope is a simple tool for Testing Complex APIs. You can use Runscope to verify that the structure and content of your API calls meets your expectations.

Sign up for a free runscope account at runscope.com and place your bucket ID in the config file to see API calls in real time.

Expand All @@ -108,21 +111,21 @@ var privateApp = new PrivateApplication();
// Alternatively a path to a JSON file can be provided as a parameter:

var myConfigFile = "/tmp/config.json";
var privateApp = new PrivateApplication(myConfigFile);
var xeroClient = new PrivateApplication(myConfigFile);
```

## Pubic Usage

```javascript
var PublicApplication = require('xero-node').PublicApplication;
var publicApp = new PublicApplication(myConfigFile);
var xeroClient = new PublicApplication(myConfigFile);
```

## Partner Usage - (Not currently tested)
## Partner Usage

```javascript
var ParnetApplication = require('xero-node').PartnerApplication;
var partnerApp = new PartnerApplication(myConfigFile);
var ParnerApplication = require('xero-node').PartnerApplication;
var xeroClient = new PartnerApplication(myConfigFile);
```

Examples
Expand All @@ -131,10 +134,9 @@ Print a count of invoices:

```javascript
//Print a count of invoices
privateApp.core.invoices.getInvoices()
xeroClient.core.invoices.getInvoices()
.then(function(invoices) {
console.log("Invoices: " + invoices.length);

}).fail(function(err) {
console.error(err);
});
Expand All @@ -144,7 +146,7 @@ Print the name of some filtered contacts:

```javascript
//Print the name of a contact
privateApp.core.contacts.getContacts({
xeroClient.core.contacts.getContacts({
where: 'Name.Contains("Bayside")'
})
.then(function(contacts) {
Expand All @@ -159,7 +161,7 @@ privateApp.core.contacts.getContacts({
Efficient paging:

```javascript
privateApp.core.contacts.getContacts({ pager: {start:1 /* page number */, callback:onContacts}})
xeroClient.core.contacts.getContacts({ pager: {start:1 /* page number */, callback: onContacts}})
.fail(function(err) {
console.log('Oh no, an error');
});
Expand All @@ -176,18 +178,17 @@ function onContacts(err, response, cb) {
Filter support: Modified After
```javascript
// No paging
publicApp.core.contacts.getContacts({
xeroClient.core.contacts.getContacts({
modifiedAfter: new Date(2013,1,1)
})
.then(function(contacts) {
_.each(contacts, function(contact) {
contacts.forEach(function(contact) {
// Do something with contact
})
});
})

```


## Tests

npm test
Expand Down
29 changes: 26 additions & 3 deletions lib/application.js
Expand Up @@ -142,6 +142,10 @@ _.extend(Application.prototype, {
}

})
.fail(function(err) {
logger.error(err);
throw err;
})

});
return deferred.promise;
Expand Down Expand Up @@ -193,6 +197,10 @@ _.extend(Application.prototype, {
deferred.resolve(ret);
callback && callback(null, obj, res);
})
.fail(function(err) {
logger.error(err);
throw err;
})
}, { stream: options.stream });

}
Expand Down Expand Up @@ -249,8 +257,13 @@ _.extend(Application.prototype, {
// Already done
return deferred.resolve();
}
if (err && data && data.indexOf('oauth_problem') >= 0) {
var dataParts = qs.parse(data);
if (err && data) {
var dataParts;
if (_.isObject(data))
dataParts = qs.parse(data);
else
dataParts = data;

var errObj = { statusCode: err.statusCode, data: dataParts };
deferred.reject(errObj);
callback && callback(errObj);
Expand Down Expand Up @@ -285,6 +298,10 @@ _.extend(Application.prototype, {
callback && callback(null, obj, res);
}
})
.fail(function(err) {
logger.error(err);
throw err;
})
}, { stream: options.stream });

}
Expand Down Expand Up @@ -348,12 +365,18 @@ _.extend(Application.prototype, {
if (ret && ret.response)
return ret.response;
})
.fail(function(err) {
logger.error(err);
throw err;
})

},
getEntities: function(path, options) {
var self = this;
var clonedOptions = _.clone(options || {});

var deferred = p.defer();

var callerPagerCallback;
if (clonedOptions.pager) {
callerPagerCallback = clonedOptions.pager.callback;
Expand All @@ -367,9 +390,9 @@ _.extend(Application.prototype, {
})
.fail(function(err) {
logger.error(err);
throw err;
})


function pagerCallback(err, result, cb) {

if (err) {
Expand Down
36 changes: 36 additions & 0 deletions lib/entities/taxrate.js
@@ -0,0 +1,36 @@
var _ = require('lodash'),
Entity = require('./entity'),
logger = require('../logger');

var TaxRateSchema = new Entity.SchemaObject({

});

var TaxRate = Entity.extend(TaxRateSchema, {
constructor: function(application, data, options) {
logger.debug('TaxRate::constructor');
this.Entity.apply(this, arguments);
},
initialize: function(data, options) {},
toXml: function() {
var taxRate = _.omit(this.toObject());
return this.application.js2xml(taxRate, 'TaxRate');
},
save: function(options) {
var self = this;
var xml = '<TaxRates>' + this.toXml() + '</TaxRates>';
var path, method;
if (this.TaxRateID) {
path = 'Items/' + this.ItemID;
method = 'post'
} else {
path = 'Items';
method = 'put'
}
return this.application.putOrPostEntity(method, path, xml, { entityPath: 'Items.Item', entityConstructor: function(data) { return self.application.core.items.newItem(data) } });
}
});


module.exports = TaxRate;
module.exports.TaxRateSchema = TaxRateSchema;
6 changes: 3 additions & 3 deletions lib/entity_helpers/contacts.js
Expand Up @@ -19,12 +19,12 @@ var Contacts = EntityHelper.extend({
})
},
saveContacts: function(contacts, options) {
return this.saveEntities(contacts, this.setupOptions(options));
return this.saveEntities(contacts, this.setUpOptions(options));
},
getContacts: function(options) {
return this.getEntities(this.setupOptions(options));
return this.getEntities(this.setUpOptions(options));
},
setupOptions: function(options) {
setUpOptions: function(options) {
var self = this;
var clonedOptions = _.clone(options || {});
clonedOptions.entityPath = 'Contacts.Contact';
Expand Down
10 changes: 10 additions & 0 deletions lib/entity_helpers/invoices.js
Expand Up @@ -26,6 +26,16 @@ var Invoices = EntityHelper.extend({
var clonedOptions = _.clone(options || {});
clonedOptions.entityConstructor = function(data) { return self.newInvoice(data) };
return this.getEntities(clonedOptions)
},
saveInvoices: function(invoices, options) {
return this.saveEntities(invoices, this.setUpOptions(options));
},
setUpOptions: function(options) {
var self = this;
var clonedOptions = _.clone(options || {});
clonedOptions.entityPath = 'Invoices.Invoice';
clonedOptions.entityConstructor = function(data) { return self.newInvoice(data) };
return clonedOptions;
}
})

Expand Down
41 changes: 17 additions & 24 deletions lib/entity_helpers/payroll_employees.js
@@ -1,40 +1,33 @@
var _ = require('lodash')
, logger = require('../logger')
, EntityHelper = require('./entity_helper')
, Employee = require('../entities/payroll_employee')
, p = require('../misc/promise')
, util = require('util')
var _ = require('lodash'),
logger = require('../logger'),
EntityHelper = require('./entity_helper'),
Employee = require('../entities/payroll_employee'),
p = require('../misc/promise'),
util = require('util')

var Employees = EntityHelper.extend({
constructor: function (application, options)
{
EntityHelper.call(this, application, _.extend({ entityName:'Employee', entityPlural:'Employees'}, options));
constructor: function(application, options) {
EntityHelper.call(this, application, _.extend({ entityName: 'Employee', entityPlural: 'Employees' }, options));
},
newEmployee: function (data, options)
{
newEmployee: function(data, options) {
return new Employee(this.application, data, options)
},
getEmployee: function (id, modifiedAfter,where, order)
{
return this.getEmployees({ id: id, modifiedAfter: modifiedAfter, where: where, order: order})
.then(function (employees)
{
getEmployee: function(id, modifiedAfter, where, order) {
return this.getEmployees({ id: id, modifiedAfter: modifiedAfter, where: where, order: order })
.then(function(employees) {
return _.first(employees);
})
},
saveEmployees: function (employees, options)
{
saveEmployees: function(employees, options) {
// TO-DO
// return this.saveEntities(employees, options)
},
getEmployees: function (options)
{
getEmployees: function(options) {
var self = this;
var clonedOptions = _.extend({},options, { api: 'payroll'});
clonedOptions.entityConstructor = function(data) { return self.newEmployee(data)};
var clonedOptions = _.extend({}, options, { api: 'payroll' });
clonedOptions.entityConstructor = function(data) { return self.newEmployee(data) };
return this.getEntities(clonedOptions)
}
})

module.exports = Employees;

module.exports = Employees;

0 comments on commit 5f719b1

Please sign in to comment.