use super::*; pub(super) fn check(binary: &std::path::Path, port: u16, bearer: &str) { let path = "/demo/account/admin/profile"; let call = |method: &str, path: &str, body: &str| { let (status, body) = request( port, method, path, "fixture.test", &format!("{bearer}Content-Type: application/json\r\n"), body, ); ( status, serde_json::from_str::(&body).unwrap()["data"].clone(), ) }; assert_eq!(request(port, "GET", path, "fixture.test", "", "").0, 401); for (method, path, allowed) in [ ("PUT", path.to_owned(), "GET, POST"), ("POST", format!("{path}/1"), "GET, PUT, DELETE"), ] { let (status, head, _) = request_head(port, method, &path, "fixture.test", bearer, ""); assert_eq!(status, 405); assert!( head.to_ascii_lowercase() .contains(&format!("\r\nallow: {}\r\n", allowed.to_ascii_lowercase())) ); } assert_eq!(call("POST", &format!("{path}/invalid"), "").0, 404); assert_eq!(call("GET", &format!("{path}?size=101"), "").0, 400); assert_eq!(call("POST", path, r#"{"name":"","bio":null}"#).0, 400); for body in [ r#"{"name":"first","name":"second"}"#, r#"{"name":"first","na\u006de":"second"}"#, r#"{"name":"bad","rank":9223372036854775808}"#, r#"{"name":"bad","status":{"Active":null}}"#, r#"{"name":"bad","bio":"\ud800"}"#, r#"["bad",null,7,null,"Active"]"#, ] { assert_eq!(call("POST", path, body).0, 400, "{body}"); } assert_eq!( call("POST", path, r#"{"name":"bad","note":"private"}"#).0, 400 ); assert_eq!(call("POST", path, r#"{"name":"bad","user_id":1}"#).0, 400); assert_eq!( call("POST", path, r#"{"name":"bad","creation_key":"forged"}"#).0, 400 ); let (status, created) = call("POST", path, r#"{"name":" Dever 中文 "}"#); assert_eq!(status, 200, "{created}"); assert_eq!(created["name"], "Dever 中文"); assert_eq!(created["rank"], 7); assert_eq!(created["status"], "Active"); assert_eq!(created["tag"], "automatic"); assert_eq!(created["uid"].as_str().unwrap().len(), 36); assert!(created.get("note").is_none()); assert!(created.get("user_id").is_none()); assert!(created.get("creation_key").is_none()); assert_eq!( call("POST", path, r#"{"name":"invalid-null","rank":null}"#).0, 400 ); assert_eq!( call( "POST", path, r#"{"name":"invalid-status","status":"Unknown"}"# ) .0, 400 ); assert_eq!( call( "POST", path, &serde_json::json!({"name":"invalid-generated","uid":created["uid"]}).to_string() ) .0, 400 ); assert!(created["created_at"].as_str().unwrap().ends_with('Z')); let id = created["id"].as_i64().unwrap(); let detail = format!("{path}/{id}"); assert_eq!(call("GET", &detail, "").1, created); let bootstrap = execute( binary, "dever.auth.owner", r#"{"site":"admin","user_id":2}"#, ); assert!( bootstrap.status.success(), "{}", String::from_utf8_lossy(&bootstrap.stderr) ); let other = format!( "Authorization: Bearer {}\r\nContent-Type: application/json\r\n", token("reader", "reader-session") ); for (method, body) in [("GET", ""), ("PUT", r#"{"name":"stolen"}"#), ("DELETE", "")] { assert_eq!( request(port, method, &detail, "fixture.test", &other, body).0, 404 ); } let (status, body) = request(port, "GET", path, "fixture.test", &other, ""); assert_eq!(status, 200); assert_eq!( serde_json::from_str::(&body).unwrap()["data"]["total"], 0 ); // 不同身份的创建键不同,名称重复仍须由名称自身的唯一约束拒绝。 assert_eq!( request( port, "POST", path, "fixture.test", &other, r#"{"name":"Dever 中文"}"# ) .0, 409 ); assert_eq!(call("POST", path, r#"{"name":"Dever 中文"}"#).0, 409); let (status, page) = call("GET", path, ""); assert_eq!(status, 200); assert_eq!(page["total"], 1); assert_eq!(page["items"][0], created); assert_eq!( call("GET", &format!("{path}?name=absent"), "").1["total"], 0 ); assert_eq!( call( "GET", &format!("{path}?name=%20Dever%20%E4%B8%AD%E6%96%87%20"), "" ) .1["total"], 1 ); assert_eq!( call("GET", &format!("{path}?page=2&size=1"), "").1["items"], serde_json::json!([]) ); assert_eq!(call("GET", &format!("{detail}?extra=1"), "").0, 400); assert_eq!( call("PUT", &detail, r#"{"name":"bad","creation_key":"forged"}"#).0, 400 ); assert_eq!( call( "PUT", &detail, r#"{"name":"new","bio":"updated","tag":null}"# ) .1["bio"], "updated" ); assert_eq!(call("GET", &detail, "").1["tag"], serde_json::Value::Null); assert_eq!( call("PUT", &detail, r#"{"name":"new","status":"Disabled"}"#).1["status"], "Disabled" ); let (status, replaced) = call("PUT", &detail, r#"{"name":"REPLACED"}"#); assert_eq!(status, 200); assert_eq!(replaced["bio"], serde_json::Value::Null); assert_eq!(replaced["name"], "replaced"); assert!(replaced.get("creation_key").is_none()); // POST:user 仍在数据库中;若 PUT 重算为 PUT:user 或清空,新名称的创建会错误成功。 assert_eq!(call("POST", path, r#"{"name":"another"}"#).0, 409); assert_eq!(call("GET", &detail, "").1, replaced); let (_, page) = call("GET", path, ""); assert_eq!(page["total"], 1); assert_eq!(page["items"][0], replaced); assert_eq!(call("DELETE", &detail, "").0, 200); assert_eq!(call("DELETE", &detail, "").0, 404); assert_eq!(call("GET", &detail, "").0, 404); assert_eq!(call("GET", path, "").1["total"], 0); }