Comparing version 0.1.0 to 0.2.0
@@ -11,6 +11,6 @@ var _ = require('lodash'); | ||
key: null, | ||
login: null, | ||
password: null, | ||
wsdl: 'https://webapi.allegro.pl/service.php?wsdl', | ||
countryId: Country.POLAND, | ||
login: null, | ||
password: null | ||
countryId: Country.POLAND | ||
}; | ||
@@ -33,2 +33,10 @@ | ||
if (!options.login) { | ||
throw new Error('No login provided'); | ||
} | ||
if (!options.password) { | ||
throw new Error('No password provided'); | ||
} | ||
return options; | ||
@@ -35,0 +43,0 @@ }; |
(function () { | ||
'use strict'; | ||
var crypto = require('crypto'); | ||
var util = require('util'); | ||
var EventEmitter = require('events').EventEmitter; | ||
var hasher = require('./hasher'); | ||
var User = require('./model/user'); | ||
var Item = require('./model/item'); | ||
var Category = require('./model/category'); | ||
var generatePasswordHash = function (password) { | ||
var sha256 = crypto.createHash('sha256'); | ||
sha256.update(password, 'utf8'); | ||
return sha256.digest('base64'); | ||
}; | ||
var JOURNAL_INTERVAL = 1000; | ||
var EVENT_BUYNOW = 'buynow'; | ||
var API_CHANGE_BUYNOW = 'now'; | ||
var Client = function (options) { | ||
EventEmitter.call(this); | ||
options = options || {}; | ||
if (!options.soapClient) { | ||
throw new Error('No soap client provided'); | ||
} | ||
if (!options.key) { | ||
throw new Error('No api key provided'); | ||
} | ||
if (!options.countryId) { | ||
throw new Error('No country id provided'); | ||
} | ||
this._soapClient = options.soapClient; | ||
this._key = options.key; | ||
this._login = options.login; | ||
this._passwordHash = hasher.generatePasswordHash(options.password); | ||
this._countryId = options.countryId; | ||
this._localVersion = '1377862002'; | ||
this._localVersion = '1378200949'; | ||
if (options.login && options.password) { | ||
this._login = options.login; | ||
this._passwordHash = generatePasswordHash(options.password); | ||
} | ||
var sessionHandle = null; | ||
var self = this; | ||
this._loginUser = function (callback) { | ||
if (sessionHandle) { | ||
callback(null, { | ||
sessionHandlePart: sessionHandle | ||
}); | ||
} else { | ||
self._soapClient.doLoginEnc({ | ||
'userLogin': self._login, | ||
'userHashPassword': self._passwordHash, | ||
'countryCode': self._countryId, | ||
'webapiKey': self._key, | ||
'localVersion': self._localVersion | ||
}, function (err, result) { | ||
sessionHandle = result.sessionHandlePart; | ||
callback(err, result); | ||
}); | ||
} | ||
}; | ||
var oldestRowId = null; | ||
this.on('newListener', function (event) { | ||
if (event === EVENT_BUYNOW) { | ||
setInterval(function () { | ||
self._loginUser(function (err, result) { | ||
var callArgs = {}; | ||
if (oldestRowId) { | ||
callArgs = { | ||
sessionHandle: result.sessionHandlePart, | ||
startingPoint: parseFloat(oldestRowId), | ||
infoType: 1 | ||
}; | ||
} else { | ||
callArgs = { | ||
sessionHandle: result.sessionHandlePart, | ||
infoType: 1 | ||
}; | ||
} | ||
self._soapClient.doGetSiteJournal(callArgs, function (err, result) { | ||
if (!err) { | ||
Object.keys(result.siteJournalArray[0].item).forEach(function (key) { | ||
var row = result.siteJournalArray[0].item[key]; | ||
if (row.changeType === API_CHANGE_BUYNOW) { | ||
self.emit(event, row.itemId); | ||
} | ||
oldestRowId = row.rowId; | ||
}); | ||
} | ||
}); | ||
}); | ||
}, JOURNAL_INTERVAL); | ||
} | ||
}); | ||
}; | ||
util.inherits(Client, EventEmitter); | ||
Client.prototype.getUser = function (userId, callback) { | ||
@@ -56,27 +102,34 @@ this._soapClient.doShowUser({ | ||
var self = this; | ||
if (this._login && this._passwordHash) { | ||
this._soapClient.doLoginEnc({ | ||
'userLogin': this._login, | ||
'userHashPassword': this._passwordHash, | ||
'countryCode': this._countryId, | ||
'webapiKey': this._key, | ||
'localVersion': this._localVersion | ||
this._loginUser(function (err, result) { | ||
self._soapClient.doShowItemInfoExt({ | ||
sessionHandle: result.sessionHandlePart, | ||
itemId: itemId | ||
}, function (err, result) { | ||
self._soapClient.doShowItemInfoExt({ | ||
sessionHandle: result.sessionHandlePart, | ||
itemId: itemId | ||
}, function (err, result) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(null, new Item(result.itemListInfoExt)); | ||
} | ||
}); | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(null, new Item(result.itemListInfoExt, self)); | ||
} | ||
}); | ||
} else { | ||
callback(new Error('Method requires session but no credential passed')); | ||
} | ||
}); | ||
}; | ||
Client.prototype.getCategory = function (itemId, callback) { | ||
var self = this; | ||
this._loginUser(function (err, result) { | ||
self._soapClient.doGetCategoryPath({ | ||
sessionId: result.sessionHandlePart, | ||
categoryId: itemId | ||
}, function (err, result) { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
var categories = result.categoryPath[0].item.length; | ||
callback(null, new Category(result.categoryPath[0].item[categories - 1])); | ||
} | ||
}); | ||
}); | ||
}; | ||
module.exports = Client; | ||
})(); |
(function () { | ||
'use strict'; | ||
function Item(apiItem) { | ||
function Item(apiItem, client) { | ||
if (!client) { | ||
throw new Error('Client instance required'); | ||
} | ||
this._client = client; | ||
this._id = apiItem.itId; | ||
this._name = apiItem.itName; | ||
this._sellerId = apiItem.itSellerId; | ||
this._location = apiItem.itLocation; | ||
} | ||
@@ -15,2 +23,10 @@ | ||
return this._name; | ||
}, | ||
get location() { | ||
return this._location; | ||
}, | ||
getSeller: function (callback) { | ||
this._client.getUser(this._sellerId, function (err, user) { | ||
callback(err, user); | ||
}); | ||
} | ||
@@ -17,0 +33,0 @@ }; |
@@ -7,2 +7,5 @@ (function () { | ||
this._login = apiUser.userLogin; | ||
this._rating = apiUser.userRating; | ||
this._createdAt = new Date(apiUser.userCreateDate * 1000); | ||
this._isAllegroStandard = (apiUser.userIsAllegroStandard === 1) ? true : false; | ||
} | ||
@@ -16,2 +19,11 @@ | ||
return this._login; | ||
}, | ||
get rating() { | ||
return this._rating; | ||
}, | ||
get createdAt() { | ||
return this._createdAt; | ||
}, | ||
get isAllegroStandard() { | ||
return this._isAllegroStandard; | ||
} | ||
@@ -18,0 +30,0 @@ }; |
{ | ||
"name": "allegro", | ||
"version": "0.1.0", | ||
"description": "Allegro.pl WebApi client", | ||
"version": "0.2.0", | ||
"description": "Allegro.pl WebAPI client", | ||
"keywords": [ | ||
@@ -6,0 +6,0 @@ "allegro", "api", "soap" |
140
README.md
@@ -1,4 +0,138 @@ | ||
allegro.js | ||
========== | ||
# allegro.js | ||
[![Build Status](https://travis-ci.org/mthenw/allegro.js.png)](https://travis-ci.org/mthenw/allegro.js) | ||
[![Build Status](https://travis-ci.org/mthenw/allegro.js.png)](https://travis-ci.org/mthenw/allegro.js) | ||
# Installation | ||
``` | ||
npm install allegro | ||
``` | ||
# Usage | ||
``` | ||
var allegro = require('allegro'); | ||
allegro.createClient({ key: 'your_webapi_key'}, function (err, client) { | ||
client.getUser(26729811, function (err, user) { | ||
console.log(user.login); | ||
}); | ||
}); | ||
``` | ||
# Documentation | ||
## allegro | ||
### createClient(options, callback) | ||
Creates API client. Available options: | ||
* ```key``` - WebAPI key, can be generated in [My Allegro](http://allegro.pl/myaccount/webapi.php) (required), | ||
* ```countryId``` - country code, default: 1 (Poland) | ||
* ```login``` - user login, credentials are needed to call some of methods (I don't know why but even for those not related to My Allegro) so, in most cases you should provide them, | ||
* ```password``` - user password. | ||
```callback``` gets two arguments: | ||
* ```error``` - Error instance if error occured, | ||
* ```client``` - [Client](#client) instance | ||
#### Example | ||
``` | ||
var allegro = require('allegro'); | ||
var key = 'your_webapi_key'; | ||
allegro.createClient({ key: 'your_webapi_key'}, function (error, client) { | ||
... | ||
}); | ||
``` | ||
## Client | ||
### getCategory(categoryId, callback) | ||
Get [Category](#category) instance by id and pass to callback. | ||
#### Example | ||
``` | ||
allegro.createClient({ … }, function (error, client) { | ||
client.getCategory(149, function (error, category) { | ||
console.log(category.name); // 'Samochody' | ||
}); | ||
}); | ||
``` | ||
### getItem(itemId, callback) | ||
Get [Item](#item) instance by id and pass to callback. | ||
#### Example | ||
``` | ||
allegro.createClient({ … }, function (error, client) { | ||
client.getItem(3482560106, function (error, item) { | ||
console.log(item.name); // 'IGŁA BMW E90' | ||
}); | ||
}); | ||
``` | ||
### getUser(userId, callback) | ||
Get [User](#user) instance by id and pass to callback. | ||
#### Example | ||
``` | ||
allegro.createClient({ … }, function (error, client) { | ||
client.getUser(26729811, function (error, user) { | ||
console.log(user.login); // 'stendi_pl' | ||
}); | ||
}); | ||
``` | ||
## Category | ||
### Proporties: | ||
* ```id``` int, | ||
* ```name``` string. | ||
## Item | ||
### Proporties: | ||
* ```id``` int, | ||
* ```name``` string. | ||
### Methods: | ||
* ```getSeller(callback)``` get [User](#user) instance of seller. ```callback``` gets error and [User](#user) instance. Example: | ||
``` | ||
allegro.createClient({ … }, function (error, client) { | ||
client.getItem(3509260334, function (error, item) { | ||
item.getSeller(function(error, user) { | ||
console.log(user.login); // 'stendi_pl' | ||
}) | ||
}); | ||
}); | ||
``` | ||
## User | ||
### Proporties: | ||
* ```id``` int, | ||
* ```login``` string, | ||
* ```rating``` int, | ||
* ```createdAt``` Date, | ||
* ```isAllegroStandrd``` bool. |
@@ -14,4 +14,21 @@ require('should'); | ||
it('should return an error if no login provided for creating client', function () { | ||
allegro.createClient({key: 'key'}, function (err) { | ||
err.should.be.an.instanceOf(Error); | ||
}); | ||
}); | ||
it('should return an error if no password provided for creating client', function () { | ||
allegro.createClient({key: 'key', login: 'login'}, function (err) { | ||
err.should.be.an.instanceOf(Error); | ||
}); | ||
}); | ||
it('should create client instance', function (done) { | ||
allegro.createClient({key: 'key', wsdl: __dirname + '/webapi.wsdl'}, function (err, client) { | ||
allegro.createClient({ | ||
key: 'key', | ||
login: 'login', | ||
password: 'password', | ||
wsdl: __dirname + '/webapi.wsdl' | ||
}, function (err, client) { | ||
client.should.be.an.instanceOf(Client); | ||
@@ -18,0 +35,0 @@ done(); |
@@ -11,39 +11,18 @@ require('should'); | ||
it('should require soap instance in constructor', function () { | ||
(function () { | ||
new Client(); | ||
}).should.throwError('No soap client provided'); | ||
}); | ||
it('should require key in constructor', function () { | ||
(function () { | ||
new Client({ | ||
soapClient: {} | ||
}); | ||
}).should.throwError('No api key provided'); | ||
}); | ||
it('should require country in constructor', function () { | ||
(function () { | ||
new Client({ | ||
soapClient: {}, | ||
key: 'key' | ||
}); | ||
}).should.throwError('No country id provided'); | ||
}); | ||
it('should return user model by user id', function (done) { | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var doShowUserStub = sinon.stub(soapClient, 'doShowUser'); | ||
doShowUserStub.callsArgWith(1, null, { | ||
'userId': 123, | ||
'userLogin': 'Test user' | ||
doShowUserStub.callsArgWith(1, null, {userId: 1}); | ||
var client = new Client({ | ||
soapClient: soapClient, | ||
key: 'key', | ||
countryId: 1, | ||
login: 'login', | ||
password: 'pass' | ||
}); | ||
var client = new Client({soapClient: soapClient, key: 'key', countryId: 1}); | ||
client.getUser(123, function (err, user) { | ||
client.getUser(1, function (err, user) { | ||
doShowUserStub.calledOnce.should.equal(true); | ||
user.should.be.an.instanceOf(User); | ||
user.id.should.equal(123); | ||
user.login.should.equal('Test user'); | ||
user.id.should.equal(1); | ||
done(); | ||
@@ -54,13 +33,2 @@ }); | ||
it('should return an error if no credential passed when getting item data', function (done) { | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var client = new Client({soapClient: soapClient, key: 'key', countryId: 1}); | ||
client.getItem(123, function (err) { | ||
err.should.be.instanceOf(Error); | ||
err.message.should.be.equal('Method requires session but no credential passed'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should login user before getting item data', function (done) { | ||
@@ -70,3 +38,3 @@ soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
doLoginEncStub.callsArgWith(1, null, { | ||
'sessionHandlePart': 'qwe', | ||
'sessionHandlePart': 'session1', | ||
'userId': 1 | ||
@@ -98,3 +66,3 @@ }); | ||
webapiKey: 'key', | ||
localVersion: '1377862002' | ||
localVersion: '1378200949' | ||
}).should.equal(true); | ||
@@ -111,3 +79,3 @@ done(); | ||
sessionHandlePart: 'session1', | ||
userId: 1 | ||
userId: 100 | ||
}); | ||
@@ -117,6 +85,3 @@ | ||
doShowItemInfoExtStub.callsArgWith(1, null, { | ||
itemListInfoExt: { | ||
itId: 2, | ||
itName: 'Test item' | ||
} | ||
itemListInfoExt: {itId: 2} | ||
}); | ||
@@ -141,3 +106,2 @@ | ||
item.id.should.be.equal(2); | ||
item.name.should.be.equal('Test item'); | ||
done(); | ||
@@ -147,2 +111,150 @@ }); | ||
}); | ||
it('should login user before getting category data', function (done) { | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var doLoginEncStub = sinon.stub(soapClient, 'doLoginEnc'); | ||
doLoginEncStub.callsArgWith(1, null, { | ||
'sessionHandlePart': 'session1', | ||
'userId': 1 | ||
}); | ||
var doGetCategoryPathStub = sinon.stub(soapClient, 'doGetCategoryPath'); | ||
doGetCategoryPathStub.callsArgWith(1, null, { | ||
categoryPath: [{ item: [{ | ||
catId: 2, | ||
catName: 'Category' | ||
}] | ||
}] | ||
}); | ||
var client = new Client({ | ||
soapClient: soapClient, | ||
key: 'key', | ||
countryId: 1, | ||
login: 'testuser', | ||
password: 'password' | ||
}); | ||
client.getCategory(2, function () { | ||
doLoginEncStub.calledOnce.should.equal(true); | ||
doLoginEncStub.calledWith({ | ||
userLogin: 'testuser', | ||
userHashPassword: 'XohImNooBHFR0OVvjcYpJ3NgPQ1qq73WKhHvch0VQtg=', | ||
countryCode: 1, | ||
webapiKey: 'key', | ||
localVersion: '1378200949' | ||
}).should.equal(true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should return category model by category id', function (done) { | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var doLoginEncStub = sinon.stub(soapClient, 'doLoginEnc'); | ||
doLoginEncStub.callsArgWith(1, null, { | ||
'sessionHandlePart': 'session1', | ||
'userId': 1 | ||
}); | ||
var doGetCategoryPathStub = sinon.stub(soapClient, 'doGetCategoryPath'); | ||
doGetCategoryPathStub.callsArgWith(1, null, { | ||
categoryPath: [{ item: [{ | ||
catId: 2, | ||
catName: 'Category' | ||
}] | ||
}] | ||
}); | ||
var client = new Client({ | ||
soapClient: soapClient, | ||
key: 'key', | ||
countryId: 1, | ||
login: 'testuser', | ||
password: 'password' | ||
}); | ||
client.getCategory(2, function () { | ||
doGetCategoryPathStub.calledOnce.should.equal(true); | ||
doGetCategoryPathStub.calledWith({ | ||
sessionId: 'session1', | ||
categoryId: 2 | ||
}).should.equal(true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should emit event when somebody buy using "buy now"', function (done) { | ||
var clock = sinon.useFakeTimers(); | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var doLoginEncStub = sinon.stub(soapClient, 'doLoginEnc'); | ||
doLoginEncStub.callsArgWith(1, null, { | ||
'sessionHandlePart': 'session1', | ||
'userId': 1 | ||
}); | ||
var doGetSiteJournalStub = sinon.stub(soapClient, 'doGetSiteJournal'); | ||
doGetSiteJournalStub.callsArgWith(1, null, { | ||
siteJournalArray: [{ | ||
item: [{ | ||
rowId: 1, | ||
itemId: 2, | ||
changeType: 'now' | ||
}] | ||
}] | ||
}); | ||
var client = new Client({ | ||
soapClient: soapClient, | ||
key: 'key', | ||
countryId: 1, | ||
login: 'testuser', | ||
password: 'password' | ||
}); | ||
client.on('buynow', function (itemId) { | ||
doGetSiteJournalStub.calledOnce.should.equal(true); | ||
doGetSiteJournalStub.calledWith({ | ||
sessionHandle: 'session1', | ||
infoType: 1 | ||
}).should.equal(true); | ||
itemId.should.equal(2); | ||
done(); | ||
}); | ||
clock.tick(1000); | ||
clock.restore(); | ||
}); | ||
}); | ||
it('should login only once for two calls', function (done) { | ||
soap.createClient(__dirname + '/webapi.wsdl', function (err, soapClient) { | ||
var doLoginEncStub = sinon.stub(soapClient, 'doLoginEnc'); | ||
doLoginEncStub.callsArgWith(1, null, { | ||
'sessionHandlePart': 'session1', | ||
'userId': 1 | ||
}); | ||
var doShowItemInfoExtStub = sinon.stub(soapClient, 'doShowItemInfoExt'); | ||
doShowItemInfoExtStub.callsArgWith(1, null, {itemListInfoExt: {itId: 1, itName: 'Item'}}); | ||
var client = new Client({ | ||
soapClient: soapClient, | ||
key: 'key', | ||
countryId: 1, | ||
login: 'testuser', | ||
password: 'password' | ||
}); | ||
client.getItem(1, function () { | ||
client.getItem(1, function () { | ||
doLoginEncStub.calledOnce.should.equal(true); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
272559
21
598
139
1