integrate to the web util testing api

This commit is contained in:
Sebastian 2023-04-21 10:49:02 -03:00
parent f470f167e3
commit 7fe5f3767e
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
13 changed files with 175 additions and 260 deletions

View File

@ -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"
}
}
}

View File

@ -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" });
});
});

View File

@ -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) => {

View File

@ -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.",
},
});
},
],

View File

@ -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,
});
};

View File

@ -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: "[[]]",
},
};

View File

@ -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 =

View File

@ -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) {

View File

@ -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) => {

View File

@ -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,
},
};
});

View File

@ -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,
},
};
});

View File

@ -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"),
});

View File

@ -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,
},
});
}