fix wallet DB

This commit is contained in:
Florian Dold 2020-08-24 20:00:15 +05:30
parent 0e88ef9bd2
commit 7deefd5b2d
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
5 changed files with 185 additions and 27 deletions

View File

@ -17,35 +17,41 @@
/**
* Imports.
*/
import { runTest, GlobalTestState, MerchantPrivateApi } from "./harness";
import { createSimpleTestkudosEnvironment, withdrawViaBank } from "./helpers";
import {
runTest,
GlobalTestState,
MerchantPrivateApi,
MerchantService,
BankServiceInterface,
MerchantServiceInterface,
WalletCli,
ExchangeServiceInterface,
} from "./harness";
import {
createSimpleTestkudosEnvironment,
withdrawViaBank,
SimpleTestEnvironment,
} from "./helpers";
import { PreparePayResultType, URL } from "taler-wallet-core";
import axios from "axios";
/**
* Test case for the refund API of the merchant backend.
*/
runTest(async (t: GlobalTestState) => {
// Set up test environment
const {
wallet,
bank,
exchange,
merchant,
} = await createSimpleTestkudosEnvironment(t);
// Withdraw digital cash into the wallet.
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
async function testRefundApiWithFulfillmentUrl(
t: GlobalTestState,
env: {
merchant: MerchantServiceInterface;
bank: BankServiceInterface;
wallet: WalletCli;
exchange: ExchangeServiceInterface;
},
): Promise<void> {
const { wallet, bank, exchange, merchant } = env;
// Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
order: {
summary: "Buy me!",
amount: "TESTKUDOS:5",
fulfillment_url: "taler://fulfillment-success/thx",
fulfillment_url: "https://example.com/fulfillment",
},
});
@ -131,7 +137,150 @@ runTest(async (t: GlobalTestState) => {
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
validateStatus: () => true,
});
console.log(publicOrderStatusResp.data)
// We didn't give any authentication, so this should be forbidden
t.assertTrue(publicOrderStatusResp.status === 403);
console.log(publicOrderStatusResp.data);
// We didn't give any authentication, so we should get a fulfillment URL back
t.assertTrue(publicOrderStatusResp.status === 202);
const fu = publicOrderStatusResp.data.fulfillment_url;
t.assertTrue(typeof fu === "string" && fu.startsWith("https://example.com"));
}
async function testRefundApiWithFulfillmentMessage(
t: GlobalTestState,
env: {
merchant: MerchantServiceInterface;
bank: BankServiceInterface;
wallet: WalletCli;
exchange: ExchangeServiceInterface;
},
): Promise<void> {
const { wallet, bank, exchange, merchant } = env;
// Set up order.
const orderResp = await MerchantPrivateApi.createOrder(merchant, "default", {
order: {
summary: "Buy me!",
amount: "TESTKUDOS:5",
fulfillment_message: "Thank you for buying foobar",
},
});
let orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
orderId: orderResp.order_id,
});
t.assertTrue(orderStatus.order_status === "unpaid");
const talerPayUri = orderStatus.taler_pay_uri;
const orderId = orderResp.order_id;
// Make wallet pay for the order
let preparePayResult = await wallet.preparePay({
talerPayUri,
});
t.assertTrue(
preparePayResult.status === PreparePayResultType.PaymentPossible,
);
const r2 = await wallet.apiRequest("confirmPay", {
proposalId: preparePayResult.proposalId,
});
t.assertTrue(r2.type === "response");
// Check if payment was successful.
orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
orderId: orderResp.order_id,
});
t.assertTrue(orderStatus.order_status === "paid");
preparePayResult = await wallet.preparePay({
talerPayUri,
});
t.assertTrue(
preparePayResult.status === PreparePayResultType.AlreadyConfirmed,
);
await MerchantPrivateApi.giveRefund(merchant, {
amount: "TESTKUDOS:5",
instance: "default",
justification: "foo",
orderId: orderResp.order_id,
});
orderStatus = await MerchantPrivateApi.queryPrivateOrderStatus(merchant, {
orderId: orderResp.order_id,
});
t.assertTrue(orderStatus.order_status === "paid");
t.assertAmountEquals(orderStatus.refund_amount, "TESTKUDOS:5");
// Now test what the merchant gives as a response for various requests to the
// public order status URL!
let publicOrderStatusUrl = new URL(
`orders/${orderId}`,
merchant.makeInstanceBaseUrl(),
);
publicOrderStatusUrl.searchParams.set(
"h_contract",
preparePayResult.contractTermsHash,
);
let publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
validateStatus: () => true,
});
console.log(publicOrderStatusResp.data);
t.assertTrue(publicOrderStatusResp.status === 200);
t.assertAmountEquals(publicOrderStatusResp.data.refund_amount, "TESTKUDOS:5");
publicOrderStatusUrl = new URL(
`orders/${orderId}`,
merchant.makeInstanceBaseUrl(),
);
publicOrderStatusResp = await axios.get(publicOrderStatusUrl.href, {
validateStatus: () => true,
});
console.log(publicOrderStatusResp.data);
// We didn't give any authentication, so we should get a fulfillment URL back
t.assertTrue(publicOrderStatusResp.status === 202);
const fu = publicOrderStatusResp.data.fulfillment_message;
t.assertTrue(typeof fu === "string" && fu.startsWith("Thank you"));
}
/**
* Test case for the refund API of the merchant backend.
*/
runTest(async (t: GlobalTestState) => {
// Set up test environment
const {
wallet,
bank,
exchange,
merchant,
} = await createSimpleTestkudosEnvironment(t);
// Withdraw digital cash into the wallet.
await withdrawViaBank(t, { wallet, bank, exchange, amount: "TESTKUDOS:20" });
await testRefundApiWithFulfillmentUrl(t, {
wallet,
bank,
exchange,
merchant,
});
await testRefundApiWithFulfillmentMessage(t, {
wallet,
bank,
exchange,
merchant,
});
});

