feat: backend MVP (auth/rbac, catalog, orders, fulfillment, invoices) + specs + scaffolds
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
mod common;
|
||||
|
||||
use common::{client, login_admin, register_customer, spawn_app};
|
||||
use serial_test::serial;
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn register_login_me_happy_path() {
|
||||
let app = spawn_app().await;
|
||||
let (token, user_id) = register_customer(&app, "alice").await;
|
||||
|
||||
let res = client()
|
||||
.get(app.url("/api/auth/me"))
|
||||
.bearer_auth(&token)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), 200);
|
||||
let me: serde_json::Value = res.json().await.unwrap();
|
||||
assert_eq!(me["id"], user_id);
|
||||
assert_eq!(me["role"], "customer");
|
||||
assert!(me.get("password_hash").is_none(), "hash must not leak");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn duplicate_email_conflict() {
|
||||
let app = spawn_app().await;
|
||||
let email = format!("dup-{}@test.local", uuid::Uuid::new_v4());
|
||||
for expected in [201, 409] {
|
||||
let res = client()
|
||||
.post(app.url("/api/auth/register"))
|
||||
.json(&serde_json::json!({
|
||||
"email": email,
|
||||
"password": "password123",
|
||||
"display_name": "dup",
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn wrong_password_unauthorized() {
|
||||
let app = spawn_app().await;
|
||||
let email = format!("wp-{}@test.local", uuid::Uuid::new_v4());
|
||||
client()
|
||||
.post(app.url("/api/auth/register"))
|
||||
.json(&serde_json::json!({
|
||||
"email": email,
|
||||
"password": "password123",
|
||||
"display_name": "wp",
|
||||
}))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let res = client()
|
||||
.post(app.url("/api/auth/login"))
|
||||
.json(&serde_json::json!({ "email": email, "password": "wrong-password" }))
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(res.status(), 401);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn me_requires_token() {
|
||||
let app = spawn_app().await;
|
||||
let res = client().get(app.url("/api/auth/me")).send().await.unwrap();
|
||||
assert_eq!(res.status(), 401);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[serial]
|
||||
async fn seeded_admin_can_login() {
|
||||
let app = spawn_app().await;
|
||||
let token = login_admin(&app).await;
|
||||
let res = client()
|
||||
.get(app.url("/api/auth/me"))
|
||||
.bearer_auth(token)
|
||||
.send()
|
||||
.await
|
||||
.unwrap();
|
||||
let me: serde_json::Value = res.json().await.unwrap();
|
||||
assert_eq!(me["role"], "platform_admin");
|
||||
}
|
||||
Reference in New Issue
Block a user