Establishes testing infrastructure for reliable development. tests/fixtures/ - GitLab API response samples: - gitlab_issue.json: Single issue with full metadata - gitlab_issues_page.json: Paginated issue list response - gitlab_discussion.json: Discussion thread with notes - gitlab_discussions_page.json: Paginated discussions response All fixtures captured from real GitLab API responses with sensitive data redacted, ensuring tests match actual behavior. tests/gitlab_types_tests.rs - Type deserialization tests: - Validates serde parsing of all GitLab API types - Tests edge cases: null fields, empty arrays, nested objects - Ensures GitLabIssue, GitLabDiscussion, GitLabNote parse correctly - Verifies optional fields handle missing data gracefully - Tests author/assignee extraction from various formats tests/fixture_tests.rs - Integration with fixtures: - Loads fixture files and validates parsing - Tests transformer functions produce correct database rows - Verifies IssueWithMetadata extracts labels and assignees - Tests NormalizedDiscussion/NormalizedNote structure - Validates raw payload preservation logic tests/migration_tests.rs - Database schema tests: - Creates in-memory SQLite for isolation - Runs all migrations and verifies schema - Tests table creation with expected columns - Validates foreign key constraints - Tests index creation for query performance - Verifies idempotent migration behavior Test infrastructure uses: - tempfile for isolated database instances - wiremock for HTTP mocking (available for future API tests) - Standard Rust #[test] attributes Run with: cargo test Run single: cargo test test_name Run with output: cargo test -- --nocapture Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
103 lines
3.2 KiB
Rust
103 lines
3.2 KiB
Rust
//! Tests for test fixtures - verifies they deserialize correctly.
|
|
|
|
use gi::gitlab::types::{GitLabDiscussion, GitLabIssue};
|
|
use serde::de::DeserializeOwned;
|
|
use std::path::PathBuf;
|
|
|
|
fn load_fixture<T: DeserializeOwned>(name: &str) -> T {
|
|
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.join("tests/fixtures")
|
|
.join(name);
|
|
let content = std::fs::read_to_string(&path)
|
|
.unwrap_or_else(|_| panic!("Failed to read fixture: {}", name));
|
|
serde_json::from_str(&content)
|
|
.unwrap_or_else(|e| panic!("Failed to parse fixture {}: {}", name, e))
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_gitlab_issue_deserializes() {
|
|
let issue: GitLabIssue = load_fixture("gitlab_issue.json");
|
|
|
|
assert_eq!(issue.id, 12345);
|
|
assert_eq!(issue.iid, 42);
|
|
assert_eq!(issue.project_id, 100);
|
|
assert_eq!(issue.title, "Test issue title");
|
|
assert!(issue.description.is_some());
|
|
assert_eq!(issue.state, "opened");
|
|
assert_eq!(issue.author.username, "testuser");
|
|
assert_eq!(issue.labels.len(), 2);
|
|
assert!(issue.labels.contains(&"bug".to_string()));
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_gitlab_issues_page_deserializes() {
|
|
let issues: Vec<GitLabIssue> = load_fixture("gitlab_issues_page.json");
|
|
|
|
assert!(
|
|
issues.len() >= 3,
|
|
"Need at least 3 issues for pagination tests"
|
|
);
|
|
|
|
// Check first issue has labels
|
|
assert!(!issues[0].labels.is_empty());
|
|
|
|
// Check second issue has null description and empty labels
|
|
assert!(issues[1].description.is_none());
|
|
assert!(issues[1].labels.is_empty());
|
|
|
|
// Check third issue has multiple labels
|
|
assert!(issues[2].labels.len() >= 3);
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_gitlab_discussion_deserializes() {
|
|
let discussion: GitLabDiscussion = load_fixture("gitlab_discussion.json");
|
|
|
|
assert_eq!(discussion.id, "6a9c1750b37d513a43987b574953fceb50b03ce7");
|
|
assert!(!discussion.individual_note);
|
|
assert!(discussion.notes.len() >= 2);
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_gitlab_discussions_page_deserializes() {
|
|
let discussions: Vec<GitLabDiscussion> = load_fixture("gitlab_discussions_page.json");
|
|
|
|
assert!(
|
|
discussions.len() >= 3,
|
|
"Need multiple discussions for testing"
|
|
);
|
|
|
|
// Check we have both individual_note=true and individual_note=false
|
|
let has_individual = discussions.iter().any(|d| d.individual_note);
|
|
let has_threaded = discussions.iter().any(|d| !d.individual_note);
|
|
assert!(
|
|
has_individual,
|
|
"Need at least one individual_note=true discussion"
|
|
);
|
|
assert!(
|
|
has_threaded,
|
|
"Need at least one individual_note=false discussion"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_has_system_note() {
|
|
let discussion: GitLabDiscussion = load_fixture("gitlab_discussion.json");
|
|
|
|
let has_system_note = discussion.notes.iter().any(|n| n.system);
|
|
assert!(
|
|
has_system_note,
|
|
"Fixture should include at least one system note"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn fixture_discussions_page_has_resolved_discussion() {
|
|
let discussions: Vec<GitLabDiscussion> = load_fixture("gitlab_discussions_page.json");
|
|
|
|
let has_resolved = discussions
|
|
.iter()
|
|
.any(|d| d.notes.iter().any(|n| n.resolved));
|
|
assert!(has_resolved, "Should have at least one resolved discussion");
|
|
}
|