gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: harness: work on otp test


From: gnunet
Subject: [taler-wallet-core] branch master updated: harness: work on otp test
Date: Tue, 30 Jan 2024 22:25:58 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new c5f97c8f4 harness: work on otp test
c5f97c8f4 is described below

commit c5f97c8f493b52f9e083548d0ac71592c56a2b79
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Jan 30 22:25:54 2024 +0100

    harness: work on otp test
---
 .../taler-harness/src/integrationtests/test-otp.ts | 77 +++++++++++++++++++++-
 .../src/integrationtests/test-payment-template.ts  |  6 +-
 packages/taler-util/src/MerchantApiClient.ts       | 29 +++++++-
 packages/taler-util/src/merchant-api-types.ts      | 38 ++++++-----
 packages/taler-util/src/operation.ts               | 26 ++++++++
 5 files changed, 152 insertions(+), 24 deletions(-)

diff --git a/packages/taler-harness/src/integrationtests/test-otp.ts 
b/packages/taler-harness/src/integrationtests/test-otp.ts
index dd6c45e4c..d4dee12ad 100644
--- a/packages/taler-harness/src/integrationtests/test-otp.ts
+++ b/packages/taler-harness/src/integrationtests/test-otp.ts
@@ -17,14 +17,22 @@
 /**
  * Imports.
  */
+import {
+  ConfirmPayResultType,
+  Duration,
+  MerchantApiClient,
+  PreparePayResultType,
+  encodeCrock,
+  getRandomBytes,
+  j2s,
+  narrowOpSuccessOrThrow,
+} from "@gnu-taler/taler-util";
 import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
 import { GlobalTestState } from "../harness/harness.js";
 import {
   createSimpleTestkudosEnvironmentV2,
   withdrawViaBankV2,
-  makeTestPaymentV2,
 } from "../harness/helpers.js";
