mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
368 lines
11 KiB
JavaScript
368 lines
11 KiB
JavaScript
var app, iapMock, inApp, rewire, sinon;
|
|
|
|
app = require('../../website/src/server');
|
|
|
|
rewire = require('rewire');
|
|
|
|
sinon = require('sinon');
|
|
|
|
inApp = rewire('../../website/src/controllers/payments/iap');
|
|
|
|
iapMock = {};
|
|
|
|
inApp.__set__('iap', iapMock);
|
|
|
|
describe('In-App Purchases', function() {
|
|
describe('Android', function() {
|
|
var next, paymentSpy, req, res;
|
|
req = {
|
|
body: {
|
|
transaction: {
|
|
reciept: 'foo',
|
|
signature: 'sig'
|
|
}
|
|
}
|
|
};
|
|
res = {
|
|
locals: {
|
|
user: {
|
|
_id: 'user'
|
|
}
|
|
},
|
|
json: sinon.spy()
|
|
};
|
|
next = function() {
|
|
return true;
|
|
};
|
|
paymentSpy = sinon.spy();
|
|
before(function() {
|
|
return inApp.__set__('payments.buyGems', paymentSpy);
|
|
});
|
|
afterEach(function() {
|
|
paymentSpy.reset();
|
|
return res.json.reset();
|
|
});
|
|
context('successful app purchase', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
|
|
return cb(null, true);
|
|
};
|
|
iapMock.isValidated = function(googleRes) {
|
|
return googleRes;
|
|
};
|
|
return iapMock.GOOGLE = 'google';
|
|
});
|
|
it('calls res.json with succesful result object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: true,
|
|
data: true
|
|
};
|
|
inApp.androidVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('calls payments.buyGems function', function() {
|
|
inApp.androidVerify(req, res, next);
|
|
expect(paymentSpy).to.be.calledOnce;
|
|
return expect(paymentSpy).to.be.calledWith({
|
|
user: res.locals.user,
|
|
paymentMethod: 'IAP GooglePlay',
|
|
amount: 5.25
|
|
});
|
|
});
|
|
});
|
|
context('error in setup', function() {
|
|
before(function() {
|
|
return iapMock.setup = function(cb) {
|
|
return cb("error in setup");
|
|
};
|
|
});
|
|
it('calls res.json with setup error object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: 'IAP Error'
|
|
};
|
|
inApp.androidVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.androidVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
context('error in validation', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
return iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
|
|
return cb('error in validation', true);
|
|
};
|
|
});
|
|
it('calls res.json with validation error object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: {
|
|
code: 6778001,
|
|
message: 'error in validation'
|
|
}
|
|
};
|
|
inApp.androidVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.androidVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
return context('iap is not valid', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapGoogle, iapBodyReciept, cb) {
|
|
return cb(null, false);
|
|
};
|
|
return iapMock.isValidated = function(googleRes) {
|
|
return googleRes;
|
|
};
|
|
});
|
|
it('does not call res.json', function() {
|
|
inApp.androidVerify(req, res, next);
|
|
return expect(res.json).to.not.be.called;
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.androidVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
});
|
|
return describe('iOS', function() {
|
|
var next, paymentSpy, req, res;
|
|
req = {
|
|
body: {
|
|
transaction: {
|
|
reciept: 'foo'
|
|
}
|
|
}
|
|
};
|
|
res = {
|
|
locals: {
|
|
user: {
|
|
_id: 'user'
|
|
}
|
|
},
|
|
json: sinon.spy()
|
|
};
|
|
next = function() {
|
|
return true;
|
|
};
|
|
paymentSpy = sinon.spy();
|
|
before(function() {
|
|
return inApp.__set__('payments.buyGems', paymentSpy);
|
|
});
|
|
afterEach(function() {
|
|
paymentSpy.reset();
|
|
return res.json.reset();
|
|
});
|
|
context('successful app purchase', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
|
|
return cb(null, true);
|
|
};
|
|
iapMock.isValidated = function(appleRes) {
|
|
return appleRes;
|
|
};
|
|
iapMock.getPurchaseData = function(appleRes) {
|
|
return [
|
|
{
|
|
productId: 'com.habitrpg.ios.Habitica.20gems'
|
|
}
|
|
];
|
|
};
|
|
return iapMock.APPLE = 'apple';
|
|
});
|
|
it('calls res.json with succesful result object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: true,
|
|
data: true
|
|
};
|
|
inApp.iosVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
expect(paymentSpy).to.be.calledOnce;
|
|
return expect(paymentSpy).to.be.calledWith({
|
|
user: res.locals.user,
|
|
paymentMethod: 'IAP AppleStore',
|
|
amount: 5.25
|
|
});
|
|
});
|
|
});
|
|
context('error in setup', function() {
|
|
before(function() {
|
|
return iapMock.setup = function(cb) {
|
|
return cb("error in setup");
|
|
};
|
|
});
|
|
it('calls res.json with setup error object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: 'IAP Error'
|
|
};
|
|
inApp.iosVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
context('error in validation', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
return iapMock.validate = function(iapApple, iapBodyReciept, cb) {
|
|
return cb('error in validation', true);
|
|
};
|
|
});
|
|
it('calls res.json with validation error object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: {
|
|
code: 6778001,
|
|
message: 'error in validation'
|
|
}
|
|
};
|
|
inApp.iosVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
context('iap is not valid', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
|
|
return cb(null, false);
|
|
};
|
|
return iapMock.isValidated = function(appleRes) {
|
|
return appleRes;
|
|
};
|
|
});
|
|
it('does not call res.json', function() {
|
|
var expectedResObj;
|
|
inApp.iosVerify(req, res, next);
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: {
|
|
code: 6778001,
|
|
message: 'Invalid receipt'
|
|
}
|
|
};
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
context('iap is valid but has no purchaseDataList', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
|
|
return cb(null, true);
|
|
};
|
|
iapMock.isValidated = function(appleRes) {
|
|
return appleRes;
|
|
};
|
|
iapMock.getPurchaseData = function(appleRes) {
|
|
return [];
|
|
};
|
|
return iapMock.APPLE = 'apple';
|
|
});
|
|
it('calls res.json with succesful result object', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: {
|
|
code: 6778001,
|
|
message: 'Incorrect receipt content'
|
|
}
|
|
};
|
|
inApp.iosVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
return context('iap is valid, has purchaseDataList, but productId does not match', function() {
|
|
before(function() {
|
|
iapMock.setup = function(cb) {
|
|
return cb(null);
|
|
};
|
|
iapMock.validate = function(iapApple, iapBodyReciept, cb) {
|
|
return cb(null, true);
|
|
};
|
|
iapMock.isValidated = function(appleRes) {
|
|
return appleRes;
|
|
};
|
|
iapMock.getPurchaseData = function(appleRes) {
|
|
return [
|
|
{
|
|
productId: 'com.another.company'
|
|
}
|
|
];
|
|
};
|
|
return iapMock.APPLE = 'apple';
|
|
});
|
|
it('calls res.json with incorrect reciept obj', function() {
|
|
var expectedResObj;
|
|
expectedResObj = {
|
|
ok: false,
|
|
data: {
|
|
code: 6778001,
|
|
message: 'Incorrect receipt content'
|
|
}
|
|
};
|
|
inApp.iosVerify(req, res, next);
|
|
expect(res.json).to.be.calledOnce;
|
|
return expect(res.json).to.be.calledWith(expectedResObj);
|
|
});
|
|
return it('does not calls payments.buyGems function', function() {
|
|
inApp.iosVerify(req, res, next);
|
|
return expect(paymentSpy).to.not.be.called;
|
|
});
|
|
});
|
|
});
|
|
});
|