Add comprehensive TDD infrastructure with 45 tests
- Add lib crate exposing modules for integration testing - Add dev-dependencies: tokio-test 0.4, tempfile - Refactor parse_csv_fields() as pure function for unit testing - Add field validation (minimum 16 fields required) - Fix repository last_insert_id using SELECT LAST_INSERT_ID() - Add 10 lib tests for CSV parsing and date formatting - Add 10 config tests for environment configuration - Add 7 import tests for CSV file parsing - Add 6 models tests for database structs - Add 12 repository tests for CRUD operations
This commit is contained in:
141
tests/models_test.rs
Normal file
141
tests/models_test.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
//! Tests for the database models.
|
||||
//!
|
||||
//! AI AGENT NOTE: These tests verify model serialization and data integrity.
|
||||
|
||||
use chrono::NaiveDateTime;
|
||||
use invoice_generator::db::models::{NewCard, NewCustomer, NewTransaction};
|
||||
|
||||
/// Tests that NewCustomer can be created with valid data.
|
||||
#[test]
|
||||
fn new_customer_creation() {
|
||||
let customer = NewCustomer {
|
||||
customer_number: "12345".to_string(),
|
||||
card_report_group: 1,
|
||||
};
|
||||
|
||||
assert_eq!(customer.customer_number, "12345");
|
||||
assert_eq!(customer.card_report_group, 1);
|
||||
}
|
||||
|
||||
/// Tests that NewCard can be created with valid data.
|
||||
#[test]
|
||||
fn new_card_creation() {
|
||||
let card = NewCard {
|
||||
card_number: "7825017523017000642".to_string(),
|
||||
customer_id: 42,
|
||||
};
|
||||
|
||||
assert_eq!(card.card_number, "7825017523017000642");
|
||||
assert_eq!(card.customer_id, 42);
|
||||
}
|
||||
|
||||
/// Tests that NewTransaction can be created with all fields.
|
||||
#[test]
|
||||
fn new_transaction_creation() {
|
||||
let date = NaiveDateTime::parse_from_str("2026-02-01 10:15:16", "%Y-%m-%d %H:%M:%S").unwrap();
|
||||
|
||||
let tx = NewTransaction {
|
||||
transaction_date: date,
|
||||
batch_number: "409".to_string(),
|
||||
amount: 559.26,
|
||||
volume: 35.85,
|
||||
price: 15.60,
|
||||
quality_code: 1001,
|
||||
quality_name: "95 Oktan".to_string(),
|
||||
card_number: "7825017523017000642".to_string(),
|
||||
station: "97254".to_string(),
|
||||
terminal: "1".to_string(),
|
||||
pump: "2".to_string(),
|
||||
receipt: "000910".to_string(),
|
||||
control_number: None,
|
||||
customer_id: Some(1),
|
||||
};
|
||||
|
||||
assert_eq!(tx.batch_number, "409");
|
||||
assert_eq!(tx.amount, 559.26);
|
||||
assert_eq!(tx.volume, 35.85);
|
||||
assert_eq!(tx.quality_name, "95 Oktan");
|
||||
assert_eq!(tx.customer_id, Some(1));
|
||||
assert!(tx.control_number.is_none());
|
||||
}
|
||||
|
||||
/// Tests that NewTransaction can be created with control number.
|
||||
#[test]
|
||||
fn new_transaction_with_control_number() {
|
||||
let date = NaiveDateTime::parse_from_str("2026-02-01 06:40:14", "%Y-%m-%d %H:%M:%S").unwrap();
|
||||
|
||||
let tx = NewTransaction {
|
||||
transaction_date: date,
|
||||
batch_number: "409".to_string(),
|
||||
amount: 267.23,
|
||||
volume: 17.13,
|
||||
price: 15.60,
|
||||
quality_code: 1001,
|
||||
quality_name: "95 Oktan".to_string(),
|
||||
card_number: "554477******9952".to_string(),
|
||||
station: "97254".to_string(),
|
||||
terminal: "1".to_string(),
|
||||
pump: "2".to_string(),
|
||||
receipt: "000898".to_string(),
|
||||
control_number: Some("756969".to_string()),
|
||||
customer_id: None,
|
||||
};
|
||||
|
||||
assert_eq!(tx.control_number, Some("756969".to_string()));
|
||||
assert!(tx.customer_id.is_none());
|
||||
}
|
||||
|
||||
/// Tests decimal precision for monetary values.
|
||||
#[test]
|
||||
fn transaction_decimal_precision() {
|
||||
let date = NaiveDateTime::parse_from_str("2026-02-01 10:15:16", "%Y-%m-%d %H:%M:%S").unwrap();
|
||||
|
||||
let tx = NewTransaction {
|
||||
transaction_date: date,
|
||||
batch_number: "409".to_string(),
|
||||
amount: 123.45,
|
||||
volume: 7.891,
|
||||
price: 15.625,
|
||||
quality_code: 1001,
|
||||
quality_name: "95 Oktan".to_string(),
|
||||
card_number: "CARD123".to_string(),
|
||||
station: "1".to_string(),
|
||||
terminal: "1".to_string(),
|
||||
pump: "1".to_string(),
|
||||
receipt: "001".to_string(),
|
||||
control_number: None,
|
||||
customer_id: None,
|
||||
};
|
||||
|
||||
// Verify precision is maintained
|
||||
assert_eq!(tx.amount, 123.45);
|
||||
assert_eq!(tx.volume, 7.891);
|
||||
assert_eq!(tx.price, 15.625);
|
||||
}
|
||||
|
||||
/// Tests that anonymized transactions have no customer.
|
||||
#[test]
|
||||
fn anonymized_transaction_has_no_customer() {
|
||||
let date = NaiveDateTime::parse_from_str("2026-02-01 06:40:14", "%Y-%m-%d %H:%M:%S").unwrap();
|
||||
|
||||
let tx = NewTransaction {
|
||||
transaction_date: date,
|
||||
batch_number: "409".to_string(),
|
||||
amount: 267.23,
|
||||
volume: 17.13,
|
||||
price: 15.60,
|
||||
quality_code: 1001,
|
||||
quality_name: "95 Oktan".to_string(),
|
||||
card_number: "554477******9952".to_string(),
|
||||
station: "97254".to_string(),
|
||||
terminal: "1".to_string(),
|
||||
pump: "2".to_string(),
|
||||
receipt: "000898".to_string(),
|
||||
control_number: Some("756969".to_string()),
|
||||
customer_id: None,
|
||||
};
|
||||
|
||||
assert!(tx.customer_id.is_none());
|
||||
// Card number is still stored
|
||||
assert_eq!(tx.card_number, "554477******9952");
|
||||
}
|
||||
Reference in New Issue
Block a user