use actix_http::StatusCode; use actix_web::test; use common::{ api_v3::ApiV3, database::{FRIEND_USER_ID, FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT}, dummy_data::DummyOAuthClientAlpha, environment::{TestEnvironment, with_test_environment}, get_json_val_str, }; use labrinth::{ models::{ oauth_clients::{OAuthClient, OAuthClientCreationResult}, pats::Scopes, }, routes::v3::oauth_clients::OAuthClientEdit, }; use common::database::USER_USER_ID_PARSED; pub mod common; #[actix_rt::test] async fn can_create_edit_get_oauth_client() { with_test_environment(None, |env: TestEnvironment| async move { let client_name = "test_client".to_string(); let redirect_uris = vec![ "https://modrinth.com".to_string(), "https://modrinth.com/a".to_string(), ]; let resp = env .api .add_oauth_client( client_name.clone(), Scopes::all() - Scopes::restricted(), redirect_uris.clone(), FRIEND_USER_PAT, ) .await; assert_status!(&resp, StatusCode::OK); let creation_result: OAuthClientCreationResult = test::read_body_json(resp).await; let client_id = get_json_val_str(creation_result.client.id); let url = Some("https://modrinth.com".to_string()); let description = Some("test description".to_string()); let edited_redirect_uris = vec![ redirect_uris[0].clone(), "https://modrinth.com/b".to_string(), ]; let edit = OAuthClientEdit { name: None, max_scopes: None, redirect_uris: Some(edited_redirect_uris.clone()), url: Some(url.clone()), description: Some(description.clone()), }; let resp = env .api .edit_oauth_client(&client_id, edit, FRIEND_USER_PAT) .await; assert_status!(&resp, StatusCode::OK); let clients = env .api .get_user_oauth_clients(FRIEND_USER_ID, FRIEND_USER_PAT) .await; assert_eq!(1, clients.len()); assert_eq!(url, clients[0].url); assert_eq!(description, clients[0].description); assert_eq!(client_name, clients[0].name); assert_eq!(2, clients[0].redirect_uris.len()); assert_eq!(edited_redirect_uris[0], clients[0].redirect_uris[0].uri); assert_eq!(edited_redirect_uris[1], clients[0].redirect_uris[1].uri); }) .await; } #[actix_rt::test] async fn create_oauth_client_with_restricted_scopes_fails() { with_test_environment(None, |env: TestEnvironment| async move { let resp = env .api .add_oauth_client( "test_client".to_string(), Scopes::restricted(), vec!["https://modrinth.com".to_string()], FRIEND_USER_PAT, ) .await; assert_status!(&resp, StatusCode::BAD_REQUEST); }) .await; } #[actix_rt::test] async fn get_oauth_client_for_client_creator_succeeds() { with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, .. } = env.dummy.oauth_client_alpha.clone(); let resp = env .api .get_oauth_client(client_id.clone(), USER_USER_PAT) .await; assert_status!(&resp, StatusCode::OK); let client: OAuthClient = test::read_body_json(resp).await; assert_eq!(get_json_val_str(client.id), client_id); }) .await; } #[actix_rt::test] async fn can_delete_oauth_client() { with_test_environment(None, |env: TestEnvironment| async move { let client_id = env.dummy.oauth_client_alpha.client_id.clone(); let resp = env.api.delete_oauth_client(&client_id, USER_USER_PAT).await; assert_status!(&resp, StatusCode::NO_CONTENT); let clients = env .api .get_user_oauth_clients(USER_USER_ID, USER_USER_PAT) .await; assert_eq!(0, clients.len()); }) .await; } #[actix_rt::test] async fn delete_oauth_client_after_issuing_access_tokens_revokes_tokens() { with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, .. } = env.dummy.oauth_client_alpha.clone(); let access_token = env .api .complete_full_authorize_flow( &client_id, &client_secret, Some("NOTIFICATION_READ"), None, None, USER_USER_PAT, ) .await; env.api.delete_oauth_client(&client_id, USER_USER_PAT).await; env.assert_read_notifications_status( USER_USER_ID, Some(&access_token), StatusCode::UNAUTHORIZED, ) .await; }) .await; } #[actix_rt::test] async fn can_list_user_oauth_authorizations() { with_test_environment(None, |env: TestEnvironment| async move { let DummyOAuthClientAlpha { client_id, client_secret, .. } = env.dummy.oauth_client_alpha.clone(); env.api .complete_full_authorize_flow( &client_id, &client_secret, None, None, None, USER_USER_PAT, ) .await; let authorizations = env.api.get_user_oauth_authorizations(USER_USER_PAT).await; assert_eq!(1, authorizations.len()); assert_eq!(USER_USER_ID_PARSED, authorizations[0].user_id.0 as i64); }) .await; }