feat: test web ui login handlers with mocks
This commit is contained in:
parent
36f1c1e0f4
commit
96ccb47aa8
|
@ -46,8 +46,6 @@ impl RequestAuthorizationInterface for RequestAuthorizationHandler {
|
|||
self.generate_random_string.clone(),
|
||||
);
|
||||
|
||||
log::info!("service found");
|
||||
|
||||
let cmd = RequestAuthorizationCommand::new_command(forge_name)?;
|
||||
let auth_page = service.request_authorization(cmd).await?;
|
||||
Ok(HttpResponse::Found()
|
||||
|
|
|
@ -5,18 +5,19 @@ use actix_web::{get, post, web, HttpResponse};
|
|||
use url::Url;
|
||||
|
||||
use crate::auth::adapter::input::web::routes::RoutesRepository;
|
||||
use crate::auth::adapter::out::forge::SupportedForges;
|
||||
use crate::auth::adapter::out::forge::{
|
||||
forge_repository::ForgeRepositoryInterface, SupportedForges,
|
||||
};
|
||||
use crate::auth::application::port::input::ui::{errors::*, login::RequestAuthorizationInterface};
|
||||
use crate::auth::application::port::out::db::save_oauth_state::SaveOAuthState;
|
||||
use crate::utils::random_string::GenerateRandomStringInterface;
|
||||
use crate::ForgeRepository;
|
||||
|
||||
use super::template::{LoginCtxFactory, LoginPageInterface};
|
||||
|
||||
#[get("/login")]
|
||||
#[tracing::instrument(name = "login page handler", skip(forges, routes, template))]
|
||||
async fn login_page(
|
||||
forges: web::Data<Arc<ForgeRepository>>,
|
||||
forges: web::Data<Arc<dyn ForgeRepositoryInterface>>,
|
||||
routes: web::Data<Arc<RoutesRepository>>,
|
||||
template: web::Data<Arc<dyn LoginPageInterface>>,
|
||||
) -> InUIResult<HttpResponse> {
|
||||
|
@ -29,16 +30,16 @@ async fn login_page(
|
|||
|
||||
#[post("/oauth/forgejo/login")]
|
||||
async fn request_oauth_authorization_forgejo(
|
||||
forges: web::Data<Arc<ForgeRepository>>,
|
||||
forges: web::Data<Arc<dyn ForgeRepositoryInterface>>,
|
||||
save_oauth_state_adapter: web::Data<Arc<dyn SaveOAuthState>>,
|
||||
routes: web::Data<Arc<RoutesRepository>>,
|
||||
generate_random_string: web::Data<Arc<dyn GenerateRandomStringInterface>>,
|
||||
routes: web::Data<Arc<RoutesRepository>>,
|
||||
settings: web::Data<crate::settings::Settings>,
|
||||
) -> InUIResult<HttpResponse> {
|
||||
let oauth_auth_req_uri_adapter = &forges
|
||||
.get_forge(&SupportedForges::Forgejo)
|
||||
.get_forge_factory(&SupportedForges::Forgejo)
|
||||
.unwrap()
|
||||
.oauth_auth_req_uri_adapter;
|
||||
.get_oauth_auth_req_uri_adapter();
|
||||
|
||||
let process_authorization_response_redirect_uri = Url::parse(&format!(
|
||||
"{}://{}{}",
|
||||
|
@ -46,7 +47,10 @@ async fn request_oauth_authorization_forgejo(
|
|||
&settings.server.domain,
|
||||
&routes.process_oauth_authorization_response(&SupportedForges::Forgejo)
|
||||
))
|
||||
.map_err(|_| InUIError::InternalServerError)?;
|
||||
.map_err(|_| {
|
||||
println!("mistake");
|
||||
InUIError::InternalServerError
|
||||
})?;
|
||||
|
||||
let web_adapter = super::adapter::RequestAuthorizationHandler::new(
|
||||
save_oauth_state_adapter.as_ref().to_owned(),
|
||||
|
@ -68,26 +72,34 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use actix_web::http::{header, StatusCode};
|
||||
use actix_web::{http::header::ContentType, test, App};
|
||||
|
||||
use crate::auth::adapter::input::web::login::template::load_templates;
|
||||
use crate::auth::adapter::out::forge::forgejo::Forgejo;
|
||||
use crate::auth::adapter::out::forge::forge_factory::{
|
||||
ForgeAdapterFactoryInterface, MockForgeAdapterFactoryInterface,
|
||||
};
|
||||
use crate::auth::adapter::out::forge::forge_repository::MockForgeRepositoryInterface;
|
||||
use crate::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
|
||||
use crate::auth::application::port::out::{
|
||||
db::save_oauth_state::MockSaveOAuthState, forge::oauth_auth_req_uri::MockOAuthAuthReqUri,
|
||||
};
|
||||
use crate::utils::random_string::*;
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_get_login_page() {
|
||||
let settings = crate::settings::Settings::new().unwrap();
|
||||
async fn test_login_page_handler() {
|
||||
let mut mock_forges = MockForgeRepositoryInterface::default();
|
||||
mock_forges
|
||||
.expect_get_supported_forges()
|
||||
.return_const(vec![SupportedForges::Forgejo])
|
||||
.times(1);
|
||||
let mock_forges: Arc<dyn ForgeRepositoryInterface> = Arc::new(mock_forges);
|
||||
|
||||
let forgejo = Forgejo::new(
|
||||
settings.forges.forgejo.url.clone(),
|
||||
settings.forges.forgejo.client_id.clone(),
|
||||
settings.forges.forgejo.client_secret.clone(),
|
||||
);
|
||||
let forges = ForgeRepository::new(forgejo);
|
||||
let routes = RoutesRepository::default();
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(web::Data::new(Arc::new(forges.clone())))
|
||||
.app_data(web::Data::new(mock_forges))
|
||||
.app_data(web::Data::new(Arc::new(routes.clone())))
|
||||
.configure(load_templates)
|
||||
.service(login_page),
|
||||
|
@ -102,4 +114,91 @@ mod tests {
|
|||
println!("{}", resp.status());
|
||||
assert!(resp.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
async fn test_ui_handler_request_oauth_authorization_forgejo() {
|
||||
let random_string = "foorand";
|
||||
let settings = crate::settings::Settings::new().unwrap();
|
||||
|
||||
let url = Url::parse("http://test_ui_handler_request_oauth_authorization_forgejo").unwrap();
|
||||
let mut redirect_uri = url.clone();
|
||||
redirect_uri.set_query(Some(&format!("state={random_string}")));
|
||||
|
||||
let mock_random_generate_string: Arc<dyn GenerateRandomStringInterface> = {
|
||||
let mut mock_random_generate_string = MockGenerateRandomStringInterface::new();
|
||||
mock_random_generate_string
|
||||
.expect_get_random()
|
||||
.times(1)
|
||||
.return_const(random_string.to_string());
|
||||
Arc::new(mock_random_generate_string)
|
||||
};
|
||||
|
||||
let mock_oauth_req_uri: Arc<dyn OAuthAuthReqUri> = {
|
||||
let r = redirect_uri.clone();
|
||||
let mut mock_oauth_req_uri = MockOAuthAuthReqUri::new();
|
||||
mock_oauth_req_uri
|
||||
.expect_oauth_auth_req_uri()
|
||||
.times(1)
|
||||
.returning(move |_, _| Ok(r.clone()));
|
||||
Arc::new(mock_oauth_req_uri)
|
||||
};
|
||||
|
||||
let mock_save_oauth_state: Arc<dyn SaveOAuthState> = {
|
||||
let mut mock_save_oauth_state = MockSaveOAuthState::new();
|
||||
mock_save_oauth_state
|
||||
.expect_save_oauth_state()
|
||||
.times(1)
|
||||
.returning(|_, _, _| Ok(()));
|
||||
Arc::new(mock_save_oauth_state)
|
||||
};
|
||||
|
||||
let mock_forges: Arc<dyn ForgeRepositoryInterface> = {
|
||||
let mut mock_forge_factory = MockForgeAdapterFactoryInterface::default();
|
||||
let a = mock_oauth_req_uri.clone();
|
||||
mock_forge_factory
|
||||
.expect_get_oauth_auth_req_uri_adapter()
|
||||
.times(1)
|
||||
.returning(move || a.clone());
|
||||
let mock_forge_factory: Arc<dyn ForgeAdapterFactoryInterface> =
|
||||
Arc::new(mock_forge_factory);
|
||||
|
||||
let mut mock_forges = MockForgeRepositoryInterface::default();
|
||||
mock_forges
|
||||
.expect_get_forge_factory()
|
||||
.times(1)
|
||||
.returning(move |_| Some(mock_forge_factory.clone()));
|
||||
|
||||
Arc::new(mock_forges)
|
||||
};
|
||||
|
||||
let routes = RoutesRepository::default();
|
||||
|
||||
let app = test::init_service(
|
||||
App::new()
|
||||
.app_data(web::Data::new(mock_save_oauth_state.clone()))
|
||||
.wrap(tracing_actix_web::TracingLogger::default())
|
||||
.app_data(web::Data::new(mock_random_generate_string))
|
||||
.app_data(web::Data::new(mock_forges))
|
||||
.app_data(web::Data::new(Arc::new(routes.clone())))
|
||||
.app_data(web::Data::new(settings.clone()))
|
||||
.service(request_oauth_authorization_forgejo),
|
||||
)
|
||||
.await;
|
||||
|
||||
let req = test::TestRequest::post()
|
||||
.uri("/oauth/forgejo/login")
|
||||
.insert_header(ContentType::html())
|
||||
.to_request();
|
||||
let resp = test::call_service(&app, req).await;
|
||||
let status = resp.status();
|
||||
assert_eq!(status, StatusCode::FOUND);
|
||||
assert_eq!(
|
||||
resp.headers()
|
||||
.get(header::LOCATION)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap(),
|
||||
redirect_uri.as_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,9 @@ pub mod out;
|
|||
|
||||
use crate::settings;
|
||||
use out::db::DBAdapter;
|
||||
use out::forge::{forgejo::Forgejo, ForgeRepository};
|
||||
use out::forge::{forge_repository::ForgeRepository, forgejo::Forgejo};
|
||||
|
||||
use self::out::forge::forge_repository::ForgeRepositoryInterface;
|
||||
|
||||
pub fn load_adapters(
|
||||
pool: PgPool,
|
||||
|
@ -19,11 +21,11 @@ pub fn load_adapters(
|
|||
settings.forges.forgejo.client_id.clone(),
|
||||
settings.forges.forgejo.client_secret.clone(),
|
||||
);
|
||||
let forges = ForgeRepository::new(forgejo);
|
||||
let forges: Arc<dyn ForgeRepositoryInterface> = Arc::new(ForgeRepository::new(forgejo));
|
||||
|
||||
let f = move |cfg: &mut web::ServiceConfig| {
|
||||
cfg.app_data(web::Data::new(Arc::new(DBAdapter::new(pool))));
|
||||
cfg.app_data(web::Data::new(Arc::new(forges.clone())));
|
||||
cfg.app_data(web::Data::new(forges.clone()));
|
||||
cfg.configure(input::web::load_ctx());
|
||||
};
|
||||
|
||||
|
|
|
@ -1,57 +1,12 @@
|
|||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use derive_more::Display;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::auth::application::port::out::forge::oauth_auth_req_uri::OAuthAuthReqUri;
|
||||
|
||||
use self::forgejo::Forgejo;
|
||||
|
||||
pub mod forge_factory;
|
||||
pub mod forge_repository;
|
||||
pub mod forgejo;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ForgeAdapter {
|
||||
pub oauth_auth_req_uri_adapter: Arc<dyn OAuthAuthReqUri>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct ForgeRepository {
|
||||
forges: HashMap<SupportedForges, ForgeAdapter>,
|
||||
}
|
||||
|
||||
impl ForgeRepository {
|
||||
fn add_forge(&mut self, name: SupportedForges, forge_factory: ForgeAdapter) {
|
||||
self.forges.insert(name, forge_factory);
|
||||
}
|
||||
|
||||
pub fn get_supported_forge_str(&self) -> Vec<String> {
|
||||
self.forges
|
||||
.clone()
|
||||
.into_keys()
|
||||
.map(|v| v.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn get_supported_forges(&self) -> Vec<SupportedForges> {
|
||||
self.forges.clone().into_keys().collect()
|
||||
}
|
||||
|
||||
pub fn get_forge(&self, name: &SupportedForges) -> Option<&ForgeAdapter> {
|
||||
self.forges.get(name)
|
||||
}
|
||||
|
||||
pub fn new(forgejo: Forgejo) -> Self {
|
||||
let forgejo_adapter = ForgeAdapter {
|
||||
oauth_auth_req_uri_adapter: Arc::new(forgejo),
|
||||
};
|
||||
let mut s = Self::default();
|
||||
s.add_forge(SupportedForges::Forgejo, forgejo_adapter);
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Display, Clone, Hash, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum SupportedForges {
|
||||
|
|
|
@ -8,11 +8,6 @@ mod db;
|
|||
mod settings;
|
||||
mod utils;
|
||||
|
||||
pub use crate::auth::adapter::out::{
|
||||
db::DBAdapter,
|
||||
forge::{forgejo::Forgejo, ForgeRepository},
|
||||
};
|
||||
|
||||
#[actix_web::main]
|
||||
async fn main() {
|
||||
let settings = settings::Settings::new().unwrap();
|
||||
|
|
Loading…
Reference in a new issue