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
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ import { render, screen, fireEvent } from 'uiSrc/utils/test-utils'

import RedisInsightLink from './RedisInsightLink'

jest.mock('uiSrc/utils/routing', () => ({
...jest.requireActual('uiSrc/utils/routing')
}))

Object.defineProperty(window, 'location', {
value: {
origin: 'http://localhost'
},
writable: true
})

describe('RedisInsightLink', () => {
it('should render', () => {
expect(render(<RedisInsightLink url="/" text="label" />)).toBeTruthy()
Expand All @@ -13,11 +24,10 @@ describe('RedisInsightLink', () => {
const pushMock = jest.fn()
reactRouterDom.useHistory = jest.fn().mockReturnValue({ push: pushMock })

// getRedirectionPage is mocked and already has tests
render(<RedisInsightLink url="/" text="label" />)
render(<RedisInsightLink url="/settings" text="label" />)

fireEvent.click(screen.getByTestId('redisinsight-link'))

expect(pushMock).toHaveBeenCalledWith('/')
expect(pushMock).toHaveBeenCalledWith('/settings')
})
})
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useState } from 'react'
import { EuiLink, EuiPopover } from '@elastic/eui'
import { useHistory, useParams } from 'react-router-dom'
import { useHistory, useLocation, useParams } from 'react-router-dom'
import cx from 'classnames'
import { isNull } from 'lodash'
import { getRedirectionPage } from 'uiSrc/utils/routing'
import DatabaseNotOpened from 'uiSrc/components/messages/database-not-opened'

Expand All @@ -18,22 +19,20 @@ const RedisInsightLink = (props: Props) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false)
const { instanceId } = useParams<{ instanceId: string }>()
const history = useHistory()
const location = useLocation()

const handleLinkClick = (e: React.MouseEvent) => {
e.preventDefault()

if (!instanceId) {
setIsPopoverOpen(true)
return
}

const href = getRedirectionPage(url, instanceId)
const href = getRedirectionPage(url, instanceId, location.pathname)
if (href) {
history.push(href)
return
}

history.push('/')
if (isNull(href)) {
setIsPopoverOpen(true)
}
}

