Skip to content

Commit

Permalink
Merge branch 'develop' into feat/custom-headers-for-modal
Browse files Browse the repository at this point in the history
  • Loading branch information
rohanm-crest committed Jan 30, 2025
2 parents e43131d + 742b405 commit 48d6f5e
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 59 deletions.
11 changes: 5 additions & 6 deletions .github/workflows/build-test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -483,9 +483,8 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: "3.7"
- uses: actions/setup-node@v4
with:
registry-url: "https://registry.npmjs.org"
- name: install UI deps
uses: ./.github/actions/cached-ui-deps
- run: curl -sSL https://install.python-poetry.org | python3 - --version 1.5.1
- uses: actions/download-artifact@v4
with:
Expand Down Expand Up @@ -515,9 +514,9 @@ jobs:
poetry build
poetry publish -n -u ${{ secrets.PYPI_USERNAME }} -p ${{ secrets.PYPI_TOKEN }}
- if: ${{ steps.semantic.outputs.new_release_published == 'true' }}
name: Publish NPM (dry-run)
name: Publish NPM
run: |
cd ui
npm publish --provenance --access public --dry-run || true
npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
24 changes: 22 additions & 2 deletions .github/workflows/build-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
workflow_call:

jobs:
build-ui:
ui-code-check:
runs-on: ubuntu-22.04
defaults:
run:
Expand All @@ -17,6 +17,26 @@ jobs:
run: yarn run lint
- name: Unit test
run: yarn run test
- name: Build lib and publish dry run
run: npm publish --provenance --access public --dry-run
- name: Pack tarball
run: npm pack
- name: Upload tarball as artifact
uses: actions/upload-artifact@v4
with:
name: UCC-UI-lib-tarball
path: "ui/*.tgz"

build-ui:
runs-on: ubuntu-22.04
defaults:
run:
working-directory: ui
shell: bash
steps:
- uses: actions/checkout@v4
- name: install deps
uses: ./.github/actions/cached-ui-deps
- name: Build UCC library
run: yarn run build:lib
- name: Build UCC UI
Expand All @@ -27,4 +47,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: UCC-UI-build
path: ui/dist/
path: ui/dist/
39 changes: 39 additions & 0 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: NPM Publish

on:
workflow_dispatch:
inputs:
tag:
description: "Git tag to publish"
required: true
dry_run:
description: "Perform a dry run of the npm publish"
required: false
default: true
type: boolean

jobs:
publish:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ui
shell: bash
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.inputs.tag }}

- name: Install deps
uses: ./.github/actions/cached-ui-deps

- name: Publish NPM package
run: |
if [ "${{ github.event.inputs.dry_run }}" = "true" ]; then
npm publish --provenance --access public --dry-run
else
npm publish --provenance --access public
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
3 changes: 2 additions & 1 deletion tests/ui/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ def pytest_runtest_call(item: pytest.Item) -> Iterator[Any]:

yield

IGNORED: List[str] = []
# sometimes RUM is down and we get a lot of severe logs
IGNORED: List[str] = ["https://rum-ingest.us1.signalfx.com"]

