720 lines
20 KiB
TypeScript
720 lines
20 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import {
|
|
// Schemas
|
|
vinSchema,
|
|
loginSchema,
|
|
registerSchema,
|
|
forgotPasswordSchema,
|
|
resetPasswordSchema,
|
|
changelogChangeTypeEnum,
|
|
changelogEntrySchema,
|
|
createChangelogEntrySchema,
|
|
updateChangelogEntrySchema,
|
|
paginationSchema,
|
|
// Utils
|
|
isValidVin,
|
|
validateVinCheckDigit,
|
|
extractWmi,
|
|
extractModelYear,
|
|
formatTRY,
|
|
kurusToLira,
|
|
liraToKurus,
|
|
formatVin,
|
|
formatDate,
|
|
formatDateTime,
|
|
slugify,
|
|
generateReferralCode,
|
|
// Constants
|
|
VIN_REGEX,
|
|
EMAIL_REGEX,
|
|
OEM_CODE_REGEX,
|
|
PLANS,
|
|
REFERRAL_REWARDS,
|
|
CURRENCY,
|
|
FULL_PLAN_BRAND_LIMIT,
|
|
ERROR_CODES,
|
|
} from "./index";
|
|
|
|
// --------------- schemas/vin ---------------
|
|
|
|
describe("vinSchema", () => {
|
|
const validVin = "WVWZZZ1JZ3W597935";
|
|
|
|
it("accepts a valid 17-character VIN", () => {
|
|
const result = vinSchema.safeParse(validVin);
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("transforms VIN to uppercase after validation", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1JZ3W597935");
|
|
expect(result.success).toBe(true);
|
|
if (result.success) {
|
|
expect(result.data).toBe("WVWZZZ1JZ3W597935");
|
|
}
|
|
});
|
|
|
|
it("rejects VIN shorter than 17 chars", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1JZ3W59793");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects VIN longer than 17 chars", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1JZ3W597935X");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects VIN with I character (not allowed)", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1IZ3W597935");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects VIN with O character (not allowed)", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1OZ3W597935");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects VIN with Q character (not allowed)", () => {
|
|
const result = vinSchema.safeParse("WVWZZZ1QZ3W597935");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty string", () => {
|
|
const result = vinSchema.safeParse("");
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("accepts 17-char uppercase string with valid chars", () => {
|
|
const result = vinSchema.safeParse("ABCDEFGHJKLMNPRST");
|
|
expect(result.success).toBe(true); // This is 17 valid chars (no I, O, Q)
|
|
});
|
|
|
|
it("rejects string with lowercase chars (regex runs before transform)", () => {
|
|
const result = vinSchema.safeParse("abcdefghjklmnprst");
|
|
expect(result.success).toBe(false); // VIN_REGEX requires uppercase
|
|
});
|
|
});
|
|
|
|
// --------------- schemas/auth ---------------
|
|
|
|
describe("loginSchema", () => {
|
|
it("accepts valid login", () => {
|
|
const result = loginSchema.safeParse({
|
|
email: "user@example.com",
|
|
password: "password123",
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("rejects invalid email", () => {
|
|
const result = loginSchema.safeParse({
|
|
email: "not-an-email",
|
|
password: "password123",
|
|
});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects short password", () => {
|
|
const result = loginSchema.safeParse({
|
|
email: "user@example.com",
|
|
password: "short",
|
|
});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects missing password", () => {
|
|
const result = loginSchema.safeParse({ email: "user@example.com" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects missing email", () => {
|
|
const result = loginSchema.safeParse({ password: "password123" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("registerSchema", () => {
|
|
const validRegister = {
|
|
name: "John Doe",
|
|
email: "john@example.com",
|
|
password: "Aa123456",
|
|
};
|
|
|
|
it("accepts valid registration", () => {
|
|
const result = registerSchema.safeParse(validRegister);
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("rejects short name", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, name: "J" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects name exceeding 100 chars", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, name: "A".repeat(101) });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects invalid email", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, email: "bad-email" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects password without uppercase", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, password: "aa123456" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects password without lowercase", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, password: "AA123456" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects password without number", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, password: "Aaabcdef" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects password shorter than 8 chars", () => {
|
|
const result = registerSchema.safeParse({ ...validRegister, password: "Aa1" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects password longer than 128 chars", () => {
|
|
const result = registerSchema.safeParse({
|
|
...validRegister,
|
|
password: "Aa1" + "x".repeat(126),
|
|
});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("forgotPasswordSchema", () => {
|
|
it("accepts valid email", () => {
|
|
const result = forgotPasswordSchema.safeParse({ email: "user@example.com" });
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("rejects invalid email", () => {
|
|
const result = forgotPasswordSchema.safeParse({ email: "not-email" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty object", () => {
|
|
const result = forgotPasswordSchema.safeParse({});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("resetPasswordSchema", () => {
|
|
const validReset = {
|
|
token: "abc123token",
|
|
password: "Aa123456",
|
|
};
|
|
|
|
it("accepts valid reset input", () => {
|
|
const result = resetPasswordSchema.safeParse(validReset);
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("rejects empty token", () => {
|
|
const result = resetPasswordSchema.safeParse({ ...validReset, token: "" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects missing token", () => {
|
|
const result = resetPasswordSchema.safeParse({ password: "Aa123456" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects weak password", () => {
|
|
const result = resetPasswordSchema.safeParse({ token: "abc", password: "weak" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
});
|
|
|
|
// --------------- schemas/pagination ---------------
|
|
|
|
describe("paginationSchema", () => {
|
|
it("accepts empty object and applies defaults", () => {
|
|
const result = paginationSchema.safeParse({});
|
|
expect(result.success).toBe(true);
|
|
if (result.success) {
|
|
expect(result.data.page).toBe(1);
|
|
expect(result.data.limit).toBe(20);
|
|
}
|
|
});
|
|
|
|
it("coerces string page to number", () => {
|
|
const result = paginationSchema.safeParse({ page: "3", limit: "50" });
|
|
expect(result.success).toBe(true);
|
|
if (result.success) {
|
|
expect(result.data.page).toBe(3);
|
|
expect(result.data.limit).toBe(50);
|
|
expect(typeof result.data.page).toBe("number");
|
|
expect(typeof result.data.limit).toBe("number");
|
|
}
|
|
});
|
|
|
|
it("rejects page less than 1", () => {
|
|
const result = paginationSchema.safeParse({ page: 0 });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects limit greater than 100", () => {
|
|
const result = paginationSchema.safeParse({ limit: 101 });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects limit less than 1", () => {
|
|
const result = paginationSchema.safeParse({ limit: 0 });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("rejects non-integer page", () => {
|
|
const result = paginationSchema.safeParse({ page: 1.5 });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
});
|
|
|
|
// --------------- schemas/changelog ---------------
|
|
|
|
describe("changelogChangeTypeEnum", () => {
|
|
it("accepts fix", () => {
|
|
expect(changelogChangeTypeEnum.safeParse("fix").success).toBe(true);
|
|
});
|
|
|
|
it("accepts feature", () => {
|
|
expect(changelogChangeTypeEnum.safeParse("feature").success).toBe(true);
|
|
});
|
|
|
|
it("accepts improvement", () => {
|
|
expect(changelogChangeTypeEnum.safeParse("improvement").success).toBe(true);
|
|
});
|
|
|
|
it("rejects invalid value", () => {
|
|
expect(changelogChangeTypeEnum.safeParse("bugfix").success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("changelogEntrySchema", () => {
|
|
const validEntry = {
|
|
id: "123e4567-e89b-12d3-a456-426614174000",
|
|
changeType: "fix",
|
|
title: "Fixed bug",
|
|
description: "This is a fix description",
|
|
publishedAt: "2026-01-15T10:00:00.000Z",
|
|
createdAt: "2026-01-15T10:00:00.000Z",
|
|
updatedAt: "2026-01-15T10:00:00.000Z",
|
|
};
|
|
|
|
it("accepts valid changelog entry", () => {
|
|
expect(changelogEntrySchema.safeParse(validEntry).success).toBe(true);
|
|
});
|
|
|
|
it("rejects missing id", () => {
|
|
const { id, ...rest } = validEntry;
|
|
expect(changelogEntrySchema.safeParse(rest).success).toBe(false);
|
|
});
|
|
|
|
it("rejects non-UUID id", () => {
|
|
expect(changelogEntrySchema.safeParse({ ...validEntry, id: "not-uuid" }).success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty title", () => {
|
|
expect(changelogEntrySchema.safeParse({ ...validEntry, title: "" }).success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty description", () => {
|
|
expect(changelogEntrySchema.safeParse({ ...validEntry, description: "" }).success).toBe(false);
|
|
});
|
|
|
|
it("rejects invalid publishedAt datetime", () => {
|
|
expect(
|
|
changelogEntrySchema.safeParse({ ...validEntry, publishedAt: "not-a-date" }).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
it("rejects invalid changeType", () => {
|
|
expect(
|
|
changelogEntrySchema.safeParse({ ...validEntry, changeType: "bugfix" }).success,
|
|
).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("createChangelogEntrySchema", () => {
|
|
const validCreate = {
|
|
changeType: "feature",
|
|
title: "New feature",
|
|
description: "Description of the new feature",
|
|
publishedAt: "2026-01-15T10:00:00.000Z",
|
|
};
|
|
|
|
it("accepts valid create input", () => {
|
|
expect(createChangelogEntrySchema.safeParse(validCreate).success).toBe(true);
|
|
});
|
|
|
|
it("rejects missing title", () => {
|
|
const { title, ...rest } = validCreate;
|
|
expect(createChangelogEntrySchema.safeParse(rest).success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty description", () => {
|
|
expect(createChangelogEntrySchema.safeParse({ ...validCreate, description: "" }).success).toBe(
|
|
false,
|
|
);
|
|
});
|
|
|
|
it("does not require id field", () => {
|
|
// create schema doesn't have id
|
|
expect(validCreate).not.toHaveProperty("id");
|
|
});
|
|
});
|
|
|
|
describe("updateChangelogEntrySchema", () => {
|
|
it("accepts partial update (empty object)", () => {
|
|
expect(updateChangelogEntrySchema.safeParse({}).success).toBe(true);
|
|
});
|
|
|
|
it("accepts single field update", () => {
|
|
expect(updateChangelogEntrySchema.safeParse({ title: "Updated" }).success).toBe(true);
|
|
});
|
|
|
|
it("accepts full update", () => {
|
|
expect(
|
|
updateChangelogEntrySchema.safeParse({
|
|
changeType: "fix",
|
|
title: "Full update",
|
|
description: "Updated description",
|
|
publishedAt: "2026-01-15T10:00:00.000Z",
|
|
}).success,
|
|
).toBe(true);
|
|
});
|
|
|
|
it("rejects invalid changeType in partial update", () => {
|
|
expect(updateChangelogEntrySchema.safeParse({ changeType: "bugfix" }).success).toBe(false);
|
|
});
|
|
|
|
it("rejects empty title in partial update", () => {
|
|
expect(updateChangelogEntrySchema.safeParse({ title: "" }).success).toBe(false);
|
|
});
|
|
});
|
|
|
|
// --------------- utils/vin-validator ---------------
|
|
|
|
describe("isValidVin", () => {
|
|
it("returns true for valid VIN", () => {
|
|
expect(isValidVin("WVWZZZ1JZ3W597935")).toBe(true);
|
|
});
|
|
|
|
it("returns false for VIN with invalid characters", () => {
|
|
expect(isValidVin("WVWZZZ1IZ3W597935")).toBe(false);
|
|
});
|
|
|
|
it("returns false for short VIN", () => {
|
|
expect(isValidVin("WVWZZZ1JZ3W59793")).toBe(false);
|
|
});
|
|
|
|
it("returns false for empty string", () => {
|
|
expect(isValidVin("")).toBe(false);
|
|
});
|
|
|
|
it("converts lowercase to uppercase for validation", () => {
|
|
expect(isValidVin("wvwzzz1jz3w597935")).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("validateVinCheckDigit", () => {
|
|
it("returns true for a VIN with valid check digit", () => {
|
|
// Known-good VIN with check digit that validates
|
|
expect(validateVinCheckDigit("1HGBH41JXMN109186")).toBe(true);
|
|
});
|
|
|
|
it("returns false for invalid VIN", () => {
|
|
expect(validateVinCheckDigit("INVALIDVIN1234567")).toBe(false);
|
|
});
|
|
|
|
it("returns false for VIN with wrong check digit", () => {
|
|
// Take a valid VIN and change position 8 (the check digit)
|
|
expect(validateVinCheckDigit("WVWZZZ1JZ9W597935")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("extractWmi", () => {
|
|
it("extracts first 3 characters as WMI", () => {
|
|
expect(extractWmi("WVWZZZ1JZ3W597935")).toBe("WVW");
|
|
});
|
|
|
|
it("uppercases the result", () => {
|
|
expect(extractWmi("wvwzzz1jz3w597935")).toBe("WVW");
|
|
});
|
|
});
|
|
|
|
describe("extractModelYear", () => {
|
|
it("extracts year for 2010 (A)", () => {
|
|
expect(extractModelYear("WVWZZZ1JZAW597935")).toBe(2010);
|
|
});
|
|
|
|
it("extracts year for 2025 (S)", () => {
|
|
expect(extractModelYear("WVWZZZ1JZSW597935")).toBe(2025);
|
|
});
|
|
|
|
it("returns null for unknown year character", () => {
|
|
expect(extractModelYear("WVWZZZ1JZ0W597935")).toBeNull();
|
|
});
|
|
|
|
it("handles lowercase input", () => {
|
|
expect(extractModelYear("wvwzzz1jzaw597935")).toBe(2010);
|
|
});
|
|
});
|
|
|
|
// --------------- utils/currency ---------------
|
|
|
|
describe("formatTRY", () => {
|
|
it("formats kurus to TRY", () => {
|
|
const result = formatTRY(200_00);
|
|
expect(result).toContain("200");
|
|
});
|
|
|
|
it("formats zero", () => {
|
|
const result = formatTRY(0);
|
|
expect(result).toContain("0");
|
|
});
|
|
});
|
|
|
|
describe("kurusToLira", () => {
|
|
it("converts 100 kurus to 1 lira", () => {
|
|
expect(kurusToLira(100)).toBe(1);
|
|
});
|
|
|
|
it("converts 20000 kurus to 200 lira", () => {
|
|
expect(kurusToLira(200_00)).toBe(200);
|
|
});
|
|
|
|
it("converts 0", () => {
|
|
expect(kurusToLira(0)).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe("liraToKurus", () => {
|
|
it("converts 1 lira to 100 kurus", () => {
|
|
expect(liraToKurus(1)).toBe(100);
|
|
});
|
|
|
|
it("converts 200 lira to 20000 kurus", () => {
|
|
expect(liraToKurus(200)).toBe(200_00);
|
|
});
|
|
|
|
it("rounds to nearest kurus", () => {
|
|
expect(liraToKurus(0.005)).toBe(1);
|
|
});
|
|
});
|
|
|
|
// --------------- utils/formatters ---------------
|
|
|
|
describe("formatVin", () => {
|
|
it("uppercases and strips invalid chars", () => {
|
|
expect(formatVin("wvw-zzz 1jz3w597935")).toBe("WVWZZZ1JZ3W597935");
|
|
});
|
|
|
|
it("handles already clean VIN", () => {
|
|
expect(formatVin("WVWZZZ1JZ3W597935")).toBe("WVWZZZ1JZ3W597935");
|
|
});
|
|
});
|
|
|
|
describe("formatDate", () => {
|
|
it("formats a Date object", () => {
|
|
const d = new Date(2026, 0, 15);
|
|
const result = formatDate(d);
|
|
expect(result).toBe("15.01.2026");
|
|
});
|
|
|
|
it("formats an ISO string", () => {
|
|
const result = formatDate("2026-01-15");
|
|
expect(result).toBe("15.01.2026");
|
|
});
|
|
});
|
|
|
|
describe("formatDateTime", () => {
|
|
it("returns a string containing date and time", () => {
|
|
const d = new Date(2026, 0, 15, 14, 30);
|
|
const result = formatDateTime(d);
|
|
expect(result).toContain("15.01.2026");
|
|
});
|
|
});
|
|
|
|
describe("slugify", () => {
|
|
it("lowercases and replaces spaces with dashes", () => {
|
|
expect(slugify("Hello World")).toBe("hello-world");
|
|
});
|
|
|
|
it("replaces Turkish characters", () => {
|
|
expect(slugify("ğüşıöç")).toBe("gusioc");
|
|
});
|
|
|
|
it("removes leading/trailing dashes", () => {
|
|
expect(slugify(" hello ")).toBe("hello");
|
|
});
|
|
|
|
it("handles special characters", () => {
|
|
expect(slugify("Merhaba Dünya!")).toBe("merhaba-dunya");
|
|
});
|
|
});
|
|
|
|
describe("generateReferralCode", () => {
|
|
it("returns 8-character string", () => {
|
|
const code = generateReferralCode();
|
|
expect(code).toHaveLength(8);
|
|
});
|
|
|
|
it("contains only uppercase letters and numbers", () => {
|
|
const code = generateReferralCode();
|
|
expect(/^[A-Z0-9]+$/.test(code)).toBe(true);
|
|
});
|
|
|
|
it("does not contain ambiguous characters", () => {
|
|
const code = generateReferralCode();
|
|
expect(code).not.toMatch(/[IO0]/);
|
|
});
|
|
|
|
it("generates different codes on repeated calls", () => {
|
|
const codes = new Set(Array.from({ length: 10 }, () => generateReferralCode()));
|
|
// Extremely unlikely all 10 generate the same code
|
|
expect(codes.size).toBeGreaterThan(1);
|
|
});
|
|
});
|
|
|
|
// --------------- constants/regex ---------------
|
|
|
|
describe("VIN_REGEX", () => {
|
|
it("matches a valid VIN", () => {
|
|
expect(VIN_REGEX.test("WVWZZZ1JZ3W597935")).toBe(true);
|
|
});
|
|
|
|
it("does not match VIN with I", () => {
|
|
expect(VIN_REGEX.test("WVWZZZ1IZ3W597935")).toBe(false);
|
|
});
|
|
|
|
it("does not match VIN with O", () => {
|
|
expect(VIN_REGEX.test("WVWZZZ1OZ3W597935")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("EMAIL_REGEX", () => {
|
|
it("matches valid email", () => {
|
|
expect(EMAIL_REGEX.test("user@example.com")).toBe(true);
|
|
});
|
|
|
|
it("does not match missing @", () => {
|
|
expect(EMAIL_REGEX.test("userexample.com")).toBe(false);
|
|
});
|
|
|
|
it("does not match missing domain", () => {
|
|
expect(EMAIL_REGEX.test("user@")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("OEM_CODE_REGEX", () => {
|
|
it("matches valid OEM code", () => {
|
|
expect(OEM_CODE_REGEX.test("06A-109-108-B")).toBe(true);
|
|
});
|
|
|
|
it("matches short OEM code", () => {
|
|
expect(OEM_CODE_REGEX.test("ABC")).toBe(true);
|
|
});
|
|
});
|
|
|
|
// --------------- constants/plans ---------------
|
|
|
|
describe("PLANS", () => {
|
|
it("has SINGLE, DOUBLE, TRIPLE, and FULL plans", () => {
|
|
expect(PLANS.SINGLE).toBeDefined();
|
|
expect(PLANS.DOUBLE).toBeDefined();
|
|
expect(PLANS.TRIPLE).toBeDefined();
|
|
expect(PLANS.FULL).toBeDefined();
|
|
});
|
|
|
|
it("FULL plan has brandCount 0 (unlimited)", () => {
|
|
expect(PLANS.FULL.brandCount).toBe(0);
|
|
});
|
|
|
|
it("SINGLE plan has brandCount 1", () => {
|
|
expect(PLANS.SINGLE.brandCount).toBe(1);
|
|
});
|
|
|
|
it("all plans have positive price", () => {
|
|
for (const plan of Object.values(PLANS)) {
|
|
expect(plan.priceMonthly).toBeGreaterThan(0);
|
|
expect(plan.priceYearly).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("FULL_PLAN_BRAND_LIMIT", () => {
|
|
it("equals 999", () => {
|
|
expect(FULL_PLAN_BRAND_LIMIT).toBe(999);
|
|
});
|
|
});
|
|
|
|
describe("REFERRAL_REWARDS", () => {
|
|
it("TIER_1 requires 3 referrals for 7 extension days", () => {
|
|
expect(REFERRAL_REWARDS.TIER_1.count).toBe(3);
|
|
expect(REFERRAL_REWARDS.TIER_1.extensionDays).toBe(7);
|
|
});
|
|
|
|
it("TIER_2 requires 5 referrals for 30 extension days", () => {
|
|
expect(REFERRAL_REWARDS.TIER_2.count).toBe(5);
|
|
expect(REFERRAL_REWARDS.TIER_2.extensionDays).toBe(30);
|
|
});
|
|
});
|
|
|
|
describe("CURRENCY", () => {
|
|
it("is TRY", () => {
|
|
expect(CURRENCY).toBe("TRY");
|
|
});
|
|
});
|
|
|
|
// --------------- constants/error-codes ---------------
|
|
|
|
describe("ERROR_CODES", () => {
|
|
it("has auth error codes", () => {
|
|
expect(ERROR_CODES.INVALID_CREDENTIALS).toBe("AUTH_001");
|
|
expect(ERROR_CODES.EMAIL_ALREADY_EXISTS).toBe("AUTH_002");
|
|
expect(ERROR_CODES.SESSION_EXPIRED).toBe("AUTH_003");
|
|
expect(ERROR_CODES.UNAUTHORIZED).toBe("AUTH_004");
|
|
expect(ERROR_CODES.FORBIDDEN).toBe("AUTH_005");
|
|
});
|
|
|
|
it("has VIN error codes", () => {
|
|
expect(ERROR_CODES.INVALID_VIN).toBe("VIN_001");
|
|
expect(ERROR_CODES.VIN_DECODE_FAILED).toBe("VIN_002");
|
|
expect(ERROR_CODES.BRAND_NOT_SUPPORTED).toBe("VIN_003");
|
|
});
|
|
|
|
it("has subscription error codes", () => {
|
|
expect(ERROR_CODES.NO_ACTIVE_SUBSCRIPTION).toBe("SUB_001");
|
|
expect(ERROR_CODES.BRAND_ACCESS_DENIED).toBe("SUB_002");
|
|
expect(ERROR_CODES.INVALID_BRAND_COUNT).toBe("SUB_003");
|
|
expect(ERROR_CODES.SUBSCRIPTION_ALREADY_ACTIVE).toBe("SUB_004");
|
|
});
|
|
|
|
it("has payment error codes", () => {
|
|
expect(ERROR_CODES.PAYMENT_FAILED).toBe("PAY_001");
|
|
expect(ERROR_CODES.EFT_RECEIPT_REQUIRED).toBe("PAY_003");
|
|
expect(ERROR_CODES.PAYMENT_ALREADY_PROCESSED).toBe("PAY_004");
|
|
});
|
|
|
|
it("has general error codes", () => {
|
|
expect(ERROR_CODES.NOT_FOUND).toBe("GEN_001");
|
|
expect(ERROR_CODES.VALIDATION_ERROR).toBe("GEN_002");
|
|
expect(ERROR_CODES.INTERNAL_ERROR).toBe("GEN_003");
|
|
expect(ERROR_CODES.RATE_LIMITED).toBe("GEN_004");
|
|
expect(ERROR_CODES.CONFLICT).toBe("GEN_005");
|
|
});
|
|
|
|
it("has integration error codes", () => {
|
|
expect(ERROR_CODES.PL24_ERROR).toBe("INT_001");
|
|
expect(ERROR_CODES.EMEX_ERROR).toBe("INT_002");
|
|
expect(ERROR_CODES.CORGI_ERROR).toBe("INT_003");
|
|
});
|
|
});
|