Spaces:
Paused
Paused
| import { describe, it, expect } from "vitest"; | |
| import { | |
| PostizErrorCode, | |
| PostizError, | |
| PostizAuthError, | |
| PostizRateLimitError, | |
| PostizNotFoundError, | |
| PostizValidationFormatError, | |
| PostizPlatformError, | |
| PostizNetworkError, | |
| PostizTimeoutError, | |
| PostizServiceUnavailableError, | |
| isPostizError, | |
| isRecoverableError, | |
| } from "../types/postiz-errors.js"; | |
| describe("PostizError", () => { | |
| describe("PostizErrorCode enum", () => { | |
| it("should have all expected error codes", () => { | |
| expect(PostizErrorCode.AUTH_ERROR).toBe("AUTH_ERROR"); | |
| expect(PostizErrorCode.RATE_LIMIT).toBe("RATE_LIMIT"); | |
| expect(PostizErrorCode.NOT_FOUND).toBe("NOT_FOUND"); | |
| expect(PostizErrorCode.VALIDATION_ERROR).toBe("VALIDATION_ERROR"); | |
| expect(PostizErrorCode.PLATFORM_ERROR).toBe("PLATFORM_ERROR"); | |
| expect(PostizErrorCode.NETWORK_ERROR).toBe("NETWORK_ERROR"); | |
| expect(PostizErrorCode.TIMEOUT_ERROR).toBe("TIMEOUT_ERROR"); | |
| expect(PostizErrorCode.SERVICE_UNAVAILABLE).toBe("SERVICE_UNAVAILABLE"); | |
| expect(PostizErrorCode.UNKNOWN_ERROR).toBe("UNKNOWN_ERROR"); | |
| }); | |
| }); | |
| describe("PostizError base class", () => { | |
| it("should create error with all properties", () => { | |
| const details = { field: "test" }; | |
| const error = new PostizError( | |
| "Test error", | |
| PostizErrorCode.UNKNOWN_ERROR, | |
| 500, | |
| details, | |
| true, | |
| 60 | |
| ); | |
| expect(error.message).toBe("Test error"); | |
| expect(error.name).toBe("PostizError"); | |
| expect(error.code).toBe(PostizErrorCode.UNKNOWN_ERROR); | |
| expect(error.statusCode).toBe(500); | |
| expect(error.details).toEqual(details); | |
| expect(error.recoverable).toBe(true); | |
| expect(error.retryAfter).toBe(60); | |
| }); | |
| it("should have default recoverable value of false", () => { | |
| const error = new PostizError( | |
| "Test error", | |
| PostizErrorCode.UNKNOWN_ERROR, | |
| 500 | |
| ); | |
| expect(error.recoverable).toBe(false); | |
| expect(error.retryAfter).toBeUndefined(); | |
| }); | |
| it("should be an instance of Error", () => { | |
| const error = new PostizError( | |
| "Test error", | |
| PostizErrorCode.UNKNOWN_ERROR, | |
| 500 | |
| ); | |
| expect(error).toBeInstanceOf(Error); | |
| expect(error).toBeInstanceOf(PostizError); | |
| }); | |
| }); | |
| describe("PostizAuthError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizAuthError("Invalid API key"); | |
| expect(error.message).toBe("Invalid API key"); | |
| expect(error.name).toBe("PostizAuthError"); | |
| expect(error.code).toBe(PostizErrorCode.AUTH_ERROR); | |
| expect(error.statusCode).toBe(401); | |
| expect(error.recoverable).toBe(false); | |
| }); | |
| it("should have default message", () => { | |
| const error = new PostizAuthError(); | |
| expect(error.message).toBe("Authentication failed"); | |
| }); | |
| it("should include details when provided", () => { | |
| const details = { reason: "expired" }; | |
| const error = new PostizAuthError("Token expired", details); | |
| expect(error.details).toEqual(details); | |
| }); | |
| }); | |
| describe("PostizRateLimitError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizRateLimitError("Rate limit exceeded", 120); | |
| expect(error.message).toBe("Rate limit exceeded"); | |
| expect(error.name).toBe("PostizRateLimitError"); | |
| expect(error.code).toBe(PostizErrorCode.RATE_LIMIT); | |
| expect(error.statusCode).toBe(429); | |
| expect(error.recoverable).toBe(true); | |
| expect(error.retryAfter).toBe(120); | |
| }); | |
| it("should have default values", () => { | |
| const error = new PostizRateLimitError(); | |
| expect(error.message).toBe("Rate limit exceeded"); | |
| expect(error.retryAfter).toBe(60); | |
| }); | |
| it("should allow custom retryAfter value", () => { | |
| const error = new PostizRateLimitError("Slow down", 300); | |
| expect(error.retryAfter).toBe(300); | |
| }); | |
| }); | |
| describe("PostizNotFoundError", () => { | |
| it("should create error with resource name only", () => { | |
| const error = new PostizNotFoundError("Post"); | |
| expect(error.message).toBe("Post not found"); | |
| expect(error.name).toBe("PostizNotFoundError"); | |
| expect(error.code).toBe(PostizErrorCode.NOT_FOUND); | |
| expect(error.statusCode).toBe(404); | |
| expect(error.recoverable).toBe(false); | |
| }); | |
| it("should create error with resource name and identifier", () => { | |
| const error = new PostizNotFoundError("Post", "abc123"); | |
| expect(error.message).toBe("Post not found: abc123"); | |
| }); | |
| }); | |
| describe("PostizValidationFormatError", () => { | |
| it("should create error with correct properties", () => { | |
| const validationErrors = [{ field: "content", message: "Required" }]; | |
| const error = new PostizValidationFormatError( | |
| "Validation failed", | |
| validationErrors | |
| ); | |
| expect(error.message).toBe("Validation failed"); | |
| expect(error.name).toBe("PostizValidationFormatError"); | |
| expect(error.code).toBe(PostizErrorCode.VALIDATION_ERROR); | |
| expect(error.statusCode).toBe(400); | |
| expect(error.recoverable).toBe(false); | |
| expect(error.validationErrors).toEqual(validationErrors); | |
| }); | |
| it("should work without validation errors", () => { | |
| const error = new PostizValidationFormatError("Invalid format"); | |
| expect(error.validationErrors).toBeUndefined(); | |
| }); | |
| }); | |
| describe("PostizPlatformError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizPlatformError( | |
| "twitter", | |
| "Character limit exceeded", | |
| "CHAR_LIMIT" | |
| ); | |
| expect(error.message).toBe("Character limit exceeded"); | |
| expect(error.name).toBe("PostizPlatformError"); | |
| expect(error.code).toBe(PostizErrorCode.PLATFORM_ERROR); | |
| expect(error.statusCode).toBe(400); | |
| expect(error.recoverable).toBe(false); | |
| expect(error.platform).toBe("twitter"); | |
| expect(error.platformCode).toBe("CHAR_LIMIT"); | |
| }); | |
| it("should work without platform code", () => { | |
| const error = new PostizPlatformError("instagram", "Media not supported"); | |
| expect(error.platform).toBe("instagram"); | |
| expect(error.platformCode).toBeUndefined(); | |
| }); | |
| }); | |
| describe("PostizNetworkError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizNetworkError("Connection refused"); | |
| expect(error.message).toBe("Connection refused"); | |
| expect(error.name).toBe("PostizNetworkError"); | |
| expect(error.code).toBe(PostizErrorCode.NETWORK_ERROR); | |
| expect(error.statusCode).toBe(0); | |
| expect(error.recoverable).toBe(true); | |
| }); | |
| it("should have default message", () => { | |
| const error = new PostizNetworkError(); | |
| expect(error.message).toBe("Network error"); | |
| }); | |
| it("should include details when provided", () => { | |
| const details = { originalError: new Error("ECONNREFUSED") }; | |
| const error = new PostizNetworkError("Connection failed", details); | |
| expect(error.details).toEqual(details); | |
| }); | |
| }); | |
| describe("PostizTimeoutError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizTimeoutError("Request timed out after 30s"); | |
| expect(error.message).toBe("Request timed out after 30s"); | |
| expect(error.name).toBe("PostizTimeoutError"); | |
| expect(error.code).toBe(PostizErrorCode.TIMEOUT_ERROR); | |
| expect(error.statusCode).toBe(504); | |
| expect(error.recoverable).toBe(true); | |
| }); | |
| it("should have default message", () => { | |
| const error = new PostizTimeoutError(); | |
| expect(error.message).toBe("Request timeout"); | |
| }); | |
| }); | |
| describe("PostizServiceUnavailableError", () => { | |
| it("should create error with correct properties", () => { | |
| const error = new PostizServiceUnavailableError("Service is down"); | |
| expect(error.message).toBe("Service is down"); | |
| expect(error.name).toBe("PostizServiceUnavailableError"); | |
| expect(error.code).toBe(PostizErrorCode.SERVICE_UNAVAILABLE); | |
| expect(error.statusCode).toBe(503); | |
| expect(error.recoverable).toBe(true); | |
| }); | |
| it("should have default message", () => { | |
| const error = new PostizServiceUnavailableError(); | |
| expect(error.message).toBe("Service unavailable"); | |
| }); | |
| }); | |
| }); | |
| describe("Helper functions", () => { | |
| describe("isPostizError", () => { | |
| it("should return true for PostizError instances", () => { | |
| const error = new PostizError( | |
| "Test", | |
| PostizErrorCode.UNKNOWN_ERROR, | |
| 500 | |
| ); | |
| expect(isPostizError(error)).toBe(true); | |
| }); | |
| it("should return true for subclass instances", () => { | |
| expect(isPostizError(new PostizAuthError())).toBe(true); | |
| expect(isPostizError(new PostizRateLimitError())).toBe(true); | |
| expect(isPostizError(new PostizNotFoundError("Test"))).toBe(true); | |
| expect(isPostizError(new PostizNetworkError())).toBe(true); | |
| }); | |
| it("should return false for regular Error", () => { | |
| const error = new Error("Test error"); | |
| expect(isPostizError(error)).toBe(false); | |
| }); | |
| it("should return false for non-error values", () => { | |
| expect(isPostizError(null)).toBe(false); | |
| expect(isPostizError(undefined)).toBe(false); | |
| expect(isPostizError("error")).toBe(false); | |
| expect(isPostizError({})).toBe(false); | |
| }); | |
| }); | |
| describe("isRecoverableError", () => { | |
| it("should return true for recoverable PostizError", () => { | |
| expect(isRecoverableError(new PostizRateLimitError())).toBe(true); | |
| expect(isRecoverableError(new PostizNetworkError())).toBe(true); | |
| expect(isRecoverableError(new PostizTimeoutError())).toBe(true); | |
| expect(isRecoverableError(new PostizServiceUnavailableError())).toBe(true); | |
| }); | |
| it("should return false for non-recoverable PostizError", () => { | |
| expect(isRecoverableError(new PostizAuthError())).toBe(false); | |
| expect(isRecoverableError(new PostizNotFoundError("Test"))).toBe(false); | |
| expect(isRecoverableError(new PostizValidationFormatError("Test"))).toBe(false); | |
| expect(isRecoverableError(new PostizPlatformError("x", "Test"))).toBe(false); | |
| }); | |
| it("should return false for regular Error", () => { | |
| const error = new Error("Test error"); | |
| expect(isRecoverableError(error)).toBe(false); | |
| }); | |
| it("should return false for non-error values", () => { | |
| expect(isRecoverableError(null)).toBe(false); | |
| expect(isRecoverableError(undefined)).toBe(false); | |
| expect(isRecoverableError("error")).toBe(false); | |
| }); | |
| it("should return true for custom PostizError with recoverable=true", () => { | |
| const error = new PostizError( | |
| "Custom error", | |
| PostizErrorCode.UNKNOWN_ERROR, | |
| 500, | |
| undefined, | |
| true | |
| ); | |
| expect(isRecoverableError(error)).toBe(true); | |
| }); | |
| }); | |
| }); | |