mirror of https://github.com/harness/drone.git
chore: [AH-612]: add test cases for Registry Artifact list (#2965)
* fix: [AH-612]: fix reg_identifier value and test case * chore: [AH-612]: fix repository test case * chore: [AH-612]: add test cases for Registry Artifact list * fix: [AH-636]: fix clearing of filterspull/3586/head
parent
0f4df14661
commit
7704d86db1
|
@ -79,7 +79,7 @@ function ArtifactListPage(): JSX.Element {
|
||||||
search_term: searchTerm,
|
search_term: searchTerm,
|
||||||
sort_field: sortField,
|
sort_field: sortField,
|
||||||
sort_order: sortOrder,
|
sort_order: sortOrder,
|
||||||
reg_identifier: repositoryKey ? [repositoryKey] : undefined,
|
reg_identifier: repositoryKey,
|
||||||
latest_version: latestVersion,
|
latest_version: latestVersion,
|
||||||
deployed_artifact: isDeployedArtifacts,
|
deployed_artifact: isDeployedArtifacts,
|
||||||
package_type: packageTypes,
|
package_type: packageTypes,
|
||||||
|
@ -93,14 +93,17 @@ function ArtifactListPage(): JSX.Element {
|
||||||
const handleClearAllFilters = (): void => {
|
const handleClearAllFilters = (): void => {
|
||||||
flushSync(searchRef.current.clear)
|
flushSync(searchRef.current.clear)
|
||||||
updateQueryParams({
|
updateQueryParams({
|
||||||
page: 0,
|
page: undefined,
|
||||||
searchTerm: '',
|
searchTerm: undefined,
|
||||||
isDeployedArtifacts: false,
|
isDeployedArtifacts: undefined,
|
||||||
latestVersion: false
|
latestVersion: undefined,
|
||||||
|
packageTypes: undefined,
|
||||||
|
repositoryKey: undefined
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasFilter = !!searchTerm || isDeployedArtifacts || latestVersion
|
const hasFilter =
|
||||||
|
!!searchTerm || isDeployedArtifacts || latestVersion || repositoryKey?.length || packageTypes?.length
|
||||||
const responseData = data?.content?.data
|
const responseData = data?.content?.data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -78,10 +78,10 @@ function RegistryArtifactListPage({ pageBodyClassName }: RegistryArtifactListPag
|
||||||
const handleClearAllFilters = (): void => {
|
const handleClearAllFilters = (): void => {
|
||||||
flushSync(searchRef.current.clear)
|
flushSync(searchRef.current.clear)
|
||||||
updateQueryParams({
|
updateQueryParams({
|
||||||
page: 0,
|
page: undefined,
|
||||||
searchTerm: '',
|
searchTerm: undefined,
|
||||||
packageTypes: [],
|
packageTypes: undefined,
|
||||||
isDeployedArtifacts: false
|
isDeployedArtifacts: undefined
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ function RegistryArtifactListPage({ pageBodyClassName }: RegistryArtifactListPag
|
||||||
[labels]
|
[labels]
|
||||||
)
|
)
|
||||||
|
|
||||||
const hasFilter = !!searchTerm || packageTypes.length || isDeployedArtifacts
|
const hasFilter = !!searchTerm || packageTypes?.length || isDeployedArtifacts
|
||||||
const responseData = data?.content?.data
|
const responseData = data?.content?.data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -0,0 +1,352 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Harness, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import { fireEvent, render, waitFor } from '@testing-library/react'
|
||||||
|
import userEvent from '@testing-library/user-event'
|
||||||
|
import {
|
||||||
|
useGetAllHarnessArtifactsQuery as _useGetAllHarnessArtifactsQuery,
|
||||||
|
getAllRegistries as _getAllRegistries
|
||||||
|
} from '@harnessio/react-har-service-client'
|
||||||
|
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||||
|
import repositoryFactory from '@ar/frameworks/RepositoryStep/RepositoryFactory'
|
||||||
|
import { DockerRepositoryType } from '@ar/pages/repository-details/DockerRepository/DockerRepositoryType'
|
||||||
|
import { HelmRepositoryType } from '@ar/pages/repository-details/HelmRepository/HelmRepositoryType'
|
||||||
|
import ArtifactListPage from '../ArtifactListPage'
|
||||||
|
import {
|
||||||
|
mockGetAllRegistriesResponse,
|
||||||
|
mockEmptyGetAllRegistriesResponse,
|
||||||
|
mockEmptyUseGetAllHarnessArtifactsQueryResponse,
|
||||||
|
mockUseGetAllHarnessArtifactsQueryResponse,
|
||||||
|
mockErrorUseGetAllHarnessArtifactsQueryResponse
|
||||||
|
} from './__mockData__'
|
||||||
|
|
||||||
|
const useGetAllHarnessArtifactsQuery = _useGetAllHarnessArtifactsQuery as jest.Mock
|
||||||
|
const getAllRegistries = _getAllRegistries as jest.Mock
|
||||||
|
|
||||||
|
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||||
|
useGetAllHarnessArtifactsQuery: jest.fn(),
|
||||||
|
getAllRegistries: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('Test Artifact List Page', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
repositoryFactory.registerStep(new DockerRepositoryType())
|
||||||
|
repositoryFactory.registerStep(new HelmRepositoryType())
|
||||||
|
|
||||||
|
useGetAllHarnessArtifactsQuery.mockImplementation(() => {
|
||||||
|
return mockUseGetAllHarnessArtifactsQueryResponse
|
||||||
|
})
|
||||||
|
getAllRegistries.mockImplementation(() => new Promise(resolve => resolve(mockGetAllRegistriesResponse)))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should render proper empty list if artifacts reponse is empty', async () => {
|
||||||
|
useGetAllHarnessArtifactsQuery.mockImplementationOnce(() => mockEmptyUseGetAllHarnessArtifactsQueryResponse)
|
||||||
|
getAllRegistries.mockImplementationOnce(() => new Promise(resolve => resolve(mockEmptyGetAllRegistriesResponse)))
|
||||||
|
|
||||||
|
const { container, getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
const noItemsText = getByText('artifactList.table.noArtifactsTitle')
|
||||||
|
expect(noItemsText).toBeInTheDocument()
|
||||||
|
|
||||||
|
const noItemsIcon = container.querySelector('[data-icon="store-artifact-bundle"]')
|
||||||
|
expect(noItemsIcon).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should render artifacts list', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const table = container.querySelector('[class*="TableV2--table"]')
|
||||||
|
expect(table).toBeInTheDocument()
|
||||||
|
|
||||||
|
const rows = container.querySelectorAll('[class*="TableV2--row"]')
|
||||||
|
expect(rows).toHaveLength(3)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should show error message if listing api fails', async () => {
|
||||||
|
const mockRefetchFn = jest.fn().mockImplementation(() => undefined)
|
||||||
|
useGetAllHarnessArtifactsQuery.mockImplementationOnce(() => {
|
||||||
|
return {
|
||||||
|
...mockErrorUseGetAllHarnessArtifactsQueryResponse,
|
||||||
|
refetch: mockRefetchFn
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const errorText = getByText('error message')
|
||||||
|
expect(errorText).toBeInTheDocument()
|
||||||
|
|
||||||
|
const retryBtn = getByText('Retry')
|
||||||
|
expect(retryBtn).toBeInTheDocument()
|
||||||
|
|
||||||
|
await userEvent.click(retryBtn)
|
||||||
|
expect(mockRefetchFn).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Search, Registeries, Package Types and Latest Versions filter should work', async () => {
|
||||||
|
const { getByTestId, getByText, getByPlaceholderText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const registriesSelect = getByTestId('regitry-select')
|
||||||
|
await userEvent.click(registriesSelect)
|
||||||
|
const registryIdOption = getByText('repo1')
|
||||||
|
await userEvent.click(registryIdOption)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: ['repo1'],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const packageTypeSelect = getByTestId('package-type-select')
|
||||||
|
await userEvent.click(packageTypeSelect)
|
||||||
|
const packageTypeOption = getByText('repositoryTypes.docker')
|
||||||
|
await userEvent.click(packageTypeOption)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: ['repo1'],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: ['DOCKER'],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const searchInput = getByPlaceholderText('search')
|
||||||
|
expect(searchInput).toBeInTheDocument()
|
||||||
|
fireEvent.change(searchInput!, { target: { value: '1234' } })
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: ['repo1'],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: ['DOCKER'],
|
||||||
|
search_term: '1234',
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
useGetAllHarnessArtifactsQuery.mockImplementationOnce(() => mockEmptyUseGetAllHarnessArtifactsQueryResponse)
|
||||||
|
getAllRegistries.mockImplementationOnce(() => new Promise(resolve => resolve(mockEmptyGetAllRegistriesResponse)))
|
||||||
|
|
||||||
|
const latestVersionTab = getByText('artifactList.table.latestVersions')
|
||||||
|
await userEvent.click(latestVersionTab)
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: ['repo1'],
|
||||||
|
latest_version: true,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: ['DOCKER'],
|
||||||
|
search_term: '1234',
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const clearAllFiltersBtn = getByText('clearFilters')
|
||||||
|
await userEvent.click(clearAllFiltersBtn)
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Sorting should work', async () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const artifactNameSortIcon = getByText('artifactList.table.columns.artifactName').nextSibling
|
||||||
|
?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(artifactNameSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'name',
|
||||||
|
sort_order: 'ASC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const downloadsSortIcon = getByText('artifactList.table.columns.downloads').nextSibling?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(downloadsSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'downloadsCount',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const lastUpdatedSortIcon = getByText('artifactList.table.columns.lastUpdated').nextSibling
|
||||||
|
?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(lastUpdatedSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'lastUpdated',
|
||||||
|
sort_order: 'ASC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Pagination should work', async () => {
|
||||||
|
const { getByText, getByTestId } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<ArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const nextPageBtn = getByText('Next')
|
||||||
|
await userEvent.click(nextPageBtn)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 1,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageSizeSelect = getByTestId('dropdown-button')
|
||||||
|
await userEvent.click(pageSizeSelect)
|
||||||
|
const pageSize20option = getByText('20')
|
||||||
|
await userEvent.click(pageSize20option)
|
||||||
|
|
||||||
|
expect(useGetAllHarnessArtifactsQuery).toHaveBeenLastCalledWith({
|
||||||
|
space_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 20,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC',
|
||||||
|
reg_identifier: [],
|
||||||
|
latest_version: false,
|
||||||
|
deployed_artifact: false,
|
||||||
|
package_type: [],
|
||||||
|
label: []
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Harness, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import userEvent from '@testing-library/user-event'
|
||||||
|
import { useGetAllArtifactsByRegistryQuery as _useGetAllArtifactsByRegistryQuery } from '@harnessio/react-har-service-client'
|
||||||
|
import { fireEvent, render, waitFor } from '@testing-library/react'
|
||||||
|
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||||
|
import {
|
||||||
|
mockUseGetAllArtifactsByRegistryQuery,
|
||||||
|
mockEmptyUseGetAllArtifactsByRegistryQuery,
|
||||||
|
mockErrorUseGetAllHarnessArtifactsQueryResponse
|
||||||
|
} from './__mockData__'
|
||||||
|
import RegistryArtifactListPage from '../RegistryArtifactListPage'
|
||||||
|
|
||||||
|
const useGetAllArtifactsByRegistryQuery = _useGetAllArtifactsByRegistryQuery as jest.Mock
|
||||||
|
|
||||||
|
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||||
|
useGetAllArtifactsByRegistryQuery: jest.fn(),
|
||||||
|
useGetArtifactSummaryQuery: jest.fn()
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('Test Registry Artifact List Page', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
useGetAllArtifactsByRegistryQuery.mockImplementation(() => mockUseGetAllArtifactsByRegistryQuery)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should render empty list if artifacts response is empty', () => {
|
||||||
|
useGetAllArtifactsByRegistryQuery.mockImplementationOnce(() => mockEmptyUseGetAllArtifactsByRegistryQuery)
|
||||||
|
const { getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
const noResultsText = getByText('artifactList.table.noArtifactsTitle')
|
||||||
|
expect(noResultsText).toBeInTheDocument()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should render artifacts list', () => {
|
||||||
|
const { container } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
const table = container.querySelector('[class*="TableV2--table"]')
|
||||||
|
expect(table).toBeInTheDocument()
|
||||||
|
|
||||||
|
const tableRows = container.querySelectorAll('[class*="TableV2--row"]')
|
||||||
|
expect(tableRows).toHaveLength(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should show error message if listing api fails', async () => {
|
||||||
|
const mockRefetchFn = jest.fn().mockImplementation()
|
||||||
|
useGetAllArtifactsByRegistryQuery.mockImplementationOnce(() => {
|
||||||
|
return {
|
||||||
|
...mockErrorUseGetAllHarnessArtifactsQueryResponse,
|
||||||
|
refetch: mockRefetchFn
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const { getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const errorText = getByText('error message')
|
||||||
|
expect(errorText).toBeInTheDocument()
|
||||||
|
|
||||||
|
const retryBtn = getByText('Retry')
|
||||||
|
expect(retryBtn).toBeInTheDocument()
|
||||||
|
await userEvent.click(retryBtn)
|
||||||
|
expect(mockRefetchFn).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Should be able to search', async () => {
|
||||||
|
const { getByText, getByPlaceholderText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
useGetAllArtifactsByRegistryQuery.mockImplementationOnce(() => mockEmptyUseGetAllArtifactsByRegistryQuery)
|
||||||
|
|
||||||
|
const searchInput = getByPlaceholderText('search')
|
||||||
|
expect(searchInput).toBeInTheDocument()
|
||||||
|
|
||||||
|
fireEvent.change(searchInput, { target: { value: 'pod' } })
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
search_term: 'pod',
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const clearAllFiltersBtn = getByText('clearFilters')
|
||||||
|
await userEvent.click(clearAllFiltersBtn)
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Sorting should work', async () => {
|
||||||
|
const { getByText } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const artifactNameSortIcon = getByText('artifactList.table.columns.name').nextSibling?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(artifactNameSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'name',
|
||||||
|
sort_order: 'ASC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const repositorySortIcon = getByText('artifactList.table.columns.repository').nextSibling?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(repositorySortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'registryIdentifier',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const downloadsSortIcon = getByText('artifactList.table.columns.downloads').nextSibling?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(downloadsSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'downloadsCount',
|
||||||
|
sort_order: 'ASC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const lastUpdatedSortIcon = getByText('artifactList.table.columns.latestVersion').nextSibling
|
||||||
|
?.firstChild as HTMLElement
|
||||||
|
await userEvent.click(lastUpdatedSortIcon)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'latestVersion',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Pagination should work', async () => {
|
||||||
|
const { getByText, getByTestId } = render(
|
||||||
|
<ArTestWrapper>
|
||||||
|
<RegistryArtifactListPage />
|
||||||
|
</ArTestWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
const nextPageBtn = getByText('Next')
|
||||||
|
await userEvent.click(nextPageBtn)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 1,
|
||||||
|
size: 50,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageSizeSelect = getByTestId('dropdown-button')
|
||||||
|
await userEvent.click(pageSizeSelect)
|
||||||
|
const pageSize20option = getByText('20')
|
||||||
|
await userEvent.click(pageSize20option)
|
||||||
|
|
||||||
|
expect(useGetAllArtifactsByRegistryQuery).toHaveBeenLastCalledWith({
|
||||||
|
registry_ref: 'undefined/+',
|
||||||
|
queryParams: {
|
||||||
|
page: 0,
|
||||||
|
size: 20,
|
||||||
|
sort_field: 'updatedAt',
|
||||||
|
sort_order: 'DESC'
|
||||||
|
},
|
||||||
|
stringifyQueryParamsOptions: { arrayFormat: 'repeat' }
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Harness, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { GetAllRegistriesOkResponse } from '@harnessio/react-har-service-client'
|
||||||
|
|
||||||
|
export const mockEmptyUseGetAllHarnessArtifactsQueryResponse = {
|
||||||
|
isFetching: false,
|
||||||
|
data: {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
artifacts: [],
|
||||||
|
itemCount: 0,
|
||||||
|
pageCount: 0,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 50
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockErrorUseGetAllHarnessArtifactsQueryResponse = {
|
||||||
|
isFetching: false,
|
||||||
|
data: null,
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: {
|
||||||
|
message: 'error message'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockEmptyGetAllRegistriesResponse: GetAllRegistriesOkResponse = {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
itemCount: 0,
|
||||||
|
pageCount: 0,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 0,
|
||||||
|
registries: []
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockUseGetAllHarnessArtifactsQueryResponse = {
|
||||||
|
isFetching: false,
|
||||||
|
data: {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
artifacts: [
|
||||||
|
{
|
||||||
|
deploymentMetadata: {
|
||||||
|
nonProdEnvCount: 0,
|
||||||
|
prodEnvCount: 0
|
||||||
|
},
|
||||||
|
downloadsCount: 0,
|
||||||
|
labels: null,
|
||||||
|
lastModified: '1730978736333',
|
||||||
|
latestVersion: '',
|
||||||
|
name: 'podinfo-artifact',
|
||||||
|
packageType: 'DOCKER',
|
||||||
|
pullCommand: 'docker pull pkg.qa.harness.io/iwr-f_zp7q/repo1/podinfo-artifact:1.0.0',
|
||||||
|
registryIdentifier: 'repo1',
|
||||||
|
registryPath: '',
|
||||||
|
version: '1.0.0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deploymentMetadata: {
|
||||||
|
nonProdEnvCount: 0,
|
||||||
|
prodEnvCount: 0
|
||||||
|
},
|
||||||
|
downloadsCount: 0,
|
||||||
|
labels: null,
|
||||||
|
lastModified: '1729862063842',
|
||||||
|
latestVersion: '',
|
||||||
|
name: 'production',
|
||||||
|
packageType: 'HELM',
|
||||||
|
pullCommand: 'helm install pkg.qa.harness.io/iwr-f_zp7q/repo2/production:1.0.15',
|
||||||
|
registryIdentifier: 'repo2',
|
||||||
|
registryPath: '',
|
||||||
|
scannedDigest: [],
|
||||||
|
version: '1.0.15'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deploymentMetadata: {
|
||||||
|
nonProdEnvCount: 0,
|
||||||
|
prodEnvCount: 0
|
||||||
|
},
|
||||||
|
downloadsCount: 2,
|
||||||
|
labels: null,
|
||||||
|
lastModified: '1729861854693',
|
||||||
|
latestVersion: '',
|
||||||
|
name: 'harness-delegate-ng',
|
||||||
|
packageType: 'HELM',
|
||||||
|
pullCommand: 'helm install pkg.qa.harness.io/iwr-f_zp7q/upstream_1/harness-delegate-ng:1.0.15',
|
||||||
|
registryIdentifier: 'upstream_1',
|
||||||
|
registryPath: '',
|
||||||
|
scannedDigest: [],
|
||||||
|
version: '1.0.15'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
itemCount: 3,
|
||||||
|
pageCount: 2,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 50
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockGetAllRegistriesResponse: GetAllRegistriesOkResponse = {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
registries: [
|
||||||
|
{
|
||||||
|
identifier: 'repo1',
|
||||||
|
packageType: 'DOCKER',
|
||||||
|
type: 'VIRTUAL',
|
||||||
|
url: 'space/repo1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
identifier: 'repo2',
|
||||||
|
packageType: 'DOCKER',
|
||||||
|
description: 'Test Discription',
|
||||||
|
labels: ['label1', 'label2', 'label2'],
|
||||||
|
type: 'VIRTUAL',
|
||||||
|
url: 'space/repo1',
|
||||||
|
downloadsCount: 100,
|
||||||
|
registrySize: '100 MB',
|
||||||
|
artifactsCount: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
identifier: 'upstream_1',
|
||||||
|
packageType: 'DOCKER',
|
||||||
|
type: 'UPSTREAM',
|
||||||
|
url: 'space/upstream_1'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
itemCount: 3,
|
||||||
|
pageCount: 10,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 10
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockEmptyUseGetAllArtifactsByRegistryQuery = {
|
||||||
|
isFetching: false,
|
||||||
|
data: {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
artifacts: [],
|
||||||
|
itemCount: 0,
|
||||||
|
pageCount: 0,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 50
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockErrorUseGetAllArtifactsByRegistryQuery = {
|
||||||
|
isFetching: false,
|
||||||
|
data: null,
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: {
|
||||||
|
message: 'error message'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockUseGetAllArtifactsByRegistryQuery = {
|
||||||
|
isFetching: false,
|
||||||
|
data: {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
artifacts: [
|
||||||
|
{
|
||||||
|
deploymentMetadata: {
|
||||||
|
nonProdEnvCount: 0,
|
||||||
|
prodEnvCount: 0
|
||||||
|
},
|
||||||
|
downloadsCount: 0,
|
||||||
|
labels: null,
|
||||||
|
lastModified: '1730978736333',
|
||||||
|
latestVersion: '',
|
||||||
|
name: 'podinfo-artifact',
|
||||||
|
packageType: 'DOCKER',
|
||||||
|
pullCommand: 'docker pull pkg.qa.harness.io/iwr-f_zp7q/repo1/podinfo-artifact:1.0.0',
|
||||||
|
registryIdentifier: 'repo1',
|
||||||
|
registryPath: '',
|
||||||
|
version: '1.0.0'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
itemCount: 1,
|
||||||
|
pageCount: 2,
|
||||||
|
pageIndex: 0,
|
||||||
|
pageSize: 50
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mockUseGetArtifactSummaryQueryResponse = {
|
||||||
|
isFetching: false,
|
||||||
|
data: {
|
||||||
|
content: {
|
||||||
|
data: {
|
||||||
|
createdAt: '1729861185934',
|
||||||
|
downloadsCount: 0,
|
||||||
|
imageName: 'harness-delegate-ng',
|
||||||
|
labels: null,
|
||||||
|
modifiedAt: '1729861854693',
|
||||||
|
packageType: 'HELM'
|
||||||
|
},
|
||||||
|
status: 'SUCCESS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refetch: jest.fn(),
|
||||||
|
error: null
|
||||||
|
}
|
|
@ -81,13 +81,14 @@ function RepositoryListPage(): JSX.Element {
|
||||||
const handleClearFilters = (): void => {
|
const handleClearFilters = (): void => {
|
||||||
flushSync(searchRef.current.clear)
|
flushSync(searchRef.current.clear)
|
||||||
updateQueryParams({
|
updateQueryParams({
|
||||||
page: 0,
|
page: undefined,
|
||||||
searchTerm: '',
|
searchTerm: undefined,
|
||||||
repositoryTypes: []
|
repositoryTypes: undefined,
|
||||||
|
configType: undefined
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasFilter = !!searchTerm || repositoryTypes.length
|
const hasFilter = !!searchTerm || repositoryTypes?.length || configType?.length
|
||||||
|
|
||||||
const responseData = data?.content.data
|
const responseData = data?.content.data
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,6 @@ describe('Test Registry List Page', () => {
|
||||||
queryParams: {
|
queryParams: {
|
||||||
package_type: [],
|
package_type: [],
|
||||||
page: 0,
|
page: 0,
|
||||||
search_term: '',
|
|
||||||
size: 50,
|
size: 50,
|
||||||
sort_field: 'updatedAt',
|
sort_field: 'updatedAt',
|
||||||
sort_order: 'DESC'
|
sort_order: 'DESC'
|
||||||
|
|
Loading…
Reference in New Issue