From 6457cf09efb379bc93ce0dac0ac5b359f931db96 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:21:09 +0200 Subject: [PATCH 01/11] feat(configuration): display UCC version --- .../schema/schema.json | 4 ++ tests/ui/pages/configuration_page.py | 8 +++- tests/ui/test_configuration_page.py | 16 +++++++ ui/src/components/UCCCredit/UCCCredit.tsx | 34 ++++++++++++++ .../pages/Configuration/ConfigurationPage.jsx | 45 +++++++++---------- ui/src/pages/entry_page.jsx | 9 ++++ ui/src/pages/style.css | 2 +- ui/src/types/globalConfig/meta.ts | 2 + 8 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 ui/src/components/UCCCredit/UCCCredit.tsx diff --git a/splunk_add_on_ucc_framework/schema/schema.json b/splunk_add_on_ucc_framework/schema/schema.json index 147539a84..79cf06bb6 100644 --- a/splunk_add_on_ucc_framework/schema/schema.json +++ b/splunk_add_on_ucc_framework/schema/schema.json @@ -1686,6 +1686,10 @@ "type": "string", "description": "Version of UCC used during build process" }, + "hideUCCVersion": { + "type": "string", + "description": "Hide the label 'Made with UCC' on the Configuration page" + }, "checkForUpdates": { "type": "boolean", "default": true diff --git a/tests/ui/pages/configuration_page.py b/tests/ui/pages/configuration_page.py index 0e622158f..a4dc52a27 100644 --- a/tests/ui/pages/configuration_page.py +++ b/tests/ui/pages/configuration_page.py @@ -24,16 +24,20 @@ def __init__( self.title = Message( ucc_smartx_selenium_helper.browser, - Selector(select='[data-test="column"] .pageTitle'), + Selector(select=".pageTitle"), ) self.description = Message( ucc_smartx_selenium_helper.browser, - Selector(select='[data-test="column"] .pageSubtitle'), + Selector(select=".pageSubtitle"), ) self.download_openapi = Button( ucc_smartx_selenium_helper.browser, Selector(select='[data-test="downloadButton"]'), ) + self.ucc_credit = Message( + ucc_smartx_selenium_helper.browser, + Selector(select='[data-test="ucc-credit"]'), + ) def open(self): """ diff --git a/tests/ui/test_configuration_page.py b/tests/ui/test_configuration_page.py index 92dd2ba1f..815d51dac 100644 --- a/tests/ui/test_configuration_page.py +++ b/tests/ui/test_configuration_page.py @@ -39,3 +39,19 @@ def test_openapi_json_download_button( download_openapi_href, operator="in", ) + + @pytest.mark.execute_enterprise_cloud_true + @pytest.mark.forwarder + @pytest.mark.configuration + def test_ucc_credits_label_exists( + self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ): + """Verifies the OpenAPI json download button""" + configuration_page = ConfigurationPage( + ucc_smartx_selenium_helper, ucc_smartx_rest_helper + ) + self.assert_util( + left="UCC", + operator="in", + right=configuration_page.ucc_credit.wait_to_display, + ) diff --git a/ui/src/components/UCCCredit/UCCCredit.tsx b/ui/src/components/UCCCredit/UCCCredit.tsx new file mode 100644 index 000000000..08d1030b8 --- /dev/null +++ b/ui/src/components/UCCCredit/UCCCredit.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Typography } from '@splunk/react-ui/Typography'; +import styled from 'styled-components'; +import Link from '@splunk/react-ui/Link'; +import { getUnifiedConfigs } from '../../util/util'; + +const StyledTypography = styled(Typography)` + font-size: 0.9em; +`; + +const UccCredit = () => { + const unifiedConfigs = getUnifiedConfigs(); + + // eslint-disable-next-line no-underscore-dangle + const uccVersion = unifiedConfigs?.meta?._uccVersion ?? null; + if (unifiedConfigs?.meta?.hideUCCVersion) { + return null; + } + return ( + + Made with{' '} + + UCC + {' '} + {uccVersion} + + ); +}; + +export default UccCredit; diff --git a/ui/src/pages/Configuration/ConfigurationPage.jsx b/ui/src/pages/Configuration/ConfigurationPage.jsx index 1a63f944c..cfdb1d845 100644 --- a/ui/src/pages/Configuration/ConfigurationPage.jsx +++ b/ui/src/pages/Configuration/ConfigurationPage.jsx @@ -1,32 +1,30 @@ -import React, { useState, useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { _ } from '@splunk/ui-utils/i18n'; import TabBar from '@splunk/react-ui/TabBar'; import ToastMessages from '@splunk/react-toast-notifications/ToastMessages'; -import ColumnLayout from '@splunk/react-ui/ColumnLayout'; import styled from 'styled-components'; import useQuery from '../../hooks/useQuery'; import { getUnifiedConfigs } from '../../util/util'; -import { TitleComponent, SubTitleComponent } from '../Input/InputPageStyle'; +import { SubTitleComponent, TitleComponent } from '../Input/InputPageStyle'; import ErrorBoundary from '../../components/ErrorBoundary/ErrorBoundary'; import CustomTab from '../../components/CustomTab/CustomTab'; import ConfigurationFormView from '../../components/ConfigurationFormView'; import ConfigurationTable from '../../components/ConfigurationTable'; import OpenApiDownloadButton from '../../components/DownloadButton/OpenApiDownloadBtn'; import SubDescription from '../../components/SubDescription/SubDescription'; +import UccCredit from '../../components/UCCCredit/UCCCredit'; -const Row = styled(ColumnLayout.Row)` - padding: 5px 0px; - - .dropdown { - text-align: right; - } +const StyledHeader = styled.header` + display: flex; + justify-content: space-between; +`; - .input_button { - text-align: right; - margin-right: 0px; - } +const StyledHeaderControls = styled.div` + align-items: center; + display: flex; + gap: 0.4rem; `; function ConfigurationPage() { @@ -99,18 +97,15 @@ function ConfigurationPage() { return (
- - - - {_(title)} - {_(description || '')} - - - - - - - + + {_(title)} + + + + + + {_(description || '')} + {tabs.map((tab) => ( diff --git a/ui/src/pages/entry_page.jsx b/ui/src/pages/entry_page.jsx index a36af9ea0..39ad59e13 100644 --- a/ui/src/pages/entry_page.jsx +++ b/ui/src/pages/entry_page.jsx @@ -64,6 +64,15 @@ const url = window.location.pathname; const urlParts = url.substring(1).split('/'); const page = urlParts[urlParts.length - 1]; +// eslint-disable-next-line no-console +console.log(` +UCC Framework is here 👋 If you encounter any issues or have feedback, please report them to us. + +For Splunkers, reach out via our Slack channel: #ucc-framework. +For external users, join us at: https://splunk-usergroups.slack.com/archives/C03SG3ZL4S1. + +We appreciate your help in making UCC better! 🚀`); + if (page === PAGE_INPUT) { layout(, { pageTitle: messageDict[116] }); } else if (page === PAGE_CONF) { diff --git a/ui/src/pages/style.css b/ui/src/pages/style.css index 5ee4fff9b..3a8d40c4d 100644 --- a/ui/src/pages/style.css +++ b/ui/src/pages/style.css @@ -22,7 +22,7 @@ body { background: #f2f4f5; /* move to class to applied changes only for Monitoring Dashboard */ } -// Safari browser specific issue - https://stackoverflow.com/questions/21400182/safari-css-font-color-issue?noredirect=1&lq=1 +/* Safari browser specific issue - https://stackoverflow.com/questions/21400182/safari-css-font-color-issue?noredirect=1&lq=1 */ input[disabled], textarea[disabled], select[disabled='disabled'] { diff --git a/ui/src/types/globalConfig/meta.ts b/ui/src/types/globalConfig/meta.ts index 26d9665ad..d42acea0e 100644 --- a/ui/src/types/globalConfig/meta.ts +++ b/ui/src/types/globalConfig/meta.ts @@ -7,6 +7,8 @@ export const meta = z.object({ apiVersion: z.string().optional(), version: z.string(), schemaVersion: z.string().optional(), + _uccVersion: z.string().optional(), + hideUCCVersion: z.boolean().optional(), checkForUpdates: z.boolean().default(true).optional(), searchViewDefault: z.boolean().default(false).optional(), }); From 408dadbaff35172c44618ae2dc77bbbef2ba5efb Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Mon, 3 Jun 2024 17:32:48 +0200 Subject: [PATCH 02/11] fix --- tests/ui/test_configuration_page.py | 2 +- ui/src/components/UCCCredit/UCCCredit.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/test_configuration_page.py b/tests/ui/test_configuration_page.py index 815d51dac..f87fc03f2 100644 --- a/tests/ui/test_configuration_page.py +++ b/tests/ui/test_configuration_page.py @@ -46,7 +46,7 @@ def test_openapi_json_download_button( def test_ucc_credits_label_exists( self, ucc_smartx_selenium_helper, ucc_smartx_rest_helper ): - """Verifies the OpenAPI json download button""" + """Verifies the UCC label is rendered on the page""" configuration_page = ConfigurationPage( ucc_smartx_selenium_helper, ucc_smartx_rest_helper ) diff --git a/ui/src/components/UCCCredit/UCCCredit.tsx b/ui/src/components/UCCCredit/UCCCredit.tsx index 08d1030b8..e45efd27a 100644 --- a/ui/src/components/UCCCredit/UCCCredit.tsx +++ b/ui/src/components/UCCCredit/UCCCredit.tsx @@ -5,7 +5,7 @@ import Link from '@splunk/react-ui/Link'; import { getUnifiedConfigs } from '../../util/util'; const StyledTypography = styled(Typography)` - font-size: 0.9em; + font-size: 0.8em; `; const UccCredit = () => { From 6812135769210e25d0b2c626970af419f21e1288 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:39:11 +0200 Subject: [PATCH 03/11] fix styles --- .../pages/Configuration/ConfigurationPage.jsx | 49 ++++++++++++------- ui/src/pages/Input/InputPageStyle.jsx | 16 +++--- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/ui/src/pages/Configuration/ConfigurationPage.jsx b/ui/src/pages/Configuration/ConfigurationPage.jsx index cfdb1d845..fb17b445e 100644 --- a/ui/src/pages/Configuration/ConfigurationPage.jsx +++ b/ui/src/pages/Configuration/ConfigurationPage.jsx @@ -5,9 +5,10 @@ import TabBar from '@splunk/react-ui/TabBar'; import ToastMessages from '@splunk/react-toast-notifications/ToastMessages'; import styled from 'styled-components'; +import ColumnLayout from '@splunk/react-ui/ColumnLayout'; import useQuery from '../../hooks/useQuery'; import { getUnifiedConfigs } from '../../util/util'; -import { SubTitleComponent, TitleComponent } from '../Input/InputPageStyle'; +import { TitleComponent, SubTitleComponent } from '../Input/InputPageStyle'; import ErrorBoundary from '../../components/ErrorBoundary/ErrorBoundary'; import CustomTab from '../../components/CustomTab/CustomTab'; import ConfigurationFormView from '../../components/ConfigurationFormView'; @@ -16,17 +17,25 @@ import OpenApiDownloadButton from '../../components/DownloadButton/OpenApiDownlo import SubDescription from '../../components/SubDescription/SubDescription'; import UccCredit from '../../components/UCCCredit/UCCCredit'; -const StyledHeader = styled.header` - display: flex; - justify-content: space-between; -`; - const StyledHeaderControls = styled.div` - align-items: center; - display: flex; + display: inline-flex; + align-items: baseline; gap: 0.4rem; `; +const Row = styled(ColumnLayout.Row)` + padding: 5px 0px; + + .dropdown { + text-align: right; + } + + .input_button { + text-align: right; + margin-right: 0px; + } +`; + function ConfigurationPage() { const unifiedConfigs = getUnifiedConfigs(); const { title, description, subDescription, tabs } = unifiedConfigs.pages.configuration; @@ -97,15 +106,21 @@ function ConfigurationPage() { return (
- - {_(title)} - - - - - - {_(description || '')} - + + + + {_(title)} + {_(description || '')} + + + + + + + + + + {tabs.map((tab) => ( diff --git a/ui/src/pages/Input/InputPageStyle.jsx b/ui/src/pages/Input/InputPageStyle.jsx index 7ca1f2a12..a955ecad0 100644 --- a/ui/src/pages/Input/InputPageStyle.jsx +++ b/ui/src/pages/Input/InputPageStyle.jsx @@ -4,21 +4,17 @@ import { variables } from '@splunk/themes'; export const TitleComponent = styled.div.attrs({ className: 'pageTitle', })` - &.pageTitle { - font-size: ${variables.fontSizeXXLarge}; - margin-bottom: 20px; - display: flex; - justify-content: space-between; - } + font-size: ${variables.fontSizeXXLarge}; + margin-bottom: 20px; + display: flex; + justify-content: space-between; `; export const SubTitleComponent = styled.div.attrs({ className: 'pageSubtitle', })` - &.pageSubtitle { - font-size: ${variables.fontSize}; - margin-bottom: 10px; - } + font-size: ${variables.fontSize}; + margin-bottom: 10px; `; export const TableCaptionComponent = styled.div` From 8484028651780011f7b52b18396ae7ab73929557 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Tue, 4 Jun 2024 09:42:21 +0000 Subject: [PATCH 04/11] update screenshots --- .../ConfigurationPage-configuration-page-view-chromium.png | 4 ++-- ...obalConfigPlayground-global-config-playground-chromium.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png index 15f4350c4..8bc26756e 100644 --- a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png +++ b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d5efe48b76d77b4393a181f08645895297b9f4622834dccb70915e2267b2f4c8 -size 63090 +oid sha256:98a8a4966a36e898e45683a139c8eb3dae9999ad8caaad80921fe09fc7d7990b +size 58117 diff --git a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png index 1cfbab929..1d4d050e1 100644 --- a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png +++ b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9e6dff1cf59f529c1e95a35d546f080f506d182c842d2cb246c60c4240a9588 -size 65929 +oid sha256:3a37d7aec2bb3595b96c88f9bbd21ce281589356a57eadfad3d41808aada0e9d +size 60639 From 36c9b85ea52218d3021ff584aa47cc6edfcef063 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Tue, 4 Jun 2024 11:44:35 +0200 Subject: [PATCH 05/11] fix --- ui/src/pages/Configuration/ConfigurationPage.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/pages/Configuration/ConfigurationPage.jsx b/ui/src/pages/Configuration/ConfigurationPage.jsx index fb17b445e..4c5467ac3 100644 --- a/ui/src/pages/Configuration/ConfigurationPage.jsx +++ b/ui/src/pages/Configuration/ConfigurationPage.jsx @@ -3,9 +3,9 @@ import React, { useCallback, useEffect, useState } from 'react'; import { _ } from '@splunk/ui-utils/i18n'; import TabBar from '@splunk/react-ui/TabBar'; import ToastMessages from '@splunk/react-toast-notifications/ToastMessages'; -import styled from 'styled-components'; - import ColumnLayout from '@splunk/react-ui/ColumnLayout'; + +import styled from 'styled-components'; import useQuery from '../../hooks/useQuery'; import { getUnifiedConfigs } from '../../util/util'; import { TitleComponent, SubTitleComponent } from '../Input/InputPageStyle'; From 91334b5c052976618accdb83b77277dea5f164d7 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:08:53 +0200 Subject: [PATCH 06/11] extend tests and fix schema.json --- splunk_add_on_ucc_framework/schema/schema.json | 2 +- tests/ui/test_configuration_page.py | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/splunk_add_on_ucc_framework/schema/schema.json b/splunk_add_on_ucc_framework/schema/schema.json index 79cf06bb6..d5d3beb72 100644 --- a/splunk_add_on_ucc_framework/schema/schema.json +++ b/splunk_add_on_ucc_framework/schema/schema.json @@ -1687,7 +1687,7 @@ "description": "Version of UCC used during build process" }, "hideUCCVersion": { - "type": "string", + "type": "boolean", "description": "Hide the label 'Made with UCC' on the Configuration page" }, "checkForUpdates": { diff --git a/tests/ui/test_configuration_page.py b/tests/ui/test_configuration_page.py index f87fc03f2..0d9abfcc5 100644 --- a/tests/ui/test_configuration_page.py +++ b/tests/ui/test_configuration_page.py @@ -2,6 +2,9 @@ from tests.ui.pages.configuration_page import ConfigurationPage import pytest +from splunk_add_on_ucc_framework import ( + __version__, +) class TestConfigurationPage(UccTester): @@ -50,8 +53,14 @@ def test_ucc_credits_label_exists( configuration_page = ConfigurationPage( ucc_smartx_selenium_helper, ucc_smartx_rest_helper ) + ucc_label = configuration_page.ucc_credit.wait_to_display() self.assert_util( left="UCC", operator="in", - right=configuration_page.ucc_credit.wait_to_display, + right=ucc_label, + ) + self.assert_util( + left=__version__, + operator="in", + right=ucc_label, ) From d4ccd8fadd5a273b0ac7f2068796131658b77eb2 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Wed, 5 Jun 2024 09:16:52 +0000 Subject: [PATCH 07/11] update screenshots --- .../ConfigurationPage-configuration-page-view-chromium.png | 4 ++-- ...obalConfigPlayground-global-config-playground-chromium.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png index 832d49450..1cb35c823 100644 --- a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png +++ b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7350d197b3bc86487d21e98fc9270569a4e6504ae10324723a6f32a3f95bde21 -size 56293 +oid sha256:ba1c834196de29260cd0a75bd4f3d0012b43da7443b51afdf660b6946400566b +size 58270 diff --git a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png index 26815f2a5..c494aab5c 100644 --- a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png +++ b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ac863047449c911ab2e6d473f9e0a4a90bdf5768cbbafe344553af46adecac9 -size 58745 +oid sha256:f9df70f2a3976f23581bf7b3ea91ed39c752a595b556f0cc9d134527905747f3 +size 60849 From d9a7ff13e7663f4bc1e41234ef2da5460ecb807c Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Wed, 5 Jun 2024 11:48:36 +0200 Subject: [PATCH 08/11] fix layout --- ui/src/pages/Configuration/ConfigurationPage.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/src/pages/Configuration/ConfigurationPage.jsx b/ui/src/pages/Configuration/ConfigurationPage.jsx index 4c5467ac3..aa8b4cb24 100644 --- a/ui/src/pages/Configuration/ConfigurationPage.jsx +++ b/ui/src/pages/Configuration/ConfigurationPage.jsx @@ -19,7 +19,9 @@ import UccCredit from '../../components/UCCCredit/UCCCredit'; const StyledHeaderControls = styled.div` display: inline-flex; - align-items: baseline; + align-items: center; + justify-content: end; + flex-wrap: wrap; gap: 0.4rem; `; From 370fa8b1ee81b73e2586fb15bc50bb9e8c8d7ed0 Mon Sep 17 00:00:00 2001 From: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> Date: Wed, 5 Jun 2024 09:51:48 +0000 Subject: [PATCH 09/11] update screenshots --- .../ConfigurationPage-configuration-page-view-chromium.png | 4 ++-- ...obalConfigPlayground-global-config-playground-chromium.png | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png index 1cb35c823..50d4d6172 100644 --- a/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png +++ b/ui/src/pages/Configuration/stories/__images__/ConfigurationPage-configuration-page-view-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba1c834196de29260cd0a75bd4f3d0012b43da7443b51afdf660b6946400566b -size 58270 +oid sha256:eb432e0739d0381cc384034e38b7e2490abc92a80d2a8e0a762b0bb0427c8ed9 +size 58115 diff --git a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png index c494aab5c..f8d85a4e1 100644 --- a/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png +++ b/ui/src/pages/stories/__images__/GlobalConfigPlayground-global-config-playground-chromium.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f9df70f2a3976f23581bf7b3ea91ed39c752a595b556f0cc9d134527905747f3 -size 60849 +oid sha256:f026a6aa8b350b462f75e658eb03d83c91daa32d27d4cba0dcdad3d6b7416efd +size 60642 From 32e2cf4be507267fc1d7d2f2173d1ac2108c5a55 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:43:49 +0200 Subject: [PATCH 10/11] add tests --- ui/src/components/ConfigurationFormView.jsx | 26 ++++++- .../MultiInputComponent.tsx | 11 ++- ui/src/components/UCCCredit/UCCCredit.tsx | 4 +- ui/src/components/table/TableWrapper.tsx | 21 ++++-- ui/src/mocks/server-response.ts | 1 + .../Configuration/ConfigurationPage.test.tsx | 70 +++++++++++++++++++ ui/src/util/axiosCallWrapper.ts | 14 ++-- 7 files changed, 125 insertions(+), 22 deletions(-) create mode 100644 ui/src/pages/Configuration/ConfigurationPage.test.tsx diff --git a/ui/src/components/ConfigurationFormView.jsx b/ui/src/components/ConfigurationFormView.jsx index b5fdeff35..2be92e75a 100644 --- a/ui/src/components/ConfigurationFormView.jsx +++ b/ui/src/components/ConfigurationFormView.jsx @@ -5,6 +5,7 @@ import { _ } from '@splunk/ui-utils/i18n'; import styled from 'styled-components'; import WaitSpinner from '@splunk/react-ui/WaitSpinner'; +import axios from 'axios'; import BaseFormView from './BaseFormView/BaseFormView'; import { StyledButton } from '../pages/EntryPageStyle'; import { axiosCallWrapper } from '../util/axiosCallWrapper'; @@ -24,15 +25,34 @@ function ConfigurationFormView({ serviceName }) { const [currentServiceState, setCurrentServiceState] = useState({}); useEffect(() => { + const abortController = new AbortController(); axiosCallWrapper({ serviceName: `settings/${serviceName}`, handleError: true, + signal: abortController.signal, callbackOnError: (err) => { + if (abortController.signal.aborted) { + return; + } setError(err); }, - }).then((response) => { - setCurrentServiceState(response.data.entry[0].content); - }); + }) + .catch((caughtError) => { + if (axios.isCancel(caughtError)) { + return null; + } + throw caughtError; + }) + .then((response) => { + if (!response) { + return; + } + setCurrentServiceState(response.data.entry[0].content); + }); + + return () => { + abortController.abort(); + }; }, [serviceName]); /** diff --git a/ui/src/components/MultiInputComponent/MultiInputComponent.tsx b/ui/src/components/MultiInputComponent/MultiInputComponent.tsx index b090a8c75..a6f2f0837 100644 --- a/ui/src/components/MultiInputComponent/MultiInputComponent.tsx +++ b/ui/src/components/MultiInputComponent/MultiInputComponent.tsx @@ -1,10 +1,9 @@ import React, { useState, useEffect, ReactElement } from 'react'; import Multiselect from '@splunk/react-ui/Multiselect'; import styled from 'styled-components'; -import axios from 'axios'; import WaitSpinner from '@splunk/react-ui/WaitSpinner'; -import { axiosCallWrapper } from '../../util/axiosCallWrapper'; +import { AxiosCallType, axiosCallWrapper } from '../../util/axiosCallWrapper'; import { filterResponse } from '../../util/util'; const MultiSelectWrapper = styled(Multiselect)` @@ -84,15 +83,15 @@ function MultiInputComponent(props: MultiInputComponentProps) { } let current = true; - const source = axios.CancelToken.source(); + const abortController = new AbortController(); const apiCallOptions = { - cancelToken: source.token, + signal: abortController.signal, handleError: true, params: { count: -1 }, serviceName: '', endpointUrl: '', - }; + } satisfies AxiosCallType; if (referenceName) { apiCallOptions.serviceName = referenceName; } else if (endpointUrl) { @@ -123,7 +122,7 @@ function MultiInputComponent(props: MultiInputComponentProps) { } // eslint-disable-next-line consistent-return return () => { - source.cancel('Operation canceled.'); + abortController.abort('Operation canceled.'); current = false; }; // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/ui/src/components/UCCCredit/UCCCredit.tsx b/ui/src/components/UCCCredit/UCCCredit.tsx index e45efd27a..bc42acff5 100644 --- a/ui/src/components/UCCCredit/UCCCredit.tsx +++ b/ui/src/components/UCCCredit/UCCCredit.tsx @@ -11,11 +11,11 @@ const StyledTypography = styled(Typography)` const UccCredit = () => { const unifiedConfigs = getUnifiedConfigs(); - // eslint-disable-next-line no-underscore-dangle - const uccVersion = unifiedConfigs?.meta?._uccVersion ?? null; if (unifiedConfigs?.meta?.hideUCCVersion) { return null; } + // eslint-disable-next-line no-underscore-dangle + const uccVersion = unifiedConfigs?.meta?._uccVersion ?? null; return ( { + const abortController = new AbortController(); + const requests = services?.map((service) => axiosCallWrapper({ serviceName: service.name, params: { count: -1 }, + signal: abortController.signal, }) ) || []; axios .all(requests) .catch((caughtError) => { + if (axios.isCancel(caughtError)) { + return; + } const message = parseErrorMsg(caughtError); generateToast(message, 'error'); setLoading(false); setError(caughtError); - return Promise.reject(caughtError); }) .then((response) => { + if (!response) { + return; + } modifyAPIResponse(response.map((res) => res.data.entry)); }); + + return () => { + abortController.abort(); + }; }; - useEffect(() => { - fetchInputs(); + useEffect( + () => fetchInputs(), // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + [] + ); /** * diff --git a/ui/src/mocks/server-response.ts b/ui/src/mocks/server-response.ts index 80dedd53d..a64b68248 100644 --- a/ui/src/mocks/server-response.ts +++ b/ui/src/mocks/server-response.ts @@ -17,6 +17,7 @@ export const mockServerResponseWithContent = { updated: '2023-08-21T11:54:12+00:00', entry: [ { + id: 1, content: { disabled: true, }, diff --git a/ui/src/pages/Configuration/ConfigurationPage.test.tsx b/ui/src/pages/Configuration/ConfigurationPage.test.tsx new file mode 100644 index 000000000..18185919a --- /dev/null +++ b/ui/src/pages/Configuration/ConfigurationPage.test.tsx @@ -0,0 +1,70 @@ +import * as React from 'react'; +import { render } from '@testing-library/react'; +import { BrowserRouter } from 'react-router-dom'; + +import { http, HttpResponse } from 'msw'; +import ConfigurationPage from './ConfigurationPage'; +import { getUnifiedConfigs } from '../../util/util'; +import { getGlobalConfigMock } from '../../mocks/globalConfigMock'; +import { type meta as metaType } from '../../types/globalConfig/meta'; +import { mockServerResponseWithContent } from '../../mocks/server-response'; +import { server } from '../../mocks/server'; + +const mockNavigateFn = jest.fn(); +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useNavigate: () => mockNavigateFn, +})); + +jest.mock('../../util/util'); + +const getUnifiedConfigsMock = getUnifiedConfigs as jest.Mock; + +beforeEach(() => { + server.use( + http.get(`/servicesNS/nobody/-/:endpointUrl`, () => + HttpResponse.json(mockServerResponseWithContent) + ) + ); +}); + +function setup(meta: Partial) { + const globalConfigMock = getGlobalConfigMock(); + + getUnifiedConfigsMock.mockImplementation(() => ({ + ...globalConfigMock, + meta: { + ...globalConfigMock.meta, + ...meta, + }, + })); + return render(, { wrapper: BrowserRouter }); +} + +it('should show UCC label', async () => { + const page = setup({ + _uccVersion: undefined, + }); + + const uccLink = page.getByRole('link', { name: /ucc/i }); + expect(uccLink).toBeInTheDocument(); + expect(uccLink.getAttribute('href')).toContain('github.io'); +}); + +it('should not show UCC label', async () => { + const page = setup({ + hideUCCVersion: true, + }); + + const uccLink = page.queryByRole('link', { name: /ucc/i }); + expect(uccLink).toBeNull(); +}); + +it('should show UCC version', async () => { + const uccVersion = '5.2221.2341'; + const page = setup({ + _uccVersion: uccVersion, + }); + + expect(page.getByTestId('ucc-credit')).toHaveTextContent(uccVersion); +}); diff --git a/ui/src/util/axiosCallWrapper.ts b/ui/src/util/axiosCallWrapper.ts index 004123137..5c2628af8 100755 --- a/ui/src/util/axiosCallWrapper.ts +++ b/ui/src/util/axiosCallWrapper.ts @@ -1,4 +1,4 @@ -import axios, { CancelToken } from 'axios'; +import axios, { AxiosRequestConfig } from 'axios'; import { CSRFToken, app } from '@splunk/splunk-utils/config'; import { createRESTURL } from '@splunk/splunk-utils/url'; import { generateEndPointUrl, generateToast } from './util'; @@ -16,7 +16,7 @@ interface axiosCallWithEndpointUrl { interface CommonAxiosCall { params?: Record; - cancelToken?: CancelToken; + signal?: AbortSignal; customHeaders?: Record; method?: 'get' | 'post' | 'delete'; body?: URLSearchParams; @@ -24,7 +24,7 @@ interface CommonAxiosCall { callbackOnError?: (error: unknown) => void; } -type AxiosCallType = (axiosCallWithServiceName | axiosCallWithEndpointUrl) & CommonAxiosCall; +export type AxiosCallType = (axiosCallWithServiceName | axiosCallWithEndpointUrl) & CommonAxiosCall; /** * @@ -44,7 +44,7 @@ const axiosCallWrapper = ({ endpointUrl, params, body, - cancelToken, + signal, customHeaders = {}, method = 'get', handleError = false, @@ -72,10 +72,10 @@ const axiosCallWrapper = ({ params: newParams, method, url, - credentials: 'include', + withCredentials: true, headers, - cancelToken, - }; + signal, + } satisfies AxiosRequestConfig; if (method === 'post') { options.data = body; From d96d537cef15891fb9d7f0e1b22fed3de02455e5 Mon Sep 17 00:00:00 2001 From: Viktor Tsvetkov <142901247+vtsvetkov-splunk@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:45:58 +0200 Subject: [PATCH 11/11] remove unnecessary code --- ui/src/pages/Configuration/ConfigurationPage.test.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ui/src/pages/Configuration/ConfigurationPage.test.tsx b/ui/src/pages/Configuration/ConfigurationPage.test.tsx index 18185919a..3a5f31cbd 100644 --- a/ui/src/pages/Configuration/ConfigurationPage.test.tsx +++ b/ui/src/pages/Configuration/ConfigurationPage.test.tsx @@ -10,12 +10,6 @@ import { type meta as metaType } from '../../types/globalConfig/meta'; import { mockServerResponseWithContent } from '../../mocks/server-response'; import { server } from '../../mocks/server'; -const mockNavigateFn = jest.fn(); -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useNavigate: () => mockNavigateFn, -})); - jest.mock('../../util/util'); const getUnifiedConfigsMock = getUnifiedConfigs as jest.Mock;