Axum initial setup
This commit is contained in:
parent
138886e55c
commit
08353a717f
26 changed files with 636 additions and 863 deletions
883
Cargo.lock
generated
883
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
15
Cargo.toml
15
Cargo.toml
|
@ -9,15 +9,12 @@ build = "build.rs"
|
|||
ui = ["native-windows-gui", "native-windows-derive"]
|
||||
|
||||
[dependencies]
|
||||
actix-files = { version = "0.6" }
|
||||
actix-web-httpauth = { version = "0.8" }
|
||||
ape = "0.5"
|
||||
base64 = "0.21"
|
||||
branca = "0.10.1"
|
||||
crossbeam-channel = "0.5"
|
||||
futures-util = { version = "0.3" }
|
||||
getopts = "0.2.21"
|
||||
http = "0.2.8"
|
||||
id3 = "1.7.0"
|
||||
lewton = "0.10.2"
|
||||
log = "0.4.17"
|
||||
|
@ -42,10 +39,10 @@ toml = "0.7"
|
|||
ureq = "2.7"
|
||||
url = "2.3"
|
||||
|
||||
[dependencies.actix-web]
|
||||
version = "4"
|
||||
[dependencies.axum]
|
||||
version = "0.7.5"
|
||||
default-features = false
|
||||
features = ["macros", "compress-brotli", "compress-gzip"]
|
||||
features = ["http1", "json", "tokio", "tower-log", "tracing", "query"]
|
||||
|
||||
[dependencies.image]
|
||||
version = "0.24.4"
|
||||
|
@ -76,8 +73,10 @@ embed-resource = "1.8"
|
|||
winres = "0.1"
|
||||
|
||||
[dev-dependencies]
|
||||
actix-test = "0.1.0"
|
||||
headers = "0.3"
|
||||
axum-test = "15.3"
|
||||
bytes = "1.6.1"
|
||||
headers = "0.4"
|
||||
http = "1.1.0"
|
||||
fs_extra = "1.2.0"
|
||||
|
||||
[profile.dev.package.sqlx-macros]
|
||||
|
|
|
@ -13,7 +13,7 @@ mod app;
|
|||
mod db;
|
||||
mod options;
|
||||
mod paths;
|
||||
mod service;
|
||||
mod server;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
mod ui;
|
||||
|
@ -149,7 +149,7 @@ async fn async_main(cli_options: CLIOptions, paths: paths::Paths) -> Result<(),
|
|||
|
||||
// Start server
|
||||
info!("Starting up server");
|
||||
if let Err(e) = service::launch(app) {
|
||||
if let Err(e) = server::launch(app).await {
|
||||
return Err(Error::ServiceStartup(e));
|
||||
}
|
||||
|
||||
|
|
|
@ -4,5 +4,5 @@ mod error;
|
|||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
mod actix;
|
||||
pub use actix::*;
|
||||
mod axum;
|
||||
pub use axum::*;
|
|
@ -26,7 +26,7 @@ use crate::app::{
|
|||
lastfm, playlist, settings, thumbnail, user,
|
||||
vfs::{self, MountDir},
|
||||
};
|
||||
use crate::service::{dto, error::*};
|
||||
use crate::server::{dto, error::*};
|
||||
|
||||
pub fn make_config() -> impl FnOnce(&mut ServiceConfig) + Clone {
|
||||
move |cfg: &mut ServiceConfig| {
|
48
src/server/axum.rs
Normal file
48
src/server/axum.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use axum::Router;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
mod api;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
||||
pub fn make_router(app: App) -> Router {
|
||||
Router::new()
|
||||
// move |cfg: &mut ServiceConfig| {
|
||||
// cfg.app_data(web::Data::new(app.index))
|
||||
// .app_data(web::Data::new(app.config_manager))
|
||||
// .app_data(web::Data::new(app.ddns_manager))
|
||||
// .app_data(web::Data::new(app.lastfm_manager))
|
||||
// .app_data(web::Data::new(app.playlist_manager))
|
||||
// .app_data(web::Data::new(app.settings_manager))
|
||||
// .app_data(web::Data::new(app.thumbnail_manager))
|
||||
// .app_data(web::Data::new(app.user_manager))
|
||||
// .app_data(web::Data::new(app.vfs_manager))
|
||||
// .service(
|
||||
// web::scope("/api")
|
||||
// .configure(api::make_config())
|
||||
// .wrap(NormalizePath::trim()),
|
||||
// )
|
||||
// .service(
|
||||
// actix_files::Files::new("/swagger", app.swagger_dir_path)
|
||||
// .redirect_to_slash_directory()
|
||||
// .index_file("index.html"),
|
||||
// )
|
||||
// .service(
|
||||
// actix_files::Files::new("/", app.web_dir_path)
|
||||
// .redirect_to_slash_directory()
|
||||
// .index_file("index.html"),
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
pub async fn launch(app: App) -> Result<(), std::io::Error> {
|
||||
let port = app.port;
|
||||
let router = make_router(app);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{port}")).await?;
|
||||
axum::serve(listener, router).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
0
src/server/axum/api.rs
Normal file
0
src/server/axum/api.rs
Normal file
89
src/server/axum/test.rs
Normal file
89
src/server/axum/test.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use axum::body::Bytes;
|
||||
use axum_test::TestServer;
|
||||
use http::{response::Builder, Method, Request, Response};
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::app::App;
|
||||
use crate::paths::Paths;
|
||||
use crate::server::axum::*;
|
||||
use crate::server::dto;
|
||||
use crate::server::test::TestService;
|
||||
use crate::test::*;
|
||||
|
||||
pub struct AxumTestService {
|
||||
authorization: Option<dto::Authorization>,
|
||||
server: TestServer,
|
||||
}
|
||||
|
||||
pub type ServiceType = AxumTestService;
|
||||
|
||||
impl TestService for AxumTestService {
|
||||
async fn new(test_name: &str) -> Self {
|
||||
let output_dir = prepare_test_directory(test_name);
|
||||
|
||||
let paths = Paths {
|
||||
cache_dir_path: ["test-output", test_name].iter().collect(),
|
||||
config_file_path: None,
|
||||
db_file_path: output_dir.join("db.sqlite"),
|
||||
#[cfg(unix)]
|
||||
pid_file_path: output_dir.join("polaris.pid"),
|
||||
log_file_path: None,
|
||||
swagger_dir_path: ["docs", "swagger"].iter().collect(),
|
||||
web_dir_path: ["test-data", "web"].iter().collect(),
|
||||
};
|
||||
|
||||
let app = App::new(5050, paths).await.unwrap();
|
||||
let router = make_router(app);
|
||||
let server = TestServer::new(router).unwrap();
|
||||
|
||||
AxumTestService {
|
||||
authorization: None,
|
||||
server,
|
||||
}
|
||||
}
|
||||
|
||||
async fn execute_request<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> (Builder, Option<Bytes>) {
|
||||
let url = request.uri().to_string();
|
||||
let body = request.body().clone();
|
||||
|
||||
let mut axum_request = match *request.method() {
|
||||
Method::GET => self.server.get(&url),
|
||||
Method::POST => self.server.post(&url),
|
||||
Method::PUT => self.server.put(&url),
|
||||
Method::DELETE => self.server.delete(&url),
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
|
||||
for (name, value) in request.headers() {
|
||||
axum_request = axum_request.add_header(name.clone(), value.clone());
|
||||
}
|
||||
|
||||
if let Some(ref authorization) = self.authorization {
|
||||
axum_request = axum_request.authorization_bearer(authorization.token.clone());
|
||||
}
|
||||
|
||||
let axum_response = axum_request.json(&body).await;
|
||||
|
||||
let mut response_builder = Response::builder().status(axum_response.status_code());
|
||||
let headers = response_builder.headers_mut().unwrap();
|
||||
for (name, value) in axum_response.headers().iter() {
|
||||
headers.append(name, value.clone());
|
||||
}
|
||||
|
||||
let is_success = axum_response.status_code().is_success();
|
||||
let body = if is_success {
|
||||
Some(axum_response.into_bytes())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(response_builder, body)
|
||||
}
|
||||
|
||||
fn set_authorization(&mut self, authorization: Option<dto::Authorization>) {
|
||||
self.authorization = authorization;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
use bytes::Bytes;
|
||||
use http::response::Builder;
|
||||
use http::{Request, Response, StatusCode};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -20,23 +23,45 @@ mod user;
|
|||
mod web;
|
||||
|
||||
use crate::app::index;
|
||||
use crate::service::dto;
|
||||
use crate::service::test::constants::*;
|
||||
use crate::server::dto;
|
||||
use crate::server::test::constants::*;
|
||||
|
||||
pub use crate::service::actix::test::ServiceType;
|
||||
pub use crate::server::axum::test::ServiceType;
|
||||
|
||||
pub trait TestService {
|
||||
async fn new(test_name: &str) -> Self;
|
||||
async fn fetch<T: Serialize + Clone + 'static>(&mut self, request: &Request<T>)
|
||||
-> Response<()>;
|
||||
|
||||
async fn execute_request<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> (Builder, Option<Bytes>);
|
||||
|
||||
async fn fetch<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<()> {
|
||||
let (response_builder, _body) = self.execute_request(request).await;
|
||||
response_builder.body(()).unwrap()
|
||||
}
|
||||
|
||||
async fn fetch_bytes<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<Vec<u8>>;
|
||||
) -> Response<Vec<u8>> {
|
||||
let (response_builder, body) = self.execute_request(request).await;
|
||||
response_builder
|
||||
.body(body.unwrap().deref().to_owned())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn fetch_json<T: Serialize + Clone + 'static, U: DeserializeOwned>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<U>;
|
||||
) -> Response<U> {
|
||||
let (response_builder, body) = self.execute_request(request).await;
|
||||
let body = serde_json::from_slice(&body.unwrap()).unwrap();
|
||||
response_builder.body(body).unwrap()
|
||||
}
|
||||
|
||||
async fn complete_initial_setup(&mut self) {
|
||||
let configuration = dto::Config {
|
|
@ -1,11 +1,11 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::app::index;
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn returns_api_version() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::version();
|
||||
|
@ -13,7 +13,7 @@ async fn returns_api_version() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn initial_setup_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::initial_setup();
|
||||
|
@ -42,7 +42,7 @@ async fn initial_setup_golden_path() {
|
|||
}
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn trigger_index_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -65,7 +65,7 @@ async fn trigger_index_golden_path() {
|
|||
assert_eq!(entries.len(), 3);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn trigger_index_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -74,7 +74,7 @@ async fn trigger_index_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn trigger_index_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,11 +1,11 @@
|
|||
use headers::{self, HeaderMapExt};
|
||||
use http::StatusCode;
|
||||
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn login_rejects_bad_username() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -15,7 +15,7 @@ async fn login_rejects_bad_username() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn login_rejects_bad_password() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -25,7 +25,7 @@ async fn login_rejects_bad_password() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn login_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -40,7 +40,7 @@ async fn login_golden_path() {
|
|||
assert!(!authorization.token.is_empty());
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn authentication_via_bearer_http_header_rejects_bad_token() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -53,7 +53,7 @@ async fn authentication_via_bearer_http_header_rejects_bad_token() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn authentication_via_bearer_http_header_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -74,7 +74,7 @@ async fn authentication_via_bearer_http_header_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn authentication_via_query_param_rejects_bad_token() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -88,7 +88,7 @@ async fn authentication_via_query_param_rejects_bad_token() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn authentication_via_query_param_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -2,10 +2,10 @@ use http::StatusCode;
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::app::index;
|
||||
use crate::service::test::{add_trailing_slash, constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::test::{add_trailing_slash, constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn browse_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::browse(&PathBuf::new());
|
||||
|
@ -13,7 +13,7 @@ async fn browse_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn browse_root() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -30,7 +30,7 @@ async fn browse_root() {
|
|||
assert_eq!(entries.len(), 1);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn browse_directory() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -48,7 +48,7 @@ async fn browse_directory() {
|
|||
assert_eq!(entries.len(), 5);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn browse_bad_directory() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -60,7 +60,7 @@ async fn browse_bad_directory() {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn flatten_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::flatten(&PathBuf::new());
|
||||
|
@ -68,7 +68,7 @@ async fn flatten_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn flatten_root() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -83,7 +83,7 @@ async fn flatten_root() {
|
|||
assert_eq!(entries.len(), 13);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn flatten_directory() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -98,7 +98,7 @@ async fn flatten_directory() {
|
|||
assert_eq!(entries.len(), 13);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn flatten_bad_directory() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -110,7 +110,7 @@ async fn flatten_bad_directory() {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn random_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::random();
|
||||
|
@ -118,7 +118,7 @@ async fn random_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn random_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -135,7 +135,7 @@ async fn random_golden_path() {
|
|||
assert_eq!(entries.len(), 3);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn random_with_trailing_slash() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -153,7 +153,7 @@ async fn random_with_trailing_slash() {
|
|||
assert_eq!(entries.len(), 3);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn recent_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::recent();
|
||||
|
@ -161,7 +161,7 @@ async fn recent_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn recent_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -178,7 +178,7 @@ async fn recent_golden_path() {
|
|||
assert_eq!(entries.len(), 3);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn recent_with_trailing_slash() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -196,7 +196,7 @@ async fn recent_with_trailing_slash() {
|
|||
assert_eq!(entries.len(), 3);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn search_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::search("");
|
||||
|
@ -204,7 +204,7 @@ async fn search_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn search_without_query() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -217,7 +217,7 @@ async fn search_without_query() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn search_with_query() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,10 +1,10 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_ddns_config_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::get_ddns_config();
|
||||
|
@ -18,7 +18,7 @@ async fn get_ddns_config_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_ddns_config_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -29,7 +29,7 @@ async fn get_ddns_config_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_ddns_config_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::put_ddns_config(dto::DDNSConfig {
|
||||
|
@ -47,7 +47,7 @@ async fn put_ddns_config_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_ddns_config_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,11 +1,11 @@
|
|||
use http::StatusCode;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn lastfm_scrobble_ignores_unlinked_user() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -22,7 +22,7 @@ async fn lastfm_scrobble_ignores_unlinked_user() {
|
|||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn lastfm_now_playing_ignores_unlinked_user() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -39,7 +39,7 @@ async fn lastfm_now_playing_ignores_unlinked_user() {
|
|||
assert_eq!(response.status(), StatusCode::NO_CONTENT);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn lastfm_link_token_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::lastfm_link_token();
|
||||
|
@ -47,7 +47,7 @@ async fn lastfm_link_token_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn lastfm_link_token_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,11 +1,11 @@
|
|||
use http::{header, HeaderValue, StatusCode};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::service::dto::ThumbnailSize;
|
||||
use crate::service::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::dto::ThumbnailSize;
|
||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn audio_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
|
||||
|
@ -18,7 +18,7 @@ async fn audio_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn audio_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -40,7 +40,7 @@ async fn audio_golden_path() {
|
|||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn audio_does_not_encode_content() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -69,7 +69,7 @@ async fn audio_does_not_encode_content() {
|
|||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn audio_partial_content() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -97,7 +97,7 @@ async fn audio_partial_content() {
|
|||
);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn audio_bad_path_returns_not_found() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -110,7 +110,7 @@ async fn audio_bad_path_returns_not_found() {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn thumbnail_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
|
||||
|
@ -125,7 +125,7 @@ async fn thumbnail_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn thumbnail_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -144,7 +144,7 @@ async fn thumbnail_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn thumbnail_bad_path_returns_not_found() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -159,23 +159,23 @@ async fn thumbnail_bad_path_returns_not_found() {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn thumbnail_size_default() {
|
||||
thumbnail_size(&test_name!(), None, None, 400).await;
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn thumbnail_size_small() {
|
||||
thumbnail_size(&test_name!(), Some(ThumbnailSize::Small), None, 400).await;
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
#[cfg(not(tarpaulin))]
|
||||
async fn thumbnail_size_large() {
|
||||
thumbnail_size(&test_name!(), Some(ThumbnailSize::Large), None, 1200).await;
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
#[cfg(not(tarpaulin))]
|
||||
async fn thumbnail_size_native() {
|
||||
thumbnail_size(&test_name!(), Some(ThumbnailSize::Native), None, 1423).await;
|
|
@ -1,11 +1,11 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::app::index;
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn list_playlists_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::playlists();
|
||||
|
@ -13,7 +13,7 @@ async fn list_playlists_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn list_playlists_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -25,7 +25,7 @@ async fn list_playlists_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn save_playlist_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let my_playlist = dto::SavePlaylistInput { tracks: Vec::new() };
|
||||
|
@ -34,7 +34,7 @@ async fn save_playlist_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn save_playlist_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -46,7 +46,7 @@ async fn save_playlist_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn save_playlist_large() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -61,7 +61,7 @@ async fn save_playlist_large() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_playlist_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::read_playlist(TEST_PLAYLIST_NAME);
|
||||
|
@ -69,7 +69,7 @@ async fn get_playlist_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_playlist_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -87,7 +87,7 @@ async fn get_playlist_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_playlist_bad_name_returns_not_found() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -98,7 +98,7 @@ async fn get_playlist_bad_name_returns_not_found() {
|
|||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_playlist_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::delete_playlist(TEST_PLAYLIST_NAME);
|
||||
|
@ -106,7 +106,7 @@ async fn delete_playlist_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_playlist_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -124,7 +124,7 @@ async fn delete_playlist_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_playlist_bad_name_returns_not_found() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -2,8 +2,8 @@ use http::{Method, Request};
|
|||
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::service::dto;
|
||||
use crate::{app::user, service::dto::ThumbnailSize};
|
||||
use crate::server::dto;
|
||||
use crate::{app::user, server::dto::ThumbnailSize};
|
||||
|
||||
pub fn web_index() -> Request<()> {
|
||||
Request::builder()
|
|
@ -1,10 +1,10 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::service::dto::{self, Settings};
|
||||
use crate::service::test::{protocol, ServiceType, TestService};
|
||||
use crate::server::dto::{self, Settings};
|
||||
use crate::server::test::{protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_settings_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -14,7 +14,7 @@ async fn get_settings_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_settings_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -25,7 +25,7 @@ async fn get_settings_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_settings_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -36,7 +36,7 @@ async fn get_settings_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_settings_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -45,7 +45,7 @@ async fn put_settings_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_settings_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -55,7 +55,7 @@ async fn put_settings_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_settings_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,9 +1,9 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::service::test::{add_trailing_slash, protocol, ServiceType, TestService};
|
||||
use crate::server::test::{add_trailing_slash, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn can_get_swagger_index() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::swagger_index();
|
||||
|
@ -11,7 +11,7 @@ async fn can_get_swagger_index() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn can_get_swagger_index_with_trailing_slash() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let mut request = protocol::swagger_index();
|
|
@ -2,11 +2,11 @@ use http::StatusCode;
|
|||
use std::default::Default;
|
||||
|
||||
use crate::app::user;
|
||||
use crate::service::dto;
|
||||
use crate::service::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::server::dto;
|
||||
use crate::server::test::{constants::*, protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn list_users_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -20,7 +20,7 @@ async fn list_users_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn list_users_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -30,7 +30,7 @@ async fn list_users_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn create_user_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -48,7 +48,7 @@ async fn create_user_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn create_user_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -64,7 +64,7 @@ async fn create_user_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn update_user_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -78,7 +78,7 @@ async fn update_user_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn update_user_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -89,7 +89,7 @@ async fn update_user_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn update_user_cannot_unadmin_self() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -106,7 +106,7 @@ async fn update_user_cannot_unadmin_self() {
|
|||
assert_eq!(response.status(), StatusCode::CONFLICT);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_user_requires_admin() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -120,7 +120,7 @@ async fn delete_user_requires_admin() {
|
|||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_user_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -131,7 +131,7 @@ async fn delete_user_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn delete_user_cannot_delete_self() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -141,7 +141,7 @@ async fn delete_user_cannot_delete_self() {
|
|||
assert_eq!(response.status(), StatusCode::CONFLICT);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_preferences_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::get_preferences();
|
||||
|
@ -149,7 +149,7 @@ async fn get_preferences_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn get_preferences_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
||||
|
@ -160,7 +160,7 @@ async fn get_preferences_golden_path() {
|
|||
assert_eq!(response.status(), StatusCode::OK);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_preferences_requires_auth() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::put_preferences(user::Preferences::default());
|
||||
|
@ -168,7 +168,7 @@ async fn put_preferences_requires_auth() {
|
|||
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn put_preferences_golden_path() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
service.complete_initial_setup().await;
|
|
@ -1,9 +1,9 @@
|
|||
use http::StatusCode;
|
||||
|
||||
use crate::service::test::{protocol, ServiceType, TestService};
|
||||
use crate::server::test::{protocol, ServiceType, TestService};
|
||||
use crate::test_name;
|
||||
|
||||
#[actix_web::test]
|
||||
#[tokio::test]
|
||||
async fn serves_web_client() {
|
||||
let mut service = ServiceType::new(&test_name!()).await;
|
||||
let request = protocol::web_index();
|
|
@ -1,76 +0,0 @@
|
|||
use actix_web::{
|
||||
dev::Service,
|
||||
middleware::{Compress, Logger, NormalizePath},
|
||||
web::{self, ServiceConfig},
|
||||
App as ActixApp, HttpServer,
|
||||
};
|
||||
use log::error;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
mod api;
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
||||
pub fn make_config(app: App) -> impl FnOnce(&mut ServiceConfig) + Clone {
|
||||
move |cfg: &mut ServiceConfig| {
|
||||
cfg.app_data(web::Data::new(app.index))
|
||||
.app_data(web::Data::new(app.config_manager))
|
||||
.app_data(web::Data::new(app.ddns_manager))
|
||||
.app_data(web::Data::new(app.lastfm_manager))
|
||||
.app_data(web::Data::new(app.playlist_manager))
|
||||
.app_data(web::Data::new(app.settings_manager))
|
||||
.app_data(web::Data::new(app.thumbnail_manager))
|
||||
.app_data(web::Data::new(app.user_manager))
|
||||
.app_data(web::Data::new(app.vfs_manager))
|
||||
.service(
|
||||
web::scope("/api")
|
||||
.configure(api::make_config())
|
||||
.wrap(NormalizePath::trim()),
|
||||
)
|
||||
.service(
|
||||
actix_files::Files::new("/swagger", app.swagger_dir_path)
|
||||
.redirect_to_slash_directory()
|
||||
.index_file("index.html"),
|
||||
)
|
||||
.service(
|
||||
actix_files::Files::new("/", app.web_dir_path)
|
||||
.redirect_to_slash_directory()
|
||||
.index_file("index.html"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn launch(app: App) -> Result<(), std::io::Error> {
|
||||
let address = ("0.0.0.0", app.port);
|
||||
tokio::spawn(
|
||||
HttpServer::new(move || {
|
||||
ActixApp::new()
|
||||
.wrap(Logger::default())
|
||||
.wrap_fn(|req, srv| {
|
||||
// For some reason, actix logs error as DEBUG level.
|
||||
// This logs them as ERROR level
|
||||
// See https://github.com/actix/actix-web/issues/2637
|
||||
let response_future = srv.call(req);
|
||||
async {
|
||||
let response = response_future.await?;
|
||||
if let Some(error) = response.response().error() {
|
||||
error!("{}", error);
|
||||
}
|
||||
Ok(response)
|
||||
}
|
||||
})
|
||||
.wrap(Compress::default())
|
||||
.configure(make_config(app.clone()))
|
||||
})
|
||||
.disable_signals()
|
||||
.bind(address)
|
||||
.map_err(|e| {
|
||||
error!("Error starting HTTP server: {:?}", e);
|
||||
e
|
||||
})?
|
||||
.run(),
|
||||
);
|
||||
Ok(())
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
use actix_test::TestServer;
|
||||
use actix_web::{
|
||||
middleware::{Compress, Logger},
|
||||
web::Bytes,
|
||||
App as ActixApp,
|
||||
};
|
||||
use http::{response::Builder, Method, Request, Response};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::app::App;
|
||||
use crate::paths::Paths;
|
||||
use crate::service::actix::*;
|
||||
use crate::service::dto;
|
||||
use crate::service::test::TestService;
|
||||
use crate::test::*;
|
||||
|
||||
pub struct ActixTestService {
|
||||
authorization: Option<dto::Authorization>,
|
||||
server: TestServer,
|
||||
}
|
||||
|
||||
pub type ServiceType = ActixTestService;
|
||||
|
||||
impl ActixTestService {
|
||||
async fn process_internal<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> (Builder, Option<Bytes>) {
|
||||
let url = request.uri().to_string();
|
||||
let body = request.body().clone();
|
||||
|
||||
let mut actix_request = match *request.method() {
|
||||
Method::GET => self.server.get(url),
|
||||
Method::POST => self.server.post(url),
|
||||
Method::PUT => self.server.put(url),
|
||||
Method::DELETE => self.server.delete(url),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
.timeout(std::time::Duration::from_secs(30));
|
||||
|
||||
for (name, value) in request.headers() {
|
||||
actix_request = actix_request.insert_header((name, value.clone()));
|
||||
}
|
||||
|
||||
if let Some(ref authorization) = self.authorization {
|
||||
actix_request = actix_request.bearer_auth(&authorization.token);
|
||||
}
|
||||
|
||||
let mut actix_response = actix_request.send_json(&body).await.unwrap();
|
||||
|
||||
let mut response_builder = Response::builder().status(actix_response.status());
|
||||
let headers = response_builder.headers_mut().unwrap();
|
||||
for (name, value) in actix_response.headers().iter() {
|
||||
headers.append(name, value.clone());
|
||||
}
|
||||
|
||||
let is_success = actix_response.status().is_success();
|
||||
let body = if is_success {
|
||||
Some(actix_response.body().await.unwrap())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(response_builder, body)
|
||||
}
|
||||
}
|
||||
|
||||
impl TestService for ActixTestService {
|
||||
async fn new(test_name: &str) -> Self {
|
||||
let output_dir = prepare_test_directory(test_name);
|
||||
|
||||
let paths = Paths {
|
||||
cache_dir_path: ["test-output", test_name].iter().collect(),
|
||||
config_file_path: None,
|
||||
db_file_path: output_dir.join("db.sqlite"),
|
||||
#[cfg(unix)]
|
||||
pid_file_path: output_dir.join("polaris.pid"),
|
||||
log_file_path: None,
|
||||
swagger_dir_path: ["docs", "swagger"].iter().collect(),
|
||||
web_dir_path: ["test-data", "web"].iter().collect(),
|
||||
};
|
||||
|
||||
let app = App::new(5050, paths).await.unwrap();
|
||||
|
||||
let server = actix_test::start(move || {
|
||||
let config = make_config(app.clone());
|
||||
ActixApp::new()
|
||||
.wrap(Logger::default())
|
||||
.wrap(Compress::default())
|
||||
.configure(config)
|
||||
});
|
||||
|
||||
ActixTestService {
|
||||
authorization: None,
|
||||
server,
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<()> {
|
||||
let (response_builder, _body) = self.process_internal(request).await;
|
||||
response_builder.body(()).unwrap()
|
||||
}
|
||||
|
||||
async fn fetch_bytes<T: Serialize + Clone + 'static>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<Vec<u8>> {
|
||||
let (response_builder, body) = self.process_internal(request).await;
|
||||
response_builder
|
||||
.body(body.unwrap().deref().to_owned())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn fetch_json<T: Serialize + Clone + 'static, U: DeserializeOwned>(
|
||||
&mut self,
|
||||
request: &Request<T>,
|
||||
) -> Response<U> {
|
||||
let (response_builder, body) = self.process_internal(request).await;
|
||||
let body = serde_json::from_slice(&body.unwrap()).unwrap();
|
||||
response_builder.body(body).unwrap()
|
||||
}
|
||||
|
||||
fn set_authorization(&mut self, authorization: Option<dto::Authorization>) {
|
||||
self.authorization = authorization;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue