integration tests: one variable for pybank/libeufin switch
This commit is contained in:
parent
1ea28c5be1
commit
59a2119dcb
@ -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}`;
|
||||||
|
@ -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[] = [];
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user