this repo has no description
1mod common; 2use common::*; 3use reqwest::StatusCode; 4use serde_json::Value; 5 6#[tokio::test] 7async fn test_frontend_client_metadata_returns_valid_json() { 8 let client = client(); 9 let res = client 10 .get(format!("{}/oauth/client-metadata.json", base_url().await)) 11 .send() 12 .await 13 .expect("Failed to send request"); 14 assert_eq!(res.status(), StatusCode::OK); 15 let body: Value = res.json().await.expect("Should return valid JSON"); 16 assert!( 17 body["client_id"].as_str().is_some(), 18 "Should have client_id" 19 ); 20 assert!( 21 body["client_name"].as_str().is_some(), 22 "Should have client_name" 23 ); 24 assert!( 25 body["redirect_uris"].as_array().is_some(), 26 "Should have redirect_uris" 27 ); 28 assert!( 29 body["grant_types"].as_array().is_some(), 30 "Should have grant_types" 31 ); 32 assert!( 33 body["response_types"].as_array().is_some(), 34 "Should have response_types" 35 ); 36 assert!(body["scope"].as_str().is_some(), "Should have scope"); 37 assert!( 38 body["token_endpoint_auth_method"].as_str().is_some(), 39 "Should have token_endpoint_auth_method" 40 ); 41} 42 43#[tokio::test] 44async fn test_frontend_client_metadata_correct_values() { 45 let client = client(); 46 let res = client 47 .get(format!("{}/oauth/client-metadata.json", base_url().await)) 48 .send() 49 .await 50 .expect("Failed to send request"); 51 assert_eq!(res.status(), StatusCode::OK); 52 let body: Value = res.json().await.unwrap(); 53 let client_id = body["client_id"].as_str().unwrap(); 54 assert!( 55 client_id.ends_with("/oauth/client-metadata.json"), 56 "client_id should end with /oauth/client-metadata.json" 57 ); 58 let grant_types = body["grant_types"].as_array().unwrap(); 59 let grant_strs: Vec<&str> = grant_types.iter().filter_map(|v| v.as_str()).collect(); 60 assert!( 61 grant_strs.contains(&"authorization_code"), 62 "Should support authorization_code grant" 63 ); 64 assert!( 65 grant_strs.contains(&"refresh_token"), 66 "Should support refresh_token grant" 67 ); 68 let response_types = body["response_types"].as_array().unwrap(); 69 let response_strs: Vec<&str> = response_types.iter().filter_map(|v| v.as_str()).collect(); 70 assert!( 71 response_strs.contains(&"code"), 72 "Should support code response type" 73 ); 74 assert_eq!( 75 body["token_endpoint_auth_method"].as_str(), 76 Some("none"), 77 "Should be public client (none auth)" 78 ); 79 assert_eq!( 80 body["application_type"].as_str(), 81 Some("web"), 82 "Should be web application" 83 ); 84 assert_eq!( 85 body["dpop_bound_access_tokens"].as_bool(), 86 Some(true), 87 "AT Protocol requires DPoP-bound access tokens" 88 ); 89 let scope = body["scope"].as_str().unwrap(); 90 assert!(scope.contains("atproto"), "Scope should include atproto"); 91} 92 93#[tokio::test] 94async fn test_frontend_client_metadata_redirect_uri_matches_client_uri() { 95 let client = client(); 96 let res = client 97 .get(format!("{}/oauth/client-metadata.json", base_url().await)) 98 .send() 99 .await 100 .expect("Failed to send request"); 101 assert_eq!(res.status(), StatusCode::OK); 102 let body: Value = res.json().await.unwrap(); 103 let client_uri = body["client_uri"].as_str().unwrap(); 104 let redirect_uris = body["redirect_uris"].as_array().unwrap(); 105 assert!( 106 !redirect_uris.is_empty(), 107 "Should have at least one redirect URI" 108 ); 109 let redirect_uri = redirect_uris[0].as_str().unwrap(); 110 assert!( 111 redirect_uri.starts_with(client_uri), 112 "Redirect URI should be on same origin as client_uri" 113 ); 114}