inventory.spec.ts 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { afterEach, describe, expect, it } from 'vitest'
  2. import { Context, type Plugin } from '@deepseek-ai/cordis'
  3. import Loader from '@deepseek-ai/cordis-plugin-loader'
  4. import { remoteMethods } from '@deepseek-ai/dsh-typert-protocol'
  5. import PluginInventoryGateway from '../src/index.ts'
  6. const contexts: Context[] = []
  7. afterEach(async () => {
  8. await Promise.all(contexts.splice(0).map(ctx => ctx.fiber.dispose()))
  9. })
  10. const activePlugin: Plugin.Function = () => {}
  11. const pendingPlugin: Plugin.Object = {
  12. inject: ['neverReady'],
  13. apply() {},
  14. }
  15. async function harness(): Promise<{
  16. ctx: Context
  17. inventory: PluginInventoryGateway
  18. }> {
  19. const ctx = new Context()
  20. contexts.push(ctx)
  21. await ctx.plugin(Loader)
  22. ctx.loader.builtins.active = activePlugin
  23. ctx.loader.builtins.pending = pendingPlugin
  24. await ctx.plugin(PluginInventoryGateway)
  25. const inventory = ctx.get('pluginInventory') as PluginInventoryGateway
  26. return { ctx, inventory }
  27. }
  28. describe('PluginInventoryGateway', () => {
  29. it('publishes one direct list method under the pluginInventory namespace', async () => {
  30. const { inventory } = await harness()
  31. expect(inventory.typertRemote).toMatchObject({
  32. serviceKey: 'pluginInventory',
  33. namespace: 'pluginInventory',
  34. })
  35. expect(remoteMethods(inventory)).toEqual([
  36. { method: 'list', invocation: { kind: 'direct' } },
  37. ])
  38. })
  39. it('projects current non-group Loader entries without a second cache', async () => {
  40. const { ctx, inventory } = await harness()
  41. const activeId = await ctx.loader.create({ name: 'cordis:active' })
  42. const pendingId = await ctx.loader.create({ name: 'cordis:pending' })
  43. const disabledId = await ctx.loader.create({
  44. name: 'cordis:not-installed',
  45. disabled: true,
  46. })
  47. await ctx.loader.create({ name: 'cordis:active', group: true })
  48. const snapshot = inventory.list()
  49. expect(snapshot.entries).toHaveLength(3)
  50. expect(snapshot.entries).toEqual(expect.arrayContaining([
  51. {
  52. entryId: activeId,
  53. moduleName: 'cordis:active',
  54. enabled: true,
  55. fiberPhase: 'active',
  56. },
  57. {
  58. entryId: pendingId,
  59. moduleName: 'cordis:pending',
  60. enabled: true,
  61. fiberPhase: 'pending',
  62. },
  63. {
  64. entryId: disabledId,
  65. moduleName: 'cordis:not-installed',
  66. enabled: false,
  67. fiberPhase: null,
  68. },
  69. ]))
  70. await ctx.loader.update(activeId, { disabled: true })
  71. expect(inventory.list().entries.find(entry => entry.entryId === activeId)).toEqual({
  72. entryId: activeId,
  73. moduleName: 'cordis:active',
  74. enabled: false,
  75. fiberPhase: null,
  76. })
  77. await ctx.loader.remove(pendingId)
  78. expect(inventory.list().entries.some(entry => entry.entryId === pendingId)).toBe(false)
  79. })
  80. })