]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20255 - Indexation migration enzyme to rtl
authorKevin Silva <kevin.silva@sonarsource.com>
Fri, 25 Aug 2023 11:44:06 +0000 (13:44 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 30 Aug 2023 20:03:06 +0000 (20:03 +0000)
server/sonar-web/src/main/js/app/components/indexation/__tests__/IndexationContextProvider-test.tsx
server/sonar-web/src/main/js/app/components/indexation/__tests__/IndexationNotification-test.tsx
server/sonar-web/src/main/js/app/components/indexation/__tests__/PageUnavailableDueToIndexation-test.tsx
server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/IndexationContextProvider-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/PageUnavailableDueToIndexation-test.tsx.snap [deleted file]

index d5f09e7d59b2c9ffeb7cfd54e6ea46e6c9014b47..71e9474b659daecfadcda84d051716730c1774b1 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-import { mount } from 'enzyme';
 import * as React from 'react';
+import { useContext } from 'react';
 import { mockAppState } from '../../../../helpers/testMocks';
+import { renderComponent } from '../../../../helpers/testReactTestingUtils';
+import { byText } from '../../../../helpers/testSelector';
 import { IndexationStatus } from '../../../../types/indexation';
+import { IndexationContext } from '../IndexationContext';
 import {
   IndexationContextProvider,
   IndexationContextProviderProps,
@@ -32,29 +35,21 @@ beforeEach(() => jest.clearAllMocks());
 
 jest.mock('../IndexationNotificationHelper');
 
-it('should render correctly and start polling if issue sync is needed', () => {
-  const wrapper = mountRender();
-
-  expect(wrapper).toMatchSnapshot();
+it('should render correctly, start polling if issue sync is needed and stop when unmounted', () => {
+  const { unmount } = renderIndexationContextProvider();
   expect(IndexationNotificationHelper.startPolling).toHaveBeenCalled();
+  unmount();
+  expect(IndexationNotificationHelper.stopPolling).toHaveBeenCalled();
 });
 
 it('should not start polling if no issue sync is needed', () => {
   const appState = mockAppState({ needIssueSync: false });
-  const wrapper = mountRender({ appState });
-
+  renderIndexationContextProvider({ appState });
   expect(IndexationNotificationHelper.startPolling).not.toHaveBeenCalled();
-
-  const expectedStatus: IndexationStatus = {
-    hasFailures: false,
-    isCompleted: true,
-  };
-
-  expect(wrapper.state().status).toEqual(expectedStatus);
 });
 
 it('should update the state on new status', () => {
-  const wrapper = mountRender();
+  renderIndexationContextProvider();
 
   const triggerNewStatus = jest.mocked(IndexationNotificationHelper.startPolling).mock
     .calls[0][0] as (status: IndexationStatus) => void;
@@ -64,21 +59,15 @@ it('should update the state on new status', () => {
     isCompleted: true,
   };
 
-  triggerNewStatus(newStatus);
-
-  expect(wrapper.state().status).toEqual(newStatus);
-});
+  expect(byText('null').get()).toBeInTheDocument();
 
-it('should stop polling when component is destroyed', () => {
-  const wrapper = mountRender();
-
-  wrapper.unmount();
+  triggerNewStatus(newStatus);
 
-  expect(IndexationNotificationHelper.stopPolling).toHaveBeenCalled();
+  expect(byText('{"status":{"hasFailures":false,"isCompleted":true}}').get()).toBeInTheDocument();
 });
 
-function mountRender(props?: IndexationContextProviderProps) {
-  return mount<IndexationContextProvider>(
+function renderIndexationContextProvider(props?: IndexationContextProviderProps) {
+  return renderComponent(
     <IndexationContextProvider appState={mockAppState({ needIssueSync: true, ...props?.appState })}>
       <TestComponent />
     </IndexationContextProvider>
@@ -86,5 +75,6 @@ function mountRender(props?: IndexationContextProviderProps) {
 }
 
 function TestComponent() {
-  return <h1>TestComponent</h1>;
+  const state = useContext(IndexationContext);
+  return <div>{JSON.stringify(state)}</div>;
 }
index 2ca99d7af36147159a8582c844fafec7437719d6..da8f78d54f1d3cc408f96fa76c037011825b7c2a 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-
-import { shallow } from 'enzyme';
 import * as React from 'react';
-import { mockCurrentUser } from '../../../../helpers/testMocks';
-import { IndexationNotificationType } from '../../../../types/indexation';
+import { mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { renderComponent } from '../../../../helpers/testReactTestingUtils';
+import { byText } from '../../../../helpers/testSelector';
+import { Permissions } from '../../../../types/permissions';
 import { IndexationNotification } from '../IndexationNotification';
 import IndexationNotificationHelper from '../IndexationNotificationHelper';
 
@@ -30,21 +30,23 @@ beforeEach(() => jest.clearAllMocks());
 jest.mock('../IndexationNotificationHelper');
 
 describe('Completed banner', () => {
-  it('should be displayed', () => {
+  it('should be displayed and call helper when updated', () => {
     jest
       .mocked(IndexationNotificationHelper.shouldDisplayCompletedNotification)
       .mockReturnValueOnce(true);
 
-    const wrapper = shallowRender();
+    const { rerender } = renderIndexationNotification();
 
-    wrapper.setProps({
-      indexationContext: {
-        status: { hasFailures: false, isCompleted: true },
-      },
-    });
+    rerender(
+      <IndexationNotification
+        currentUser={mockCurrentUser()}
+        indexationContext={{
+          status: { completedCount: 23, hasFailures: false, isCompleted: true, total: 42 },
+        }}
+      />
+    );
 
     expect(IndexationNotificationHelper.shouldDisplayCompletedNotification).toHaveBeenCalled();
-    expect(wrapper.state().notificationType).toBe(IndexationNotificationType.Completed);
   });
 
   it('should be displayed at startup', () => {
@@ -52,14 +54,13 @@ describe('Completed banner', () => {
       .mocked(IndexationNotificationHelper.shouldDisplayCompletedNotification)
       .mockReturnValueOnce(true);
 
-    const wrapper = shallowRender({
+    renderIndexationNotification({
       indexationContext: {
         status: { hasFailures: false, isCompleted: true },
       },
     });
 
     expect(IndexationNotificationHelper.shouldDisplayCompletedNotification).toHaveBeenCalled();
-    expect(wrapper.state().notificationType).toBe(IndexationNotificationType.Completed);
   });
 
   it('should be hidden once completed without failure', () => {
@@ -69,59 +70,88 @@ describe('Completed banner', () => {
       .mocked(IndexationNotificationHelper.shouldDisplayCompletedNotification)
       .mockReturnValueOnce(true);
 
-    const wrapper = shallowRender({
+    renderIndexationNotification({
       indexationContext: {
         status: { hasFailures: false, isCompleted: true },
       },
     });
 
-    expect(wrapper.state().notificationType).toBe(IndexationNotificationType.Completed);
     expect(IndexationNotificationHelper.markCompletedNotificationAsDisplayed).toHaveBeenCalled();
 
     jest.runAllTimers();
 
-    expect(wrapper.state().notificationType).toBeUndefined();
+    expect(IndexationNotificationHelper.markCompletedNotificationAsDisplayed).toHaveBeenCalled();
 
     jest.useRealTimers();
   });
-});
 
-it('should display the completed-with-failure banner', () => {
-  const wrapper = shallowRender({
-    indexationContext: {
-      status: { hasFailures: true, isCompleted: true },
-    },
+  it('should start progress > progress with failure > complete with failure', () => {
+    const { rerender } = renderIndexationNotification({
+      indexationContext: {
+        status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
+      },
+    });
+
+    expect(byText('indexation.progression.23.42').get()).toBeInTheDocument();
+
+    rerender(
+      <IndexationNotification
+        currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })}
+        indexationContext={{
+          status: { completedCount: 23, hasFailures: true, isCompleted: false, total: 42 },
+        }}
+      />
+    );
+
+    expect(byText('indexation.progression_with_error').get()).toBeInTheDocument();
+
+    rerender(
+      <IndexationNotification
+        currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })}
+        indexationContext={{
+          status: { completedCount: 23, hasFailures: true, isCompleted: true, total: 42 },
+        }}
+      />
+    );
+    expect(byText('indexation.completed_with_error').get()).toBeInTheDocument();
   });
 
-  expect(wrapper.state().notificationType).toBe(IndexationNotificationType.CompletedWithFailure);
-});
+  it('should start progress > success > disappear', () => {
+    const { rerender } = renderIndexationNotification({
+      indexationContext: {
+        status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
+      },
+    });
+
+    expect(byText('indexation.progression.23.42').get()).toBeInTheDocument();
 
-it('should display the progress banner', () => {
-  const wrapper = shallowRender({
-    indexationContext: {
-      status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
-    },
+    rerender(
+      <IndexationNotification
+        currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })}
+        indexationContext={{
+          status: { completedCount: 23, hasFailures: false, isCompleted: true, total: 42 },
+        }}
+      />
+    );
+    expect(IndexationNotificationHelper.shouldDisplayCompletedNotification).toHaveBeenCalled();
   });
 
-  expect(IndexationNotificationHelper.markCompletedNotificationAsToDisplay).toHaveBeenCalled();
-  expect(wrapper.state().notificationType).toBe(IndexationNotificationType.InProgress);
-});
+  it('should not see notification if not admin', () => {
+    renderIndexationNotification({
+      indexationContext: {
+        status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
+      },
+      currentUser: mockLoggedInUser(),
+    });
 
-it('should display the progress-with-failure banner', () => {
-  const wrapper = shallowRender({
-    indexationContext: {
-      status: { completedCount: 23, hasFailures: true, isCompleted: false, total: 42 },
-    },
+    expect(byText('indexation.progression.23.42').query()).not.toBeInTheDocument();
   });
-
-  expect(IndexationNotificationHelper.markCompletedNotificationAsToDisplay).toHaveBeenCalled();
-  expect(wrapper.state().notificationType).toBe(IndexationNotificationType.InProgressWithFailure);
 });
 
-function shallowRender(props?: Partial<IndexationNotification['props']>) {
-  return shallow<IndexationNotification>(
+function renderIndexationNotification(props?: Partial<IndexationNotification['props']>) {
+  return renderComponent(
     <IndexationNotification
-      currentUser={mockCurrentUser()}
+      currentUser={mockLoggedInUser({ permissions: { global: [Permissions.Admin] } })}
       indexationContext={{
         status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
       }}
index 7ea9bc3c3c84f151f4b770cb84459f82308acea0..c58dc4927da5f78ecc386fb5e9b65229dddba329 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-import { shallow } from 'enzyme';
 import * as React from 'react';
+import { renderComponent } from '../../../../helpers/testReactTestingUtils';
+import { byRole } from '../../../../helpers/testSelector';
 import { PageUnavailableDueToIndexation } from '../PageUnavailableDueToIndexation';
 
 it('should render correctly', () => {
-  const wrapper = shallowRender();
+  renderPageUnavailableToIndexation();
 
-  expect(wrapper).toMatchSnapshot();
+  expect(byRole('link', { name: 'learn_more' }).get()).toBeInTheDocument();
 });
 
 it('should not refresh the page once the indexation is complete if there were failures', () => {
@@ -36,17 +37,17 @@ it('should not refresh the page once the indexation is complete if there were fa
     value: { reload },
   });
 
-  const wrapper = shallowRender();
+  const { rerender } = renderPageUnavailableToIndexation();
 
   expect(reload).not.toHaveBeenCalled();
 
-  wrapper.setProps({
-    indexationContext: {
-      status: { hasFailures: true, isCompleted: true },
-    },
-  });
-
-  wrapper.update();
+  rerender(
+    <PageUnavailableDueToIndexation
+      indexationContext={{
+        status: { hasFailures: true, isCompleted: true },
+      }}
+    />
+  );
 
   expect(reload).not.toHaveBeenCalled();
 });
@@ -59,23 +60,23 @@ it('should refresh the page once the indexation is complete if there were NO fai
     value: { reload },
   });
 
-  const wrapper = shallowRender();
+  const { rerender } = renderPageUnavailableToIndexation();
 
   expect(reload).not.toHaveBeenCalled();
 
-  wrapper.setProps({
-    indexationContext: {
-      status: { hasFailures: false, isCompleted: true },
-    },
-  });
-
-  wrapper.update();
+  rerender(
+    <PageUnavailableDueToIndexation
+      indexationContext={{
+        status: { hasFailures: false, isCompleted: true },
+      }}
+    />
+  );
 
   expect(reload).toHaveBeenCalled();
 });
 
-function shallowRender() {
-  return shallow<PageUnavailableDueToIndexation>(
+function renderPageUnavailableToIndexation() {
+  return renderComponent(
     <PageUnavailableDueToIndexation
       indexationContext={{
         status: { completedCount: 23, hasFailures: false, isCompleted: false, total: 42 },
diff --git a/server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/IndexationContextProvider-test.tsx.snap b/server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/IndexationContextProvider-test.tsx.snap
deleted file mode 100644 (file)
index 143f0fa..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly and start polling if issue sync is needed 1`] = `
-<IndexationContextProvider
-  appState={
-    {
-      "documentationUrl": "https://docs.sonarsource.com/sonarqube/10.0",
-      "edition": "community",
-      "needIssueSync": true,
-      "productionDatabase": true,
-      "qualifiers": [
-        "TRK",
-      ],
-      "settings": {},
-      "version": "1.0",
-    }
-  }
->
-  <TestComponent>
-    <h1>
-      TestComponent
-    </h1>
-  </TestComponent>
-</IndexationContextProvider>
-`;
diff --git a/server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/PageUnavailableDueToIndexation-test.tsx.snap b/server/sonar-web/src/main/js/app/components/indexation/__tests__/__snapshots__/PageUnavailableDueToIndexation-test.tsx.snap
deleted file mode 100644 (file)
index 2d3cf8c..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<div
-  className="page-wrapper-simple"
->
-  <FlagMessage
-    className="sw-m-10"
-    variant="info"
-  >
-    <span
-      className="sw-w-[290px]"
-    >
-      indexation.page_unavailable.description
-      <span
-        className="sw-ml-1"
-      >
-        <FormattedMessage
-          defaultMessage="indexation.page_unavailable.description.additional_information"
-          id="indexation.page_unavailable.description.additional_information"
-          values={
-            {
-              "link": <StandoutLink
-                to="https://docs.sonarsource.com/sonarqube/latest/instance-administration/reindexing/"
-              >
-                learn_more
-              </StandoutLink>,
-            }
-          }
-        />
-      </span>
-    </span>
-  </FlagMessage>
-</div>
-`;