| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- import { mkdtempSync, rmSync } from 'node:fs'
- import { tmpdir } from 'node:os'
- import { join } from 'node:path'
- import { afterEach, describe, expect, it } from 'vitest'
- import { PushCoordinator } from '../../src/server/pushCoordinator.js'
- import { PushCoordinatorEventAdapter } from '../../src/server/pushEventAdapter.js'
- import type { APNsRequest } from '../../src/server/apns.js'
- const roots: string[] = []
- afterEach(() => {
- for (const home of roots.splice(0)) rmSync(home, { recursive: true, force: true })
- })
- function fixture() {
- const home = mkdtempSync(join(tmpdir(), 'yaoyao-web-push-'))
- roots.push(home)
- const requests: APNsRequest[] = []
- const push = new PushCoordinator({
- home,
- autoFlush: false,
- apns: {
- keyFile: join(home, 'unused.p8'),
- keyId: 'KEY123',
- teamId: 'TEAM123',
- topic: 'cn.samien.yaoyao.hermes',
- },
- provider: {
- send: async (request) => {
- requests.push(request)
- return { disposition: 'success', status: 200 }
- },
- },
- })
- push.registerInstallation({
- userId: 'owner',
- installationId: 'phone',
- clientAccountId: 'account',
- deviceToken: 'ab'.repeat(32),
- environment: 'development',
- })
- return { push, requests, adapter: new PushCoordinatorEventAdapter(push) }
- }
- describe('Web-owned push delivery', () => {
- it('deduplicates workspace completion notifications and retains application navigation', async () => {
- const { push, requests, adapter } = fixture()
- push.setGroupSubscription('owner', 'room', true, 0)
- const candidate = {
- kind: 'group.message.completed' as const,
- eventID: 'workspace:run',
- localUserID: 'owner',
- roomID: 'room',
- title: '团队',
- body: '已完成',
- collapseID: 'workspace:room',
- data: { workspace: '1', conversationId: 'room' },
- }
- expect(adapter.enqueueNotification(candidate)).toBe('enqueued')
- expect(adapter.enqueueNotification(candidate)).toBe('duplicate')
- await push.flushDue()
- expect(requests).toHaveLength(1)
- expect(requests[0]!.payload).toMatchObject({ workspace: '1', conversationId: 'room' })
- push.close()
- })
- it('does not deliver group events to an unsubscribed account', () => {
- const { push, adapter } = fixture()
- expect(
- adapter.enqueueNotification({
- kind: 'group.message.completed',
- eventID: 'workspace:run',
- localUserID: 'owner',
- roomID: 'other-room',
- title: '团队',
- body: '结果',
- collapseID: 'workspace:other',
- data: { conversationId: 'other-room' },
- }),
- ).toBe('ignored')
- expect(push.status().pendingCount).toBe(0)
- push.close()
- })
- })
|