plugin.client.spec.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * The settings domain base plugin's own mounting behavior: it stands up
  3. * `ctx.settingsScope` over one shared describe mirror, keeps that mirror
  4. * fresh on settings-document and connection-reset invalidations, and retires
  5. * both the service and the subscriptions with its fiber.
  6. */
  7. import { Context } from '@deepseek-ai/cordis'
  8. import { describe, expect, it, vi } from 'vitest'
  9. import { TestRemote } from '@deepseek-ai/dsh-client-test-runtime'
  10. import { apply, inject } from '../src/client/index.ts'
  11. import { SettingsSchemaService } from '../src/client/schema.ts'
  12. import { SettingsScopeBinder } from '../src/client/settings-scope.ts'
  13. /** Boot the browser half over a fake loopback connection and test remote. */
  14. function bench() {
  15. const describeCall = vi.fn().mockResolvedValue({
  16. rpcId: 'plugin-bench' as never,
  17. result: { ok: true, value: { writable: true, hasDocument: true, namespaces: [] } },
  18. })
  19. const ctx = new Context()
  20. ctx.provide('connection', {
  21. api: { settings: { describe: describeCall } },
  22. isLoopback: true,
  23. } as never)
  24. new TestRemote(ctx)
  25. return { ctx, describeCall, fiber: ctx.plugin({ inject: [...inject], apply }) }
  26. }
  27. describe('settings domain base plugin', () => {
  28. it('mounts the scope service under settingsScope and reads once eagerly', async () => {
  29. const { ctx, describeCall, fiber } = bench()
  30. await fiber.await()
  31. expect(ctx.get('settingsScope')).toBeInstanceOf(SettingsScopeBinder)
  32. expect(ctx.get('settingsSchema')).toBeInstanceOf(SettingsSchemaService)
  33. await vi.waitFor(() => { expect(describeCall).toHaveBeenCalledTimes(1) })
  34. })
  35. it('refreshes the mirror on document commits and connection resets, once each', async () => {
  36. const { ctx, describeCall, fiber } = bench()
  37. await fiber.await()
  38. await vi.waitFor(() => { expect(describeCall).toHaveBeenCalledTimes(1) })
  39. ctx.remote.$dispatch('settings/document-updated', ['ui-test', 0])
  40. await vi.waitFor(() => { expect(describeCall).toHaveBeenCalledTimes(2) })
  41. ctx.emit('connection/reset')
  42. await vi.waitFor(() => { expect(describeCall).toHaveBeenCalledTimes(3) })
  43. })
  44. it('fiber disposal retires the service and its invalidation subscriptions', async () => {
  45. const { ctx, describeCall, fiber } = bench()
  46. await fiber.await()
  47. await vi.waitFor(() => { expect(describeCall).toHaveBeenCalledTimes(1) })
  48. await fiber.dispose()
  49. expect(ctx.get('settingsScope')).toBeUndefined()
  50. expect(ctx.get('settingsSchema')).toBeUndefined()
  51. ctx.remote.$dispatch('settings/document-updated', ['ui-test', 0])
  52. ctx.emit('connection/reset')
  53. await Promise.resolve()
  54. expect(describeCall).toHaveBeenCalledTimes(1)
  55. })
  56. })