Skip to content
Open
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
31 changes: 20 additions & 11 deletions e2e/tests/media-library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,24 +146,33 @@ async function createFolder(page: Page, name: string) {
await expect(dialog).not.toBeVisible();
}

async function boxCenter(locator: Locator) {
const box = await locator.boundingBox();
if (!box) throw new Error("Drag source or target is not visible");
return { x: box.x + box.width / 2, y: box.y + box.height / 2 };
}

async function pointerDrag(page: Page, source: Locator, target: Locator) {
const sourceBox = await source.boundingBox();
const targetBox = await target.boundingBox();
if (!sourceBox || !targetBox) throw new Error("Drag source or target is not visible");
const sourcePoint = {
x: sourceBox.x + sourceBox.width / 2,
y: sourceBox.y + sourceBox.height / 2,
};
const targetPoint = {
x: targetBox.x + targetBox.width / 2,
y: targetBox.y + targetBox.height / 2,
};
// Starting a drag near the viewport edge triggers the drag library's
// auto-scroll, which moves the target away from coordinates measured earlier.
await source.evaluate((element) => element.scrollIntoView({ block: "center" }));
const sourcePoint = await boxCenter(source);
let targetPoint = await boxCenter(target);
await page.mouse.move(sourcePoint.x, sourcePoint.y);
await page.mouse.down();
await page.mouse.move(sourcePoint.x + 12, sourcePoint.y, { steps: 2 });
await page.mouse.move(targetPoint.x, targetPoint.y, { steps: 8 });
const overlayCard = page.locator("[data-media-drag-overlay] > *");
await overlayCard.waitFor();
await expect
.poll(async () => {
const current = await boxCenter(target);
const moved = Math.hypot(current.x - targetPoint.x, current.y - targetPoint.y) > 1;
targetPoint = current;
if (moved) await page.mouse.move(current.x, current.y, { steps: 2 });
return moved;
})
.toBe(false);
const overlayBox = await overlayCard.boundingBox();
if (!overlayBox) throw new Error("Drag overlay is not visible");
expect(Math.abs(overlayBox.x + overlayBox.width / 2 - targetPoint.x)).toBeLessThanOrEqual(4);
Expand Down
8 changes: 4 additions & 4 deletions e2e/tests/sandbox-plugin-admin-surfaces.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,18 @@ test.describe("Sandboxed plugin admin surfaces", () => {

const response = await page.request.post("/_emdash/api/plugins/marketplace-test/events-list", {
headers: { "X-EmDash-Request": "1" },
data: {},
data: { ids: [contentId, `action:publish:${contentId}`] },
});
const body = (await response.json()) as {
data: { events: { items: Array<{ id: string; data: Record<string, unknown> }> } };
};
expect(body.data.events.items).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: contentId, data: { type: "saved", collection: "posts" } }),
expect.objectContaining({
{ id: contentId, data: { type: "saved", collection: "posts" } },
{
id: `action:publish:${contentId}`,
data: { type: "content-action", action: "publish", contentId },
}),
},
]),
);
});
Expand Down
4 changes: 3 additions & 1 deletion e2e/tests/sandbox-plugin-boundaries.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ test.describe("Sandboxed plugin production boundaries", () => {
posts: { slug: "posts" },
});
await expect(invoke("users-exercise")).resolves.toMatchObject({
page: { items: [expect.objectContaining({ email: "dev@emdash.local" })] },
page: {
items: expect.arrayContaining([expect.objectContaining({ email: "dev@emdash.local" })]),
},
});
await expect(invoke("cron-exercise")).resolves.toMatchObject({
scheduled: [expect.objectContaining({ name: "diagnostic" })],
Expand Down
20 changes: 16 additions & 4 deletions packages/plugins/marketplace-test/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,10 +1207,22 @@ const plugin: SandboxedPlugin = {
},
},
"events-list": {
handler: async (_route, ctx) => ({
events: await ctx.storage.events.query({ limit: 100 }),
lifecycle: await ctx.storage.lifecycle.query({ limit: 100 }),
}),
handler: async (route, ctx) => {
const ids =
typeof route.input === "object" && route.input !== null && "ids" in route.input
? route.input.ids
: undefined;
if (Array.isArray(ids) && ids.every((id) => typeof id === "string")) {
const found = await ctx.storage.events.getMany(ids);
return {
events: { items: Array.from(found, ([id, data]) => ({ id, data })) },
};
}
return {
events: await ctx.storage.events.query({ limit: 100 }),
lifecycle: await ctx.storage.lifecycle.query({ limit: 100 }),
};
},
},
"private-user": {
permission: "content:edit_any",
Expand Down
Loading