teqo-backup/tests/unit/campaignPwa.unit.spec.ts

78 lines
3.2 KiB
TypeScript

// @vitest-environment node
import { describe, expect, it } from 'vitest'
import { GET as getManifest } from '@/app/(campaign)/campanha/manifest.webmanifest/route'
import {
GET as getServiceWorker,
dynamic as serviceWorkerDynamic,
} from '@/app/(campaign)/campanha/sw.js/route'
import {
buildCampaignServiceWorkerScript,
CAMPAIGN_CACHE_PREFIX,
CAMPAIGN_PWA_CLEAR_CACHES_MESSAGE,
CAMPAIGN_PWA_SCOPE,
CAMPAIGN_PWA_THEME_COLOR,
CAMPAIGN_WEB_MANIFEST,
resolveCampaignPwaBuildId,
} from '@/utilities/campaignPwa'
describe('campaign PWA helpers', () => {
it('builds a manifest scoped to /campanha without a trailing slash', () => {
expect(CAMPAIGN_WEB_MANIFEST.start_url).toBe(CAMPAIGN_PWA_SCOPE)
expect(CAMPAIGN_WEB_MANIFEST.scope).toBe(CAMPAIGN_PWA_SCOPE)
expect(CAMPAIGN_WEB_MANIFEST.start_url.endsWith('/')).toBe(false)
expect(CAMPAIGN_WEB_MANIFEST.scope.endsWith('/')).toBe(false)
expect(CAMPAIGN_WEB_MANIFEST.display).toBe('standalone')
expect(CAMPAIGN_WEB_MANIFEST.theme_color).toBe(CAMPAIGN_PWA_THEME_COLOR)
expect(CAMPAIGN_WEB_MANIFEST.icons.some((icon) => icon.purpose === 'maskable')).toBe(true)
})
it('resolves a stable build id from Vercel env with a local fallback', () => {
expect(resolveCampaignPwaBuildId({ VERCEL_GIT_COMMIT_SHA: 'abc123' })).toBe('abc123')
expect(resolveCampaignPwaBuildId({ VERCEL_DEPLOYMENT_ID: 'dpl_1' })).toBe('dpl_1')
expect(resolveCampaignPwaBuildId({})).toBe('dev')
})
it('embeds invite exclusion, RSC skip, cache prefix, and logout message in the SW script', () => {
const script = buildCampaignServiceWorkerScript('sha-test')
expect(script).toContain(`${CAMPAIGN_CACHE_PREFIX}sha-test`)
expect(script).toContain(`SCOPE + '/convite'`)
expect(script).toContain(CAMPAIGN_PWA_CLEAR_CACHES_MESSAGE)
expect(script).toContain(`${CAMPAIGN_PWA_SCOPE}/offline`)
expect(script).toContain('isRscRequest')
expect(script).toContain('skipWaiting')
expect(script).toContain('clients.claim')
})
})
describe('campaign PWA route handlers', () => {
it('serves the web manifest with the expected headers and body', async () => {
const response = getManifest()
const body = await response.json()
expect(response.status).toBe(200)
expect(response.headers.get('Content-Type')).toContain('application/manifest+json')
expect(response.headers.get('Cache-Control')).toBe('no-cache')
expect(body.scope).toBe('/campanha')
expect(body.start_url).toBe('/campanha')
})
it('serves the service worker with Service-Worker-Allowed scoped to /campanha', async () => {
const response = getServiceWorker()
const body = await response.text()
expect(response.status).toBe(200)
expect(response.headers.get('Content-Type')).toContain('text/javascript')
expect(response.headers.get('Cache-Control')).toBe('no-cache')
expect(response.headers.get('Service-Worker-Allowed')).toBe('/campanha')
expect(body).toContain('campanha-')
expect(body).toContain(`SCOPE + '/convite'`)
expect(body).toContain('isRscRequest')
})
it('serves the service worker dynamically so the deploy-scoped build id resolves at runtime', () => {
expect(serviceWorkerDynamic).toBe('force-dynamic')
})
})