Add comprehensive tests for client validation, revenue and expense categories, invoice generation, and schemas
- Implement tests for client validation functions including tax ID, VAT ID, IBAN, BIC, website, and company form validation. - Create tests for revenue and expense categories ensuring all expected categories and labels are present. - Add tests for invoice number generation with various scenarios including prefix handling and sequence padding. - Introduce tests for default categories and their integration, ensuring no overlaps and consistent naming conventions. - Implement Zod schema validation tests for currency, tax rates, IBAN, tax ID, VAT ID, invoices, companies, and customers. - Add utility tests for tax calculations, including item amounts and invoice totals, ensuring correct handling of tax rates and formatting. - Set up Vitest configuration and global test setup for consistent testing environment.
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
/**
|
||||
* Integration Test Setup
|
||||
* Uses a separate test database to avoid polluting development data
|
||||
*/
|
||||
|
||||
const TEST_DATABASE_URL = process.env.TEST_DATABASE_URL ||
|
||||
"mysql://annas_user:annas_password@localhost:3306/annas_rechnungen_test";
|
||||
|
||||
export const testPrisma = new PrismaClient({
|
||||
datasources: {
|
||||
db: {
|
||||
url: TEST_DATABASE_URL,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Setup test database: push schema and seed if needed
|
||||
* Returns true if successful, false if database unavailable
|
||||
*/
|
||||
export async function setupTestDatabase(): Promise<boolean> {
|
||||
console.log("Setting up test database...");
|
||||
|
||||
try {
|
||||
// Push schema to test database
|
||||
execSync(`npx prisma db push --force-reset`, {
|
||||
env: {
|
||||
...process.env,
|
||||
DATABASE_URL: TEST_DATABASE_URL,
|
||||
},
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
console.log("Test database ready");
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn("Test database not available:", error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up test database
|
||||
*/
|
||||
export async function cleanupTestDatabase() {
|
||||
// Delete all data in correct order (respecting foreign keys)
|
||||
const tables = [
|
||||
"audit_logs",
|
||||
"invoice_items",
|
||||
"invoices",
|
||||
"buchung_kategorien",
|
||||
"buchungen",
|
||||
"anlagegueter",
|
||||
"services",
|
||||
"customers",
|
||||
"companies",
|
||||
"users",
|
||||
];
|
||||
|
||||
for (const table of tables) {
|
||||
await testPrisma.$executeRawUnsafe(`DELETE FROM ${table}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test user
|
||||
*/
|
||||
export async function createTestUser(email: string, username: string) {
|
||||
const bcrypt = await import("bcryptjs");
|
||||
const passwordHash = await bcrypt.default.hash("test1234", 10);
|
||||
|
||||
return testPrisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
username,
|
||||
name: "Test User",
|
||||
passwordHash,
|
||||
role: "ADMIN",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test company for a user
|
||||
*/
|
||||
export async function createTestCompany(userId: string, name: string = "Test GmbH") {
|
||||
return testPrisma.company.create({
|
||||
data: {
|
||||
name,
|
||||
address: "Teststraße 1",
|
||||
zip: "12345",
|
||||
city: "Berlin",
|
||||
country: "DE",
|
||||
userId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a test customer for a company
|
||||
*/
|
||||
export async function createTestCustomer(companyId: string, name: string = "Test Customer") {
|
||||
return testPrisma.customer.create({
|
||||
data: {
|
||||
name,
|
||||
address: "Kundenstraße 1",
|
||||
zip: "54321",
|
||||
city: "Hamburg",
|
||||
country: "DE",
|
||||
companyId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate auth cookie for test requests
|
||||
* (Simplified - in real scenario, you'd create a session)
|
||||
*/
|
||||
export function getAuthHeaders(userId: string) {
|
||||
// For integration tests, we might mock the session or use a test session
|
||||
return {
|
||||
"Content-Type": "application/json",
|
||||
"X-Test-User-Id": userId, // Custom header for test auth bypass
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user