persistedStore.spec.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {act} from 'react-test-renderer';
  2. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  3. import OrganizationStore from 'sentry/stores/organizationStore';
  4. import {
  5. DefaultLoadedPersistedStore,
  6. DefaultPersistedStore,
  7. PersistedStoreProvider,
  8. usePersistedStoreCategory,
  9. } from 'sentry/stores/persistedStore';
  10. import {OrganizationContext} from 'sentry/views/organizationContext';
  11. describe('PersistedStore', function () {
  12. let org, wrapper;
  13. beforeEach(() => {
  14. org = TestStubs.Organization();
  15. MockApiClient.addMockResponse({
  16. url: `/organizations/${org.slug}/client-state/`,
  17. body: {
  18. onboarding: {
  19. test: 1,
  20. },
  21. },
  22. });
  23. OrganizationStore.onUpdate(org, {replace: true});
  24. wrapper = ({children}) => (
  25. <PersistedStoreProvider>
  26. <OrganizationContext.Provider value={org}>
  27. {children}
  28. </OrganizationContext.Provider>
  29. </PersistedStoreProvider>
  30. );
  31. });
  32. afterEach(() => {
  33. MockApiClient.clearMockResponses();
  34. });
  35. it('provides the persisted data category from client-state API', async function () {
  36. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  37. initialProps: 'onboarding' as const,
  38. wrapper,
  39. });
  40. await waitForNextUpdate();
  41. const [state] = result.current;
  42. expect(state).toMatchObject({
  43. test: 1,
  44. });
  45. });
  46. it('sets the persisted data category from client-state API', async function () {
  47. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  48. initialProps: 'onboarding' as const,
  49. wrapper,
  50. });
  51. await waitForNextUpdate();
  52. const [_, setState] = result.current;
  53. const clientStateUpdate = MockApiClient.addMockResponse({
  54. url: `/organizations/${org.slug}/client-state/onboarding/`,
  55. method: 'PUT',
  56. });
  57. act(() => {
  58. setState({test: 2} as any);
  59. });
  60. const [state2] = result.current;
  61. expect(state2).toMatchObject({
  62. test: 2,
  63. });
  64. expect(clientStateUpdate).toHaveBeenCalledWith(
  65. `/organizations/${org.slug}/client-state/onboarding/`,
  66. expect.objectContaining({
  67. method: 'PUT',
  68. data: {
  69. test: 2,
  70. },
  71. })
  72. );
  73. });
  74. it('deletes the persisted data category on set to null', async function () {
  75. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  76. initialProps: 'onboarding' as const,
  77. wrapper,
  78. });
  79. await waitForNextUpdate();
  80. const [_, setState] = result.current;
  81. const clientStateDelete = MockApiClient.addMockResponse({
  82. url: `/organizations/${org.slug}/client-state/onboarding/`,
  83. method: 'DELETE',
  84. });
  85. act(() => {
  86. setState(null);
  87. });
  88. const [state2] = result.current;
  89. expect(state2).toBe(DefaultPersistedStore.onboarding);
  90. expect(clientStateDelete).toHaveBeenCalledWith(
  91. `/organizations/${org.slug}/client-state/onboarding/`,
  92. expect.objectContaining({
  93. method: 'DELETE',
  94. })
  95. );
  96. });
  97. it('returns default when state is empty', async function () {
  98. MockApiClient.addMockResponse({
  99. url: `/organizations/${org.slug}/client-state/`,
  100. body: {},
  101. });
  102. const {result, waitForNextUpdate} = reactHooks.renderHook(usePersistedStoreCategory, {
  103. initialProps: 'onboarding' as const,
  104. wrapper,
  105. });
  106. const [state] = result.current;
  107. expect(state).toBe(DefaultPersistedStore.onboarding);
  108. await waitForNextUpdate();
  109. const [state2] = result.current;
  110. expect(state2).toBe(DefaultLoadedPersistedStore.onboarding);
  111. });
  112. it('returns default when state fails to load', function () {
  113. MockApiClient.addMockResponse({
  114. url: `/organizations/${org.slug}/client-state/`,
  115. statusCode: 500,
  116. });
  117. const {result} = reactHooks.renderHook(usePersistedStoreCategory, {
  118. initialProps: 'onboarding' as const,
  119. wrapper,
  120. });
  121. const [state] = result.current;
  122. expect(state).toBe(DefaultPersistedStore.onboarding);
  123. });
  124. });