UNPKG

@kenniy/godeye-data-contracts

Version:

Enterprise-grade base repository architecture for GOD-EYE microservices with zero overhead and maximum code reuse

309 lines (308 loc) 13.9 kB
"use strict"; /** * Complete Integration Test * Tests the entire package working together as described in usage guides */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("../index"); const class_validator_1 = require("class-validator"); const class_transformer_1 = require("class-transformer"); const auth_constants_1 = require("../constants/auth.constants"); // Test DTO matching usage guide examples class UserResponseDto { } __decorate([ (0, index_1.IsValidId)(), __metadata("design:type", String) ], UserResponseDto.prototype, "id", void 0); __decorate([ (0, index_1.IsRequiredEmail)(), (0, index_1.ToLowerCase)(), (0, index_1.Trim)(), __metadata("design:type", String) ], UserResponseDto.prototype, "email", void 0); describe("Complete Integration Test", () => { describe("Usage Guide Compliance - ResponseFactory", () => { it("should match simple-response-usage.md examples", () => { // Test simple success response const userData = { id: "123", name: "John Doe", email: "john@example.com", }; const response = index_1.ResponseFactory.success(userData, "User found"); expect(response).toMatchObject({ success: true, data: userData, message: "User found", status_code: 200, }); expect(response.timestamp).toBeDefined(); expect(response.trace_id).toBeDefined(); expect(response.time_ms).toBeDefined(); }); it("should auto-detect paginated responses", () => { const paginatedUsers = { items: [ { id: "1", name: "User 1" }, { id: "2", name: "User 2" }, ], total: 50, page: 2, limit: 20, }; const response = index_1.ResponseFactory.success(paginatedUsers); expect(response.success).toBe(true); expect(response.data.items).toEqual(paginatedUsers.items); expect(response.data).toMatchObject({ items: paginatedUsers.items, total: 50, page: 2, limit: 20, totalPages: 3, hasNext: true, hasPrev: true, }); }); it("should handle different pagination formats", () => { // Test 'data' format const dataFormat = { data: [{ id: "1" }], total: 5, page: 1, limit: 10, }; const dataResponse = index_1.ResponseFactory.success(dataFormat); expect(dataResponse.data.items).toEqual([{ id: "1" }]); expect(dataResponse.data.total).toBe(5); // Test 'results' format const resultsFormat = { results: [{ id: "2" }], count: 3, }; const resultsResponse = index_1.ResponseFactory.success(resultsFormat); expect(resultsResponse.data.items).toEqual([{ id: "2" }]); expect(resultsResponse.data.total).toBe(3); }); }); describe("Usage Guide Compliance - Validation System", () => { it("should match validation-pipeline-usage.md examples", async () => { class TestDto { } __decorate([ (0, index_1.IsValidId)(), __metadata("design:type", String) ], TestDto.prototype, "userId", void 0); __decorate([ (0, index_1.IsRequiredEmail)(), (0, index_1.ToLowerCase)(), (0, index_1.Trim)(), __metadata("design:type", String) ], TestDto.prototype, "email", void 0); // Test valid data const validInput = { userId: "550e8400-e29b-41d4-a716-446655440000", // UUID email: " TEST@EXAMPLE.COM ", }; const dto = (0, class_transformer_1.plainToClass)(TestDto, validInput); expect(dto.email).toBe("test@example.com"); // Transformed const errors = await (0, class_validator_1.validate)(dto); expect(errors).toHaveLength(0); // Test MongoDB ObjectId const mongoInput = { userId: "507f1f77bcf86cd799439011", email: "mongo@example.com", }; const mongoDto = (0, class_transformer_1.plainToClass)(TestDto, mongoInput); const mongoErrors = await (0, class_validator_1.validate)(mongoDto); expect(mongoErrors).toHaveLength(0); }); it("should validate with ValidationUtils", () => { // UUID validation expect(index_1.ValidationUtils.isValidId("550e8400-e29b-41d4-a716-446655440000")).toBe(true); // MongoDB ObjectId validation expect(index_1.ValidationUtils.isValidId("507f1f77bcf86cd799439011")).toBe(true); // Numeric ID validation expect(index_1.ValidationUtils.isValidId("12345")).toBe(true); // Invalid ID validation expect(index_1.ValidationUtils.isValidId("invalid-id")).toBe(false); // Email validation expect(index_1.ValidationUtils.isValidEmail("test@example.com")).toBe(true); expect(index_1.ValidationUtils.isValidEmail("invalid-email")).toBe(false); }); }); describe("Usage Guide Compliance - Kong Authentication", () => { it("should match kong-usage.md examples", () => { const headers = { [auth_constants_1.KONG_HEADERS.USER_ID]: "123", [auth_constants_1.KONG_HEADERS.USER_EMAIL]: "user@example.com", [auth_constants_1.KONG_HEADERS.USER_TYPE]: "patient,admin", [auth_constants_1.KONG_HEADERS.PROFILE_ID]: "profile-456", }; const userContext = (0, index_1.extractKongUserContext)(headers); expect(userContext).toMatchObject({ id: "123", email: "user@example.com", type: ["patient", "admin"], profile_id: "profile-456", }); }); it("should normalize headers correctly", () => { const rawHeaders = { "x-user-id": "123", "x-user-type": ["admin", "user"], "content-type": "application/json", }; const normalized = (0, index_1.normalizeHeaders)(rawHeaders); expect(normalized).toEqual({ "x-user-id": "123", "x-user-type": "admin,user", "content-type": "application/json", }); }); }); describe("Usage Guide Compliance - Bootstrap System", () => { it("should match bootstrap-usage.md configuration structure", () => { const basicConfig = { serviceName: "my-service", port: 3003, enableSwagger: true, }; const advancedConfig = { serviceName: "my-service", port: 3003, swagger: { enabled: true, title: "My Service API", description: "API documentation with ResponseFactory patterns", version: "1.0.0", path: "docs", }, cors: { enabled: true, origins: ["http://localhost:3000"], credentials: true, }, validation: { whitelist: true, transform: true, }, }; // Test that configurations match expected structure expect(basicConfig.serviceName).toBe("my-service"); expect(basicConfig.enableSwagger).toBe(true); expect(advancedConfig.swagger?.title).toBe("My Service API"); expect(advancedConfig.cors?.origins).toContain("http://localhost:3000"); expect(advancedConfig.validation?.whitelist).toBe(true); }); }); describe("End-to-End Workflow Test", () => { it("should support complete microservice setup workflow", async () => { // 1. Validation - Transform and validate user input class CreateUserDto { } __decorate([ (0, index_1.IsRequiredEmail)(), (0, index_1.ToLowerCase)(), (0, index_1.Trim)(), __metadata("design:type", String) ], CreateUserDto.prototype, "email", void 0); __decorate([ (0, index_1.IsValidId)(), __metadata("design:type", String) ], CreateUserDto.prototype, "profileId", void 0); const rawInput = { email: " JOHN@EXAMPLE.COM ", profileId: "550e8400-e29b-41d4-a716-446655440000", }; const dto = (0, class_transformer_1.plainToClass)(CreateUserDto, rawInput); expect(dto.email).toBe("john@example.com"); // Transformed const validationErrors = await (0, class_validator_1.validate)(dto); expect(validationErrors).toHaveLength(0); // 2. Kong Auth - Extract user context from headers const kongHeaders = { [auth_constants_1.KONG_HEADERS.USER_ID]: "456", [auth_constants_1.KONG_HEADERS.USER_EMAIL]: "admin@example.com", [auth_constants_1.KONG_HEADERS.USER_TYPE]: "admin", }; const userContext = (0, index_1.extractKongUserContext)(kongHeaders); expect(userContext.id).toBe("456"); expect(userContext.type).toContain("admin"); // 3. Response Factory - Create standardized responses const createdUser = { id: dto.profileId, email: dto.email, createdBy: userContext.id, createdAt: new Date().toISOString(), }; const successResponse = index_1.ResponseFactory.success(createdUser, "User created successfully"); expect(successResponse).toMatchObject({ success: true, data: createdUser, message: "User created successfully", status_code: 200, }); // 4. Error handling const errorResponse = index_1.ResponseFactory.validationError("Validation failed", ["Email is required", "Invalid ID format"]); expect(errorResponse).toMatchObject({ success: false, error: "Validation Error", status_code: 422, }); expect(errorResponse.metadata?.validation_errors).toEqual([ "Email is required", "Invalid ID format", ]); // 5. Pagination response const usersList = { items: [createdUser], total: 1, page: 1, limit: 20, }; const paginatedResponse = index_1.ResponseFactory.success(usersList); expect(paginatedResponse.data.items).toBeDefined(); expect(paginatedResponse.data.total).toBe(1); }); }); describe("Package Consistency", () => { it("should maintain consistent response format across all methods", () => { const baseFields = [ "success", "status_code", "timestamp", "trace_id", "time_ms", ]; const successResponse = index_1.ResponseFactory.success({ test: true }); const errorResponse = index_1.ResponseFactory.error("Test Error", "Test message", 400); const notFoundResponse = index_1.ResponseFactory.notFound("Not found"); baseFields.forEach((field) => { expect(successResponse).toHaveProperty(field); expect(errorResponse).toHaveProperty(field); expect(notFoundResponse).toHaveProperty(field); }); }); it("should maintain consistent trace_id format", () => { const response1 = index_1.ResponseFactory.success({ test: 1 }); const response2 = index_1.ResponseFactory.error("Error", "Test error"); expect(response1.trace_id).toMatch(/^trace_\d+_[a-zA-Z0-9]+$/); expect(response2.trace_id).toMatch(/^trace_\d+_[a-zA-Z0-9]+$/); }); it("should provide consistent timing information", () => { const response = index_1.ResponseFactory.success({ test: true }); expect(typeof response.time_ms).toBe("number"); expect(response.time_ms).toBeGreaterThanOrEqual(0); expect(response.timestamp).toMatch(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/); }); }); });