Test for user system and comments

This commit is contained in:
Alphonse Paix
2025-10-06 02:08:26 +02:00
parent d96a29ee73
commit 04c2d2b7f5
12 changed files with 501 additions and 29 deletions

346
tests/api/users.rs Normal file
View File

@@ -0,0 +1,346 @@
use crate::helpers::{TestApp, fake_newsletter_body, fake_post_body, when_sending_an_email};
use sqlx::PgPool;
use wiremock::ResponseTemplate;
use zero2prod::authentication::Role;
#[sqlx::test]
async fn admin_can_create_user(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, false).await;
let record = sqlx::query!("SELECT user_id FROM users WHERE username = $1", username)
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_some());
let html = app.get_admin_dashboard_html().await;
assert!(html.contains(username));
}
#[sqlx::test]
async fn admin_can_create_admin_user(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, true).await;
let record = sqlx::query!(
r#"
SELECT role as "role: Role"
FROM users WHERE username = $1
"#,
username
)
.fetch_one(&app.connection_pool)
.await
.unwrap();
matches!(record.role, Role::Admin);
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
let html = app.get_admin_dashboard_html().await;
assert!(html.contains("Administration"));
}
#[sqlx::test]
async fn admin_users_can_create_posts(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, true).await;
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
app.create_confirmed_subscriber().await;
when_sending_an_email()
.respond_with(ResponseTemplate::new(200))
.expect(1)
.mount(&app.email_server)
.await;
app.post_create_post(&fake_post_body()).await;
app.dispatch_all_pending_emails().await;
}
#[sqlx::test]
async fn admin_users_can_send_emails(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, true).await;
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
app.create_confirmed_subscriber().await;
when_sending_an_email()
.respond_with(ResponseTemplate::new(200))
.expect(1)
.mount(&app.email_server)
.await;
app.post_newsletters(&fake_newsletter_body()).await;
app.dispatch_all_pending_emails().await;
}
#[sqlx::test]
async fn admin_users_can_create_users(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, true).await;
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
let username = "other_user";
app.create_user(username, password, true).await;
let html = app.get_admin_dashboard_html().await;
assert!(html.contains(username));
}
#[sqlx::test]
async fn admin_users_can_delete_contents(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, true).await;
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
app.create_confirmed_subscriber().await;
let (subscriber_id, email) = {
let record = sqlx::query!("SELECT id, email FROM subscriptions")
.fetch_one(&app.connection_pool)
.await
.unwrap();
(record.id, record.email)
};
let response = app.delete_subscriber(subscriber_id).await;
let text = response.text().await.unwrap();
assert!(text.contains(&email));
assert!(text.contains("has been deleted"));
app.create_user("other_user", password, true).await;
let user_id = {
let record = sqlx::query!("SELECT user_id FROM users")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.user_id
};
let response = app.delete_user(user_id).await;
let text = response.text().await.unwrap();
assert!(text.contains("The user has been deleted"));
app.post_create_post(&fake_post_body()).await;
let post_id = {
let record = sqlx::query!("SELECT post_id FROM posts")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.post_id
};
let comment_body = serde_json::json!({
"author": "author",
"content": "comment",
"idempotency_key": "key",
});
app.post_comment(&post_id, &comment_body).await;
let comment_id = {
let record = sqlx::query!("SELECT comment_id FROM comments")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.comment_id
};
let response = app.delete_comment(comment_id).await;
assert!(
response
.text()
.await
.unwrap()
.contains("The comment has been deleted")
);
let response = app.delete_post(post_id).await;
let text = response.text().await.unwrap();
assert!(text.contains("The post has been deleted"));
}
#[sqlx::test]
async fn admin_functions_are_hidden_for_non_admin_users(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, false).await;
let record = sqlx::query!(
r#"
SELECT role as "role: Role"
FROM users WHERE username = $1
"#,
username
)
.fetch_one(&app.connection_pool)
.await
.unwrap();
matches!(record.role, Role::Writer);
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
let response = app.post_login(&login_body).await;
assert!(!response.text().await.unwrap().contains("Administration"));
}
#[sqlx::test]
async fn writers_can_publish_posts_and_send_emails(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, false).await;
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
app.create_confirmed_subscriber().await;
when_sending_an_email()
.respond_with(ResponseTemplate::new(200))
.expect(2)
.mount(&app.email_server)
.await;
app.post_create_post(&fake_post_body()).await;
app.post_newsletters(&fake_newsletter_body()).await;
app.dispatch_all_pending_emails().await;
}
#[sqlx::test]
async fn writers_cannot_perform_admin_functions(connection_pool: PgPool) {
let app = TestApp::spawn(connection_pool).await;
app.admin_login().await;
let username = "alphonse";
let password = "123456789abc";
app.create_user(username, password, false).await;
app.post_create_post(&fake_post_body()).await;
let post_id = {
let record = sqlx::query!("SELECT post_id FROM posts")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.post_id
};
app.create_confirmed_subscriber().await;
let subscriber_id = {
let record = sqlx::query!("SELECT id FROM subscriptions")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.id
};
let comment_body = serde_json::json!({
"author": "author",
"content": "comment",
"idempotency_key": "key",
});
app.post_comment(&post_id, &comment_body).await;
let comment_id = {
let record = sqlx::query!("SELECT comment_id FROM comments")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.comment_id
};
app.logout().await;
let login_body = serde_json::json!({
"username": username,
"password": password
});
app.post_login(&login_body).await;
let response = app.delete_subscriber(subscriber_id).await;
let html = response.text().await.unwrap();
assert!(html.contains("requires administrator privileges"));
let record = sqlx::query!("SELECT id FROM subscriptions")
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_some());
let response = app.delete_comment(comment_id).await;
let html = response.text().await.unwrap();
assert!(html.contains("requires administrator privileges"));
let record = sqlx::query!("SELECT comment_id FROM comments")
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_some());
let response = app.delete_post(post_id).await;
let html = response.text().await.unwrap();
assert!(html.contains("requires administrator privileges"));
let record = sqlx::query!("SELECT post_id FROM posts")
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_some());
let user_id = {
let record = sqlx::query!("SELECT user_id FROM users")
.fetch_one(&app.connection_pool)
.await
.unwrap();
record.user_id
};
let response = app.delete_user(user_id).await;
let html = response.text().await.unwrap();
assert!(html.contains("requires administrator privileges"));
let record = sqlx::query_scalar!("SELECT username FROM users WHERE user_id = $1", user_id)
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_some());
let username = "friend";
let password = "123456789abc";
let response = app.create_user(username, password, false).await;
let html = response.text().await.unwrap();
assert!(html.contains("requires administrator privileges"));
let record = sqlx::query!("SELECT user_id FROM users WHERE username = $1", username)
.fetch_optional(&app.connection_pool)
.await
.unwrap();
assert!(record.is_none());
}