mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-22 19:51:52 -05:00
ffd4478184
Signed-off-by: gulshank0 <gulshanbahadur002@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Theodór Tómas <theodortomas@gmail.com> Co-authored-by: Anshuman Pandey <54475686+pandeymangg@users.noreply.github.com> Co-authored-by: Bhagya Amarasinghe <b.sithumini@yahoo.com> Co-authored-by: Chowdhury Tafsir Ahmed Siddiki <ctafsiras@gmail.com> Co-authored-by: neila <40727091+neila@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Tiago <1585571+xernobyl@users.noreply.github.com> Co-authored-by: Harsh Bhat <90265455+harshsbhat@users.noreply.github.com> Co-authored-by: Harsh Bhat <harshbhat@Harshs-MacBook-Air.local> Co-authored-by: Johannes <johannes@formbricks.com> Co-authored-by: pandeymangg <anshuman.pandey9999@gmail.com> Co-authored-by: Balázs Úr <balazs@urbalazs.hu> Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com> Co-authored-by: Gulshan <gulshanbahadur002@gmail.com> Co-authored-by: Tiago Farto <tiago@formbricks.com> Co-authored-by: Harsh Bhat <harsh121102@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
227 lines
8.0 KiB
TypeScript
227 lines
8.0 KiB
TypeScript
import { describe, expect, test } from "vitest";
|
|
import type { TChartQuery } from "@formbricks/types/analysis";
|
|
import { type ChartBuilderState, buildCubeQuery, parseQueryToState } from "./query-builder";
|
|
|
|
describe("query-builder", () => {
|
|
describe("buildCubeQuery", () => {
|
|
test("builds minimal query with measures only", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [],
|
|
filterLogic: "and",
|
|
timeDimension: null,
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.measures).toEqual(["FeedbackRecords.count"]);
|
|
expect(query.dimensions).toBeUndefined();
|
|
expect(query.timeDimensions).toBeUndefined();
|
|
expect(query.filters).toBeUndefined();
|
|
});
|
|
|
|
test("adds dimensions when present", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: ["FeedbackRecords.sentiment"],
|
|
filters: [],
|
|
filterLogic: "and",
|
|
timeDimension: null,
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.dimensions).toEqual(["FeedbackRecords.sentiment"]);
|
|
});
|
|
|
|
test("adds time dimension with string dateRange", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [],
|
|
filterLogic: "and",
|
|
timeDimension: {
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "day",
|
|
dateRange: "last 30 days",
|
|
},
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.timeDimensions).toEqual([
|
|
{ dimension: "FeedbackRecords.collectedAt", granularity: "day", dateRange: "last 30 days" },
|
|
]);
|
|
});
|
|
|
|
test("adds time dimension without granularity (filter only)", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [],
|
|
filterLogic: "and",
|
|
timeDimension: {
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
dateRange: "last 30 days",
|
|
},
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.timeDimensions).toEqual([
|
|
{ dimension: "FeedbackRecords.collectedAt", dateRange: "last 30 days" },
|
|
]);
|
|
});
|
|
|
|
test("adds time dimension with Date array dateRange", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [],
|
|
filterLogic: "and",
|
|
timeDimension: {
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "month",
|
|
dateRange: [new Date("2024-01-15"), new Date("2024-06-20")],
|
|
},
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.timeDimensions).toEqual([
|
|
{
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "month",
|
|
dateRange: ["2024-01-15", "2024-06-20"],
|
|
},
|
|
]);
|
|
});
|
|
|
|
test("adds AND filters as member filters", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [
|
|
{ id: "f1", field: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] },
|
|
{ id: "f2", field: "FeedbackRecords.sourceType", operator: "set", values: null },
|
|
],
|
|
filterLogic: "and",
|
|
timeDimension: null,
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.filters).toEqual([
|
|
{ member: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] },
|
|
{ member: "FeedbackRecords.sourceType", operator: "set" },
|
|
]);
|
|
});
|
|
|
|
test("adds OR filters wrapped in or", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: [],
|
|
filters: [{ id: "f1", field: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] }],
|
|
filterLogic: "or",
|
|
timeDimension: null,
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
expect(query.filters).toEqual([
|
|
{
|
|
or: [{ member: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] }],
|
|
},
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("parseQueryToState", () => {
|
|
test("parses minimal query", () => {
|
|
const state = parseQueryToState({ measures: ["FeedbackRecords.count"] });
|
|
expect(state.selectedMeasures).toEqual(["FeedbackRecords.count"]);
|
|
expect(state.selectedDimensions).toEqual([]);
|
|
expect(state.filters).toEqual([]);
|
|
expect(state.filterLogic).toBe("and");
|
|
expect(state.timeDimension).toBeNull();
|
|
});
|
|
|
|
test("parses AND member filters", () => {
|
|
const query = {
|
|
measures: ["FeedbackRecords.count"],
|
|
filters: [{ member: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] }],
|
|
};
|
|
const state = parseQueryToState(query);
|
|
expect(state.filterLogic).toBe("and");
|
|
expect(state.filters?.map(({ field, operator, values }) => ({ field, operator, values }))).toEqual([
|
|
{ field: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] },
|
|
]);
|
|
});
|
|
|
|
test("parses OR filters", () => {
|
|
const query = {
|
|
measures: ["FeedbackRecords.count"],
|
|
filters: [
|
|
{
|
|
or: [{ member: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] }],
|
|
},
|
|
],
|
|
};
|
|
const state = parseQueryToState(query);
|
|
expect(state.filterLogic).toBe("or");
|
|
expect(state.filters?.map(({ field, operator, values }) => ({ field, operator, values }))).toEqual([
|
|
{ field: "FeedbackRecords.sentiment", operator: "equals", values: ["positive"] },
|
|
]);
|
|
});
|
|
|
|
test("parses time dimension with granularity and dateRange", () => {
|
|
const query: TChartQuery = {
|
|
measures: ["FeedbackRecords.count"],
|
|
timeDimensions: [
|
|
{
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "day",
|
|
dateRange: "last 30 days",
|
|
},
|
|
],
|
|
};
|
|
const state = parseQueryToState(query);
|
|
expect(state.timeDimension).toEqual({
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "day",
|
|
dateRange: "last 30 days",
|
|
});
|
|
});
|
|
|
|
test("parses time dimension without granularity (filter only)", () => {
|
|
const query = {
|
|
measures: ["FeedbackRecords.count"],
|
|
timeDimensions: [
|
|
{
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
dateRange: "last 30 days",
|
|
},
|
|
],
|
|
};
|
|
const state = parseQueryToState(query);
|
|
expect(state.timeDimension).toEqual({
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
dateRange: "last 30 days",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("round-trip", () => {
|
|
test("buildCubeQuery then parseQueryToState restores state", () => {
|
|
const config: ChartBuilderState = {
|
|
selectedMeasures: ["FeedbackRecords.count"],
|
|
selectedDimensions: ["FeedbackRecords.sentiment"],
|
|
filters: [{ id: "f1", field: "FeedbackRecords.sourceType", operator: "equals", values: ["survey"] }],
|
|
filterLogic: "and",
|
|
timeDimension: {
|
|
dimension: "FeedbackRecords.collectedAt",
|
|
granularity: "week",
|
|
dateRange: "last 7 days",
|
|
},
|
|
};
|
|
const query = buildCubeQuery(config);
|
|
const restored = parseQueryToState(query);
|
|
|
|
expect(restored.selectedMeasures).toEqual(config.selectedMeasures);
|
|
expect(restored.selectedDimensions).toEqual(config.selectedDimensions);
|
|
expect(restored.filterLogic).toBe(config.filterLogic);
|
|
expect(restored.timeDimension).toEqual(config.timeDimension);
|
|
expect(restored.filters?.map(({ field, operator, values }) => ({ field, operator, values }))).toEqual(
|
|
config.filters.map(({ field, operator, values }) => ({ field, operator, values }))
|
|
);
|
|
});
|
|
});
|
|
});
|