mirror of
https://github.com/lukevella/rallly.git
synced 2025-06-03 11:11:48 +02:00
♻️ Update house keeping (#1591)
This commit is contained in:
parent
b173cc78a0
commit
c25ee09855
7 changed files with 394 additions and 109 deletions
273
apps/web/tests/house-keeping.spec.ts
Normal file
273
apps/web/tests/house-keeping.spec.ts
Normal file
|
@ -0,0 +1,273 @@
|
|||
import { expect, test } from "@playwright/test";
|
||||
import { prisma } from "@rallly/database";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
/**
|
||||
* This test suite tests the house-keeping API endpoints:
|
||||
* 1. delete-inactive-polls: Marks inactive polls as deleted
|
||||
* 2. remove-deleted-polls: Permanently removes polls that have been marked as deleted for more than 7 days
|
||||
*/
|
||||
test.describe("House-keeping API", () => {
|
||||
// Store created poll IDs for cleanup
|
||||
const createdPollIds: string[] = [];
|
||||
const createdUserIds: string[] = [];
|
||||
|
||||
// API Secret for authentication
|
||||
const API_SECRET = process.env.API_SECRET;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
// Clean up any existing test data
|
||||
await cleanup();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
// Clean up test data
|
||||
await cleanup();
|
||||
});
|
||||
|
||||
async function cleanup() {
|
||||
// Delete test users - related polls will be deleted automatically due to cascade
|
||||
if (createdUserIds.length > 0) {
|
||||
await prisma.user.deleteMany({
|
||||
where: {
|
||||
id: {
|
||||
in: createdUserIds,
|
||||
},
|
||||
},
|
||||
});
|
||||
createdUserIds.length = 0;
|
||||
}
|
||||
|
||||
// Delete polls that don't have a user (not covered by cascade delete)
|
||||
if (createdPollIds.length > 0) {
|
||||
await prisma.poll.deleteMany({
|
||||
where: {
|
||||
id: {
|
||||
in: createdPollIds,
|
||||
},
|
||||
userId: null,
|
||||
},
|
||||
});
|
||||
createdPollIds.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
test("should mark inactive polls as deleted for users without active subscriptions", async ({
|
||||
request,
|
||||
baseURL,
|
||||
}) => {
|
||||
// Create test users
|
||||
const regularUser = await prisma.user.create({
|
||||
data: {
|
||||
name: "Regular User",
|
||||
email: "regular-user@example.com",
|
||||
},
|
||||
});
|
||||
createdUserIds.push(regularUser.id);
|
||||
|
||||
const proUser = await prisma.user.create({
|
||||
data: {
|
||||
name: "Pro User",
|
||||
email: "pro-user@example.com",
|
||||
subscription: {
|
||||
create: {
|
||||
id: "sub_test_pro",
|
||||
priceId: "price_test",
|
||||
amount: 1000,
|
||||
status: "active",
|
||||
active: true,
|
||||
currency: "USD",
|
||||
interval: "month",
|
||||
periodStart: new Date(),
|
||||
periodEnd: dayjs().add(30, "day").toDate(),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
createdUserIds.push(proUser.id);
|
||||
|
||||
// Create test polls
|
||||
|
||||
// 1. Old poll from regular user (should be marked as deleted)
|
||||
const oldPollRegularUser = await prisma.poll.create({
|
||||
data: {
|
||||
id: "old-poll-regular-user",
|
||||
title: "Old Poll Regular User",
|
||||
participantUrlId: "old-poll-regular-user-participant",
|
||||
adminUrlId: "old-poll-regular-user-admin",
|
||||
userId: regularUser.id,
|
||||
touchedAt: dayjs().subtract(35, "day").toDate(), // 35 days old
|
||||
},
|
||||
});
|
||||
createdPollIds.push(oldPollRegularUser.id);
|
||||
|
||||
// 2. Old poll from pro user (should NOT be marked as deleted)
|
||||
const oldPollProUser = await prisma.poll.create({
|
||||
data: {
|
||||
id: "old-poll-pro-user",
|
||||
title: "Old Poll Pro User",
|
||||
participantUrlId: "old-poll-pro-user-participant",
|
||||
adminUrlId: "old-poll-pro-user-admin",
|
||||
userId: proUser.id,
|
||||
touchedAt: dayjs().subtract(35, "day").toDate(), // 35 days old
|
||||
},
|
||||
});
|
||||
createdPollIds.push(oldPollProUser.id);
|
||||
|
||||
// 3. Recent poll from regular user (should NOT be marked as deleted)
|
||||
const recentPollRegularUser = await prisma.poll.create({
|
||||
data: {
|
||||
id: "recent-poll-regular-user",
|
||||
title: "Recent Poll Regular User",
|
||||
participantUrlId: "recent-poll-regular-user-participant",
|
||||
adminUrlId: "recent-poll-regular-user-admin",
|
||||
userId: regularUser.id,
|
||||
touchedAt: dayjs().subtract(15, "day").toDate(), // 15 days old
|
||||
},
|
||||
});
|
||||
createdPollIds.push(recentPollRegularUser.id);
|
||||
|
||||
// 4. Old poll with future options from regular user (should NOT be marked as deleted)
|
||||
const oldPollWithFutureOptions = await prisma.poll.create({
|
||||
data: {
|
||||
id: "old-poll-with-future-options",
|
||||
title: "Old Poll With Future Options",
|
||||
participantUrlId: "old-poll-with-future-options-participant",
|
||||
adminUrlId: "old-poll-with-future-options-admin",
|
||||
userId: regularUser.id,
|
||||
touchedAt: dayjs().subtract(35, "day").toDate(), // 35 days old
|
||||
options: {
|
||||
create: {
|
||||
startTime: dayjs().add(10, "day").toDate(), // Future date
|
||||
duration: 60,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
createdPollIds.push(oldPollWithFutureOptions.id);
|
||||
|
||||
// 5. Old poll without a user (should be marked as deleted)
|
||||
const oldPollNoUser = await prisma.poll.create({
|
||||
data: {
|
||||
id: "old-poll-no-user",
|
||||
title: "Old Poll No User",
|
||||
participantUrlId: "old-poll-no-user-participant",
|
||||
adminUrlId: "old-poll-no-user-admin",
|
||||
touchedAt: dayjs().subtract(35, "day").toDate(), // 35 days old
|
||||
},
|
||||
});
|
||||
createdPollIds.push(oldPollNoUser.id);
|
||||
|
||||
// Call the delete-inactive-polls endpoint
|
||||
const response = await request.post(
|
||||
`${baseURL}/api/house-keeping/delete-inactive-polls`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${API_SECRET}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
expect(response.ok()).toBeTruthy();
|
||||
const responseData = await response.json();
|
||||
expect(responseData.success).toBeTruthy();
|
||||
|
||||
// We expect 2 polls to be marked as deleted:
|
||||
// - Old poll from regular user
|
||||
// - Old poll without a user
|
||||
expect(responseData.summary.markedDeleted).toBe(2);
|
||||
|
||||
// Verify the state of each poll
|
||||
const updatedOldPollRegularUser = await prisma.poll.findUnique({
|
||||
where: { id: oldPollRegularUser.id },
|
||||
});
|
||||
expect(updatedOldPollRegularUser?.deleted).toBe(true);
|
||||
expect(updatedOldPollRegularUser?.deletedAt).not.toBeNull();
|
||||
|
||||
const updatedOldPollProUser = await prisma.poll.findUnique({
|
||||
where: { id: oldPollProUser.id },
|
||||
});
|
||||
expect(updatedOldPollProUser?.deleted).toBe(false);
|
||||
expect(updatedOldPollProUser?.deletedAt).toBeNull();
|
||||
|
||||
const updatedRecentPollRegularUser = await prisma.poll.findUnique({
|
||||
where: { id: recentPollRegularUser.id },
|
||||
});
|
||||
expect(updatedRecentPollRegularUser?.deleted).toBe(false);
|
||||
expect(updatedRecentPollRegularUser?.deletedAt).toBeNull();
|
||||
|
||||
const updatedOldPollWithFutureOptions = await prisma.poll.findUnique({
|
||||
where: { id: oldPollWithFutureOptions.id },
|
||||
});
|
||||
expect(updatedOldPollWithFutureOptions?.deleted).toBe(false);
|
||||
expect(updatedOldPollWithFutureOptions?.deletedAt).toBeNull();
|
||||
|
||||
const updatedOldPollNoUser = await prisma.poll.findUnique({
|
||||
where: { id: oldPollNoUser.id },
|
||||
});
|
||||
expect(updatedOldPollNoUser?.deleted).toBe(true);
|
||||
expect(updatedOldPollNoUser?.deletedAt).not.toBeNull();
|
||||
});
|
||||
|
||||
test("should permanently remove polls that have been marked as deleted for more than 7 days", async ({
|
||||
request,
|
||||
baseURL,
|
||||
}) => {
|
||||
// Create a poll that was marked as deleted more than 7 days ago
|
||||
const oldDeletedPoll = await prisma.poll.create({
|
||||
data: {
|
||||
id: "old-deleted-poll",
|
||||
title: "Old Deleted Poll",
|
||||
participantUrlId: "old-deleted-poll-participant",
|
||||
adminUrlId: "old-deleted-poll-admin",
|
||||
deleted: true,
|
||||
deletedAt: dayjs().subtract(8, "day").toDate(), // Deleted 8 days ago
|
||||
},
|
||||
});
|
||||
createdPollIds.push(oldDeletedPoll.id);
|
||||
|
||||
// Create a poll that was marked as deleted less than 7 days ago
|
||||
const recentDeletedPoll = await prisma.poll.create({
|
||||
data: {
|
||||
id: "recent-deleted-poll",
|
||||
title: "Recent Deleted Poll",
|
||||
participantUrlId: "recent-deleted-poll-participant",
|
||||
adminUrlId: "recent-deleted-poll-admin",
|
||||
deleted: true,
|
||||
deletedAt: dayjs().subtract(3, "day").toDate(), // Deleted 3 days ago
|
||||
},
|
||||
});
|
||||
createdPollIds.push(recentDeletedPoll.id);
|
||||
|
||||
// Call the remove-deleted-polls endpoint
|
||||
const response = await request.post(
|
||||
`${baseURL}/api/house-keeping/remove-deleted-polls`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${API_SECRET}`,
|
||||
},
|
||||
data: {}, // Empty JSON body
|
||||
},
|
||||
);
|
||||
|
||||
expect(response.ok()).toBeTruthy();
|
||||
const responseData = await response.json();
|
||||
expect(responseData.success).toBeTruthy();
|
||||
|
||||
// We expect 1 poll to be permanently deleted
|
||||
expect(responseData.summary.deleted.polls).toBe(1);
|
||||
|
||||
// Verify that the old deleted poll is gone
|
||||
const checkOldDeletedPoll = await prisma.poll.findUnique({
|
||||
where: { id: oldDeletedPoll.id },
|
||||
});
|
||||
expect(checkOldDeletedPoll).toBeNull();
|
||||
|
||||
// Verify that the recent deleted poll still exists
|
||||
const checkRecentDeletedPoll = await prisma.poll.findUnique({
|
||||
where: { id: recentDeletedPoll.id },
|
||||
});
|
||||
expect(checkRecentDeletedPoll).not.toBeNull();
|
||||
expect(checkRecentDeletedPoll?.deleted).toBe(true);
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue