integration tests: one variable for pybank/libeufin switch

This commit is contained in:
Florian Dold 2022-06-01 10:14:23 +02:00
parent 1ea28c5be1
commit 59a2119dcb
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 61 additions and 36 deletions

View File

@ -856,6 +856,9 @@ class PybankService extends BankServiceBase implements BankServiceHandle {
} }
} }
// Use libeufin bank instead of pybank.
const useLibeufinBank = process.env.WALLET_HARNESS_WITH_EUFIN;
/** /**
* Return a euFin or a pyBank implementation of * Return a euFin or a pyBank implementation of
* the exported BankService class. This allows * the exported BankService class. This allows
@ -866,7 +869,7 @@ function getBankServiceImpl(): {
prototype: typeof PybankService.prototype; prototype: typeof PybankService.prototype;
create: typeof PybankService.create; create: typeof PybankService.create;
} { } {
if (process.env.WALLET_HARNESS_WITH_EUFIN) if (useLibeufinBank)
return { return {
prototype: EufinBankService.prototype, prototype: EufinBankService.prototype,
create: EufinBankService.create, create: EufinBankService.create,
@ -1003,7 +1006,7 @@ export class ExchangeService implements ExchangeServiceInterface {
} }
async runWirewatchOnce() { async runWirewatchOnce() {
if (process.env.WALLET_HARNESS_WITH_EUFIN) { if (useLibeufinBank) {
// Not even 2 secods showed to be enough! // Not even 2 secods showed to be enough!
await waitMs(4000); await waitMs(4000);
} }
@ -2016,7 +2019,7 @@ export function getRandomIban(salt: string | null = null): string {
// Only used in one tipping test. // Only used in one tipping test.
export function getWireMethod(): string { export function getWireMethod(): string {
if (process.env.WALLET_HARNESS_WITH_EUFIN) return "iban"; if (useLibeufinBank) return "iban";
return "x-taler-bank"; return "x-taler-bank";
} }
@ -2025,7 +2028,7 @@ export function getWireMethod(): string {
* on whether the banking is served by euFin or Pybank. * on whether the banking is served by euFin or Pybank.
*/ */
export function getPayto(label: string): string { export function getPayto(label: string): string {
if (process.env.WALLET_HARNESS_WITH_EUFIN) if (useLibeufinBank)
return `payto://iban/SANDBOXX/${getRandomIban( return `payto://iban/SANDBOXX/${getRandomIban(
label, label,
)}?receiver-name=${label}`; )}?receiver-name=${label}`;

View File

@ -222,7 +222,7 @@ export async function runTests(spec: TestRunSpec) {
path.join(os.tmpdir(), "taler-integrationtests-"), path.join(os.tmpdir(), "taler-integrationtests-"),
); );
updateCurrentSymlink(testRootDir); updateCurrentSymlink(testRootDir);
console.log("testsuite root directory: ", testRootDir); console.log(`testsuite root directory: ${testRootDir}`);
const testResults: TestRunResult[] = []; const testResults: TestRunResult[] = [];

View File

