UNPKG

bitcore-wallet-client

Version:
230 lines (210 loc) 6.33 kB
'use strict'; const chai = require('chai'); const sinon = require('sinon'); const crypto = require('crypto'); const should = chai.should(); const { PayPro: payPro } = require('../ts_build/lib/paypro'); const TestData = require('./testdata'); function mockRequest(bodyBuf, headers) { bodyBuf = Array.isArray(bodyBuf) ? bodyBuf : [bodyBuf]; payPro.r = { 'get': (_url) => { return { set: (_k, _v) => { }, query: (_opts) => { }, end: (cb) => { return cb(null, { headers: headers || {}, statusCode: 200, statusMessage: 'OK', text: bodyBuf.shift() }) } } }, 'post': (_url) => { return { set: (_k, _v) => { }, send: (_opts) => { }, end: (cb) => { return cb(null, { headers: headers || {}, statusCode: 200, statusMessage: 'OK', text: bodyBuf.shift() }) } } } } }; describe('paypro', function () { var clock, oldreq; before(function () { // Stub time before cert expiration at Mar 27 2016 clock = sinon.useFakeTimers(1459105693843); }); beforeEach(() => { oldreq = payPro.r; }); after(function () { clock.restore(); }); afterEach(function () { payPro.r = oldreq; }); it('Make and verify PP request', function (done) { mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), TestData.payProJson.bch.headers); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { should.not.exist(err); res.should.be.deep.equal({ "amount": 769200, "coin": "bch", "expires": "2019-03-07T18:20:44.301Z", "memo": "Payment request for BitPay invoice 3oZcpotopVGcZ2stRw2dop for merchant GusPay", "network": "testnet", "paymentId": "3oZcpotopVGcZ2stRw2dop", "requiredFeeRate": 1.398, "toAddress": "qz78y0832kskq84rr4f9t22fequ5c0l4gu6wsehezr", "verified": true, }); done(); }); }); it('Should handle a failed (404) request', function (done) { payPro.r = { 'get': (_url) => { return { set: (_k, _v) => { }, query: (_opts) => { }, end: (cb) => { return cb(null, { statusCode: 404, statusMessage: 'Not Found', }, 'This invoice was not found or has been archived'); } } }, 'post': () => { } } payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { should.exist(err); done(); }); }); it('Should detect a tampered PP request (bad signature)', function (done) { let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers)); h.signature = crypto.randomBytes(64).toString('hex'); mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { err.toString().should.contain('signature invalid'); done(); }); }); it('Should detect a tampered PP request (short signature)', function (done) { let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers)); h.signature = h.signature.slice(0, -1); mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { err.toString().should.contain('signature invalid'); done(); }); }); it('Should detect a tampered PP request (non-hex signature)', function (done) { let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers)); h.signature = crypto.randomBytes(64).toString('base64'); mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { err.toString().should.contain('signature invalid'); done(); }); }); it('Should detect a tampered PP request (bogus signature)', function (done) { let h = JSON.parse(JSON.stringify(TestData.payProJson.bch.headers)); h.signature = 'xx'; mockRequest(Buffer.from(TestData.payProJson.bch.body, 'hex'), h); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { err.toString().should.contain('signature invalid'); done(); }); }); it('Should detect a tampered PP request (bad amount)', function (done) { let b = JSON.parse(TestData.payProJson.bch.body); b.outputs[0].amount = 100; b = JSON.stringify(b); mockRequest(Buffer.from(b), TestData.payProJson.bch.headers); payPro.get({ url: 'https://test.bitpay.com/paypro', network: 'testnet', coin: 'bch', }, function (err, res) { err.toString().should.contain('not match digest'); done(); }); }); it('should send a PP payment', function (done) { var opts = { rawTx: 'rawTx1', rawTxUnsigned: 'rawTxUnsigned', url: 'http://an.url.com/paypro', coin: 'bch', }; mockRequest([Buffer.from('{"memo":"Payment seems OK"}'), Buffer.from('{"memo":"memo1"}')], { }); payPro.send(opts, function (err, data, memo) { should.not.exist(err); memo.should.equal('memo1'); done(); }); }); it('should not send PP payment if verify fails', function (done) { var opts = { rawTx: 'rawTx1', rawTxUnsigned: 'rawTxUnsigned', url: 'http://an.url.com/paypro', coin: 'bch', }; payPro.r = { 'post': (_url) => { return { set: (_k, _v) => { }, send: (_opts) => { }, end: (cb) => { return cb(null, { statusCode: 400, statusMessage: 'ss', }, 'This invoice was not found or has been archived'); } } } } payPro.send(opts, function (err, data, memo) { should.exist(err); done(); }); }); });