sseSource.test.ts 5.6 KB

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