1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-29 22:01:14 +03:00

storage-pg: add tests for most remaining repositories

Also fixes all the list_paginated() repository methods
This commit is contained in:
Quentin Gliech
2023-01-26 15:51:53 +01:00
parent 3f4ad789bf
commit 0bf1a1998e
5 changed files with 161 additions and 5 deletions

View File

@ -35,11 +35,12 @@ mod tests {
CompatAccessTokenRepository, CompatRefreshTokenRepository, CompatSessionRepository,
},
user::UserRepository,
Clock, Repository, RepositoryAccess,
Clock, Pagination, Repository, RepositoryAccess,
};
use rand::SeedableRng;
use rand_chacha::ChaChaRng;
use sqlx::PgPool;
use ulid::Ulid;
use crate::PgRepository;
@ -323,4 +324,126 @@ mod tests {
repo.save().await.unwrap();
}
#[sqlx::test(migrator = "crate::MIGRATOR")]
async fn test_compat_sso_login_repository(pool: PgPool) {
let mut rng = ChaChaRng::seed_from_u64(42);
let clock = MockClock::default();
let mut repo = PgRepository::from_pool(&pool).await.unwrap().boxed();
// Create a user
let user = repo
.user()
.add(&mut rng, &clock, "john".to_owned())
.await
.unwrap();
// Lookup an unknown SSO login
let login = repo.compat_sso_login().lookup(Ulid::nil()).await.unwrap();
assert_eq!(login, None);
// Lookup an unknown login token
let login = repo
.compat_sso_login()
.find_by_token("login-token")
.await
.unwrap();
assert_eq!(login, None);
// Start a new SSO login
let login = repo
.compat_sso_login()
.add(
&mut rng,
&clock,
"login-token".to_owned(),
"https://example.com/callback".parse().unwrap(),
)
.await
.unwrap();
assert!(login.is_pending());
// Lookup the login by ID
let login_lookup = repo
.compat_sso_login()
.lookup(login.id)
.await
.unwrap()
.expect("login not found");
assert_eq!(login_lookup, login);
// Find the login by token
let login_lookup = repo
.compat_sso_login()
.find_by_token("login-token")
.await
.unwrap()
.expect("login not found");
assert_eq!(login_lookup, login);
// Exchanging before fulfilling should not work
// Note: It should also not poison the SQL transaction
let res = repo
.compat_sso_login()
.exchange(&clock, login.clone())
.await;
assert!(res.is_err());
// Start a compat session for that user
let device = Device::generate(&mut rng);
let session = repo
.compat_session()
.add(&mut rng, &clock, &user, device)
.await
.unwrap();
// Associate the login with the session
let login = repo
.compat_sso_login()
.fulfill(&clock, login, &session)
.await
.unwrap();
assert!(login.is_fulfilled());
// Fulfilling again should not work
// Note: It should also not poison the SQL transaction
let res = repo
.compat_sso_login()
.fulfill(&clock, login.clone(), &session)
.await;
assert!(res.is_err());
// Exchange that login
let login = repo
.compat_sso_login()
.exchange(&clock, login)
.await
.unwrap();
assert!(login.is_exchanged());
// Exchange again should not work
// Note: It should also not poison the SQL transaction
let res = repo
.compat_sso_login()
.exchange(&clock, login.clone())
.await;
assert!(res.is_err());
// Fulfilling after exchanging should not work
// Note: It should also not poison the SQL transaction
let res = repo
.compat_sso_login()
.fulfill(&clock, login.clone(), &session)
.await;
assert!(res.is_err());
// List the logins for the user
let logins = repo
.compat_sso_login()
.list_paginated(&user, Pagination::first(10))
.await
.unwrap();
assert!(!logins.has_next_page);
assert_eq!(logins.edges, vec![login]);
}
}

View File

@ -323,12 +323,12 @@ impl<'c> CompatSsoLoginRepository for PgCompatSsoLoginRepository<'c> {
, cl.compat_session_id
FROM compat_sso_logins cl
INNER JOIN compat_sessions ON compat_session_id
INNER JOIN compat_sessions cs USING (compat_session_id)
"#,
);
query
.push(" WHERE user_id = ")
.push(" WHERE cs.user_id = ")
.push_bind(Uuid::from(user.id))
.generate_pagination("cl.compat_sso_login_id", pagination);

View File

@ -176,6 +176,29 @@ mod tests {
.await
.unwrap();
// Lookup the consent the user gave to the client
let consent = repo
.oauth2_client()
.get_consent_for_user(&client, &user)
.await
.unwrap();
assert!(consent.is_empty());
// Give consent to the client
let scope = Scope::from_iter([OPENID]);
repo.oauth2_client()
.give_consent_for_user(&mut rng, &clock, &client, &user, &scope)
.await
.unwrap();
// Lookup the consent the user gave to the client
let consent = repo
.oauth2_client()
.get_consent_for_user(&client, &user)
.await
.unwrap();
assert_eq!(scope, consent);
// Lookup a non-existing session
let session = repo.oauth2_session().lookup(Ulid::nil()).await.unwrap();
assert_eq!(session, None);

View File

@ -249,7 +249,7 @@ impl<'c> UserEmailRepository for PgUserEmailRepository<'c> {
query
.push(" WHERE user_id = ")
.push_bind(Uuid::from(user.id))
.generate_pagination("ue.user_email_id", pagination);
.generate_pagination("user_email_id", pagination);
let edges: Vec<UserEmailLookup> = query
.build_query_as()

View File

@ -16,7 +16,7 @@ use chrono::Duration;
use mas_storage::{
clock::MockClock,
user::{BrowserSessionRepository, UserEmailRepository, UserPasswordRepository, UserRepository},
Repository, RepositoryAccess,
Pagination, Repository, RepositoryAccess,
};
use rand::SeedableRng;
use rand_chacha::ChaChaRng;
@ -230,6 +230,16 @@ async fn test_user_email_repo(pool: PgPool) {
.unwrap()
.is_some());
// Listing the user emails should work
let emails = repo
.user_email()
.list_paginated(&user, Pagination::first(10))
.await
.unwrap();
assert!(!emails.has_next_page);
assert_eq!(emails.edges.len(), 1);
assert_eq!(emails.edges[0], user_email);
// Deleting the user email should work
repo.user_email().remove(user_email).await.unwrap();
assert_eq!(repo.user_email().count(&user).await.unwrap(), 0);