Skip to content

Commit

Permalink
feat: user update (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
cudidotdev authored Aug 1, 2023
1 parent ca10e29 commit d7a41db
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 3 deletions.
32 changes: 32 additions & 0 deletions crates/core/src/user/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ pub struct InsertUserDto {
pub password_hash: String,
}

pub struct UpdateUserDto {
pub name: Option<String>,
pub surname: Option<String>,
}

#[derive(Clone)]
pub struct UserRepository {
db: Database,
Expand Down Expand Up @@ -96,6 +101,33 @@ impl UserRepository {
Ok(UserRepository::into_record(model))
}

pub async fn update(&self, id: Pxid, dto: UpdateUserDto) -> Result<UserRecord> {
let user = entity::prelude::User::find_by_id(&id.to_string())
.one(&*self.db)
.await
.map_err(|_| UserError::DatabaseError)?;

if let Some(u) = user {
let mut active_model: entity::user::ActiveModel = u.into();

if let Some(name) = dto.name {
active_model.name = Set(name);
}
if let Some(surname) = dto.surname {
active_model.surname = Set(surname);
}

let record = active_model
.update(&*self.db)
.await
.map_err(|_| UserError::DatabaseError)?;

return Ok(Self::into_record(record));
}

Err(UserError::UserNotFound)
}

pub async fn find(&self, filter: Option<UserFilter>) -> Result<Vec<UserRecord>> {
let mut query = entity::user::Entity::find();

Expand Down
12 changes: 11 additions & 1 deletion crates/core/src/user/service.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use pxid::Pxid;

use super::error::Result;
use super::model::{Email, Password, User, Username};
use super::repository::{InsertUserDto, UserFilter, UserRepository};
use super::repository::{InsertUserDto, UpdateUserDto, UserFilter, UserRepository};

pub struct CreateUserDto {
pub name: String,
Expand Down Expand Up @@ -48,4 +50,12 @@ impl UserService {

Ok(users)
}

pub async fn update(&self, id: Pxid, dto: UpdateUserDto) -> Result<User> {
let record = self.repository.update(id, dto).await?;

let user = User::try_from(record)?;

Ok(user)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl PostCreate {
post: None,
error: Some(PostError {
code: PostErrorCode::Unknown,
message: format!("An error ocurred: {err}", err = err),
message: format!("An error ocurred: {err}"),
}),
}),
}
Expand Down
11 changes: 11 additions & 0 deletions crates/server/src/graphql/modules/user/mutation/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
mod token_create;
mod user_register;
mod user_update;

use async_graphql::{Context, Object, Result};
use pxid::graphql::Pxid;

use self::token_create::TokenCreate;
use self::user_register::{UserRegister, UserRegisterInput};
use self::user_update::{UserUpdate, UserUpdateInput};

#[derive(Debug, Default)]
pub struct UserMutationRoot;
Expand All @@ -26,4 +29,12 @@ impl UserMutationRoot {
) -> Result<UserRegister> {
UserRegister::exec(ctx, input).await
}
async fn user_update(
&self,
ctx: &Context<'_>,
id: Pxid,
input: UserUpdateInput,
) -> Result<UserUpdate> {
UserUpdate::exec(ctx, id, input).await
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl UserRegister {
user: None,
error: Some(UserError {
code: UserErrorCode::Internal,
message: format!("An error ocurred: {err}", err = err),
message: format!("An error ocurred: {err}"),
}),
}),
}
Expand Down
43 changes: 43 additions & 0 deletions crates/server/src/graphql/modules/user/mutation/user_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use async_graphql::{Context, InputObject, Result, SimpleObject};
use gabble::user::repository::UpdateUserDto;
use pxid::graphql::Pxid;
use serde::{Deserialize, Serialize};

use crate::context::SharedContext;
use crate::graphql::modules::user::types::{User, UserError, UserErrorCode};

#[derive(Debug, Default, InputObject)]
pub struct UserUpdateInput {
pub name: Option<String>,
pub surname: Option<String>,
}

#[derive(Debug, Default, Deserialize, Serialize, SimpleObject)]
pub struct UserUpdate {
user: Option<User>,
error: Option<UserError>,
}

impl UserUpdate {
pub async fn exec(ctx: &Context<'_>, id: Pxid, input: UserUpdateInput) -> Result<Self> {
let context = ctx.data_unchecked::<SharedContext>();
let dto = UpdateUserDto {
name: input.name,
surname: input.surname,
};

match context.services.user.update(id.into_inner(), dto).await {
Ok(user) => Ok(Self {
user: Some(User::from(user)),
error: None,
}),
Err(err) => Ok(Self {
user: None,
error: Some(UserError {
code: UserErrorCode::Internal,
message: format!("An error ocurred: {err}"),
}),
}),
}
}
}
1 change: 1 addition & 0 deletions crates/test/src/modules/user/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod user_register;
mod user_update;
65 changes: 65 additions & 0 deletions crates/test/src/modules/user/user_update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use std::str::FromStr;

use async_graphql::{Request, Variables};
use gabble::user::{
model::{Email, Password, Username},
service::CreateUserDto,
};
use serde_json::json;

use crate::TestUtil;

#[tokio::test]
async fn updates_a_user() {
let test_util = TestUtil::new_cleared().await;
let (context, schema) = test_util.parts();

let user = context
.services
.user
.create(CreateUserDto {
name: "Augustine".into(),
surname: "Madu".into(),
email: Email::from_str("augustine@gmail.com").unwrap(),
username: Username::from_str("Cudi").unwrap(),
password: Password::from_str("Password12##$$").unwrap(),
})
.await
.unwrap();

let mutation: &str = "
mutation UpdateUser($id: Pxid, $payload: UserUpdateInput!) {
userUpdate(id:$id, input: $payload) {
user {
id
name
surname
}
error {
code
message
}
}
}
";

let result = schema
.execute(
Request::new(mutation).variables(Variables::from_json(json!({
"id": user.id.to_string(),
"payload": {
"name": "John",
"surname": "Appleseed",
}
}))),
)
.await;

println!("{result:#?}");

let data = result.data.into_json().unwrap();
let user_update_user = &data["userUpdate"]["user"];

assert_eq!(user_update_user["name"], "John");
assert_eq!(user_update_user["surname"], "Appleseed");
}

0 comments on commit d7a41db

Please sign in to comment.