diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-08-24 11:52:12 +0530 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-08-24 11:52:12 +0530 |
commit | b1fd7d09a605558bc61ed113331e0e065e0e2681 (patch) | |
tree | 1c25c1f9620413149e44c628655781172c85508b /packages | |
parent | 1548086f50a7e33f17c5a5218fa0fc3383a8a2d5 (diff) |
test case for order claiming; more accurate EC
Diffstat (limited to 'packages')
6 files changed, 45 insertions, 20 deletions
diff --git a/packages/taler-integrationtests/src/harness.ts b/packages/taler-integrationtests/src/harness.ts index 545ea3097..f4429d43f 100644 --- a/packages/taler-integrationtests/src/harness.ts +++ b/packages/taler-integrationtests/src/harness.ts @@ -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`, ); } diff --git a/packages/taler-integrationtests/src/test-payment.ts b/packages/taler-integrationtests/src/test-payment.ts index d2cbb10f4..d2401e072 100644 --- a/packages/taler-integrationtests/src/test-payment.ts +++ b/packages/taler-integrationtests/src/test-payment.ts @@ -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"; diff --git a/packages/taler-wallet-core/src/TalerErrorCode.ts b/packages/taler-wallet-core/src/TalerErrorCode.ts index ff8511046..7285a0fbe 100644 --- a/packages/taler-wallet-core/src/TalerErrorCode.ts +++ b/packages/taler-wallet-core/src/TalerErrorCode.ts @@ -3210,6 +3210,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). * (A value of 0 indicates that the error is generated client-side). diff --git a/packages/taler-wallet-core/src/headless/NodeHttpLib.ts b/packages/taler-wallet-core/src/headless/NodeHttpLib.ts index 85f37cfa3..62ab9caf6 100644 --- a/packages/taler-wallet-core/src/headless/NodeHttpLib.ts +++ b/packages/taler-wallet-core/src/headless/NodeHttpLib.ts @@ -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, diff --git a/packages/taler-wallet-core/src/operations/pay.ts b/packages/taler-wallet-core/src/operations/pay.ts index f20632344..0d1d4f993 100644 --- a/packages/taler-wallet-core/src/operations/pay.ts +++ b/packages/taler-wallet-core/src/operations/pay.ts @@ -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. diff --git a/packages/taler-wallet-webextension/src/pages/pay.tsx b/packages/taler-wallet-webextension/src/pages/pay.tsx index f1ba2c2b3..a7c5526ed 100644 --- a/packages/taler-wallet-webextension/src/pages/pay.tsx +++ b/packages/taler-wallet-webextension/src/pages/pay.tsx @@ -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); } |