diff --git a/.github/workflows/ci-backend.yaml b/.github/workflows/ci-backend.yaml index 0c96067..d8551c0 100644 --- a/.github/workflows/ci-backend.yaml +++ b/.github/workflows/ci-backend.yaml @@ -29,6 +29,23 @@ jobs: run: | cargo build + lint: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./backend + steps: + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Checkout + uses: actions/checkout@v4 + + - name: Restore Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: backend + - name: lint check run: | cargo clippy @@ -36,3 +53,25 @@ jobs: - name: format check run: | cargo fmt --check + + test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./backend + steps: + - name: Setup Rust + uses: dtolnay/rust-toolchain@stable + + - name: Checkout + uses: actions/checkout@v4 + + - name: Restore Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: backend + + - name: test + run: | + cargo test + diff --git a/backend/db-schema/migrations/20240908082102_/migration.sql b/backend/db-schema/migrations/20240908082102_/migration.sql new file mode 100644 index 0000000..fdbd511 --- /dev/null +++ b/backend/db-schema/migrations/20240908082102_/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "updated_at" DROP NOT NULL; diff --git a/backend/db-schema/schema.prisma b/backend/db-schema/schema.prisma index 126fcb8..5b6d6e3 100644 --- a/backend/db-schema/schema.prisma +++ b/backend/db-schema/schema.prisma @@ -23,7 +23,7 @@ model User { user_name String @unique display_name String @db.VarChar(255) created_at DateTime @default(now()) - updated_at DateTime @updatedAt + updated_at DateTime? @updatedAt channel Channel[] message Message[] channel_user ChannelUser[] diff --git a/backend/src/generate/entities/user.rs b/backend/src/generate/entities/user.rs index a1b67da..63a5377 100644 --- a/backend/src/generate/entities/user.rs +++ b/backend/src/generate/entities/user.rs @@ -11,7 +11,7 @@ pub struct Model { pub user_name: String, pub display_name: String, pub created_at: DateTime, - pub updated_at: DateTime, + pub updated_at: Option, } #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] diff --git a/backend/src/handler.rs b/backend/src/handler.rs index 827aa39..facb74c 100644 --- a/backend/src/handler.rs +++ b/backend/src/handler.rs @@ -1,3 +1,4 @@ pub mod mutation; pub mod query; mod test_handler; +mod user; diff --git a/backend/src/handler/query.rs b/backend/src/handler/query.rs index afed9b5..dc056aa 100644 --- a/backend/src/handler/query.rs +++ b/backend/src/handler/query.rs @@ -1,5 +1,7 @@ use crate::handler::test_handler::TestQuery; use async_graphql::MergedObject; +use crate::handler::user::UserQuery; + #[derive(MergedObject, Default)] -pub struct Query(TestQuery); +pub struct Query(TestQuery, UserQuery); diff --git a/backend/src/handler/user.rs b/backend/src/handler/user.rs new file mode 100644 index 0000000..e778595 --- /dev/null +++ b/backend/src/handler/user.rs @@ -0,0 +1,27 @@ +use async_graphql::Error; +use async_graphql::Object; +use async_graphql::Result; + +use crate::context::Context; +use crate::models; +use crate::usecase; + +#[derive(Default)] +pub struct UserQuery; + +#[Object] +impl UserQuery { + async fn user<'ctx>( + &self, + ctx: &async_graphql::Context<'ctx>, + id: String, + ) -> Result { + let ctx = ctx.data_unchecked::(); + + match usecase::user::get_user_by_id(ctx, id.as_str()).await { + Ok(Some(user)) => Ok(user), + Ok(None) => Err(Error::new("Not found")), + Err(_) => Err(Error::new("Internal server error")), + } + } +} diff --git a/backend/src/usecase/user.rs b/backend/src/usecase/user.rs index 156596d..f34a5f4 100644 --- a/backend/src/usecase/user.rs +++ b/backend/src/usecase/user.rs @@ -1,7 +1,20 @@ +use sea_orm::EntityTrait; + +use crate::generate::entities::user; use crate::{context::Context, models::user::User}; -pub async fn get_user_by_id(_ctx: &Context, _id: &str) -> Result { - todo!(); +pub async fn get_user_by_id(ctx: &Context, id: &str) -> Result, ()> { + let db = &ctx.db; + + let Ok(user) = user::Entity::find_by_id(id).one(db).await else { + return Err(()); + }; + + Ok(user.map(|user| User { + id: user.id, + name: user.user_name, + display_name: user.display_name, + })) } #[cfg(test)] @@ -27,8 +40,7 @@ pub mod test { display_name: "あいうえお".to_string(), created_at: DateTime::parse_from_str("2024-08-08 00:00:00", "%Y-%m-%d %H:%M:%S") .unwrap(), - updated_at: DateTime::parse_from_str("2024-08-08 00:00:00", "%Y-%m-%d %H:%M:%S") - .unwrap(), + updated_at: None, }]]) .into_connection(); @@ -43,29 +55,21 @@ pub mod test { // Assert assert_eq!( result, - Ok(User { + Ok(Some(User { id: id.to_string(), name: "aiueo".to_string(), display_name: "あいうえお".to_string(), - }) + })) ); } #[tokio::test] - async fn 指定IDのユーザが存在しない場合失敗() { + async fn 指定IDのユーザが存在しない場合None() { // Arrange let id = "4e36eb58-49a5-43aa-935f-5a5cccb77a90"; let db: DatabaseConnection = MockDatabase::new(sea_orm::DatabaseBackend::Postgres) - .append_query_results([vec![user::Model { - id: id.to_string(), - user_name: "aiueo".to_string(), - display_name: "あいうえお".to_string(), - created_at: DateTime::parse_from_str("2024-08-08 00:00:00", "%Y-%m-%d %H:%M:%S") - .unwrap(), - updated_at: DateTime::parse_from_str("2024-08-08 00:00:00", "%Y-%m-%d %H:%M:%S") - .unwrap(), - }]]) + .append_query_results(vec![Vec::::new()]) .into_connection(); let ctx = Context { @@ -77,6 +81,6 @@ pub mod test { let result = get_user_by_id(&ctx, "存在しないID").await; // Assert - assert_eq!(result, Err(())); + assert_eq!(result, Ok(None)); } }