mirror of
https://git.dirksys.ovh/dirk/bankserver.git
synced 2025-12-20 02:59:20 +01:00
add tests and fix account and user list endpoints
This commit is contained in:
parent
456c507c10
commit
6e04bb561c
@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use axum::{Router, extract::Path, http::StatusCode, routing::get};
|
||||
use serde::Serialize;
|
||||
use tracing::instrument;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
@ -29,7 +30,10 @@ pub struct ListAccounts {
|
||||
accounts: Vec<AccountInfo>,
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn account_info(EState(state): State, _: Auth, Path(id): Path<Uuid>) {}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn account_transactions(
|
||||
EState(state): State,
|
||||
auth: Auth,
|
||||
@ -53,6 +57,8 @@ pub async fn account_transactions(
|
||||
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn list_accounts(
|
||||
EState(state): State,
|
||||
_: Auth,
|
||||
|
||||
@ -404,7 +404,7 @@ impl RequestPagination {
|
||||
}
|
||||
#[inline]
|
||||
pub const fn offset(&self) -> i64 {
|
||||
self.limit as i64
|
||||
self.offset as i64
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -333,7 +333,7 @@ impl MakePayment {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TransactionQuery {
|
||||
#[serde(flatten)]
|
||||
pub pagination: RequestPagination,
|
||||
|
||||
@ -2,6 +2,7 @@ use std::sync::Arc;
|
||||
|
||||
use axum::{Router, extract::Path, http::StatusCode, routing::get};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tracing::instrument;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
@ -69,12 +70,16 @@ pub async fn user_info(
|
||||
}
|
||||
Err(ApiError::NOT_FOUND.into())
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn user_balance(EState(state): State, auth: Auth) -> Result<Json<UserBalance>, Error> {
|
||||
let conn = state.conn().await?;
|
||||
let info = Account::list_for_user(&conn, auth.user_id()).await?;
|
||||
let balance = info.iter().map(|info| info.balance).sum();
|
||||
Ok(Json(UserBalance { balance }))
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn list_users(
|
||||
EState(state): State,
|
||||
_: Auth,
|
||||
@ -84,6 +89,8 @@ pub async fn list_users(
|
||||
let users = User::list(&conn, pagination).await?;
|
||||
Ok(Json(users))
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn me_transaction_history(
|
||||
EState(state): State,
|
||||
auth: Auth,
|
||||
@ -97,6 +104,7 @@ pub async fn me_transaction_history(
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
#[instrument(skip(state))]
|
||||
pub async fn user_accounts(EState(state): State, auth: Auth) -> Result<Json<UserAccounts>, Error> {
|
||||
let user = auth.user_id();
|
||||
let conn = state.conn().await?;
|
||||
|
||||
@ -96,7 +96,7 @@ impl Account {
|
||||
.prepare_cached("select id,\"user\",name from accounts limit $1 offset $2")
|
||||
.await?;
|
||||
let stmt_count = client
|
||||
.prepare_cached("select count(*) from accounts limit $1 offset $2")
|
||||
.prepare_cached("select count(*) from accounts")
|
||||
.await?;
|
||||
let users = client
|
||||
.query(&stmt, &[&pagination.limit(), &pagination.offset()])
|
||||
|
||||
@ -5,6 +5,7 @@ use garde::Validate;
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio_postgres::{ToStatement, types::ToSql};
|
||||
use tracing::{info, instrument};
|
||||
use uuid::Uuid;
|
||||
|
||||
mod account;
|
||||
@ -50,7 +51,8 @@ pub struct IdWithName {
|
||||
pub name: Name,
|
||||
}
|
||||
|
||||
async fn count<T: ?Sized + ToStatement + Sync + Send>(
|
||||
#[instrument(skip(client))]
|
||||
async fn count<T: ?Sized + ToStatement + Sync + Send + std::fmt::Debug>(
|
||||
client: &impl GenericClient,
|
||||
statement: &T,
|
||||
params: &[&(dyn ToSql + Sync)],
|
||||
|
||||
@ -8,7 +8,7 @@ use crate::api::{Pagination, RequestPagination};
|
||||
|
||||
use super::{User, account::ReducedAccountInfo};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[cfg_attr(feature = "schemas", derive(schemars::JsonSchema))]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum Direction {
|
||||
|
||||
@ -100,21 +100,14 @@ impl User {
|
||||
let stmt = client
|
||||
.prepare_cached("select id,name from users limit $1 offset $2")
|
||||
.await?;
|
||||
let stmt_count = client
|
||||
.prepare_cached("select count(*) from users limit $1 offset $2")
|
||||
.await?;
|
||||
let stmt_count = client.prepare_cached("select count(*) from users").await?;
|
||||
let users = client
|
||||
.query(&stmt, &[&pagination.limit(), &pagination.offset()])
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(User::from)
|
||||
.collect();
|
||||
let count = count(
|
||||
client,
|
||||
&stmt_count,
|
||||
&[&pagination.limit(), &pagination.offset()],
|
||||
)
|
||||
.await?;
|
||||
let count = count(client, &stmt_count, &[]).await?;
|
||||
Ok(Pagination::new(users, count, pagination))
|
||||
}
|
||||
|
||||
|
||||
25
tests/integration/account-list.hurl
Normal file
25
tests/integration/account-list.hurl
Normal file
@ -0,0 +1,25 @@
|
||||
POST {{host}}/api/login
|
||||
{
|
||||
"name": "user1",
|
||||
"password": "this-is-a-password"
|
||||
}
|
||||
HTTP 200
|
||||
|
||||
[Captures]
|
||||
token: jsonpath "$.token"
|
||||
|
||||
GET {{host}}/api/accounts?limit=50
|
||||
Authorization: Bearer {{token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.pagination.total" == 7
|
||||
jsonpath "$.pagination.limit" == 50
|
||||
jsonpath "$.pagination.offset" == 0
|
||||
jsonpath "$.result" isCollection
|
||||
jsonpath "$.result[0].name" == "user1"
|
||||
jsonpath "$.result[1].name" == "user2"
|
||||
jsonpath "$.result[2].name" == "user3"
|
||||
jsonpath "$.result[3].name" == "user4"
|
||||
jsonpath "$.result[4].name" == "user5"
|
||||
jsonpath "$.result[5].name" == "user6"
|
||||
jsonpath "$.result[6].name" == "test-user"
|
||||
@ -18,3 +18,10 @@ POST {{host}}/api/login
|
||||
"password": "this-is-a-test"
|
||||
}
|
||||
HTTP 200
|
||||
|
||||
[Captures]
|
||||
token: jsonpath "$.token"
|
||||
|
||||
GET {{host}}/api/users/@me
|
||||
Authorization: Bearer {{token}}
|
||||
HTTP 200
|
||||
|
||||
25
tests/integration/user-list.hurl
Normal file
25
tests/integration/user-list.hurl
Normal file
@ -0,0 +1,25 @@
|
||||
POST {{host}}/api/login
|
||||
{
|
||||
"name": "user1",
|
||||
"password": "this-is-a-password"
|
||||
}
|
||||
HTTP 200
|
||||
|
||||
[Captures]
|
||||
token: jsonpath "$.token"
|
||||
|
||||
GET {{host}}/api/users?limit=50
|
||||
Authorization: Bearer {{token}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
jsonpath "$.pagination.total" == 7
|
||||
jsonpath "$.pagination.limit" == 50
|
||||
jsonpath "$.pagination.offset" == 0
|
||||
jsonpath "$.result" isCollection
|
||||
jsonpath "$.result[0].name" == "user1"
|
||||
jsonpath "$.result[1].name" == "user2"
|
||||
jsonpath "$.result[2].name" == "user3"
|
||||
jsonpath "$.result[3].name" == "user4"
|
||||
jsonpath "$.result[4].name" == "user5"
|
||||
jsonpath "$.result[5].name" == "user6"
|
||||
jsonpath "$.result[6].name" == "test-user"
|
||||
Loading…
x
Reference in New Issue
Block a user