Add comprehensive documentation and unit tests

Documentation:
- Add detailed README files for all services (auth, character, database, launcher, packet, utils, world)
- Create API documentation for the database service with detailed endpoint specifications
- Document database schema and relationships
- Add service architecture overviews and configuration instructions

Unit Tests:
- Implement comprehensive test suite for database repositories (user, character, session)
- Add gRPC service tests for database interactions
- Create tests for packet service components (bufferpool, connection, packets)
- Add utility service tests (health check, logging, load balancer, redis cache, service discovery)
- Implement auth service user tests
- Add character service tests

Code Structure:
- Reorganize test files into a more consistent structure
- Create a dedicated tests crate for integration testing
- Add test helpers and mock implementations for easier testing
This commit is contained in:
2025-04-09 13:29:38 -04:00
parent d47d5f44b1
commit a8755bd3de
85 changed files with 4218 additions and 764 deletions

View File

@@ -0,0 +1,137 @@
use database_service::users::User;
use mockall::predicate::*;
use mockall::predicate::eq;
use mockall::mock;
use std::sync::Arc;
use chrono::NaiveDateTime;
// Mock the UserRepository
mock! {
pub UserRepository {
fn get_user_by_id(&self, user_id: i32) -> Result<User, sqlx::Error>;
fn get_user_by_username(&self, username: &str) -> Result<User, sqlx::Error>;
fn get_user_by_email(&self, email: &str) -> Result<User, sqlx::Error>;
}
}
// Mock the CharacterRepository
mock! {
pub CharacterRepository {
fn get_character_by_id(&self, character_id: i32) -> Result<database_service::characters::Character, sqlx::Error>;
fn get_character_list(&self, user_id: String) -> Result<Vec<database_service::characters::Character>, sqlx::Error>;
fn create_character(
&self,
user_id: String,
name: &str,
inventory: serde_json::Value,
skills: serde_json::Value,
stats: serde_json::Value,
looks: serde_json::Value,
position: serde_json::Value,
) -> Result<i32, sqlx::Error>;
fn delete_character(&self, character_id: i32, delete_type: i32) -> Result<i64, sqlx::Error>;
}
}
// Mock the SessionRepository
mock! {
pub SessionRepository {
fn get_session(&self, session_id: &str) -> Result<database_service::sessions::Session, sqlx::Error>;
fn refresh_session(&self, session_id: &str) -> Result<database_service::sessions::Session, sqlx::Error>;
}
}
// Mock the Database struct
struct MockDatabase<U, C, S> {
user_repo: Arc<U>,
character_repo: Arc<C>,
session_repo: Arc<S>,
}
type MockDatabaseWithMocks = MockDatabase<MockUserRepository, MockCharacterRepository, MockSessionRepository>;
#[tokio::test]
async fn test_user_repository_mock() {
// Create a mock UserRepository
let mut mock_user_repo = MockUserRepository::new();
// Set up expectations
mock_user_repo
.expect_get_user_by_id()
.with(eq(123))
.times(1)
.returning(|_| {
Ok(User {
id: 123,
name: "mock_user".to_string(),
email: "mock@example.com".to_string(),
role: "user".to_string(),
created_at: NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
updated_at: NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
})
});
// Test the mock
let user = mock_user_repo.get_user_by_id(123).unwrap();
assert_eq!(user.id, 123);
assert_eq!(user.name, "mock_user");
assert_eq!(user.email, "mock@example.com");
}
#[tokio::test]
async fn test_character_repository_mock() {
// Create a mock CharacterRepository
let mut mock_character_repo = MockCharacterRepository::new();
// Set up expectations
mock_character_repo
.expect_get_character_by_id()
.with(eq(456))
.times(1)
.returning(|_| {
Ok(database_service::characters::Character {
id: 456,
user_id: "123".to_string(),
name: "mock_character".to_string(),
money: 1000,
inventory: serde_json::json!({}),
stats: serde_json::json!({}),
skills: serde_json::json!({}),
looks: serde_json::json!({}),
position: serde_json::json!({}),
created_at: NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
updated_at: NaiveDateTime::from_timestamp_opt(0, 0).unwrap(),
deleted_at: None,
is_active: true,
})
});
// Test the mock
let character = mock_character_repo.get_character_by_id(456).unwrap();
assert_eq!(character.id, 456);
assert_eq!(character.name, "mock_character");
assert_eq!(character.user_id, "123");
}
#[tokio::test]
async fn test_session_repository_mock() {
// Create a mock SessionRepository
let mut mock_session_repo = MockSessionRepository::new();
// Set up expectations
mock_session_repo
.expect_get_session()
.with(eq("session123"))
.times(1)
.returning(|_| {
Ok(database_service::sessions::Session {
id: "session123".to_string(),
user_id: "123".to_string(),
})
});
// Test the mock
let session = mock_session_repo.get_session("session123").unwrap();
assert_eq!(session.id, "session123");
assert_eq!(session.user_id, "123");
}