Files
formbricks-formbricks/apps/web/lib/response/utils.test.ts
Anshuman Pandey f888aa8a19 feat: MQP (#6901)
Co-authored-by: Matti Nannt <matti@formbricks.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Dhruwang Jariwala <67850763+Dhruwang@users.noreply.github.com>
Co-authored-by: Dhruwang <dhruwangjariwala18@gmail.com>
2025-11-28 12:36:17 +00:00

886 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Prisma } from "@prisma/client";
import { describe, expect, test } from "vitest";
import { TResponse } from "@formbricks/types/responses";
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
import { TSurvey } from "@formbricks/types/surveys/types";
import {
buildWhereClause,
calculateTtcTotal,
extracMetadataKeys,
extractChoiceIdsFromResponse,
extractSurveyDetails,
generateAllPermutationsOfSubsets,
getResponseContactAttributes,
getResponseHiddenFields,
getResponseMeta,
getResponsesFileName,
getResponsesJson,
} from "./utils";
describe("Response Utils", () => {
describe("calculateTtcTotal", () => {
test("should calculate total time correctly", () => {
const ttc = {
question1: 10,
question2: 20,
question3: 30,
};
const result = calculateTtcTotal(ttc);
expect(result._total).toBe(60);
});
test("should handle empty ttc object", () => {
const ttc = {};
const result = calculateTtcTotal(ttc);
expect(result._total).toBe(0);
});
});
describe("buildWhereClause", () => {
const mockSurvey: Partial<TSurvey> = {
id: "survey1",
name: "Test Survey",
blocks: [],
questions: [],
type: "app",
hiddenFields: { enabled: true, fieldIds: [] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "env1",
createdBy: "user1",
status: "draft",
};
test("should build where clause with finished filter", () => {
const filterCriteria = { finished: true };
const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
expect(result.AND).toContainEqual({ finished: true });
});
test("should build where clause with date range", () => {
const filterCriteria = {
createdAt: {
min: new Date("2024-01-01"),
max: new Date("2024-12-31"),
},
};
const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
expect(result.AND).toContainEqual({
createdAt: {
gte: new Date("2024-01-01"),
lte: new Date("2024-12-31"),
},
});
});
test("should build where clause with tags", () => {
const filterCriteria = {
tags: {
applied: ["tag1", "tag2"],
notApplied: ["tag3"],
},
};
const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
expect(result.AND).toHaveLength(1);
});
test("should build where clause with contact attributes", () => {
const filterCriteria = {
contactAttributes: {
email: { op: "equals" as const, value: "test@example.com" },
},
};
const result = buildWhereClause(mockSurvey as TSurvey, filterCriteria);
expect(result.AND).toHaveLength(1);
});
});
describe("buildWhereClause others & meta filters", () => {
const baseSurvey: Partial<TSurvey> = {
id: "s1",
name: "Survey",
blocks: [],
questions: [],
type: "app",
hiddenFields: { enabled: false, fieldIds: [] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "e1",
createdBy: "u1",
status: "inProgress",
};
test("others: equals & notEquals", () => {
const criteria = {
others: {
Language: { op: "equals" as const, value: "en" },
Region: { op: "notEquals" as const, value: "APAC" },
},
};
const result = buildWhereClause(baseSurvey as TSurvey, criteria);
expect(result.AND).toEqual([
{
AND: [{ language: "en" }, { region: { not: "APAC" } }],
},
]);
});
test("meta: equals & notEquals map to userAgent paths", () => {
const criteria = {
meta: {
browser: { op: "equals" as const, value: "Chrome" },
os: { op: "notEquals" as const, value: "Windows" },
},
};
const result = buildWhereClause(baseSurvey as TSurvey, criteria);
expect(result.AND).toEqual([
{
AND: [
{ meta: { path: ["userAgent", "browser"], equals: "Chrome" } },
{ meta: { path: ["userAgent", "os"], not: "Windows" } },
],
},
]);
});
test("meta: URL string comparison operations", () => {
const testCases = [
{
name: "contains",
criteria: { meta: { url: { op: "contains" as const, value: "example.com" } } },
expected: { meta: { path: ["url"], string_contains: "example.com" } },
},
{
name: "doesNotContain",
criteria: { meta: { url: { op: "doesNotContain" as const, value: "test.com" } } },
expected: { NOT: { meta: { path: ["url"], string_contains: "test.com" } } },
},
{
name: "startsWith",
criteria: { meta: { url: { op: "startsWith" as const, value: "https://" } } },
expected: { meta: { path: ["url"], string_starts_with: "https://" } },
},
{
name: "doesNotStartWith",
criteria: { meta: { url: { op: "doesNotStartWith" as const, value: "http://" } } },
expected: { NOT: { meta: { path: ["url"], string_starts_with: "http://" } } },
},
{
name: "endsWith",
criteria: { meta: { url: { op: "endsWith" as const, value: ".com" } } },
expected: { meta: { path: ["url"], string_ends_with: ".com" } },
},
{
name: "doesNotEndWith",
criteria: { meta: { url: { op: "doesNotEndWith" as const, value: ".org" } } },
expected: { NOT: { meta: { path: ["url"], string_ends_with: ".org" } } },
},
];
testCases.forEach(({ criteria, expected }) => {
const result = buildWhereClause(baseSurvey as TSurvey, criteria);
expect(result.AND).toEqual([{ AND: [expected] }]);
});
});
});
describe("buildWhereClause datafield filter operations", () => {
const textSurvey: Partial<TSurvey> = {
id: "s2",
name: "TextSurvey",
blocks: [
{
id: "block1",
name: "Block 1",
elements: [
{
id: "qText",
type: TSurveyElementTypeEnum.OpenText,
headline: { default: "Text Q" },
required: false,
isDraft: false,
charLimit: {},
inputType: "text",
},
{
id: "qNum",
type: TSurveyElementTypeEnum.OpenText,
headline: { default: "Num Q" },
required: false,
isDraft: false,
charLimit: {},
inputType: "number",
},
],
},
],
questions: [],
type: "app",
hiddenFields: { enabled: false, fieldIds: [] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "e2",
createdBy: "u2",
status: "inProgress",
};
const ops: Array<[keyof TSurveyElementTypeEnum | string, any, any]> = [
["submitted", { op: "submitted" }, { path: ["qText"], not: Prisma.DbNull }],
["filledOut", { op: "filledOut" }, { path: ["qText"], not: [] }],
["skipped", { op: "skipped" }, "OR"],
["equals", { op: "equals", value: "foo" }, { path: ["qText"], equals: "foo" }],
["notEquals", { op: "notEquals", value: "bar" }, "NOT"],
["lessThan", { op: "lessThan", value: 5 }, { path: ["qNum"], lt: 5 }],
["lessEqual", { op: "lessEqual", value: 10 }, { path: ["qNum"], lte: 10 }],
["greaterThan", { op: "greaterThan", value: 1 }, { path: ["qNum"], gt: 1 }],
["greaterEqual", { op: "greaterEqual", value: 2 }, { path: ["qNum"], gte: 2 }],
[
"includesAll",
{ op: "includesAll", value: ["a", "b"] },
{ path: ["qText"], array_contains: ["a", "b"] },
],
];
ops.forEach(([name, filter, expected]) => {
test(name as string, () => {
const result = buildWhereClause(textSurvey as TSurvey, {
data: {
[["submitted", "filledOut", "equals", "includesAll"].includes(name as string) ? "qText" : "qNum"]:
filter,
},
});
// for OR/NOT cases we just ensure the operator key exists
if (expected === "OR" || expected === "NOT") {
expect(JSON.stringify(result)).toMatch(
new RegExp(name === "skipped" ? `"OR":\\s*\\[` : `"not":"${filter.value}"`)
);
} else {
expect(result.AND).toEqual([
{
AND: [{ data: expected }],
},
]);
}
});
});
test("uploaded & notUploaded", () => {
const res1 = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: "uploaded" } } });
expect(res1.AND).toContainEqual({
AND: [{ data: { path: ["qText"], not: "skipped" } }],
});
const res2 = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: "notUploaded" } } });
expect(JSON.stringify(res2)).toMatch(/"equals":"skipped"/);
expect(JSON.stringify(res2)).toMatch(/"equals":{}/);
});
test("clicked, accepted & booked", () => {
["clicked", "accepted", "booked"].forEach((status) => {
const key = status as "clicked" | "accepted" | "booked";
const res = buildWhereClause(textSurvey as TSurvey, { data: { qText: { op: key } } });
expect(res.AND).toEqual([{ AND: [{ data: { path: ["qText"], equals: status } }] }]);
});
});
test("matrix", () => {
const matrixSurvey: Partial<TSurvey> = {
id: "s3",
name: "MatrixSurvey",
blocks: [
{
id: "block1",
name: "Block 1",
elements: [
{
id: "qM",
type: TSurveyElementTypeEnum.Matrix,
headline: { default: "Matrix" },
required: false,
rows: [{ id: "r1", label: { default: "R1" } }],
columns: [{ id: "c1", label: { default: "C1" } }],
shuffleOption: "none",
isDraft: false,
},
],
},
],
questions: [],
type: "app",
hiddenFields: { enabled: false, fieldIds: [] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "e3",
createdBy: "u3",
status: "inProgress",
};
const res = buildWhereClause(matrixSurvey as TSurvey, {
data: { qM: { op: "matrix", value: { R1: "foo" } } },
});
expect(res.AND).toEqual([
{
AND: [
{
data: { path: ["qM", "R1"], equals: "foo" },
},
],
},
]);
});
});
describe("getResponsesFileName", () => {
test("should generate correct filename", () => {
const surveyName = "Test Survey";
const extension = "csv";
const result = getResponsesFileName(surveyName, extension);
expect(result).toContain("export-test_survey-");
});
});
describe("extracMetadataKeys", () => {
test("should extract metadata keys correctly", () => {
const meta = {
userAgent: { browser: "Chrome", os: "Windows", device: "Desktop" },
country: "US",
source: "direct",
};
const result = extracMetadataKeys(meta);
expect(result).toContain("userAgent - browser");
expect(result).toContain("userAgent - os");
expect(result).toContain("userAgent - device");
expect(result).toContain("country");
expect(result).toContain("source");
});
test("should handle empty metadata", () => {
const result = extracMetadataKeys({});
expect(result).toEqual([]);
});
});
// TODO: Fix this test after the survey editor poc is merged
describe("extractSurveyDetails", () => {
const mockSurvey: Partial<TSurvey> = {
id: "survey1",
name: "Test Survey",
blocks: [
{
id: "block1",
name: "Block 1",
elements: [
{
id: "q1",
type: TSurveyElementTypeEnum.MultipleChoiceSingle,
headline: { default: "Question 1" },
required: true,
choices: [
{ id: "1", label: { default: "Option 1" } },
{ id: "2", label: { default: "Option 2" } },
],
shuffleOption: "none",
isDraft: false,
},
{
id: "q2",
type: TSurveyElementTypeEnum.Matrix,
headline: { default: "Matrix Question" },
required: true,
rows: [
{ id: "r1", label: { default: "Row 1" } },
{ id: "r2", label: { default: "Row 2" } },
],
columns: [
{ id: "c1", label: { default: "Column 1" } },
{ id: "c2", label: { default: "Column 2" } },
],
shuffleOption: "none",
isDraft: false,
},
],
},
],
questions: [],
type: "app",
hiddenFields: { enabled: true, fieldIds: ["hidden1"] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "env1",
createdBy: "user1",
status: "draft",
};
const mockResponses: Partial<TResponse>[] = [
{
id: "response1",
surveyId: "survey1",
data: {},
meta: { userAgent: { browser: "Chrome" } },
contactAttributes: { email: "test@example.com" },
finished: true,
createdAt: new Date(),
updatedAt: new Date(),
tags: [],
},
];
test("should extract survey details correctly", () => {
const result = extractSurveyDetails(mockSurvey as TSurvey, mockResponses as TResponse[]);
expect(result.metaDataFields).toContain("userAgent - browser");
expect(result.elements).toHaveLength(2); // 1 regular question + 2 matrix rows
expect(result.hiddenFields).toContain("hidden1");
expect(result.userAttributes).toContain("email");
});
});
describe("getResponsesJson", () => {
const mockSurvey: Partial<TSurvey> = {
id: "survey1",
name: "Test Survey",
blocks: [
{
id: "block1",
name: "Block 1",
elements: [
{
id: "q1",
type: TSurveyElementTypeEnum.MultipleChoiceSingle,
headline: { default: "Question 1" },
required: true,
choices: [
{ id: "1", label: { default: "Option 1" } },
{ id: "2", label: { default: "Option 2" } },
],
shuffleOption: "none",
isDraft: false,
},
],
},
],
questions: [],
type: "app",
hiddenFields: { enabled: true, fieldIds: [] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "env1",
createdBy: "user1",
status: "draft",
};
const mockResponses: Partial<TResponse>[] = [
{
id: "response1",
surveyId: "survey1",
data: { q1: "answer1" },
meta: { userAgent: { browser: "Chrome" } },
contactAttributes: { email: "test@example.com" },
finished: true,
createdAt: new Date(),
updatedAt: new Date(),
tags: [],
},
];
test("should generate correct JSON data", () => {
const questionsHeadlines = [["1. Question 1"]];
const userAttributes = ["email"];
const hiddenFields: string[] = [];
const result = getResponsesJson(
mockSurvey as TSurvey,
mockResponses as TResponse[],
questionsHeadlines,
userAttributes,
hiddenFields,
false
);
expect(result[0]["Response ID"]).toBe("response1");
expect(result[0]["userAgent - browser"]).toBe("Chrome");
expect(result[0]["1. Question 1"]).toBe("answer1");
expect(result[0]["email"]).toBe("test@example.com");
});
});
describe("getResponseContactAttributes", () => {
test("should extract contact attributes correctly", () => {
const responses = [
{
contactAttributes: { email: "test1@example.com", name: "Test 1" },
data: {},
meta: {},
},
{
contactAttributes: { email: "test2@example.com", name: "Test 2" },
data: {},
meta: {},
},
];
const result = getResponseContactAttributes(
responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]
);
expect(result.email).toContain("test1@example.com");
expect(result.email).toContain("test2@example.com");
expect(result.name).toContain("Test 1");
expect(result.name).toContain("Test 2");
});
test("should handle empty responses", () => {
const result = getResponseContactAttributes([]);
expect(result).toEqual({});
});
});
describe("getResponseMeta", () => {
test("should extract meta data correctly", () => {
const responses = [
{
contactAttributes: {},
data: {},
meta: {
userAgent: { browser: "Chrome", os: "Windows" },
country: "US",
},
},
{
contactAttributes: {},
data: {},
meta: {
userAgent: { browser: "Firefox", os: "MacOS" },
country: "UK",
},
},
];
const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
expect(result.browser).toContain("Chrome");
expect(result.browser).toContain("Firefox");
expect(result.os).toContain("Windows");
expect(result.os).toContain("MacOS");
});
test("should extract URL data correctly", () => {
const responses = [
{
contactAttributes: {},
data: {},
meta: {
url: "https://example.com/page1",
source: "direct",
},
},
{
contactAttributes: {},
data: {},
meta: {
url: "https://test.com/page2?param=value",
source: "google",
},
},
];
const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
expect(result.url).toEqual([]);
expect(result.source).toContain("direct");
expect(result.source).toContain("google");
});
test("should handle mixed meta data with URLs", () => {
const responses = [
{
contactAttributes: {},
data: {},
meta: {
userAgent: { browser: "Chrome", device: "desktop" },
url: "https://formbricks.com/dashboard",
country: "US",
},
},
{
contactAttributes: {},
data: {},
meta: {
userAgent: { browser: "Safari", device: "mobile" },
url: "https://formbricks.com/surveys/123",
country: "UK",
},
},
];
const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
expect(result.browser).toContain("Chrome");
expect(result.browser).toContain("Safari");
expect(result.device).toContain("desktop");
expect(result.device).toContain("mobile");
expect(result.url).toEqual([]);
expect(result.country).toContain("US");
expect(result.country).toContain("UK");
});
test("should handle empty responses", () => {
const result = getResponseMeta([]);
expect(result).toEqual({});
});
test("should ignore empty or null URL values", () => {
const responses = [
{
contactAttributes: {},
data: {},
meta: {
url: "",
source: "direct",
},
},
{
contactAttributes: {},
data: {},
meta: {
url: null as any,
source: "newsletter",
},
},
{
contactAttributes: {},
data: {},
meta: {
url: "https://valid.com",
source: "google",
},
},
];
const result = getResponseMeta(responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]);
expect(result.url).toEqual([]);
expect(result.source).toEqual(expect.arrayContaining(["direct", "newsletter", "google"]));
});
});
describe("getResponseHiddenFields", () => {
const mockSurvey: Partial<TSurvey> = {
id: "survey1",
name: "Test Survey",
questions: [],
type: "app",
hiddenFields: { enabled: true, fieldIds: ["hidden1", "hidden2"] },
createdAt: new Date(),
updatedAt: new Date(),
environmentId: "env1",
createdBy: "user1",
status: "draft",
};
test("should extract hidden fields correctly", () => {
const responses = [
{
contactAttributes: {},
data: { hidden1: "value1", hidden2: "value2" },
meta: {},
},
{
contactAttributes: {},
data: { hidden1: "value3", hidden2: "value4" },
meta: {},
},
];
const result = getResponseHiddenFields(
mockSurvey as TSurvey,
responses as Pick<TResponse, "contactAttributes" | "data" | "meta">[]
);
expect(result.hidden1).toContain("value1");
expect(result.hidden1).toContain("value3");
expect(result.hidden2).toContain("value2");
expect(result.hidden2).toContain("value4");
});
test("should handle empty responses", () => {
const result = getResponseHiddenFields(mockSurvey as TSurvey, []);
expect(result).toEqual({
hidden1: [],
hidden2: [],
});
});
});
describe("generateAllPermutationsOfSubsets", () => {
test("with empty array returns empty", () => {
expect(generateAllPermutationsOfSubsets([])).toEqual([]);
});
test("with two elements returns 4 permutations", () => {
const out = generateAllPermutationsOfSubsets(["x", "y"]);
expect(out).toEqual(expect.arrayContaining([["x"], ["y"], ["x", "y"], ["y", "x"]]));
expect(out).toHaveLength(4);
});
});
});
describe("extractChoiceIdsFromResponse", () => {
const multipleChoiceMultiQuestion = {
id: "multi-choice-id",
type: TSurveyElementTypeEnum.MultipleChoiceMulti as typeof TSurveyElementTypeEnum.MultipleChoiceMulti,
headline: { default: "Select multiple options" },
required: false,
choices: [
{
id: "choice-1",
label: { default: "Option 1", es: "Opción 1" },
},
{
id: "choice-2",
label: { default: "Option 2", es: "Opción 2" },
},
{
id: "choice-3",
label: { default: "Option 3", es: "Opción 3" },
},
],
shuffleOption: "none" as const,
};
const multipleChoiceSingleQuestion = {
id: "single-choice-id",
type: TSurveyElementTypeEnum.MultipleChoiceSingle as typeof TSurveyElementTypeEnum.MultipleChoiceSingle,
headline: { default: "Select one option" },
required: false,
choices: [
{
id: "choice-a",
label: { default: "Choice A", fr: "Choix A" },
},
{
id: "choice-b",
label: { default: "Choice B", fr: "Choix B" },
},
],
shuffleOption: "none" as const,
};
const textQuestion = {
id: "text-id",
type: TSurveyElementTypeEnum.OpenText as typeof TSurveyElementTypeEnum.OpenText,
headline: { default: "What do you think?" },
required: false,
inputType: "text" as const,
charLimit: { enabled: false, min: 0, max: 0 },
};
describe("multipleChoiceMulti questions", () => {
test("should extract choice IDs from array response with default language", () => {
const responseValue = ["Option 1", "Option 3"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual(["choice-1", "choice-3"]);
});
test("should extract choice IDs from array response with specific language", () => {
const responseValue = ["Opción 1", "Opción 2"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "es");
expect(result).toEqual(["choice-1", "choice-2"]);
});
test("should fall back to checking all language values when exact language match fails", () => {
const responseValue = ["Opción 1", "Option 2"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual(["choice-1", "choice-2"]);
});
test("should render other option when non-matching choice is selected", () => {
const responseValue = ["Option 1", "Non-existent option", "Option 3"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual(["choice-1", "other", "choice-3"]);
});
test("should return empty array for empty response", () => {
const responseValue: string[] = [];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual([]);
});
});
describe("multipleChoiceSingle questions", () => {
test("should extract choice ID from string response with default language", () => {
const responseValue = "Choice A";
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");
expect(result).toEqual(["choice-a"]);
});
test("should extract choice ID from string response with specific language", () => {
const responseValue = "Choix B";
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "fr");
expect(result).toEqual(["choice-b"]);
});
test("should fall back to checking all language values for single choice", () => {
const responseValue = "Choix A";
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");
expect(result).toEqual(["choice-a"]);
});
test("should return empty array for empty string response", () => {
const responseValue = "";
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceSingleQuestion, "default");
expect(result).toEqual([]);
});
});
describe("edge cases", () => {
test("should return empty array for non-multiple choice questions", () => {
const responseValue = "Some text response";
const result = extractChoiceIdsFromResponse(responseValue, textQuestion, "default");
expect(result).toEqual([]);
});
test("should handle missing language parameter by defaulting to 'default'", () => {
const responseValue = "Option 1";
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion);
expect(result).toEqual(["choice-1"]);
});
test("should handle numeric or other types by returning empty array", () => {
const responseValue = 123;
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual([]);
});
test("should handle object responses by returning empty array", () => {
const responseValue = { invalid: "object" };
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "default");
expect(result).toEqual([]);
});
});
describe("language handling", () => {
test("should use provided language parameter", () => {
const responseValue = ["Opción 1"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, "es");
expect(result).toEqual(["choice-1"]);
});
test("should handle null language parameter by defaulting to 'default'", () => {
const responseValue = ["Option 1"];
const result = extractChoiceIdsFromResponse(responseValue, multipleChoiceMultiQuestion, null as any);
expect(result).toEqual(["choice-1"]);
});
test("should handle undefined language parameter by defaulting to 'default'", () => {
const responseValue = ["Option 1"];
const result = extractChoiceIdsFromResponse(
responseValue,
multipleChoiceMultiQuestion,
undefined as any
);
expect(result).toEqual(["choice-1"]);
});
});
});