use super::*;
async fn setup_user() -> (axum::Router, AppState, String) {
let (mut app, state) = test_app().await;
let (access_token, _) =
register_and_login(&mut app, "addr_user@test.com", "addruser", "Password123!").await;
(app, state, access_token)
}
fn sample_address() -> Value {
json!({
"recipient_name": "Zhang San",
"phone": "13800138000",
"country": "CN",
"province": "Guangdong",
"city": "Shenzhen",
"district": "Nanshan",
"address_line1": "123 Tech Park Road",
"postal_code": "518000",
"is_default": true,
"address_type": "shipping",
})
}
#[tokio::test]
async fn create_address() {
let (mut app, _, tok) = setup_user().await;
let (status, body) = send(
&mut app,
post_json_auth("/api/v1/user/addresses", sample_address(), &tok),
)
.await;
assert!(status.is_success(), "create address: {status} {body:?}");
assert_eq!(body["data"]["recipient_name"], "Zhang San");
assert_eq!(body["data"]["phone"], "13800138000");
assert_eq!(body["data"]["province"], "Guangdong");
assert!(body["data"]["is_default"].as_bool().unwrap());
}
#[tokio::test]
async fn create_address_validation() {
let (mut app, _, tok) = setup_user().await;
let (status, _) = send(
&mut app,
post_json_auth("/api/v1/user/addresses", json!({}), &tok),
)
.await;
assert!(!status.is_success());
}
#[tokio::test]
async fn list_addresses() {
let (mut app, _, tok) = setup_user().await;
send(
&mut app,
post_json_auth(
"/api/v1/user/addresses",
json!({
"recipient_name": "A",
"phone": "111",
"address_line1": "Addr A",
}),
&tok,
),
)
.await;
send(
&mut app,
post_json_auth(
"/api/v1/user/addresses",
json!({
"recipient_name": "B",
"phone": "222",
"address_line1": "Addr B",
}),
&tok,
),
)
.await;
let (status, body) = send(&mut app, get_auth("/api/v1/user/addresses", &tok)).await;
assert!(status.is_success(), "list addresses: {status} {body:?}");
assert_eq!(body["data"].as_array().unwrap().len(), 2);
}
#[tokio::test]
async fn list_addresses_empty() {
let (mut app, _, tok) = setup_user().await;
let (status, body) = send(&mut app, get_auth("/api/v1/user/addresses", &tok)).await;
assert!(status.is_success());
assert_eq!(body["data"].as_array().unwrap().len(), 0);
}
#[tokio::test]
async fn update_address() {
let (mut app, _, tok) = setup_user().await;
let (_, create_body) = send(
&mut app,
post_json_auth("/api/v1/user/addresses", sample_address(), &tok),
)
.await;
let id = create_body["data"]["id"].as_str().unwrap();
let (status, body) = send(
&mut app,
put_json_auth(
&format!("/api/v1/user/addresses/{id}"),
json!({"recipient_name": "Li Si", "phone": "13900139000", "city": "Beijing"}),
&tok,
),
)
.await;
assert!(status.is_success(), "update address: {status} {body:?}");
assert_eq!(body["data"]["recipient_name"], "Li Si");
assert_eq!(body["data"]["phone"], "13900139000");
assert_eq!(body["data"]["city"], "Beijing");
}
#[tokio::test]
async fn delete_address() {
let (mut app, _, tok) = setup_user().await;
let (_, create_body) = send(
&mut app,
post_json_auth("/api/v1/user/addresses", sample_address(), &tok),
)
.await;
let id = create_body["data"]["id"].as_str().unwrap();
let (status, _) = send(
&mut app,
delete_auth(&format!("/api/v1/user/addresses/{id}"), &tok),
)
.await;
assert!(status.is_success(), "delete address: {status}");
let (_, body) = send(&mut app, get_auth("/api/v1/user/addresses", &tok)).await;
assert_eq!(body["data"].as_array().unwrap().len(), 0);
}
#[tokio::test]
async fn cannot_operate_other_users_address() {
let (mut app, _, tok) = setup_user().await;
let (_, create_body) = send(
&mut app,
post_json_auth("/api/v1/user/addresses", sample_address(), &tok),
)
.await;
let id = create_body["data"]["id"].as_str().unwrap();
let (access_token2, _) =
register_and_login(&mut app, "addr_user2@test.com", "addruser2", "Password123!").await;
let (status, _) = send(
&mut app,
put_json_auth(
&format!("/api/v1/user/addresses/{id}"),
json!({"recipient_name": "Hacked"}),
&access_token2,
),
)
.await;
assert!(!status.is_success(), "should not update other user address");
let (status, _) = send(
&mut app,
delete_auth(&format!("/api/v1/user/addresses/{id}"), &access_token2),
)
.await;
assert!(!status.is_success(), "should not delete other user address");
}
#[tokio::test]
async fn address_type_shipping_and_billing() {
let (mut app, _, tok) = setup_user().await;
let (_, create_body) = send(
&mut app,
post_json_auth(
"/api/v1/user/addresses",
json!({
"recipient_name": "Office",
"phone": "111",
"address_line1": "456 Business Ave",
"address_type": "billing",
}),
&tok,
),
)
.await;
assert_eq!(create_body["data"]["address_type"], "billing");
}