-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added unit test, updated endpoints from put to patch, updated readme
- Loading branch information
Showing
11 changed files
with
483 additions
and
48 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
mod common; | ||
|
||
use axum::{ | ||
body::Body, | ||
http::{Request, StatusCode}, | ||
}; | ||
use rust_microservice_starter_kit::models::feature_flags::Model as FeatureFlag; | ||
use serde_json::{json, Value}; | ||
use tower::ServiceExt; // for `oneshot` and `ready` | ||
|
||
use crate::common::feature_flag_mock; | ||
use crate::common::read_body; | ||
|
||
#[tokio::test] | ||
async fn test_health_check() { | ||
let service = feature_flag_mock::create_feature_flag_service(); | ||
let app = feature_flag_mock::create_test_app(service); | ||
|
||
let response = app | ||
.oneshot(Request::builder().uri("/").body(Body::empty()).unwrap()) | ||
.await | ||
.unwrap(); | ||
|
||
let body = read_body(response.into_body()).await.unwrap(); | ||
let json: Value = serde_json::from_slice(&body).expect("Failed to parse JSON"); | ||
|
||
// Check the structure of the JSON response | ||
assert_eq!(json["status"], "Ok"); | ||
assert!(json["available_routes"].is_array()); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_get_all_feature_flags() { | ||
let service = feature_flag_mock::create_feature_flag_service(); | ||
let app = feature_flag_mock::create_test_app(service); | ||
|
||
let response = app | ||
.oneshot( | ||
Request::builder() | ||
.uri("/api/v1/feature_flags") | ||
.body(Body::empty()) | ||
.unwrap(), | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(response.status(), StatusCode::OK); | ||
|
||
let body = read_body(response.into_body()).await.unwrap(); | ||
let flags: Vec<FeatureFlag> = serde_json::from_slice(&body).unwrap(); | ||
|
||
assert_eq!(flags.len(), 3); | ||
assert_eq!(flags[1].name, "flag1"); | ||
assert_eq!(flags[2].name, "flag2"); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_delete_feature_flag() { | ||
let service = feature_flag_mock::create_feature_flag_service(); | ||
let app = feature_flag_mock::create_test_app(service); | ||
|
||
let response = app | ||
.oneshot( | ||
Request::builder() | ||
.method("DELETE") | ||
.uri("/api/v1/feature_flags/flag--sample-deleted") | ||
.body(Body::empty()) | ||
.unwrap(), | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
assert!( | ||
response.status() == StatusCode::NO_CONTENT || response.status() == StatusCode::NOT_FOUND | ||
); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_get_specific_feature_flag() { | ||
let service = feature_flag_mock::create_feature_flag_service(); | ||
let app = feature_flag_mock::create_test_app(service); | ||
|
||
let response = app | ||
.oneshot( | ||
Request::builder() | ||
.uri("/api/v1/feature_flags/new_flag") | ||
.body(Body::empty()) | ||
.unwrap(), | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
let body = read_body(response.into_body()).await.unwrap(); | ||
let flag: FeatureFlag = serde_json::from_slice(&body).unwrap(); | ||
|
||
assert_eq!(flag.name, "new_flag"); | ||
assert_eq!(flag.description, "New test flag"); | ||
assert_eq!(flag.enabled as i32, 1); | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_create_feature_flag() { | ||
let service = feature_flag_mock::create_feature_flag_service(); | ||
let app = feature_flag_mock::create_test_app(service); | ||
|
||
let new_flag = json!({ | ||
"name": "new_flag", | ||
"description": "New test flag", | ||
"enabled": true | ||
}); | ||
|
||
let response = app | ||
.oneshot( | ||
Request::builder() | ||
.method("POST") | ||
.uri("/api/v1/feature_flags") | ||
.header("Content-Type", "application/json") | ||
.body(Body::from(new_flag.to_string())) | ||
.unwrap(), | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
assert_eq!(response.status(), StatusCode::CREATED); | ||
|
||
let body = read_body(response.into_body()).await.unwrap(); | ||
let created_flag: FeatureFlag = serde_json::from_slice(&body).unwrap(); | ||
|
||
assert_eq!(created_flag.name, "new_flag"); | ||
assert_eq!(created_flag.description, "New test flag"); | ||
assert_eq!(created_flag.enabled as u8, 1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use crate::common::create_mock_db; | ||
|
||
use axum::Router; | ||
use rust_microservice_starter_kit::{ | ||
api::routes, models::feature_flags, services::feature_flag_service::FeatureFlagService, | ||
}; | ||
use std::sync::Arc; | ||
|
||
//# @INFO: Preloaded Feature Flag Mocked Data | ||
pub fn create_feature_flag_service() -> FeatureFlagService { | ||
let mock_data = vec![ | ||
feature_flags::Model { | ||
name: "new_flag".to_string(), | ||
description: "New test flag".to_string(), | ||
enabled: true, | ||
}, | ||
feature_flags::Model { | ||
name: "flag1".to_string(), | ||
description: "Test flag 1".to_string(), | ||
enabled: true, | ||
}, | ||
feature_flags::Model { | ||
name: "flag2".to_string(), | ||
description: "Test flag 2".to_string(), | ||
enabled: false, | ||
}, | ||
]; | ||
|
||
let db = create_mock_db::<feature_flags::Entity>(mock_data); | ||
FeatureFlagService::new(db) | ||
} | ||
|
||
pub fn create_test_app(service: FeatureFlagService) -> Router { | ||
routes::create_router(Arc::new(service)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
pub mod feature_flag_mock; | ||
|
||
use axum::body::to_bytes; | ||
use axum::body::Body; | ||
use bytes::Bytes; | ||
use sea_orm::{DatabaseConnection, EntityTrait, MockDatabase, MockExecResult}; | ||
|
||
const MAX_BODY_SIZE: usize = 1024 * 1024; // 1 MB limit, adjust as needed | ||
pub async fn read_body(body: Body) -> Result<Bytes, Box<dyn std::error::Error>> { | ||
Ok(to_bytes(body, MAX_BODY_SIZE).await?) | ||
} | ||
|
||
pub fn create_mock_db<E: EntityTrait>(mock_data: Vec<E::Model>) -> DatabaseConnection | ||
where | ||
E::Model: Clone, | ||
{ | ||
MockDatabase::new(sea_orm::DatabaseBackend::Postgres) | ||
.append_query_results([mock_data]) | ||
.append_exec_results([MockExecResult { | ||
last_insert_id: 1, | ||
rows_affected: 1, | ||
}]) | ||
.into_connection() | ||
} |
Empty file.