browser_logs = s_utils.get_browser_logs(item.selenium_helper.browser)
severe_logs = [
Expand Down
60 changes: 35 additions & 25 deletions ui/src/components/CustomControl/CustomControl.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { render, screen } from '@testing-library/react';
import { act, render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import userEvent from '@testing-library/user-event';
import CustomControl from './CustomControl';
Expand All @@ -18,48 +18,58 @@ const mockClearErrorMsg = jest.fn();

const FIELD_NAME = 'testCustomField';

beforeEach(() => {
const setup = async () => {
const mockConfig = getGlobalConfigMock();
setUnifiedConfig(mockConfig);

jest.mock(`${getBuildDirPath()}/custom/${MODULE}.js`, () => mockCustomControlMockForTest, {
virtual: true,
});

render(
<CustomControl
data={{
value: 'input_default',
mode: 'create',
serviceName: 'serviceName',
}}
field={FIELD_NAME}
handleChange={handleChange}
controlOptions={{
src: MODULE,
type: 'external',
}}
addCustomValidator={addingCustomValidation}
utilCustomFunctions={{
setState: mockSetState,
setErrorFieldMsg: mockSetErrorFieldMsg,
clearAllErrorMsg: mockClearErrorMsg,
setErrorMsg: mockSetErrorMsg,
}}
/>
);
});
await act(async () => {
render(
<CustomControl
data={{
value: 'input_default',
mode: 'create',
serviceName: 'serviceName',
}}
field={FIELD_NAME}
handleChange={handleChange}
controlOptions={{
src: MODULE,
type: 'external',
}}
addCustomValidator={addingCustomValidation}
utilCustomFunctions={{
setState: mockSetState,
setErrorFieldMsg: mockSetErrorFieldMsg,
clearAllErrorMsg: mockClearErrorMsg,
setErrorMsg: mockSetErrorMsg,
}}
/>
);

const loading = screen.queryByText('Loading...');
if (loading) {
await waitFor(() => expect(loading).not.toHaveTextContent('Loading...'));
}
});
};

it('should render custom component correctly', async () => {
await setup();
const renderedModal = await screen.findByTestId('customSelect');
expect(renderedModal).toBeInTheDocument();
});

it('should try to add validator', async () => {
await setup();
expect(addingCustomValidation).toHaveBeenCalled();
});

it('should correctly call handler on change', async () => {
await setup();
const selectElem = document.querySelector('select');
expect(selectElem).toBeInTheDocument();
const SELECTED_OPTION = 'input_one';
Expand Down
14 changes: 8 additions & 6 deletions ui/src/components/EntityModal/EntityModal.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import { act, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { http, HttpResponse } from 'msw';
import EntityModal, { EntityModalProps } from './EntityModal';
Expand Down Expand Up @@ -491,12 +491,12 @@ describe('Oauth - separated endpoint authorization', () => {

// triggering manually external oauth window behaviour after success authorization
const code = '200';
window.getMessage({ code, state: stateCodeFromUrl, error: undefined });

await waitFor(async () => {
expect(requestHandler).toHaveBeenCalledTimes(1);
await act(async () => {
window.getMessage({ code, state: stateCodeFromUrl, error: undefined });
});

expect(requestHandler).toHaveBeenCalledTimes(1);

const receivedRequest: Request = requestHandler.mock.calls[0][0];
const receivedBody = await receivedRequest.text();

Expand Down Expand Up @@ -534,7 +534,9 @@ describe('Oauth - separated endpoint authorization', () => {
// triggering manually external oauth window behaviour after success authorization
const code = '200';
const passedState = `tests${stateCodeFromUrl}`;
window.getMessage({ code, state: passedState, error: undefined });
await act(async () => {
window.getMessage({ code, state: passedState, error: undefined });
});

expect(screen.getByText(ERROR_STATE_MISSING_TRY_AGAIN)).toBeInTheDocument();
});
Expand Down
31 changes: 19 additions & 12 deletions ui/src/components/InteractAllStatusButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';

import { render, screen } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import { InputRowData, InteractAllStatusButtons } from './InteractAllStatusButton';

describe('InteractAllStatusButtons', () => {
Expand Down Expand Up @@ -95,15 +96,16 @@ describe('InteractAllStatusButtons', () => {
});

it('Deactivate All enabled rows correctly', async () => {
const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();

disableBtn.click();
await user.click(disableBtn);

const yesPopUpBtn = await screen.findByText('Yes');
expect(yesPopUpBtn).toBeInTheDocument();

yesPopUpBtn.click();
await user.click(yesPopUpBtn);

expect(handleToggleStatusChange).toHaveBeenCalledWith(
allDataRowsMockUp.find((x) => x.name === 'aaaaa')
Expand All @@ -118,15 +120,16 @@ describe('InteractAllStatusButtons', () => {
});

it('Activate All disabled rows correctly', async () => {
const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();

enableBtn.click();
await user.click(enableBtn);

const yesPopUpBtn = await screen.findByText('Yes');
expect(yesPopUpBtn).toBeInTheDocument();

yesPopUpBtn.click();
await user.click(yesPopUpBtn);

expect(handleToggleStatusChange).toHaveBeenCalledWith(
allDataRowsMockUp.find((x) => x.name === 'cccccc')
Expand All @@ -141,57 +144,61 @@ describe('InteractAllStatusButtons', () => {
});

it('Do not disable status if rejected', async () => {
const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();

disableBtn.click();
await user.click(disableBtn);

const noPopUpBtn = await screen.findByText('No');
expect(noPopUpBtn).toBeInTheDocument();

noPopUpBtn.click();
await user.click(noPopUpBtn);

expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});

it('Do not enable status if rejected', async () => {
const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();

enableBtn.click();
await user.click(enableBtn);

const noPopUpBtn = await screen.findByText('No');
expect(noPopUpBtn).toBeInTheDocument();

noPopUpBtn.click();
await user.click(noPopUpBtn);

expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});

it('Do not enable status if popup modal closed by X', async () => {
const user = userEvent.setup();
const enableBtn = await screen.findByText('Activate all');
expect(enableBtn).toBeInTheDocument();

enableBtn.click();
await user.click(enableBtn);

const closeXBtn = screen.getByTestId('close');
expect(closeXBtn).toBeInTheDocument();

closeXBtn.click();
await user.click(closeXBtn);

expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});

it('Do not disable status if popup modal closed by X', async () => {
const user = userEvent.setup();
const disableBtn = await screen.findByText('Deactivate all');
expect(disableBtn).toBeInTheDocument();

disableBtn.click();
await user.click(disableBtn);

const closeXBtn = screen.getByTestId('close');
expect(closeXBtn).toBeInTheDocument();

closeXBtn.click();
await user.click(closeXBtn);

expect(handleToggleStatusChange).toHaveBeenCalledTimes(0);
});
Expand Down
7 changes: 5 additions & 2 deletions ui/src/components/table/tests/CustomTableRow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { render, screen, within } from '@testing-library/react';
import { userEvent } from '@testing-library/user-event';
import React from 'react';

import { BrowserRouter } from 'react-router-dom';
Expand Down Expand Up @@ -52,7 +53,8 @@ it('Render action icons correctly', async () => {
});

it('Correctly call action handlers for page dialog', async () => {
(await screen.findAllByRole('button', { name: /edit/i }))[0].click();
const user = userEvent.setup();
await user.click((await screen.findAllByRole('button', { name: /edit/i }))[0]);

expect(handleOpenPageStyleDialog).toHaveBeenCalledWith(expect.objectContaining({}), 'edit');

Expand All @@ -66,8 +68,9 @@ it('Correctly call action handlers for page dialog', async () => {
});

it('Correctly render modal for delete action click', async () => {
const user = userEvent.setup();
// Clicking delete renders modal
(await screen.findAllByRole('button', { name: /delete/i }))[0].click();
await user.click((await screen.findAllByRole('button', { name: /delete/i }))[0]);

expect(await screen.findByRole('dialog')).toHaveTextContent('Delete Confirmation');
});
Expand Down
Loading

0 comments on commit 48d6f5e

Please sign in to comment.