Add tests for count=false and count=only

This commit is contained in:
Quentin Gliech
2025-09-29 18:47:57 +02:00
parent 39fc59deb2
commit eca3ec4171
8 changed files with 1137 additions and 0 deletions

View File

@@ -471,5 +471,140 @@ mod tests {
}
}
"#);
// Test count=false
let request = Request::get("/api/admin/v1/compat-sessions?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "compat-session",
"id": "01FSHNB530AAPR7PEV8KNBZD5Y",
"attributes": {
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"device_id": "LoieH5Iecx",
"user_session_id": null,
"redirect_uri": null,
"created_at": "2022-01-16T14:41:00Z",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null,
"finished_at": null,
"human_name": null
},
"links": {
"self": "/api/admin/v1/compat-sessions/01FSHNB530AAPR7PEV8KNBZD5Y"
}
},
{
"type": "compat-session",
"id": "01FSHNCZP0PPF7X0EVMJNECPZW",
"attributes": {
"user_id": "01FSHNB530AJ6AC5HQ9X6H4RP4",
"device_id": "ZXyvelQWW9",
"user_session_id": null,
"redirect_uri": null,
"created_at": "2022-01-16T14:42:00Z",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null,
"finished_at": "2022-01-16T14:43:00Z",
"human_name": null
},
"links": {
"self": "/api/admin/v1/compat-sessions/01FSHNCZP0PPF7X0EVMJNECPZW"
}
}
],
"links": {
"self": "/api/admin/v1/compat-sessions?count=false&page[first]=10",
"first": "/api/admin/v1/compat-sessions?count=false&page[first]=10",
"last": "/api/admin/v1/compat-sessions?count=false&page[last]=10"
}
}
"#);
// Test count=only
let request = Request::get("/api/admin/v1/compat-sessions?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/compat-sessions?count=only"
}
}
"#);
// Test count=false with filtering
let request = Request::get(format!(
"/api/admin/v1/compat-sessions?count=false&filter[user]={}",
alice.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "compat-session",
"id": "01FSHNB530AAPR7PEV8KNBZD5Y",
"attributes": {
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"device_id": "LoieH5Iecx",
"user_session_id": null,
"redirect_uri": null,
"created_at": "2022-01-16T14:41:00Z",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null,
"finished_at": null,
"human_name": null
},
"links": {
"self": "/api/admin/v1/compat-sessions/01FSHNB530AAPR7PEV8KNBZD5Y"
}
}
],
"links": {
"self": "/api/admin/v1/compat-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"first": "/api/admin/v1/compat-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"last": "/api/admin/v1/compat-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request =
Request::get("/api/admin/v1/compat-sessions?count=only&filter[status]=active")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/compat-sessions?filter[status]=active&count=only"
}
}
"#);
}
}

View File

@@ -381,5 +381,61 @@ mod tests {
}
}
"#);
// Test count=false
let request = Request::get("/api/admin/v1/oauth2-sessions?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "oauth2-session",
"id": "01FSHN9AG0MKGTBNZ16RDR3PVY",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"finished_at": null,
"user_id": null,
"user_session_id": null,
"client_id": "01FSHN9AG0FAQ50MT1E9FFRPZR",
"scope": "urn:mas:admin",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null,
"human_name": null
},
"links": {
"self": "/api/admin/v1/oauth2-sessions/01FSHN9AG0MKGTBNZ16RDR3PVY"
}
}
],
"links": {
"self": "/api/admin/v1/oauth2-sessions?count=false&page[first]=10",
"first": "/api/admin/v1/oauth2-sessions?count=false&page[first]=10",
"last": "/api/admin/v1/oauth2-sessions?count=false&page[last]=10"
}
}
"#);
// Test count=only
let request = Request::get("/api/admin/v1/oauth2-sessions?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/oauth2-sessions?count=only"
}
}
"#);
}
}

View File