-import { MerchantApiClient, j2s } from "@gnu-taler/taler-util";
 
 /**
  * Run test for basic, bank-integrated withdrawal and payment.
@@ -36,6 +44,71 @@ export async function runOtpTest(t: GlobalTestState) {
     await createSimpleTestkudosEnvironmentV2(t);
 
   const merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl());
+  const createOtpRes = await merchantClient.createOtpDevice({
+    otp_algorithm: 1,
+    otp_device_description: "Hello",
+    otp_device_id: "mydevice",
+    otp_key: encodeCrock(getRandomBytes(16)),
+  });
+  narrowOpSuccessOrThrow(createOtpRes);
+
+  const createTemplateRes = await merchantClient.createTemplate({
+    template_description: "my template",
+    template_id: "tpl1",
+    otp_id: "mydevice",
+    template_contract: {
+      summary: "test",
+      amount: "TESTKUDOS:1",
+      minimum_age: 0,
+      pay_duration: Duration.toTalerProtocolDuration(
+        Duration.fromSpec({ hours: 1 }),
+      ),
+    },
+  });
+  narrowOpSuccessOrThrow(createTemplateRes);
+
+  const getTemplateResp = await merchantClient.getTemplate("tpl1");
+  narrowOpSuccessOrThrow(getTemplateResp);
+  console.log(`template: ${j2s(getTemplateResp.body)}`);
+
+  const wres = await withdrawViaBankV2(t, {
+    walletClient,
+    bank,
+    exchange,
+    amount: "TESTKUDOS:20",
+  });
+  await wres.withdrawalFinishedCond;
+
+  const preparePayResult = await walletClient.call(
+    WalletApiOperation.PreparePayForTemplate,
+    {
+      talerPayTemplateUri: 
`taler+http://pay-template/localhost:${merchant.port}/tpl1`,
+      templateParams: {},
+    },
+  );
+
+  console.log(preparePayResult);
+
+  t.assertTrue(
+    preparePayResult.status === PreparePayResultType.PaymentPossible,
+  );
+
+  // Pay for it
+
+  const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, {
+    transactionId: preparePayResult.transactionId,
+  });
+
+  t.assertTrue(r2.type === ConfirmPayResultType.Done);
+
+  const transaction = await walletClient.call(
+    WalletApiOperation.GetTransactionById,
+    {
+      transactionId: preparePayResult.transactionId,
+    },
+  );
+
+  console.log(j2s(transaction));
 }
 
 runOtpTest.suites = ["wallet"];
diff --git 
a/packages/taler-harness/src/integrationtests/test-payment-template.ts 
b/packages/taler-harness/src/integrationtests/test-payment-template.ts
index e77236a9a..c9f1caacd 100644
--- a/packages/taler-harness/src/integrationtests/test-payment-template.ts
+++ b/packages/taler-harness/src/integrationtests/test-payment-template.ts
@@ -22,6 +22,7 @@ import {
   Duration,
   MerchantApiClient,
   PreparePayResultType,
+  narrowOpSuccessOrThrow,
 } from "@gnu-taler/taler-util";
 import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
 import { GlobalTestState } from "../harness/harness.js";
@@ -41,7 +42,7 @@ export async function runPaymentTemplateTest(t: 
GlobalTestState) {
 
   const merchantClient = new MerchantApiClient(merchant.makeInstanceBaseUrl());
 
-  await merchantClient.createTemplate({
+  const createTemplateRes = await merchantClient.createTemplate({
     template_id: "template1",
     template_description: "my test template",
     template_contract: {
@@ -54,6 +55,7 @@ export async function runPaymentTemplateTest(t: 
GlobalTestState) {
       summary: "hello, I'm a summary",
     },
   });
+  narrowOpSuccessOrThrow(createTemplateRes);
 
   // Withdraw digital cash into the wallet.
 
@@ -84,7 +86,7 @@ export async function runPaymentTemplateTest(t: 
GlobalTestState) {
   // Pay for it
 
   const r2 = await walletClient.call(WalletApiOperation.ConfirmPay, {
-    proposalId: preparePayResult.proposalId,
+    transactionId: preparePayResult.transactionId,
   });
 
   t.assertTrue(r2.type === ConfirmPayResultType.Done);
diff --git a/packages/taler-util/src/MerchantApiClient.ts 
b/packages/taler-util/src/MerchantApiClient.ts
index 561226ba9..db1ffef4e 100644
--- a/packages/taler-util/src/MerchantApiClient.ts
+++ b/packages/taler-util/src/MerchantApiClient.ts
@@ -362,8 +362,30 @@ export class MerchantApiClient {
       body: req,
       headers: this.makeAuthHeader(),
     });
-    if (resp.status !== 204) {
-      throw Error("failed to create template");
+    switch (resp.status) {
+      case HttpStatusCode.Ok:
+      case HttpStatusCode.NoContent:
+        return opEmptySuccess(resp);
+      case HttpStatusCode.NotFound:
+        return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await resp.text());
+    }
+  }
+
+  async getTemplate(templateId: string) {
+    let url = new URL(`private/templates/${templateId}`, this.baseUrl);
+    const resp = await this.httpClient.fetch(url.href, {
+      method: "GET",
+      headers: this.makeAuthHeader(),
+    });
+    switch (resp.status) {
+      case HttpStatusCode.Ok:
+        return opSuccess(resp, codecForAny());
+      case HttpStatusCode.NotFound:
+        return opKnownHttpFailure(resp.status, resp);
+      default:
+        return opUnknownFailure(resp, await resp.text());
     }
   }
 
@@ -391,7 +413,7 @@ export class MerchantApiClient {
   async createOtpDevice(
     req: OtpDeviceAddDetails,
   ): Promise<OperationOk<void> | OperationFail<HttpStatusCode.NotFound>> {
-    let url = new URL("private/templates", this.baseUrl);
+    let url = new URL("private/otp-devices", this.baseUrl);
     const resp = await this.httpClient.fetch(url.href, {
       method: "POST",
       body: req,
@@ -399,6 +421,7 @@ export class MerchantApiClient {
     });
     switch (resp.status) {
       case HttpStatusCode.Ok:
+      case HttpStatusCode.NoContent:
         return opEmptySuccess(resp);
       case HttpStatusCode.NotFound:
         return opKnownHttpFailure(resp.status, resp);
diff --git a/packages/taler-util/src/merchant-api-types.ts 
b/packages/taler-util/src/merchant-api-types.ts
index 999246597..724e99b55 100644
--- a/packages/taler-util/src/merchant-api-types.ts
+++ b/packages/taler-util/src/merchant-api-types.ts
@@ -25,29 +25,29 @@
  * Imports.
  */
 import {
-  MerchantContractTerms,
-  Codec,
-  buildCodecForObject,
-  codecForString,
-  codecOptional,
-  codecForConstString,
-  codecForBoolean,
-  codecForNumber,
-  codecForMerchantContractTerms,
-  codecForAny,
-  buildCodecForUnion,
-  AmountString,
   AbsoluteTime,
+  AmountString,
+  Codec,
   CoinPublicKeyString,
   EddsaPublicKeyString,
-  codecForAmountString,
+  ExchangeWireAccount,
+  FacadeCredentials,
+  MerchantContractTerms,
   TalerProtocolDuration,
-  codecForTimestamp,
   TalerProtocolTimestamp,
-  ExchangeWireAccount,
+  buildCodecForObject,
+  buildCodecForUnion,
+  codecForAmountString,
+  codecForAny,
+  codecForBoolean,
+  codecForConstString,
   codecForExchangeWireAccount,
   codecForList,
-  FacadeCredentials,
+  codecForMerchantContractTerms,
+  codecForNumber,
+  codecForString,
+  codecForTimestamp,
+  codecOptional,
 } from "@gnu-taler/taler-util";
 
 export interface MerchantPostOrderRequest {
@@ -345,7 +345,7 @@ export interface MerchantTemplateContractDetails {
 
   // The price is imposed by the merchant and cannot be changed by the 
customer.
   // This parameter is optional.
-  amount?: AmountString;
+  amount?: string;
 
   // Minimum age buyer must have (in years). Default is 0.
   minimum_age: number;
@@ -369,6 +369,10 @@ export interface MerchantTemplateAddDetails {
 
   // Additional information in a separate template.
   template_contract: MerchantTemplateContractDetails;
+
+  // OTP device ID.
+  // This parameter is optional.
+  otp_id?: string;
 }
 
 export interface MerchantReserveCreateConfirmation {
diff --git a/packages/taler-util/src/operation.ts 
b/packages/taler-util/src/operation.ts
index 213bfeecd..a554e1f31 100644
--- a/packages/taler-util/src/operation.ts
+++ b/packages/taler-util/src/operation.ts
@@ -147,6 +147,32 @@ export function opUnknownFailure(resp: HttpResponse, text: 
string): never {
   );
 }
 
+/**
+ * Convenience function to throw an error if the operation is not a success.
+ */
+export function narrowOpSuccessOrThrow<Body, ErrorEnum>(
+  opRes: OperationResult<Body, ErrorEnum>,
+): asserts opRes is OperationOk<Body> {
+  const httpResponse = opRes.httpResp;
+  if (opRes.type !== "ok") {
+    throw TalerError.fromDetail(
+      TalerErrorCode.WALLET_UNEXPECTED_REQUEST_ERROR,
+      {
+        requestUrl: httpResponse.requestUrl,
+        requestMethod: httpResponse.requestMethod,
+        httpStatusCode: httpResponse.status,
+        errorResponse:
+          "detail" in opRes
+            ? opRes.detail
+            : "body" in opRes
+              ? opRes.body
+              : undefined,
+      },
+      `Unexpected HTTP status ${httpResponse.status} in response`,
+    );
+  }
+}
+
 export type ResultByMethod<
   TT extends object,
   p extends keyof TT,

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]