mirror of
https://github.com/misenhower/splatoon2.ink.git
synced 2026-09-28 20:27:00 -05:00
95 lines
3.5 KiB
JavaScript
95 lines
3.5 KiB
JavaScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { env } from 'cloudflare:test';
|
|
import { runPosters } from './src/posters.mjs';
|
|
import { fakeSplatNet, ROUTES } from './fakeSplatNet.mjs';
|
|
import { getTopOfCurrentHour } from '../../src/common/time.js';
|
|
|
|
// The posters (src/app/social) running inside workerd: data from R2, screenshots from a
|
|
// stubbed Browser binding, no social credentials (shadow mode).
|
|
const PNG = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
|
|
describe('runPosters', () => {
|
|
let renders;
|
|
|
|
beforeEach(async () => {
|
|
process.env.SITE_URL = 'https://example.test';
|
|
|
|
for (let name of ['BLUESKY_SERVICE', 'BLUESKY_IDENTIFIER', 'BLUESKY_PASSWORD'])
|
|
delete process.env[name];
|
|
|
|
let now = getTopOfCurrentHour();
|
|
let rotation = { ...ROUTES['/api/schedules']().regular[0], start_time: now, end_time: now + 7200 };
|
|
|
|
await env.ASSETS.put(
|
|
'data/schedules.json',
|
|
JSON.stringify({ regular: [rotation], gachi: [rotation], league: [rotation] }),
|
|
);
|
|
await env.ASSETS.put(
|
|
'data/festivals.json',
|
|
JSON.stringify({
|
|
na: { festivals: [], results: [] },
|
|
eu: { festivals: [], results: [] },
|
|
jp: { festivals: [], results: [] },
|
|
}),
|
|
);
|
|
await env.ASSETS.put('data/coop-schedules.json', JSON.stringify({ schedules: [], details: [] }));
|
|
await env.ASSETS.put('data/timeline.json', JSON.stringify({ coop: null, weapon_availability: null }));
|
|
await env.ASSETS.put(
|
|
'data/merchandises.json',
|
|
JSON.stringify({
|
|
merchandises: [{ end_time: now + 3600, gear: { name: 'Hat' }, skill: { name: 'Skill' } }],
|
|
}),
|
|
);
|
|
|
|
await env.ASSETS.put('data/locale/en.json', JSON.stringify({}));
|
|
renders = [];
|
|
|
|
let splatnet = fakeSplatNet();
|
|
|
|
vi.spyOn(env.BROWSER, 'quickAction').mockImplementation(async (action, options) => {
|
|
renders.push(options);
|
|
|
|
return new Response(PNG, { headers: { 'content-type': 'image/png' } });
|
|
});
|
|
|
|
vi.stubGlobal('fetch', async (input, init) => {
|
|
let url = new URL(input);
|
|
|
|
if (url.hostname === 'example.test') {
|
|
let object = await env.ASSETS.get(url.pathname.slice(1));
|
|
|
|
return object ? new Response(object.body) : new Response('missing', { status: 404 });
|
|
}
|
|
|
|
return splatnet(input, init);
|
|
});
|
|
});
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('renders the public images for the hour without posting anywhere', async () => {
|
|
let summary = await runPosters(env);
|
|
|
|
expect(summary.ok).toBe(true);
|
|
expect(summary.clients).toEqual([]);
|
|
expect(renders.map(r => r.url)).toEqual([
|
|
`https://example.test/screenshots.html#/schedules/${getTopOfCurrentHour()}`,
|
|
`https://example.test/screenshots.html#/splatNetGear/${getTopOfCurrentHour()}`,
|
|
]);
|
|
expect(renders.every(r => r.screenshotOptions.type === 'png')).toBe(true);
|
|
expect(await env.ASSETS.get('twitter-images/schedule.png')).not.toBeNull();
|
|
expect(await env.ASSETS.get('twitter-images/gear.png')).not.toBeNull();
|
|
expect((await env.ASSETS.head('twitter-images/schedule.png')).httpMetadata.contentType).toBe('image/png');
|
|
expect(await env.PRIVATE.get('bluesky-lastPostTimes.json')).toBeNull(); // nothing was posted
|
|
});
|
|
|
|
it('rejects a rendering site serving different data before making screenshots', async () => {
|
|
vi.stubGlobal('fetch', async () => Response.json({ stale: true }));
|
|
|
|
await expect(runPosters(env)).rejects.toThrow('Rendering site data does not match');
|
|
expect(renders).toEqual([]);
|
|
});
|
|
});
|