@@ -517,5 +517,155 @@ mod tests {
}
}
"###);
// Test count=false
let request = Request::get("/api/admin/v1/upstream-oauth-links?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r###"
{
"data": [
{
"type": "upstream-oauth-link",
"id": "01FSHN9AG0AQZQP8DX40GD59PW",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"provider_id": "01FSHN9AG09NMZYX8MFYH578R9",
"subject": "subject1",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"human_account_name": "alice@acme"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links/01FSHN9AG0AQZQP8DX40GD59PW"
}
},
{
"type": "upstream-oauth-link",
"id": "01FSHN9AG0PJZ6DZNTAA1XKPT4",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"provider_id": "01FSHN9AG09NMZYX8MFYH578R9",
"subject": "subject3",
"user_id": "01FSHN9AG0AJ6AC5HQ9X6H4RP4",
"human_account_name": "bob@acme"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links/01FSHN9AG0PJZ6DZNTAA1XKPT4"
}
},
{
"type": "upstream-oauth-link",
"id": "01FSHN9AG0QHEHKX2JNQ2A2D07",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"provider_id": "01FSHN9AG0KEPHYQQXW9XPTX6Z",
"subject": "subject2",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"human_account_name": "alice@example"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links/01FSHN9AG0QHEHKX2JNQ2A2D07"
}
}
],
"links": {
"self": "/api/admin/v1/upstream-oauth-links?count=false&page[first]=10",
"first": "/api/admin/v1/upstream-oauth-links?count=false&page[first]=10",
"last": "/api/admin/v1/upstream-oauth-links?count=false&page[last]=10"
}
}
"###);
// Test count=only
let request = Request::get("/api/admin/v1/upstream-oauth-links?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r###"
{
"meta": {
"count": 3
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links?count=only"
}
}
"###);
// Test count=false with filtering
let request = Request::get(format!(
"/api/admin/v1/upstream-oauth-links?count=false&filter[user]={}",
alice.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "upstream-oauth-link",
"id": "01FSHN9AG0AQZQP8DX40GD59PW",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"provider_id": "01FSHN9AG09NMZYX8MFYH578R9",
"subject": "subject1",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"human_account_name": "alice@acme"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links/01FSHN9AG0AQZQP8DX40GD59PW"
}
},
{
"type": "upstream-oauth-link",
"id": "01FSHN9AG0QHEHKX2JNQ2A2D07",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"provider_id": "01FSHN9AG0KEPHYQQXW9XPTX6Z",
"subject": "subject2",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"human_account_name": "alice@example"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links/01FSHN9AG0QHEHKX2JNQ2A2D07"
}
}
],
"links": {
"self": "/api/admin/v1/upstream-oauth-links?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"first": "/api/admin/v1/upstream-oauth-links?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"last": "/api/admin/v1/upstream-oauth-links?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request = Request::get(format!(
"/api/admin/v1/upstream-oauth-links?count=only&filter[provider]={}",
provider1.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/upstream-oauth-links?filter[provider]=01FSHN9AG09NMZYX8MFYH578R9&count=only"
}
}
"#);
}
}

View File

@@ -565,4 +565,162 @@ mod tests {
let response = state.request(request).await;
response.assert_status(StatusCode::BAD_REQUEST);
}
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
async fn test_count_parameter(pool: PgPool) {
setup();
let mut state = TestState::from_pool(pool).await.unwrap();
let admin_token = state.token_with_scope("urn:mas:admin").await;
create_test_providers(&mut state).await;
// Test count=false
let request = Request::get("/api/admin/v1/upstream-oauth-providers?count=false")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json::<serde_json::Value>();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "upstream-oauth-provider",
"id": "01FSHN9AG07HNEZXNQM2KNBNF6",
"attributes": {
"issuer": "https://appleid.apple.com",
"human_name": "Apple ID",
"brand_name": "apple",
"created_at": "2022-01-16T14:40:00Z",
"disabled_at": "2022-01-16T14:40:00Z"
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers/01FSHN9AG07HNEZXNQM2KNBNF6"
}
},
{
"type": "upstream-oauth-provider",
"id": "01FSHN9AG09AVTNSQFMSR34AJC",
"attributes": {
"issuer": "https://login.microsoftonline.com/common/v2.0",
"human_name": "Microsoft",
"brand_name": "microsoft",
"created_at": "2022-01-16T14:40:00Z",
"disabled_at": null
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers/01FSHN9AG09AVTNSQFMSR34AJC"
}
},
{
"type": "upstream-oauth-provider",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"issuer": "https://accounts.google.com",
"human_name": "Google",
"brand_name": "google",
"created_at": "2022-01-16T14:40:00Z",
"disabled_at": null
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/upstream-oauth-providers?count=false&page[first]=10",
"first": "/api/admin/v1/upstream-oauth-providers?count=false&page[first]=10",
"last": "/api/admin/v1/upstream-oauth-providers?count=false&page[last]=10"
}
}
"#);
// Test count=only
let request = Request::get("/api/admin/v1/upstream-oauth-providers?count=only")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json::<serde_json::Value>();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 3
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers?count=only"
}
}
"#);
// Test count=false with filtering
let request =
Request::get("/api/admin/v1/upstream-oauth-providers?count=false&filter[enabled]=true")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json::<serde_json::Value>();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "upstream-oauth-provider",
"id": "01FSHN9AG09AVTNSQFMSR34AJC",
"attributes": {
"issuer": "https://login.microsoftonline.com/common/v2.0",
"human_name": "Microsoft",
"brand_name": "microsoft",
"created_at": "2022-01-16T14:40:00Z",
"disabled_at": null
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers/01FSHN9AG09AVTNSQFMSR34AJC"
}
},
{
"type": "upstream-oauth-provider",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"issuer": "https://accounts.google.com",
"human_name": "Google",
"brand_name": "google",
"created_at": "2022-01-16T14:40:00Z",
"disabled_at": null
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/upstream-oauth-providers?filter[enabled]=true&count=false&page[first]=10",
"first": "/api/admin/v1/upstream-oauth-providers?filter[enabled]=true&count=false&page[first]=10",
"last": "/api/admin/v1/upstream-oauth-providers?filter[enabled]=true&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request =
Request::get("/api/admin/v1/upstream-oauth-providers?count=only&filter[enabled]=false")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json::<serde_json::Value>();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/upstream-oauth-providers?count=only&filter[enabled]=false"
}
}
"#);
}
}

