Prepare production and Coolify deployment with original exports and datetime pickers
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
import {test,expect} from "bun:test";
|
||||
import {unzipSync} from "fflate";
|
||||
import {and,eq} from "drizzle-orm";
|
||||
import {events,getDb,photos,photoExports,user,guests,submissions} from "@album/database";
|
||||
import {getObjectBuffer,deleteObject,putObject,headObject} from "@album/storage";
|
||||
import {processPhotoExport} from "./exports";
|
||||
|
||||
test.skipIf(process.env.EXPORT_INTEGRATION!=="1")("original ZIP bytes, approved filtering, duplicate requests and expiry",async()=>{
|
||||
if (!["localhost","127.0.0.1"].includes(new URL(process.env.DATABASE_URL!).hostname) || !["localhost","127.0.0.1"].includes(new URL(process.env.S3_ENDPOINT!).hostname)) throw new Error("Local storage/database required");
|
||||
const db=getDb();
|
||||
const [demo]=await db.select().from(events).where(eq(events.slug,"demo"));
|
||||
const [owner]=await db.select({id:user.id}).from(user).limit(1);
|
||||
const [event]=await db.insert(events).values({groupId:demo!.groupId,title:"Export test",slug:`export-${crypto.randomUUID()}`}).returning();
|
||||
const [guest]=await db.insert(guests).values({eventId:event!.id,tokenHash:crypto.randomUUID()}).returning();
|
||||
const [submission]=await db.insert(submissions).values({eventId:event!.id,guestId:guest!.id}).returning();
|
||||
const bytes=Buffer.from("original bytes preserved exactly");
|
||||
const sourceKey=`events/${event!.id}/export-test/original`;
|
||||
const jobIds:string[]=[];
|
||||
try {
|
||||
await putObject({key:sourceKey,body:bytes,contentType:"image/jpeg"});
|
||||
const [photo]=await db.insert(photos).values({eventId:event!.id,submissionId:submission!.id,originalKey:sourceKey,contentType:"image/jpeg",byteSize:bytes.length,processingStatus:"ready",visibility:"public"}).returning();
|
||||
await db.insert(photos).values({eventId:event!.id,submissionId:submission!.id,originalKey:sourceKey,contentType:"image/jpeg",byteSize:bytes.length,processingStatus:"ready",visibility:"private"});
|
||||
for(const filter of ["approved","all"]) {
|
||||
const [job]=await db.insert(photoExports).values({eventId:event!.id,requestedBy:owner!.id,filter,expiresAt:new Date(Date.now()+86400000)}).returning();
|
||||
jobIds.push(job!.id);
|
||||
expect(await db.insert(photoExports).values({eventId:event!.id,requestedBy:owner!.id,filter,expiresAt:new Date(Date.now()+86400000)}).onConflictDoNothing().returning()).toHaveLength(0);
|
||||
await processPhotoExport();
|
||||
const [finished]=await db.select().from(photoExports).where(and(eq(photoExports.id,job!.id),eq(photoExports.eventId,event!.id)));
|
||||
expect(finished?.status).toBe("ready");
|
||||
const zip=unzipSync(await getObjectBuffer(`exports/${event!.id}/${job!.id}.zip`));
|
||||
expect(Object.keys(zip)).toHaveLength(filter==="approved"?1:2);
|
||||
expect(Buffer.from(zip[`${photo!.id}.jpg`]!)).toEqual(bytes);
|
||||
await db.update(photoExports).set({expiresAt:new Date(0)}).where(and(eq(photoExports.id,job!.id),eq(photoExports.eventId,event!.id)));
|
||||
await processPhotoExport();
|
||||
expect(await headObject(`exports/${event!.id}/${job!.id}.zip`)).toBeNull();
|
||||
}
|
||||
} finally {
|
||||
for(const id of jobIds) await deleteObject(`exports/${event!.id}/${id}.zip`);
|
||||
await deleteObject(sourceKey);
|
||||
await db.delete(events).where(eq(events.id,event!.id));
|
||||
}
|
||||
},30000);
|
||||
Reference in New Issue
Block a user