diff options
author | Sebastian <sebasjm@gmail.com> | 2023-11-03 19:00:47 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-11-03 19:00:47 -0300 |
commit | 11b99b9256d13e16aff460db6f014390ded4670b (patch) | |
tree | 998290c45c98158dfdc454b9a6978091c40b54b2 | |
parent | 08898c7aa32b5a4dbc40c2fecd82a5a652126705 (diff) | |
download | wallet-core-11b99b9256d13e16aff460db6f014390ded4670b.tar.xz |
test for every error code in the spec
-rw-r--r-- | packages/taler-harness/src/http-client/bank-core.ts | 1375 | ||||
-rw-r--r-- | packages/taler-harness/src/index.ts | 111 |
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) + }) }); |