Skip to content

Commit

Permalink
add query strings for dynamic requesting media items for specific yea…
Browse files Browse the repository at this point in the history
…rs & months
  • Loading branch information
thebino committed Nov 3, 2023
1 parent b1354be commit 842975b
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 21 deletions.
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ rsa = "0.9.2"
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json", "stream", "multipart"] }

serde = "1.0.183"
serde_qs = "0.12.0"
serde_json = { version = "1.0.104", features = ["raw_value"] }
serde_with = "3.3.0"
serde_urlencoded = "0.7.1"
Expand Down
7 changes: 6 additions & 1 deletion crates/common/src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,12 @@ pub trait Database {
async fn disable_user(&self, user_id: &str) -> Result<()>;
async fn enable_user(&self, user_id: &str) -> Result<()>;

async fn get_media_items(&self, user_id: &str) -> Result<Vec<MediaItem>>;
async fn get_media_items(
&self,
user_id: &str,
years: Vec<i32>,
months: Vec<i32>,
) -> Result<Vec<MediaItem>>;
async fn create_media_item(
&self,
user_id: &str,
Expand Down
7 changes: 6 additions & 1 deletion crates/database/src/postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,12 @@ impl Database for PostgresDatabase {
unimplemented!()
}

async fn get_media_items(&self, _user_id: &str) -> Result<Vec<MediaItem>> {
async fn get_media_items(
&self,
_user_id: &str,
_years: Vec<i32>,
_months: Vec<i32>,
) -> Result<Vec<MediaItem>> {
unimplemented!()
}

Expand Down
9 changes: 7 additions & 2 deletions crates/database/src/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,13 @@ impl Database for SqliteDatabase {
unimplemented!()
}

async fn get_media_items(&self, _user_id: &str) -> Result<Vec<MediaItem>> {
unimplemented!()
async fn get_media_items(
&self,
_user_id: &str,
years: Vec<i32>,

Check warning on line 128 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `years`

Check failure on line 128 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Lint checks

unused variable: `years`

Check warning on line 128 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Tests

unused variable: `years`
months: Vec<i32>,

Check warning on line 129 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Check

unused variable: `months`

Check failure on line 129 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Lint checks

unused variable: `months`

Check warning on line 129 in crates/database/src/sqlite.rs

View workflow job for this annotation

GitHub Actions / Tests

unused variable: `months`
) -> Result<Vec<MediaItem>> {
Ok(vec![])
}
async fn create_media_item(
&self,
Expand Down
1 change: 1 addition & 0 deletions crates/media/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ hyper = { workspace = true, features = ["full"] }
tower-http.workspace = true
mime.workspace = true
bytes.workspace = true
serde_qs = { workspace = true, features = ["axum"] }

# persistency
uuid = { workspace = true, features = ["serde"] }
Expand Down
6 changes: 3 additions & 3 deletions crates/media/src/api/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ mod tests {
let response = app
.oneshot(
Request::builder()
.uri("/media?limit=100000&offset=1")
.uri("/media")
.method("GET")
.header("Authorization", "FakeAuth")
.body(Body::empty())
Expand All @@ -135,7 +135,7 @@ mod tests {
let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let body: String = serde_json::from_slice(&body).unwrap();

assert_eq!(body, "list media items. limit=100000, offset=1");
assert_eq!(body, "list media items. limit=, offset=");
}

#[tokio::test]
Expand Down Expand Up @@ -172,7 +172,7 @@ mod tests {
let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
let body: String = serde_json::from_slice(&body).unwrap();

assert_eq!(body, "list media items. limit=1000, offset=0");
assert_eq!(body, "list media items. limit=, offset=");
}

#[tokio::test]
Expand Down
145 changes: 134 additions & 11 deletions crates/media/src/api/routes/get_media.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
//! Returns a list of owned media items for current user
//!
use axum::extract::State;
use axum::{extract::Query, http::StatusCode, Json};
use axum::{http::StatusCode, Json};
use common::auth::user::User;
use serde::{Deserialize, Serialize};
use serde_qs::axum::QsQuery;
use std::result::Result;
use tracing::error;
use uuid::Uuid;
Expand All @@ -31,17 +32,21 @@ use crate::repository::MediaRepositoryState;

#[derive(Serialize, Deserialize)]
pub(crate) struct MediaListQuery {
offset: Option<i32>,
limit: Option<i32>,
years: Option<Vec<i32>>,
months: Option<Vec<i32>>,
}

pub(crate) async fn get_media(
State(repo): State<MediaRepositoryState>,
user: User,
Query(query): Query<MediaListQuery>,
QsQuery(query): QsQuery<MediaListQuery>, //Query(query): Query<MediaListQuery>,
) -> Result<Json<String>, StatusCode> {
let items: Result<Vec<MediaItem>, DataAccessError> = repo
.get_media_items_for_user(Uuid::parse_str(user.uuid.as_str()).unwrap())
.get_media_items_for_user(
Uuid::parse_str(user.uuid.as_str()).unwrap(),
query.years.unwrap_or(vec![]),
query.months.unwrap_or(vec![]),
)
.await;
match items {
Ok(i) => {
Expand All @@ -51,15 +56,11 @@ pub(crate) async fn get_media(
error!("Failed to get media items!");
}
}

// TODO: read list from persistency
// TODO: return list
Ok(Json(
format!(
"list media items. limit={}, offset={}",
query.limit.unwrap_or(1000),
query.offset.unwrap_or(0)
)
.to_owned(),
format!("list media items. limit=, offset=").to_owned(),
))
}

Expand Down Expand Up @@ -105,4 +106,126 @@ mod tests {
// then
assert_eq!(response.status(), StatusCode::UNAUTHORIZED);
}

#[sqlx::test]
async fn get_media_with_multiple_years_only_should_return_only_requested_years(
pool: SqlitePool,
) {
// given
let state: ApplicationState = ApplicationState {
config: Configuration::empty().into(),
plugins: HashMap::new(),
router: None,
database: Arc::new(SqliteDatabase { pool }),
};

let app = Router::new().nest("/", MediaApi::routes(&state).await);

// when
let response = app
.oneshot(
Request::builder()
.method("GET")
.header(hyper::header::AUTHORIZATION, "FakeAuth")
.uri(format!("/media?years=[1990,1991]"))
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// then
assert_eq!(response.status(), StatusCode::OK);
}

#[sqlx::test]
async fn get_media_with_multiple_years_and_months_should_return_requested_years_and_months(
pool: SqlitePool,
) {
// given
let state: ApplicationState = ApplicationState {
config: Configuration::empty().into(),
plugins: HashMap::new(),
router: None,
database: Arc::new(SqliteDatabase { pool }),
};

let app = Router::new().nest("/", MediaApi::routes(&state).await);

// when
let response = app
.oneshot(
Request::builder()
.method("GET")
.header(hyper::header::AUTHORIZATION, "FakeAuth")
.uri(format!("/media?years=[1990,1991]&months=[3,4]"))
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// then
assert_eq!(response.status(), StatusCode::OK);
}

#[sqlx::test]
async fn get_media_with_multiple_month_only_should_return_requested_months_for_all_years(
pool: SqlitePool,
) {
// given
let state: ApplicationState = ApplicationState {
config: Configuration::empty().into(),
plugins: HashMap::new(),
router: None,
database: Arc::new(SqliteDatabase { pool }),
};

let app = Router::new().nest("/", MediaApi::routes(&state).await);

// when
let response = app
.oneshot(
Request::builder()
.method("GET")
.header(hyper::header::AUTHORIZATION, "FakeAuth")
.uri(format!("/media?years=[1990,1991]"))
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// then
assert_eq!(response.status(), StatusCode::OK);
}

#[sqlx::test]
async fn get_media_without_parameters_should_return_all(pool: SqlitePool) {
// given
let state: ApplicationState = ApplicationState {
config: Configuration::empty().into(),
plugins: HashMap::new(),
router: None,
database: Arc::new(SqliteDatabase { pool }),
};

let app = Router::new().nest("/", MediaApi::routes(&state).await);

// when
let response = app
.oneshot(
Request::builder()
.method("GET")
.header(hyper::header::AUTHORIZATION, "FakeAuth")
.uri(format!("/media"))
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

// then
assert_eq!(response.status(), StatusCode::OK);
}
}
13 changes: 10 additions & 3 deletions crates/media/src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub trait MediaRepositoryTrait {
async fn get_media_items_for_user(
&self,
user_id: Uuid,
years: Vec<i32>,
months: Vec<i32>,
) -> Result<Vec<MediaItem>, DataAccessError>;

/// Create a new media item for the given user
Expand Down Expand Up @@ -76,12 +78,17 @@ impl MediaRepositoryTrait for MediaRepository {
async fn get_media_items_for_user(
&self,
user_id: Uuid,
years: Vec<i32>,
months: Vec<i32>,
) -> Result<Vec<MediaItem>, DataAccessError> {
info!("get items for user {}", user_id);
info!(
"get items for user:{}, years: {:?}, month: {:?}",
user_id, years, months
);

let items_result = &self
.database
.get_media_items(user_id.hyphenated().to_string().as_str())
.get_media_items(user_id.hyphenated().to_string().as_str(), years, months)
.await;
return match items_result {
Ok(items) => {
Expand Down Expand Up @@ -208,7 +215,7 @@ mod tests {

// when
let result = repository
.get_media_items_for_user(Uuid::parse_str(user_id).unwrap())
.get_media_items_for_user(Uuid::parse_str(user_id).unwrap(), Vec::new(), Vec::new())
.await;

// then
Expand Down

0 comments on commit 842975b

Please sign in to comment.