Compare commits

...

7 Commits

Author SHA1 Message Date
KD 2023fc81f8 Version fix (#193)
* Version fix

* Workflow fix

* Test fix

* Test fix

* Removing code that was meant to be removed

Caused an extra file to be created when the request is called

* Updated env sample to address workflow

* Removed import

* env fix

* Version change

* Version bump

Going with the version I done earlier. I won't have the versioning match the api version in the endpoints

* Fixing versions for app dependencies
2025-10-14 22:02:26 -04:00
KD 48a40a4821 tsk-182: Update rust version (#191)
* Updated rust version

* Warning fix

* Updating crates and dependencies

* Version bump

* tsk-182: cargo update

* Updated jsonwebtoken
2025-10-12 18:23:56 -04:00
KD 8bf99be22c icarus_models version bump (#190)
* icarus_models version bump

* icarus_models changes

* Code refactoring

* Changes

* Version bump

* Fixed todo
2025-10-11 19:50:56 -04:00
KD 8c12c8c761 icarus_envy version bump (#189)
* icarus_envy version bump

* icarus_envy related changes

* Code formatting

* Code cleanup

* Version bump
2025-10-10 19:04:01 -04:00
KD caaec248db CORS support (#183)
* Changes to same .env file

* Updated sample env files

* icarus_envy version bump

* Adding CORS

* Added other urls

* Code formatting

* Changed allowed urls

* Modified docker compose. Port changes

* Changed port

* Cleanup

* Version bump
2025-10-10 16:33:15 -04:00
KD 309d76785a Language change (#185)
* Adding skeleton file

* Adding content

* Still having issues with the language

* Some changes

* Ignoring .NET related files
2025-10-01 09:55:04 -04:00
KD c83a37c20a Change language of project (#184)
* Adding skeleton file

* Adding content
2025-10-01 09:48:02 -04:00
15 changed files with 456 additions and 443 deletions
+5
View File
@@ -1,3 +1,8 @@
APP_ENV=development
BACKEND_PORT=8000
FRONTEND_URL=http://localhost:4200
RUST_LOG=debug
ALLOWED_ORIGINS=https://soaricarus.com,https://www.soaricarus.com
SECRET_MAIN_KEY=refero34o8rfhfjn983thf39fhc943rf923n3h SECRET_MAIN_KEY=refero34o8rfhfjn983thf39fhc943rf923n3h
ROOT_DIRECTORY=/home/icarus/mydata ROOT_DIRECTORY=/home/icarus/mydata
POSTGRES_MAIN_USER=icarus POSTGRES_MAIN_USER=icarus
+5
View File
@@ -1,3 +1,8 @@
APP_ENV=production
BACKEND_PORT=8000
FRONTEND_URL=http://localhost:4200
RUST_LOG=debug
ALLOWED_ORIGINS=https://soaricarus.com,https://www.soaricarus.com,http://localhost:8000,http://127.0.0.1:8000
SECRET_MAIN_KEY=refero34o8rfhfjn983thf39fhc943rf923n3h SECRET_MAIN_KEY=refero34o8rfhfjn983thf39fhc943rf923n3h
ROOT_DIRECTORY=/home/icarus/mydata ROOT_DIRECTORY=/home/icarus/mydata
POSTGRES_MAIN_USER=icarus POSTGRES_MAIN_USER=icarus
+9
View File
@@ -0,0 +1,9 @@
# Override specific file types
*.cs linguist-language=Rust
*.sln linguist-documentation
*.csproj linguist-documentation
# Or vendor all non-Rust files
*.cs linguist-vendored
*.js linguist-vendored
*.py linguist-vendored
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
- name: Install Rust - name: Install Rust
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: 1.88.0 toolchain: 1.90.0
components: cargo components: cargo
- name: Extract Version from Cargo.toml - name: Extract Version from Cargo.toml
+6 -6
View File
@@ -2,9 +2,9 @@ name: Rust CI
on: on:
push: push:
branches: [ "v0.2" ] branches: [ "main" ]
pull_request: pull_request:
branches: [ "v0.2" ] branches: [ "main" ]
jobs: jobs:
build: build:
@@ -25,12 +25,12 @@ jobs:
--health-retries 5 --health-retries 5
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v5
- name: Install Rust 1.88.0 - name: Install Rust 1.90.0
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: 1.88.0 toolchain: 1.90.0
components: clippy, rustfmt components: clippy, rustfmt
override: true override: true
@@ -69,7 +69,7 @@ jobs:
ROOT_DIRECTORY: "/tmp" ROOT_DIRECTORY: "/tmp"
DATABASE_URL: "postgres://${{ secrets.POSTGRES_USER }}:${{ secrets.POSTGRES_PASSWORD }}@localhost:5432/${{ secrets.POSTGRES_DB }}" DATABASE_URL: "postgres://${{ secrets.POSTGRES_USER }}:${{ secrets.POSTGRES_PASSWORD }}@localhost:5432/${{ secrets.POSTGRES_DB }}"
run: | run: |
cat .env.sample | head -1 > .env cat .env.sample | head -6 > .env
cargo test --verbose -- cargo test --verbose --
- name: Run clippy - name: Run clippy
+4
View File
@@ -7,3 +7,7 @@
.DS_STORE .DS_STORE
Storage/ Storage/
*.sln
*.cs
*.csproj
Generated
+297 -326
View File
File diff suppressed because it is too large Load Diff
+19 -19
View File
@@ -1,35 +1,35 @@
[package] [package]
name = "icarus" name = "icarus"
version = "0.2.0" version = "0.3.0"
edition = "2024" edition = "2024"
rust-version = "1.88" rust-version = "1.90"
[dependencies] [dependencies]
axum = { version = "0.8.4", features = ["multipart"] } axum = { version = "0.8.6", features = ["multipart"] }
axum-extra = { version = "0.10.1", features = ["cookie"] } axum-extra = { version = "0.10.3", features = ["cookie"] }
serde = { version = "1.0.219", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = { version = "1.0.140" } serde_json = { version = "1.0.145" }
tower = { version = "0.5.2", features = ["full"] } tower = { version = "0.5.2", features = ["full"] }
tokio = { version = "1.45.1", features = ["full"] } tokio = { version = "1.47.1", features = ["full"] }
tokio-util = { version = "0.7.15", features = ["io"] } tokio-util = { version = "0.7.16", features = ["io"] }
tower-http = { version = "0.6.6", features = ["cors", "timeout"] } tower-http = { version = "0.6.6", features = ["cors", "timeout"] }
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.20"
futures = { version = "0.3.31" } futures = { version = "0.3.31" }
mime_guess = { version = "2.0.5" } mime_guess = { version = "2.0.5" }
uuid = { version = "1.17.0", features = ["v4", "serde"] } uuid = { version = "1.18.1", features = ["v4", "serde"] }
sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] } sqlx = { version = "0.8.6", features = ["postgres", "runtime-tokio-native-tls", "time", "uuid"] }
time = { version = "0.3.41", features = ["formatting", "macros", "parsing", "serde"] } time = { version = "0.3.44", features = ["formatting", "macros", "parsing", "serde"] }
thiserror = "1.0" thiserror = "2.0.17"
base64 = "0.21" base64 = "0.22.1"
jsonwebtoken = { version = "9.3.1" } jsonwebtoken = { version = "9.3.1" }
josekit = { version = "0.10.1" } josekit = { version = "0.10.3" }
utoipa = { version = "5.4.0", features = ["axum_extras"] } utoipa = { version = "5.4.0", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] } utoipa-swagger-ui = { version = "9.0.2", features = ["axum"] }
icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.3.0" } icarus_meta = { git = "ssh://git@git.kundeng.us/phoenix/icarus_meta.git", tag = "v0.4.0" }
icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.5.6" } icarus_models = { git = "ssh://git@git.kundeng.us/phoenix/icarus_models.git", tag = "v0.7.0" }
icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.3.2" } icarus_envy = { git = "ssh://git@git.kundeng.us/phoenix/icarus_envy.git", tag = "v0.5.0" }
[dev-dependencies] [dev-dependencies]
common-multipart-rfc7578 = { version = "0.7.0" } common-multipart-rfc7578 = { version = "0.7.0" }
url = { version = "2.5.4" } url = { version = "2.5.7" }
tempfile = { version = "3.20.0" } tempfile = { version = "3.23.0" }
+1 -1
View File
@@ -1,5 +1,5 @@
# Stage 1: Build the application # Stage 1: Build the application
FROM rust:1.88 as builder FROM rust:1.90 as builder
# Set the working directory inside the container # Set the working directory inside the container
WORKDIR /usr/src/app WORKDIR /usr/src/app
+4
View File
@@ -2,6 +2,10 @@
Web API for the Icarus project. Web API for the Icarus project.
### Requires
`icarus_auth` +v0.6.0
`songparser` +v0.4.1
## Getting Started ## Getting Started
Quickest way to get started is with docker. Make sure `icarus_auth` and `songparser` repositories Quickest way to get started is with docker. Make sure `icarus_auth` and `songparser` repositories
are located in the root of the parent directory. Check the respective repositories to ensure they are located in the root of the parent directory. Check the respective repositories to ensure they
+2 -2
View File
@@ -10,7 +10,7 @@ services:
ports: ports:
# Map host port 8000 to container port 3000 (adjust as needed) # Map host port 8000 to container port 3000 (adjust as needed)
# Format: "HOST_PORT:CONTAINER_PORT" # Format: "HOST_PORT:CONTAINER_PORT"
- "8000:3000" - "8000:8000"
env_file: env_file:
- .env - .env
depends_on: depends_on:
@@ -29,7 +29,7 @@ services:
container_name: auth_api container_name: auth_api
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8001:3000" # Map host port 8000 to container port 8000 (adjust container port based on your app's EXPOSE in Dockerfile) - "8001:8001" # Map host port 8000 to container port 8000 (adjust container port based on your app's EXPOSE in Dockerfile)
# environment: # environment:
# Environment variables your API needs, e.g., database connection # Environment variables your API needs, e.g., database connection
# Add other necessary environment variables # Add other necessary environment variables
+1 -6
View File
@@ -1,6 +1,3 @@
// use std::collections::BTreeMap;
// use std::sync::Arc;
use axum::{ use axum::{
Json, Json,
http::{Request, StatusCode}, http::{Request, StatusCode},
@@ -10,9 +7,7 @@ use axum::{
use axum_extra::extract::cookie::CookieJar; use axum_extra::extract::cookie::CookieJar;
use jsonwebtoken::{DecodingKey, Validation, decode}; use jsonwebtoken::{DecodingKey, Validation, decode};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
// use serde_json::{json, Value};
use thiserror::Error; use thiserror::Error;
// use time::OffsetDateTime;
fn deserialize_i64_from_f64<'de, D>(deserializer: D) -> Result<i64, D::Error> fn deserialize_i64_from_f64<'de, D>(deserializer: D) -> Result<i64, D::Error>
where where
@@ -95,7 +90,7 @@ pub async fn auth<B>(
(StatusCode::UNAUTHORIZED, Json(json_error)) (StatusCode::UNAUTHORIZED, Json(json_error))
})?; })?;
let secret_key = icarus_envy::environment::get_secret_main_key().await; let secret_key = icarus_envy::environment::get_secret_main_key().await.value;
let mut validation = Validation::new(jsonwebtoken::Algorithm::HS256); let mut validation = Validation::new(jsonwebtoken::Algorithm::HS256);
validation.set_audience(&["icarus"]); // Must match exactly what's in the token validation.set_audience(&["icarus"]); // Must match exactly what's in the token
+14 -8
View File
@@ -473,8 +473,6 @@ pub mod cov_db {
} }
pub mod endpoint { pub mod endpoint {
use std::io::Write;
use axum::response::IntoResponse; use axum::response::IntoResponse;
/// Endpoint to queue cover art /// Endpoint to queue cover art
@@ -702,7 +700,7 @@ pub mod endpoint {
let song_id = payload.song_id; let song_id = payload.song_id;
match crate::callers::song::song_db::get_song(&pool, &song_id).await { match crate::callers::song::song_db::get_song(&pool, &song_id).await {
Ok(song) => { Ok(song) => {
let directory = icarus_envy::environment::get_root_directory().await; let directory = icarus_envy::environment::get_root_directory().await.value;
let dir = std::path::Path::new(&directory); let dir = std::path::Path::new(&directory);
// TODO: Make this random and the file extension should not be hard coded // TODO: Make this random and the file extension should not be hard coded
@@ -714,12 +712,11 @@ pub mod endpoint {
coverart.title = song.album.clone(); coverart.title = song.album.clone();
coverart.data = data; coverart.data = data;
let mut file = std::fs::File::create(&save_path).unwrap(); match coverart.save_to_filesystem() {
file.write_all(&coverart.data).unwrap(); Ok(_) => {
match super::cov_db::create(&pool, &coverart, &song.id).await { match super::cov_db::create(&pool, &coverart, &song.id).await {
Ok(id) => { Ok(id) => {
// TODO: Populate song_id coverart.song_id = song_id;
coverart.id = id; coverart.id = id;
println!("Cover Art created"); println!("Cover Art created");
@@ -734,6 +731,15 @@ pub mod endpoint {
} }
} }
} }
Err(err) => {
response.message = err.to_string();
(
axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response),
)
}
}
}
Err(err) => { Err(err) => {
response.message = err.to_string(); response.message = err.to_string();
(axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) (axum::http::StatusCode::BAD_REQUEST, axum::Json(response))
@@ -848,7 +854,7 @@ pub mod endpoint {
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>, axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
) -> (axum::http::StatusCode, axum::response::Response) { ) -> (axum::http::StatusCode, axum::response::Response) {
match super::cov_db::get_coverart(&pool, &id).await { match super::cov_db::get_coverart(&pool, &id).await {
Ok(coverart) => match coverart.to_data() { Ok(coverart) => match icarus_models::coverart::io::to_data(&coverart) {
Ok(data) => { Ok(data) => {
let bytes = axum::body::Bytes::from(data); let bytes = axum::body::Bytes::from(data);
let mut response = bytes.into_response(); let mut response = bytes.into_response();
+8 -35
View File
@@ -571,11 +571,6 @@ pub mod song_db {
mod song_queue { mod song_queue {
use sqlx::Row; use sqlx::Row;
#[derive(Debug, serde::Serialize, sqlx::FromRow)]
pub struct InsertedData {
pub id: uuid::Uuid,
}
// TODO: Move this somewhere else at some point // TODO: Move this somewhere else at some point
#[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow, utoipa::ToSchema)] #[derive(Debug, serde::Deserialize, serde::Serialize, sqlx::FromRow, utoipa::ToSchema)]
pub struct SongQueue { pub struct SongQueue {
@@ -874,8 +869,6 @@ mod song_queue {
pub mod endpoint { pub mod endpoint {
use axum::{Json, http::StatusCode, response::IntoResponse}; use axum::{Json, http::StatusCode, response::IntoResponse};
use std::io::Write;
use crate::callers::song::song_queue; use crate::callers::song::song_queue;
/// Endpoint to queue a song. Starts the process and places the song in a queue /// Endpoint to queue a song. Starts the process and places the song in a queue
@@ -912,11 +905,6 @@ pub mod endpoint {
data.len() data.len()
); );
// TODO: Remove this
// Save the file to disk
let mut file = std::fs::File::create(&file_name).unwrap();
file.write_all(&data).unwrap();
let raw_data: Vec<u8> = data.to_vec(); let raw_data: Vec<u8> = data.to_vec();
let queue_repo = song_queue::insert( let queue_repo = song_queue::insert(
&pool, &pool,
@@ -1207,9 +1195,11 @@ pub mod endpoint {
if payload.is_valid() { if payload.is_valid() {
let mut song = payload.to_song(); let mut song = payload.to_song();
song.filename = song.filename = icarus_models::song::generate_filename(
song.generate_filename(icarus_models::types::MusicTypes::FlacExtension, true); icarus_models::types::MusicTypes::FlacExtension,
song.directory = icarus_envy::environment::get_root_directory().await; true,
);
song.directory = icarus_envy::environment::get_root_directory().await.value;
match song_queue::get_data(&pool, &payload.song_queue_id).await { match song_queue::get_data(&pool, &payload.song_queue_id).await {
Ok(data) => { Ok(data) => {
@@ -1227,13 +1217,7 @@ pub mod endpoint {
} }
} }
let save_path = dir.join(&song.filename); match song.save_to_filesystem() {
match std::fs::File::create(&save_path) {
Ok(mut file) => {
file.write_all(&song.data).unwrap();
match song.song_path() {
Ok(_) => match super::song_db::insert(&pool, &song).await { Ok(_) => match super::song_db::insert(&pool, &song).await {
Ok((date_created, id)) => { Ok((date_created, id)) => {
song.id = id; song.id = id;
@@ -1244,23 +1228,12 @@ pub mod endpoint {
(axum::http::StatusCode::OK, axum::Json(response)) (axum::http::StatusCode::OK, axum::Json(response))
} }
Err(err) => { Err(err) => {
response.message = response.message = format!("{:?} song {:?}", err.to_string(), song);
format!("{:?} song {:?}", err.to_string(), song);
(axum::http::StatusCode::BAD_REQUEST, axum::Json(response)) (axum::http::StatusCode::BAD_REQUEST, axum::Json(response))
} }
}, },
Err(err) => { Err(err) => {
response.message = err.to_string(); response.message = err.to_string();
(axum::http::StatusCode::BAD_REQUEST, axum::Json(response))
}
}
}
Err(err) => {
let song_path = song.song_path();
response.message = format!(
"{err:?} Song directory: {} Filename: {} Save Path: {:?} Song Path: {:?}",
song.directory, song.filename, save_path, song_path
);
( (
axum::http::StatusCode::INTERNAL_SERVER_ERROR, axum::http::StatusCode::INTERNAL_SERVER_ERROR,
axum::Json(response), axum::Json(response),
@@ -1466,7 +1439,7 @@ pub mod endpoint {
axum::extract::Path(id): axum::extract::Path<uuid::Uuid>, axum::extract::Path(id): axum::extract::Path<uuid::Uuid>,
) -> (axum::http::StatusCode, axum::response::Response) { ) -> (axum::http::StatusCode, axum::response::Response) {
match super::song_db::get_song(&pool, &id).await { match super::song_db::get_song(&pool, &id).await {
Ok(song) => match song.to_data() { Ok(song) => match icarus_models::song::io::to_data(&song) {
Ok(data) => { Ok(data) => {
let bytes = axum::body::Bytes::from(data); let bytes = axum::body::Bytes::from(data);
let mut response = bytes.into_response(); let mut response = bytes.into_response();
+60 -19
View File
@@ -10,7 +10,7 @@ pub mod db {
} }
pub async fn create_pool() -> Result<sqlx::PgPool, sqlx::Error> { pub async fn create_pool() -> Result<sqlx::PgPool, sqlx::Error> {
let database_url = icarus_envy::environment::get_db_url().await; let database_url = icarus_envy::environment::get_db_url().await.value;
println!("Database url: {database_url}"); println!("Database url: {database_url}");
PgPoolOptions::new() PgPoolOptions::new()
@@ -45,16 +45,12 @@ async fn main() {
} }
pub mod init { pub mod init {
use axum::routing::{delete, get, patch, post};
use std::time::Duration; use std::time::Duration;
use axum::routing::{delete, get, patch, post};
use tower_http::timeout::TimeoutLayer; use tower_http::timeout::TimeoutLayer;
use utoipa::OpenApi; use utoipa::OpenApi;
use axum::http::{
HeaderValue, Method,
header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE},
};
use crate::callers::coverart as coverart_caller; use crate::callers::coverart as coverart_caller;
use crate::callers::metadata as metadata_caller; use crate::callers::metadata as metadata_caller;
use crate::callers::song as song_caller; use crate::callers::song as song_caller;
@@ -65,6 +61,54 @@ pub mod init {
use song_caller::endpoint as song_endpoints; use song_caller::endpoint as song_endpoints;
use song_caller::response as song_responses; use song_caller::response as song_responses;
mod cors {
pub async fn configure_cors() -> tower_http::cors::CorsLayer {
let cors = tower_http::cors::CorsLayer::new()
.allow_methods([
axum::http::Method::GET,
axum::http::Method::POST,
axum::http::Method::PUT,
axum::http::Method::DELETE,
]) // Specify allowed methods:cite[2]
.allow_headers([
axum::http::header::CONTENT_TYPE,
axum::http::header::AUTHORIZATION,
]) // Specify allowed headers:cite[2]
.allow_credentials(true) // If you need to send cookies or authentication headers:cite[2]
.max_age(std::time::Duration::from_secs(3600)); // Cache the preflight response for 1 hour:cite[2]
// Dynamically set the allowed origin based on the environment
match std::env::var(icarus_envy::keys::APP_ENV).as_deref() {
Ok("production") => {
// In production, allow only your specific, trusted origins
let allowed_origins_env = icarus_envy::environment::get_allowed_origins().await;
match icarus_envy::utility::delimitize(&allowed_origins_env) {
Ok(alwd) => {
let allowed_origins: Vec<axum::http::HeaderValue> = alwd
.into_iter()
.map(|a| a.parse::<axum::http::HeaderValue>().unwrap())
.collect();
cors.allow_origin(allowed_origins)
}
Err(err) => {
eprintln!("Error getting allowed origins: Error: {err:?}");
std::process::exit(-1);
}
}
}
_ => {
// Development (default): Allow localhost origins
cors.allow_origin(vec![
"http://localhost:8000".parse().unwrap(),
"http://127.0.0.1:8000".parse().unwrap(),
"http://localhost:4200".parse().unwrap(),
"http://127.0.0.1:4200".parse().unwrap(),
])
}
}
}
}
#[derive(utoipa::OpenApi)] #[derive(utoipa::OpenApi)]
#[openapi( #[openapi(
paths(song_endpoints::queue_song, song_endpoints::link_user_id, song_endpoints::fetch_queue_song, song_endpoints::download_flac, paths(song_endpoints::queue_song, song_endpoints::link_user_id, song_endpoints::fetch_queue_song, song_endpoints::download_flac,
@@ -226,6 +270,7 @@ pub mod init {
crate::callers::endpoints::GETALLSONGS, crate::callers::endpoints::GETALLSONGS,
get(crate::callers::song::endpoint::get_all_songs), get(crate::callers::song::endpoint::get_all_songs),
) )
.layer(cors::configure_cors().await)
} }
pub async fn app() -> axum::Router { pub async fn app() -> axum::Router {
@@ -235,11 +280,7 @@ pub mod init {
// TODO: Look into handling this. Seems redundant to run migrations multiple times // TODO: Look into handling this. Seems redundant to run migrations multiple times
crate::db::migrations(&pool).await; crate::db::migrations(&pool).await;
let cors = tower_http::cors::CorsLayer::new() let cors = cors::configure_cors().await;
.allow_origin("http://localhost:3000".parse::<HeaderValue>().unwrap())
.allow_methods([Method::GET, Method::POST, Method::PATCH, Method::DELETE])
.allow_credentials(true)
.allow_headers([AUTHORIZATION, ACCEPT, CONTENT_TYPE]);
routes() routes()
.await .await
@@ -265,7 +306,7 @@ fn get_address() -> String {
// TODO: Move elsewhere // TODO: Move elsewhere
fn get_port() -> String { fn get_port() -> String {
String::from("3000") String::from("8000")
} }
// TODO: Move elsewhere // TODO: Move elsewhere
@@ -294,7 +335,7 @@ mod tests {
pub const LIMIT: usize = 6; pub const LIMIT: usize = 6;
pub async fn get_pool() -> Result<sqlx::PgPool, sqlx::Error> { pub async fn get_pool() -> Result<sqlx::PgPool, sqlx::Error> {
let tm_db_url = icarus_envy::environment::get_db_url().await; let tm_db_url = icarus_envy::environment::get_db_url().await.value;
let tm_options = sqlx::postgres::PgConnectOptions::from_str(&tm_db_url).unwrap(); let tm_options = sqlx::postgres::PgConnectOptions::from_str(&tm_db_url).unwrap();
sqlx::PgPool::connect_with(tm_options).await sqlx::PgPool::connect_with(tm_options).await
} }
@@ -307,7 +348,7 @@ mod tests {
} }
pub async fn connect_to_db(db_name: &str) -> Result<sqlx::PgPool, sqlx::Error> { pub async fn connect_to_db(db_name: &str) -> Result<sqlx::PgPool, sqlx::Error> {
let db_url = icarus_envy::environment::get_db_url().await; let db_url = icarus_envy::environment::get_db_url().await.value;
let options = sqlx::postgres::PgConnectOptions::from_str(&db_url)?.database(db_name); let options = sqlx::postgres::PgConnectOptions::from_str(&db_url)?.database(db_name);
sqlx::PgPool::connect_with(options).await sqlx::PgPool::connect_with(options).await
} }
@@ -334,7 +375,7 @@ mod tests {
} }
pub async fn get_database_name() -> Result<String, Box<dyn std::error::Error>> { pub async fn get_database_name() -> Result<String, Box<dyn std::error::Error>> {
let database_url = icarus_envy::environment::get_db_url().await; let database_url = icarus_envy::environment::get_db_url().await.value;
let parsed_url = url::Url::parse(&database_url)?; let parsed_url = url::Url::parse(&database_url)?;
if parsed_url.scheme() == "postgres" || parsed_url.scheme() == "postgresql" { if parsed_url.scheme() == "postgres" || parsed_url.scheme() == "postgresql" {
@@ -384,7 +425,7 @@ mod tests {
pub const TEST_USER_ID: uuid::Uuid = uuid::uuid!("cc938368-615a-4694-b2ca-6e122fa31c52"); pub const TEST_USER_ID: uuid::Uuid = uuid::uuid!("cc938368-615a-4694-b2ca-6e122fa31c52");
pub async fn test_token() -> Result<String, josekit::JoseError> { pub async fn test_token() -> Result<String, josekit::JoseError> {
let key: String = icarus_envy::environment::get_secret_main_key().await; let key: String = icarus_envy::environment::get_secret_main_key().await.value;
let (message, issuer, audience) = token_fields(); let (message, issuer, audience) = token_fields();
let token_resource = icarus_models::token::TokenResource { let token_resource = icarus_models::token::TokenResource {
@@ -2343,8 +2384,8 @@ mod tests {
..Default::default() ..Default::default()
}; };
match song.to_data() { match icarus_models::song::io::to_data(&song) {
Ok(song_data) => match coverart.to_data() { Ok(song_data) => match icarus_models::coverart::io::to_data(&coverart) {
Ok(coverart_data) => Ok((song_data, coverart_data)), Ok(coverart_data) => Ok((song_data, coverart_data)),
Err(err) => Err(err), Err(err) => Err(err),
}, },