Files
calendar/packages/features/ee/integration-attribute-sync/schemas/zod.test.ts
T
98b6d63164 refactor: apply biome formatting to packages/features (#27844)
* refactor: apply biome formatting to packages/features (batch 1 - small subdirs)

Format small subdirectories in packages/features: di, flags, holidays, oauth,
settings, users, assignment-reason, selectedCalendar, hashedLink, host, form,
form-builder, availability, data-table, pbac, schedules, troubleshooter,
eventtypes, calendar-subscription, and root-level files.

Also includes straggler apps/web BookEventForm.tsx.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 2 - medium subdirs)

Format medium subdirectories in packages/features: auth, credentials,
calendars, routing-forms, routing-trace, attributes, watchlist, calAIPhone,
tasker, and webhooks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 3 - bookings + insights)

Format bookings and insights subdirectories in packages/features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 4 - ee)

Format packages/features/ee subdirectory covering billing, workflows,
organizations, teams, managed-event-types, round-robin, dsync,
integration-attribute-sync, and payments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 5 - booking-audit part 1)

Format booking-audit di, actions, common, dto, repository, and types
subdirectories in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: apply biome formatting to packages/features (batch 6 - booking-audit part 2)

Format booking-audit service subdirectory in packages/features/booking-audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 15:47:14 +01:00

416 lines
9.9 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { attributeSyncRuleConditionSchema, attributeSyncRuleSchema, syncFormDataSchema } from "./zod";
describe("attributeSyncRuleConditionSchema", () => {
describe("team conditions", () => {
it("should validate a valid team condition with equals operator", () => {
const condition = {
identifier: "teamId",
operator: "equals",
value: [1, 2, 3],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
if (result.success) {
expect(result.data).toEqual(condition);
}
});
it("should validate a valid team condition with notEquals operator", () => {
const condition = {
identifier: "teamId",
operator: "notEquals",
value: [5],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
});
it("should validate a valid team condition with in operator", () => {
const condition = {
identifier: "teamId",
operator: "in",
value: [1, 2],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
});
it("should validate a valid team condition with notIn operator", () => {
const condition = {
identifier: "teamId",
operator: "notIn",
value: [3, 4],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
});
it("should reject team condition with string values", () => {
const condition = {
identifier: "teamId",
operator: "equals",
value: ["team-1", "team-2"],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
it("should reject team condition with invalid operator", () => {
const condition = {
identifier: "teamId",
operator: "contains",
value: [1],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
});
describe("attribute conditions", () => {
it("should validate a valid attribute condition with equals operator", () => {
const condition = {
identifier: "attributeId",
attributeId: "attr-123",
operator: "equals",
value: ["option-1", "option-2"],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
if (result.success) {
expect(result.data).toEqual(condition);
}
});
it("should validate a valid attribute condition with in operator", () => {
const condition = {
identifier: "attributeId",
attributeId: "attr-456",
operator: "in",
value: ["opt-a", "opt-b", "opt-c"],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(true);
});
it("should reject attribute condition without attributeId", () => {
const condition = {
identifier: "attributeId",
operator: "equals",
value: ["option-1"],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
it("should reject attribute condition with number values", () => {
const condition = {
identifier: "attributeId",
attributeId: "attr-123",
operator: "equals",
value: [1, 2, 3],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
});
describe("invalid conditions", () => {
it("should reject condition with invalid identifier", () => {
const condition = {
identifier: "invalidId",
operator: "equals",
value: [1],
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
it("should reject condition without value", () => {
const condition = {
identifier: "teamId",
operator: "equals",
};
const result = attributeSyncRuleConditionSchema.safeParse(condition);
expect(result.success).toBe(false);
});
});
});
describe("attributeSyncRuleSchema", () => {
it("should validate a rule with AND operator and team conditions", () => {
const rule = {
operator: "AND",
conditions: [
{
identifier: "teamId",
operator: "equals",
value: [1, 2],
},
],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(true);
if (result.success) {
expect(result.data).toEqual(rule);
}
});
it("should validate a rule with OR operator and attribute conditions", () => {
const rule = {
operator: "OR",
conditions: [
{
identifier: "attributeId",
attributeId: "attr-1",
operator: "in",
value: ["opt-1"],
},
{
identifier: "attributeId",
attributeId: "attr-2",
operator: "notIn",
value: ["opt-2"],
},
],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(true);
});
it("should validate a rule with mixed conditions", () => {
const rule = {
operator: "AND",
conditions: [
{
identifier: "teamId",
operator: "equals",
value: [1],
},
{
identifier: "attributeId",
attributeId: "attr-1",
operator: "in",
value: ["opt-1"],
},
],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(true);
});
it("should validate a rule with empty conditions array", () => {
const rule = {
operator: "AND",
conditions: [],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(true);
});
it("should reject a rule with invalid operator", () => {
const rule = {
operator: "XOR",
conditions: [],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(false);
});
it("should reject a rule without operator", () => {
const rule = {
conditions: [],
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(false);
});
it("should reject a rule without conditions", () => {
const rule = {
operator: "AND",
};
const result = attributeSyncRuleSchema.safeParse(rule);
expect(result.success).toBe(false);
});
});
describe("syncFormDataSchema", () => {
const validFormData = {
id: "sync-123",
name: "Test Sync",
credentialId: 1,
enabled: true,
organizationId: 123,
ruleId: "rule-123",
rule: {
operator: "AND",
conditions: [
{
identifier: "teamId",
operator: "equals",
value: [1],
},
],
},
syncFieldMappings: [
{
id: "mapping-1",
integrationFieldName: "field1",
attributeId: "attr-1",
enabled: true,
},
],
};
it("should validate valid form data with existing mappings", () => {
const result = syncFormDataSchema.safeParse(validFormData);
expect(result.success).toBe(true);
if (result.success) {
expect(result.data.id).toBe("sync-123");
expect(result.data.name).toBe("Test Sync");
}
});
it("should validate form data with new mappings (without id)", () => {
const formData = {
...validFormData,
syncFieldMappings: [
{
integrationFieldName: "newField",
attributeId: "attr-new",
enabled: false,
},
],
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(true);
});
it("should validate form data with mixed new and existing mappings", () => {
const formData = {
...validFormData,
syncFieldMappings: [
{
id: "existing-mapping",
integrationFieldName: "existingField",
attributeId: "attr-1",
enabled: true,
},
{
integrationFieldName: "newField",
attributeId: "attr-2",
enabled: false,
},
],
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(true);
});
it("should validate form data with empty mappings array", () => {
const formData = {
...validFormData,
syncFieldMappings: [],
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(true);
});
it("should reject form data with empty name", () => {
const formData = {
...validFormData,
name: "",
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(false);
});
it("should reject form data without required fields", () => {
const formData = {
name: "Test",
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(false);
});
it("should reject form data with invalid rule", () => {
const formData = {
...validFormData,
rule: {
operator: "INVALID",
conditions: [],
},
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(false);
});
it("should reject form data with invalid mapping", () => {
const formData = {
...validFormData,
syncFieldMappings: [
{
integrationFieldName: "field",
// missing attributeId and enabled
},
],
};
const result = syncFormDataSchema.safeParse(formData);
expect(result.success).toBe(false);
});
});