Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: faker applications and reviews #240

Merged
merged 10 commits into from
Jun 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions app/opportunities/[opportunity_id]/review/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,29 @@ export default async function StartReview({ params }: StartReviewProps) {
// Iterate over applications to find the first suitable one
for (const application of applications) {
// Find a suitable questionnaire within this application
suitableQuestionnaire = application.questionnaires.find(
(questionnaire) =>
questionnaire.reviewers.some(
(reviewer) => reviewer.id === session.user.id,
) && // User is a reviewer
questionnaire.reviews.filter(
(review) =>
review.userId === session.user.id &&
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
).length === 0 && // User has not reviewed questionnaire and application together
suitableQuestionnaire = application.questionnaires.find((questionnaire) => {
// User is a reviewer
const isReviewer = questionnaire.reviewers.some(
(reviewer) => reviewer.id === session.user.id,
);

// User has not reviewed questionnaire and application together
const hasNotReviewed = !questionnaire.reviews.some(
(review) =>
review.userId === session.user.id &&
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
);

const lessReviewsThanRequired =
questionnaire.reviews.filter(
(review) =>
review.questionnaireId === questionnaire.id &&
review.applicationId === application.id,
).length < questionnaire.requiredReviews, // Less reviews than required
);
).length < questionnaire.requiredReviews;

return isReviewer && hasNotReviewed && lessReviewsThanRequired;
});

if (suitableQuestionnaire) {
suitableApplication = application;
Expand Down
Binary file modified bun.lockb
Binary file not shown.
161 changes: 161 additions & 0 deletions lib/faker/applications.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { faker } from "@faker-js/faker";
import { Tally, TallyData, TallyField } from "@lib/types/tally";
import { keyUniqueEnforcer, now, options } from "./utils";
import db from "server/db";

enum FieldTypes {
CHECKBOXES = "CHECKBOXES",
MULTIPLE_CHOICE = "MULTIPLE_CHOICE",
DROPDOWN = "DROPDOWN",
}

enum NormalFieldTypes {
TEXTAREA = "TEXTAREA",
INPUT_TEXT = "INPUT_TEXT",
INPUT_NUMBER = "INPUT_NUMBER",
INPUT_DATE = "INPUT_DATE",
INPUT_EMAIL = "INPUT_EMAIL",
INPUT_LINK = "INPUT_LINK",
}

type Application = {
content: Tally;
opportunityId: number;
};

const minNumberOfApplications = parseInt(options.minapplications, 10);
const maxNumberOfApplications = parseInt(options.maxapplications, 10);

export async function generateApplications(opportunityIds: number[]) {
const applications: Application[] = opportunityIds.flatMap((id) =>
Array.from(
{
length: faker.number.int({
min: minNumberOfApplications,
max: maxNumberOfApplications,
}),
},
() => generateApplication(id),
),
);

for (const application of applications) {
await db.application.create({
data: {
content: application.content,
opportunity: { connect: { id: application.opportunityId } },
},
});
}

return applications;
}

function generateApplication(opportunityId: number): Application {
return {
content: generateTallyContent(),
opportunityId: opportunityId,
};
}

function generateTallyContent(): Tally {
return {
eventId: faker.string.uuid(),
eventType: "FORM_RESPONSE",
createdAt: now.toISOString(),
data: generateTallyData(),
};
}

function generateTallyData(): TallyData {
return {
responseId: faker.string.nanoid(6),
submissionId: faker.string.nanoid(6),
respondentId: faker.string.nanoid(6),
formId: faker.string.nanoid(6),
formName: faker.science.chemicalElement().name,
createdAt: now.toISOString(),
fields: Array.from({ length: faker.number.int({ min: 3, max: 6 }) }, () =>
generateTallyField(),
),
};
}

function generateTallyField(): TallyField {
const fieldTypes: (string | FieldTypes)[] = Object.values(FieldTypes);
const fieldType = faker.helpers.arrayElement(fieldTypes);

const baseField = {
label: faker.music.genre(),
key: keyUniqueEnforcer.enforce(() => faker.string.nanoid(6)),
};

return generateTallyFieldDetails(baseField, fieldType);
}

function generateTallyFieldDetails(
baseField: {
label: string;
key: string;
},
fieldType: string | FieldTypes,
): TallyField {
switch (fieldType) {
case FieldTypes.CHECKBOXES:
const checkbox_options = Array.from(
{ length: faker.number.int({ min: 1, max: 4 }) },
() => ({ id: faker.string.uuid(), text: faker.music.songName() }),
);
return {
...baseField,
type: FieldTypes.CHECKBOXES,
value: faker.helpers.arrayElements(
checkbox_options.map((o) => o.id),
{ min: 1, max: 4 },
),
options: checkbox_options,
};

case FieldTypes.DROPDOWN:
const dropdown_options = Array.from(
{ length: faker.number.int({ min: 1, max: 4 }) },
() => ({ id: faker.string.uuid(), text: faker.music.songName() }),
);
return {
...baseField,
type: FieldTypes.DROPDOWN,
value: faker.helpers.arrayElements(
dropdown_options.map((o) => o.id),
1,
),
options: dropdown_options,
};

case FieldTypes.MULTIPLE_CHOICE:
const multiple_options = Array.from(
{ length: faker.number.int({ min: 1, max: 4 }) },
() => ({ id: faker.string.uuid(), text: faker.music.songName() }),
);
return {
...baseField,
type: FieldTypes.MULTIPLE_CHOICE,
value: faker.helpers.arrayElements(
multiple_options.map((o) => o.id),
1,
),
options: multiple_options,
};

default:
if (
Object.values(NormalFieldTypes).includes(fieldType as NormalFieldTypes)
) {
return {
...baseField,
type: fieldType as NormalFieldTypes,
value: faker.lorem.sentence(),
};
}
throw new Error("Unknown field type");
}
}
Loading
Loading