Files
calendar/apps/web/playwright/lib/test-helpers/organizationHelpers.ts
T
Hariom BalharaandGitHub f667417d84 test: Add e2e for prerendering headless router with attribute routing (#22080)
* test: Add e2e for prerender

* wip

* fix tests

* conflict resolution

* Fix unit tests and e2e failure

* chore: Reorganize
2025-07-14 22:47:12 -03:00

178 lines
4.8 KiB
TypeScript

import { prisma } from "@calcom/prisma";
/**
* Example usage:
*
* // Basic usage with default assignments
* await createAttributes({
* orgId: 1,
* attributes: [
* {
* name: "Department",
* type: "SINGLE_SELECT",
* options: ["Engineering", "Sales", "Marketing"]
* }
* ],
* assignments: [
* {
* memberIndex: 0,
* attributeValues: {
* "Department": ["Engineering"]
* }
* }
* ]
* });
*
* // Create attributes without assignments
* await createAttributes({
* orgId: 1,
* attributes: [
* { name: "Bio", type: "TEXT" },
* { name: "Years of Experience", type: "NUMBER" }
* ]
* });
*/
interface AttributeConfig {
name: string;
type: "SINGLE_SELECT" | "MULTI_SELECT" | "TEXT" | "NUMBER";
options?: string[];
}
interface MemberAssignment {
memberIndex: number;
attributeValues: Record<string, string[]>; // attribute name -> selected values
}
interface SeedAttributesConfig {
orgId: number;
attributes: AttributeConfig[];
assignments?: MemberAssignment[];
}
/**
* Seeds attributes for an organization with configurable types, values, and assignments
* @param config - Configuration object containing orgId, attributes, and optional assignments
* @returns Array of created attributes with their options
*/
export async function createAttributes(config: SeedAttributesConfig) {
const { orgId, attributes: attributeConfigs, assignments = [] } = config;
console.log(`🎯 Seeding attributes for org ${orgId}`);
// Check if attributes already exist
const existingAttributes = await prisma.attribute.findMany({
where: {
teamId: orgId,
name: {
in: attributeConfigs.map((attr) => attr.name),
},
},
});
if (existingAttributes.length > 0) {
console.log(`Skipping attributes seed, attributes already exist`);
return;
}
const memberships = await prisma.membership.findMany({
where: {
teamId: orgId,
},
select: {
id: true,
userId: true,
},
});
console.log(`🎯 Creating attributes for org ${orgId}`);
const attributes: { id: string; name: string; options: { id: string; value: string }[] }[] = [];
for (const attr of attributeConfigs) {
const attribute = await prisma.attribute.create({
data: {
name: attr.name,
slug: `org:${orgId}-${attr.name.toLowerCase().replace(/ /g, "-")}`,
type: attr.type as "TEXT" | "NUMBER" | "SINGLE_SELECT" | "MULTI_SELECT",
teamId: orgId,
enabled: true,
options: attr.options
? {
create: attr.options.map((opt) => ({
value: opt,
slug: opt.toLowerCase().replace(/ /g, "-"),
})),
}
: undefined,
},
include: {
options: true,
},
});
attributes.push({
id: attribute.id,
name: attribute.name,
options: attribute.options.map((opt) => ({
id: opt.id,
value: opt.value,
})),
});
console.log(`\t📝 Created attribute: ${attr.name}`);
// Process assignments for this attribute
for (const assignment of assignments) {
const { memberIndex, attributeValues } = assignment;
// Check if this assignment has values for the current attribute
const valuesForAttribute = attributeValues[attr.name];
if (!valuesForAttribute || valuesForAttribute.length === 0) {
console.log(
`\t\t⏭️ Skipped ${attr.name} assignment for member ${memberIndex + 1} - no values specified`
);
continue;
}
// Get the member at the specified index
const member = memberships[memberIndex];
if (!member) {
console.log(`\t\t⚠️ Skipped ${attr.name} assignment - member at index ${memberIndex} not found`);
continue;
}
// Find the options for the specified values
const selectedOptions = attribute.options.filter((opt) => valuesForAttribute.includes(opt.value));
if (selectedOptions.length === 0) {
console.log(
`\t\t⚠️ Skipped ${attr.name} assignment for user ${
member.userId
} - no matching options found for values: ${valuesForAttribute.join(", ")}`
);
continue;
}
// Create assignments for each selected option
for (const option of selectedOptions) {
await prisma.attributeToUser.create({
data: {
memberId: member.id,
attributeOptionId: option.id,
},
});
}
const assignedValues = selectedOptions.map((opt) => opt.value);
console.log(
`\t\t✅ Assigned ${attr.name} [${assignedValues.map((v) => `"${v}"`).join(", ")}] to user ${
member.userId
} (member ${memberIndex + 1})`
);
}
}
return attributes;
}