test case for order claiming; more accurate EC

This commit is contained in:
Florian Dold 2020-08-24 11:52:12 +05:30
parent 1548086f50
commit b1fd7d09a6
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
6 changed files with 45 additions and 20 deletions

View File

@ -1266,22 +1266,24 @@ function shellWrap(s: string) {
}
export class WalletCli {
constructor(private globalTestState: GlobalTestState) {}
constructor(private globalTestState: GlobalTestState, private name: string = "default") {}
get dbfile(): string {
return this.globalTestState.testDir + `/walletdb-${this.name}.json`;
}
deleteDatabase() {
const wdb = this.globalTestState.testDir + "/walletdb.json";
fs.unlinkSync(wdb);
fs.unlinkSync(this.dbfile);
}
async apiRequest(
request: string,
payload: unknown,
): Promise<CoreApiResponse> {
const wdb = this.globalTestState.testDir + "/walletdb.json";
const resp = await sh(
this.globalTestState,
"wallet",
`taler-wallet-cli --no-throttle --wallet-db '${wdb}' api '${request}' ${shellWrap(
`wallet-${this.name}`,
`taler-wallet-cli --no-throttle --wallet-db '${this.dbfile}' api '${request}' ${shellWrap(
JSON.stringify(payload),
)}`,
);
@ -1290,20 +1292,18 @@ export class WalletCli {
}
async runUntilDone(): Promise<void> {
const wdb = this.globalTestState.testDir + "/walletdb.json";
await sh(
this.globalTestState,
"wallet",
`taler-wallet-cli --no-throttle --wallet-db ${wdb} run-until-done`,
`wallet-${this.name}`,
`taler-wallet-cli --no-throttle --wallet-db ${this.dbfile} run-until-done`,
);
}
async runPending(): Promise<void> {
const wdb = this.globalTestState.testDir + "/walletdb.json";
await sh(
this.globalTestState,
"wallet",
`taler-wallet-cli --no-throttle --wallet-db ${wdb} run-pending`,
`wallet-${this.name}`,
`taler-wallet-cli --no-throttle --wallet-db ${this.dbfile} run-pending`,
);
}

View File

@ -17,7 +17,7 @@
/**
* Imports.
*/
import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
import { runTest, GlobalTestState, MerchantPrivateApi, WalletCli } from "./harness";
import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
import { PreparePayResultType } from "taler-wallet-core";

View File

@ -3209,6 +3209,13 @@ export enum TalerErrorCode {
*/
WALLET_HTTP_REQUEST_TIMEOUT = 7013,
/**
* The order has already been claimed by another wallet.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).
* (A value of 0 indicates that the error is generated client-side).
*/
WALLET_ORDER_ALREADY_CLAIMED = 7014,
/**
* End of error code range.
* Returned with an HTTP status code of #MHD_HTTP_UNINITIALIZED (0).

View File

@ -30,6 +30,9 @@ import Axios from "axios";
import { OperationFailedError, makeErrorDetails } from "../operations/errors";
import { TalerErrorCode } from "../TalerErrorCode";
import { URL } from "../util/url";
import { Logger } from "../util/logging";
const logger = new Logger("NodeHttpLib.ts");
/**
* Implementation of the HTTP request library interface for node.
@ -96,6 +99,7 @@ export class NodeHttpLib implements HttpRequestLibrary {
try {
responseJson = JSON.parse(respText);
} catch (e) {
logger.trace(`invalid json: '${respText}'`);
throw new OperationFailedError(
makeErrorDetails(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,
@ -109,6 +113,7 @@ export class NodeHttpLib implements HttpRequestLibrary {
);
}
if (responseJson === null || typeof responseJson !== "object") {
logger.trace(`invalid json (not an object): '${respText}'`);
throw new OperationFailedError(
makeErrorDetails(
TalerErrorCode.WALLET_RECEIVED_MALFORMED_RESPONSE,

View File

@ -71,6 +71,7 @@ import {
readSuccessResponseJsonOrThrow,
throwUnexpectedRequestError,
getHttpResponseErrorDetails,
readSuccessResponseJsonOrErrorCode,
} from "../util/http";
import { TalerErrorCode } from "../TalerErrorCode";
import { URL } from "../util/url";
@ -638,13 +639,25 @@ async function processDownloadProposalImpl(
requestBody.token = proposal.claimToken;
}
const resp = await ws.http.postJson(orderClaimUrl, requestBody, {
const httpResponse = await ws.http.postJson(orderClaimUrl, requestBody, {
timeout: getProposalRequestTimeout(proposal),
});
const proposalResp = await readSuccessResponseJsonOrThrow(
resp,
codecForProposal(),
);
const r = await readSuccessResponseJsonOrErrorCode(httpResponse, codecForProposal());
if (r.isError) {
switch (r.talerErrorResponse.code) {
case TalerErrorCode.ORDERS_ALREADY_CLAIMED:
throw OperationFailedError.fromCode(
TalerErrorCode.WALLET_ORDER_ALREADY_CLAIMED,
"order already claimed (likely by other wallet)",
{
orderId: proposal.orderId,
claimUrl: orderClaimUrl,
});
default:
throwUnexpectedRequestError(httpResponse, r.talerErrorResponse);
}
}
const proposalResp = r.response;
// The proposalResp contains the contract terms as raw JSON,
// as the coded to parse them doesn't necessarily round-trip.

View File

@ -59,11 +59,11 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }): JSX.Element {
}
let insufficientBalance = false;
if (payStatus.status == "insufficient-balance") {
if (payStatus.status == PreparePayResultType.InsufficientBalance) {
insufficientBalance = true;
}
if (payStatus.status === "payment-possible") {
if (payStatus.status === PreparePayResultType.PaymentPossible) {
amountEffective = Amounts.parseOrThrow(payStatus.amountEffective);
}