mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-19 11:45:49 +00:00
Change prepare* methods to reject Promise on error (#984)
* Reject Promise on error, update docs, and add tests: * preparePayment * prepareTrustline * prepareOrder * prepareOrderCancellation * prepareSettings * prepareEscrowCreation * prepareEscrowExecution * prepareCheckCreate * prepareCheckCash * prepareCheckCancel * preparePaymentChannelCreate * preparePaymentChannelFund * preparePaymentChannelClaim Note that we can't update mocha to ^5.2.0 because it causes testing to hang indefinitely; this needs to be investigated.
This commit is contained in:
48
HISTORY.md
48
HISTORY.md
@@ -1,5 +1,53 @@
|
||||
# ripple-lib Release History
|
||||
|
||||
## UNRELEASED
|
||||
|
||||
**BREAKING CHANGE:**
|
||||
|
||||
The `prepare*` methods now reject the Promise when an error occurs.
|
||||
|
||||
Previously, the methods would synchronously throw on validation errors, despite being asynchronous methods that return Promises.
|
||||
|
||||
In other words, to handle errors in the past, you would need to use a try/catch block:
|
||||
|
||||
```
|
||||
// OBSOLETE - no need for try/catch anymore
|
||||
try {
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle asynchronous error
|
||||
});
|
||||
} catch (error) {
|
||||
// Handle synchronous error
|
||||
}
|
||||
```
|
||||
|
||||
Now, you can rely on the Promise's `catch` handler, which is called with the error when the Promise is rejected:
|
||||
|
||||
```
|
||||
api.preparePayment(address, payment, instructions).then(prepared => {
|
||||
res.send(prepared.txJSON);
|
||||
}).catch(error => {
|
||||
// Handle error
|
||||
});
|
||||
```
|
||||
|
||||
This applies to:
|
||||
* preparePayment
|
||||
* prepareTrustline
|
||||
* prepareOrder
|
||||
* prepareOrderCancellation
|
||||
* prepareSettings
|
||||
* prepareEscrowCreation
|
||||
* prepareEscrowExecution
|
||||
* prepareCheckCreate
|
||||
* prepareCheckCash
|
||||
* prepareCheckCancel
|
||||
* preparePaymentChannelCreate
|
||||
* preparePaymentChannelClaim
|
||||
* preparePaymentChannelFund
|
||||
|
||||
## 1.1.2 (2018-12-12)
|
||||
|
||||
+ Update `submit` response (#978)
|
||||
|
||||
@@ -4584,8 +4584,11 @@ const payment = {
|
||||
}
|
||||
}
|
||||
};
|
||||
return api.preparePayment(address, payment).then(prepared =>
|
||||
{/* ... */});
|
||||
return api.preparePayment(address, payment).then(prepared => {
|
||||
/* ... */
|
||||
}).catch(error => {
|
||||
/* ... as with all prepare* methods, use a Promise catch block to handle errors ... */
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,11 @@ All "prepare*" methods have the same return type.
|
||||
```javascript
|
||||
const address = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const payment = <%- importFile('test/fixtures/requests/prepare-payment.json') %>;
|
||||
return api.preparePayment(address, payment).then(prepared =>
|
||||
{/* ... */});
|
||||
return api.preparePayment(address, payment).then(prepared => {
|
||||
/* ... */
|
||||
}).catch(error => {
|
||||
/* ... as with all prepare* methods, use a Promise catch block to handle errors ... */
|
||||
})
|
||||
```
|
||||
|
||||
<%- renderFixture("responses/prepare-payment.json") %>
|
||||
|
||||
@@ -22,11 +22,15 @@ function prepareCheckCancel(address: string,
|
||||
checkCancel: CheckCancel,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCancel(
|
||||
{address, checkCancel, instructions})
|
||||
const txJSON = createCheckCancelTransaction(
|
||||
address, checkCancel)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCancel
|
||||
|
||||
@@ -40,11 +40,15 @@ function prepareCheckCash(address: string,
|
||||
checkCash: CheckCash,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCash(
|
||||
{address, checkCash, instructions})
|
||||
const txJSON = createCheckCashTransaction(
|
||||
address, checkCash)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCash
|
||||
|
||||
@@ -41,11 +41,15 @@ function prepareCheckCreate(address: string,
|
||||
checkCreate: CheckCreate,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareCheckCreate(
|
||||
{address, checkCreate, instructions})
|
||||
const txJSON = createCheckCreateTransaction(
|
||||
address, checkCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareCheckCreate
|
||||
|
||||
@@ -56,11 +56,15 @@ function prepareEscrowCreation(address: string,
|
||||
escrowCreation: EscrowCreation,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareEscrowCreation(
|
||||
{address, escrowCreation, instructions})
|
||||
const txJSON = createEscrowCreationTransaction(
|
||||
address, escrowCreation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareEscrowCreation(
|
||||
{address, escrowCreation, instructions})
|
||||
const txJSON = createEscrowCreationTransaction(
|
||||
address, escrowCreation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareEscrowCreation
|
||||
|
||||
@@ -44,11 +44,15 @@ function prepareEscrowExecution(address: string,
|
||||
escrowExecution: EscrowExecution,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareEscrowExecution(
|
||||
{address, escrowExecution, instructions})
|
||||
const txJSON = createEscrowExecutionTransaction(
|
||||
address, escrowExecution)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareEscrowExecution(
|
||||
{address, escrowExecution, instructions})
|
||||
const txJSON = createEscrowExecutionTransaction(
|
||||
address, escrowExecution)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareEscrowExecution
|
||||
|
||||
@@ -47,9 +47,13 @@ function createOrderTransaction(
|
||||
function prepareOrder(address: string, order: FormattedOrderSpecification,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrder({address, order, instructions})
|
||||
const txJSON = createOrderTransaction(address, order)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareOrder({address, order, instructions})
|
||||
const txJSON = createOrderTransaction(address, order)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareOrder
|
||||
|
||||
@@ -20,9 +20,13 @@ function createOrderCancellationTransaction(account: string,
|
||||
function prepareOrderCancellation(address: string, orderCancellation: object,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareOrderCancellation({address, orderCancellation, instructions})
|
||||
const txJSON = createOrderCancellationTransaction(address, orderCancellation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareOrderCancellation({address, orderCancellation, instructions})
|
||||
const txJSON = createOrderCancellationTransaction(address, orderCancellation)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareOrderCancellation
|
||||
|
||||
@@ -62,11 +62,15 @@ function preparePaymentChannelClaim(address: string,
|
||||
paymentChannelClaim: PaymentChannelClaim,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelClaim(
|
||||
{address, paymentChannelClaim, instructions})
|
||||
const txJSON = createPaymentChannelClaimTransaction(
|
||||
address, paymentChannelClaim)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelClaim(
|
||||
{address, paymentChannelClaim, instructions})
|
||||
const txJSON = createPaymentChannelClaimTransaction(
|
||||
address, paymentChannelClaim)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelClaim
|
||||
|
||||
@@ -41,11 +41,15 @@ function preparePaymentChannelCreate(address: string,
|
||||
paymentChannelCreate: PaymentChannelCreate,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelCreate(
|
||||
{address, paymentChannelCreate, instructions})
|
||||
const txJSON = createPaymentChannelCreateTransaction(
|
||||
address, paymentChannelCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelCreate(
|
||||
{address, paymentChannelCreate, instructions})
|
||||
const txJSON = createPaymentChannelCreateTransaction(
|
||||
address, paymentChannelCreate)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelCreate
|
||||
|
||||
@@ -29,11 +29,15 @@ function preparePaymentChannelFund(address: string,
|
||||
paymentChannelFund: PaymentChannelFund,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePaymentChannelFund(
|
||||
{address, paymentChannelFund, instructions})
|
||||
const txJSON = createPaymentChannelFundTransaction(
|
||||
address, paymentChannelFund)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePaymentChannelFund(
|
||||
{address, paymentChannelFund, instructions})
|
||||
const txJSON = createPaymentChannelFundTransaction(
|
||||
address, paymentChannelFund)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePaymentChannelFund
|
||||
|
||||
@@ -172,9 +172,13 @@ function createPaymentTransaction(address: string, paymentArgument: Payment
|
||||
function preparePayment(address: string, payment: Payment,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.preparePayment({address, payment, instructions})
|
||||
const txJSON = createPaymentTransaction(address, payment)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.preparePayment({address, payment, instructions})
|
||||
const txJSON = createPaymentTransaction(address, payment)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default preparePayment
|
||||
|
||||
@@ -8,7 +8,7 @@ const AccountFields = utils.common.constants.AccountFields
|
||||
import {Instructions, Prepare} from './types'
|
||||
import {FormattedSettings, WeightedSigner} from '../common/types/objects'
|
||||
|
||||
// Emptry string passed to setting will clear it
|
||||
// Empty string passed to setting will clear it
|
||||
const CLEAR_SETTING = null
|
||||
|
||||
function setTransactionFlags(txJSON: any, values: FormattedSettings) {
|
||||
@@ -43,7 +43,7 @@ function setTransactionFields(txJSON: object, input: FormattedSettings) {
|
||||
|
||||
if (field.encoding === 'hex' && !field.length) {
|
||||
// This is currently only used for Domain field
|
||||
value = new Buffer(value, 'ascii').toString('hex').toUpperCase()
|
||||
value = Buffer.from(value, 'ascii').toString('hex').toUpperCase()
|
||||
}
|
||||
|
||||
txJSON[fieldName] = value
|
||||
@@ -125,9 +125,13 @@ function createSettingsTransaction(account: string, settings: FormattedSettings
|
||||
function prepareSettings(address: string, settings: FormattedSettings,
|
||||
instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareSettings({address, settings, instructions})
|
||||
const txJSON = createSettingsTransaction(address, settings)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareSettings({address, settings, instructions})
|
||||
const txJSON = createSettingsTransaction(address, settings)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareSettings
|
||||
|
||||
@@ -53,9 +53,13 @@ function createTrustlineTransaction(account: string,
|
||||
function prepareTrustline(address: string,
|
||||
trustline: FormattedTrustlineSpecification, instructions: Instructions = {}
|
||||
): Promise<Prepare> {
|
||||
validate.prepareTrustline({address, trustline, instructions})
|
||||
const txJSON = createTrustlineTransaction(address, trustline)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
try {
|
||||
validate.prepareTrustline({address, trustline, instructions})
|
||||
const txJSON = createTrustlineTransaction(address, trustline)
|
||||
return utils.prepareTransaction(txJSON, this, instructions)
|
||||
} catch (e) {
|
||||
return Promise.reject(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default prepareTrustline
|
||||
|
||||
378
test/api-test.js
378
test/api-test.js
@@ -519,23 +519,170 @@ describe('RippleAPI', function () {
|
||||
})
|
||||
});
|
||||
|
||||
it('preparePayment - XRP to XRP no partial', function () {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongPartial);
|
||||
}, /XRP to XRP payments cannot be partial payments/);
|
||||
});
|
||||
describe('errors', function () {
|
||||
|
||||
it('preparePayment - address must match payment.source.address', function (
|
||||
) {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAddress);
|
||||
}, /address must match payment.source.address/);
|
||||
});
|
||||
const senderAddress = 'r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59';
|
||||
const recipientAddress = 'rpZc4mVfWUif9CRoHRKKcmhu1nx2xktxBo';
|
||||
|
||||
it('preparePayment - wrong amount', function () {
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAmount);
|
||||
}, this.api.errors.ValidationError);
|
||||
it('rejects promise and does not throw when payment object is invalid', function (done) {
|
||||
const payment = {
|
||||
source: {
|
||||
address: senderAddress,
|
||||
amount: { // instead of `maxAmount`
|
||||
value: '1000',
|
||||
currency: 'drops'
|
||||
}
|
||||
},
|
||||
destination: {
|
||||
address: recipientAddress,
|
||||
amount: {
|
||||
value: '1000',
|
||||
currency: 'drops'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cannot use `assert.rejects` because then the test passes (with UnhandledPromiseRejectionWarning) even when it should not.
|
||||
// See https://github.com/mochajs/mocha/issues/3097
|
||||
try {
|
||||
this.api.preparePayment(senderAddress, payment).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('rejects promise and does not throw when field is missing', function (done) {
|
||||
const payment = {
|
||||
source: {
|
||||
address: senderAddress
|
||||
// `maxAmount` missing
|
||||
},
|
||||
destination: {
|
||||
address: recipientAddress,
|
||||
amount: {
|
||||
value: '1000',
|
||||
currency: 'drops'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cannot use `assert.rejects` because then the test passes (with UnhandledPromiseRejectionWarning) even when it should not.
|
||||
// See https://github.com/mochajs/mocha/issues/3097
|
||||
try {
|
||||
this.api.preparePayment(senderAddress, payment).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.payment.source is not exactly one from <sourceExactAdjustment>,<maxAdjustment>');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('rejects promise and does not throw when fee exceeds maxFeeXRP', function (done) {
|
||||
const payment = {
|
||||
source: {
|
||||
address: senderAddress,
|
||||
maxAmount: {
|
||||
value: '1000',
|
||||
currency: 'drops'
|
||||
}
|
||||
},
|
||||
destination: {
|
||||
address: recipientAddress,
|
||||
amount: {
|
||||
value: '1000',
|
||||
currency: 'drops'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cannot use `assert.rejects` because then the test passes (with UnhandledPromiseRejectionWarning) even when it should not.
|
||||
// See https://github.com/mochajs/mocha/issues/3097
|
||||
try {
|
||||
this.api.preparePayment(senderAddress, payment, {
|
||||
fee: '3' // XRP
|
||||
}).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'Fee of 3 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor.');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('preparePayment - XRP to XRP no partial', function (done) {
|
||||
try {
|
||||
// Cannot return promise because we want/expect it to reject.
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongPartial).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'XRP to XRP payments cannot be partial payments');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('preparePayment - address must match payment.source.address', function (done) {
|
||||
try {
|
||||
// Cannot return promise because we want/expect it to reject.
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAddress).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'address must match payment.source.address');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('preparePayment - wrong amount', function (done) {
|
||||
try {
|
||||
// Cannot return promise because we want/expect it to reject.
|
||||
this.api.preparePayment(address, requests.preparePayment.wrongAmount).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'payment must specify either (source.maxAmount and destination.amount) or (source.amount and destination.minAmount)');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('preparePayment - throws when fee exceeds 2 XRP', function (done) {
|
||||
const localInstructions = _.defaults({
|
||||
fee: '2.1'
|
||||
}, instructions);
|
||||
|
||||
try {
|
||||
// Cannot return promise because we want/expect it to reject.
|
||||
this.api.preparePayment(
|
||||
address, requests.preparePayment.normal, localInstructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'Fee of 2.1 XRP exceeds max of 2 XRP. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor.');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
it('preparePayment with all options specified', function () {
|
||||
@@ -565,17 +712,6 @@ describe('RippleAPI', function () {
|
||||
responses.preparePayment.minAmount, 'prepare'));
|
||||
});
|
||||
|
||||
it('preparePayment - throws when fee exceeds 2 XRP', function () {
|
||||
const localInstructions = _.defaults({
|
||||
fee: '2.1'
|
||||
}, instructions);
|
||||
|
||||
assert.throws(() => {
|
||||
this.api.preparePayment(
|
||||
address, requests.preparePayment.normal, localInstructions)
|
||||
}, /Fee of 2\.1 XRP exceeds max of 2 XRP\. To use this fee, increase `maxFeeXRP` in the RippleAPI constructor\./)
|
||||
});
|
||||
|
||||
it('preparePayment - caps fee at 2 XRP by default', function () {
|
||||
this.api._feeCushion = 1000000;
|
||||
|
||||
@@ -633,6 +769,22 @@ describe('RippleAPI', function () {
|
||||
_.partial(checkResult, responses.prepareOrder.sell, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareOrder - invalid', function (done) {
|
||||
const request = requests.prepareOrder.sell;
|
||||
delete request.direction; // Make invalid
|
||||
try {
|
||||
this.api.prepareOrder(address, request, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.order requires property "direction"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareOrderCancellation', function () {
|
||||
const request = requests.prepareOrderCancellation.simple;
|
||||
return this.api.prepareOrderCancellation(address, request, instructions)
|
||||
@@ -656,6 +808,22 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareOrderCancellation - invalid', function (done) {
|
||||
const request = requests.prepareOrderCancellation.withMemos;
|
||||
delete request.orderSequence; // Make invalid
|
||||
try {
|
||||
this.api.prepareOrderCancellation(address, request).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.orderCancellation requires property "orderSequence"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareTrustline - simple', function () {
|
||||
return this.api.prepareTrustline(
|
||||
address, requests.prepareTrustline.simple, instructions).then(
|
||||
@@ -674,6 +842,23 @@ describe('RippleAPI', function () {
|
||||
_.partial(checkResult, responses.prepareTrustline.complex, 'prepare'));
|
||||
});
|
||||
|
||||
it('prepareTrustline - invalid', function (done) {
|
||||
const trustline = requests.prepareTrustline.complex;
|
||||
delete trustline.limit; // Make invalid
|
||||
try {
|
||||
this.api.prepareTrustline(
|
||||
address, trustline, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.trustline requires property "limit"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareSettings', function () {
|
||||
return this.api.prepareSettings(
|
||||
address, requests.prepareSettings.domain, instructions).then(
|
||||
@@ -756,18 +941,34 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - signers no threshold', function () {
|
||||
it('prepareSettings - signers no threshold', function (done) {
|
||||
const settings = requests.prepareSettings.signers.noThreshold;
|
||||
assert.throws(() => {
|
||||
this.api.prepareSettings(address, settings, instructions);
|
||||
}, this.api.errors.ValidationError);
|
||||
try {
|
||||
this.api.prepareSettings(address, settings, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.settings.signers requires property "threshold"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareSettings - signers no weights', function () {
|
||||
it('prepareSettings - signers no weights', function (done) {
|
||||
const settings = requests.prepareSettings.signers.noWeights;
|
||||
assert.throws(() => {
|
||||
this.api.prepareSettings(address, settings, instructions);
|
||||
}, this.api.errors.ValidationError);
|
||||
try {
|
||||
this.api.prepareSettings(address, settings, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.settings.signers requires property "weights"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareSettings - fee for multisign', function () {
|
||||
@@ -780,6 +981,30 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareSettings - invalid', function (done) {
|
||||
// domain must be a string
|
||||
const settings = Object.assign({},
|
||||
requests.prepareSettings.domain,
|
||||
{domain: 123});
|
||||
|
||||
const localInstructions = _.defaults({
|
||||
signersCount: 4
|
||||
}, instructions);
|
||||
|
||||
try {
|
||||
this.api.prepareSettings(
|
||||
address, settings, localInstructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.settings.domain is not of a type(s) string');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareEscrowCreation', function () {
|
||||
const localInstructions = _.defaults({
|
||||
maxFee: '0.000012'
|
||||
@@ -798,6 +1023,23 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareEscrowCreation - invalid', function (done) {
|
||||
const escrow = Object.assign({}, requests.prepareEscrowCreation.full);
|
||||
delete escrow.amount; // Make invalid
|
||||
try {
|
||||
this.api.prepareEscrowCreation(
|
||||
address, escrow).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, 'instance.escrowCreation requires property "amount"');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareEscrowExecution', function () {
|
||||
return this.api.prepareEscrowExecution(
|
||||
address,
|
||||
@@ -816,18 +1058,34 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('prepareEscrowExecution - no condition', function () {
|
||||
assert.throws(() => {
|
||||
it('prepareEscrowExecution - no condition', function (done) {
|
||||
try {
|
||||
this.api.prepareEscrowExecution(address,
|
||||
requests.prepareEscrowExecution.noCondition, instructions);
|
||||
}, /"condition" and "fulfillment" fields on EscrowFinish must only be specified together./);
|
||||
requests.prepareEscrowExecution.noCondition, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareEscrowExecution - no fulfillment', function () {
|
||||
assert.throws(() => {
|
||||
it('prepareEscrowExecution - no fulfillment', function (done) {
|
||||
try {
|
||||
this.api.prepareEscrowExecution(address,
|
||||
requests.prepareEscrowExecution.noFulfillment, instructions);
|
||||
}, /"condition" and "fulfillment" fields on EscrowFinish must only be specified together./);
|
||||
requests.prepareEscrowExecution.noFulfillment, instructions).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, '"condition" and "fulfillment" fields on EscrowFinish must only be specified together.');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('prepareEscrowCancellation', function () {
|
||||
@@ -1382,22 +1640,34 @@ describe('RippleAPI', function () {
|
||||
'prepare'));
|
||||
});
|
||||
|
||||
it('throws on preparePaymentChannelClaim with renew and close', function () {
|
||||
assert.throws(() => {
|
||||
it('rejects Promise on preparePaymentChannelClaim with renew and close', function (done) {
|
||||
try {
|
||||
this.api.preparePaymentChannelClaim(
|
||||
address, requests.preparePaymentChannelClaim.full).then(
|
||||
_.partial(checkResult, responses.preparePaymentChannelClaim.full,
|
||||
'prepare'));
|
||||
}, this.api.errors.ValidationError);
|
||||
address, requests.preparePaymentChannelClaim.full).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, '"renew" and "close" flags on PaymentChannelClaim are mutually exclusive');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('throws on preparePaymentChannelClaim with no signature', function () {
|
||||
assert.throws(() => {
|
||||
it('rejects Promise on preparePaymentChannelClaim with no signature', function (done) {
|
||||
try {
|
||||
this.api.preparePaymentChannelClaim(
|
||||
address, requests.preparePaymentChannelClaim.noSignature).then(
|
||||
_.partial(checkResult, responses.preparePaymentChannelClaim.noSignature,
|
||||
'prepare'));
|
||||
}, this.api.errors.ValidationError);
|
||||
address, requests.preparePaymentChannelClaim.noSignature).then(prepared => {
|
||||
done(new Error('Expected method to reject. Prepared transaction: ' + JSON.stringify(prepared)));
|
||||
}).catch(err => {
|
||||
assert.strictEqual(err.name, 'ValidationError');
|
||||
assert.strictEqual(err.message, '"signature" and "publicKey" fields on PaymentChannelClaim must only be specified together.');
|
||||
done();
|
||||
}).catch(done); // Finish test with assertion failure immediately instead of waiting for timeout.
|
||||
} catch (err) {
|
||||
done(new Error('Expected method to reject, but method threw. Thrown: ' + err));
|
||||
};
|
||||
});
|
||||
|
||||
it('sign', function () {
|
||||
|
||||
Reference in New Issue
Block a user