View File

@@ -335,5 +335,121 @@ mod tests {
}
}
"###);
// Test count=false
let request = Request::get("/api/admin/v1/user-emails?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r###"
{
"data": [
{
"type": "user-email",
"id": "01FSHN9AG09NMZYX8MFYH578R9",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"email": "alice@example.com"
},
"links": {
"self": "/api/admin/v1/user-emails/01FSHN9AG09NMZYX8MFYH578R9"
}
},
{
"type": "user-email",
"id": "01FSHN9AG0KEPHYQQXW9XPTX6Z",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"user_id": "01FSHN9AG0AJ6AC5HQ9X6H4RP4",
"email": "bob@example.com"
},
"links": {
"self": "/api/admin/v1/user-emails/01FSHN9AG0KEPHYQQXW9XPTX6Z"
}
}
],
"links": {
"self": "/api/admin/v1/user-emails?count=false&page[first]=10",
"first": "/api/admin/v1/user-emails?count=false&page[first]=10",
"last": "/api/admin/v1/user-emails?count=false&page[last]=10"
}
}
"###);
// Test count=only
let request = Request::get("/api/admin/v1/user-emails?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r###"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/user-emails?count=only"
}
}
"###);
// Test count=false with filtering
let request = Request::get(format!(
"/api/admin/v1/user-emails?count=false&filter[user]={}",
alice.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "user-email",
"id": "01FSHN9AG09NMZYX8MFYH578R9",
"attributes": {
"created_at": "2022-01-16T14:40:00Z",
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"email": "alice@example.com"
},
"links": {
"self": "/api/admin/v1/user-emails/01FSHN9AG09NMZYX8MFYH578R9"
}
}
],
"links": {
"self": "/api/admin/v1/user-emails?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"first": "/api/admin/v1/user-emails?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"last": "/api/admin/v1/user-emails?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request = Request::get(format!(
"/api/admin/v1/user-emails?count=only&filter[user]={}",
alice.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/user-emails?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=only"
}
}
"#);
}
}

View File

