paypro: tests - send raw http requests to test mock server.
This commit is contained in:
parent
f67e30bfd2
commit
785a9cdd31
2 changed files with 206 additions and 7 deletions
|
|
@ -804,7 +804,7 @@ Wallet.prototype.createPaymentTx = function(options, cb) {
|
||||||
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
||||||
'Content-Type': 'application/octet-stream'
|
'Content-Type': 'application/octet-stream'
|
||||||
// XHR does not allow this:
|
// XHR does not allow this:
|
||||||
// 'Content-Length': 0
|
// 'Content-Length': '0'
|
||||||
},
|
},
|
||||||
responseType: 'arraybuffer'
|
responseType: 'arraybuffer'
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -158,11 +158,31 @@ describe('PayPro (in Wallet) model', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var pr;
|
||||||
|
|
||||||
it('#retrieve a payment request message via http', function(done) {
|
it('#retrieve a payment request message via http', function(done) {
|
||||||
var w = createWallet();
|
var w = createWallet();
|
||||||
should.exist(w);
|
should.exist(w);
|
||||||
var req = {};
|
|
||||||
|
var req = {
|
||||||
|
headers: {
|
||||||
|
'Host': 'localhost:8080',
|
||||||
|
'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
|
||||||
|
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
||||||
|
'Content-Type': 'application/octet-stream',
|
||||||
|
'Content-Length': '0'
|
||||||
|
},
|
||||||
|
socket: {
|
||||||
|
remoteAddress: 'localhost',
|
||||||
|
remotePort: 8080
|
||||||
|
},
|
||||||
|
body: {}
|
||||||
|
};
|
||||||
|
|
||||||
server.POST['/-/request'](req, function(err, res, body) {
|
server.POST['/-/request'](req, function(err, res, body) {
|
||||||
|
var data = PayPro.PaymentRequest.decode(body);
|
||||||
|
pr = new PayPro();
|
||||||
|
pr = pr.makePaymentRequest(data);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -170,8 +190,187 @@ describe('PayPro (in Wallet) model', function() {
|
||||||
it('#send a payment message via http', function(done) {
|
it('#send a payment message via http', function(done) {
|
||||||
var w = createWallet();
|
var w = createWallet();
|
||||||
should.exist(w);
|
should.exist(w);
|
||||||
var req = {};
|
|
||||||
|
var ver = pr.get('payment_details_version');
|
||||||
|
var pki_type = pr.get('pki_type');
|
||||||
|
var pki_data = pr.get('pki_data');
|
||||||
|
var details = pr.get('serialized_payment_details');
|
||||||
|
var sig = pr.get('signature');
|
||||||
|
|
||||||
|
var certs = PayPro.X509Certificates.decode(pki_data);
|
||||||
|
certs = certs.certificate;
|
||||||
|
|
||||||
|
var verified = pr.verify();
|
||||||
|
|
||||||
|
if (!verified) {
|
||||||
|
return done(new Error('Server sent a bad signature.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
details = PayPro.PaymentDetails.decode(details);
|
||||||
|
var pd = new PayPro();
|
||||||
|
pd = pd.makePaymentDetails(details);
|
||||||
|
|
||||||
|
var network = pd.get('network');
|
||||||
|
var outputs = pd.get('outputs');
|
||||||
|
var time = pd.get('time');
|
||||||
|
var expires = pd.get('expires');
|
||||||
|
var memo = pd.get('memo');
|
||||||
|
var payment_url = pd.get('payment_url');
|
||||||
|
var merchant_data = pd.get('merchant_data');
|
||||||
|
|
||||||
|
var opts = {
|
||||||
|
remainderOut: {
|
||||||
|
address: w._doGenerateAddress(true).toString()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var outs = [];
|
||||||
|
outputs.forEach(function(output) {
|
||||||
|
outs.push({
|
||||||
|
address: w.getAddressesStr()[0] || '2N6J45pqfu5y7zgWDwXDAmdd8qzK1oRdz3A',
|
||||||
|
amountSatStr: '0'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var b = new bitcore.TransactionBuilder(opts)
|
||||||
|
.setUnspent(unspent)
|
||||||
|
.setOutputs(outs);
|
||||||
|
|
||||||
|
var selectedUtxos = b.getSelectedUnspent();
|
||||||
|
var inputChainPaths = selectedUtxos.map(function(utxo) {
|
||||||
|
return pkr.pathForAddress(utxo.address);
|
||||||
|
});
|
||||||
|
|
||||||
|
b = b.setHashToScriptMap(pkr.getRedeemScriptMap(inputChainPaths));
|
||||||
|
|
||||||
|
if (priv) {
|
||||||
|
var keys = priv.getForPaths(inputChainPaths);
|
||||||
|
var signed = b.sign(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
outputs.forEach(function(output, i) {
|
||||||
|
var amount = output.get('amount');
|
||||||
|
var script = {
|
||||||
|
offset: output.get('script').offset,
|
||||||
|
limit: output.get('script').limit,
|
||||||
|
buffer: output.get('script').buffer
|
||||||
|
};
|
||||||
|
|
||||||
|
var v = new Buffer(8);
|
||||||
|
v[0] = (amount.low >> 0) & 0xff;
|
||||||
|
v[1] = (amount.low >> 8) & 0xff;
|
||||||
|
v[2] = (amount.low >> 16) & 0xff;
|
||||||
|
v[3] = (amount.low >> 24) & 0xff;
|
||||||
|
v[4] = (amount.high >> 0) & 0xff;
|
||||||
|
v[5] = (amount.high >> 8) & 0xff;
|
||||||
|
v[6] = (amount.high >> 16) & 0xff;
|
||||||
|
v[7] = (amount.high >> 24) & 0xff;
|
||||||
|
|
||||||
|
var s = script.buffer.slice(script.offset, script.limit);
|
||||||
|
|
||||||
|
b.tx.outs[i].v = v;
|
||||||
|
b.tx.outs[i].s = s;
|
||||||
|
});
|
||||||
|
|
||||||
|
var tx = b.build();
|
||||||
|
|
||||||
|
var refund_outputs = [];
|
||||||
|
|
||||||
|
var refund_to = w.publicKeyRing.getPubKeys(0, false, w.getMyCopayerId())[0];
|
||||||
|
|
||||||
|
var total = outputs.reduce(function(total, _, i) {
|
||||||
|
return total.add(bitcore.Bignum.fromBuffer(tx.outs[i].v, {
|
||||||
|
endian: 'little',
|
||||||
|
size: 1
|
||||||
|
}));
|
||||||
|
}, bitcore.Bignum('0', 10));
|
||||||
|
|
||||||
|
var rpo = new PayPro();
|
||||||
|
rpo = rpo.makeOutput();
|
||||||
|
|
||||||
|
rpo.set('amount', +total.toString(10));
|
||||||
|
|
||||||
|
rpo.set('script',
|
||||||
|
Buffer.concat([
|
||||||
|
new Buffer([
|
||||||
|
118, // OP_DUP
|
||||||
|
169, // OP_HASH160
|
||||||
|
76, // OP_PUSHDATA1
|
||||||
|
20, // number of bytes
|
||||||
|
]),
|
||||||
|
// needs to be ripesha'd
|
||||||
|
bitcore.util.sha256ripe160(options.refund_to),
|
||||||
|
new Buffer([
|
||||||
|
136, // OP_EQUALVERIFY
|
||||||
|
172 // OP_CHECKSIG
|
||||||
|
])
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
refund_outputs.push(rpo.message);
|
||||||
|
|
||||||
|
var pay = new PayPro();
|
||||||
|
pay = pay.makePayment();
|
||||||
|
pay.set('merchant_data', new Buffer([0, 1]));
|
||||||
|
pay.set('transactions', [tx.serialize()]);
|
||||||
|
pay.set('refund_to', refund_outputs);
|
||||||
|
pay.set('memo', 'Hi server, I would like to give you some money.');
|
||||||
|
|
||||||
|
pay = pay.serialize();
|
||||||
|
|
||||||
|
var req = {
|
||||||
|
headers: {
|
||||||
|
'Host': 'localhost:8080',
|
||||||
|
'Accept': PayPro.PAYMENT_REQUEST_CONTENT_TYPE
|
||||||
|
+ ', ' + PayPro.PAYMENT_ACK_CONTENT_TYPE,
|
||||||
|
'Content-Type': PayPro.PAYMENT_CONTENT_TYPE,
|
||||||
|
'Content-Length': pay.length + ''
|
||||||
|
},
|
||||||
|
socket: {
|
||||||
|
remoteAddress: 'localhost',
|
||||||
|
remotePort: 8080
|
||||||
|
},
|
||||||
|
body: pay,
|
||||||
|
data: pay
|
||||||
|
};
|
||||||
|
|
||||||
server.POST['/-/pay'](req, function(err, res, body) {
|
server.POST['/-/pay'](req, function(err, res, body) {
|
||||||
|
if (err) return done(err);
|
||||||
|
|
||||||
|
var data = PayPro.PaymentACK.decode(body);
|
||||||
|
var ack = new PayPro();
|
||||||
|
ack = ack.makePaymentACK(data);
|
||||||
|
|
||||||
|
var payment = ack.get('payment');
|
||||||
|
var memo = ack.get('memo');
|
||||||
|
|
||||||
|
payment = PayPro.Payment.decode(payment);
|
||||||
|
var pay = new PayPro();
|
||||||
|
payment = pay.makePayment(payment);
|
||||||
|
|
||||||
|
var tx = payment.message.transactions[0];
|
||||||
|
|
||||||
|
if (!tx) {
|
||||||
|
return done(new Error('No tx in payment ACK.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx.buffer) {
|
||||||
|
tx.buffer = new Buffer(new Uint8Array(tx.buffer));
|
||||||
|
tx.buffer = tx.buffer.slice(tx.offset, tx.limit);
|
||||||
|
var ptx = new bitcore.Transaction();
|
||||||
|
ptx.parse(tx.buffer);
|
||||||
|
tx = ptx;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ackTotal = outputs.reduce(function(total, _, i) {
|
||||||
|
return total.add(bitcore.Bignum.fromBuffer(tx.outs[i].v, {
|
||||||
|
endian: 'little',
|
||||||
|
size: 1
|
||||||
|
}));
|
||||||
|
}, bitcore.Bignum('0', 10));
|
||||||
|
|
||||||
|
assert.equal(ackTotal.toString(10), total.toString(10));
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -181,21 +380,21 @@ describe('PayPro (in Wallet) model', function() {
|
||||||
should.exist(w);
|
should.exist(w);
|
||||||
var address = 'bitcoin:mq7se9wy2egettFxPbmn99cK8v5AFq55Lx?amount=0.11&r=' + server.uri + '/request';
|
var address = 'bitcoin:mq7se9wy2egettFxPbmn99cK8v5AFq55Lx?amount=0.11&r=' + server.uri + '/request';
|
||||||
var commentText = 'Hello, server. I\'d like to make a payment.';
|
var commentText = 'Hello, server. I\'d like to make a payment.';
|
||||||
w.createTx(address, commentText, function(ntxid, ca) {
|
w.createTx(address, commentText, function(ntxid, merchantData) {
|
||||||
if (w.totalCopayers > 1) {
|
if (w.totalCopayers > 1) {
|
||||||
should.exist(ntxid);
|
should.exist(ntxid);
|
||||||
console.log('Sent TX proposal to other copayers:');
|
console.log('Sent TX proposal to other copayers:');
|
||||||
console.log([ntxid, ca]);
|
console.log([ntxid, merchantData]);
|
||||||
server.close(function() {
|
server.close(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('Sending TX to merchant server:');
|
console.log('Sending TX to merchant server:');
|
||||||
console.log(ntxid);
|
console.log(ntxid);
|
||||||
w.sendTx(ntxid, function(txid, ca) {
|
w.sendTx(ntxid, function(txid, merchantData) {
|
||||||
should.exist(txid);
|
should.exist(txid);
|
||||||
console.log('TX sent:');
|
console.log('TX sent:');
|
||||||
console.log([ntxid, ca]);
|
console.log([ntxid, merchantData]);
|
||||||
server.close(function() {
|
server.close(function() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue