Cleaner TestService API

This commit is contained in:
Antoine Gersant 2020-01-17 21:14:25 -08:00
parent 9f4f6b4337
commit 5ccc006515
2 changed files with 100 additions and 58 deletions

View file

@ -1,6 +1,5 @@
use http::response::{Builder, Response}; use http::response::{Builder, Response};
use rocket; use rocket;
use rocket::http::Status;
use rocket::local::Client; use rocket::local::Client;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
@ -14,26 +13,31 @@ use crate::db::DB;
use crate::index; use crate::index;
use crate::service::test::TestService; use crate::service::test::TestService;
pub struct RocketResponse<'r, 's>(&'r mut rocket::Response<'s>); pub struct RocketResponse<'r, 's> {
response: &'s mut rocket::Response<'r>,
impl<'r, 's> Into<Builder> for RocketResponse<'r, 's> {
fn into(self) -> Builder {
Response::builder().status(self.0.status().code)
}
} }
impl<'r, 's> Into<Response<()>> for RocketResponse<'r, 's> { impl<'r, 's> RocketResponse<'r, 's> {
fn into(self) -> Response<()> { fn builder(&self) -> Builder {
let builder: Builder = self.into(); Response::builder().status(self.response.status().code)
}
fn to_void(&self) -> Response<()> {
let builder = self.builder();
builder.body(()).unwrap() builder.body(()).unwrap()
} }
}
impl<'r, 's> Into<Response<Vec<u8>>> for RocketResponse<'r, 's> { fn to_bytes(&mut self) -> Response<Vec<u8>> {
fn into(self) -> Response<Vec<u8>> { let body = self.response.body().unwrap();
let body = self.0.body().unwrap();
let body = body.into_bytes().unwrap(); let body = body.into_bytes().unwrap();
let builder: Builder = self.into(); let builder = self.builder();
builder.body(body).unwrap()
}
fn to_object<T: DeserializeOwned>(&mut self) -> Response<T> {
let body = self.response.body_string().unwrap();
let body = serde_json::from_str(&body).unwrap();
let builder = self.builder();
builder.body(body).unwrap() builder.body(body).unwrap()
} }
} }
@ -83,43 +87,61 @@ impl TestService for RocketTestService {
fn get(&mut self, url: &str) -> Response<()> { fn get(&mut self, url: &str) -> Response<()> {
let mut response = self.client.get(url).dispatch(); let mut response = self.client.get(url).dispatch();
RocketResponse(response.deref_mut()).into() RocketResponse {
response: response.deref_mut(),
}
.to_void()
} }
fn get_bytes(&mut self, url: &str) -> Response<Vec<u8>> { fn get_bytes(&mut self, url: &str) -> Response<Vec<u8>> {
let mut response = self.client.get(url).dispatch(); let mut response = self.client.get(url).dispatch();
RocketResponse(response.deref_mut()).into() RocketResponse {
response: response.deref_mut(),
}
.to_bytes()
} }
fn post(&mut self, url: &str) -> Response<()> { fn post(&mut self, url: &str) -> Response<()> {
let mut response = self.client.post(url).dispatch(); let mut response = self.client.post(url).dispatch();
RocketResponse(response.deref_mut()).into() RocketResponse {
response: response.deref_mut(),
}
.to_void()
} }
fn delete(&mut self, url: &str) -> Response<()> { fn delete(&mut self, url: &str) -> Response<()> {
let mut response = self.client.delete(url).dispatch(); let mut response = self.client.delete(url).dispatch();
RocketResponse(response.deref_mut()).into() RocketResponse {
response: response.deref_mut(),
}
.to_void()
} }
fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> T { fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> Response<T> {
let client = &self.client; let mut response = self.client.get(url).dispatch();
let mut response = client.get(url).dispatch(); RocketResponse {
assert_eq!(response.status(), Status::Ok); response: response.deref_mut(),
let response_body = response.body_string().unwrap(); }
serde_json::from_str(&response_body).unwrap() .to_object()
} }
fn put_json<T: Serialize>(&mut self, url: &str, payload: &T) { fn put_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()> {
let client = &self.client; let client = &self.client;
let body = serde_json::to_string(payload).unwrap(); let body = serde_json::to_string(payload).unwrap();
let response = client.put(url).body(&body).dispatch(); let mut response = client.put(url).body(&body).dispatch();
assert_eq!(response.status(), Status::Ok); RocketResponse {
response: response.deref_mut(),
}
.to_void()
} }
fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()> { fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()> {
let body = serde_json::to_string(payload).unwrap(); let body = serde_json::to_string(payload).unwrap();
let mut response = self.client.post(url).body(&body).dispatch(); let mut response = self.client.post(url).body(&body).dispatch();
RocketResponse(response.deref_mut()).into() RocketResponse {
response: response.deref_mut(),
}
.to_void()
} }
} }

View file

@ -23,8 +23,8 @@ pub trait TestService {
fn get_bytes(&mut self, url: &str) -> Response<Vec<u8>>; fn get_bytes(&mut self, url: &str) -> Response<Vec<u8>>;
fn post(&mut self, url: &str) -> Response<()>; fn post(&mut self, url: &str) -> Response<()>;
fn delete(&mut self, url: &str) -> Response<()>; fn delete(&mut self, url: &str) -> Response<()>;
fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> T; fn get_json<T: DeserializeOwned>(&mut self, url: &str) -> Response<T>;
fn put_json<T: Serialize>(&mut self, url: &str, payload: &T); fn put_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()>;
fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()>; fn post_json<T: Serialize>(&mut self, url: &str, payload: &T) -> Response<()>;
fn complete_initial_setup(&mut self) { fn complete_initial_setup(&mut self) {
@ -57,7 +57,8 @@ pub trait TestService {
fn index(&mut self) { fn index(&mut self) {
assert!(self.post("/api/trigger_index").status() == StatusCode::OK); assert!(self.post("/api/trigger_index").status() == StatusCode::OK);
for _ in 1..20 { for _ in 1..20 {
let entries: Vec<index::CollectionFile> = self.get_json("/api/browse"); let response = self.get_json::<Vec<index::CollectionFile>>("/api/browse");
let entries = response.body();
if entries.len() > 0 { if entries.len() > 0 {
return; return;
} }
@ -92,8 +93,9 @@ fn test_service_swagger_index_with_trailing_slash() {
#[test] #[test]
fn test_service_version() { fn test_service_version() {
let mut service = ServiceType::new(function_name!()); let mut service = ServiceType::new(function_name!());
let version: dto::Version = service.get_json("/api/version"); let response = service.get_json::<dto::Version>("/api/version");
assert_eq!(version, dto::Version { major: 4, minor: 0 }); let version = response.body();
assert_eq!(version, &dto::Version { major: 4, minor: 0 });
} }
#[named] #[named]
@ -101,20 +103,22 @@ fn test_service_version() {
fn test_service_initial_setup() { fn test_service_initial_setup() {
let mut service = ServiceType::new(function_name!()); let mut service = ServiceType::new(function_name!());
{ {
let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); let response = service.get_json::<dto::InitialSetup>("/api/initial_setup");
let initial_setup = response.body();
assert_eq!( assert_eq!(
initial_setup, initial_setup,
dto::InitialSetup { &dto::InitialSetup {
has_any_users: false has_any_users: false
} }
); );
} }
service.complete_initial_setup(); service.complete_initial_setup();
{ {
let initial_setup: dto::InitialSetup = service.get_json("/api/initial_setup"); let response = service.get_json::<dto::InitialSetup>("/api/initial_setup");
let initial_setup = response.body();
assert_eq!( assert_eq!(
initial_setup, initial_setup,
dto::InitialSetup { &dto::InitialSetup {
has_any_users: true has_any_users: true
} }
); );
@ -131,10 +135,11 @@ fn test_service_settings() {
service.login(); service.login();
{ {
let configuration: config::Config = service.get_json("/api/settings"); let response = service.get_json::<config::Config>("/api/settings");
let configuration = response.body();
assert_eq!( assert_eq!(
configuration, configuration,
config::Config { &config::Config {
album_art_pattern: Some("Folder.(jpg|png)".to_string()), album_art_pattern: Some("Folder.(jpg|png)".to_string()),
reindex_every_n_seconds: Some(1800), reindex_every_n_seconds: Some(1800),
mount_dirs: Some(vec![vfs::MountPoint { mount_dirs: Some(vec![vfs::MountPoint {
@ -204,8 +209,9 @@ fn test_service_settings() {
}, },
]); ]);
let received: config::Config = service.get_json("/api/settings"); let response = service.get_json::<config::Config>("/api/settings");
assert_eq!(received, configuration); let received = response.body();
assert_eq!(received, &configuration);
} }
#[named] #[named]
@ -221,12 +227,14 @@ fn test_service_trigger_index() {
service.complete_initial_setup(); service.complete_initial_setup();
service.login(); service.login();
let entries: Vec<index::Directory> = service.get_json("/api/random"); let response = service.get_json::<Vec<index::Directory>>("/api/random");
let entries = response.body();
assert_eq!(entries.len(), 0); assert_eq!(entries.len(), 0);
service.index(); service.index();
let entries: Vec<index::Directory> = service.get_json("/api/random"); let response = service.get_json::<Vec<index::Directory>>("/api/random");
let entries = response.body();
assert_eq!(entries.len(), 2); assert_eq!(entries.len(), 2);
} }
@ -268,7 +276,8 @@ fn test_service_browse() {
service.login(); service.login();
service.index(); service.index();
let entries: Vec<index::CollectionFile> = service.get_json("/api/browse"); let response = service.get_json::<Vec<index::CollectionFile>>("/api/browse");
let entries = response.body();
assert_eq!(entries.len(), 1); assert_eq!(entries.len(), 1);
let mut path = PathBuf::new(); let mut path = PathBuf::new();
@ -280,7 +289,8 @@ fn test_service_browse() {
percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC) percent_encode(path.to_string_lossy().as_ref().as_bytes(), NON_ALPHANUMERIC)
); );
let entries: Vec<index::CollectionFile> = service.get_json(&uri); let response = service.get_json::<Vec<index::CollectionFile>>(&uri);
let entries = response.body();
assert_eq!(entries.len(), 5); assert_eq!(entries.len(), 5);
} }
@ -292,10 +302,12 @@ fn test_service_flatten() {
service.login(); service.login();
service.index(); service.index();
let entries: Vec<index::Song> = service.get_json("/api/flatten"); let response = service.get_json::<Vec<index::Song>>("/api/flatten");
let entries = response.body();
assert_eq!(entries.len(), 12); assert_eq!(entries.len(), 12);
let entries: Vec<index::Song> = service.get_json("/api/flatten/collection"); let response = service.get_json::<Vec<index::Song>>("/api/flatten/collection");
let entries = response.body();
assert_eq!(entries.len(), 12); assert_eq!(entries.len(), 12);
} }
@ -307,7 +319,8 @@ fn test_service_random() {
service.login(); service.login();
service.index(); service.index();
let entries: Vec<index::Directory> = service.get_json("/api/random"); let response = service.get_json::<Vec<index::Directory>>("/api/random");
let entries = response.body();
assert_eq!(entries.len(), 2); assert_eq!(entries.len(), 2);
} }
@ -319,7 +332,8 @@ fn test_service_recent() {
service.login(); service.login();
service.index(); service.index();
let entries: Vec<index::Directory> = service.get_json("/api/recent"); let response = service.get_json::<Vec<index::Directory>>("/api/recent");
let entries = response.body();
assert_eq!(entries.len(), 2); assert_eq!(entries.len(), 2);
} }
@ -331,7 +345,8 @@ fn test_service_search() {
service.login(); service.login();
service.index(); service.index();
let results: Vec<index::CollectionFile> = service.get_json("/api/search/door"); let response = service.get_json::<Vec<index::CollectionFile>>("/api/search/door");
let results = response.body();
assert_eq!(results.len(), 1); assert_eq!(results.len(), 1);
match results[0] { match results[0] {
index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())), index::CollectionFile::Song(ref s) => assert_eq!(s.title, Some("Beyond The Door".into())),
@ -383,10 +398,12 @@ fn test_service_playlists() {
service.login(); service.login();
service.index(); service.index();
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists"); let response = service.get_json::<Vec<dto::ListPlaylistsEntry>>("/api/playlists");
let playlists = response.body();
assert_eq!(playlists.len(), 0); assert_eq!(playlists.len(), 0);
let mut my_songs: Vec<index::Song> = service.get_json("/api/flatten"); let response = service.get_json::<Vec<index::Song>>("/api/flatten");
let mut my_songs = response.into_body();
my_songs.pop(); my_songs.pop();
my_songs.pop(); my_songs.pop();
let my_playlist = dto::SavePlaylistInput { let my_playlist = dto::SavePlaylistInput {
@ -394,19 +411,22 @@ fn test_service_playlists() {
}; };
service.put_json("/api/playlist/my_playlist", &my_playlist); service.put_json("/api/playlist/my_playlist", &my_playlist);
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists"); let response = service.get_json::<Vec<dto::ListPlaylistsEntry>>("/api/playlists");
let playlists = response.body();
assert_eq!( assert_eq!(
playlists, playlists,
vec![dto::ListPlaylistsEntry { &vec![dto::ListPlaylistsEntry {
name: "my_playlist".into() name: "my_playlist".into()
}] }]
); );
let songs: Vec<index::Song> = service.get_json("/api/playlist/my_playlist"); let response = service.get_json::<Vec<index::Song>>("/api/playlist/my_playlist");
assert_eq!(songs, my_songs); let songs = response.body();
assert_eq!(songs, &my_songs);
service.delete("/api/playlist/my_playlist"); service.delete("/api/playlist/my_playlist");
let playlists: Vec<dto::ListPlaylistsEntry> = service.get_json("/api/playlists"); let response = service.get_json::<Vec<dto::ListPlaylistsEntry>>("/api/playlists");
let playlists = response.body();
assert_eq!(playlists.len(), 0); assert_eq!(playlists.len(), 0);
} }