@@ -1186,4 +1186,207 @@ mod tests {
.contains("Invalid filter parameters")
);
}
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
async fn test_count_parameter(pool: PgPool) {
setup();
let mut state = TestState::from_pool(pool).await.unwrap();
let admin_token = state.token_with_scope("urn:mas:admin").await;
create_test_tokens(&mut state).await;
// Test count=false
let request = Request::get("/api/admin/v1/user-registration-tokens?count=false")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "user-registration_token",
"id": "01FSHN9AG064K8BYZXSY5G511Z",
"attributes": {
"token": "token_expired",
"valid": false,
"usage_limit": 5,
"times_used": 0,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": null,
"expires_at": "2022-01-15T14:40:00Z",
"revoked_at": null
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG064K8BYZXSY5G511Z"
}
},
{
"type": "user-registration_token",
"id": "01FSHN9AG07HNEZXNQM2KNBNF6",
"attributes": {
"token": "token_used",
"valid": true,
"usage_limit": 10,
"times_used": 1,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": "2022-01-16T14:40:00Z",
"expires_at": null,
"revoked_at": null
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG07HNEZXNQM2KNBNF6"
}
},
{
"type": "user-registration_token",
"id": "01FSHN9AG09AVTNSQFMSR34AJC",
"attributes": {
"token": "token_revoked",
"valid": false,
"usage_limit": 10,
"times_used": 0,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": null,
"expires_at": null,
"revoked_at": "2022-01-16T14:40:00Z"
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG09AVTNSQFMSR34AJC"
}
},
{
"type": "user-registration_token",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"token": "token_unused",
"valid": true,
"usage_limit": 10,
"times_used": 0,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": null,
"expires_at": null,
"revoked_at": null
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG0MZAA6S4AF7CTV32E"
}
},
{
"type": "user-registration_token",
"id": "01FSHN9AG0S3ZJD8CXQ7F11KXN",
"attributes": {
"token": "token_used_revoked",
"valid": false,
"usage_limit": 10,
"times_used": 1,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": "2022-01-16T14:40:00Z",
"expires_at": null,
"revoked_at": "2022-01-16T14:40:00Z"
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG0S3ZJD8CXQ7F11KXN"
}
}
],
"links": {
"self": "/api/admin/v1/user-registration-tokens?count=false&page[first]=10",
"first": "/api/admin/v1/user-registration-tokens?count=false&page[first]=10",
"last": "/api/admin/v1/user-registration-tokens?count=false&page[last]=10"
}
}
"#);
// Test count=only
let request = Request::get("/api/admin/v1/user-registration-tokens?count=only")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 5
},
"links": {
"self": "/api/admin/v1/user-registration-tokens?count=only"
}
}
"#);
// Test count=false with filtering
let request =
Request::get("/api/admin/v1/user-registration-tokens?count=false&filter[valid]=true")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "user-registration_token",
"id": "01FSHN9AG07HNEZXNQM2KNBNF6",
"attributes": {
"token": "token_used",
"valid": true,
"usage_limit": 10,
"times_used": 1,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": "2022-01-16T14:40:00Z",
"expires_at": null,
"revoked_at": null
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG07HNEZXNQM2KNBNF6"
}
},
{
"type": "user-registration_token",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"token": "token_unused",
"valid": true,
"usage_limit": 10,
"times_used": 0,
"created_at": "2022-01-16T14:40:00Z",
"last_used_at": null,
"expires_at": null,
"revoked_at": null
},
"links": {
"self": "/api/admin/v1/user-registration-tokens/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/user-registration-tokens?filter[valid]=true&count=false&page[first]=10",
"first": "/api/admin/v1/user-registration-tokens?filter[valid]=true&count=false&page[first]=10",
"last": "/api/admin/v1/user-registration-tokens?filter[valid]=true&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request =
Request::get("/api/admin/v1/user-registration-tokens?count=only&filter[revoked]=true")
.bearer(&admin_token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/user-registration-tokens?filter[revoked]=true&count=only"
}
}
"#);
}
}

View File

@@ -416,5 +416,127 @@ mod tests {
}
}
"###);
// Test count=false
let request = Request::get("/api/admin/v1/user-sessions?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r###"
{
"data": [
{
"type": "user-session",
"id": "01FSHNB5309NMZYX8MFYH578R9",
"attributes": {
"created_at": "2022-01-16T14:41:00Z",
"finished_at": null,
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null
},
"links": {
"self": "/api/admin/v1/user-sessions/01FSHNB5309NMZYX8MFYH578R9"
}
},
{
"type": "user-session",
"id": "01FSHNB530KEPHYQQXW9XPTX6Z",
"attributes": {
"created_at": "2022-01-16T14:41:00Z",
"finished_at": "2022-01-16T14:42:00Z",
"user_id": "01FSHNB530AJ6AC5HQ9X6H4RP4",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null
},
"links": {
"self": "/api/admin/v1/user-sessions/01FSHNB530KEPHYQQXW9XPTX6Z"
}
}
],
"links": {
"self": "/api/admin/v1/user-sessions?count=false&page[first]=10",
"first": "/api/admin/v1/user-sessions?count=false&page[first]=10",
"last": "/api/admin/v1/user-sessions?count=false&page[last]=10"
}
}
"###);
// Test count=only
let request = Request::get("/api/admin/v1/user-sessions?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r###"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/user-sessions?count=only"
}
}
"###);
// Test count=false with filtering
let request = Request::get(format!(
"/api/admin/v1/user-sessions?count=false&filter[user]={}",
alice.id
))
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "user-session",
"id": "01FSHNB5309NMZYX8MFYH578R9",
"attributes": {
"created_at": "2022-01-16T14:41:00Z",
"finished_at": null,
"user_id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"user_agent": null,
"last_active_at": null,
"last_active_ip": null
},
"links": {
"self": "/api/admin/v1/user-sessions/01FSHNB5309NMZYX8MFYH578R9"
}
}
],
"links": {
"self": "/api/admin/v1/user-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"first": "/api/admin/v1/user-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[first]=10",
"last": "/api/admin/v1/user-sessions?filter[user]=01FSHN9AG0MZAA6S4AF7CTV32E&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request = Request::get("/api/admin/v1/user-sessions?count=only&filter[status]=active")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/user-sessions?filter[status]=active&count=only"
}
}
"#);
}
}

