Skip to content

Commit

Permalink
Merge pull request #13 from JakenHerman/jaken/update-and-complete-todos
Browse files Browse the repository at this point in the history
Add functionality to update and complete todos w/ tests
  • Loading branch information
JakenHerman authored Oct 14, 2024
2 parents 3f6a3f9 + 2d1f5f4 commit bfb9858
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use diesel::prelude::*;
use diesel::SqliteConnection;
use rocket::local::blocking::Client;
use rocket::{self, routes};
use crate::routes::{get_todos, add_todo, delete_todo};
use crate::routes::{get_todos, add_todo, delete_todo, update_todo, complete_todo};
use std::fs;
use diesel::sql_query;
use diesel::r2d2::{self, ConnectionManager};
Expand All @@ -20,7 +20,7 @@ pub fn setup_rocket() -> Client {

let rocket = rocket::build()
.manage(pool)
.mount("/", routes![get_todos, add_todo, delete_todo]);
.mount("/", routes![get_todos, add_todo, delete_todo, update_todo, complete_todo]);
Client::tracked(rocket).expect("valid rocket instance")
}

Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ fn rocket() -> _ {
let pool = db::establish_connection();
rocket::build()
.manage(pool)
.mount("/", routes![routes::get_todos, routes::add_todo, routes::delete_todo])
.mount("/", routes![routes::get_todos, routes::add_todo, routes::delete_todo, routes::update_todo, routes::complete_todo])
}
42 changes: 41 additions & 1 deletion src/routes.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use rocket::http::Status;
use rocket::State;
use rocket::serde::{json::Json};
use rocket::serde::json::Json;
use crate::db::{TodoItem, NewTodoItem};
use crate::schema::todos;
use diesel::prelude::*;
Expand Down Expand Up @@ -44,3 +44,43 @@ pub fn delete_todo(pool: &State<DbPool>, id: i32) -> Result<&'static str, (Statu

Ok("Todo deleted successfully!")
}

// Update an existing to-do item
#[put("/todos/<id>", format = "json", data = "<updated_todo>")]
pub fn update_todo(pool: &State<DbPool>, id: i32, updated_todo: Json<NewTodoItem>) -> Result<&'static str, (Status, &'static str)> {
let mut connection = pool.get().map_err(|_| (Status::InternalServerError, "Failed to get connection from pool"))?;

// Get the existing todo item from the database
let target = todos::table.find(id);

// Create updated data based on existing and new values
let updated_data = NewTodoItem {
title: updated_todo.title,
completed: updated_todo.completed,
};

// Update the todo in the database
diesel::update(target)
.set((
todos::dsl::title.eq(updated_data.title),
todos::dsl::completed.eq(updated_data.completed),
))
.execute(&mut connection)
.map_err(|_| (Status::InternalServerError, "Failed to update todo"))?;

Ok("Todo updated successfully!")
}

// Mark a to-do item as completed
#[put("/todos/<id>/complete")]
pub fn complete_todo(pool: &State<DbPool>, id: i32) -> Result<&'static str, (Status, &'static str)> {
let mut connection = pool.get().map_err(|_| (Status::InternalServerError, "Failed to get connection from pool"))?;

// Update the completed status of the todo
diesel::update(todos::table.find(id))
.set(todos::dsl::completed.eq(true))
.execute(&mut connection)
.map_err(|_| (Status::InternalServerError, "Failed to complete todo"))?;

Ok("Todo marked as completed!")
}
50 changes: 50 additions & 0 deletions tests/complete_todo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use rocket::http::Status;
use dooly::{db::TodoItem, helpers::{cleanup_database, establish_connection, run_seed_script, setup_rocket}};
use serde_json::json;
use rocket::http::ContentType;

#[test]
fn test_complete_todo() {
cleanup_database(); // Clean up the database before starting the test
let mut connection = establish_connection();
run_seed_script(&mut connection); // Seed the database with initial data

let client = setup_rocket();

// Create a new todo item
let new_todo = json!({
"title": "Test Incomplete Todo",
"completed": false
});

let response = client.post("/todos")
.header(ContentType::JSON)
.body(new_todo.to_string())
.dispatch();

assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "Todo added successfully!");

// Fetch the todo items to get the ID of the newly added todo
let response = client.get("/todos")
.dispatch();

assert_eq!(response.status(), Status::Ok);
let todos: Vec<TodoItem> = serde_json::from_str(&response.into_string().unwrap()).unwrap();
let todo_id = todos[0].id; // Assuming this is the only todo item

// Mark the todo item as completed
let response = client.put(format!("/todos/{}/complete", todo_id))
.dispatch();

assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "Todo marked as completed!");

// Fetch the updated todo to verify the changes
let response = client.get("/todos")
.dispatch();

assert_eq!(response.status(), Status::Ok);
let todos: Vec<TodoItem> = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(todos[0].completed, true);
}
50 changes: 50 additions & 0 deletions tests/update_todo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use rocket::http::Status;
use dooly::{db::TodoItem, helpers::{cleanup_database, establish_connection, run_seed_script, setup_rocket}};
use serde_json::json;
use rocket::http::ContentType;

#[test]
fn test_update_todo() {
cleanup_database(); // Clean up the database before starting the test
let mut connection = establish_connection();
run_seed_script(&mut connection); // Seed the database with initial data

let client = setup_rocket();

// Create a new todo item to update
let new_todo = json!({
"title": "Initial Todo",
"completed": false
});

let response = client.post("/todos")
.header(ContentType::JSON)
.body(new_todo.to_string())
.dispatch();

assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "Todo added successfully!");

// Update the existing todo item
let updated_todo = json!({
"title": "Updated Todo Title",
"completed": true
});

let response = client.put("/todos/1")
.header(ContentType::JSON)
.body(updated_todo.to_string())
.dispatch();

assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "Todo updated successfully!");

// Fetch the updated todo to verify the changes
let response = client.get("/todos")
.dispatch();

assert_eq!(response.status(), Status::Ok);
let todos: Vec<TodoItem> = serde_json::from_str(&response.into_string().unwrap()).unwrap();
assert_eq!(todos[0].title, "Updated Todo Title");
assert_eq!(todos[0].completed, true);
}

0 comments on commit bfb9858

Please sign in to comment.