diff --git a/apps/web/app/middleware/endpoint-validator.test.ts b/apps/web/app/middleware/endpoint-validator.test.ts index 2a70af8d15..624fffdd8f 100644 --- a/apps/web/app/middleware/endpoint-validator.test.ts +++ b/apps/web/app/middleware/endpoint-validator.test.ts @@ -59,7 +59,6 @@ describe("endpoint-validator", () => { describe("isClientSideApiRoute", () => { test("should return true for client-side API routes", () => { - expect(isClientSideApiRoute("/api/packages/something")).toBe(true); expect(isClientSideApiRoute("/api/v1/js/actions")).toBe(true); expect(isClientSideApiRoute("/api/v1/client/storage")).toBe(true); expect(isClientSideApiRoute("/api/v1/client/other")).toBe(true); diff --git a/apps/web/app/middleware/endpoint-validator.ts b/apps/web/app/middleware/endpoint-validator.ts index cff058dfce..cf5e95c711 100644 --- a/apps/web/app/middleware/endpoint-validator.ts +++ b/apps/web/app/middleware/endpoint-validator.ts @@ -8,7 +8,6 @@ export const isVerifyEmailRoute = (url: string) => url === "/auth/verify-email"; export const isForgotPasswordRoute = (url: string) => url === "/auth/forgot-password"; export const isClientSideApiRoute = (url: string): boolean => { - if (url.includes("/api/packages/")) return true; if (url.includes("/api/v1/js/actions")) return true; if (url.includes("/api/v1/client/storage")) return true; const regex = /^\/api\/v\d+\/client\//; diff --git a/apps/web/next.config.mjs b/apps/web/next.config.mjs index 88b7e02243..27b5843988 100644 --- a/apps/web/next.config.mjs +++ b/apps/web/next.config.mjs @@ -23,7 +23,6 @@ const nextConfig = { productionBrowserSourceMaps: false, serverExternalPackages: ["@aws-sdk", "@opentelemetry/instrumentation", "pino", "pino-pretty"], outputFileTracingIncludes: { - "app/api/packages": ["../../packages/js-core/dist/*", "../../packages/surveys/dist/*"], "/api/auth/**/*": ["../../node_modules/jose/**/*"], }, experimental: {}, @@ -189,7 +188,8 @@ const nextConfig = { headers: [ { key: "Cache-Control", - value: "public, max-age=3600, s-maxage=604800, stale-while-revalidate=3600, stale-if-error=3600", + value: + "public, max-age=3600, s-maxage=2592000, stale-while-revalidate=3600, stale-if-error=86400", }, { key: "Content-Type", @@ -199,19 +199,151 @@ const nextConfig = { key: "Access-Control-Allow-Origin", value: "*", }, + { + key: "Vary", + value: "Accept-Encoding", + }, ], }, - // headers for /api/packages/(.*) -- the api route does not exist, but we still need the headers for the rewrites to work correctly! + // Favicon files - long cache since they rarely change { - source: "/api/packages/(.*)", + source: "/favicon/(.*)", headers: [ { key: "Cache-Control", - value: "public, max-age=3600, s-maxage=604800, stale-while-revalidate=3600, stale-if-error=3600", + value: "public, max-age=2592000, s-maxage=31536000, immutable", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + ], + }, + // Root favicon.ico - long cache + { + source: "/favicon.ico", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=2592000, s-maxage=31536000, immutable", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + ], + }, + // SVG files (icons, logos) - long cache since they're usually static + { + source: "/(.*)\\.svg", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=2592000, s-maxage=31536000, immutable", }, { key: "Content-Type", - value: "application/javascript; charset=UTF-8", + value: "image/svg+xml", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + ], + }, + // Image backgrounds - medium cache (might update more frequently) + { + source: "/image-backgrounds/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=86400, s-maxage=2592000, stale-while-revalidate=86400", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + { + key: "Vary", + value: "Accept-Encoding", + }, + ], + }, + // Video files - long cache since they're large and expensive to transfer + { + source: "/video/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=604800, s-maxage=31536000, stale-while-revalidate=604800", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + { + key: "Accept-Ranges", + value: "bytes", + }, + ], + }, + // Animated backgrounds (4K videos) - very long cache since they're large and immutable + { + source: "/animated-bgs/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=604800, s-maxage=31536000, immutable", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + { + key: "Accept-Ranges", + value: "bytes", + }, + ], + }, + // CSV templates - shorter cache since they might update with feature changes + { + source: "/sample-csv/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=3600, s-maxage=86400, stale-while-revalidate=3600", + }, + { + key: "Content-Type", + value: "text/csv", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + ], + }, + // Web manifest and browser config files - medium cache + { + source: "/(site\\.webmanifest|browserconfig\\.xml)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=86400, s-maxage=604800, stale-while-revalidate=86400", + }, + { + key: "Access-Control-Allow-Origin", + value: "*", + }, + ], + }, + // Optimize caching for other static assets in public folder (fallback) + { + source: "/(images|fonts|icons)/(.*)", + headers: [ + { + key: "Cache-Control", + value: "public, max-age=31536000, s-maxage=31536000, immutable", }, { key: "Access-Control-Allow-Origin", diff --git a/apps/web/public/next.svg b/apps/web/public/next.svg deleted file mode 100644 index 5174b28c56..0000000000 --- a/apps/web/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/onboarding/meme.png b/apps/web/public/onboarding/meme.png deleted file mode 100644 index 546f8ec3a4..0000000000 Binary files a/apps/web/public/onboarding/meme.png and /dev/null differ diff --git a/apps/web/public/thirteen.svg b/apps/web/public/thirteen.svg deleted file mode 100644 index 8977c1bd12..0000000000 --- a/apps/web/public/thirteen.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/vercel.svg b/apps/web/public/vercel.svg deleted file mode 100644 index d2f8422273..0000000000 --- a/apps/web/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/web/public/video/lost-sw.mp4 b/apps/web/public/video/lost-sw.mp4 deleted file mode 100644 index 5a5ebc93b2..0000000000 Binary files a/apps/web/public/video/lost-sw.mp4 and /dev/null differ diff --git a/apps/web/public/video/tooltips/change-survey-type-app.mp4 b/apps/web/public/video/tooltips/change-survey-type-app.mp4 deleted file mode 100644 index 4653954a46..0000000000 Binary files a/apps/web/public/video/tooltips/change-survey-type-app.mp4 and /dev/null differ diff --git a/apps/web/public/video/walkthrough-v1.mp4 b/apps/web/public/video/walkthrough-v1.mp4 deleted file mode 100644 index 239a7bba9f..0000000000 Binary files a/apps/web/public/video/walkthrough-v1.mp4 and /dev/null differ diff --git a/packages/surveys/src/lib/color.test.ts b/packages/surveys/src/lib/color.test.ts index fd701c0721..8f05a5a8af 100644 --- a/packages/surveys/src/lib/color.test.ts +++ b/packages/surveys/src/lib/color.test.ts @@ -1,49 +1,49 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, test } from "vitest"; import { isLight, mixColor } from "./color"; describe("mixColor", () => { - it("should mix a color with white", () => { + test("should mix a color with white", () => { expect(mixColor("#FF0000", "#FFFFFF", 0.5)).toBe("#ff8080"); // Red mixed with white expect(mixColor("#0000FF", "#FFFFFF", 0.5)).toBe("#8080ff"); // Blue mixed with white expect(mixColor("#00FF00", "#FFFFFF", 0.2)).toBe("#33ff33"); // Green mixed with white (less white) }); - it("should mix a color with black", () => { + test("should mix a color with black", () => { expect(mixColor("#FF0000", "#000000", 0.5)).toBe("#800000"); // Red mixed with black expect(mixColor("#FFFF00", "#000000", 0.5)).toBe("#808000"); // Yellow mixed with black }); - it("should return the first color if weight is 0", () => { + test("should return the first color if weight is 0", () => { expect(mixColor("#FF0000", "#00FF00", 0)).toBe("#ff0000"); }); - it("should return the second color if weight is 1", () => { + test("should return the second color if weight is 1", () => { expect(mixColor("#FF0000", "#00FF00", 1)).toBe("#00ff00"); }); - it("should handle shorthand hex codes", () => { + test("should handle shorthand hex codes", () => { expect(mixColor("#F00", "#0F0", 0.5)).toBe("#808000"); // Red and Green expect(mixColor("#00F", "#FFF", 0.5)).toBe("#8080ff"); // Blue and White }); - it("should handle hex codes without # prefix (implicitly handled by hexToRGBA regex)", () => { + test("should handle hex codes without # prefix (implicitly handled by hexToRGBA regex)", () => { expect(mixColor("FF0000", "00FF00", 0.5)).toBe("#808000"); }); - it("should default to black if one color is invalid/empty", () => { + test("should default to black if one color is invalid/empty", () => { // hexToRGBA returns "" for invalid, which becomes [0,0,0] in mixColor expect(mixColor("invalidColor", "#FFFFFF", 0.5)).toBe("#808080"); // invalid (black) mixed with white expect(mixColor("#FF0000", "", 0.5)).toBe("#800000"); // Red mixed with empty (black) expect(mixColor("", "", 0.5)).toBe("#000000"); // Both empty (black) }); - it("should mix two distinct colors correctly", () => { + test("should mix two distinct colors correctly", () => { expect(mixColor("#FF0000", "#0000FF", 0.5)).toBe("#800080"); // Red and Blue -> Purple }); }); describe("isLight", () => { - it("should return true for light colors", () => { + test("should return true for light colors", () => { expect(isLight("#FFFFFF")).toBe(true); // White expect(isLight("#F0F0F0")).toBe(true); // Light gray expect(isLight("#FFD700")).toBe(true); // Gold @@ -51,7 +51,7 @@ describe("isLight", () => { expect(isLight("#ABC")).toBe(true); // Shorthand light color }); - it("should return false for dark colors", () => { + test("should return false for dark colors", () => { expect(isLight("#000000")).toBe(false); // Black expect(isLight("#333333")).toBe(false); // Dark gray expect(isLight("#8B0000")).toBe(false); // Dark red @@ -59,7 +59,7 @@ describe("isLight", () => { expect(isLight("#123")).toBe(false); // Shorthand dark color }); - it("should handle colors near the threshold", () => { + test("should handle colors near the threshold", () => { // Luminance of #808080 (gray) is 128. Formula: r*0.299 + g*0.587 + b*0.114 > 128 // For #808080 (128,128,128): 128*0.299 + 128*0.587 + 128*0.114 = 128*1 = 128. So it's not > 128. expect(isLight("#808080")).toBe(false); // Gray (threshold case, should be false) @@ -67,7 +67,7 @@ describe("isLight", () => { expect(isLight("#7F7F7F")).toBe(false); // Slightly darker than gray }); - it("should throw error for invalid color strings", () => { + test("should throw error for invalid color strings", () => { expect(() => isLight("#12345")).toThrow("Invalid color"); expect(() => isLight("notacolor")).toThrow("Invalid color"); expect(isLight("#GGHHII")).toBe(false); // Invalid hex characters currently return false diff --git a/packages/surveys/src/lib/date-time.test.ts b/packages/surveys/src/lib/date-time.test.ts index 11f2561578..a224425385 100644 --- a/packages/surveys/src/lib/date-time.test.ts +++ b/packages/surveys/src/lib/date-time.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, test } from "vitest"; import { formatDateWithOrdinal, getMonthName, getOrdinalDate, isValidDateString } from "./date-time"; // Manually define getOrdinalSuffix for testing as it's not exported @@ -14,42 +14,42 @@ const getOrdinalSuffix = (day: number): string => { }; describe("getMonthName", () => { - it("should return correct month name for en-US", () => { + test("should return correct month name for en-US", () => { expect(getMonthName(0)).toBe("January"); expect(getMonthName(6)).toBe("July"); expect(getMonthName(11)).toBe("December"); }); - it("should return correct month name for a different locale (es-ES)", () => { + test("should return correct month name for a different locale (es-ES)", () => { expect(getMonthName(0, "es-ES")).toBe("enero"); expect(getMonthName(6, "es-ES")).toBe("julio"); expect(getMonthName(11, "es-ES")).toBe("diciembre"); }); - it("should throw an error for invalid month index", () => { + test("should throw an error for invalid month index", () => { expect(() => getMonthName(-1)).toThrow("Month index must be between 0 and 11"); expect(() => getMonthName(12)).toThrow("Month index must be between 0 and 11"); }); }); describe("getOrdinalDate", () => { - it('should return date with "st" for 1, 21, 31 (but not 11)', () => { + test('should return date with "st" for 1, 21, 31 (but not 11)', () => { expect(getOrdinalDate(1)).toBe("1st"); expect(getOrdinalDate(21)).toBe("21st"); expect(getOrdinalDate(31)).toBe("31st"); }); - it('should return date with "nd" for 2, 22 (but not 12)', () => { + test('should return date with "nd" for 2, 22 (but not 12)', () => { expect(getOrdinalDate(2)).toBe("2nd"); expect(getOrdinalDate(22)).toBe("22nd"); }); - it('should return date with "rd" for 3, 23 (but not 13)', () => { + test('should return date with "rd" for 3, 23 (but not 13)', () => { expect(getOrdinalDate(3)).toBe("3rd"); expect(getOrdinalDate(23)).toBe("23rd"); }); - it('should return date with "th" for 11, 12, 13 and others', () => { + test('should return date with "th" for 11, 12, 13 and others', () => { expect(getOrdinalDate(4)).toBe("4th"); expect(getOrdinalDate(11)).toBe("11th"); expect(getOrdinalDate(12)).toBe("12th"); @@ -61,24 +61,24 @@ describe("getOrdinalDate", () => { }); describe("isValidDateString", () => { - it("should return true for valid YYYY-MM-DD format", () => { + test("should return true for valid YYYY-MM-DD format", () => { expect(isValidDateString("2023-01-15")).toBe(true); expect(isValidDateString("2024-02-29")).toBe(true); // Leap year }); - it("should return true for valid DD-MM-YYYY format", () => { - expect(isValidDateString("15-01-2023")).toBe(false); - expect(isValidDateString("29-02-2024")).toBe(false); + test("should return true for valid DD-MM-YYYY format", () => { + expect(isValidDateString("15-01-2023")).toBe(true); + expect(isValidDateString("29-02-2024")).toBe(true); }); - it("should return false for invalid dates in valid format", () => { + test("should return false for invalid dates in valid format", () => { expect(isValidDateString("2023-02-30")).toBe(true); expect(isValidDateString("2023-13-01")).toBe(false); expect(isValidDateString("32-01-2023")).toBe(false); - expect(isValidDateString("01-13-2023")).toBe(true); + expect(isValidDateString("01-13-2023")).toBe(false); }); - it("should return false for invalid formats", () => { + test("should return false for invalid formats", () => { expect(isValidDateString("2023/01/15")).toBe(false); expect(isValidDateString("01/15/2023")).toBe(false); expect(isValidDateString("Jan 15, 2023")).toBe(false); @@ -89,25 +89,25 @@ describe("isValidDateString", () => { }); describe("getOrdinalSuffix (helper)", () => { - it('should return "st" for 1, 21, 31', () => { + test('should return "st" for 1, 21, 31', () => { expect(getOrdinalSuffix(1)).toBe("st"); expect(getOrdinalSuffix(21)).toBe("st"); expect(getOrdinalSuffix(31)).toBe("st"); }); - it('should return "nd" for 2, 22', () => { + test('should return "nd" for 2, 22', () => { expect(getOrdinalSuffix(2)).toBe("nd"); expect(getOrdinalSuffix(22)).toBe("nd"); expect(getOrdinalSuffix(32)).toBe("nd"); // Test for day >= 30 leading to relevantDigits = 2 }); - it('should return "rd" for 3, 23', () => { + test('should return "rd" for 3, 23', () => { expect(getOrdinalSuffix(3)).toBe("rd"); expect(getOrdinalSuffix(23)).toBe("rd"); expect(getOrdinalSuffix(33)).toBe("rd"); // Test for day >= 30 leading to relevantDigits = 3 }); - it('should return "th" for 4-20, 24-30, and 11, 12, 13 variants', () => { + test('should return "th" for 4-20, 24-30, and 11, 12, 13 variants', () => { expect(getOrdinalSuffix(4)).toBe("th"); expect(getOrdinalSuffix(11)).toBe("th"); expect(getOrdinalSuffix(12)).toBe("th"); @@ -121,7 +121,7 @@ describe("getOrdinalSuffix (helper)", () => { }); describe("formatDateWithOrdinal", () => { - it("should format date correctly for en-US", () => { + test("should format date correctly for en-US", () => { // Test with a few specific dates // Monday, January 1st, 2024 const date1 = new Date(2024, 0, 1); @@ -136,7 +136,7 @@ describe("formatDateWithOrdinal", () => { expect(formatDateWithOrdinal(date3)).toBe("Sunday, March 13th, 2022"); }); - it("should format date correctly for a different locale (fr-FR)", () => { + test("should format date correctly for a different locale (fr-FR)", () => { const date1 = new Date(2024, 0, 1); // The exact output depends on Intl and Node version, it might include periods or different capitalization. // For consistency, we'll check for key parts. @@ -161,7 +161,7 @@ describe("formatDateWithOrdinal", () => { expect(formattedDate2).toContain("2023"); }); - it("should handle the 1st with French locale (specific check for 1er)", () => { + test("should handle the 1st with French locale (specific check for 1er)", () => { const date = new Date(2024, 0, 1); // January 1st // The original getOrdinalSuffix is English-specific. It will produce '1st'. // A truly internationalized getOrdinalSuffix would be needed for '1er'. @@ -170,7 +170,7 @@ describe("formatDateWithOrdinal", () => { expect(formatDateWithOrdinal(date, "fr-FR")).toBe("lundi, janvier 1st, 2024"); }); - it("should handle other dates with French locale", () => { + test("should handle other dates with French locale", () => { const date = new Date(2024, 0, 2); // January 2nd expect(formatDateWithOrdinal(date, "fr-FR")).toBe("mardi, janvier 2nd, 2024"); diff --git a/packages/surveys/src/lib/date-time.ts b/packages/surveys/src/lib/date-time.ts index 457ccf3c1b..961f53456c 100644 --- a/packages/surveys/src/lib/date-time.ts +++ b/packages/surveys/src/lib/date-time.ts @@ -29,6 +29,10 @@ export const isValidDateString = (value: string) => { return false; } + if (RegExp(/^\d{2}-\d{2}-\d{4}$/).exec(value) !== null) { + value = value.replace(/(\d{2})-(\d{2})-(\d{4})/, "$3-$2-$1"); + } + const date = new Date(value); return !isNaN(date.getTime()); }; diff --git a/packages/surveys/src/lib/response.test.ts b/packages/surveys/src/lib/response.test.ts index 6511faa2a3..42cedd2e0a 100644 --- a/packages/surveys/src/lib/response.test.ts +++ b/packages/surveys/src/lib/response.test.ts @@ -1,66 +1,66 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, test } from "vitest"; import { processResponseData } from "./response"; describe("processResponseData", () => { - it("should return the same string if input is a string", () => { + test("should return the same string if input is a string", () => { expect(processResponseData("hello world")).toBe("hello world"); expect(processResponseData("")).toBe(""); }); - it("should convert number to string", () => { + test("should convert number to string", () => { expect(processResponseData(123)).toBe("123"); expect(processResponseData(0)).toBe("0"); expect(processResponseData(-42.5)).toBe("-42.5"); }); describe("when input is an array", () => { - it('should join array elements with "; "', () => { + test('should join array elements with "; "', () => { expect(processResponseData(["apple", "banana", "cherry"])).toBe("apple; banana; cherry"); }); - it("should filter out null, undefined, and empty strings from array", () => { + test("should filter out null, undefined, and empty strings from array", () => { expect(processResponseData(["one", null, "two", undefined, "", "three"] as any)).toBe( "one; two; three" ); }); - it("should return an empty string if array is empty after filtering", () => { + test("should return an empty string if array is empty after filtering", () => { expect(processResponseData([null, undefined, ""] as any)).toBe(""); }); - it("should return an empty string for an empty array", () => { + test("should return an empty string for an empty array", () => { expect(processResponseData([])).toBe(""); }); - it("should handle an array with a single element", () => { + test("should handle an array with a single element", () => { expect(processResponseData(["single"])).toBe("single"); }); }); describe("when input is an object", () => { - it('should format object entries as "key: value" pairs, joined by newline', () => { + test('should format object entries as "key: value" pairs, joined by newline', () => { // Assuming Object.entries preserves insertion order for string keys here expect(processResponseData({ name: "John Doe", age: "30" })).toBe("name: John Doe\nage: 30"); // Test with different order to confirm typical Object.entries behavior expect(processResponseData({ age: "30", name: "John Doe" })).toBe("age: 30\nname: John Doe"); }); - it("should filter out entries with empty string values", () => { + test("should filter out entries with empty string values", () => { expect(processResponseData({ fruit: "apple", taste: "", color: "red" })).toBe( "fruit: apple\ncolor: red" ); }); - it("should return an empty string if object is empty after filtering", () => { + test("should return an empty string if object is empty after filtering", () => { expect(processResponseData({ a: "", b: "" })).toBe(""); }); - it("should return an empty string for an empty object", () => { + test("should return an empty string for an empty object", () => { expect(processResponseData({})).toBe(""); }); }); - it("should return an empty string for undefined input (default case)", () => { + test("should return an empty string for undefined input (default case)", () => { // This tests the default case of the switch statement. // Need to cast to 'any' to bypass TypeScript's stricter typing for the function signature. expect(processResponseData(undefined as any)).toBe(""); diff --git a/packages/surveys/src/lib/storage.test.ts b/packages/surveys/src/lib/storage.test.ts index 7cf28ccdac..0ccfa4792a 100644 --- a/packages/surveys/src/lib/storage.test.ts +++ b/packages/surveys/src/lib/storage.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { getOriginalFileNameFromUrl } from "./storage"; describe("getOriginalFileNameFromUrl", () => { @@ -16,42 +16,42 @@ describe("getOriginalFileNameFromUrl", () => { // Test cases for URLs with --fid-- describe("with --fid-- separator", () => { - it("should extract original name from /storage/ path with extension", () => { + test("should extract original name from /storage/ path with extension", () => { const url = "/storage/My%20Document--fid--123xyz.pdf"; expect(getOriginalFileNameFromUrl(url)).toBe("My Document.pdf"); }); - it("should extract original name from full URL with extension", () => { + test("should extract original name from full URL with extension", () => { const url = "https://example.com/files/Another%20File--fid--abc456.docx"; expect(getOriginalFileNameFromUrl(url)).toBe("Another File.docx"); }); - it("should handle filenames with dots before --fid--", () => { + test("should handle filenames with dots before --fid--", () => { const url = "/storage/archive.version1--fid--qwerty.tar.gz"; expect(getOriginalFileNameFromUrl(url)).toBe("archive.version1.gz"); }); - it("should handle missing original filename part", () => { + test("should handle missing original filename part", () => { const url = "/storage/--fid--789.txt"; expect(getOriginalFileNameFromUrl(url)).toBe(""); }); - it("should handle if fileId part is empty but has an extension", () => { + test("should handle if fileId part is empty but has an extension", () => { const url = "/storage/report-data--fid--.csv"; expect(getOriginalFileNameFromUrl(url)).toBe("report-data.csv"); }); - it("should handle if there is no extension after fileId", () => { + test("should handle if there is no extension after fileId", () => { const url = "/storage/image_file--fid--uniqueid"; expect(getOriginalFileNameFromUrl(url)).toBe("image_file.image_file--fid--uniqueid"); }); - it("should handle filename ending with a dot after --fid--", () => { + test("should handle filename ending with a dot after --fid--", () => { const url = "/storage/reportData--fid--version2."; expect(getOriginalFileNameFromUrl(url)).toBe("reportData."); }); - it("should handle complex encoded originalFileName with an extension", () => { + test("should handle complex encoded originalFileName with an extension", () => { const url = "/storage/File%20With%20%25%20Percent--fid--idWith.dot.ext"; expect(getOriginalFileNameFromUrl(url)).toBe("File With % Percent.ext"); }); @@ -59,32 +59,32 @@ describe("getOriginalFileNameFromUrl", () => { // Test cases for URLs without --fid-- describe("without --fid-- separator", () => { - it("should return decoded name from /storage/ path", () => { + test("should return decoded name from /storage/ path", () => { const url = "/storage/My%20CV.pdf"; expect(getOriginalFileNameFromUrl(url)).toBe("My CV.pdf"); }); - it("should return decoded name from full URL", () => { + test("should return decoded name from full URL", () => { const url = "https://cdn.example.com/assets/Company%20Logo.png"; expect(getOriginalFileNameFromUrl(url)).toBe("Company Logo.png"); }); - it("should handle filenames without extension", () => { + test("should handle filenames without extension", () => { const url = "/storage/report_final"; expect(getOriginalFileNameFromUrl(url)).toBe("report_final"); }); - it("should handle filenames starting with a dot", () => { + test("should handle filenames starting with a dot", () => { const url = "https://example.com/configs/.env_prod"; expect(getOriginalFileNameFromUrl(url)).toBe(".env_prod"); }); - it("should handle filename ending with a dot (no --fid--)", () => { + test("should handle filename ending with a dot (no --fid--)", () => { const url = "/storage/finalReport."; expect(getOriginalFileNameFromUrl(url)).toBe("finalReport."); }); - it("should handle complex encoded name with extension-like part", () => { + test("should handle complex encoded name with extension-like part", () => { const url = "/storage/Another%20Complex%20Name%26Symbols.part1"; expect(getOriginalFileNameFromUrl(url)).toBe("Another Complex Name&Symbols.part1"); }); @@ -92,18 +92,18 @@ describe("getOriginalFileNameFromUrl", () => { // Edge cases and error handling describe("edge cases and error handling", () => { - it("should return empty string for an empty URL", () => { + test("should return empty string for an empty URL", () => { expect(getOriginalFileNameFromUrl("")).toBe(""); expect(consoleErrorSpy).toHaveBeenCalled(); }); - it("should return empty string for an invalid URL and log error", () => { + test("should return empty string for an invalid URL and log error", () => { const url = "this is not a url"; expect(getOriginalFileNameFromUrl(url)).toBe(""); expect(consoleErrorSpy).toHaveBeenCalled(); }); - it("should return empty string if URL ends with a slash", () => { + test("should return empty string if URL ends with a slash", () => { const url = "https://example.com/files/path/"; expect(getOriginalFileNameFromUrl(url)).toBe(""); // Depending on URL parsing, this might or might not log an error. @@ -111,7 +111,7 @@ describe("getOriginalFileNameFromUrl", () => { // but .pop() on split by / might yield empty string, thus no error logged from catch. }); - it("should handle URL with query parameters and fragment", () => { + test("should handle URL with query parameters and fragment", () => { const url = "https://example.com/files/document.pdf?version=2#page10"; expect(getOriginalFileNameFromUrl(url)).toBe("document.pdf"); }); diff --git a/packages/surveys/src/lib/styles.test.ts b/packages/surveys/src/lib/styles.test.ts index 085549ca5f..fd13b4688b 100644 --- a/packages/surveys/src/lib/styles.test.ts +++ b/packages/surveys/src/lib/styles.test.ts @@ -1,4 +1,4 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { type TProjectStyling } from "@formbricks/types/project"; import { type TSurveyStyling } from "@formbricks/types/surveys/types"; import { addCustomThemeToDom, addStylesToDom } from "./styles"; @@ -54,7 +54,7 @@ describe("addStylesToDom", () => { } }); - it("should add a style element to the head with combined CSS", () => { + test("should add a style element to the head with combined CSS", () => { addStylesToDom(); const styleElement = document.getElementById("formbricks__css") as HTMLStyleElement; expect(styleElement).not.toBeNull(); @@ -65,7 +65,7 @@ describe("addStylesToDom", () => { expect(styleElement.innerHTML).toBe(expectedCss); }); - it("should not add a new style element if one already exists", () => { + test("should not add a new style element if one already exists", () => { addStylesToDom(); // First call const firstStyleElement = document.getElementById("formbricks__css"); const initialInnerHTML = firstStyleElement?.innerHTML; @@ -113,7 +113,7 @@ describe("addCustomThemeToDom", () => { return variables; }; - it("should add a custom theme style element to the head", () => { + test("should add a custom theme style element to the head", () => { const styling = getBaseProjectStyling({ brandColor: { light: "#FF0000" } }); addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -122,7 +122,7 @@ describe("addCustomThemeToDom", () => { expect(document.head.contains(styleElement)).toBe(true); }); - it("should reuse existing custom theme style element", () => { + test("should reuse existing custom theme style element", () => { const styling1 = getBaseProjectStyling({ brandColor: { light: "#FF0000" } }); addCustomThemeToDom({ styling: styling1 }); const firstElement = document.getElementById("formbricks__css__custom"); @@ -136,7 +136,7 @@ describe("addCustomThemeToDom", () => { expect(secondElement).toBe(firstElement); }); - it("should apply minimal styling with brandColor and default roundness", () => { + test("should apply minimal styling with brandColor and default roundness", () => { const styling = getBaseProjectStyling({ brandColor: { light: "#0000FF" } }); // A dark color, roundness will use default addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -148,7 +148,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-border-radius"]).toBe("8px"); // Default roundness }); - it("should apply brand-text-color as black for light brandColor", () => { + test("should apply brand-text-color as black for light brandColor", () => { const styling = getBaseProjectStyling({ brandColor: { light: "#FFFF00" } }); // A light color addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -156,7 +156,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-brand-text-color"]).toBe("black"); // isLight('#FFFF00') is true }); - it("should default brand-text-color to white if brandColor is undefined", () => { + test("should default brand-text-color to white if brandColor is undefined", () => { const styling = getBaseProjectStyling({ brandColor: null }); // Explicitly null brandColor addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -164,7 +164,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-brand-text-color"]).toBe("#ffffff"); }); - it("should apply all survey styling properties", () => { + test("should apply all survey styling properties", () => { const styling: TSurveyStyling = { brandColor: { light: "#112233" }, questionColor: { light: "#AABBCC" }, @@ -205,7 +205,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-calendar-tile-color"]).toBeUndefined(); // isLight('#112233') is false, so this should be undefined }); - it("should set signature and branding text colors for dark questionColor", () => { + test("should set signature and branding text colors for dark questionColor", () => { const styling = getBaseProjectStyling({ questionColor: { light: "#202020" }, // A dark color brandColor: { light: "#123456" }, // brandColor needed for some default fallbacks if not directly testing them @@ -219,7 +219,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-branding-text-color"]).toBeDefined(); }); - it("should handle roundness 0 correctly", () => { + test("should handle roundness 0 correctly", () => { const styling = getBaseProjectStyling({ roundness: 0, brandColor: { light: "#123456" } }); addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -227,7 +227,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-border-radius"]).toBe("0px"); }); - it("should set input-background-color-selected to slate-50 for white inputColor", () => { + test("should set input-background-color-selected to slate-50 for white inputColor", () => { const whiteColors = ["#fff", "#ffffff", "white"]; whiteColors.forEach((color) => { const styling = getBaseProjectStyling({ inputColor: { light: color }, brandColor: { light: "#123" } }); @@ -238,7 +238,7 @@ describe("addCustomThemeToDom", () => { }); }); - it("should mix input-background-color-selected for non-white inputColor", () => { + test("should mix input-background-color-selected for non-white inputColor", () => { const styling = getBaseProjectStyling({ inputColor: { light: "#E0E0E0" }, brandColor: { light: "#123" }, @@ -252,7 +252,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-input-background-color-selected"]).not.toBe("var(--slate-50)"); }); - it("should not set calendar-tile-color if brandColor is undefined", () => { + test("should not set calendar-tile-color if brandColor is undefined", () => { const styling = getBaseProjectStyling({ brandColor: null }); addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -260,7 +260,7 @@ describe("addCustomThemeToDom", () => { expect(variables["--fb-calendar-tile-color"]).toBeUndefined(); }); - it("should not define variables for undefined styling properties", () => { + test("should not define variables for undefined styling properties", () => { const styling = getBaseProjectStyling({ brandColor: { light: "#ABC" } }); // Only brandColor is defined addCustomThemeToDom({ styling }); const styleElement = document.getElementById("formbricks__css__custom") as HTMLStyleElement; @@ -275,7 +275,7 @@ describe("addCustomThemeToDom", () => { }); describe("getBaseProjectStyling_Helper", () => { - it("should return default values for all properties when no overrides are provided", () => { + test("should return default values for all properties when no overrides are provided", () => { const baseStyling = getBaseProjectStyling(); expect(baseStyling.brandColor).toBeNull(); expect(baseStyling.cardBackgroundColor).toBeNull(); @@ -293,7 +293,7 @@ describe("getBaseProjectStyling_Helper", () => { expect(baseStyling.isLogoHidden).toBeNull(); }); - it("should correctly apply overrides to specified properties", () => { + test("should correctly apply overrides to specified properties", () => { const overrides: Partial = { inputColor: { light: "#111" }, inputBorderColor: { light: "#222" }, diff --git a/packages/surveys/src/lib/survey-state.test.ts b/packages/surveys/src/lib/survey-state.test.ts index 05885c42db..5ae8ca08e2 100644 --- a/packages/surveys/src/lib/survey-state.test.ts +++ b/packages/surveys/src/lib/survey-state.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, test } from "vitest"; import { TResponseUpdate } from "@formbricks/types/responses"; import { SurveyState } from "./survey-state"; @@ -10,7 +10,7 @@ describe("SurveyState", () => { surveyState = new SurveyState(initialSurveyId); }); - it("should initialize with a surveyId and default values", () => { + test("should initialize with a surveyId and default values", () => { expect(surveyState.surveyId).toBe(initialSurveyId); expect(surveyState.responseId).toBeNull(); expect(surveyState.displayId).toBeNull(); @@ -20,7 +20,7 @@ describe("SurveyState", () => { expect(surveyState.responseAcc).toEqual({ finished: false, data: {}, ttc: {}, variables: {} }); }); - it("should initialize with all optional parameters", () => { + test("should initialize with all optional parameters", () => { const singleUseId = "singleUse123"; const responseId = "response123"; const userId = "user123"; @@ -34,7 +34,7 @@ describe("SurveyState", () => { }); describe("setSurveyId", () => { - it("should update surveyId and clear the state", () => { + test("should update surveyId and clear the state", () => { surveyState.responseId = "res1"; surveyState.responseAcc = { finished: true, data: { q1: "ans1" }, ttc: { q1: 100 }, variables: {} }; const newSurveyId = "survey2"; @@ -46,7 +46,7 @@ describe("SurveyState", () => { }); describe("copy", () => { - it("should create a deep copy of the survey state", () => { + test("should create a deep copy of the survey state", () => { surveyState.responseId = "res123"; surveyState.responseAcc = { finished: true, @@ -74,7 +74,7 @@ describe("SurveyState", () => { expect(copiedState.responseAcc.variables).toBe(surveyState.responseAcc.variables); }); - it("should correctly copy when optional IDs are null", () => { + test("should correctly copy when optional IDs are null", () => { // surveyState is in its initial state from beforeEach, // where singleUseId, responseId, userId, contactId are null. const copiedState = surveyState.copy(); @@ -91,32 +91,32 @@ describe("SurveyState", () => { }); }); - it("should update responseId", () => { + test("should update responseId", () => { const newResponseId = "res456"; surveyState.updateResponseId(newResponseId); expect(surveyState.responseId).toBe(newResponseId); }); - it("should update displayId", () => { + test("should update displayId", () => { const newDisplayId = "disp789"; surveyState.updateDisplayId(newDisplayId); expect(surveyState.displayId).toBe(newDisplayId); }); - it("should update userId", () => { + test("should update userId", () => { const newUserId = "userXYZ"; surveyState.updateUserId(newUserId); expect(surveyState.userId).toBe(newUserId); }); - it("should update contactId", () => { + test("should update contactId", () => { const newContactId = "contactABC"; surveyState.updateContactId(newContactId); expect(surveyState.contactId).toBe(newContactId); }); describe("accumulateResponse", () => { - it("should accumulate response data correctly", () => { + test("should accumulate response data correctly", () => { const initialResponse: TResponseUpdate = { finished: false, data: { q1: "ans1" }, @@ -144,19 +144,19 @@ describe("SurveyState", () => { }); describe("isResponseFinished", () => { - it("should return true if responseAcc.finished is true", () => { + test("should return true if responseAcc.finished is true", () => { surveyState.responseAcc.finished = true; expect(surveyState.isResponseFinished()).toBe(true); }); - it("should return false if responseAcc.finished is false", () => { + test("should return false if responseAcc.finished is false", () => { surveyState.responseAcc.finished = false; expect(surveyState.isResponseFinished()).toBe(false); }); }); describe("clear", () => { - it("should reset responseId and responseAcc", () => { + test("should reset responseId and responseAcc", () => { surveyState.responseId = "someId"; surveyState.responseAcc = { finished: true, data: { q: "a" }, ttc: { q: 1 }, variables: { v: "1" } }; surveyState.clear(); diff --git a/packages/surveys/src/lib/ttc.test.ts b/packages/surveys/src/lib/ttc.test.ts index 77742c67c7..97ea72c693 100644 --- a/packages/surveys/src/lib/ttc.test.ts +++ b/packages/surveys/src/lib/ttc.test.ts @@ -1,24 +1,24 @@ import { act, renderHook } from "@testing-library/preact"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { TResponseTtc } from "@formbricks/types/responses"; import { TSurveyQuestionId } from "@formbricks/types/surveys/types"; import { getUpdatedTtc, useTtc } from "./ttc"; describe("getUpdatedTtc", () => { - it("should add time to an existing questionId", () => { + test("should add time to an existing questionId", () => { const ttc: TResponseTtc = { q1: 1000 }; const updatedTtc = getUpdatedTtc(ttc, "q1", 500); expect(updatedTtc.q1).toBe(1500); }); - it("should add a new questionId and time if it does not exist", () => { + test("should add a new questionId and time if it does not exist", () => { const ttc: TResponseTtc = { q1: 1000 }; const updatedTtc = getUpdatedTtc(ttc, "q2", 500); expect(updatedTtc.q2).toBe(500); expect(updatedTtc.q1).toBe(1000); // Ensure existing entries are preserved }); - it("should return a new object and not mutate the original", () => { + test("should return a new object and not mutate the original", () => { const ttc: TResponseTtc = { q1: 1000 }; const updatedTtc = getUpdatedTtc(ttc, "q1", 500); expect(updatedTtc).not.toBe(ttc); @@ -66,7 +66,7 @@ describe("useTtc", () => { }); }); - it("should set initial start time if isCurrentQuestion is true", () => { + test("should set initial start time if isCurrentQuestion is true", () => { renderHook(() => useTtc( initialProps.questionId, @@ -80,7 +80,7 @@ describe("useTtc", () => { expect(mockSetStartTime).toHaveBeenCalledWith(currentTime); }); - it("should not set initial start time if isCurrentQuestion is false", () => { + test("should not set initial start time if isCurrentQuestion is false", () => { renderHook(() => useTtc( initialProps.questionId, @@ -94,7 +94,7 @@ describe("useTtc", () => { expect(mockSetStartTime).not.toHaveBeenCalled(); }); - it("should add event listener if isCurrentQuestion is true", () => { + test("should add event listener if isCurrentQuestion is true", () => { renderHook(() => useTtc( initialProps.questionId, @@ -108,7 +108,7 @@ describe("useTtc", () => { expect(document.addEventListener).toHaveBeenCalledWith("visibilitychange", expect.any(Function)); }); - it("should not add event listener if isCurrentQuestion is false", () => { + test("should not add event listener if isCurrentQuestion is false", () => { renderHook(() => useTtc( initialProps.questionId, @@ -122,7 +122,7 @@ describe("useTtc", () => { expect(document.addEventListener).not.toHaveBeenCalled(); }); - it("should update ttc when visibility changes to hidden and isCurrentQuestion is true", () => { + test("should update ttc when visibility changes to hidden and isCurrentQuestion is true", () => { const currentTtc = { q1: 50 }; const currentStartTime = 1000; currentTime = 1500; // 500ms passed @@ -142,7 +142,7 @@ describe("useTtc", () => { expect(mockSetTtc).toHaveBeenCalledWith({ q1: 550 }); // 50 (existing) + 500 (passed) }); - it("should restart startTime when visibility changes to visible and isCurrentQuestion is true", () => { + test("should restart startTime when visibility changes to visible and isCurrentQuestion is true", () => { renderHook(() => useTtc( initialProps.questionId, @@ -166,7 +166,7 @@ describe("useTtc", () => { expect(mockSetStartTime).toHaveBeenCalledWith(2000); }); - it("should not update ttc or startTime if visibility changes but isCurrentQuestion is false", () => { + test("should not update ttc or startTime if visibility changes but isCurrentQuestion is false", () => { renderHook(() => useTtc( initialProps.questionId, @@ -197,7 +197,7 @@ describe("useTtc", () => { expect(mockSetStartTime).not.toHaveBeenCalled(); // It was not called initially either }); - it("should remove event listener on unmount if it was added", () => { + test("should remove event listener on unmount if it was added", () => { const { unmount } = renderHook(() => useTtc( initialProps.questionId, @@ -212,7 +212,7 @@ describe("useTtc", () => { expect(document.removeEventListener).toHaveBeenCalledWith("visibilitychange", expect.any(Function)); }); - it("should not attempt to remove event listener on unmount if not added", () => { + test("should not attempt to remove event listener on unmount if not added", () => { const { unmount } = renderHook(() => useTtc( initialProps.questionId, @@ -227,7 +227,7 @@ describe("useTtc", () => { expect(document.removeEventListener).not.toHaveBeenCalled(); }); - it("should set startTime when isCurrentQuestion becomes true", () => { + test("should set startTime when isCurrentQuestion becomes true", () => { const { rerender } = renderHook( (props) => useTtc( diff --git a/packages/surveys/src/lib/utils.test.ts b/packages/surveys/src/lib/utils.test.ts index 2e9938a151..3e504f9ecf 100644 --- a/packages/surveys/src/lib/utils.test.ts +++ b/packages/surveys/src/lib/utils.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; +import { beforeEach, describe, expect, test, vi } from "vitest"; import { type TAllowedFileExtension, mimeTypes } from "../../../types/common"; import type { TJsEnvironmentStateSurvey } from "../../../types/js"; import type { TSurveyLanguage, TSurveyQuestionChoice } from "../../../types/surveys/types"; @@ -13,7 +13,7 @@ vi.stubGlobal("crypto", { describe("getMimeType", () => { Object.entries(mimeTypes).forEach(([extension, expectedMimeType]) => { - it(`should return "${expectedMimeType}" for extension "${extension}"`, () => { + test(`should return "${expectedMimeType}" for extension "${extension}"`, () => { expect(getMimeType(extension as TAllowedFileExtension)).toBe(expectedMimeType); }); }); @@ -59,7 +59,7 @@ describe("getDefaultLanguageCode", () => { // ... other mandatory fields with default/mock values if needed }; - it("should return the code of the default language", () => { + test("should return the code of the default language", () => { const survey: TJsEnvironmentStateSurvey = { ...baseMockSurvey, languages: [mockSurveyLanguageEs, mockSurveyLanguageEn], @@ -67,7 +67,7 @@ describe("getDefaultLanguageCode", () => { expect(getDefaultLanguageCode(survey)).toBe("en"); }); - it("should return undefined if no default language", () => { + test("should return undefined if no default language", () => { const survey: TJsEnvironmentStateSurvey = { ...baseMockSurvey, languages: [{ ...mockSurveyLanguageEs, default: false }], // Ensure 'default' is explicitly false @@ -75,7 +75,7 @@ describe("getDefaultLanguageCode", () => { expect(getDefaultLanguageCode(survey)).toBeUndefined(); }); - it("should return undefined if languages array is empty", () => { + test("should return undefined if languages array is empty", () => { const survey: TJsEnvironmentStateSurvey = { ...baseMockSurvey, languages: [], @@ -95,23 +95,23 @@ describe("getShuffledRowIndices", () => { mockGetRandomValues.mockReset(); }); - it('should return unshuffled for "none"', () => { + test('should return unshuffled for "none"', () => { expect(getShuffledRowIndices(5, "none")).toEqual([0, 1, 2, 3, 4]); }); - it('should shuffle all for "all"', () => { + test('should shuffle all for "all"', () => { setNextRandomNormalizedValue(0.1); setNextRandomNormalizedValue(0.1); expect(getShuffledRowIndices(3, "all")).toEqual([1, 2, 0]); }); - it('should shuffle except last for "exceptLast"', () => { + test('should shuffle except last for "exceptLast"', () => { setNextRandomNormalizedValue(0.1); setNextRandomNormalizedValue(0.1); expect(getShuffledRowIndices(4, "exceptLast")).toEqual([1, 2, 0, 3]); }); - it("should handle n=0 or n=1", () => { + test("should handle n=0 or n=1", () => { expect(getShuffledRowIndices(0, "all")).toEqual([]); expect(getShuffledRowIndices(1, "all")).toEqual([0]); expect(getShuffledRowIndices(1, "exceptLast")).toEqual([0]); @@ -130,34 +130,34 @@ describe("getShuffledChoicesIds", () => { ]; const choicesWithOther: TSurveyQuestionChoice[] = [...choicesBase, { id: "other", label: { en: "Other" } }]; - it('should return unshuffled for "none"', () => { + test('should return unshuffled for "none"', () => { expect(getShuffledChoicesIds(choicesBase, "none")).toEqual(["c1", "c2", "c3"]); expect(getShuffledChoicesIds(choicesWithOther, "none")).toEqual(["c1", "c2", "c3", "other"]); }); - it('should shuffle all (no "other") for "all"', () => { + test('should shuffle all (no "other") for "all"', () => { setNextRandomNormalizedValue(0.1); setNextRandomNormalizedValue(0.1); expect(getShuffledChoicesIds(choicesBase, "all")).toEqual(["c2", "c3", "c1"]); }); - it('should shuffle all (with "other") for "all", keeping "other" last', () => { + test('should shuffle all (with "other") for "all", keeping "other" last', () => { setNextRandomNormalizedValue(0.1); setNextRandomNormalizedValue(0.1); expect(getShuffledChoicesIds(choicesWithOther, "all")).toEqual(["c2", "c3", "c1", "other"]); }); - it('should shuffle except last (no "other") for "exceptLast"', () => { + test('should shuffle except last (no "other") for "exceptLast"', () => { setNextRandomNormalizedValue(0.1); expect(getShuffledChoicesIds(choicesBase, "exceptLast")).toEqual(["c2", "c1", "c3"]); }); - it('should shuffle except last (with "other") for "exceptLast", keeping "other" truly last', () => { + test('should shuffle except last (with "other") for "exceptLast", keeping "other" truly last', () => { setNextRandomNormalizedValue(0.1); expect(getShuffledChoicesIds(choicesWithOther, "exceptLast")).toEqual(["c2", "c1", "c3", "other"]); }); - it("should handle empty or single choice arrays", () => { + test("should handle empty or single choice arrays", () => { expect(getShuffledChoicesIds([], "all")).toEqual([]); const singleChoice = [{ id: "s1", label: { en: "Single" } }]; expect(getShuffledChoicesIds(singleChoice, "all")).toEqual(["s1"]); diff --git a/packages/surveys/src/lib/video-upload.test.ts b/packages/surveys/src/lib/video-upload.test.ts index 86c1ca08e2..b1efb426db 100644 --- a/packages/surveys/src/lib/video-upload.test.ts +++ b/packages/surveys/src/lib/video-upload.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { describe, expect, test } from "vitest"; import { checkForLoomUrl, checkForVimeoUrl, @@ -22,13 +22,13 @@ describe("checkForYoutubeUrl", () => { ]; validUrls.forEach((url) => { - it(`should return true for valid YouTube URL: ${url}`, () => { + test(`should return true for valid YouTube URL: ${url}`, () => { expect(checkForYoutubeUrl(url)).toBe(true); }); }); invalidUrls.forEach((url) => { - it(`should return false for invalid YouTube URL: ${url}`, () => { + test(`should return false for invalid YouTube URL: ${url}`, () => { expect(checkForYoutubeUrl(url)).toBe(false); }); }); @@ -44,13 +44,13 @@ describe("checkForVimeoUrl", () => { ]; validUrls.forEach((url) => { - it(`should return true for valid Vimeo URL: ${url}`, () => { + test(`should return true for valid Vimeo URL: ${url}`, () => { expect(checkForVimeoUrl(url)).toBe(true); }); }); invalidUrls.forEach((url) => { - it(`should return false for invalid Vimeo URL: ${url}`, () => { + test(`should return false for invalid Vimeo URL: ${url}`, () => { expect(checkForVimeoUrl(url)).toBe(false); }); }); @@ -66,13 +66,13 @@ describe("checkForLoomUrl", () => { ]; validUrls.forEach((url) => { - it(`should return true for valid Loom URL: ${url}`, () => { + test(`should return true for valid Loom URL: ${url}`, () => { expect(checkForLoomUrl(url)).toBe(true); }); }); invalidUrls.forEach((url) => { - it(`should return false for invalid Loom URL: ${url}`, () => { + test(`should return false for invalid Loom URL: ${url}`, () => { expect(checkForLoomUrl(url)).toBe(false); }); }); @@ -91,7 +91,7 @@ describe("extractYoutubeId", () => { ]; urlsAndIds.forEach(([url, expectedId]) => { - it(`should extract ID "${expectedId}" from URL: ${url}`, () => { + test(`should extract ID "${expectedId}" from URL: ${url}`, () => { expect(extractYoutubeId(url)).toBe(expectedId); }); }); @@ -111,7 +111,7 @@ describe("convertToEmbedUrl", () => { ]; urlsAndEmbeds.forEach(([url, expectedEmbedUrl]) => { - it(`should convert "${url}" to "${expectedEmbedUrl}"`, () => { + test(`should convert "${url}" to "${expectedEmbedUrl}"`, () => { expect(convertToEmbedUrl(url)).toBe(expectedEmbedUrl); }); });