aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-harness/src/http-client/bank-core.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-harness/src/http-client/bank-core.ts')
-rw-r--r--packages/taler-harness/src/http-client/bank-core.ts547
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 }
+}