View File

@ -8,7 +8,7 @@ import { IDBFactory, IDBDatabase } from "idb-bridge";
* with each major change. When incrementing the major version,
* the wallet should import data from the previous version.
*/
const TALER_DB_NAME = "taler-walletdb-v7";
const TALER_DB_NAME = "taler-walletdb-v8";
/**
* Current database minor version, should be incremented

View File

@ -686,7 +686,7 @@ async function processDownloadProposalImpl(
contractData: {
amount,
contractTermsHash: contractTermsHash,
fulfillmentUrl: parsedContractTerms.fulfillment_url,
fulfillmentUrl: parsedContractTerms.fulfillment_url ?? "",
merchantBaseUrl: parsedContractTerms.merchant_base_url,
merchantPub: parsedContractTerms.merchant_pub,
merchantSig: proposalResp.sig,

View File

@ -235,7 +235,6 @@ export async function getTransactions(
return;
}
const info: OrderShortInfo = {
fulfillmentUrl: pr.contractData.fulfillmentUrl,
merchant: pr.contractData.merchant,
orderId: pr.contractData.orderId,
products: pr.contractData.products,
@ -243,6 +242,9 @@ export async function getTransactions(
summary_i18n: pr.contractData.summaryI18n,
contractTermsHash: pr.contractData.contractTermsHash,
};
if (pr.contractData.fulfillmentUrl !== "") {
info.fulfillmentUrl = pr.contractData.fulfillmentUrl;
}
const paymentTransactionId = makeEventId(
TransactionType.Payment,
pr.proposalId,

View File

@ -1271,7 +1271,14 @@ export interface AllowedExchangeInfo {
export interface WalletContractData {
products?: Product[];
summaryI18n: { [lang_tag: string]: string } | undefined;
fulfillmentUrl?: string;
/**
* Fulfillment URL, or the empty string if the order has no fulfillment URL.
*
* Stored as a non-nullable string as we use this field for IndexedDB indexing.
*/
fulfillmentUrl: string;
contractTermsHash: string;
fulfillmentMessage?: string;
fulfillmentMessageI18n?: InternationalizedString;