temp
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,4 +4,5 @@
|
||||
.DS_Store
|
||||
.env
|
||||
conf.toml
|
||||
.fleet\
|
||||
config.toml
|
||||
.fleet\
|
||||
|
||||
62
src/api/account.rs
Normal file
62
src/api/account.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use crate::middleware::auth::Claims;
|
||||
use crate::model::db::account::{
|
||||
ActiveModel as AccountActiveModel, Column as AccountColumn, Model as AccountModel,
|
||||
};
|
||||
use crate::model::db::prelude::Account as AccountPrelude;
|
||||
use crate::model::http_body::account::{AccountReq, AccountResp};
|
||||
use crate::model::http_body::common::SimpleResponse;
|
||||
use crate::AppState;
|
||||
use axum::extract::{Path, State};
|
||||
use axum::http::StatusCode;
|
||||
use axum::routing::{get, post};
|
||||
use axum::{Json, Router};
|
||||
use sea_orm::sqlx::types::chrono::Local;
|
||||
use sea_orm::{ActiveModelTrait, DbErr, Iden, Set};
|
||||
|
||||
pub fn get_nest_handlers() -> Router<crate::AppState> {
|
||||
Router::new()
|
||||
.route("/{id}/update", post(update_account_handler))
|
||||
.route("/{id}", get(get_account_by_id_handler))
|
||||
.route(
|
||||
"/",
|
||||
post(create_account_handler).get(get_all_accounts_handler),
|
||||
)
|
||||
}
|
||||
|
||||
async fn update_account_handler(
|
||||
Path(id): Path<i64>,
|
||||
state: State<AppState>,
|
||||
claims: Claims,
|
||||
Json(payload): Json<AccountReq>,
|
||||
) -> Result<Json<SimpleResponse>, (StatusCode, String)> {
|
||||
let uid: i64 = claims.uid.clone();
|
||||
let mut active_model: AccountActiveModel = AccountPrelude::find_by_id(id)
|
||||
.filter(AccountColumn::Uid.eq(uid))
|
||||
.filter(AccountColumn::IsDeleted.eq(false))
|
||||
.one(&state.conn)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
match payload.name {
|
||||
Some(n) => {
|
||||
active_model.name = Set(n);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
active_model.updated_at = Set(Local::now().naive_utc());
|
||||
|
||||
active_model.update(&state.conn).await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
let resp = SimpleResponse{
|
||||
code: 0,
|
||||
message: "".to_string()
|
||||
};
|
||||
Ok(Json(resp))
|
||||
}
|
||||
|
||||
async fn get_account_by_id_handler() {}
|
||||
|
||||
async fn create_account_handler() {}
|
||||
|
||||
async fn get_all_accounts_handler() {}
|
||||
198
src/api/book_test.rs
Normal file
198
src/api/book_test.rs
Normal file
@@ -0,0 +1,198 @@
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
// use axum::{
|
||||
// http::{Request, StatusCode},
|
||||
// Router,
|
||||
// routing::{get, put},
|
||||
// body::Body,
|
||||
// };
|
||||
// use sea_orm::{
|
||||
// MockDatabase, MockExecResult, DatabaseConnection, DatabaseTransaction,
|
||||
// entity::prelude::*,
|
||||
// QueryFilter, Condition, DbErr, EntityTrait,
|
||||
// };
|
||||
// use serde_json::{json, Value};
|
||||
// use tower::ServiceExt;
|
||||
// use std::sync::Arc;
|
||||
//
|
||||
// // 模拟 Book 实体
|
||||
// #[derive(Clone, Debug, PartialEq, DeriveEntityModel)]
|
||||
// #[sea_orm(table_name = "books")]
|
||||
// pub struct Model {
|
||||
// #[sea_orm(primary_key)]
|
||||
// pub id: i32,
|
||||
// pub title: String,
|
||||
// pub author: String,
|
||||
// }
|
||||
//
|
||||
// #[derive(Copy, Clone, Debug, EnumIter)]
|
||||
// pub enum Relation {}
|
||||
//
|
||||
// impl Related<super::book::Entity> for Entity {
|
||||
// fn to() -> RelationDef {
|
||||
// panic!("No relations defined")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 创建测试用的 Router
|
||||
// async fn setup_router(db: DatabaseConnection) -> Router {
|
||||
// Router::new()
|
||||
// .route("/books/:id", get(get_book_by_id).put(update_book_by_id))
|
||||
// .route("/books", get(get_all_book))
|
||||
// .with_state(Arc::new(db))
|
||||
// }
|
||||
//
|
||||
// // 测试 get_book_by_id
|
||||
// #[tokio::test]
|
||||
// async fn test_get_book_by_id() {
|
||||
// // 设置模拟数据库
|
||||
// let db = MockDatabase::new(DatabaseBackend::Postgres)
|
||||
// .append_query_results(vec![vec![Model {
|
||||
// id: 1,
|
||||
// title: "Test Book".to_string(),
|
||||
// author: "Test Author".to_string(),
|
||||
// }]])
|
||||
// .into_connection();
|
||||
//
|
||||
// let app = setup_router(db).await;
|
||||
//
|
||||
// // 构造请求
|
||||
// let request = Request::builder()
|
||||
// .uri("/books/1")
|
||||
// .method("GET")
|
||||
// .body(Body::empty())
|
||||
// .unwrap();
|
||||
//
|
||||
// // 发送请求
|
||||
// let response = app.oneshot(request).await.unwrap();
|
||||
// assert_eq!(response.status(), StatusCode::OK);
|
||||
//
|
||||
// // 解析响应
|
||||
// let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
|
||||
// let body: Value = serde_json::from_slice(&body).unwrap();
|
||||
// assert_eq!(
|
||||
// body,
|
||||
// json!({
|
||||
// "id": 1,
|
||||
// "title": "Test Book",
|
||||
// "author": "Test Author"
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// // 测试 get_book_by_id 未找到
|
||||
// #[tokio::test]
|
||||
// async fn test_get_book_by_id_not_found() {
|
||||
// let db = MockDatabase::new(DatabaseBackend::Postgres)
|
||||
// .append_query_results(vec![vec![] as Vec<Model>])
|
||||
// .into_connection();
|
||||
//
|
||||
// let app = setup_router(db).await;
|
||||
//
|
||||
// let request = Request::builder()
|
||||
// .uri("/books/999")
|
||||
// .method("GET")
|
||||
// .body(Body::empty())
|
||||
// .unwrap();
|
||||
//
|
||||
// let response = app.oneshot(request).await.unwrap();
|
||||
// assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
// }
|
||||
//
|
||||
// // 测试 update_book_by_id
|
||||
// #[tokio::test]
|
||||
// async fn test_update_book_by_id() {
|
||||
// let db = MockDatabase::new(DatabaseBackend::Postgres)
|
||||
// .append_query_results(vec![vec![Model {
|
||||
// id: 1,
|
||||
// title: "Updated Book".to_string(),
|
||||
// author: "Updated Author".to_string(),
|
||||
// }]])
|
||||
// .append_exec_results(vec![MockExecResult {
|
||||
// last_insert_id: 1,
|
||||
// rows_affected: 1,
|
||||
// }])
|
||||
// .into_connection();
|
||||
//
|
||||
// let app = setup_router(db).await;
|
||||
//
|
||||
// // 构造请求
|
||||
// let request = Request::builder()
|
||||
// .uri("/books/1")
|
||||
// .method("PUT")
|
||||
// .header("Content-Type", "application/json")
|
||||
// .body(Body::from(
|
||||
// json!({
|
||||
// "title": "Updated Book",
|
||||
// "author": "Updated Author"
|
||||
// })
|
||||
// .to_string(),
|
||||
// ))
|
||||
// .unwrap();
|
||||
//
|
||||
// // 发送请求
|
||||
// let response = app.oneshot(request).await.unwrap();
|
||||
// assert_eq!(response.status(), StatusCode::OK);
|
||||
//
|
||||
// // 解析响应
|
||||
// let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
|
||||
// let body: Value = serde_json::from_slice(&body).unwrap();
|
||||
// assert_eq!(
|
||||
// body,
|
||||
// json!({
|
||||
// "id": 1,
|
||||
// "title": "Updated Book",
|
||||
// "author": "Updated Author"
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// // 测试 get_all_book
|
||||
// #[tokio::test]
|
||||
// async fn test_get_all_book() {
|
||||
// let db = MockDatabase::new(DatabaseBackend::Postgres)
|
||||
// .append_query_results(vec![vec![
|
||||
// Model {
|
||||
// id: 1,
|
||||
// title: "Book 1".to_string(),
|
||||
// author: "Author 1".to_string(),
|
||||
// },
|
||||
// Model {
|
||||
// id: 2,
|
||||
// title: "Book 2".to_string(),
|
||||
// author: "Author 2".to_string(),
|
||||
// },
|
||||
// ]])
|
||||
// .into_connection();
|
||||
//
|
||||
// let app = setup_router(db).await;
|
||||
//
|
||||
// let request = Request::builder()
|
||||
// .uri("/books")
|
||||
// .method("GET")
|
||||
// .body(Body::empty())
|
||||
// .unwrap();
|
||||
//
|
||||
// let response = app.oneshot(request).await.unwrap();
|
||||
// assert_eq!(response.status(), StatusCode::OK);
|
||||
//
|
||||
// let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
|
||||
// let body: Value = serde_json::from_slice(&body).unwrap();
|
||||
// assert_eq!(
|
||||
// body,
|
||||
// json!([
|
||||
// {
|
||||
// "id": 1,
|
||||
// "title": "Book 1",
|
||||
// "author": "Author 1"
|
||||
// },
|
||||
// {
|
||||
// "id": 2,
|
||||
// "title": "Book 2",
|
||||
// "author": "Author 2"
|
||||
// }
|
||||
// ])
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod book;
|
||||
pub mod category;
|
||||
pub mod tag;
|
||||
pub mod transaction;
|
||||
pub mod transaction;
|
||||
pub mod account;
|
||||
14
src/model/http_body/account.rs
Normal file
14
src/model/http_body/account.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct AccountResp {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub account_type: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub struct AccountReq {
|
||||
pub name: Option<String>,
|
||||
pub account_type: Option<String>,
|
||||
}
|
||||
@@ -2,4 +2,5 @@ pub mod book;
|
||||
pub mod common;
|
||||
pub mod category;
|
||||
pub mod tag;
|
||||
pub mod transaction;
|
||||
pub mod transaction;
|
||||
pub mod account;
|
||||
|
||||
@@ -18,4 +18,8 @@
|
||||
pub category_id: Option<String>,
|
||||
pub tags: Vec<String>,
|
||||
}
|
||||
|
||||
|
||||
pub struct TransactionAmountReq {
|
||||
pub id: Option<String>,
|
||||
pub account_id: Option<String>,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user