diff options
Diffstat (limited to 'packages/taler-harness/src/http-client/bank-core.ts')
-rw-r--r-- | packages/taler-harness/src/http-client/bank-core.ts | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/packages/taler-harness/src/http-client/bank-core.ts b/packages/taler-harness/src/http-client/bank-core.ts new file mode 100644 index 000000000..c67ff1bf8 --- /dev/null +++ b/packages/taler-harness/src/http-client/bank-core.ts @@ -0,0 +1,547 @@ +import { AccessToken, Amounts, TalerCoreBankHttpClient, TalerCorebankApi, 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 = "user-" + 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 = "user-" + 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) + ) + await failOrThrow("previously-aborted", () => + this.api.confirmWithdrawalById(secondWithdrawal) + ) + } +} + +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 + }) + ) + } +} + + +} + +export async function createRandomTestUser(api: TalerCoreBankHttpClient, adminToken: AccessToken, options: Partial<TalerCorebankApi.RegisterAccountRequest> = {}) { + const username = "user-" + encodeCrock(getRandomBytes(10)).toLowerCase(); + await succeedOrThrow(() => + api.createAccount(adminToken, { + name: username, + username, password: "123", + ...options + }) + ) + const { access_token } = await succeedOrThrow(() => + api.getAuthenticationAPI(username).createAccessToken("123", { + scope: "readwrite" + }) + ) + return { username, token: access_token } +} |