From 7fe5f3767ea256fc9ebe4b5ef3f79d4c168a331f Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 21 Apr 2023 10:49:02 -0300 Subject: integrate to the web util testing api --- packages/demobank-ui/package.json | 4 +- .../demobank-ui/src/components/Cashouts/test.ts | 134 ++----------------- .../src/components/Transactions/state.ts | 38 ------ .../src/components/Transactions/test.ts | 148 ++++++++++++--------- packages/demobank-ui/src/context/backend.ts | 19 +++ packages/demobank-ui/src/endpoints.ts | 17 ++- packages/demobank-ui/src/hooks/access.ts | 4 +- packages/demobank-ui/src/hooks/backend.ts | 5 +- packages/demobank-ui/src/hooks/circuit.ts | 4 +- .../src/pages/PaymentOptions.stories.tsx | 10 +- .../src/pages/PaytoWireTransferForm.stories.tsx | 10 +- .../src/pages/QrCodeSection.stories.tsx | 11 +- packages/demobank-ui/src/stories.test.ts | 31 +++-- 13 files changed, 175 insertions(+), 260 deletions(-) diff --git a/packages/demobank-ui/package.json b/packages/demobank-ui/package.json index 41849afa7..586beae05 100644 --- a/packages/demobank-ui/package.json +++ b/packages/demobank-ui/package.json @@ -8,7 +8,7 @@ "build": "./build.mjs", "check": "tsc", "compile": "tsc && ./build.mjs", - "test": "pnpm compile && mocha --require source-map-support/register 'dist/**/*.test.js' 'dist/**/test.js'", + "test": "mocha --require source-map-support/register 'dist/**/*.test.js' 'dist/**/test.js'", "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", "i18n:extract": "pogen extract", "i18n:merge": "pogen merge", @@ -66,4 +66,4 @@ "pogen": { "domain": "bank" } -} \ No newline at end of file +} diff --git a/packages/demobank-ui/src/components/Cashouts/test.ts b/packages/demobank-ui/src/components/Cashouts/test.ts index 6d61b0af4..c0a9aba00 100644 --- a/packages/demobank-ui/src/components/Cashouts/test.ts +++ b/packages/demobank-ui/src/components/Cashouts/test.ts @@ -22,11 +22,11 @@ import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { SwrMockEnvironment } from "@gnu-taler/web-util/lib/tests/swr"; import { expect } from "chai"; -import { TRANSACTION_API_EXAMPLE } from "../../endpoints.js"; +import { CASHOUT_API_EXAMPLE } from "../../endpoints.js"; import { Props } from "./index.js"; import { useComponentState } from "./state.js"; -describe("Transaction states", () => { +describe("Cashout states", () => { it("should query backend and render transactions", async () => { const env = new SwrMockEnvironment(); @@ -37,62 +37,16 @@ describe("Transaction states", () => { }, }; - env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_FIRST_PAGE, { + env.addRequestExpectation(CASHOUT_API_EXAMPLE.LIST_FIRST_PAGE, { response: { - transactions: [ - { - creditorIban: "DE159593", - creditorBic: "SANDBOXX", - creditorName: "exchange company", - debtorIban: "DE118695", - debtorBic: "SANDBOXX", - debtorName: "Name unknown", - amount: "1", - currency: "KUDOS", - subject: - "Taler Withdrawal N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410", - date: "2022-12-12Z", - uid: "8PPFR9EM", - direction: "DBIT", - pmtInfId: null, - msgId: null, - }, - { - creditorIban: "DE159593", - creditorBic: "SANDBOXX", - creditorName: "exchange company", - debtorIban: "DE118695", - debtorBic: "SANDBOXX", - debtorName: "Name unknown", - amount: "5.00", - currency: "KUDOS", - subject: "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0", - date: "2022-12-07Z", - uid: "7FZJC3RJ", - direction: "DBIT", - pmtInfId: null, - msgId: null, - }, - { - creditorIban: "DE118695", - creditorBic: "SANDBOXX", - creditorName: "Name unknown", - debtorIban: "DE579516", - debtorBic: "SANDBOXX", - debtorName: "The Bank", - amount: "100", - currency: "KUDOS", - subject: "Sign-up bonus", - date: "2022-12-07Z", - uid: "I31A06J8", - direction: "CRDT", - pmtInfId: null, - msgId: null, - }, - ], + cashouts: [], }, }); + env.addRequestExpectation(CASHOUT_API_EXAMPLE.MULTI_GET_EMPTY_FIRST_PAGE, { + response: [], + }); + const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, props, @@ -113,76 +67,4 @@ describe("Transaction states", () => { expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); }); - - it("should show error message on not found", async () => { - const env = new SwrMockEnvironment(); - - const props: Props = { - account: "123", - onSelected: () => { - null; - }, - }; - - env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, {}); - - const hookBehavior = await tests.hookBehaveLikeThis( - useComponentState, - props, - [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - ({ status, error }) => { - expect(status).equals("loading-error"); - expect(error).deep.eq({ - hasError: true, - operational: false, - message: "Transactions page 0 was not found.", - }); - }, - ], - env.buildTestingContext(), - ); - - expect(hookBehavior).deep.eq({ result: "ok" }); - expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); - }); - - it("should show error message on server error", async () => { - const env = new SwrMockEnvironment(false); - - const props: Props = { - account: "123", - onSelected: () => { - null; - }, - }; - - env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, {}); - - const hookBehavior = await tests.hookBehaveLikeThis( - useComponentState, - props, - [ - ({ status, error }) => { - expect(status).equals("loading"); - expect(error).undefined; - }, - ({ status, error }) => { - expect(status).equals("loading-error"); - expect(error).deep.equal({ - hasError: true, - operational: false, - message: "Transaction page 0 could not be retrieved.", - }); - }, - ], - env.buildTestingContext(), - ); - - expect(hookBehavior).deep.eq({ result: "ok" }); - expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); - }); }); diff --git a/packages/demobank-ui/src/components/Transactions/state.ts b/packages/demobank-ui/src/components/Transactions/state.ts index 198ef6c5f..4f99ed678 100644 --- a/packages/demobank-ui/src/components/Transactions/state.ts +++ b/packages/demobank-ui/src/components/Transactions/state.ts @@ -32,44 +32,6 @@ export function useComponentState({ account }: Props): State { error: result, }; } - // if (error) { - // switch (error.status) { - // case 404: - // return { - // status: "loading-error", - // error: { - // hasError: true, - // operational: false, - // message: `Transactions page ${pageNumber} was not found.`, - // }, - // }; - // case 401: - // return { - // status: "loading-error", - // error: { - // hasError: true, - // operational: false, - // message: "Wrong credentials given.", - // }, - // }; - // default: - // return { - // status: "loading-error", - // error: { - // hasError: true, - // operational: false, - // message: `Transaction page ${pageNumber} could not be retrieved.`, - // } as any, - // }; - // } - // } - - // if (!data) { - // return { - // status: "loading", - // error: undefined, - // }; - // } const transactions = result.data.transactions .map((item: unknown) => { diff --git a/packages/demobank-ui/src/components/Transactions/test.ts b/packages/demobank-ui/src/components/Transactions/test.ts index 3f2d5fb68..b13767f7c 100644 --- a/packages/demobank-ui/src/components/Transactions/test.ts +++ b/packages/demobank-ui/src/components/Transactions/test.ts @@ -19,12 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ -import { tests } from "@gnu-taler/web-util/lib/index.browser"; +import { ErrorType, tests } from "@gnu-taler/web-util/lib/index.browser"; import { SwrMockEnvironment } from "@gnu-taler/web-util/lib/tests/swr"; import { expect } from "chai"; import { TRANSACTION_API_EXAMPLE } from "../../endpoints.js"; import { Props } from "./index.js"; import { useComponentState } from "./state.js"; +import { HttpStatusCode } from "@gnu-taler/taler-util"; describe("Transaction states", () => { it("should query backend and render transactions", async () => { @@ -34,59 +35,62 @@ describe("Transaction states", () => { account: "myAccount", }; + //@ts-ignore env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_FIRST_PAGE, { response: { - transactions: [ - { - creditorIban: "DE159593", - creditorBic: "SANDBOXX", - creditorName: "exchange company", - debtorIban: "DE118695", - debtorBic: "SANDBOXX", - debtorName: "Name unknown", - amount: "1", - currency: "KUDOS", - subject: - "Taler Withdrawal N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410", - date: "2022-12-12Z", - uid: "8PPFR9EM", - direction: "DBIT", - pmtInfId: null, - msgId: null, - }, - { - creditorIban: "DE159593", - creditorBic: "SANDBOXX", - creditorName: "exchange company", - debtorIban: "DE118695", - debtorBic: "SANDBOXX", - debtorName: "Name unknown", - amount: "5.00", - currency: "KUDOS", - subject: "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0", - date: "2022-12-07Z", - uid: "7FZJC3RJ", - direction: "DBIT", - pmtInfId: null, - msgId: null, - }, - { - creditorIban: "DE118695", - creditorBic: "SANDBOXX", - creditorName: "Name unknown", - debtorIban: "DE579516", - debtorBic: "SANDBOXX", - debtorName: "The Bank", - amount: "100", - currency: "KUDOS", - subject: "Sign-up bonus", - date: "2022-12-07Z", - uid: "I31A06J8", - direction: "CRDT", - pmtInfId: null, - msgId: null, - }, - ], + data: { + transactions: [ + { + creditorIban: "DE159593", + creditorBic: "SANDBOXX", + creditorName: "exchange company", + debtorIban: "DE118695", + debtorBic: "SANDBOXX", + debtorName: "Name unknown", + amount: "1", + currency: "KUDOS", + subject: + "Taler Withdrawal N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410", + date: "2022-12-12Z", + uid: "8PPFR9EM", + direction: "DBIT", + pmtInfId: null, + msgId: null, + }, + { + creditorIban: "DE159593", + creditorBic: "SANDBOXX", + creditorName: "exchange company", + debtorIban: "DE118695", + debtorBic: "SANDBOXX", + debtorName: "Name unknown", + amount: "5.00", + currency: "KUDOS", + subject: "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0", + date: "2022-12-07Z", + uid: "7FZJC3RJ", + direction: "DBIT", + pmtInfId: null, + msgId: null, + }, + { + creditorIban: "DE118695", + creditorBic: "SANDBOXX", + creditorName: "Name unknown", + debtorIban: "DE579516", + debtorBic: "SANDBOXX", + debtorName: "The Bank", + amount: "100", + currency: "KUDOS", + subject: "Sign-up bonus", + date: "2022-12-07Z", + uid: "I31A06J8", + direction: "CRDT", + pmtInfId: null, + msgId: null, + }, + ], + }, }, }); @@ -118,7 +122,13 @@ describe("Transaction states", () => { account: "myAccount", }; - env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, {}); + env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, { + response: { + error: { + description: "Transaction page 0 could not be retrieved.", + }, + }, + }); const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, @@ -130,10 +140,13 @@ describe("Transaction states", () => { }, ({ status, error }) => { expect(status).equals("loading-error"); - expect(error).deep.eq({ - hasError: true, - operational: false, - message: "Transactions page 0 was not found.", + if (error === undefined || error.type !== ErrorType.CLIENT) { + throw Error("not the expected error"); + } + expect(error.payload).deep.equal({ + error: { + description: "Transaction page 0 could not be retrieved.", + }, }); }, ], @@ -145,13 +158,19 @@ describe("Transaction states", () => { }); it("should show error message on server error", async () => { - const env = new SwrMockEnvironment(false); + const env = new SwrMockEnvironment(); const props: Props = { account: "myAccount", }; - env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, {}); + env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, { + response: { + error: { + description: "Transaction page 0 could not be retrieved.", + }, + }, + }); const hookBehavior = await tests.hookBehaveLikeThis( useComponentState, @@ -163,10 +182,13 @@ describe("Transaction states", () => { }, ({ status, error }) => { expect(status).equals("loading-error"); - expect(error).deep.equal({ - hasError: true, - operational: false, - message: "Transaction page 0 could not be retrieved.", + if (error === undefined || error.type !== ErrorType.SERVER) { + throw Error("not the expected error"); + } + expect(error.payload).deep.equal({ + error: { + description: "Transaction page 0 could not be retrieved.", + }, }); }, ], diff --git a/packages/demobank-ui/src/context/backend.ts b/packages/demobank-ui/src/context/backend.ts index b462d20e3..b311ddbb0 100644 --- a/packages/demobank-ui/src/context/backend.ts +++ b/packages/demobank-ui/src/context/backend.ts @@ -54,3 +54,22 @@ export const BackendStateProvider = ({ children, }); }; + +export const BackendStateProviderTesting = ({ + children, + state, +}: { + children: ComponentChildren; + state: typeof defaultState; +}): VNode => { + const value: BackendStateHandler = { + state, + logIn: () => {}, + logOut: () => {}, + }; + + return h(Context.Provider, { + value, + children, + }); +}; diff --git a/packages/demobank-ui/src/endpoints.ts b/packages/demobank-ui/src/endpoints.ts index e20525ae2..b28c76613 100644 --- a/packages/demobank-ui/src/endpoints.ts +++ b/packages/demobank-ui/src/endpoints.ts @@ -22,16 +22,27 @@ export const TRANSACTION_API_EXAMPLE = { LIST_FIRST_PAGE: { method: "get" as const, - url: "access-api/accounts/myAccount/transactions?page=0", + url: '["access-api/accounts/myAccount/transactions",null,20]', }, LIST_ERROR: { method: "get" as const, - url: "access-api/accounts/myAccount/transactions?page=0", + url: '["access-api/accounts/myAccount/transactions",null,20]', code: 500, }, LIST_NOT_FOUND: { method: "get" as const, - url: "access-api/accounts/myAccount/transactions?page=0", + url: '["access-api/accounts/myAccount/transactions",null,20]', code: 404, }, }; + +export const CASHOUT_API_EXAMPLE = { + LIST_FIRST_PAGE: { + method: "get" as const, + url: '["circuit-api/cashouts","123"]', + }, + MULTI_GET_EMPTY_FIRST_PAGE: { + method: "get" as const, + url: "[[]]", + }, +}; diff --git a/packages/demobank-ui/src/hooks/access.ts b/packages/demobank-ui/src/hooks/access.ts index 546d59a84..5eddec033 100644 --- a/packages/demobank-ui/src/hooks/access.ts +++ b/packages/demobank-ui/src/hooks/access.ts @@ -378,7 +378,9 @@ export function useTransactions( if (afterData) setLastAfter(afterData); }, [afterData]); - if (afterError) return afterError.info; + if (afterError) { + return afterError.cause; + } // if the query returns less that we ask, then we have reach the end or beginning const isReachingEnd = diff --git a/packages/demobank-ui/src/hooks/backend.ts b/packages/demobank-ui/src/hooks/backend.ts index 9fe0f5b14..c67d1cdeb 100644 --- a/packages/demobank-ui/src/hooks/backend.ts +++ b/packages/demobank-ui/src/hooks/backend.ts @@ -52,7 +52,10 @@ interface LoggedOut { } export function getInitialBackendBaseURL(): string { - const overrideUrl = localStorage.getItem("bank-base-url"); + const overrideUrl = + typeof localStorage !== "undefined" + ? localStorage.getItem("bank-base-url") + : undefined; if (!overrideUrl) { //normal path if (!bankUiSettings.backendBaseURL) { diff --git a/packages/demobank-ui/src/hooks/circuit.ts b/packages/demobank-ui/src/hooks/circuit.ts index f90469e24..8169947d3 100644 --- a/packages/demobank-ui/src/hooks/circuit.ts +++ b/packages/demobank-ui/src/hooks/circuit.ts @@ -525,8 +525,8 @@ export function useCashouts( refreshWhenOffline: false, }); - if (listError) return listError.info; - if (productError) return productError.info; + if (listError) return listError.cause; + if (productError) return productError.cause; if (cashouts) { const dataWithId = cashouts.map((d) => { diff --git a/packages/demobank-ui/src/pages/PaymentOptions.stories.tsx b/packages/demobank-ui/src/pages/PaymentOptions.stories.tsx index aced5eea9..fa94af75a 100644 --- a/packages/demobank-ui/src/pages/PaymentOptions.stories.tsx +++ b/packages/demobank-ui/src/pages/PaymentOptions.stories.tsx @@ -19,15 +19,17 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { PaymentOptions } from "./PaymentOptions.js"; export default { title: "PaymentOptions", }; -export const USD = { - component: PaymentOptions, - props: { +export const USD = tests.createExample(PaymentOptions, { + limit: { currency: "USD", + fraction: 0, + value: 1, }, -}; +}); diff --git a/packages/demobank-ui/src/pages/PaytoWireTransferForm.stories.tsx b/packages/demobank-ui/src/pages/PaytoWireTransferForm.stories.tsx index 141b9addf..d5f2d941f 100644 --- a/packages/demobank-ui/src/pages/PaytoWireTransferForm.stories.tsx +++ b/packages/demobank-ui/src/pages/PaytoWireTransferForm.stories.tsx @@ -19,15 +19,17 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { PaytoWireTransferForm } from "./PaytoWireTransferForm.js"; export default { title: "PaytoWireTransferForm", }; -export const USD = { - component: PaytoWireTransferForm, - props: { +export const USD = tests.createExample(PaytoWireTransferForm, { + limit: { currency: "USD", + fraction: 0, + value: 1, }, -}; +}); diff --git a/packages/demobank-ui/src/pages/QrCodeSection.stories.tsx b/packages/demobank-ui/src/pages/QrCodeSection.stories.tsx index 521d4255e..11c21cc09 100644 --- a/packages/demobank-ui/src/pages/QrCodeSection.stories.tsx +++ b/packages/demobank-ui/src/pages/QrCodeSection.stories.tsx @@ -19,15 +19,14 @@ * @author Sebastian Javier Marchano (sebasjm) */ +import { tests } from "@gnu-taler/web-util/lib/index.browser"; import { QrCodeSection } from "./QrCodeSection.js"; +import { parseWithdrawUri } from "@gnu-taler/taler-util"; export default { title: "Qr Code Selection", }; -export const SimpleExample = { - component: QrCodeSection, - props: { - talerWithdrawUri: "taler://withdraw/asdasdasd", - }, -}; +export const SimpleExample = tests.createExample(QrCodeSection, { + withdrawUri: parseWithdrawUri("taler://withdraw/bank.com/operationId"), +}); diff --git a/packages/demobank-ui/src/stories.test.ts b/packages/demobank-ui/src/stories.test.ts index a9e5ec5c0..19b16d52c 100644 --- a/packages/demobank-ui/src/stories.test.ts +++ b/packages/demobank-ui/src/stories.test.ts @@ -19,13 +19,13 @@ * @author Sebastian Javier Marchano (sebasjm) */ import { setupI18n } from "@gnu-taler/taler-util"; -import { parseGroupImport } from "@gnu-taler/web-util/lib/index.browser"; +import { parseGroupImport, tests } from "@gnu-taler/web-util/lib/index.browser"; -import * as pages from "./pages/index.stories.js"; import * as components from "./components/index.examples.js"; +import * as pages from "./pages/index.stories.js"; -import { h as create } from "preact"; -import { render as renderToString } from "preact-render-to-string"; +import { ComponentChildren, VNode, h as create } from "preact"; +import { BackendStateProviderTesting } from "./context/backend.js"; setupI18n("en", { en: {} }); @@ -37,12 +37,7 @@ describe("All the examples:", () => { describe(`Component ${component.name}:`, () => { component.examples.forEach((example) => { it(`should render example: ${example.name}`, () => { - const vdom = create( - example.render.component, - example.render.props, - ); - const html = renderToString(vdom); - // console.log(html) + tests.renderUI(example.render, DefaultTestingContext); }); }); }); @@ -50,3 +45,19 @@ describe("All the examples:", () => { }); }); }); + +function DefaultTestingContext({ + children, +}: { + children: ComponentChildren; +}): VNode { + return create(BackendStateProviderTesting, { + children, + state: { + status: "loggedIn", + username: "test", + password: "pwd", + isUserAdministrator: false, + }, + }); +} -- cgit v1.2.3