sseSource.test.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import { describe, test, it, expect } from 'vitest'
  2. import SseSource from "~/services/sse/sseSource";
  3. import {EventSourcePolyfill} from "event-source-polyfill";
  4. class TestableSseSource extends SseSource {
  5. public getUrl() { return this.url }
  6. public getOnOpen() { return this.onOpen }
  7. public getOnMessage() { return this.onMessage }
  8. public getOnClose() { return this.onClose }
  9. public getWithCredentials() { return this.withCredentials }
  10. public createEventSource(url: string, withCredentials: boolean): EventSourcePolyfill {
  11. return super.createEventSource(url, withCredentials)
  12. }
  13. public setEventSource(eventSource: EventSourcePolyfill) {
  14. this.eventSource = eventSource
  15. }
  16. }
  17. let mercureUrl: string
  18. let topic: string
  19. let onOpen: () => any
  20. let onMessage: (data: Array<any>) => any
  21. let onClose: () => any
  22. let sseSource: TestableSseSource
  23. const init_console_log = console.log
  24. beforeEach(() => {
  25. mercureUrl = 'https://my.mercure.com'
  26. topic = 'mytopic'
  27. onOpen = () => 'opened'
  28. onMessage = (data: Array<any>) => 'message'
  29. onClose = () => 'closed'
  30. sseSource = new TestableSseSource(mercureUrl, topic, onOpen, onMessage, onClose, false)
  31. })
  32. afterEach(() => {
  33. console.log = init_console_log
  34. vi.restoreAllMocks()
  35. })
  36. describe('test constructor', () => {
  37. test('with all params', () => {
  38. expect(sseSource.getUrl().toString()).toEqual('https://my.mercure.com/?topic=mytopic')
  39. expect(sseSource.getOnOpen()).toEqual(onOpen)
  40. expect(sseSource.getOnMessage()).toEqual(onMessage)
  41. expect(sseSource.getOnClose()).toEqual(onClose)
  42. expect(sseSource.getWithCredentials()).toEqual(false)
  43. })
  44. })
  45. describe('createEventSource', () => {
  46. test('simple call', () => {
  47. const eventSource = sseSource.createEventSource(mercureUrl, false)
  48. expect(eventSource.readyState).toEqual(0)
  49. expect(eventSource.url).toEqual(mercureUrl)
  50. expect(eventSource.withCredentials).toEqual(false)
  51. })
  52. })
  53. describe('isConnected', () => {
  54. test('no event source', () => {
  55. expect(sseSource.isConnected()).toEqual(false)
  56. })
  57. test('got an event source, but it is not open', () => {
  58. const eventSource = sseSource.createEventSource(mercureUrl, true)
  59. sseSource.setEventSource(eventSource)
  60. expect(sseSource.isConnected()).toEqual(false)
  61. })
  62. test('got an open event source', () => {
  63. // @ts-ignore
  64. const eventSource = vi.fn() as EventSourcePolyfill
  65. // @ts-ignore
  66. // noinspection JSConstantReassignment
  67. eventSource.readyState = EventSourcePolyfill.OPEN
  68. sseSource.setEventSource(eventSource)
  69. expect(sseSource.isConnected()).toEqual(true)
  70. })
  71. })
  72. describe('subscribe', () => {
  73. test('already connected', () => {
  74. sseSource.isConnected = vi.fn(() => true)
  75. expect(() => sseSource.subscribe()).toThrowError("SSE - Already subscribed to this event source")
  76. })
  77. test('is server side', () => {
  78. process.server = true
  79. expect(() => sseSource.subscribe()).toThrowError("SSE - Cannot subscribe on server side")
  80. process.server = false
  81. })
  82. test('successful subscription', () => {
  83. onOpen = vi.fn(() => null)
  84. onMessage = vi.fn((data: Array<any>) => null)
  85. sseSource = new TestableSseSource(mercureUrl, topic, onOpen, onMessage, onClose)
  86. const dummyEventSource = new EventSourcePolyfill('https://my.mercure.com', { withCredentials: true })
  87. sseSource.createEventSource = vi.fn((url: string, withCredentials: boolean) => {
  88. return dummyEventSource
  89. })
  90. console.log = vi.fn()
  91. console.error = vi.fn()
  92. sseSource.subscribe()
  93. expect(sseSource.createEventSource).toHaveBeenCalled()
  94. // @ts-ignore
  95. dummyEventSource.onopen()
  96. expect(onOpen).toHaveBeenCalled()
  97. expect(console.log).toHaveBeenCalledWith('SSE - Listening for events...')
  98. // @ts-ignore
  99. dummyEventSource.onmessage({ data: '1' })
  100. expect(onMessage).toHaveBeenCalledWith(1)
  101. // @ts-ignore
  102. dummyEventSource.onerror()
  103. expect(console.error).toHaveBeenCalledWith('SSE - An error happened')
  104. })
  105. })
  106. describe('unsubscribe', () => {
  107. test('if no event source, does nothing', () => {
  108. onClose = vi.fn(() => null)
  109. sseSource = new TestableSseSource(mercureUrl, topic, onOpen, onMessage, onClose)
  110. sseSource.unsubscribe()
  111. expect(onClose).toHaveBeenCalledTimes(0)
  112. })
  113. test('if event source is not opened, does nothing', () => {
  114. onClose = vi.fn(() => null)
  115. sseSource = new TestableSseSource(mercureUrl, topic, onOpen, onMessage, onClose)
  116. // @ts-ignore
  117. const eventSource = vi.fn() as EventSourcePolyfill
  118. // @ts-ignore
  119. // noinspection JSConstantReassignment
  120. eventSource.readyState = EventSourcePolyfill.CLOSED
  121. sseSource.setEventSource(eventSource)
  122. sseSource.unsubscribe()
  123. expect(onClose).toHaveBeenCalledTimes(0)
  124. })
  125. test('has an open subscription', () => {
  126. onClose = vi.fn(() => null)
  127. sseSource = new TestableSseSource(mercureUrl, topic, onOpen, onMessage, onClose)
  128. // @ts-ignore
  129. const eventSource = vi.fn() as EventSourcePolyfill
  130. // @ts-ignore
  131. // noinspection JSConstantReassignment
  132. eventSource.readyState = EventSourcePolyfill.OPEN
  133. eventSource.close = vi.fn(() => null)
  134. sseSource.setEventSource(eventSource)
  135. console.log = vi.fn()
  136. sseSource.unsubscribe()
  137. expect(eventSource.close).toHaveBeenCalled()
  138. expect(onClose).toHaveBeenCalled()
  139. expect(console.log).toHaveBeenCalledWith('SSE - Subscription closed')
  140. })
  141. })