77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
import { APIRequestContext, request } from "@playwright/test"
|
|
import { ADMIN_TOKEN, API_BASE } from "../../fixtures/test-constants"
|
|
|
|
let adminContext: APIRequestContext | null = null
|
|
|
|
/**
|
|
* Get or create a singleton admin API context with the ADMIN_TOKEN.
|
|
*/
|
|
async function getAdminContext(baseURL: string): Promise<APIRequestContext> {
|
|
if (!adminContext) {
|
|
adminContext = await request.newContext({
|
|
baseURL,
|
|
ignoreHTTPSErrors: true,
|
|
extraHTTPHeaders: {
|
|
Token: ADMIN_TOKEN,
|
|
},
|
|
})
|
|
}
|
|
return adminContext
|
|
}
|
|
|
|
/**
|
|
* Delete a user by ID via admin API.
|
|
*/
|
|
export async function deleteUser(baseURL: string, userId: string): Promise<boolean> {
|
|
const ctx = await getAdminContext(baseURL)
|
|
const res = await ctx.delete(`${API_BASE}/user/${userId}`)
|
|
return res.ok()
|
|
}
|
|
|
|
/**
|
|
* Cleanup test users matching a pattern in their email.
|
|
*/
|
|
export async function cleanupTestUsers(baseURL: string, emailPattern: RegExp | string): Promise<number> {
|
|
const ctx = await getAdminContext(baseURL)
|
|
const res = await ctx.get(`${API_BASE}/user`)
|
|
if (!res.ok()) return 0
|
|
|
|
const users: { id?: string; _id?: string; email?: string }[] = await res.json()
|
|
if (!Array.isArray(users)) return 0
|
|
|
|
let deleted = 0
|
|
for (const user of users) {
|
|
const email = user.email || ""
|
|
const matches = typeof emailPattern === "string" ? email.includes(emailPattern) : emailPattern.test(email)
|
|
|
|
if (matches) {
|
|
const userId = user.id || user._id
|
|
if (userId) {
|
|
const ok = await deleteUser(baseURL, userId)
|
|
if (ok) deleted++
|
|
}
|
|
}
|
|
}
|
|
|
|
return deleted
|
|
}
|
|
|
|
/**
|
|
* Cleanup all test data (users and tokens matching @test.example.com).
|
|
*/
|
|
export async function cleanupAllTestData(baseURL: string): Promise<{ users: number }> {
|
|
const testPattern = "@test.example.com"
|
|
const users = await cleanupTestUsers(baseURL, testPattern)
|
|
return { users }
|
|
}
|
|
|
|
/**
|
|
* Dispose the admin API context. Call in globalTeardown.
|
|
*/
|
|
export async function disposeAdminApi(): Promise<void> {
|
|
if (adminContext) {
|
|
await adminContext.dispose()
|
|
adminContext = null
|
|
}
|
|
}
|