Modrinth/apps/labrinth/tests/oauth_clients.rs
Alejandro González f84f8c1c2b
chore(clippy): enable and fix many stricter lints (#3783)
* chore(clippy): enable and fix many stricter lints

These ensure that the codebase uses more idiomatic, performant, and
concise language constructions.

* chore: make non-Clippy compiler warnings also deny by default
2025-06-14 00:10:12 +00:00

188 lines
5.7 KiB
Rust

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<ApiV3>| 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<ApiV3>| 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<ApiV3>| 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<ApiV3>| 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<ApiV3>| 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<ApiV3>| 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;
}