@ -121,8 +121,7 @@ export namespace BankApi {
paytoUri = respJson.paytoUri; paytoUri = respJson.paytoUri;
} }
} catch (e) { } catch (e) {
logger.error("error trying to parse json from response", e); // Do nothing
throw TalerError.fromException(e);
} }
return { return {
password, password,

View File

@ -25,18 +25,28 @@
*/ */
import { import {
AbortingCoin, AbortingCoin,
AbortRequest, AbsoluteTime, AmountJson, AbortRequest,
AbsoluteTime,
AmountJson,
Amounts, Amounts,
ApplyRefundResponse, ApplyRefundResponse,
codecForAbortResponse, codecForAbortResponse,
codecForMerchantOrderRefundPickupResponse, codecForMerchantOrderStatusPaid, CoinPublicKey, Duration, Logger, codecForMerchantOrderRefundPickupResponse,
codecForMerchantOrderStatusPaid,
CoinPublicKey,
Duration,
Logger,
MerchantCoinRefundFailureStatus, MerchantCoinRefundFailureStatus,
MerchantCoinRefundStatus, MerchantCoinRefundStatus,
MerchantCoinRefundSuccessStatus, MerchantCoinRefundSuccessStatus,
NotificationType, NotificationType,
parseRefundUri, PrepareRefundResult, RefreshReason, parseRefundUri,
PrepareRefundResult,
RefreshReason,
TalerErrorCode, TalerErrorCode,
TalerErrorDetail, TalerProtocolTimestamp, URL TalerErrorDetail,
TalerProtocolTimestamp,
URL,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
AbortStatus, AbortStatus,
@ -44,21 +54,18 @@ import {
PurchaseRecord, PurchaseRecord,
RefundReason, RefundReason,
RefundState, RefundState,
WalletStoresV1 WalletStoresV1,
} from "../db.js"; } from "../db.js";
import { InternalWalletState } from "../internal-wallet-state.js"; import { InternalWalletState } from "../internal-wallet-state.js";
import { readSuccessResponseJsonOrThrow } from "../util/http.js"; import { readSuccessResponseJsonOrThrow } from "../util/http.js";
import { checkDbInvariant } from "../util/invariants.js"; import { checkDbInvariant } from "../util/invariants.js";
import { GetReadWriteAccess } from "../util/query.js"; import { GetReadWriteAccess } from "../util/query.js";
import { import { RetryInfo } from "../util/retries.js";
RetryInfo
} from "../util/retries.js";
import { guardOperationException } from "./common.js"; import { guardOperationException } from "./common.js";
import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js"; import { createRefreshGroup, getTotalRefreshCost } from "./refresh.js";
const logger = new Logger("refund.ts"); const logger = new Logger("refund.ts");
export async function prepareRefund( export async function prepareRefund(
ws: InternalWalletState, ws: InternalWalletState,
talerRefundUri: string, talerRefundUri: string,
@ -88,11 +95,11 @@ export async function prepareRefund(
); );
} }
const awaiting = await queryAndSaveAwaitingRefund(ws, purchase) const awaiting = await queryAndSaveAwaitingRefund(ws, purchase);
const summary = calculateRefundSummary(purchase) const summary = calculateRefundSummary(purchase);
const proposalId = purchase.proposalId; const proposalId = purchase.proposalId;
const { contractData: c } = purchase.download const { contractData: c } = purchase.download;
return { return {
proposalId, proposalId,
@ -109,10 +116,9 @@ export async function prepareRefund(
summary: c.summary, summary: c.summary,
fulfillmentMessage: c.fulfillmentMessage, fulfillmentMessage: c.fulfillmentMessage,
summary_i18n: c.summaryI18n, summary_i18n: c.summaryI18n,
fulfillmentMessage_i18n: fulfillmentMessage_i18n: c.fulfillmentMessageI18n,
c.fulfillmentMessageI18n,
}, },
} };
} }
/** /**
* Retry querying and applying refunds for an order later. * Retry querying and applying refunds for an order later.
@ -496,7 +502,7 @@ async function acceptRefunds(
} else { } else {
// No error, but we need to try again! // No error, but we need to try again!
p.timestampLastRefundStatus = now; p.timestampLastRefundStatus = now;
p.refundStatusRetryInfo = RetryInfo.increment(p.refundStatusRetryInfo) p.refundStatusRetryInfo = RetryInfo.increment(p.refundStatusRetryInfo);
p.lastRefundStatusError = undefined; p.lastRefundStatusError = undefined;
logger.trace("refund query not done"); logger.trace("refund query not done");
} }
@ -509,7 +515,6 @@ async function acceptRefunds(
}); });
} }
function calculateRefundSummary(p: PurchaseRecord): RefundSummary { function calculateRefundSummary(p: PurchaseRecord): RefundSummary {
let amountRefundGranted = Amounts.getZero( let amountRefundGranted = Amounts.getZero(
p.download.contractData.amount.currency, p.download.contractData.amount.currency,
@ -544,7 +549,12 @@ function calculateRefundSummary(p: PurchaseRecord): RefundSummary {
).amount; ).amount;
} }
}); });
return { amountEffectivePaid: p.totalPayCost, amountRefundGone, amountRefundGranted, pendingAtExchange } return {
amountEffectivePaid: p.totalPayCost,
amountRefundGone,
amountRefundGranted,
pendingAtExchange,
};
} }
/** /**
@ -590,14 +600,13 @@ export async function applyRefund(
); );
} }
return applyRefundFromPurchaseId(ws, purchase.proposalId) return applyRefundFromPurchaseId(ws, purchase.proposalId);
} }
export async function applyRefundFromPurchaseId( export async function applyRefundFromPurchaseId(
ws: InternalWalletState, ws: InternalWalletState,
proposalId: string, proposalId: string,
): Promise<ApplyRefundResponse> { ): Promise<ApplyRefundResponse> {
logger.trace("applying refund for purchase", proposalId); logger.trace("applying refund for purchase", proposalId);
logger.info("processing purchase for refund"); logger.info("processing purchase for refund");
@ -640,7 +649,7 @@ export async function applyRefundFromPurchaseId(
throw Error("purchase no longer exists"); throw Error("purchase no longer exists");
} }
const summary = calculateRefundSummary(purchase) const summary = calculateRefundSummary(purchase);
return { return {
contractTermsHash: purchase.download.contractData.contractTermsHash, contractTermsHash: purchase.download.contractData.contractTermsHash,
@ -682,7 +691,8 @@ export async function processPurchaseQueryRefund(
async function queryAndSaveAwaitingRefund( async function queryAndSaveAwaitingRefund(
ws: InternalWalletState, ws: InternalWalletState,
purchase: PurchaseRecord, purchase: PurchaseRecord,
waitForAutoRefund?: boolean): Promise<AmountJson> { waitForAutoRefund?: boolean,
): Promise<AmountJson> {
const requestUrl = new URL( const requestUrl = new URL(
`orders/${purchase.download.contractData.orderId}`, `orders/${purchase.download.contractData.orderId}`,
purchase.download.contractData.merchantBaseUrl, purchase.download.contractData.merchantBaseUrl,
@ -709,12 +719,22 @@ async function queryAndSaveAwaitingRefund(
const refundAwaiting = Amounts.sub( const refundAwaiting = Amounts.sub(
Amounts.parseOrThrow(orderStatus.refund_amount), Amounts.parseOrThrow(orderStatus.refund_amount),
Amounts.parseOrThrow(orderStatus.refund_taken) Amounts.parseOrThrow(orderStatus.refund_taken),
).amount ).amount;
console.log("refund waiting found, ", refundAwaiting, orderStatus, purchase.refundAwaiting, purchase.refundAwaiting && Amounts.cmp(refundAwaiting, purchase.refundAwaiting)) logger.info(
"refund waiting found, ",
refundAwaiting,
orderStatus,
purchase.refundAwaiting,
purchase.refundAwaiting &&
Amounts.cmp(refundAwaiting, purchase.refundAwaiting),
);
if (purchase.refundAwaiting === undefined || Amounts.cmp(refundAwaiting, purchase.refundAwaiting) !== 0) { if (
purchase.refundAwaiting === undefined ||
Amounts.cmp(refundAwaiting, purchase.refundAwaiting) !== 0
) {
await ws.db await ws.db
.mktx((x) => ({ purchases: x.purchases })) .mktx((x) => ({ purchases: x.purchases }))
.runReadWrite(async (tx) => { .runReadWrite(async (tx) => {
@ -723,7 +743,7 @@ async function queryAndSaveAwaitingRefund(
logger.warn("purchase does not exist anymore"); logger.warn("purchase does not exist anymore");
return; return;
} }
p.refundAwaiting = refundAwaiting p.refundAwaiting = refundAwaiting;
await tx.purchases.put(p); await tx.purchases.put(p);
}); });
} }
@ -731,7 +751,6 @@ async function queryAndSaveAwaitingRefund(
return refundAwaiting; return refundAwaiting;
} }
async function processPurchaseQueryRefundImpl( async function processPurchaseQueryRefundImpl(
ws: InternalWalletState, ws: InternalWalletState,
proposalId: string, proposalId: string,
@ -765,7 +784,11 @@ async function processPurchaseQueryRefundImpl(
AbsoluteTime.fromTimestamp(purchase.autoRefundDeadline), AbsoluteTime.fromTimestamp(purchase.autoRefundDeadline),
) )
) { ) {
const awaitingAmount = await queryAndSaveAwaitingRefund(ws, purchase, waitForAutoRefund) const awaitingAmount = await queryAndSaveAwaitingRefund(
ws,
purchase,
waitForAutoRefund,
);
if (Amounts.isZero(awaitingAmount)) return; if (Amounts.isZero(awaitingAmount)) return;
} }