return (
Expand Down
3 changes: 3 additions & 0 deletions redisinsight/ui/src/services/resourcesService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const resourcesService = axios.create({
baseURL: RESOURCES_BASE_URL,
})

// TODO: it seems it's shoudn't be location.origin
// TODO: check all cases and rename this to getResourcesUrl
// TODO: also might be helpful create function which returns origin url
export const getOriginUrl = () => (IS_ABSOLUTE_PATH.test(RESOURCES_BASE_URL)
? RESOURCES_BASE_URL
: (window?.location?.origin || RESOURCES_BASE_URL))
Expand Down
21 changes: 16 additions & 5 deletions redisinsight/ui/src/utils/routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { IRoute } from 'uiSrc/constants'
import { Maybe, Nullable } from 'uiSrc/utils'
import DEFAULT_ROUTES from 'uiSrc/components/main-router/constants/defaultRoutes'

const CURRENT_PAGE_URL_SYNTAX = '/_'

export const findRouteByPathname = (routes: IRoute[], pathname: string): Maybe<IRoute> => {
let findRoute

Expand All @@ -22,18 +24,27 @@ export const findRouteByPathname = (routes: IRoute[], pathname: string): Maybe<I
return findRoute
}

export const getRedirectionPage = (pageInput: string, databaseId?: string): Nullable<string> => {
// undefined - route was not found
// null - route found but private
export const getRedirectionPage = (
pageInput: string,
databaseId?: string,
currentPathname?: string
): Nullable<Maybe<string>> => {
let page = pageInput.replace(/^\//, '')
try {
const pageUrl = new URL(page, window.location.origin)
const { pathname, searchParams } = pageUrl
const { pathname, searchParams } = new URL(page, window.location.origin)

if (currentPathname && pathname === CURRENT_PAGE_URL_SYNTAX) {
return `${currentPathname}?${searchParams.toString()}`
}

if (searchParams.has('guidePath') || searchParams.has('tutorialId')) {
page += '&insights=open'
}

const foundRoute = findRouteByPathname(DEFAULT_ROUTES, pathname)
if (!foundRoute) return null
if (!foundRoute) return undefined

if (foundRoute.path.includes(':instanceId')) {
if (databaseId) {
Expand All @@ -44,7 +55,7 @@ export const getRedirectionPage = (pageInput: string, databaseId?: string): Null

return `/${page}`
} catch (_e) {
return `/${page}`
return undefined
}
}

Expand Down
13 changes: 12 additions & 1 deletion redisinsight/ui/src/utils/tests/routing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ jest.mock('uiSrc/utils/routing', () => ({
...jest.requireActual('uiSrc/utils/routing')
}))

Object.defineProperty(window, 'location', {
value: {
origin: 'http://localhost'
},
writable: true
})

const databaseId = '1'
const getRedirectionPageTests = [
{ input: ['settings'], expected: '/settings' },
Expand All @@ -12,8 +19,12 @@ const getRedirectionPageTests = [
{ input: ['/analytics/slowlog', databaseId], expected: '/1/analytics/slowlog' },
{ input: ['/analytics/slowlog'], expected: null },
{ input: ['/analytics', databaseId], expected: '/1/analytics' },
{ input: ['/analytics/page', databaseId], expected: null },
{ input: ['/analytics/page', databaseId], expected: undefined },
{ input: ['/analytics'], expected: null },
{ input: ['some-page'], expected: undefined },
{ input: ['/workbench?guidePath=introduction.md', databaseId], expected: '/1/workbench?guidePath=introduction.md&insights=open' },
{ input: ['/_?tutorialId=tutorial'], expected: undefined },
{ input: ['/_?tutorialId=tutorial', databaseId, `/${databaseId}/workbench`], expected: '/1/workbench?tutorialId=tutorial' },
]

describe('getRedirectionPage', () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export enum ResourcePath {
}

export enum ExploreTabs {
Explore = 'Explore',
Tutorials = 'Tutorials',
Tips = 'Tips',
}

Expand Down
1 change: 1 addition & 0 deletions tests/e2e/pageObjects/components/explore-tab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class ExploreTab {
uploadDataBulkBtn = Selector('[data-testid=upload-data-bulk-btn]');
uploadDataBulkApplyBtn = Selector('[data-testid=upload-data-bulk-apply-btn]');
downloadFileBtn = Selector('[data-testid=download-redis-upload-file]');
tutorialLink = Selector('[data-testid=redisinsight-link]');

//CSS
cssTutorialDeleteIcon = '[data-testid^=delete-tutorial-icon-]';
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/pageObjects/components/insights-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export class InsightsPanel {
* Click on Panel tab
* @param type of the tab
*/
async setActiveTab(type: ExploreTabs.Explore): Promise<ExploreTab>
async setActiveTab(type: ExploreTabs.Tutorials): Promise<ExploreTab>
async setActiveTab(type: ExploreTabs.Tips): Promise<RecommendationsTab>
async setActiveTab(type: ExploreTabs): Promise<ExploreTab | RecommendationsTab> {
const activeTabName = await this.getActiveTabName();
if(type === ExploreTabs.Explore) {
if(type === ExploreTabs.Tutorials) {
if(type !== activeTabName) {
await t.click(this.exploreTab);
}
Expand Down
9 changes: 5 additions & 4 deletions tests/e2e/pageObjects/memory-efficiency-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class MemoryEfficiencyPage extends InstancePage {
selectedReport = Selector('[data-testid=select-report]');
sortByLength = Selector('[data-testid=btn-change-table-keys]');
recommendationsTab = Selector('[data-testid=Recommendations-tab]');
veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0);
usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0);
notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0);
recommendationsFeedbackBtn = Selector('[data-testid=recommendation-feedback-btn]');
// ICONS
reportTooltipIcon = Selector('[data-testid=db-new-reports-icon]');
// TEXT ELEMENTS
Expand Down Expand Up @@ -56,10 +60,7 @@ export class MemoryEfficiencyPage extends InstancePage {
readMoreLink = Selector('[data-testid=read-more-link]');
workbenchLink = Selector('[data-test-subj=workbench-page-btn]');
// CONTAINERS
veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0);
usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0);
notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0);
recommendationsFeedbackBtn = Selector('[data-testid=recommendation-feedback-btn]');
analysisPage = Selector('[data-testid=database-analysis-page]');

/**
* Get recommendation selector by name
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
In very broad terms probabilistic data structures (PDS) allow us to get to a "close enough" result in a much shorter time and by using significantly less memory.
In very broad terms probabilistic data structures (PDS) allow us to get to a "close enough" result in a much shorter time and by using significantly less memory.

[linkTheSamePage](redisinsight:_?tutorialId=ds-json-create)

[link2AnalyticsPageWithTutorial](redisinsight:analytics/database-analysis?tutorialId=ds-json-intro)

[link3InvalidPage](redisinsight:invalidPage?tutorialId=ds-json-intro)

[link4InvalidTutorial](redisinsight:invalidPage?tutorialId=invalid-tutorial)

[link5JustAnalyticsPage](redisinsight:analytics/database-analysis)

[link6JustTheSamePage](redisinsight:_)
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ if (fs.existsSync(workingDirectory)) {

// Check Enablement area and validate that removed file is existed in Guides
await workbenchPage.InsightsPanel.togglePanel(true);
const tab = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tab = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.click(tab.guidesGraphAccordion);
await t.click(tab.guidesIntroductionGraphLink.nth(1));
await t.expect(tab.enablementAreaEmptyContent.visible).notOk('Guides folder is not updated');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fixture `Redis Stack command in Workbench`
test.skip('Verify that user can switches between Graph and Text for GRAPH command and see results corresponding to their views', async t => {
// Send Graph command
await workbenchPage.InsightsPanel.togglePanel(true);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.click(tutorials.redisStackTutorialsButton);
await t.click(tutorials.tutorialsWorkingWithGraphLink);
await tutorials.runBlockCode('Create a bike node');
Expand All @@ -46,7 +46,7 @@ test.skip('Verify that user can switches between Graph and Text for GRAPH comman
test.skip('Verify that user can see "No data to visualize" message for Graph command', async t => {
// Send Graph command
await workbenchPage.InsightsPanel.togglePanel(true);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.click(tutorials.redisStackTutorialsButton);
await tutorials.runBlockCode('Show all sales per region');
await t.click(workbenchPage.submitCommandButton);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ test
}
//Run Create hash index command to load network and memory
await clusterDetailsPage.InsightsPanel.togglePanel(true);
const tutorials = await clusterDetailsPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tutorials = await clusterDetailsPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);

await t.click(tutorials.dataStructureAccordionTutorialButton);
await t.click(tutorials.internalLinkWorkingWithHashes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ test
await t.expect(browserPage.OverviewPanel.overviewCpu.exists).ok('CPU (%) is dispalyed in the Overview');
//Run Create hash index command
await browserPage.InsightsPanel.togglePanel(true);
const tutorials = await browserPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tutorials = await browserPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.click(tutorials.dataStructureAccordionTutorialButton);
await t.click(tutorials.internalLinkWorkingWithHashes);
await tutorials.runBlockCode('Create a hash');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ test.skip
// Verify that tutorial opened
await t.click(memoryEfficiencyPage.getToTutorialBtnByRecomName(searchJsonRecommendation));
await workbenchPage.InsightsPanel.togglePanel(true);
await t.expect(await workbenchPage.InsightsPanel.getActiveTabName()).eql(ExploreTabs.Explore);
const tutorial = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
await t.expect(await workbenchPage.InsightsPanel.getActiveTabName()).eql(ExploreTabs.Tutorials);
const tutorial = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.expect(tutorial.preselectArea.visible).ok('Workbench Enablement area not opened');
// Verify that REDIS FOR TIME SERIES tutorial expanded
await t.expect(tutorial.getTutorialByName('INTRODUCTION').visible).ok('INTRODUCTION tutorial is not expanded');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ test
await t.navigateTo(generateLink(connectUrlParams));
await t.wait(10_000);
await t.expect(workbenchPage.submitCommandButton.exists).ok('Redirection to Workbench is not correct');
const tab = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tab = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.expect(tab.preselectArea.textContent).contains('INTRODUCTION', 'the tutorial page is incorrect');
await t.expect(tab.preselectArea.textContent).contains('JSON', 'the tutorial is incorrect');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ test
await workbenchPage.sendCommandInWorkbench(commandsForSend.join('\n'));
// Run automatically added "FT._LIST" and "FT.INFO {index}" scripts
await workbenchPage.InsightsPanel.togglePanel(true);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Explore);
const tutorials = await workbenchPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
await t.click(tutorials.dataStructureAccordionTutorialButton);
await t.click(tutorials.internalLinkWorkingWithHashes);

Expand Down
Loading