刘光辉
4 小时以前 cf11e63b659afcc9792ab3e395f1b45d844431a8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { describe, expect, it, vi } from 'vitest';
 
import { createUploadEditCoordinator } from './uploadEditCoordinator';
 
const context = (field: string, recordId = 'record') => ({ modelId: 'model', recordId, field, taskId: 'task' });
const value = (field: string) => ({ draftId: field, revision: 1, files: [] });
 
describe('dMS form attachment coordinator', () => {
  it('batches positions while preserving each result and makes a fresh request for submission', async () => {
    const load = vi.fn(async (contexts) => ({ data: contexts.map((item: any) => value(item.field)) }));
    const coordinator = createUploadEditCoordinator(load);
    const result = await Promise.all([coordinator.loadShared(context('main')), coordinator.loadShared(context('child'))]);
    expect(load).toHaveBeenCalledTimes(1);
    expect(result.map((item) => item.data.draftId)).toEqual(['main', 'child']);
    await coordinator.loadShared(context('main'));
    expect(load).toHaveBeenCalledTimes(2);
  });
  it('does not combine different records, swallow denial, or return partial batch results', async () => {
    const load = vi.fn(async () => ({ data: [value('file')] }));
    const coordinator = createUploadEditCoordinator(load);
    await Promise.all([coordinator.loadShared(context('main')), coordinator.loadShared(context('main', 'other'))]);
    expect(load).toHaveBeenCalledTimes(2);
    const partial = await Promise.allSettled([coordinator.loadShared(context('main')), coordinator.loadShared(context('child'))]);
    expect(partial.every((item) => item.status === 'rejected')).toBe(true);
    load.mockRejectedValueOnce(new Error('denied'));
    await expect(coordinator.loadShared(context('main'))).rejects.toThrow('denied');
  });
  it('waits for editor finalization before preparing the confirmed manifest', async () => {
    const coordinator = createUploadEditCoordinator(vi.fn());
    let finish!: () => void;
    const closing = new Promise<void>((resolve) => {
      finish = resolve;
    });
    const prepare = vi.fn(async () => undefined);
    const work = coordinator.prepare([{ settle: () => closing, prepare }]);
    await Promise.resolve();
    expect(prepare).not.toHaveBeenCalled();
    finish();
    await work;
    expect(prepare).toHaveBeenCalledOnce();
  });
  it('rejects pending and new reads after disposal', async () => {
    const coordinator = createUploadEditCoordinator(vi.fn());
    const pending = coordinator.loadShared(context('main'));
    coordinator.dispose();
    await expect(pending).rejects.toThrow('表单已关闭');
    await expect(coordinator.loadShared(context('main'))).rejects.toThrow('表单已关闭');
  });
});