DispatchingStore.spec.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { BehaviorSubject, Subject } from "rxjs"
  2. import isEqual from "lodash/isEqual"
  3. import DispatchingStore from "~/newstore/DispatchingStore"
  4. describe("DispatchingStore", () => {
  5. test("'subject$' property properly returns an BehaviorSubject", () => {
  6. const store = new DispatchingStore({}, {})
  7. expect(store.subject$ instanceof BehaviorSubject).toEqual(true)
  8. })
  9. test("'value' property properly returns the current state value", () => {
  10. const store = new DispatchingStore({}, {})
  11. expect(store.value).toEqual({})
  12. })
  13. test("'dispatches$' property properly returns a Subject", () => {
  14. const store = new DispatchingStore({}, {})
  15. expect(store.dispatches$ instanceof Subject).toEqual(true)
  16. })
  17. test("dispatch with invalid dispatcher are thrown", () => {
  18. const store = new DispatchingStore({}, {})
  19. expect(() => {
  20. store.dispatch({
  21. dispatcher: "non-existent",
  22. payload: {},
  23. })
  24. }).toThrow()
  25. })
  26. test("valid dispatcher calls run without throwing", () => {
  27. const store = new DispatchingStore(
  28. {},
  29. {
  30. testDispatcher(_currentValue, _payload) {
  31. // Nothing here
  32. },
  33. }
  34. )
  35. expect(() => {
  36. store.dispatch({
  37. dispatcher: "testDispatcher",
  38. payload: {},
  39. })
  40. }).not.toThrow()
  41. })
  42. test("only correct dispatcher method is ran", () => {
  43. const dispatchFn = jest.fn().mockReturnValue({})
  44. const dontCallDispatchFn = jest.fn().mockReturnValue({})
  45. const store = new DispatchingStore(
  46. {},
  47. {
  48. testDispatcher: dispatchFn,
  49. dontCallDispatcher: dontCallDispatchFn,
  50. }
  51. )
  52. store.dispatch({
  53. dispatcher: "testDispatcher",
  54. payload: {},
  55. })
  56. expect(dispatchFn).toHaveBeenCalledTimes(1)
  57. expect(dontCallDispatchFn).not.toHaveBeenCalled()
  58. })
  59. test("passes current value and the payload to the dispatcher", () => {
  60. const testInitValue = { name: "bob" }
  61. const testPayload = { name: "alice" }
  62. const testDispatchFn = jest.fn().mockReturnValue({})
  63. const store = new DispatchingStore(testInitValue, {
  64. testDispatcher: testDispatchFn,
  65. })
  66. store.dispatch({
  67. dispatcher: "testDispatcher",
  68. payload: testPayload,
  69. })
  70. expect(testDispatchFn).toHaveBeenCalledWith(testInitValue, testPayload)
  71. })
  72. test("dispatcher returns are used to update the store correctly", () => {
  73. const testInitValue = { name: "bob" }
  74. const testDispatchReturnVal = { name: "alice" }
  75. const testDispatchFn = jest.fn().mockReturnValue(testDispatchReturnVal)
  76. const store = new DispatchingStore(testInitValue, {
  77. testDispatcher: testDispatchFn,
  78. })
  79. store.dispatch({
  80. dispatcher: "testDispatcher",
  81. payload: {}, // Payload doesn't matter because the function is mocked
  82. })
  83. expect(store.value).toEqual(testDispatchReturnVal)
  84. })
  85. test("dispatching patches in new values if not existing on the store", () => {
  86. const testInitValue = { name: "bob" }
  87. const testDispatchReturnVal = { age: 25 }
  88. const testDispatchFn = jest.fn().mockReturnValue(testDispatchReturnVal)
  89. const store = new DispatchingStore(testInitValue, {
  90. testDispatcher: testDispatchFn,
  91. })
  92. store.dispatch({
  93. dispatcher: "testDispatcher",
  94. payload: {},
  95. })
  96. expect(store.value).toEqual({
  97. name: "bob",
  98. age: 25,
  99. })
  100. })
  101. test("emits the current store value to the new subscribers", (done) => {
  102. const testInitValue = { name: "bob" }
  103. const testDispatchFn = jest.fn().mockReturnValue({})
  104. const store = new DispatchingStore(testInitValue, {
  105. testDispatcher: testDispatchFn,
  106. })
  107. store.subject$.subscribe((value) => {
  108. if (value === testInitValue) {
  109. done()
  110. }
  111. })
  112. })
  113. test("emits the dispatched store value to the subscribers", (done) => {
  114. const testInitValue = { name: "bob" }
  115. const testDispatchReturnVal = { age: 25 }
  116. const testDispatchFn = jest.fn().mockReturnValue(testDispatchReturnVal)
  117. const store = new DispatchingStore(testInitValue, {
  118. testDispatcher: testDispatchFn,
  119. })
  120. store.subject$.subscribe((value) => {
  121. if (isEqual(value, { name: "bob", age: 25 })) {
  122. done()
  123. }
  124. })
  125. store.dispatch({
  126. dispatcher: "testDispatcher",
  127. payload: {},
  128. })
  129. })
  130. test("dispatching emits the new dispatch requests to the subscribers", () => {
  131. const testInitValue = { name: "bob" }
  132. const testPayload = { age: 25 }
  133. const testDispatchFn = jest.fn().mockReturnValue({})
  134. const store = new DispatchingStore(testInitValue, {
  135. testDispatcher: testDispatchFn,
  136. })
  137. store.dispatches$.subscribe((value) => {
  138. if (
  139. isEqual(value, { dispatcher: "testDispatcher", payload: testPayload })
  140. ) {
  141. done()
  142. }
  143. })
  144. store.dispatch({
  145. dispatcher: "testDispatcher",
  146. payload: {},
  147. })
  148. })
  149. })