View File

@@ -204,3 +204,200 @@ pub async fn handler(
Ok(Json(response))
}
#[cfg(test)]
mod tests {
use hyper::{Request, StatusCode};
use sqlx::PgPool;
use crate::test_utils::{RequestBuilderExt, ResponseExt, TestState, setup};
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
async fn test_list_users(pool: PgPool) {
setup();
let mut state = TestState::from_pool(pool).await.unwrap();
let token = state.token_with_scope("urn:mas:admin").await;
let mut rng = state.rng();
// Provision two users
let mut repo = state.repository().await.unwrap();
repo.user()
.add(&mut rng, &state.clock, "alice".to_owned())
.await
.unwrap();
repo.user()
.add(&mut rng, &state.clock, "bob".to_owned())
.await
.unwrap();
repo.save().await.unwrap();
// Test default behavior (count=true)
let request = Request::get("/api/admin/v1/users").bearer(&token).empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 2
},
"data": [
{
"type": "user",
"id": "01FSHN9AG0AJ6AC5HQ9X6H4RP4",
"attributes": {
"username": "bob",
"created_at": "2022-01-16T14:40:00Z",
"locked_at": null,
"deactivated_at": null,
"admin": false,
"legacy_guest": false
},
"links": {
"self": "/api/admin/v1/users/01FSHN9AG0AJ6AC5HQ9X6H4RP4"
}
},
{
"type": "user",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"username": "alice",
"created_at": "2022-01-16T14:40:00Z",
"locked_at": null,
"deactivated_at": null,
"admin": false,
"legacy_guest": false
},
"links": {
"self": "/api/admin/v1/users/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/users?page[first]=10",
"first": "/api/admin/v1/users?page[first]=10",
"last": "/api/admin/v1/users?page[last]=10"
}
}
"#);
// Test count=false
let request = Request::get("/api/admin/v1/users?count=false")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r###"
{
"data": [
{
"type": "user",
"id": "01FSHN9AG0AJ6AC5HQ9X6H4RP4",
"attributes": {
"username": "bob",
"created_at": "2022-01-16T14:40:00Z",
"locked_at": null,
"deactivated_at": null,
"admin": false,
"legacy_guest": false
},
"links": {
"self": "/api/admin/v1/users/01FSHN9AG0AJ6AC5HQ9X6H4RP4"
}
},
{
"type": "user",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"username": "alice",
"created_at": "2022-01-16T14:40:00Z",
"locked_at": null,
"deactivated_at": null,
"admin": false,
"legacy_guest": false
},
"links": {
"self": "/api/admin/v1/users/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/users?count=false&page[first]=10",
"first": "/api/admin/v1/users?count=false&page[first]=10",
"last": "/api/admin/v1/users?count=false&page[last]=10"
}
}
"###);
// Test count=only
let request = Request::get("/api/admin/v1/users?count=only")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r###"
{
"meta": {
"count": 2
},
"links": {
"self": "/api/admin/v1/users?count=only"
}
}
"###);
// Test count=false with filtering
let request = Request::get("/api/admin/v1/users?count=false&filter[search]=alice")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"data": [
{
"type": "user",
"id": "01FSHN9AG0MZAA6S4AF7CTV32E",
"attributes": {
"username": "alice",
"created_at": "2022-01-16T14:40:00Z",
"locked_at": null,
"deactivated_at": null,
"admin": false,
"legacy_guest": false
},
"links": {
"self": "/api/admin/v1/users/01FSHN9AG0MZAA6S4AF7CTV32E"
}
}
],
"links": {
"self": "/api/admin/v1/users?filter[search]=alice&count=false&page[first]=10",
"first": "/api/admin/v1/users?filter[search]=alice&count=false&page[first]=10",
"last": "/api/admin/v1/users?filter[search]=alice&count=false&page[last]=10"
}
}
"#);
// Test count=only with filtering
let request = Request::get("/api/admin/v1/users?count=only&filter[search]=alice")
.bearer(&token)
.empty();
let response = state.request(request).await;
response.assert_status(StatusCode::OK);
let body: serde_json::Value = response.json();
insta::assert_json_snapshot!(body, @r#"
{
"meta": {
"count": 1
},
"links": {
"self": "/api/admin/v1/users?filter[search]=alice&count=only"
}
}
"#);
}
}