MetaController.test.mjs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { expect, vi } from 'vitest'
  2. import sinon from 'sinon'
  3. import MockResponse from '../helpers/MockResponse.mjs'
  4. const modulePath = '../../../../app/src/Features/Metadata/MetaController.mjs'
  5. describe('MetaController', function () {
  6. beforeEach(async function (ctx) {
  7. ctx.EditorRealTimeController = {
  8. emitToRoom: sinon.stub(),
  9. }
  10. ctx.MetaHandler = {
  11. promises: {
  12. getAllMetaForProject: sinon.stub(),
  13. getMetaForDoc: sinon.stub(),
  14. },
  15. }
  16. vi.doMock(
  17. '../../../../app/src/Features/Editor/EditorRealTimeController',
  18. () => ({
  19. default: ctx.EditorRealTimeController,
  20. })
  21. )
  22. vi.doMock('../../../../app/src/Features/Metadata/MetaHandler', () => ({
  23. default: ctx.MetaHandler,
  24. }))
  25. vi.doMock(
  26. '../../../../app/src/Features/Analytics/AnalyticsManager',
  27. () => ({ default: {} })
  28. )
  29. ctx.MetadataController = (await import(modulePath)).default
  30. })
  31. describe('getMetadata', function () {
  32. it('should respond with json', async function (ctx) {
  33. const projectMeta = {
  34. 'doc-id': {
  35. labels: ['foo'],
  36. packages: { a: { commands: [] } },
  37. packageNames: ['a'],
  38. },
  39. }
  40. ctx.MetaHandler.promises.getAllMetaForProject = sinon
  41. .stub()
  42. .resolves(projectMeta)
  43. const req = { params: { project_id: 'project-id' } }
  44. const res = new MockResponse(vi)
  45. const next = sinon.stub()
  46. await ctx.MetadataController.getMetadata(req, res, next)
  47. ctx.MetaHandler.promises.getAllMetaForProject.should.have.been.calledWith(
  48. 'project-id'
  49. )
  50. expect(res.json).toHaveBeenCalledTimes(1)
  51. expect(res.json).toHaveBeenCalledWith({
  52. projectId: 'project-id',
  53. projectMeta,
  54. })
  55. next.should.not.have.been.called
  56. })
  57. it('should handle an error', async function (ctx) {
  58. ctx.MetaHandler.promises.getAllMetaForProject = sinon
  59. .stub()
  60. .throws(new Error('woops'))
  61. const req = { params: { project_id: 'project-id' } }
  62. const res = new MockResponse(vi)
  63. const next = sinon.stub()
  64. await ctx.MetadataController.getMetadata(req, res, next)
  65. ctx.MetaHandler.promises.getAllMetaForProject.should.have.been.calledWith(
  66. 'project-id'
  67. )
  68. expect(res.json).not.toHaveBeenCalled()
  69. next.should.have.been.calledWithMatch(error => error instanceof Error)
  70. })
  71. })
  72. describe('broadcastMetadataForDoc', function () {
  73. it('should broadcast on broadcast:true ', async function (ctx) {
  74. ctx.MetaHandler.promises.getMetaForDoc = sinon.stub().resolves({
  75. labels: ['foo'],
  76. packages: { a: { commands: [] } },
  77. packageNames: ['a'],
  78. })
  79. ctx.EditorRealTimeController.emitToRoom = sinon.stub()
  80. const req = {
  81. params: { project_id: 'project-id', doc_id: 'doc-id' },
  82. body: { broadcast: true },
  83. }
  84. const res = new MockResponse(vi)
  85. const next = sinon.stub()
  86. await ctx.MetadataController.broadcastMetadataForDoc(req, res, next)
  87. ctx.MetaHandler.promises.getMetaForDoc.should.have.been.calledWith(
  88. 'project-id'
  89. )
  90. expect(res.json).not.toHaveBeenCalled()
  91. expect(res.sendStatus).toHaveBeenCalledTimes(1)
  92. expect(res.sendStatus).toHaveBeenCalledWith(200)
  93. next.should.not.have.been.called
  94. ctx.EditorRealTimeController.emitToRoom.should.have.been.calledOnce
  95. const { lastCall } = ctx.EditorRealTimeController.emitToRoom
  96. expect(lastCall.args[0]).to.equal('project-id')
  97. expect(lastCall.args[1]).to.equal('broadcastDocMeta')
  98. expect(lastCall.args[2]).to.have.all.keys(['docId', 'meta'])
  99. })
  100. it('should return json on broadcast:false ', async function (ctx) {
  101. const docMeta = {
  102. labels: ['foo'],
  103. packages: { a: [] },
  104. packageNames: ['a'],
  105. }
  106. ctx.MetaHandler.promises.getMetaForDoc = sinon.stub().resolves(docMeta)
  107. ctx.EditorRealTimeController.emitToRoom = sinon.stub()
  108. const req = {
  109. params: { project_id: 'project-id', doc_id: 'doc-id' },
  110. body: { broadcast: false },
  111. }
  112. const res = new MockResponse(vi)
  113. const next = sinon.stub()
  114. await ctx.MetadataController.broadcastMetadataForDoc(req, res, next)
  115. ctx.MetaHandler.promises.getMetaForDoc.should.have.been.calledWith(
  116. 'project-id'
  117. )
  118. ctx.EditorRealTimeController.emitToRoom.should.not.have.been.called
  119. expect(res.json).toHaveBeenCalledTimes(1)
  120. expect(res.json).toHaveBeenCalledWith({
  121. docId: 'doc-id',
  122. meta: docMeta,
  123. })
  124. next.should.not.have.been.called
  125. })
  126. it('should handle an error', async function (ctx) {
  127. ctx.MetaHandler.promises.getMetaForDoc = sinon
  128. .stub()
  129. .throws(new Error('woops'))
  130. ctx.EditorRealTimeController.emitToRoom = sinon.stub()
  131. const req = {
  132. params: { project_id: 'project-id', doc_id: 'doc-id' },
  133. body: { broadcast: true },
  134. }
  135. const res = new MockResponse(vi)
  136. const next = sinon.stub()
  137. await ctx.MetadataController.broadcastMetadataForDoc(req, res, next)
  138. ctx.MetaHandler.promises.getMetaForDoc.should.have.been.calledWith(
  139. 'project-id'
  140. )
  141. expect(res.json).not.toHaveBeenCalled()
  142. next.should.have.been.calledWithMatch(error => error instanceof Error)
  143. })
  144. })
  145. })