aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-harness
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-11-03 19:00:47 -0300
committerSebastian <sebasjm@gmail.com>2023-11-03 19:00:47 -0300
commit11b99b9256d13e16aff460db6f014390ded4670b (patch)
tree998290c45c98158dfdc454b9a6978091c40b54b2 /packages/taler-harness
parent08898c7aa32b5a4dbc40c2fecd82a5a652126705 (diff)
downloadwallet-core-11b99b9256d13e16aff460db6f014390ded4670b.tar.xz
test for every error code in the spec
Diffstat (limited to 'packages/taler-harness')
-rw-r--r--packages/taler-harness/src/http-client/bank-core.ts1375
-rw-r--r--packages/taler-harness/src/index.ts111
2 files changed, 893 insertions, 593 deletions
diff --git a/packages/taler-harness/src/http-client/bank-core.ts b/packages/taler-harness/src/http-client/bank-core.ts
index 6f9641dc9..ccefd2bfe 100644
--- a/packages/taler-harness/src/http-client/bank-core.ts
+++ b/packages/taler-harness/src/http-client/bank-core.ts
@@ -1,542 +1,841 @@
-import { AccessToken, Amounts, TalerCoreBankHttpClient, TalerCorebankApi, buildPayto, encodeCrock, failOrThrow, getRandomBytes, parsePaytoUri, stringifyPaytoUri, succeedOrThrow } from "@gnu-taler/taler-util"
-
-export class BankCoreSmokeTest {
- constructor(readonly api: TalerCoreBankHttpClient) {
-
- }
-
- async testConfig() {
- const config = await this.api.getConfig()
- if (!this.api.isCompatible(config.body.version)) {
- throw Error(`not compatible with server ${config.body.version}`)
- }
- return config.body
- }
-
- async testCashouts(adminPassword: string) {
- }
- async testMonitor(adminPassword: string) {
- const { access_token: adminToken } = await succeedOrThrow(() =>
- this.api.getAuthenticationAPI("admin").createAccessToken(adminPassword, {
- scope: "readwrite"
- })
- )
-
- await succeedOrThrow(() => (
- this.api.getMonitor()
- ))
-
- await succeedOrThrow(() => (
- this.api.getMonitor({
- timeframe: TalerCorebankApi.MonitorTimeframeParam.day,
- which: (new Date()).getDate() - 1
- })
- ))
- }
-
- async testAccountManagement(adminPassword: string) {
-
- const { access_token: adminToken } = await succeedOrThrow(() =>
- this.api.getAuthenticationAPI("admin").createAccessToken(adminPassword, {
- scope: "readwrite"
- })
- )
-
- /**
- * Create account
- */
- {
- const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
-
- // await failOrThrow("invalid-input",() =>
- // this.api.createAccount(adminToken, {
- // name: username,
- // username, password: "123",
- // challenge_contact_data: {
- // email: "invalid email",
- // phone: "invalid phone",
- // }
- // })
- // )
-
- // await failOrThrow("unable-to-create",() =>
- // this.api.createAccount(adminToken, {
- // name: "admin",
- // username, password: "123"
- // })
- // )
-
- // await failOrThrow("unable-to-create",() =>
- // this.api.createAccount(adminToken, {
- // name: "bank",
- // username, password: "123"
- // })
- // )
-
- await succeedOrThrow(() =>
- this.api.createAccount(adminToken, {
- name: username,
- username, password: "123"
- })
- )
-
- await failOrThrow("already-exist", () =>
- this.api.createAccount(adminToken, {
- name: username,
- username, password: "123"
- })
- );
- }
-
- /**
- * Delete account
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- await failOrThrow("not-found", () =>
- this.api.deleteAccount({ username: "not-found", token: adminToken })
- )
- await failOrThrow("unable-to-delete", () =>
- this.api.deleteAccount({ username: "admin", token: adminToken })
- )
- await failOrThrow("unable-to-delete", () =>
- this.api.deleteAccount({ username: "bank", token: adminToken })
- )
-
- await failOrThrow("balance-not-zero", () =>
- this.api.deleteAccount({ username, token: adminToken })
- )
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
-
- const adminInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username: "admin", token: adminToken })
- )
-
- const adminAccount = parsePaytoUri(adminInfo.payto_uri)!
- adminAccount.params["message"] = "all my money"
- const withSubject = stringifyPaytoUri(adminAccount)
-
- await succeedOrThrow(() =>
- this.api.createTransaction({ username, token }, {
- payto_uri: withSubject,
- amount: userInfo.balance.amount
- })
- )
-
-
- const otherUsername = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
-
- await succeedOrThrow(() =>
- this.api.createAccount(adminToken, {
- name: otherUsername,
- username: otherUsername, password: "123"
- })
- )
-
- await failOrThrow("unauthorized", () =>
- this.api.deleteAccount({ username: otherUsername, token })
- )
-
- await succeedOrThrow(() =>
- this.api.deleteAccount({ username, token: adminToken })
- )
- }
-
- /**
- * Update account
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- await failOrThrow("cant-change-legal-name-or-admin", () =>
- this.api.updateAccount({ username, token }, {
- name: "something else",
- })
- )
-
- // await failOrThrow("not-found", () =>
- // this.api.updateAccount({ username: "notfound", token }, {
- // challenge_contact_data: {
- // email: "asd@Aasd.com"
- // }
- // })
- // )
-
- await failOrThrow("unauthorized", () =>
- this.api.updateAccount({ username: "notfound", token: "wrongtoken" as AccessToken }, {
- challenge_contact_data: {
- email: "asd@Aasd.com"
- }
- })
- )
-
- await succeedOrThrow(() =>
- this.api.updateAccount({ username, token }, {
- challenge_contact_data: {
- email: "asd@Aasd.com"
- }
- })
- )
- }
-
- /**
- * Update password
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- await succeedOrThrow(() =>
- this.api.updatePassword({ username, token }, {
- old_password: "123",
- new_password: "234"
- })
- )
- // await failOrThrow("not-found",() =>
- // this.api.updatePassword({ username:"notfound", token: userTempToken }, {
- // old_password: "123",
- // new_password: "234"
- // })
- // )
- await failOrThrow("unauthorized", () =>
- this.api.updatePassword({ username: "admin", token }, {
- old_password: "123",
- new_password: "234"
- })
- )
- // await failOrThrow("old-password-invalid-or-not-allowed",() =>
- // this.api.updatePassword({ username, token: userTempToken }, {
- // old_password: "123",
- // new_password: "234"
- // })
- // )
-
- }
-
- /**
- * public accounts
- */
- {
- const acs = await succeedOrThrow(() => this.api.getPublicAccounts())
-
- }
- /**
- * get accounts
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
- // await failOrThrow("no-rights",() =>
- // this.api.getAccounts(token)
- // )
- await failOrThrow("unauthorized", () =>
- this.api.getAccounts("ASDASD" as AccessToken)
- )
-
- const acs = await succeedOrThrow(() =>
- this.api.getAccounts(adminToken)
- )
- }
-
- }
-
- async testWithdrawals(adminPassword: string) {
- const { access_token: adminToken } = await succeedOrThrow(() =>
- this.api.getAuthenticationAPI("admin").createAccessToken(adminPassword, {
- scope: "readwrite"
- })
- )
- /**
- * create withdrawals
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
-
- const balance = Amounts.parseOrThrow(userInfo.balance.amount)
- const moreThanBalance = Amounts.stringify(Amounts.mult(balance, 5).amount)
- await failOrThrow("insufficient-funds", () =>
- this.api.createWithdrawal({ username, token }, {
- amount: moreThanBalance
- })
- )
-
- await failOrThrow("unauthorized", () =>
- this.api.createWithdrawal({ username, token: "wrongtoken" as AccessToken }, {
- amount: userInfo.balance.amount
- })
- )
-
- await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
- }
-
- /**
- * get withdrawal
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
-
- const { withdrawal_id } = await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
-
- await succeedOrThrow(() =>
- this.api.getWithdrawalById(withdrawal_id)
- )
-
- await failOrThrow("invalid-id", () =>
- this.api.getWithdrawalById("invalid")
- )
- await failOrThrow("not-found", () =>
- this.api.getWithdrawalById("11111111-1111-1111-1111-111111111111")
- )
- }
-
- /**
- * abort withdrawal
- */
- {
- const { username: exchangeUser, token: exchangeToken } = await createRandomTestUser(this.api, adminToken, { is_taler_exchange: true })
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
- const exchangeInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username: exchangeUser, token: exchangeToken })
- )
-
- await failOrThrow("invalid-id", () =>
- this.api.abortWithdrawalById("invalid")
- )
- await failOrThrow("not-found", () =>
- this.api.abortWithdrawalById("11111111-1111-1111-1111-111111111111")
- )
-
- const { withdrawal_id: firstWithdrawal } = await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
-
- await succeedOrThrow(() =>
- this.api.abortWithdrawalById(firstWithdrawal)
- )
-
- const { taler_withdraw_uri: uri, withdrawal_id: secondWithdrawal } = await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
-
- await succeedOrThrow(() =>
- this.api.getIntegrationAPI().completeWithdrawalOperationById(secondWithdrawal, {
- reserve_pub: encodeCrock(getRandomBytes(32)),
- selected_exchange: exchangeInfo.payto_uri,
- })
- )
- await succeedOrThrow(() =>
- this.api.confirmWithdrawalById(secondWithdrawal)
- )
- await failOrThrow("previously-confirmed", () =>
- this.api.abortWithdrawalById(secondWithdrawal)
- )
- }
-
- /**
- * confirm withdrawal
- */
- {
- const { username: exchangeUser, token: exchangeToken } = await createRandomTestUser(this.api, adminToken, { is_taler_exchange: true })
- const { username, token } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
- const exchangeInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username: exchangeUser, token: exchangeToken })
- )
-
- await failOrThrow("invalid-id", () =>
- this.api.confirmWithdrawalById("invalid")
- )
- await failOrThrow("not-found", () =>
- this.api.confirmWithdrawalById("11111111-1111-1111-1111-111111111111")
- )
-
- const { withdrawal_id: firstWithdrawal } = await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
-
- await failOrThrow("no-exchange-or-reserve-selected", () =>
- this.api.confirmWithdrawalById(firstWithdrawal)
- )
-
- await succeedOrThrow(() =>
- this.api.getIntegrationAPI().completeWithdrawalOperationById(firstWithdrawal, {
- reserve_pub: encodeCrock(getRandomBytes(32)),
- selected_exchange: exchangeInfo.payto_uri,
- })
- )
-
- await succeedOrThrow(() =>
- this.api.confirmWithdrawalById(firstWithdrawal)
- )
-
- const { withdrawal_id: secondWithdrawal } = await succeedOrThrow(() =>
- this.api.createWithdrawal({ username, token }, {
- amount: userInfo.balance.amount
- })
- )
-
- await succeedOrThrow(() =>
- this.api.abortWithdrawalById(secondWithdrawal)
- )
- //FIXME: skip
- // await failOrThrow("previously-aborted", () =>
- // this.api.confirmWithdrawalById(secondWithdrawal)
- // )
- }
+import { AccessToken, Amounts, TalerCoreBankHttpClient, TalerCorebankApi, TestForApi, buildPayto, encodeCrock, failOrThrow, getRandomBytes, parsePaytoUri, stringifyPaytoUri, succeedOrThrow } from "@gnu-taler/taler-util"
+
+
+
+export function createTestForBankCore(adminToken: AccessToken): TestForApi<TalerCoreBankHttpClient> {
+ return {
+ test_abortCashoutById: {
+ success: undefined,
+ "already-confirmed": undefined,
+ "cashout-not-supported": undefined,
+ "not-found": undefined,
+ },
+ test_createCashout: {
+ "account-not-found": undefined,
+ "incorrect-exchange-rate": undefined,
+ "no-contact-info": undefined,
+ "no-enough-balance": undefined,
+ "cashout-not-supported": undefined,
+ success: undefined,
+ },
+ test_confirmCashoutById: {
+ "cashout-address-changed": undefined,
+ "cashout-not-supported": undefined,
+ "not-found": undefined,
+ "wrong-tan-or-credential": undefined,
+ success: undefined,
+ },
+ test_getAccountCashouts: {
+ "cashout-not-supported": undefined,
+ "account-not-found": undefined,
+ success: undefined,
+ },
+ test_getCashoutById: {
+ "cashout-not-supported": undefined,
+ success: undefined,
+ "not-found": undefined,
+ },
+ test_getCashoutRate: {
+ "cashout-not-supported": undefined,
+ "not-supported": undefined,
+ "wrong-calculation": undefined,
+ success: undefined,
+ },
+ test_getGlobalCashouts: {
+ "cashout-not-supported": undefined,
+ success: undefined,
+ },
+ test_abortWithdrawalById: {
+ "invalid-id": async (api) => {
+ await failOrThrow("invalid-id", () =>
+ api.abortWithdrawalById("invalid")
+ )
+ },
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () =>
+ api.abortWithdrawalById("11111111-1111-1111-1111-111111111111")
+ )
+ },
+ "previously-confirmed": async (api) => {
+ const { username: exchangeUser, token: exchangeToken } = await createRandomTestUser(api, adminToken, { is_taler_exchange: true })
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const exchangeInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: exchangeUser, token: exchangeToken })
+ )
+
+ const { withdrawal_id } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ await succeedOrThrow(() =>
+ api.getIntegrationAPI().completeWithdrawalOperationById(withdrawal_id, {
+ reserve_pub: encodeCrock(getRandomBytes(32)),
+ selected_exchange: exchangeInfo.payto_uri,
+ })
+ )
+ await succeedOrThrow(() =>
+ api.confirmWithdrawalById(withdrawal_id)
+ )
+ await failOrThrow("previously-confirmed", () =>
+ api.abortWithdrawalById(withdrawal_id)
+ )
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const { withdrawal_id: firstWithdrawal } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ await succeedOrThrow(() =>
+ api.abortWithdrawalById(firstWithdrawal)
+ )
+ },
+ },
+ test_confirmWithdrawalById: {
+ "insufficient-funds": async (api) => {
+
+ },
+ "invalid-id": async (api) => {
+ await failOrThrow("invalid-id", () =>
+ api.confirmWithdrawalById("invalid")
+ )
+ },
+ "no-exchange-or-reserve-selected": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const { withdrawal_id } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ await failOrThrow("no-exchange-or-reserve-selected", () =>
+ api.confirmWithdrawalById(withdrawal_id)
+ )
+ },
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () =>
+ api.confirmWithdrawalById("11111111-1111-1111-1111-111111111111")
+ )
+ },
+ "previously-aborted": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const { withdrawal_id } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ await succeedOrThrow(() =>
+ api.abortWithdrawalById(withdrawal_id)
+ )
+ await failOrThrow("previously-aborted", () =>
+ api.confirmWithdrawalById(withdrawal_id)
+ )
+ },
+ success: async (api) => {
+ const { username: exchangeUser, token: exchangeToken } = await createRandomTestUser(api, adminToken, { is_taler_exchange: true })
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const exchangeInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: exchangeUser, token: exchangeToken })
+ )
+
+ const { withdrawal_id } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ await succeedOrThrow(() =>
+ api.getIntegrationAPI().completeWithdrawalOperationById(withdrawal_id, {
+ reserve_pub: encodeCrock(getRandomBytes(32)),
+ selected_exchange: exchangeInfo.payto_uri,
+ })
+ )
+
+ await succeedOrThrow(() =>
+ api.confirmWithdrawalById(withdrawal_id)
+ )
+
+ },
+ },
+ test_createAccount: {
+ "insufficient-funds": undefined,
+ "payto-already-exists": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const anotherUsername = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+ await failOrThrow("payto-already-exists", () =>
+ api.createAccount(adminToken, {
+ name: anotherUsername,
+ username: anotherUsername,
+ password: "123",
+ internal_payto_uri: userInfo.payto_uri,
+ })
+ );
+
+ },
+ "username-reserved": async (api) => {
+ await failOrThrow("username-reserved", () =>
+ api.createAccount(adminToken, {
+ name: "admin",
+ username: "admin", password: "123"
+ })
+ )
+ },
+ "username-already-exists": async (api) => {
+ const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+ await succeedOrThrow(() =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123"
+ })
+ )
+
+ await failOrThrow("username-already-exists", () =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123"
+ })
+ );
+ },
+ "invalid-phone-or-email": async (api) => {
+ const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+ await failOrThrow("invalid-input", () =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123",
+ challenge_contact_data: {
+ email: "invalid email",
+ phone: "invalid phone",
+ }
+ })
+ )
+ },
+ success: async (api) => {
+ const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+
+ await succeedOrThrow(() =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123"
+ })
+ )
+ },
+ unauthorized: async (api) => {
+ const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+
+ await succeedOrThrow(() =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123"
+ })
+ )
+
+ const { access_token } = await succeedOrThrow(() =>
+ api.getAuthenticationAPI(username).createAccessToken("123", {
+ scope: "readwrite"
+ })
+ )
+
+ const anotherUser = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+ await failOrThrow("unauthorized", () =>
+ api.createAccount(access_token, {
+ name: anotherUser,
+ username: anotherUser, password: "123"
+ })
+ )
+
+ },
+
+ },
+ test_createTransaction: {
+ "creditor-not-found": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const notFoundAccount = buildPayto("iban", "DE1231231231", undefined)
+ notFoundAccount.params["message"] = "not-found"
+ await failOrThrow("creditor-not-found", () =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(notFoundAccount),
+ amount: userInfo.balance.amount
+ })
+ )
+ },
+ "creditor-same": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const account = parsePaytoUri(userInfo.payto_uri)!
+ account.params["message"] = "myaccount"
+
+ await failOrThrow("creditor-same", () =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(account),
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ "insufficient-funds": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ await failOrThrow("insufficient-funds", () =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ amount: Amounts.stringify(Amounts.mult(userInfo.balance.amount, 20).amount)
+ })
+ )
+ },
+ "not-found": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ await succeedOrThrow(() =>
+ api.createTransaction({ username: "notfound", token }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ amount: userInfo.balance.amount
+ })
+ )
+ },
+ "invalid-input": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ //missing amount
+ await failOrThrow("invalid-input", () =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ // amount: userInfo.balance.amount
+ })
+ )
+ //missing subject
+ await failOrThrow("invalid-input", () =>
+ api.createTransaction({ username, token }, {
+ payto_uri: otherInfo.payto_uri,
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ await succeedOrThrow(() =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ await failOrThrow("unauthorized", () =>
+ api.createTransaction({ username, token: "wrongtoken" as AccessToken }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ amount: userInfo.balance.amount
+ })
+ )
+ },
+ },
+ test_createWithdrawal: {
+ "account-not-found": async (api) => {
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: "admin", token: adminToken })
+ )
+ await succeedOrThrow(() =>
+ api.createWithdrawal({ username: "notfound", token: adminToken }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ "insufficient-funds": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const balance = Amounts.parseOrThrow(userInfo.balance.amount)
+ const moreThanBalance = Amounts.stringify(Amounts.mult(balance, 5).amount)
+ await failOrThrow("insufficient-funds", () =>
+ api.createWithdrawal({ username, token }, {
+ amount: moreThanBalance
+ })
+ )
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ await failOrThrow("unauthorized", () =>
+ api.createWithdrawal({ username, token: "wrongtoken" as AccessToken }, {
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ },
+ test_deleteAccount: {
+ "balance-not-zero": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await failOrThrow("balance-not-zero", () =>
+ api.deleteAccount({ username, token: adminToken })
+ )
+
+ },
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () =>
+ api.deleteAccount({ username: "not-found", token: adminToken })
+ )
+ },
+ "username-reserved": async (api) => {
+ await failOrThrow("username-reserved", () =>
+ api.deleteAccount({ username: "admin", token: adminToken })
+ )
+ await failOrThrow("username-reserved", () =>
+ api.deleteAccount({ username: "bank", token: adminToken })
+ )
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+
+ const adminInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: "admin", token: adminToken })
+ )
+
+ const adminAccount = parsePaytoUri(adminInfo.payto_uri)!
+ adminAccount.params["message"] = "all my money"
+ const withSubject = stringifyPaytoUri(adminAccount)
+
+ await succeedOrThrow(() =>
+ api.createTransaction({ username, token }, {
+ payto_uri: withSubject,
+ amount: userInfo.balance.amount
+ })
+ )
+
+ },
+ unauthorized: async (api) => {
+ const username = "harness-" + encodeCrock(getRandomBytes(10)).toLowerCase();
+
+ await succeedOrThrow(() =>
+ api.createAccount(adminToken, {
+ name: username,
+ username, password: "123"
+ })
+ )
+
+ const { token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("unauthorized", () =>
+ api.deleteAccount({ username: username, token })
+ )
+
+ },
+ },
+ test_getAccount: {
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () =>
+ api.getAccount({ username: "not-found", token: adminToken })
+ )
+
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("unauthorized", () =>
+ api.getAccount({ username, token: "wrongtoken" as AccessToken })
+ )
+ },
+ },
+ test_getAccounts: {
+ success: async (api) => {
+ await succeedOrThrow(() =>
+ api.getAccounts(adminToken)
+ )
+ await succeedOrThrow(() =>
+ api.getAccounts(adminToken, {
+ account: "admin"
+ })
+ )
+ await succeedOrThrow(() =>
+ api.getAccounts(adminToken, undefined, {
+ order: "dec",
+ limit: 10,
+ offset: "1"
+ })
+ )
+ },
+ unauthorized: async (api) => {
+ await failOrThrow("unauthorized", () =>
+ api.getAccounts("ASDASD" as AccessToken)
+ )
+ },
+ },
+ test_getConfig: {
+ success: async (api) => {
+ const config = await succeedOrThrow(() => api.getConfig())
+
+ if (!api.isCompatible(config.version)) {
+ throw Error(`not compatible with server ${config.version}`)
+ }
+
+ },
+ },
+ test_getMonitor: {
+ "unauthorized": async (api) => {
+ await failOrThrow("unauthorized", () => (
+ api.getMonitor("wrongtoken" as AccessToken)
+ ))
+
+ },
+ "invalid-input": async (api) => {
+
+ await failOrThrow("invalid-input", () => (
+ api.getMonitor(adminToken, {
+ timeframe: TalerCorebankApi.MonitorTimeframeParam.day,
+ which: 100
+ })
+ ))
+
+ },
+ "monitor-not-supported": undefined,
+ success: async (api) => {
+
+ await succeedOrThrow(() => (
+ api.getMonitor(adminToken)
+ ))
+
+ await succeedOrThrow(() => (
+ api.getMonitor(adminToken, {
+ timeframe: TalerCorebankApi.MonitorTimeframeParam.day,
+ which: (new Date()).getDate() - 1
+ })
+ ))
+
+ },
+ },
+ test_getPublicAccounts: {
+ success: async (api) => {
+ await succeedOrThrow(() => (
+ api.getPublicAccounts()
+ ))
+
+ await succeedOrThrow(() => (
+ api.getPublicAccounts({
+ order: "asc"
+ })
+ ))
+ await succeedOrThrow(() => (
+ api.getPublicAccounts({
+ order: "dec"
+ })
+ ))
+ await succeedOrThrow(() => (
+ api.getPublicAccounts({
+ order: "dec", limit: 10, offset: String(1)
+ })
+ ))
+ },
+ },
+ test_getTransactionById: {
+ "not-found": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("not-found", () =>
+ api.getTransactionById({ username, token }, 123123123)
+ )
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const { username: otherUser, token: otherToken } = await createRandomTestUser(api, adminToken)
+
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const otherInfo = await succeedOrThrow(() =>
+ api.getAccount({ username: otherUser, token: otherToken })
+ )
+ const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
+ otherAccount.params["message"] = "all"
+
+ await succeedOrThrow(() =>
+ api.createTransaction({ username, token }, {
+ payto_uri: stringifyPaytoUri(otherAccount),
+ amount: userInfo.balance.amount
+ })
+ )
+
+ const txs = await succeedOrThrow(() => api.getTransactions({ username, token }, {
+ limit: 5,
+ order: "asc"
+ }))
+ const rowId = txs.transactions[0].row_id
+
+ await succeedOrThrow(() =>
+ api.getTransactionById({ username, token }, rowId)
+ )
+
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("unauthorized", () =>
+ api.getTransactionById({ username, token: "wrongtoken" as AccessToken }, 123123123)
+ )
+ },
+ },
+ test_getTransactions: {
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () => api.getTransactions({
+ username: "not-found",
+ token: adminToken,
+ }))
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ // await succeedOrThrow(() => api.getTransactions(creds))
+ const txs = await succeedOrThrow(() => api.getTransactions({ username, token }, {
+ limit: 5,
+ order: "asc"
+ }))
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await failOrThrow("unauthorized", () => api.getTransactions({
+ username: username,
+ token: "wrongtoken" as AccessToken,
+ }))
+
+ },
+ },
+ test_getWithdrawalById: {
+ "invalid-id": async (api) => {
+
+ await failOrThrow("invalid-id", () =>
+ api.getWithdrawalById("invalid")
+ )
+
+ },
+ "not-found": async (api) => {
+ await failOrThrow("not-found", () =>
+ api.getWithdrawalById("11111111-1111-1111-1111-111111111111")
+ )
+
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ const userInfo = await succeedOrThrow(() =>
+ api.getAccount({ username, token })
+ )
+ const { withdrawal_id } = await succeedOrThrow(() =>
+ api.createWithdrawal({ username, token }, {
+ amount: userInfo.balance.amount
+ })
+ )
+ await succeedOrThrow(() =>
+ api.getWithdrawalById(withdrawal_id)
+ )
+ },
+ },
+ test_updateAccount: {
+ "cant-change-legal-name-or-admin": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await failOrThrow("cant-change-legal-name-or-admin", () =>
+ api.updateAccount({ username, token }, {
+ name: "something else",
+ })
+ )
+
+ },
+ "not-found": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("not-found", () =>
+ api.updateAccount({ username: "notfound", token }, {
+ challenge_contact_data: {
+ email: "asd@Aasd.com"
+ }
+ })
+ )
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await succeedOrThrow(() =>
+ api.updateAccount({ username, token }, {
+ challenge_contact_data: {
+ email: "asd@Aasd.com"
+ }
+ })
+ )
+
+ },
+ unauthorized: async (api) => {
+
+ await failOrThrow("unauthorized", () =>
+ api.updateAccount({ username: "notfound", token: "wrongtoken" as AccessToken }, {
+ challenge_contact_data: {
+ email: "asd@Aasd.com"
+ }
+ })
+ )
+ },
+ },
+ test_updatePassword: {
+ "not-found": async (api) => {
+
+ await failOrThrow("not-found", () =>
+ api.updatePassword({ username: "notfound", token: adminToken }, {
+ old_password: "123",
+ new_password: "234"
+ })
+ )
+
+
+ },
+ "old-password-invalid-or-not-allowed": async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await failOrThrow("old-password-invalid-or-not-allowed", () =>
+ api.updatePassword({ username, token }, {
+ old_password: "1233",
+ new_password: "234"
+ })
+ )
+
+ },
+ success: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+
+ await succeedOrThrow(() =>
+ api.updatePassword({ username, token }, {
+ old_password: "123",
+ new_password: "234"
+ })
+ )
+
+
+ },
+ unauthorized: async (api) => {
+ const { username, token } = await createRandomTestUser(api, adminToken)
+ await failOrThrow("unauthorized", () =>
+ api.updatePassword({ username: "admin", token }, {
+ old_password: "123",
+ new_password: "234"
+ })
+ )
+
+
+ },
+ },
}
-
- async testTransactions(adminPassword: string) {
- const { access_token: adminToken } = await succeedOrThrow(() =>
- this.api.getAuthenticationAPI("admin").createAccessToken(adminPassword, {
- scope: "readwrite"
- })
- )
- // get transactions
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
- // await succeedOrThrow(() => this.api.getTransactions(creds))
- const txs = await succeedOrThrow(() => this.api.getTransactions({ username, token }, {
- limit: 5,
- order: "asc"
- }))
- // await failOrThrow("not-found",() => this.api.getTransactions({
- // username:"not-found",
- // token: creds.token,
- // }))
- await failOrThrow("unauthorized", () => this.api.getTransactions({
- username: username,
- token: "wrongtoken" as AccessToken,
- }))
- }
-
- /**
- * getTxby id
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
- const { username: otherUser, token: otherToken } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
- const otherInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username: otherUser, token: otherToken })
- )
- const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
- otherAccount.params["message"] = "all"
-
- await succeedOrThrow(() =>
- this.api.createTransaction({ username, token }, {
- payto_uri: stringifyPaytoUri(otherAccount),
- amount: userInfo.balance.amount
- })
- )
-
- const txs = await succeedOrThrow(() => this.api.getTransactions({ username, token }, {
- limit: 5,
- order: "asc"
- }))
- const rowId = txs.transactions[0].row_id
-
- await succeedOrThrow(() =>
- this.api.getTransactionById({ username, token }, rowId)
- )
-
- await failOrThrow("not-found", () =>
- this.api.getTransactionById({ username, token }, 123123123)
- )
-
- await failOrThrow("unauthorized", () =>
- this.api.getTransactionById({ username, token: "wrongtoken" as AccessToken }, 123123123)
- )
- }
-
- /**
- * create transactions
- */
- {
- const { username, token } = await createRandomTestUser(this.api, adminToken)
- const { username: otherUser, token: otherToken } = await createRandomTestUser(this.api, adminToken)
-
- const userInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username, token })
- )
- const otherInfo = await succeedOrThrow(() =>
- this.api.getAccount({ username: otherUser, token: otherToken })
- )
- const otherAccount = parsePaytoUri(otherInfo.payto_uri)!
- otherAccount.params["message"] = "all"
-
- await succeedOrThrow(() =>
- this.api.createTransaction({ username, token }, {
- payto_uri: stringifyPaytoUri(otherAccount),
- amount: userInfo.balance.amount
- })
- )
- //missing amount
- await failOrThrow("invalid-input", () =>
- this.api.createTransaction({ username, token }, {
- payto_uri: stringifyPaytoUri(otherAccount),
- // amount: userInfo.balance.amount
- })
- )
- //missing subject
- await failOrThrow("invalid-input", () =>
- this.api.createTransaction({ username, token }, {
- payto_uri: otherInfo.payto_uri,
- amount: userInfo.balance.amount
- })
- )
- await failOrThrow("unauthorized", () =>
- this.api.createTransaction({ username, token: "wrongtoken" as AccessToken }, {
- payto_uri: otherInfo.payto_uri,
- amount: userInfo.balance.amount
- })
- )
-
- const notFoundAccount = buildPayto("iban", "DE1231231231", undefined)
- notFoundAccount.params["message"] = "not-found"
- await failOrThrow("account-not-found", () =>
- this.api.createTransaction({ username, token }, {
- payto_uri: stringifyPaytoUri(notFoundAccount),
- amount: userInfo.balance.amount
- })
- )
- }
- }
-
-
}
export async function createRandomTestUser(api: TalerCoreBankHttpClient, adminToken: AccessToken, options: Partial<TalerCorebankApi.RegisterAccountRequest> = {}) {
diff --git a/packages/taler-harness/src/index.ts b/packages/taler-harness/src/index.ts
index 717aee57d..af4e5c788 100644
--- a/packages/taler-harness/src/index.ts
+++ b/packages/taler-harness/src/index.ts
@@ -51,7 +51,7 @@ import {
} from "@gnu-taler/taler-wallet-core";
import { deepStrictEqual } from "assert";
import fs from "fs";
-import { BankCoreSmokeTest } from "http-client/bank-core.js";
+import { createRandomTestUser, createTestForBankCore } from "http-client/bank-core.js";
import os from "os";
import path from "path";
import { runBench1 } from "./bench1.js";
@@ -667,68 +667,69 @@ deploymentCli
const httpLib = createPlatformHttpLib();
const api = new TalerCoreBankHttpClient(args.testBankAPI.corebankApiBaseUrl, httpLib);
- const tester = new BankCoreSmokeTest(api)
+ process.stdout.write("config: ");
+ const config = await api.getConfig()
+ if (!api.isCompatible(config.body.version)) {
+ console.log("fail")
+ return;
+ } else {
+ console.log("ok")
+ }
+
+ if (!args.testBankAPI.adminPwd) {
+ console.log("no admin password, exit")
+ return;
+ }
+
+ const resp = await api.getAuthenticationAPI("admin").createAccessToken(args.testBankAPI.adminPwd, {
+ scope: "readwrite"
+ })
+
+ if (resp.type === "fail") {
+ console.log("wrong admin password")
+ return;
+ }
+ const tester = createTestForBankCore(resp.body.access_token)
+
if (args.testBankAPI.showCurl) {
setPrintHttpRequestAsCurl(true)
}
- try {
- process.stdout.write("config: ");
- const config = await tester.testConfig()
- console.log("ok")
- const admin = args.testBankAPI.adminPwd
- process.stdout.write("account management: ");
- const withAdmin = !!admin && admin !== "-"
- if (withAdmin) {
- await tester.testAccountManagement(admin)
- console.log("ok")
- } else {
- console.log("skipped")
- }
-
- process.stdout.write("transactions: ");
- if (withAdmin) {
- await tester.testTransactions(admin)
- console.log("ok")
- } else {
- console.log("skipped")
- }
- process.stdout.write("withdrawals: ");
- if (withAdmin) {
- await tester.testWithdrawals(admin)
- console.log("ok")
- } else {
- console.log("skipped")
+ const apiState = await Promise.all(Object.entries(tester).flatMap(([testName, casesMap]) => {
+ return Object.entries(casesMap).map(([caseName, caseFunc]) => {
+ if (!caseFunc) {
+ return { testName, caseName, result: "skiped" as const }
+ }
+ return caseFunc(api)
+ .then(r => ({ testName, caseName, result: "ok" as const }))
+ .catch(error => ({ testName, caseName, result: "fail" as const, error }))
+ })
+ }))
+
+ const total = apiState.reduce((prev, testResult) => {
+ if (testResult.result === "ok") {
+ prev.ok += 1
}
-
- process.stdout.write("monitor: ");
- if (withAdmin && config.have_cashout) {
- await tester.testMonitor(admin)
- console.log("ok")
- } else {
- console.log("skipped")
+ if (testResult.result === "skiped") {
+ prev.skiped += 1
}
-
- process.stdout.write("cashout: ");
- if (withAdmin && config.have_cashout) {
- await tester.testCashouts(admin)
- console.log("ok")
- } else {
- console.log("skipped")
+ if (testResult.result === "fail") {
+ prev.fail += 1
}
-
- } catch (e: any) {
- console.log("")
- if (e instanceof TalerError) {
- console.error("FAILED", JSON.stringify(e.errorDetail, undefined, 2))
- console.error(e.stack)
- } else if (e instanceof Error) {
- console.error(`FAILED: ${e.message}`)
- console.error(e.stack)
- } else {
- console.error(`FAILED: ${e}`)
+ return prev
+ }, { "ok": 0, "skiped": 0, "fail": 0 })
+
+ console.log("successful tests:", total.ok)
+ console.log("uncompleted tests:", total.skiped)
+ apiState.forEach((testResult) => {
+ if (testResult.result === "skiped") {
+ console.log(" ", testResult.testName, testResult.caseName)
}
- }
+ })
+ console.log("failed tests:", total.fail)
+ apiState.filter(t => t.result === "fail").forEach((testResult, i) => {
+ console.log(i, ")", testResult)
+ })
});