Skip to content

Commit

Permalink
feat: ✨ Add post tests
Browse files Browse the repository at this point in the history
Issue: #44
  • Loading branch information
ittokunvim committed May 16, 2023
1 parent d3eab38 commit 83a463e
Show file tree
Hide file tree
Showing 4 changed files with 261 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/db/crud/mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl Mutation {
let post: post::ActiveModel = Post::find_by_id(id)
.one(db)
.await?
.ok_or(DbErr::Custom("Cannot Find Post".to_owned()))
.ok_or(DbErr::RecordNotFound("Cannot Find Post".to_owned()))
.map(Into::into)?;

post::ActiveModel {
Expand Down
176 changes: 176 additions & 0 deletions tests/post_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
use actix_web::test::{init_service, read_body_json, TestRequest};
use actix_web::App;
use serde_json::Value;

use api_ittoku_tech::db::post;
use api_ittoku_tech::routes;

mod utils;

use utils::prelude::*;

#[actix_web::test]
async fn post_list() {
let app = init_service(
App::new()
.app_data(app_state().await)
.configure(routes::init),
)
.await;
let resp = TestRequest::get().uri("/posts").send_request(&app).await;
assert!(resp.status().is_success());
}

#[actix_web::test]
async fn post_create() {
let app = init_service(
App::new()
.app_data(app_state().await)
.configure(routes::init),
)
.await;
// Empty post data
let post_data = NEW_POST_EMPTY.to_owned();
let resp = TestRequest::post()
.uri("/posts")
.set_json(post_data)
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp: Value = read_body_json(resp).await;
let resp_empty = RESP_POST_EMPTY.to_owned();
assert_eq!(resp, resp_empty);
// Too long post data
let post_data = NEW_POST_TOO_LONG.to_owned();
let resp = TestRequest::post()
.uri("/posts")
.set_json(post_data)
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp: Value = read_body_json(resp).await;
let resp_too_long = RESP_POST_TOO_LONG.to_owned();
assert_eq!(resp, resp_too_long);
// success to create post
let post_data = NEW_POST.to_owned();
let resp = TestRequest::post()
.uri("/posts")
.set_json(&post_data)
.send_request(&app)
.await;
assert!(resp.status().is_success());
let resp: Value = read_body_json(resp).await;
assert_eq!(resp["title"], post_data["title"]);
delete_post(resp["id"].as_i64().unwrap() as i32).await;
}

#[actix_web::test]
async fn post_detail() {
let app = init_service(
App::new()
.app_data(app_state().await)
.configure(routes::init),
)
.await;
let post = create_post().await;
// post not found
let resp = TestRequest::get()
.uri("/posts/hoge")
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp_not_found = RESP_NOTFOUND.to_owned();
let resp: Value = read_body_json(resp).await;
assert_eq!(resp, resp_not_found);
// success to get post
let resp = TestRequest::get()
.uri(&format!("/posts/{}", post.id))
.send_request(&app)
.await;
assert!(resp.status().is_success());
let resp: post::Model = read_body_json(resp).await;
assert_eq!(resp, post);
delete_post(resp.id).await;
}

#[actix_web::test]
async fn post_update() {
let app = init_service(
App::new()
.app_data(app_state().await)
.configure(routes::init),
)
.await;
let post = create_post().await;
// Empty post data
let post_data = NEW_POST_EMPTY.to_owned();
let resp = TestRequest::patch()
.uri(&format!("/posts/{}", post.id))
.set_json(post_data)
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp: Value = read_body_json(resp).await;
let resp_empty = RESP_POST_EMPTY.to_owned();
assert_eq!(resp, resp_empty);
// Too long post data
let post_data = NEW_POST_TOO_LONG.to_owned();
let resp = TestRequest::patch()
.uri(&format!("/posts/{}", post.id))
.set_json(post_data)
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp: Value = read_body_json(resp).await;
let resp_too_long = RESP_POST_TOO_LONG.to_owned();
assert_eq!(resp, resp_too_long);
// post not found
let post_data = NEW_POST_UPDATED.to_owned();
let resp = TestRequest::patch()
.uri("/posts/hoge")
.set_json(&post_data)
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp_not_found = RESP_NOTFOUND.to_owned();
let resp: Value = read_body_json(resp).await;
assert_eq!(resp, resp_not_found);
// success to update post
let resp = TestRequest::patch()
.uri(&format!("/posts/{}", post.id))
.set_json(&post_data)
.send_request(&app)
.await;
assert!(resp.status().is_success());
let resp: Value = read_body_json(resp).await;
assert_eq!(resp["title"], post_data["title"]);
delete_post(resp["id"].as_i64().unwrap() as i32).await;
}

#[actix_web::test]
async fn post_delete() {
let app = init_service(
App::new()
.app_data(app_state().await)
.configure(routes::init),
)
.await;
let post = create_post().await;
// post not found
let resp = TestRequest::delete()
.uri("/posts/hoge")
.send_request(&app)
.await;
assert!(resp.status().is_client_error());
let resp_not_found = RESP_NOTFOUND.to_owned();
let resp: Value = read_body_json(resp).await;
assert_eq!(resp, resp_not_found);
// success to delete post
let resp = TestRequest::delete()
.uri(&format!("/posts/{}", post.id))
.send_request(&app)
.await;
assert!(resp.status().is_success());
let resp: post::Model = read_body_json(resp).await;
assert_eq!(resp, post);
}
67 changes: 67 additions & 0 deletions tests/utils/json_data.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,82 @@
use once_cell::sync::Lazy;
use serde_json::{json, Value};

#[allow(dead_code)]
pub static RESP_ROOT: Lazy<Value> = Lazy::new(|| {
json!({
"post_detail_url": "http://0.0.0.0:8080/posts/{id}",
"post_list_url": "http://0.0.0.0:8080/posts"
})
});

#[allow(dead_code)]
pub static RESP_NOTFOUND: Lazy<Value> =
Lazy::new(|| json!({"status": 404, "message": "Not Found".to_string()}));

#[allow(dead_code)]
pub static RESP_INVALID_JSON: Lazy<Value> =
Lazy::new(|| json!({"status": 400, "message": "Invalid JSON Data".to_string()}));

#[allow(dead_code)]
pub static NEW_POST: Lazy<Value> = Lazy::new(|| {
json!({
"title": "test title",
"text": "test text",
})
});

#[allow(dead_code)]
pub static NEW_POST_UPDATED: Lazy<Value> = Lazy::new(|| {
json!({
"title": "test title updated",
"text": "test text updated",
})
});

#[allow(dead_code)]
pub static NEW_POST_EMPTY: Lazy<Value> = Lazy::new(|| {
json!({
"title": "",
"text": "",
})
});

#[allow(dead_code)]
pub static NEW_POST_TOO_LONG: Lazy<Value> = Lazy::new(|| {
json!({
"title": "x".repeat(257),
"text": "x".repeat(65537),
})
});

#[allow(dead_code)]
pub static RESP_POST_EMPTY: Lazy<Value> = Lazy::new(|| {
json!({
"errors": [
{
"status": 422,
"message": "title cannot be empty",
},
{
"status": 422,
"message": "text cannot be empty",
},
]
})
});

#[allow(dead_code)]
pub static RESP_POST_TOO_LONG: Lazy<Value> = Lazy::new(|| {
json!({
"errors": [
{
"status": 422,
"message": "title cannot be longer than 256 characters",
},
{
"status": 422,
"message": "text cannot be longer than 65536 characters",
},
]
})
});
18 changes: 17 additions & 1 deletion tests/utils/setup.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use api_ittoku_tech::db::database_connection;
use api_ittoku_tech::db::{database_connection, post, Mutation};
use api_ittoku_tech::AppState;

use actix_web::web;
Expand All @@ -7,3 +7,19 @@ pub async fn app_state() -> web::Data<AppState> {
let conn = database_connection().await.unwrap();
web::Data::new(AppState { conn })
}

#[allow(dead_code)]
pub async fn create_post() -> post::Model {
let conn = database_connection().await.unwrap();
let post_data = post::NewModel {
title: "test title".to_owned(),
text: "test text".to_owned(),
};
Mutation::create_post(&conn, post_data).await.unwrap()
}

#[allow(dead_code)]
pub async fn delete_post(id: i32) -> post::Model {
let conn = database_connection().await.unwrap();
Mutation::delete_post_by_id(&conn, id).await.unwrap()
}

0 comments on commit 83a463e

Please sign in to comment.