Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions redisinsight/ui/src/components/config/Config.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { getRedisCommands } from 'uiSrc/slices/app/redis-commands'
import { ONBOARDING_FEATURES } from 'uiSrc/components/onboarding-features'
import { getWBGuides } from 'uiSrc/slices/workbench/wb-guides'
import { getWBTutorials } from 'uiSrc/slices/workbench/wb-tutorials'
import { getContentRecommendations } from 'uiSrc/slices/recommendations/recommendations'
import Config from './Config'

let store: typeof mockedStore
Expand Down Expand Up @@ -61,6 +62,7 @@ describe('Config', () => {
processCliClient(),
getRedisCommands(),
getNotifications(),
getContentRecommendations(),
getWBGuides(),
getWBTutorials(),
getFeatureFlags(),
Expand Down Expand Up @@ -94,6 +96,7 @@ describe('Config', () => {
processCliClient(),
getRedisCommands(),
getNotifications(),
getContentRecommendations(),
getWBGuides(),
getWBTutorials(),
getFeatureFlags(),
Expand Down
2 changes: 2 additions & 0 deletions redisinsight/ui/src/components/config/Config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { fetchRedisCommandsInfo } from 'uiSrc/slices/app/redis-commands'
import { fetchGuides } from 'uiSrc/slices/workbench/wb-guides'
import { fetchTutorials } from 'uiSrc/slices/workbench/wb-tutorials'
import { ONBOARDING_FEATURES } from 'uiSrc/components/onboarding-features'
import { fetchContentRecommendations } from 'uiSrc/slices/recommendations/recommendations'
import favicon from 'uiSrc/assets/favicon.ico'

const SETTINGS_PAGE_PATH = '/settings'
Expand All @@ -48,6 +49,7 @@ const Config = () => {
dispatch(fetchUnsupportedCliCommandsAction())
dispatch(fetchRedisCommandsInfo())
dispatch(fetchNotificationsAction())
dispatch(fetchContentRecommendations())

// get guides & tutorials
dispatch(fetchGuides())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
import { Pages } from 'uiSrc/constants'
import { RECOMMENDATIONS_DATA_MOCK } from 'uiSrc/mocks/handlers/recommendations/recommendationsHandler'
import { appContextDbConfig, setRecommendationsShowHidden } from 'uiSrc/slices/app/context'
import _content from 'uiSrc/constants/dbAnalysisRecommendations.json'
import { IRecommendationsStatic } from 'uiSrc/slices/interfaces/recommendations'
import { EXTERNAL_LINKS } from 'uiSrc/constants/links'
import { MOCK_RECOMMENDATIONS } from 'uiSrc/constants/mocks/mock-recommendations'

import LiveTimeRecommendations from './LiveTimeRecommendations'

const recommendationsContent = _content as IRecommendationsStatic

let store: typeof mockedStore
const recommendationsContent = MOCK_RECOMMENDATIONS

const mockRecommendationsSelector = jest.requireActual('uiSrc/slices/recommendations/recommendations')
const mockRecommendationsSelector = {
...jest.requireActual('uiSrc/slices/recommendations/recommendations'),
content: recommendationsContent,
}
const mockAppContextDbConfigSelector = jest.requireActual('uiSrc/slices/app/context')

jest.mock('uiSrc/slices/instances/instances', () => ({
Expand Down Expand Up @@ -190,7 +191,7 @@ describe('LiveTimeRecommendations', () => {
data: {
recommendations: [{ name: 'RTS' }],
},
isContentVisible: true
isContentVisible: true,
}))
const pushMock = jest.fn()
reactRouterDom.useHistory = jest.fn().mockReturnValue({ push: pushMock })
Expand Down Expand Up @@ -223,7 +224,7 @@ describe('LiveTimeRecommendations', () => {
data: {
recommendations: [],
},
isContentVisible: true
isContentVisible: true,
}))
render(<LiveTimeRecommendations />)
const afterRenderActions = [...store.getActions()]
Expand All @@ -241,7 +242,7 @@ describe('LiveTimeRecommendations', () => {
(recommendationsSelector as jest.Mock).mockImplementation(() => ({
...mockRecommendationsSelector,
isContentVisible: true,
data: RECOMMENDATIONS_DATA_MOCK
data: RECOMMENDATIONS_DATA_MOCK,
}))

const { queryByTestId } = render(<LiveTimeRecommendations />)
Expand All @@ -266,7 +267,7 @@ describe('LiveTimeRecommendations', () => {
(recommendationsSelector as jest.Mock).mockImplementation(() => ({
...mockRecommendationsSelector,
isContentVisible: true,
data: RECOMMENDATIONS_DATA_MOCK
data: RECOMMENDATIONS_DATA_MOCK,
}))
const { queryByTestId } = render(<LiveTimeRecommendations />)

Expand All @@ -278,7 +279,7 @@ describe('LiveTimeRecommendations', () => {
(recommendationsSelector as jest.Mock).mockImplementation(() => ({
...mockRecommendationsSelector,
isContentVisible: true,
data: RECOMMENDATIONS_DATA_MOCK
data: RECOMMENDATIONS_DATA_MOCK,
}));
(appContextDbConfig as jest.Mock).mockImplementation(() => ({
...mockAppContextDbConfigSelector,
Expand All @@ -294,7 +295,7 @@ describe('LiveTimeRecommendations', () => {
(recommendationsSelector as jest.Mock).mockImplementation(() => ({
...mockRecommendationsSelector,
isContentVisible: true,
data: RECOMMENDATIONS_DATA_MOCK
data: RECOMMENDATIONS_DATA_MOCK,
}));
(appContextDbConfig as jest.Mock).mockImplementation(() => ({
...mockAppContextDbConfigSelector,
Expand All @@ -317,7 +318,7 @@ describe('LiveTimeRecommendations', () => {
data: {
...RECOMMENDATIONS_DATA_MOCK,
recommendations: RECOMMENDATIONS_DATA_MOCK.recommendations.map((rec) => ({ ...rec, hide: true }))
}
},
}));
(appContextDbConfig as jest.Mock).mockImplementation(() => ({
...mockAppContextDbConfigSelector,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
import { workbenchGuidesSelector } from 'uiSrc/slices/workbench/wb-guides'

import { workbenchTutorialsSelector } from 'uiSrc/slices/workbench/wb-tutorials'
import { IRecommendation, IRecommendationsStatic } from 'uiSrc/slices/interfaces/recommendations'
import { IRecommendation } from 'uiSrc/slices/interfaces/recommendations'
import { appContextDbConfig, setRecommendationsShowHidden } from 'uiSrc/slices/app/context'
import { ConnectionType } from 'uiSrc/slices/interfaces'
import { createNewAnalysis } from 'uiSrc/slices/analytics/dbAnalysis'

import _content from 'uiSrc/constants/dbAnalysisRecommendations.json'
import { ReactComponent as TriggerIcon } from 'uiSrc/assets/img/bulb.svg'
import { ReactComponent as TriggerActiveIcon } from 'uiSrc/assets/img/bulb-active.svg'
import InfoIcon from 'uiSrc/assets/img/icons/help_illus.svg'
Expand All @@ -50,8 +49,6 @@ import WelcomeScreen from './components/welcome-screen'
import PopoverRunAnalyze from './components/popover-run-analyze'
import styles from './styles.module.scss'

const recommendationsContent = _content as IRecommendationsStatic

const DELAY_TO_SHOW_ONBOARDING_MS = 500

const LiveTimeRecommendations = () => {
Expand All @@ -61,6 +58,7 @@ const LiveTimeRecommendations = () => {
data: { recommendations, totalUnread },
isContentVisible,
isHighlighted,
content: recommendationsContent,
} = useSelector(recommendationsSelector)
const { items: guides } = useSelector(workbenchGuidesSelector)
const { items: tutorials } = useSelector(workbenchTutorialsSelector)
Expand Down Expand Up @@ -198,6 +196,7 @@ const LiveTimeRecommendations = () => {
tutorial={recommendationsContent[name]?.tutorial}
provider={provider}
params={params}
recommendationsContent={recommendationsContent}
/>
))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import { MOCK_GUIDES_ITEMS, MOCK_TUTORIALS_ITEMS, Pages } from 'uiSrc/constants'

import { updateRecommendation } from 'uiSrc/slices/recommendations/recommendations'
import { INSTANCE_ID_MOCK } from 'uiSrc/mocks/handlers/instances/instancesHandlers'
import { MOCK_RECOMMENDATIONS } from 'uiSrc/constants/mocks/mock-recommendations'
import Recommendation, { IProps } from './Recommendation'

const recommendationsContent = MOCK_RECOMMENDATIONS
const mockedProps = mock<IProps>()

const instanceMock = {
...instance(mockedProps),
recommendationsContent,
}

jest.mock('uiSrc/telemetry', () => ({
...jest.requireActual('uiSrc/telemetry'),
sendEventTelemetry: jest.fn(),
Expand All @@ -28,12 +35,14 @@ const PROVIDER = 'RE_CLOUD'

describe('Recommendation', () => {
it('should render', () => {
expect(render(<Recommendation {...instance(mockedProps)} />)).toBeTruthy()
expect(render(<Recommendation
{...instanceMock}
/>)).toBeTruthy()
})

it('should render content if recommendation is not read', () => {
render(<Recommendation
{...instance(mockedProps)}
{...instanceMock}
name="searchJSON"
tutorial=""
isRead={false}
Expand All @@ -44,7 +53,7 @@ describe('Recommendation', () => {
})

it('should render RecommendationVoting', () => {
const { container } = render(<Recommendation {...instance(mockedProps)} name="searchJSON" />)
const { container } = render(<Recommendation {...instanceMock} name="searchJSON" />)
fireEvent.click(container.querySelector('[data-test-subj="searchJSON-button"]') as HTMLButtonElement)
expect(screen.getByTestId('recommendation-voting')).toBeInTheDocument()
})
Expand All @@ -56,7 +65,7 @@ describe('Recommendation', () => {

const { container } = render(
<Recommendation
{...instance(mockedProps)}
{...instanceMock}
isRead={false}
name="searchJSON"
tutorial=""
Expand Down Expand Up @@ -86,7 +95,7 @@ describe('Recommendation', () => {

const { container } = render(
<Recommendation
{...instance(mockedProps)}
{...instanceMock}
isRead={false}
name="searchJSON"
tutorial="quick-guides/working-with-hash.html"
Expand Down Expand Up @@ -118,7 +127,7 @@ describe('Recommendation', () => {

const { container } = render(
<Recommendation
{...instance(mockedProps)}
{...instanceMock}
isRead={false}
name="searchJSON"
tutorial="/redis_stack/working_with_json.md"
Expand All @@ -145,7 +154,7 @@ describe('Recommendation', () => {

it('should render hide/unhide button', () => {
const name = 'searchJSON'
render(<Recommendation {...instance(mockedProps)} name={name} />)
render(<Recommendation {...instanceMock} name={name} />)

expect(screen.getByTestId('toggle-hide-searchJSON-btn')).toBeInTheDocument()
})
Expand All @@ -155,7 +164,7 @@ describe('Recommendation', () => {
const nameMock = 'searchJSON'
const { queryByTestId } = render(
<Recommendation
{...instance(mockedProps)}
{...instanceMock}
id={idMock}
name={nameMock}
/>
Expand All @@ -173,28 +182,28 @@ describe('Recommendation', () => {

it('should not render "Tutorial" btn if tutorial is Undefined', () => {
const name = 'searchJSON'
const { queryByTestId } = render(<Recommendation {...instance(mockedProps)} name={name} tutorial={undefined} />)
const { queryByTestId } = render(<Recommendation {...instanceMock} name={name} tutorial={undefined} />)

expect(queryByTestId(`${name}-to-tutorial-btn`)).not.toBeInTheDocument()
})

it('should render "Tutorial" if tutorial="path"', () => {
const name = 'searchJSON'
const { queryByTestId } = render(<Recommendation {...instance(mockedProps)} name={name} tutorial="path" />)
const { queryByTestId } = render(<Recommendation {...instanceMock} name={name} tutorial="path" />)

expect(queryByTestId(`${name}-to-tutorial-btn`)).toHaveTextContent('Tutorial')
})

it('should render "Workbench" btn if tutorial=""', () => {
const name = 'searchJSON'
const { queryByTestId } = render(<Recommendation {...instance(mockedProps)} name={name} tutorial="" />)
const { queryByTestId } = render(<Recommendation {...instanceMock} name={name} tutorial="" />)

expect(queryByTestId(`${name}-to-tutorial-btn`)).toHaveTextContent('Workbench')
})

it('should render Snooze button', () => {
const name = 'searchJSON'
render(<Recommendation {...instance(mockedProps)} name={name} />)
render(<Recommendation {...instanceMock} name={name} />)

expect(screen.getByTestId(`${name}-delete-btn`)).toBeInTheDocument()
})
Expand All @@ -204,7 +213,7 @@ describe('Recommendation', () => {
const nameMock = 'searchJSON'
const { queryByTestId } = render(
<Recommendation
{...instance(mockedProps)}
{...instanceMock}
id={idMock}
name={nameMock}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import { EXTERNAL_LINKS } from 'uiSrc/constants/links'
import { IEnablementAreaItem } from 'uiSrc/slices/interfaces'
import { IRecommendationsStatic, IRecommendationParams } from 'uiSrc/slices/interfaces/recommendations'

import _content from 'uiSrc/constants/dbAnalysisRecommendations.json'
import RediStackDarkMin from 'uiSrc/assets/img/modules/redistack/RediStackDark-min.svg'
import RediStackLightMin from 'uiSrc/assets/img/modules/redistack/RediStackLight-min.svg'
import { ReactComponent as SnoozeIcon } from 'uiSrc/assets/img/icons/snooze.svg'
Expand All @@ -46,10 +45,9 @@ export interface IProps {
tutorial?: string
provider?: string
params: IRecommendationParams
recommendationsContent: IRecommendationsStatic
}

const recommendationsContent = _content as IRecommendationsStatic

const Recommendation = ({
id,
name,
Expand All @@ -61,6 +59,7 @@ const Recommendation = ({
hide,
provider,
params,
recommendationsContent,
}: IProps) => {
const [isLoading, setIsLoading] = useState(false)
const history = useHistory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ import {
import { EXTERNAL_LINKS } from 'uiSrc/constants/links'
import { Vote } from 'uiSrc/constants/recommendations'
import { putRecommendationVote } from 'uiSrc/slices/analytics/dbAnalysis'
import { IRecommendationsStatic } from 'uiSrc/slices/interfaces/recommendations'
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
import _content from 'uiSrc/constants/dbAnalysisRecommendations.json'
import { updateLiveRecommendation } from 'uiSrc/slices/recommendations/recommendations'
import { recommendationsSelector, updateLiveRecommendation } from 'uiSrc/slices/recommendations/recommendations'
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
import { Nullable } from 'uiSrc/utils'
import PetardIcon from 'uiSrc/assets/img/icons/petard.svg'
Expand All @@ -38,8 +36,6 @@ export interface Props {
name: string
}

const recommendationsContent = _content as IRecommendationsStatic

const VoteOption = (props: Props) => {
const {
voteOption,
Expand All @@ -54,6 +50,7 @@ const VoteOption = (props: Props) => {

const dispatch = useDispatch()
const { id: instanceId = '', provider } = useSelector(connectedInstanceSelector)
const { content: recommendationsContent } = useSelector(recommendationsSelector)

const onSuccessVoted = ({ vote, name }: { name: string, vote: Nullable<Vote> }) => {
sendEventTelemetry({
Expand Down
1 change: 1 addition & 0 deletions redisinsight/ui/src/constants/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ enum ApiEndpoints {
PLUGINS = 'plugins',
STATE = 'state',
CONTENT_CREATE_DATABASE = 'static/content/create-redis.json',
CONTENT_RECOMMENDATIONS = 'static/content/recommendations.json',
GUIDES_PATH = 'static/guides',
TUTORIALS_PATH = 'static/tutorials',
CUSTOM_TUTORIALS_PATH = 'static/custom-tutorials',
Expand Down
Loading