mirror of
https://github.com/agersant/polaris
synced 2024-11-10 10:14:12 +00:00
Decoupled most tests from rocket
This commit is contained in:
parent
9ed0526075
commit
ed66200689
10 changed files with 533 additions and 670 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1547,6 +1547,7 @@ dependencies = [
|
|||
"tokio 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unix-daemonize 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
|
|
@ -42,6 +42,7 @@ simplelog = "0.7"
|
|||
thiserror = "1.0"
|
||||
time = "0.1"
|
||||
toml = "0.5"
|
||||
url = "2.1"
|
||||
|
||||
[dependencies.rocket_contrib]
|
||||
version = "0.4.2"
|
||||
|
|
|
@ -10,3 +10,19 @@ pub struct Version {
|
|||
pub struct InitialSetup {
|
||||
pub has_any_users: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct AuthCredentials {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ListPlaylistsEntry {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SavePlaylistInput {
|
||||
pub tracks: Vec<String>,
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ mod dto;
|
|||
mod error;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod test;
|
||||
|
||||
#[cfg(feature = "service-rocket")]
|
||||
mod rocket;
|
||||
|
|
|
@ -4,7 +4,6 @@ use rocket::request::{self, FromParam, FromRequest, Request};
|
|||
use rocket::response::content::Html;
|
||||
use rocket::{delete, get, post, put, routes, Outcome, State};
|
||||
use rocket_contrib::json::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::File;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
|
@ -239,21 +238,10 @@ fn trigger_index(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct AuthCredentials {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct AuthOutput {
|
||||
admin: bool,
|
||||
}
|
||||
|
||||
#[post("/auth", data = "<credentials>")]
|
||||
fn auth(
|
||||
db: State<'_, DB>,
|
||||
credentials: Json<AuthCredentials>,
|
||||
credentials: Json<dto::AuthCredentials>,
|
||||
mut cookies: Cookies<'_>,
|
||||
) -> std::result::Result<(), APIError> {
|
||||
if !user::auth(&db, &credentials.username, &credentials.password)? {
|
||||
|
@ -335,33 +323,23 @@ fn serve(db: State<'_, DB>, _auth: Auth, path: VFSPathBuf) -> Result<serve::Rang
|
|||
Ok(serve::RangeResponder::new(file))
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ListPlaylistsEntry {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[get("/playlists")]
|
||||
fn list_playlists(db: State<'_, DB>, auth: Auth) -> Result<Json<Vec<ListPlaylistsEntry>>> {
|
||||
fn list_playlists(db: State<'_, DB>, auth: Auth) -> Result<Json<Vec<dto::ListPlaylistsEntry>>> {
|
||||
let playlist_names = playlist::list_playlists(&auth.username, db.deref().deref())?;
|
||||
let playlists: Vec<ListPlaylistsEntry> = playlist_names
|
||||
let playlists: Vec<dto::ListPlaylistsEntry> = playlist_names
|
||||
.into_iter()
|
||||
.map(|p| ListPlaylistsEntry { name: p })
|
||||
.map(|p| dto::ListPlaylistsEntry { name: p })
|
||||
.collect();
|
||||
|
||||
Ok(Json(playlists))
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SavePlaylistInput {
|
||||
pub tracks: Vec<String>,
|
||||
}
|
||||
|
||||
#[put("/playlist/<name>", data = "<playlist>")]
|
||||
fn save_playlist(
|
||||
db: State<'_, DB>,
|
||||
auth: Auth,
|
||||
name: String,
|
||||
playlist: Json<SavePlaylistInput>,
|
||||
playlist: Json<dto::SavePlaylistInput>,
|
||||
) -> Result<()> {
|
||||
playlist::save_playlist(&name, &auth.username, &playlist.tracks, db.deref().deref())?;
|
||||
Ok(())
|
||||
|
|
|
@ -1,479 +0,0 @@
|
|||
use rocket::http::hyper::header::*;
|
||||
use rocket::http::uri::Uri;
|
||||
use rocket::http::Status;
|
||||
use rocket::local::Client;
|
||||
use std::{thread, time};
|
||||
|
||||
use super::api;
|
||||
use crate::config;
|
||||
use crate::ddns;
|
||||
use crate::index;
|
||||
use crate::vfs;
|
||||
|
||||
use super::test::get_test_environment;
|
||||
|
||||
const TEST_USERNAME: &str = "test_user";
|
||||
const TEST_PASSWORD: &str = "test_password";
|
||||
const TEST_MOUNT_NAME: &str = "collection";
|
||||
const TEST_MOUNT_SOURCE: &str = "test/collection";
|
||||
|
||||
fn complete_initial_setup(client: &Client) {
|
||||
let configuration = config::Config {
|
||||
album_art_pattern: None,
|
||||
prefix_url: None,
|
||||
reindex_every_n_seconds: None,
|
||||
ydns: None,
|
||||
users: Some(vec![config::ConfigUser {
|
||||
name: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
admin: true,
|
||||
}]),
|
||||
mount_dirs: Some(vec![vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into(),
|
||||
}]),
|
||||
};
|
||||
let body = serde_json::to_string(&configuration).unwrap();
|
||||
let response = client.put("/api/settings").body(&body).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
fn do_auth(client: &Client) {
|
||||
let credentials = api::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
};
|
||||
let body = serde_json::to_string(&credentials).unwrap();
|
||||
let response = client.post("/api/auth").body(body).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn settings() {
|
||||
let env = get_test_environment("api_settings.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
|
||||
{
|
||||
let response = client.get("/api/settings").dispatch();
|
||||
assert_eq!(response.status(), Status::Unauthorized);
|
||||
}
|
||||
|
||||
do_auth(client);
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/settings").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: config::Config = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(
|
||||
response_json,
|
||||
config::Config {
|
||||
album_art_pattern: Some("Folder.(jpg|png)".to_string()),
|
||||
reindex_every_n_seconds: Some(1800),
|
||||
mount_dirs: Some(vec![vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into()
|
||||
}]),
|
||||
prefix_url: None,
|
||||
users: Some(vec![config::ConfigUser {
|
||||
name: TEST_USERNAME.into(),
|
||||
password: "".into(),
|
||||
admin: true
|
||||
}]),
|
||||
ydns: Some(ddns::DDNSConfig {
|
||||
host: "".into(),
|
||||
username: "".into(),
|
||||
password: "".into()
|
||||
}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let mut configuration = config::Config {
|
||||
album_art_pattern: Some("my_pattern".to_owned()),
|
||||
reindex_every_n_seconds: Some(3600),
|
||||
mount_dirs: Some(vec![
|
||||
vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into(),
|
||||
},
|
||||
vfs::MountPoint {
|
||||
name: "more_music".into(),
|
||||
source: "test/collection".into(),
|
||||
},
|
||||
]),
|
||||
prefix_url: Some("my_prefix".to_owned()),
|
||||
users: Some(vec![
|
||||
config::ConfigUser {
|
||||
name: "test_user".into(),
|
||||
password: "some_password".into(),
|
||||
admin: true,
|
||||
},
|
||||
config::ConfigUser {
|
||||
name: "other_user".into(),
|
||||
password: "some_other_password".into(),
|
||||
admin: false,
|
||||
},
|
||||
]),
|
||||
ydns: Some(ddns::DDNSConfig {
|
||||
host: "my_host".into(),
|
||||
username: "my_username".into(),
|
||||
password: "my_password".into(),
|
||||
}),
|
||||
};
|
||||
|
||||
let body = serde_json::to_string(&configuration).unwrap();
|
||||
|
||||
configuration.users = Some(vec![
|
||||
config::ConfigUser {
|
||||
name: "test_user".into(),
|
||||
password: "".into(),
|
||||
admin: true,
|
||||
},
|
||||
config::ConfigUser {
|
||||
name: "other_user".into(),
|
||||
password: "".into(),
|
||||
admin: false,
|
||||
},
|
||||
]);
|
||||
|
||||
client.put("/api/settings").body(body).dispatch();
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/settings").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: config::Config = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json, configuration);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferences() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trigger_index() {
|
||||
let env = get_test_environment("api_trigger_index.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/random").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Directory> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 0);
|
||||
}
|
||||
|
||||
{
|
||||
let response = client.post("/api/trigger_index").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
let timeout = time::Duration::from_secs(5);
|
||||
thread::sleep(timeout);
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/random").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Directory> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn auth() {
|
||||
let env = get_test_environment("api_auth.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
|
||||
{
|
||||
let credentials = api::AuthCredentials {
|
||||
username: "garbage".into(),
|
||||
password: "garbage".into(),
|
||||
};
|
||||
let response = client
|
||||
.post("/api/auth")
|
||||
.body(serde_json::to_string(&credentials).unwrap())
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Unauthorized);
|
||||
}
|
||||
{
|
||||
let credentials = api::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: "garbage".into(),
|
||||
};
|
||||
let response = client
|
||||
.post("/api/auth")
|
||||
.body(serde_json::to_string(&credentials).unwrap())
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Unauthorized);
|
||||
}
|
||||
{
|
||||
let credentials = api::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
};
|
||||
let response = client
|
||||
.post("/api/auth")
|
||||
.body(serde_json::to_string(&credentials).unwrap())
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
assert!(response
|
||||
.cookies()
|
||||
.iter()
|
||||
.any(|cookie| cookie.name() == "username"));
|
||||
assert!(response
|
||||
.cookies()
|
||||
.iter()
|
||||
.any(|cookie| cookie.name() == "admin"));
|
||||
assert!(response
|
||||
.cookies()
|
||||
.iter()
|
||||
.any(|cookie| cookie.name() == "session"));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn browse() {
|
||||
let env = get_test_environment("api_browse.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/browse").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::CollectionFile> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 1);
|
||||
}
|
||||
|
||||
let mut next;
|
||||
{
|
||||
let mut response = client.get("/api/browse/collection").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::CollectionFile> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 2);
|
||||
|
||||
match response_json[0] {
|
||||
index::CollectionFile::Directory(ref d) => {
|
||||
next = d.path.clone();
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
// /api/browse/collection/Khemmis
|
||||
{
|
||||
let url = format!("/api/browse/{}", Uri::percent_encode(&next));
|
||||
let mut response = client.get(url).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::CollectionFile> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 1);
|
||||
match response_json[0] {
|
||||
index::CollectionFile::Directory(ref d) => {
|
||||
next = d.path.clone();
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
// /api/browse/collection/Khemmis/Hunted
|
||||
{
|
||||
let url = format!("/api/browse/{}", Uri::percent_encode(&next));
|
||||
let mut response = client.get(url).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::CollectionFile> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flatten() {
|
||||
let env = get_test_environment("api_flatten.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/flatten").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Song> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 12);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/flatten/collection").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Song> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 12);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn random() {
|
||||
let env = get_test_environment("api_random.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
let mut response = client.get("/api/random").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Directory> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recent() {
|
||||
let env = get_test_environment("api_recent.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
let mut response = client.get("/api/recent").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Directory> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn search() {
|
||||
let env = get_test_environment("api_search.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
let mut response = client.get("/api/search/door").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::CollectionFile> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 1);
|
||||
match response_json[0] {
|
||||
index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serve() {
|
||||
let env = get_test_environment("api_serve.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
{
|
||||
let mut response = client
|
||||
.get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3")
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let body = response.body().unwrap();
|
||||
let body = body.into_bytes().unwrap();
|
||||
assert_eq!(body.len(), 24_142);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client
|
||||
.get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3")
|
||||
.header(Range::bytes(100, 299))
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::PartialContent);
|
||||
let body = response.body().unwrap();
|
||||
let body = body.into_bytes().unwrap();
|
||||
assert_eq!(body.len(), 200);
|
||||
assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn playlists() {
|
||||
let env = get_test_environment("api_playlists.sqlite");
|
||||
let client = &env.client;
|
||||
complete_initial_setup(client);
|
||||
do_auth(client);
|
||||
env.update_index();
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/playlists").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<api::ListPlaylistsEntry> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 0);
|
||||
}
|
||||
|
||||
{
|
||||
let songs: Vec<index::Song>;
|
||||
{
|
||||
let mut response = client.get("/api/flatten").dispatch();
|
||||
let response_body = response.body_string().unwrap();
|
||||
songs = serde_json::from_str(&response_body).unwrap();
|
||||
}
|
||||
let my_playlist = api::SavePlaylistInput {
|
||||
tracks: songs[2..6].into_iter().map(|s| s.path.clone()).collect(),
|
||||
};
|
||||
let response = client
|
||||
.put("/api/playlist/my_playlist")
|
||||
.body(serde_json::to_string(&my_playlist).unwrap())
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/playlists").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<api::ListPlaylistsEntry> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(
|
||||
response_json,
|
||||
vec![api::ListPlaylistsEntry {
|
||||
name: "my_playlist".into()
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/playlist/my_playlist").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<index::Song> = serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 4);
|
||||
}
|
||||
|
||||
{
|
||||
let response = client.delete("/api/playlist/my_playlist").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client.get("/api/playlists").dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
let response_json: Vec<api::ListPlaylistsEntry> =
|
||||
serde_json::from_str(&response_body).unwrap();
|
||||
assert_eq!(response_json.len(), 0);
|
||||
}
|
||||
}
|
|
@ -3,7 +3,5 @@ mod serve;
|
|||
|
||||
pub mod server;
|
||||
|
||||
#[cfg(test)]
|
||||
mod api_tests;
|
||||
#[cfg(test)]
|
||||
pub mod test;
|
||||
|
|
|
@ -11,84 +11,107 @@ use std::sync::Arc;
|
|||
use super::server;
|
||||
use crate::db::DB;
|
||||
use crate::index;
|
||||
use crate::service::test::{HttpStatus, TestService};
|
||||
|
||||
pub struct TestEnvironment {
|
||||
pub client: Client,
|
||||
pub struct RocketTestService {
|
||||
client: Client,
|
||||
command_sender: Arc<index::CommandSender>,
|
||||
db: DB,
|
||||
}
|
||||
|
||||
impl TestEnvironment {
|
||||
pub fn update_index(&self) {
|
||||
index::update(&self.db).unwrap();
|
||||
pub type ServiceType = RocketTestService;
|
||||
|
||||
impl HttpStatus for Status {
|
||||
fn is_ok(&self) -> bool {
|
||||
*self == Status::Ok
|
||||
}
|
||||
|
||||
fn is_unauthorized(&self) -> bool {
|
||||
*self == Status::Unauthorized
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestEnvironment {
|
||||
impl TestService for RocketTestService {
|
||||
type Status = Status;
|
||||
|
||||
fn new(db_name: &str) -> Self {
|
||||
let mut db_path = PathBuf::new();
|
||||
db_path.push("test");
|
||||
db_path.push(format!("{}.sqlite", db_name));
|
||||
if db_path.exists() {
|
||||
fs::remove_file(&db_path).unwrap();
|
||||
}
|
||||
let db = DB::new(&db_path).unwrap();
|
||||
|
||||
let web_dir_path = PathBuf::from("web");
|
||||
let mut swagger_dir_path = PathBuf::from("docs");
|
||||
swagger_dir_path.push("swagger");
|
||||
let command_sender = index::init(db.clone());
|
||||
|
||||
let auth_secret: [u8; 32] = [0; 32];
|
||||
|
||||
let server = server::get_server(
|
||||
5050,
|
||||
&auth_secret,
|
||||
"/api",
|
||||
"/",
|
||||
&web_dir_path,
|
||||
"/swagger",
|
||||
&swagger_dir_path,
|
||||
db.clone(),
|
||||
command_sender.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
let client = Client::new(server).unwrap();
|
||||
RocketTestService {
|
||||
client,
|
||||
command_sender,
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&mut self, url: &str) -> Status {
|
||||
let client = &self.client;
|
||||
let response = client.get(url).dispatch();
|
||||
response.status()
|
||||
}
|
||||
|
||||
fn post(&mut self, url: &str) -> Status {
|
||||
let client = &self.client;
|
||||
let response = client.post(url).dispatch();
|
||||
response.status()
|
||||
}
|
||||
|
||||
fn delete(&mut self, url: &str) -> Status {
|
||||
let client = &self.client;
|
||||
let response = client.delete(url).dispatch();
|
||||
response.status()
|
||||
}
|
||||
|
||||
fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> T {
|
||||
let client = &self.client;
|
||||
let mut response = client.get(url).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
dbg!(&response_body);
|
||||
serde_json::from_str(&response_body).unwrap()
|
||||
}
|
||||
|
||||
fn put_json<T: Serialize>(&mut self, url: &str, payload: &T) {
|
||||
let client = &self.client;
|
||||
let body = serde_json::to_string(payload).unwrap();
|
||||
let response = client.put(url).body(&body).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Status {
|
||||
let client = &self.client;
|
||||
let body = serde_json::to_string(payload).unwrap();
|
||||
let response = client.post(url).body(&body).dispatch();
|
||||
response.status()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for RocketTestService {
|
||||
fn drop(&mut self) {
|
||||
self.command_sender.deref().exit().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_test_environment(db_name: &str) -> TestEnvironment {
|
||||
let mut db_path = PathBuf::new();
|
||||
db_path.push("test");
|
||||
db_path.push(db_name);
|
||||
if db_path.exists() {
|
||||
fs::remove_file(&db_path).unwrap();
|
||||
}
|
||||
let db = DB::new(&db_path).unwrap();
|
||||
|
||||
let web_dir_path = PathBuf::from("web");
|
||||
let mut swagger_dir_path = PathBuf::from("docs");
|
||||
swagger_dir_path.push("swagger");
|
||||
let command_sender = index::init(db.clone());
|
||||
|
||||
let auth_secret: [u8; 32] = [0; 32];
|
||||
|
||||
let server = server::get_server(
|
||||
5050,
|
||||
&auth_secret,
|
||||
"/api",
|
||||
"/",
|
||||
&web_dir_path,
|
||||
"/swagger",
|
||||
&swagger_dir_path,
|
||||
db.clone(),
|
||||
command_sender.clone(),
|
||||
)
|
||||
.unwrap();
|
||||
let client = Client::new(server).unwrap();
|
||||
TestEnvironment {
|
||||
client,
|
||||
command_sender,
|
||||
db,
|
||||
}
|
||||
}
|
||||
|
||||
pub type ServiceType = TestEnvironment;
|
||||
|
||||
pub async fn make_service(test_name: &str) -> TestEnvironment {
|
||||
get_test_environment(&format!("{}.sqlite", test_name))
|
||||
}
|
||||
|
||||
pub async fn get(service: &mut TestEnvironment, url: &str) {
|
||||
let client = &service.client;
|
||||
let response = client.get(url).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
||||
pub async fn get_json<T: DeserializeOwned>(service: &mut TestEnvironment, url: &str) -> T {
|
||||
let client = &service.client;
|
||||
let mut response = client.get(url).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let response_body = response.body_string().unwrap();
|
||||
serde_json::from_str(&response_body).unwrap()
|
||||
}
|
||||
|
||||
pub async fn put_json<T: Serialize>(service: &mut TestEnvironment, url: &str, payload: &T) {
|
||||
let client = &service.client;
|
||||
let body = serde_json::to_string(payload).unwrap();
|
||||
let response = client.put(url).body(&body).dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
}
|
||||
|
|
416
src/service/test.rs
Normal file
416
src/service/test.rs
Normal file
|
@ -0,0 +1,416 @@
|
|||
use function_name::named;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use url::form_urlencoded::byte_serialize;
|
||||
|
||||
use crate::service::dto;
|
||||
use crate::{config, ddns, index, vfs};
|
||||
|
||||
#[cfg(feature = "service-rocket")]
|
||||
pub use crate::service::rocket::test::ServiceType;
|
||||
|
||||
const TEST_USERNAME: &str = "test_user";
|
||||
const TEST_PASSWORD: &str = "test_password";
|
||||
const TEST_MOUNT_NAME: &str = "collection";
|
||||
const TEST_MOUNT_SOURCE: &str = "test/collection";
|
||||
|
||||
pub trait HttpStatus {
|
||||
fn is_ok(&self) -> bool;
|
||||
fn is_unauthorized(&self) -> bool;
|
||||
}
|
||||
|
||||
pub trait TestService {
|
||||
type Status: HttpStatus;
|
||||
|
||||
fn new(db_name: &str) -> Self;
|
||||
fn get(&mut self, url: &str) -> Self::Status;
|
||||
fn post(&mut self, url: &str) -> Self::Status;
|
||||
fn delete(&mut self, url: &str) -> Self::Status;
|
||||
fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> T;
|
||||
fn put_json<T: Serialize>(&mut self, url: &str, payload: &T);
|
||||
fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Self::Status;
|
||||
|
||||
fn complete_initial_setup(&mut self) {
|
||||
let configuration = config::Config {
|
||||
album_art_pattern: None,
|
||||
prefix_url: None,
|
||||
reindex_every_n_seconds: None,
|
||||
ydns: None,
|
||||
users: Some(vec![config::ConfigUser {
|
||||
name: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
admin: true,
|
||||
}]),
|
||||
mount_dirs: Some(vec![vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into(),
|
||||
}]),
|
||||
};
|
||||
self.put_json("/api/settings", &configuration);
|
||||
}
|
||||
|
||||
fn login(&mut self) {
|
||||
let credentials = dto::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
};
|
||||
self.post_json("/api/auth", &credentials);
|
||||
}
|
||||
|
||||
fn index(&mut self) {
|
||||
assert!(self.post("/api/trigger_index").is_ok());
|
||||
for _ in 1..20 {
|
||||
let entries: Vec<index::CollectionFile> = self.get_json("/api/browse");
|
||||
if entries.len() > 0 {
|
||||
return;
|
||||
}
|
||||
std::thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
panic!("index timeout");
|
||||
}
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_index() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.get("/");
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_swagger_index() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
assert!(service.get("/swagger").is_ok());
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_swagger_index_with_trailing_slash() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
assert!(service.get("/swagger/").is_ok());
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_version() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
let version: dto::Version = service.get_json("/api/version");
|
||||
assert_eq!(version, dto::Version { major: 4, minor: 0 });
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_initial_setup() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
{
|
||||
let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup");
|
||||
assert_eq!(
|
||||
initial_setup,
|
||||
dto::InitialSetup {
|
||||
has_any_users: false
|
||||
}
|
||||
);
|
||||
}
|
||||
service.complete_initial_setup();
|
||||
{
|
||||
let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup");
|
||||
assert_eq!(
|
||||
initial_setup,
|
||||
dto::InitialSetup {
|
||||
has_any_users: true
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_settings() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
|
||||
assert!(service.get("/api/settings").is_unauthorized());
|
||||
service.login();
|
||||
|
||||
{
|
||||
let configuration: config::Config = service.get_json("/api/settings");
|
||||
assert_eq!(
|
||||
configuration,
|
||||
config::Config {
|
||||
album_art_pattern: Some("Folder.(jpg|png)".to_string()),
|
||||
reindex_every_n_seconds: Some(1800),
|
||||
mount_dirs: Some(vec![vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into()
|
||||
}]),
|
||||
prefix_url: None,
|
||||
users: Some(vec![config::ConfigUser {
|
||||
name: TEST_USERNAME.into(),
|
||||
password: "".into(),
|
||||
admin: true
|
||||
}]),
|
||||
ydns: Some(ddns::DDNSConfig {
|
||||
host: "".into(),
|
||||
username: "".into(),
|
||||
password: "".into()
|
||||
}),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let mut configuration = config::Config {
|
||||
album_art_pattern: Some("my_pattern".to_owned()),
|
||||
reindex_every_n_seconds: Some(3600),
|
||||
mount_dirs: Some(vec![
|
||||
vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into(),
|
||||
},
|
||||
vfs::MountPoint {
|
||||
name: "more_music".into(),
|
||||
source: "test/collection".into(),
|
||||
},
|
||||
]),
|
||||
prefix_url: Some("my_prefix".to_owned()),
|
||||
users: Some(vec![
|
||||
config::ConfigUser {
|
||||
name: "test_user".into(),
|
||||
password: "some_password".into(),
|
||||
admin: true,
|
||||
},
|
||||
config::ConfigUser {
|
||||
name: "other_user".into(),
|
||||
password: "some_other_password".into(),
|
||||
admin: false,
|
||||
},
|
||||
]),
|
||||
ydns: Some(ddns::DDNSConfig {
|
||||
host: "my_host".into(),
|
||||
username: "my_username".into(),
|
||||
password: "my_password".into(),
|
||||
}),
|
||||
};
|
||||
|
||||
service.put_json("/api/settings", &configuration);
|
||||
|
||||
configuration.users = Some(vec![
|
||||
config::ConfigUser {
|
||||
name: "test_user".into(),
|
||||
password: "".into(),
|
||||
admin: true,
|
||||
},
|
||||
config::ConfigUser {
|
||||
name: "other_user".into(),
|
||||
password: "".into(),
|
||||
admin: false,
|
||||
},
|
||||
]);
|
||||
|
||||
let received: config::Config = service.get_json("/api/settings");
|
||||
assert_eq!(received, configuration);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_preferences() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_trigger_index() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
|
||||
let entries: Vec<index::Directory> = service.get_json("/api/random");
|
||||
assert_eq!(entries.len(), 0);
|
||||
|
||||
service.index();
|
||||
|
||||
let entries: Vec<index::Directory> = service.get_json("/api/random");
|
||||
assert_eq!(entries.len(), 2);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_auth() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
|
||||
{
|
||||
let credentials = dto::AuthCredentials {
|
||||
username: "garbage".into(),
|
||||
password: "garbage".into(),
|
||||
};
|
||||
assert!(service
|
||||
.post_json("/api/auth", &credentials)
|
||||
.is_unauthorized());
|
||||
}
|
||||
{
|
||||
let credentials = dto::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: "garbage".into(),
|
||||
};
|
||||
assert!(service
|
||||
.post_json("/api/auth", &credentials)
|
||||
.is_unauthorized());
|
||||
}
|
||||
{
|
||||
let credentials = dto::AuthCredentials {
|
||||
username: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
};
|
||||
assert!(service.post_json("/api/auth", &credentials).is_ok());
|
||||
// TODO validate cookies
|
||||
}
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_browse() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let entries: Vec<index::CollectionFile> = service.get_json("/api/browse");
|
||||
assert_eq!(entries.len(), 1);
|
||||
|
||||
let mut path = PathBuf::new();
|
||||
path.push("collection");
|
||||
path.push("Khemmis");
|
||||
path.push("Hunted");
|
||||
let encoded_path: String = byte_serialize(path.to_string_lossy().as_ref().as_bytes()).collect();
|
||||
let uri = format!("/api/browse/{}", encoded_path);
|
||||
|
||||
let entries: Vec<index::CollectionFile> = service.get_json(&uri);
|
||||
assert_eq!(entries.len(), 5);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_flatten() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let entries: Vec<index::Song> = service.get_json("/api/flatten");
|
||||
assert_eq!(entries.len(), 12);
|
||||
|
||||
let entries: Vec<index::Song> = service.get_json("/api/flatten/collection");
|
||||
assert_eq!(entries.len(), 12);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_random() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let entries: Vec<index::Directory> = service.get_json("/api/random");
|
||||
assert_eq!(entries.len(), 2);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_recent() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let entries: Vec<index::Directory> = service.get_json("/api/recent");
|
||||
assert_eq!(entries.len(), 2);
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_search() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let results: Vec<index::CollectionFile> = service.get_json("/api/search/door");
|
||||
assert_eq!(results.len(), 1);
|
||||
match results[0] {
|
||||
index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_serve() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
{
|
||||
let mut response = client
|
||||
.get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3")
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::Ok);
|
||||
let body = response.body().unwrap();
|
||||
let body = body.into_bytes().unwrap();
|
||||
assert_eq!(body.len(), 24_142);
|
||||
}
|
||||
|
||||
{
|
||||
let mut response = client
|
||||
.get("/api/serve/collection%2FKhemmis%2FHunted%2F02%20-%20Candlelight.mp3")
|
||||
.header(Range::bytes(100, 299))
|
||||
.dispatch();
|
||||
assert_eq!(response.status(), Status::PartialContent);
|
||||
let body = response.body().unwrap();
|
||||
let body = body.into_bytes().unwrap();
|
||||
assert_eq!(body.len(), 200);
|
||||
assert_eq!(response.headers().get_one("Content-Length").unwrap(), "200");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[named]
|
||||
#[test]
|
||||
fn test_service_playlists() {
|
||||
let mut service = ServiceType::new(function_name!());
|
||||
service.complete_initial_setup();
|
||||
service.login();
|
||||
service.index();
|
||||
|
||||
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists");
|
||||
assert_eq!(playlists.len(), 0);
|
||||
|
||||
let mut my_songs: Vec<index::Song> = service.get_json("/api/flatten");
|
||||
my_songs.pop();
|
||||
my_songs.pop();
|
||||
let my_playlist = dto::SavePlaylistInput {
|
||||
tracks: my_songs.iter().map(|s| s.path.clone()).collect(),
|
||||
};
|
||||
service.put_json("/api/playlist/my_playlist", &my_playlist);
|
||||
|
||||
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists");
|
||||
assert_eq!(
|
||||
playlists,
|
||||
vec![dto::ListPlaylistsEntry {
|
||||
name: "my_playlist".into()
|
||||
}]
|
||||
);
|
||||
|
||||
let songs: Vec<index::Song> = service.get_json("/api/playlist/my_playlist");
|
||||
assert_eq!(songs, my_songs);
|
||||
|
||||
service.delete("/api/playlist/my_playlist");
|
||||
|
||||
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists");
|
||||
assert_eq!(playlists.len(), 0);
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
use function_name::named;
|
||||
|
||||
use crate::config;
|
||||
use crate::service::dto;
|
||||
use crate::vfs;
|
||||
|
||||
#[cfg(feature = "service-rocket")]
|
||||
pub use crate::service::rocket::test;
|
||||
|
||||
const TEST_USERNAME: &str = "test_user";
|
||||
const TEST_PASSWORD: &str = "test_password";
|
||||
const TEST_MOUNT_NAME: &str = "collection";
|
||||
const TEST_MOUNT_SOURCE: &str = "test/collection";
|
||||
|
||||
#[named]
|
||||
#[tokio::test]
|
||||
async fn test_index() {
|
||||
let mut service = test::make_service(function_name!()).await;
|
||||
test::get(&mut service, "/").await;
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[tokio::test]
|
||||
async fn test_swagger_index() {
|
||||
let mut service = test::make_service(function_name!()).await;
|
||||
test::get(&mut service, "/swagger").await;
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[tokio::test]
|
||||
async fn test_swagger_index_with_trailing_slash() {
|
||||
let mut service = test::make_service(function_name!()).await;
|
||||
test::get(&mut service, "/swagger/").await;
|
||||
}
|
||||
|
||||
async fn complete_initial_setup(service: &mut test::ServiceType) {
|
||||
let configuration = config::Config {
|
||||
album_art_pattern: None,
|
||||
prefix_url: None,
|
||||
reindex_every_n_seconds: None,
|
||||
ydns: None,
|
||||
users: Some(vec![config::ConfigUser {
|
||||
name: TEST_USERNAME.into(),
|
||||
password: TEST_PASSWORD.into(),
|
||||
admin: true,
|
||||
}]),
|
||||
mount_dirs: Some(vec![vfs::MountPoint {
|
||||
name: TEST_MOUNT_NAME.into(),
|
||||
source: TEST_MOUNT_SOURCE.into(),
|
||||
}]),
|
||||
};
|
||||
test::put_json(service, "/api/settings", &configuration).await;
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[tokio::test]
|
||||
async fn test_version() {
|
||||
let mut service = test::make_service(function_name!()).await;
|
||||
let version: dto::Version = test::get_json(&mut service, "/api/version").await;
|
||||
assert_eq!(version, dto::Version { major: 4, minor: 0 });
|
||||
}
|
||||
|
||||
#[named]
|
||||
#[tokio::test]
|
||||
async fn test_initial_setup() {
|
||||
let mut service = test::make_service(function_name!()).await;
|
||||
|
||||
{
|
||||
let initial_setup: dto::InitialSetup =
|
||||
test::get_json(&mut service, "/api/initial_setup").await;
|
||||
assert_eq!(
|
||||
initial_setup,
|
||||
dto::InitialSetup {
|
||||
has_any_users: false
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
complete_initial_setup(&mut service).await;
|
||||
|
||||
{
|
||||
let initial_setup: dto::InitialSetup =
|
||||
test::get_json(&mut service, "/api/initial_setup").await;
|
||||
assert_eq!(
|
||||
initial_setup,
|
||||
dto::InitialSetup {
|
||||
has_any_users: true
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue