mirror of https://github.com/harness/drone.git
feat: [AH-916]: upstream proxy edit tests (#3404)
* feat: [AH-916]: upstream proxy edit tests * feat: [AH-916]: refactor upstream proxy create tests * feat: [AH-916]: add unit tests for create upstream proxy flowpull/3616/head
parent
12796dc321
commit
4250c0554a
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* 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 { render, screen, waitFor } from '@testing-library/react'
|
||||
import type { Registry } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { Parent } from '@ar/common/types'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
import RepositoryListPage from '@ar/pages/repository-list/RepositoryListPage'
|
||||
|
||||
import { MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData } from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
import '../../RepositoryFactory'
|
||||
|
||||
const createRegistryFn = jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData))
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
const mockHistoryPush = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetAllRegistriesQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
data: { content: { data: { registries: [] }, status: 'SUCCESS' } },
|
||||
refetch: jest.fn(),
|
||||
error: null
|
||||
})),
|
||||
useCreateRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
mutateAsync: createRegistryFn
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify create docker upstream registry flow', () => {
|
||||
test('Verify Modal header', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const modal = await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogHeader = screen.getByTestId('modaldialog-header')
|
||||
expect(dialogHeader).toHaveTextContent('upstreamProxyDetails.createForm.title')
|
||||
|
||||
const closeButton = modal.querySelector('button[aria-label="Close"]')
|
||||
expect(closeButton).toBeInTheDocument()
|
||||
await userEvent.click(closeButton!)
|
||||
|
||||
expect(modal).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('verify registry type selector', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as DockerHub > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'Dockerhub', 'Anonymous')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: { auth: null, authType: 'Anonymous', source: 'Dockerhub', type: 'UPSTREAM', url: '' },
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as DockerHub > Username Password', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'Dockerhub', 'UserPassword')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as AWS ECR > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'AwsEcr', 'Anonymous')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: { auth: null, authType: 'Anonymous', source: 'AwsEcr', type: 'UPSTREAM', url: 'https://aws.ecr.com' },
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as AWS ECR > Access Key and Secret Key', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'AwsEcr', 'AccessKeySecretKey')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeyType: 'TEXT',
|
||||
secretKeyIdentifier: 'secretKey',
|
||||
authType: 'AccessKeySecretKey'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as Custom > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'Custom', 'Anonymous')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify docker registry create form with success scenario > Source as Custom > Username Password', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'DOCKER')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(dialogBody, formData, 'Custom', 'UserPassword')
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
packageType: 'DOCKER',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/docker-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,533 @@
|
|||
/*
|
||||
* 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 { fireEvent, getByTestId, render, waitFor } from '@testing-library/react'
|
||||
|
||||
import { DEFAULT_DATE_TIME_FORMAT } from '@ar/constants'
|
||||
import { getReadableDateTime } from '@ar/common/dateUtils'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
import { Parent, RepositoryPackageType } from '@ar/common/types'
|
||||
import repositoryFactory from '@ar/frameworks/RepositoryStep/RepositoryFactory'
|
||||
|
||||
import { queryByNameAttribute } from 'utils/test/testUtils'
|
||||
import RepositoryDetailsPage from '../../RepositoryDetailsPage'
|
||||
import {
|
||||
MockGetArtifactsByRegistryResponse,
|
||||
MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData
|
||||
} from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
|
||||
const modifyRepository = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise(onSuccess => {
|
||||
onSuccess({ content: { status: 'SUCCESS' } })
|
||||
})
|
||||
)
|
||||
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
const mockHistoryPush = jest.fn()
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData
|
||||
})),
|
||||
useGetAllArtifactsByRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetArtifactsByRegistryResponse
|
||||
})),
|
||||
useDeleteRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: jest.fn()
|
||||
})),
|
||||
useModifyRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: modifyRepository
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify header section for docker artifact registry', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('Verify breadcrumbs', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const pageHeader = container.querySelector('div[data-testid=page-header]')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
const breadcrumbsSection = pageHeader?.querySelector('div[class*=PageHeader--breadcrumbsDiv--]')
|
||||
expect(breadcrumbsSection).toBeInTheDocument()
|
||||
|
||||
expect(breadcrumbsSection).toHaveTextContent('breadcrumbs.repositories')
|
||||
})
|
||||
|
||||
test('Verify registry icon, registry name, tag, lables, description and last updated', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
expect(pageHeader?.querySelector('span[data-icon=docker-step]')).toBeInTheDocument()
|
||||
const data = MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data
|
||||
|
||||
expect(pageHeader).toHaveTextContent(data.identifier)
|
||||
|
||||
expect(pageHeader).toHaveTextContent(getReadableDateTime(Number(data.modifiedAt), DEFAULT_DATE_TIME_FORMAT))
|
||||
})
|
||||
|
||||
test('Verify registry setup client action not visible', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const setupClientBtn = pageHeader.querySelector('button[aria-label="actions.setupClient"]')
|
||||
expect(setupClientBtn).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Verify other registry actions', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const actions3DotsBtn = pageHeader.querySelector('span[data-icon=Options')
|
||||
expect(actions3DotsBtn).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(actions3DotsBtn!)
|
||||
const dialogs = document.getElementsByClassName('bp3-popover')
|
||||
await waitFor(() => expect(dialogs).toHaveLength(1))
|
||||
const selectPopover = dialogs[0] as HTMLElement
|
||||
|
||||
const items = selectPopover.getElementsByClassName('bp3-menu-item')
|
||||
for (let idx = 0; idx < items.length; idx++) {
|
||||
const actionItem = items[idx]
|
||||
expect(actionItem.querySelector('span[data-icon=code-delete]')).toBeInTheDocument()
|
||||
expect(actionItem).toHaveTextContent('actions.delete')
|
||||
}
|
||||
})
|
||||
|
||||
test('Verify tab selection status', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper
|
||||
path="/registries/:repositoryIdentifier/:tab"
|
||||
pathParams={{ repositoryIdentifier: 'abcd', tab: 'packages' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const tabList = container.querySelector('div[role=tablist]')
|
||||
expect(tabList).toBeInTheDocument()
|
||||
|
||||
const artifactsTab = tabList?.querySelector('div[data-tab-id=packages][aria-selected=true]')
|
||||
expect(artifactsTab).toBeInTheDocument()
|
||||
|
||||
const configurationTab = tabList?.querySelector('div[data-tab-id=configuration][aria-selected=false]')
|
||||
expect(configurationTab).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(configurationTab!)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/abcd/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Verify configuration form', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('should render form correctly with all data prefilled', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
// Artifact registry defination section
|
||||
const registryDefinitionSection = getByTestId(container, 'upstream-registry-definition')
|
||||
const nameField = queryByNameAttribute('identifier', registryDefinitionSection)
|
||||
expect(nameField).toBeInTheDocument()
|
||||
expect(nameField).toBeDisabled()
|
||||
expect(nameField).toHaveAttribute(
|
||||
'value',
|
||||
MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data.identifier
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', registryDefinitionSection)
|
||||
expect(descriptionField).toBeInTheDocument()
|
||||
expect(descriptionField).not.toBeDisabled()
|
||||
expect(descriptionField).toHaveTextContent(
|
||||
MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data.description
|
||||
)
|
||||
|
||||
const tags = registryDefinitionSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
tags.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data.labels[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// verify source selection
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
const sourceSection = sourceAuthSection.querySelector('input[type=radio][name="config.source"][value=Dockerhub]')
|
||||
expect(sourceSection).toBeChecked()
|
||||
expect(sourceSection).not.toBeDisabled()
|
||||
|
||||
// verify auth type selection
|
||||
const authTypeSelection = sourceAuthSection.querySelector(
|
||||
'input[type=radio][name="config.authType"][value=Anonymous]'
|
||||
)
|
||||
expect(authTypeSelection).toBeChecked()
|
||||
expect(authTypeSelection).not.toBeDisabled()
|
||||
|
||||
// Security scan section
|
||||
const securityScanSection = getByTestId(container, 'security-scan-section')
|
||||
expect(securityScanSection).toBeInTheDocument()
|
||||
|
||||
const checkboxes = securityScanSection.querySelectorAll('label.bp3-control.bp3-checkbox')
|
||||
const supportedScanners =
|
||||
repositoryFactory.getRepositoryType(RepositoryPackageType.DOCKER)?.getSupportedScanners() || []
|
||||
|
||||
checkboxes.forEach((each, idx) => {
|
||||
const ele = each.querySelector(`input[value=${supportedScanners[idx]}][type=checkbox]`)
|
||||
expect(ele).toBeInTheDocument()
|
||||
expect(ele).toBeChecked()
|
||||
expect(ele).toBeDisabled()
|
||||
})
|
||||
|
||||
// artifact filtering rules
|
||||
const filteringRulesSection = getByTestId(container, 'include-exclude-patterns-section')
|
||||
expect(filteringRulesSection).toBeInTheDocument()
|
||||
|
||||
const blockedPatternsSection = filteringRulesSection.querySelectorAll('div.bp3-form-group')[1]
|
||||
const blockedPatterns = blockedPatternsSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
blockedPatterns.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data.blockedPattern[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// cleanup policy section
|
||||
const cleanupPoliciesSection = getByTestId(container, 'cleanup-policy-section')
|
||||
expect(cleanupPoliciesSection).toBeInTheDocument()
|
||||
const addCleanupPolicyBtn = cleanupPoliciesSection.querySelector(
|
||||
'a[role=button][aria-label="cleanupPolicy.addBtn"]'
|
||||
)
|
||||
expect(addCleanupPolicyBtn).toBeInTheDocument()
|
||||
expect(addCleanupPolicyBtn).toHaveAttribute('disabled', '')
|
||||
|
||||
// action buttons
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).toBeDisabled()
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Success Scenario', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.updateSuccessMessage'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('Verify source and auth section with multiple scenarios', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS} path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
|
||||
// verify Dockerhub, UserPassword
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Dockerhub',
|
||||
'UserPassword',
|
||||
'Dockerhub',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify AwsEcr, Anonymous
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'AwsEcr',
|
||||
'Anonymous',
|
||||
'Dockerhub',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify AwsEcr, AccessKeySecretKey
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'AwsEcr',
|
||||
'AccessKeySecretKey',
|
||||
'Dockerhub',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeyType: 'TEXT',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify Custom, Anonymous
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Custom',
|
||||
'Anonymous',
|
||||
'Dockerhub',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify Custom, UserPassword
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Custom',
|
||||
'UserPassword',
|
||||
'Dockerhub',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Failure Scenario', async () => {
|
||||
modifyRepository.mockImplementationOnce(
|
||||
() =>
|
||||
new Promise((_, onReject) => {
|
||||
onReject({ message: 'error message' })
|
||||
})
|
||||
)
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showErrorToast).toHaveBeenLastCalledWith('error message')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -120,3 +120,26 @@ export const MockGetSetupClientOnRegistryConfigPageResponse = {
|
|||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
||||
export const MockGetDockerUpstreamRegistryResponseWithDockerhubSourceAllData = {
|
||||
content: {
|
||||
data: {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
identifier: 'docker-up-repo',
|
||||
description: 'test description',
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
url: ''
|
||||
},
|
||||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* 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 { render, screen, waitFor } from '@testing-library/react'
|
||||
import type { Registry } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { Parent } from '@ar/common/types'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
import RepositoryListPage from '@ar/pages/repository-list/RepositoryListPage'
|
||||
|
||||
import { MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData } from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
import '../../RepositoryFactory'
|
||||
|
||||
const createRegistryFn = jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData))
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
const mockHistoryPush = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetAllRegistriesQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
data: { content: { data: { registries: [] }, status: 'SUCCESS' } },
|
||||
refetch: jest.fn(),
|
||||
error: null
|
||||
})),
|
||||
useCreateRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
mutateAsync: createRegistryFn
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify create helm upstream registry flow', () => {
|
||||
test('Verify Modal header', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const modal = await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogHeader = screen.getByTestId('modaldialog-header')
|
||||
expect(dialogHeader).toHaveTextContent('upstreamProxyDetails.createForm.title')
|
||||
|
||||
const closeButton = modal.querySelector('button[aria-label="Close"]')
|
||||
expect(closeButton).toBeInTheDocument()
|
||||
await userEvent.click(closeButton!)
|
||||
|
||||
expect(modal).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('verify registry type selector', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'HELM')
|
||||
})
|
||||
|
||||
test('verify helm registry create form with success scenario > Source as Custom > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'HELM')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'Custom',
|
||||
'Anonymous',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
packageType: 'HELM',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/helm-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify helm registry create form with success scenario > Source as Custom > Username Password', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'HELM')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'Custom',
|
||||
'UserPassword',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
packageType: 'HELM',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/helm-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify helm registry create form with success scenario > Source as AWS ECR > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'HELM')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'AwsEcr',
|
||||
'Anonymous',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: { auth: null, authType: 'Anonymous', source: 'AwsEcr', type: 'UPSTREAM', url: 'https://aws.ecr.com' },
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
packageType: 'HELM',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/helm-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify helm registry create form with success scenario > Source as AWS ECR > Access Key and Secret Key', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'HELM')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'AwsEcr',
|
||||
'AccessKeySecretKey',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeyType: 'TEXT',
|
||||
secretKeyIdentifier: 'secretKey',
|
||||
authType: 'AccessKeySecretKey'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
packageType: 'HELM',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/helm-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,460 @@
|
|||
/*
|
||||
* 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 { fireEvent, getByTestId, queryByTestId, render, waitFor } from '@testing-library/react'
|
||||
|
||||
import { Parent } from '@ar/common/types'
|
||||
import { DEFAULT_DATE_TIME_FORMAT } from '@ar/constants'
|
||||
import { getReadableDateTime } from '@ar/common/dateUtils'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
|
||||
import { queryByNameAttribute } from 'utils/test/testUtils'
|
||||
import RepositoryDetailsPage from '../../RepositoryDetailsPage'
|
||||
import {
|
||||
MockGetHelmArtifactsByRegistryResponse,
|
||||
MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData
|
||||
} from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
|
||||
const modifyRepository = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise(onSuccess => {
|
||||
onSuccess({ content: { status: 'SUCCESS' } })
|
||||
})
|
||||
)
|
||||
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
const mockHistoryPush = jest.fn()
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData
|
||||
})),
|
||||
useGetAllArtifactsByRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetHelmArtifactsByRegistryResponse
|
||||
})),
|
||||
useDeleteRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: jest.fn()
|
||||
})),
|
||||
useModifyRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: modifyRepository
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify header section for docker artifact registry', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('Verify breadcrumbs', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const pageHeader = container.querySelector('div[data-testid=page-header]')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
const breadcrumbsSection = pageHeader?.querySelector('div[class*=PageHeader--breadcrumbsDiv--]')
|
||||
expect(breadcrumbsSection).toBeInTheDocument()
|
||||
|
||||
expect(breadcrumbsSection).toHaveTextContent('breadcrumbs.repositories')
|
||||
})
|
||||
|
||||
test('Verify registry icon, registry name, tag, lables, description and last updated', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
expect(pageHeader?.querySelector('span[data-icon=service-helm]')).toBeInTheDocument()
|
||||
const data = MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data
|
||||
|
||||
expect(pageHeader).toHaveTextContent(data.identifier)
|
||||
|
||||
expect(pageHeader).toHaveTextContent(getReadableDateTime(Number(data.modifiedAt), DEFAULT_DATE_TIME_FORMAT))
|
||||
})
|
||||
|
||||
test('Verify registry setup client action not visible', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const setupClientBtn = pageHeader.querySelector('button[aria-label="actions.setupClient"]')
|
||||
expect(setupClientBtn).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Verify other registry actions', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const actions3DotsBtn = pageHeader.querySelector('span[data-icon=Options')
|
||||
expect(actions3DotsBtn).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(actions3DotsBtn!)
|
||||
const dialogs = document.getElementsByClassName('bp3-popover')
|
||||
await waitFor(() => expect(dialogs).toHaveLength(1))
|
||||
const selectPopover = dialogs[0] as HTMLElement
|
||||
|
||||
const items = selectPopover.getElementsByClassName('bp3-menu-item')
|
||||
for (let idx = 0; idx < items.length; idx++) {
|
||||
const actionItem = items[idx]
|
||||
expect(actionItem.querySelector('span[data-icon=code-delete]')).toBeInTheDocument()
|
||||
expect(actionItem).toHaveTextContent('actions.delete')
|
||||
}
|
||||
})
|
||||
|
||||
test('Verify tab selection status', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper
|
||||
path="/registries/:repositoryIdentifier/:tab"
|
||||
pathParams={{ repositoryIdentifier: 'abcd', tab: 'packages' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const tabList = container.querySelector('div[role=tablist]')
|
||||
expect(tabList).toBeInTheDocument()
|
||||
|
||||
const artifactsTab = tabList?.querySelector('div[data-tab-id=packages][aria-selected=true]')
|
||||
expect(artifactsTab).toBeInTheDocument()
|
||||
|
||||
const configurationTab = tabList?.querySelector('div[data-tab-id=configuration][aria-selected=false]')
|
||||
expect(configurationTab).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(configurationTab!)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/abcd/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Verify configuration form', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('should render form correctly with all data prefilled', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
// Artifact registry defination section
|
||||
const registryDefinitionSection = getByTestId(container, 'upstream-registry-definition')
|
||||
const nameField = queryByNameAttribute('identifier', registryDefinitionSection)
|
||||
expect(nameField).toBeInTheDocument()
|
||||
expect(nameField).toBeDisabled()
|
||||
expect(nameField).toHaveAttribute(
|
||||
'value',
|
||||
MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data.identifier
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', registryDefinitionSection)
|
||||
expect(descriptionField).toBeInTheDocument()
|
||||
expect(descriptionField).not.toBeDisabled()
|
||||
expect(descriptionField).toHaveTextContent(
|
||||
MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data.description
|
||||
)
|
||||
|
||||
const tags = registryDefinitionSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
tags.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data.labels[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// verify source selection
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
const sourceSection = sourceAuthSection.querySelector('input[type=radio][name="config.source"][value=Custom]')
|
||||
expect(sourceSection).toBeChecked()
|
||||
expect(sourceSection).not.toBeDisabled()
|
||||
|
||||
// verify auth type selection
|
||||
const authTypeSelection = sourceAuthSection.querySelector(
|
||||
'input[type=radio][name="config.authType"][value=Anonymous]'
|
||||
)
|
||||
expect(authTypeSelection).toBeChecked()
|
||||
expect(authTypeSelection).not.toBeDisabled()
|
||||
|
||||
// Security scan section
|
||||
const securityScanSection = queryByTestId(container, 'security-scan-section')
|
||||
expect(securityScanSection).not.toBeInTheDocument()
|
||||
|
||||
// artifact filtering rules
|
||||
const filteringRulesSection = getByTestId(container, 'include-exclude-patterns-section')
|
||||
expect(filteringRulesSection).toBeInTheDocument()
|
||||
|
||||
const allowedPatternsSection = filteringRulesSection.querySelectorAll('div.bp3-form-group')[0]
|
||||
const allowedPatterns = allowedPatternsSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
allowedPatterns.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data.allowedPattern[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// cleanup policy section
|
||||
const cleanupPoliciesSection = getByTestId(container, 'cleanup-policy-section')
|
||||
expect(cleanupPoliciesSection).toBeInTheDocument()
|
||||
const addCleanupPolicyBtn = cleanupPoliciesSection.querySelector(
|
||||
'a[role=button][aria-label="cleanupPolicy.addBtn"]'
|
||||
)
|
||||
expect(addCleanupPolicyBtn).toBeInTheDocument()
|
||||
expect(addCleanupPolicyBtn).toHaveAttribute('disabled', '')
|
||||
|
||||
// action buttons
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).toBeDisabled()
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Success Scenario', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
let sourceSection = sourceAuthSection.querySelector('input[type=radio][name="config.authType"][value=UserPassword]')
|
||||
await userEvent.click(sourceSection!)
|
||||
sourceSection = sourceAuthSection.querySelector('input[type=radio][name="config.authType"][value=Anonymous]')
|
||||
await userEvent.click(sourceSection!)
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.updateSuccessMessage'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('Verify source and auth section with multiple scenarios', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS} path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
|
||||
// verify Custom, UserPassword
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Custom',
|
||||
'UserPassword',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'HELM',
|
||||
cleanupPolicy: [],
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify AwsEcr, Anonymous
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'AwsEcr',
|
||||
'Anonymous',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'HELM',
|
||||
cleanupPolicy: [],
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify AwsEcr, AccessKeySecretKey
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'AwsEcr',
|
||||
'AccessKeySecretKey',
|
||||
'Custom',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeyType: 'TEXT',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'helm-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'HELM',
|
||||
cleanupPolicy: [],
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Failure Scenario', async () => {
|
||||
modifyRepository.mockImplementationOnce(
|
||||
() =>
|
||||
new Promise((_, onReject) => {
|
||||
onReject({ message: 'error message' })
|
||||
})
|
||||
)
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showErrorToast).toHaveBeenLastCalledWith('error message')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -110,3 +110,27 @@ export const MockGetHelmSetupClientOnRegistryConfigPageResponse = {
|
|||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
||||
export const MockGetHelmUpstreamRegistryResponseWithCustomSourceAllData = {
|
||||
content: {
|
||||
data: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
identifier: 'helm-up-repo',
|
||||
description: 'test description',
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'HELM',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
url: ''
|
||||
},
|
||||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,318 @@
|
|||
/*
|
||||
* 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 { render, screen, waitFor } from '@testing-library/react'
|
||||
import type { Registry } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { Parent } from '@ar/common/types'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
import RepositoryListPage from '@ar/pages/repository-list/RepositoryListPage'
|
||||
|
||||
import { MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData } from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
import '../../RepositoryFactory'
|
||||
|
||||
const createRegistryFn = jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData))
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
const mockHistoryPush = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetAllRegistriesQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
data: { content: { data: { registries: [] }, status: 'SUCCESS' } },
|
||||
refetch: jest.fn(),
|
||||
error: null
|
||||
})),
|
||||
useCreateRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
mutateAsync: createRegistryFn
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify create maven upstream registry flow', () => {
|
||||
test('Verify Modal header', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const modal = await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogHeader = screen.getByTestId('modaldialog-header')
|
||||
expect(dialogHeader).toHaveTextContent('upstreamProxyDetails.createForm.title')
|
||||
|
||||
const closeButton = modal.querySelector('button[aria-label="Close"]')
|
||||
expect(closeButton).toBeInTheDocument()
|
||||
await userEvent.click(closeButton!)
|
||||
|
||||
expect(modal).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('verify registry type selector', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'MAVEN')
|
||||
})
|
||||
|
||||
test('verify maven registry create form with success scenario > Source as MavenCentral > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'MAVEN')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'MavenCentral',
|
||||
'Anonymous',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: { auth: null, authType: 'Anonymous', source: 'MavenCentral', type: 'UPSTREAM', url: '' },
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
packageType: 'MAVEN',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/maven-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify maven registry create form with success scenario > Source as Maven Central > UserPassword', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'MAVEN')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'MavenCentral',
|
||||
'UserPassword',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'MavenCentral',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
packageType: 'MAVEN',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/maven-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify maven registry create form with success scenario > Source as Custom > Anonymous', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'MAVEN')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'Custom',
|
||||
'Anonymous',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
packageType: 'MAVEN',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/maven-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
test('verify maven registry create form with success scenario > Source as Custom > Username Password', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryListPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
await upstreamProxyUtils.openModal(container)
|
||||
|
||||
const dialogBody = screen.getByTestId('modaldialog-body')
|
||||
expect(dialogBody).toBeInTheDocument()
|
||||
|
||||
await upstreamProxyUtils.verifyPackageTypeSelector(dialogBody, 'MAVEN')
|
||||
|
||||
expect(dialogBody).toHaveTextContent('upstreamProxyDetails.form.title')
|
||||
|
||||
const formData = MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data as Registry
|
||||
|
||||
await upstreamProxyUtils.verifyUpstreamProxyCreateForm(
|
||||
dialogBody,
|
||||
formData,
|
||||
'Custom',
|
||||
'UserPassword',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
const createButton = await upstreamProxyUtils.getSubmitButton()
|
||||
await userEvent.click(createButton!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createRegistryFn).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
packageType: 'MAVEN',
|
||||
parentRef: 'undefined',
|
||||
scanners: []
|
||||
},
|
||||
queryParams: { space_ref: 'undefined' }
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.createSuccessMessage'
|
||||
)
|
||||
expect(mockHistoryPush).toHaveBeenLastCalledWith('/registries/maven-up-repo/configuration')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -0,0 +1,543 @@
|
|||
/*
|
||||
* 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 { fireEvent, getByTestId, queryByTestId, render, waitFor } from '@testing-library/react'
|
||||
|
||||
import { Parent } from '@ar/common/types'
|
||||
import ArTestWrapper from '@ar/utils/testUtils/ArTestWrapper'
|
||||
|
||||
import { queryByNameAttribute } from 'utils/test/testUtils'
|
||||
import RepositoryDetailsPage from '../../RepositoryDetailsPage'
|
||||
import {
|
||||
MockGetMavenArtifactsByRegistryResponse,
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData
|
||||
} from './__mockData__'
|
||||
import upstreamProxyUtils from '../../__tests__/utils'
|
||||
|
||||
const modifyRepository = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise(onSuccess => {
|
||||
onSuccess({ content: { status: 'SUCCESS' } })
|
||||
})
|
||||
)
|
||||
|
||||
const deleteRegistry = jest.fn().mockImplementation(
|
||||
() =>
|
||||
new Promise(onSuccess => {
|
||||
onSuccess({ content: { status: 'SUCCESS' } })
|
||||
})
|
||||
)
|
||||
|
||||
const showSuccessToast = jest.fn()
|
||||
const showErrorToast = jest.fn()
|
||||
|
||||
jest.mock('@harnessio/uicore', () => ({
|
||||
...jest.requireActual('@harnessio/uicore'),
|
||||
useToaster: jest.fn().mockImplementation(() => ({
|
||||
showSuccess: showSuccessToast,
|
||||
showError: showErrorToast,
|
||||
clear: jest.fn()
|
||||
}))
|
||||
}))
|
||||
|
||||
const mockHistoryPush = jest.fn()
|
||||
// eslint-disable-next-line jest-no-mock
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush
|
||||
})
|
||||
}))
|
||||
|
||||
jest.mock('@harnessio/react-har-service-client', () => ({
|
||||
useGetRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData
|
||||
})),
|
||||
useGetAllArtifactsByRegistryQuery: jest.fn().mockImplementation(() => ({
|
||||
isFetching: false,
|
||||
refetch: jest.fn(),
|
||||
error: false,
|
||||
data: MockGetMavenArtifactsByRegistryResponse
|
||||
})),
|
||||
useDeleteRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: deleteRegistry
|
||||
})),
|
||||
useModifyRegistryMutation: jest.fn().mockImplementation(() => ({
|
||||
isLoading: false,
|
||||
mutateAsync: modifyRepository
|
||||
}))
|
||||
}))
|
||||
|
||||
describe('Verify header section for docker artifact registry', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('Verify breadcrumbs', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const pageHeader = container.querySelector('div[data-testid=page-header]')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
const breadcrumbsSection = pageHeader?.querySelector('div[class*=PageHeader--breadcrumbsDiv--]')
|
||||
expect(breadcrumbsSection).toBeInTheDocument()
|
||||
|
||||
expect(breadcrumbsSection).toHaveTextContent('breadcrumbs.repositories')
|
||||
})
|
||||
|
||||
test('Verify registry icon, registry name, tag, lables, description and last updated', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
expect(pageHeader).toBeInTheDocument()
|
||||
|
||||
expect(pageHeader?.querySelector('span[data-icon=maven-repository-type]')).toBeInTheDocument()
|
||||
const data = MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data
|
||||
|
||||
expect(pageHeader).toHaveTextContent(data.identifier)
|
||||
|
||||
expect(pageHeader).toHaveTextContent('na')
|
||||
})
|
||||
|
||||
test('Verify registry setup client action not visible', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const setupClientBtn = pageHeader.querySelector('button[aria-label="actions.setupClient"]')
|
||||
expect(setupClientBtn).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Verify other registry actions', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const actions3DotsBtn = pageHeader.querySelector('span[data-icon=Options')
|
||||
expect(actions3DotsBtn).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(actions3DotsBtn!)
|
||||
const dialogs = document.getElementsByClassName('bp3-popover')
|
||||
await waitFor(() => expect(dialogs).toHaveLength(1))
|
||||
const selectPopover = dialogs[0] as HTMLElement
|
||||
|
||||
const items = selectPopover.getElementsByClassName('bp3-menu-item')
|
||||
for (let idx = 0; idx < items.length; idx++) {
|
||||
const actionItem = items[idx]
|
||||
expect(actionItem.querySelector('span[data-icon=code-delete]')).toBeInTheDocument()
|
||||
expect(actionItem).toHaveTextContent('actions.delete')
|
||||
}
|
||||
})
|
||||
|
||||
test('verify delete action: Success', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const actions3DotsBtn = pageHeader.querySelector('span[data-icon=Options')
|
||||
expect(actions3DotsBtn).toBeInTheDocument()
|
||||
await userEvent.click(actions3DotsBtn!)
|
||||
const selectPopover = document.getElementsByClassName('bp3-popover')[0] as HTMLElement
|
||||
|
||||
const items = selectPopover.getElementsByClassName('bp3-menu-item')
|
||||
const actionItem = items[0]
|
||||
expect(actionItem.querySelector('span[data-icon=code-delete]')).toBeInTheDocument()
|
||||
expect(actionItem).toHaveTextContent('actions.delete')
|
||||
|
||||
await userEvent.click(actionItem)
|
||||
let deleteDialog = document.getElementsByClassName('bp3-dialog')[0]
|
||||
expect(deleteDialog).toBeInTheDocument()
|
||||
expect(deleteDialog).toHaveTextContent('upstreamProxyDetails.actions.delete.title')
|
||||
expect(deleteDialog).toHaveTextContent('upstreamProxyDetails.actions.delete.contentText')
|
||||
|
||||
const cancelButton = deleteDialog.querySelector('button[aria-label=cancel]')
|
||||
expect(cancelButton).toBeInTheDocument()
|
||||
await userEvent.click(cancelButton!)
|
||||
expect(deleteDialog).not.toBeInTheDocument()
|
||||
|
||||
await userEvent.click(actionItem!)
|
||||
deleteDialog = document.getElementsByClassName('bp3-dialog')[0]
|
||||
expect(deleteDialog).toBeInTheDocument()
|
||||
const deleteBtn = deleteDialog.querySelector('button[aria-label=delete]')
|
||||
expect(deleteBtn).toBeInTheDocument()
|
||||
await userEvent.click(deleteBtn!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(deleteRegistry).toHaveBeenLastCalledWith({ registry_ref: 'undefined/maven-up-repo/+' })
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries')
|
||||
expect(showSuccessToast).toHaveBeenCalledWith('upstreamProxyDetails.actions.delete.repositoryDeleted')
|
||||
})
|
||||
expect(deleteDialog).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('verify delete action: Failure', async () => {
|
||||
deleteRegistry.mockImplementationOnce(
|
||||
() =>
|
||||
new Promise((_, onReject) => {
|
||||
onReject({ message: 'error message' })
|
||||
})
|
||||
)
|
||||
const { container } = render(
|
||||
<ArTestWrapper>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
const pageHeader = getByTestId(container, 'upstream-registry-header-container')
|
||||
const actions3DotsBtn = pageHeader.querySelector('span[data-icon=Options')
|
||||
expect(actions3DotsBtn).toBeInTheDocument()
|
||||
await userEvent.click(actions3DotsBtn!)
|
||||
const selectPopover = document.getElementsByClassName('bp3-popover')[0] as HTMLElement
|
||||
|
||||
const items = selectPopover.getElementsByClassName('bp3-menu-item')
|
||||
const actionItem = items[0]
|
||||
expect(actionItem.querySelector('span[data-icon=code-delete]')).toBeInTheDocument()
|
||||
expect(actionItem).toHaveTextContent('actions.delete')
|
||||
|
||||
await userEvent.click(actionItem)
|
||||
const deleteDialog = document.getElementsByClassName('bp3-dialog')[0]
|
||||
expect(deleteDialog).toBeInTheDocument()
|
||||
expect(deleteDialog).toHaveTextContent('upstreamProxyDetails.actions.delete.title')
|
||||
expect(deleteDialog).toHaveTextContent('upstreamProxyDetails.actions.delete.contentText')
|
||||
|
||||
const deleteBtn = deleteDialog.querySelector('button[aria-label=delete]')
|
||||
expect(deleteBtn).toBeInTheDocument()
|
||||
await userEvent.click(deleteBtn!)
|
||||
|
||||
await waitFor(() => {
|
||||
expect(deleteRegistry).toHaveBeenLastCalledWith({ registry_ref: 'undefined/maven-up-repo/+' })
|
||||
expect(mockHistoryPush).not.toHaveBeenCalledWith('/registries')
|
||||
expect(showErrorToast).toHaveBeenLastCalledWith('error message')
|
||||
})
|
||||
expect(deleteDialog).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('Verify tab selection status', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper
|
||||
path="/registries/:repositoryIdentifier/:tab"
|
||||
pathParams={{ repositoryIdentifier: 'abcd', tab: 'packages' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const tabList = container.querySelector('div[role=tablist]')
|
||||
expect(tabList).toBeInTheDocument()
|
||||
|
||||
const artifactsTab = tabList?.querySelector('div[data-tab-id=packages][aria-selected=true]')
|
||||
expect(artifactsTab).toBeInTheDocument()
|
||||
|
||||
const configurationTab = tabList?.querySelector('div[data-tab-id=configuration][aria-selected=false]')
|
||||
expect(configurationTab).toBeInTheDocument()
|
||||
|
||||
await userEvent.click(configurationTab!)
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith('/registries/abcd/configuration')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Verify configuration form', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
test('should render form correctly with all data prefilled', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
// Artifact registry defination section
|
||||
const registryDefinitionSection = getByTestId(container, 'upstream-registry-definition')
|
||||
const nameField = queryByNameAttribute('identifier', registryDefinitionSection)
|
||||
expect(nameField).toBeInTheDocument()
|
||||
expect(nameField).toBeDisabled()
|
||||
expect(nameField).toHaveAttribute(
|
||||
'value',
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data.identifier
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', registryDefinitionSection)
|
||||
expect(descriptionField).toBeInTheDocument()
|
||||
expect(descriptionField).not.toBeDisabled()
|
||||
expect(descriptionField).toHaveTextContent(
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data.description
|
||||
)
|
||||
|
||||
const tags = registryDefinitionSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
tags.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data.labels[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// verify source selection
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
const sourceSection = sourceAuthSection.querySelector('input[type=radio][name="config.source"][value=MavenCentral]')
|
||||
expect(sourceSection).toBeChecked()
|
||||
expect(sourceSection).not.toBeDisabled()
|
||||
|
||||
// verify auth type selection
|
||||
const authTypeSelection = sourceAuthSection.querySelector(
|
||||
'input[type=radio][name="config.authType"][value=Anonymous]'
|
||||
)
|
||||
expect(authTypeSelection).toBeChecked()
|
||||
expect(authTypeSelection).not.toBeDisabled()
|
||||
|
||||
// Security scan section
|
||||
const securityScanSection = queryByTestId(container, 'security-scan-section')
|
||||
expect(securityScanSection).not.toBeInTheDocument()
|
||||
|
||||
// artifact filtering rules
|
||||
const filteringRulesSection = getByTestId(container, 'include-exclude-patterns-section')
|
||||
expect(filteringRulesSection).toBeInTheDocument()
|
||||
|
||||
const allowedPatternsSection = filteringRulesSection.querySelectorAll('div.bp3-form-group')[0]
|
||||
const allowedPatterns = allowedPatternsSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
allowedPatterns.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data.allowedPattern[idx]
|
||||
)
|
||||
})
|
||||
|
||||
const blockedPatternsSection = filteringRulesSection.querySelectorAll('div.bp3-form-group')[1]
|
||||
const blockedPatterns = blockedPatternsSection.querySelectorAll('div.bp3-tag-input-values .bp3-tag')
|
||||
blockedPatterns.forEach((each, idx) => {
|
||||
expect(each).toHaveTextContent(
|
||||
MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data.blockedPattern[idx]
|
||||
)
|
||||
})
|
||||
|
||||
// cleanup policy section
|
||||
const cleanupPoliciesSection = getByTestId(container, 'cleanup-policy-section')
|
||||
expect(cleanupPoliciesSection).toBeInTheDocument()
|
||||
const addCleanupPolicyBtn = cleanupPoliciesSection.querySelector(
|
||||
'a[role=button][aria-label="cleanupPolicy.addBtn"]'
|
||||
)
|
||||
expect(addCleanupPolicyBtn).toBeInTheDocument()
|
||||
expect(addCleanupPolicyBtn).toHaveAttribute('disabled', '')
|
||||
|
||||
// action buttons
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).toBeDisabled()
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Success Scenario', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showSuccessToast).toHaveBeenLastCalledWith(
|
||||
'upstreamProxyDetails.actions.createUpdateModal.updateSuccessMessage'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
test('Verify source and auth section with multiple scenarios', async () => {
|
||||
const { container } = render(
|
||||
<ArTestWrapper parent={Parent.OSS} path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
|
||||
const sourceAuthSection = getByTestId(container, 'upstream-source-auth-definition')
|
||||
|
||||
// verify MavenCentral, UserPassword
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'MavenCentral',
|
||||
'UserPassword',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'MavenCentral',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
packageType: 'MAVEN',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify Custom, Anonymous
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Custom',
|
||||
'Anonymous',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
packageType: 'MAVEN',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// verify Custom, UserPassword
|
||||
{
|
||||
await upstreamProxyUtils.verifySourceAndAuthSection(
|
||||
sourceAuthSection,
|
||||
'Custom',
|
||||
'UserPassword',
|
||||
'MavenCentral',
|
||||
'Anonymous'
|
||||
)
|
||||
|
||||
userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: { authType: 'UserPassword', secretIdentifier: 'password', userName: 'username' },
|
||||
authType: 'UserPassword',
|
||||
source: 'Custom',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://custom.docker.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'maven-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
packageType: 'MAVEN',
|
||||
url: ''
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
test('should able to submit the form with updated data: Failure Scenario', async () => {
|
||||
modifyRepository.mockImplementationOnce(
|
||||
() =>
|
||||
new Promise((_, onReject) => {
|
||||
onReject({ message: 'error message' })
|
||||
})
|
||||
)
|
||||
const { container } = render(
|
||||
<ArTestWrapper path="/registries/abcd/:tab" pathParams={{ tab: 'configuration' }}>
|
||||
<RepositoryDetailsPage />
|
||||
</ArTestWrapper>
|
||||
)
|
||||
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
fireEvent.change(descriptionField!, { target: { value: 'updated description' } })
|
||||
expect(descriptionField).toHaveTextContent('updated description')
|
||||
|
||||
const saveBtn = container.querySelector('button[aria-label=save]')
|
||||
expect(saveBtn).not.toBeDisabled()
|
||||
|
||||
const discardBtn = container.querySelector('button[aria-label=discard]')
|
||||
expect(discardBtn).not.toBeDisabled()
|
||||
|
||||
await userEvent.click(saveBtn!)
|
||||
await waitFor(() => {
|
||||
expect(modifyRepository).toHaveBeenLastCalledWith({
|
||||
body: {
|
||||
...MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData.content.data,
|
||||
description: 'updated description'
|
||||
},
|
||||
registry_ref: 'undefined/abcd/+'
|
||||
})
|
||||
expect(showErrorToast).toHaveBeenLastCalledWith('error message')
|
||||
})
|
||||
})
|
||||
})
|
|
@ -332,3 +332,26 @@ export const MockGetMavenSetupClientOnRegistryConfigPageResponse = {
|
|||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
||||
export const MockGetMavenUpstreamRegistryResponseWithMavenCentralSourceAllData = {
|
||||
content: {
|
||||
data: {
|
||||
allowedPattern: ['test1', 'test2'],
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: null,
|
||||
authType: 'Anonymous',
|
||||
source: 'MavenCentral',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
identifier: 'maven-up-repo',
|
||||
description: 'test description',
|
||||
packageType: 'MAVEN',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
url: ''
|
||||
},
|
||||
status: 'SUCCESS'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* 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 userEvent from '@testing-library/user-event'
|
||||
import type { Registry } from '@harnessio/react-har-service-client'
|
||||
import { fireEvent, getByTestId, screen } from '@testing-library/react'
|
||||
import { queryByNameAttribute } from 'utils/test/testUtils'
|
||||
|
||||
async function openModal(container: HTMLElement): Promise<Element> {
|
||||
const pageSubHeader = getByTestId(container, 'page-subheader')
|
||||
const createRegistryButton = pageSubHeader.querySelector('button span[icon="chevron-down"]')
|
||||
expect(createRegistryButton).toBeInTheDocument()
|
||||
await userEvent.click(createRegistryButton!)
|
||||
|
||||
const createUpstreamRegistryBtn = screen.getByText('repositoryList.upstreamProxy.label')
|
||||
await userEvent.click(createUpstreamRegistryBtn!)
|
||||
|
||||
const modal = document.getElementsByClassName('bp3-dialog')[0]
|
||||
expect(modal).toBeInTheDocument()
|
||||
return modal
|
||||
}
|
||||
|
||||
async function verifyPackageTypeSelector(container: HTMLElement, packageType: string): Promise<void> {
|
||||
expect(container).toHaveTextContent('repositoryDetails.repositoryForm.selectRepoType')
|
||||
const packageTypeOption = container.querySelector(`input[type="checkbox"][name=packageType][value=${packageType}]`)
|
||||
expect(packageTypeOption).not.toBeDisabled()
|
||||
await userEvent.click(packageTypeOption!)
|
||||
expect(packageTypeOption).toBeChecked()
|
||||
}
|
||||
|
||||
async function verifySourceAndAuthSection(
|
||||
container: HTMLElement,
|
||||
source: string,
|
||||
authType: string,
|
||||
defaultSource = 'Dockerhub',
|
||||
defaultAuthType = 'Anonymous'
|
||||
) {
|
||||
// add source
|
||||
const sourceOption = container.querySelector(`input[type="radio"][name="config.source"][value="${source}"]`)
|
||||
expect(sourceOption).not.toBeDisabled()
|
||||
if (defaultSource !== source) {
|
||||
await userEvent.click(sourceOption!)
|
||||
}
|
||||
expect(sourceOption).toBeChecked()
|
||||
|
||||
// add registry url
|
||||
if (source === 'Custom') {
|
||||
const urlField = queryByNameAttribute('config.url', container)
|
||||
expect(urlField).toBeInTheDocument()
|
||||
expect(urlField).not.toBeDisabled()
|
||||
fireEvent.change(urlField!, { target: { value: 'https://custom.docker.com' } })
|
||||
} else if (source === 'AwsEcr') {
|
||||
const urlField = queryByNameAttribute('config.url', container)
|
||||
expect(urlField).toBeInTheDocument()
|
||||
expect(urlField).not.toBeDisabled()
|
||||
fireEvent.change(urlField!, { target: { value: 'https://aws.ecr.com' } })
|
||||
} else {
|
||||
const urlField = queryByNameAttribute('config.url', container)
|
||||
expect(urlField).not.toBeInTheDocument
|
||||
}
|
||||
|
||||
// add auth
|
||||
const authTypeOption = container.querySelector(`input[type="radio"][name="config.authType"][value="${authType}"]`)
|
||||
expect(authTypeOption).not.toBeDisabled()
|
||||
if (defaultAuthType !== authType) {
|
||||
await userEvent.click(authTypeOption!)
|
||||
}
|
||||
expect(authTypeOption).toBeChecked()
|
||||
|
||||
if (authType === 'UserPassword') {
|
||||
// add username password
|
||||
const usernameField = queryByNameAttribute('config.auth.userName', container)
|
||||
expect(usernameField).toBeInTheDocument()
|
||||
fireEvent.change(usernameField!, { target: { value: 'username' } })
|
||||
|
||||
const passwordField = queryByNameAttribute('config.auth.secretIdentifier', container)
|
||||
expect(passwordField).toBeInTheDocument()
|
||||
fireEvent.change(passwordField!, { target: { value: 'password' } })
|
||||
} else if (authType === 'AccessKeySecretKey') {
|
||||
// add access key and secret key
|
||||
const accessKeyField = queryByNameAttribute('config.auth.accessKey', container)
|
||||
expect(accessKeyField).toBeInTheDocument()
|
||||
fireEvent.change(accessKeyField!, { target: { value: 'accessKey' } })
|
||||
|
||||
const secretKeyField = queryByNameAttribute('config.auth.secretKeyIdentifier', container)
|
||||
expect(secretKeyField).toBeInTheDocument()
|
||||
fireEvent.change(secretKeyField!, { target: { value: 'secretKey' } })
|
||||
} else {
|
||||
const usernameField = queryByNameAttribute('config.auth.userName', container)
|
||||
expect(usernameField).not.toBeInTheDocument()
|
||||
|
||||
const passwordField = queryByNameAttribute('config.auth.secretIdentifier', container)
|
||||
expect(passwordField).not.toBeInTheDocument()
|
||||
|
||||
const accessKeyField = queryByNameAttribute('config.auth.accessKey', container)
|
||||
expect(accessKeyField).not.toBeInTheDocument()
|
||||
|
||||
const secretKeyField = queryByNameAttribute('config.auth.secretKeyIdentifier', container)
|
||||
expect(secretKeyField).not.toBeInTheDocument()
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyUpstreamProxyCreateForm(
|
||||
container: HTMLElement,
|
||||
formData: Registry,
|
||||
source: string,
|
||||
authType: string,
|
||||
defaultSource = 'Dockerhub',
|
||||
defaultAuthType = 'Anonymous'
|
||||
): Promise<void> {
|
||||
// Add name
|
||||
const nameField = queryByNameAttribute('identifier', container)
|
||||
expect(nameField).not.toBeDisabled()
|
||||
fireEvent.change(nameField!, { target: { value: formData.identifier } })
|
||||
|
||||
// add description
|
||||
const descriptionEditButton = getByTestId(container, 'description-edit')
|
||||
expect(descriptionEditButton).toBeInTheDocument()
|
||||
await userEvent.click(descriptionEditButton)
|
||||
const descriptionField = queryByNameAttribute('description', container)
|
||||
expect(descriptionField).not.toBeDisabled()
|
||||
fireEvent.change(descriptionField!, { target: { value: formData.description } })
|
||||
|
||||
// verify source and auth section
|
||||
await verifySourceAndAuthSection(container, source, authType, defaultSource, defaultAuthType)
|
||||
}
|
||||
|
||||
async function getSubmitButton(): Promise<Element> {
|
||||
const dialogFooter = screen.getByTestId('modaldialog-footer')
|
||||
expect(dialogFooter).toBeInTheDocument()
|
||||
const createButton = dialogFooter.querySelector(
|
||||
'button[type="submit"][aria-label="upstreamProxyDetails.createForm.create"]'
|
||||
)
|
||||
expect(createButton).toBeInTheDocument()
|
||||
return createButton!
|
||||
}
|
||||
|
||||
const upstreamProxyUtils = {
|
||||
openModal,
|
||||
verifyPackageTypeSelector,
|
||||
verifyUpstreamProxyCreateForm,
|
||||
verifySourceAndAuthSection,
|
||||
getSubmitButton
|
||||
}
|
||||
|
||||
export default upstreamProxyUtils
|
|
@ -28,7 +28,7 @@ export default function UpstreamProxyAuthenticationFormContent({
|
|||
readonly
|
||||
}: UpstreamProxyAuthenticationFormContentProps): JSX.Element {
|
||||
return (
|
||||
<Layout.Vertical spacing="small">
|
||||
<Layout.Vertical data-testid="upstream-source-auth-definition" spacing="small">
|
||||
<RepositoryUrlInput readonly={readonly} />
|
||||
<AuthenticationFormInput readonly={readonly} />
|
||||
</Layout.Vertical>
|
||||
|
|
|
@ -44,7 +44,7 @@ export default function UpstreamProxyCleanupPoliciesFormContent(
|
|||
}
|
||||
|
||||
return (
|
||||
<Layout.Vertical flex={{ alignItems: 'flex-start' }} spacing="xsmall">
|
||||
<Layout.Vertical data-testid="cleanup-policy-section" flex={{ alignItems: 'flex-start' }} spacing="xsmall">
|
||||
<Text font={{ variation: FontVariation.CARD_TITLE }}>
|
||||
{getString('repositoryDetails.repositoryForm.cleanupPoliciesTitle')}
|
||||
</Text>
|
||||
|
|
|
@ -36,7 +36,7 @@ export default function UpstreamProxyDetailsFormContent(props: UpstreamProxyDeta
|
|||
const { description, labels } = values
|
||||
const { getString } = useStrings()
|
||||
return (
|
||||
<Layout.Vertical>
|
||||
<Layout.Vertical data-testid="upstream-registry-definition">
|
||||
<FormInput.Text
|
||||
name="identifier"
|
||||
label={getString('upstreamProxyDetails.createForm.key')}
|
||||
|
|
|
@ -35,7 +35,7 @@ export default function UpstreamProxyIncludeExcludePatternFormContent(
|
|||
const { isEdit, readonly, formikProps } = props
|
||||
const { getString } = useStrings()
|
||||
return (
|
||||
<Layout.Vertical spacing="small">
|
||||
<Layout.Vertical spacing="small" data-testid="include-exclude-patterns-section">
|
||||
<Text font={{ variation: FontVariation.CARD_TITLE }}>
|
||||
{getString('repositoryDetails.repositoryForm.includeExcludePatternsTitle')}
|
||||
</Text>
|
||||
|
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* 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 { Parent } from '@ar/common/types'
|
||||
|
||||
import type { UpstreamRegistryRequest } from '@ar/pages/upstream-proxy-details/types'
|
||||
import {
|
||||
getFormattedFormDataForCleanupPolicy,
|
||||
getFormattedIntialValuesForCleanupPolicy
|
||||
} from '@ar/components/CleanupPolicyList/utils'
|
||||
|
||||
import {
|
||||
getFormattedFormDataForAuthType,
|
||||
getFormattedInitialValuesForAuthType,
|
||||
getReferenceStringFromSecretSpacePath,
|
||||
getSecretSpacePath
|
||||
} from '../utils'
|
||||
|
||||
const mockUpstreamProxyFormData = {
|
||||
packageType: 'DOCKER',
|
||||
identifier: 'test1',
|
||||
config: {
|
||||
type: 'UPSTREAM',
|
||||
source: 'Dockerhub',
|
||||
url: '',
|
||||
authType: 'UserPassword',
|
||||
auth: {
|
||||
userName: 'admin',
|
||||
secretIdentifier: {
|
||||
name: 'prod-shiv-pass',
|
||||
identifier: 'prod-shiv-pass',
|
||||
orgIdentifier: 'org',
|
||||
projectIdentifier: 'project',
|
||||
type: 'SecretText',
|
||||
referenceString: 'prod-shiv-pass'
|
||||
}
|
||||
}
|
||||
},
|
||||
cleanupPolicy: [],
|
||||
scanners: []
|
||||
} as UpstreamRegistryRequest
|
||||
|
||||
const mockUpstreamProxyFormDataForAwsEcr = {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeySecretIdentifier: undefined,
|
||||
accessKeySecretSpacePath: undefined,
|
||||
accessKeyType: 'TEXT',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: {
|
||||
identifier: 'secretKey',
|
||||
name: 'secretKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'secretKey'
|
||||
}
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
} as UpstreamRegistryRequest
|
||||
|
||||
const mockUpstreamProxyData = {
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
authType: 'UserPassword',
|
||||
secretIdentifier: 'prod-shiv-pass',
|
||||
secretSpacePath: 'acc/org/project',
|
||||
userName: 'admin'
|
||||
},
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
identifier: 'test1',
|
||||
packageType: 'DOCKER',
|
||||
scanners: []
|
||||
} as UpstreamRegistryRequest
|
||||
|
||||
const mockUpstreamProxyDataForAwsEcr = {
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeyType: 'TEXT',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
} as UpstreamRegistryRequest
|
||||
|
||||
const scope = {
|
||||
accountId: 'acc',
|
||||
orgIdentifier: 'org',
|
||||
projectIdentifier: 'project',
|
||||
space: 'acc/org/project'
|
||||
}
|
||||
|
||||
describe('Verify Upstream Proxy Form utils', () => {
|
||||
test('verify getFormattedFormDataForAuthType', () => {
|
||||
const updatedValue = getFormattedFormDataForAuthType(mockUpstreamProxyFormData, Parent.Enterprise, scope)
|
||||
expect(updatedValue).toEqual({
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
authType: 'UserPassword',
|
||||
secretIdentifier: 'prod-shiv-pass',
|
||||
secretSpacePath: 'acc/org/project',
|
||||
userName: 'admin'
|
||||
},
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
identifier: 'test1',
|
||||
packageType: 'DOCKER',
|
||||
scanners: []
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedFormDataForAuthType for aws ecr: Text', () => {
|
||||
const updatedValue = getFormattedFormDataForAuthType(mockUpstreamProxyFormDataForAwsEcr, Parent.Enterprise, scope)
|
||||
expect(updatedValue).toEqual({
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeySecretIdentifier: undefined,
|
||||
accessKeySecretSpacePath: undefined,
|
||||
accessKeyType: undefined,
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey',
|
||||
secretKeySpacePath: 'acc/org/project'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedFormDataForAuthType for aws ecr: Secret', () => {
|
||||
const updatedValue = getFormattedFormDataForAuthType(
|
||||
{
|
||||
...mockUpstreamProxyFormDataForAwsEcr,
|
||||
config: {
|
||||
...mockUpstreamProxyFormDataForAwsEcr.config,
|
||||
auth: {
|
||||
accessKey: undefined,
|
||||
accessKeySecretIdentifier: {
|
||||
identifier: 'accessKey',
|
||||
name: 'accessKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'accessKey'
|
||||
},
|
||||
accessKeyType: 'ENCRYPTED',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: {
|
||||
identifier: 'secretKey',
|
||||
name: 'secretKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'secretKey'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Parent.Enterprise,
|
||||
scope
|
||||
)
|
||||
expect(updatedValue).toEqual({
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: undefined,
|
||||
accessKeySecretIdentifier: 'accessKey',
|
||||
accessKeySecretSpacePath: 'acc/org/project',
|
||||
accessKeyType: undefined,
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey',
|
||||
secretKeySpacePath: 'acc/org/project'
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedFormDataForCleanupPolicy', () => {
|
||||
const updatedValue = getFormattedFormDataForCleanupPolicy(mockUpstreamProxyFormData)
|
||||
expect(updatedValue).toEqual({
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
secretIdentifier: {
|
||||
identifier: 'prod-shiv-pass',
|
||||
name: 'prod-shiv-pass',
|
||||
orgIdentifier: 'org',
|
||||
projectIdentifier: 'project',
|
||||
referenceString: 'prod-shiv-pass',
|
||||
type: 'SecretText'
|
||||
},
|
||||
userName: 'admin'
|
||||
},
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
identifier: 'test1',
|
||||
packageType: 'DOCKER',
|
||||
scanners: []
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedInitialValuesForAuthType', () => {
|
||||
const updatedValue = getFormattedInitialValuesForAuthType(mockUpstreamProxyData, Parent.Enterprise)
|
||||
expect(updatedValue).toEqual({
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
authType: 'UserPassword',
|
||||
secretIdentifier: {
|
||||
identifier: 'prod-shiv-pass',
|
||||
name: 'prod-shiv-pass',
|
||||
orgIdentifier: 'org',
|
||||
projectIdentifier: 'project',
|
||||
referenceString: 'prod-shiv-pass'
|
||||
},
|
||||
secretSpacePath: 'acc/org/project',
|
||||
userName: 'admin'
|
||||
},
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
identifier: 'test1',
|
||||
packageType: 'DOCKER',
|
||||
scanners: []
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedInitialValuesForAuthType for aws ecr: Text', () => {
|
||||
const updatedValue = getFormattedInitialValuesForAuthType(mockUpstreamProxyDataForAwsEcr, Parent.Enterprise)
|
||||
expect(updatedValue).toEqual({
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: 'accessKey',
|
||||
accessKeySecretIdentifier: undefined,
|
||||
accessKeySecretSpacePath: undefined,
|
||||
accessKeyType: 'TEXT',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: {
|
||||
identifier: 'secretKey',
|
||||
name: 'secretKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'secretKey'
|
||||
}
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedInitialValuesForAuthType for aws ecr: Secret', () => {
|
||||
const updatedValue = getFormattedInitialValuesForAuthType(
|
||||
{
|
||||
...mockUpstreamProxyDataForAwsEcr,
|
||||
config: {
|
||||
...mockUpstreamProxyDataForAwsEcr.config,
|
||||
auth: {
|
||||
accessKeySecretIdentifier: 'accessKey',
|
||||
accessKeyType: 'ENCRYPTED',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: 'secretKey'
|
||||
}
|
||||
}
|
||||
},
|
||||
Parent.Enterprise
|
||||
)
|
||||
expect(updatedValue).toEqual({
|
||||
blockedPattern: ['test3', 'test4'],
|
||||
config: {
|
||||
auth: {
|
||||
accessKey: undefined,
|
||||
accessKeySecretIdentifier: {
|
||||
identifier: 'accessKey',
|
||||
name: 'accessKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'accessKey'
|
||||
},
|
||||
accessKeyType: 'ENCRYPTED',
|
||||
authType: 'AccessKeySecretKey',
|
||||
secretKeyIdentifier: {
|
||||
identifier: 'secretKey',
|
||||
name: 'secretKey',
|
||||
orgIdentifier: undefined,
|
||||
projectIdentifier: undefined,
|
||||
referenceString: 'secretKey'
|
||||
}
|
||||
},
|
||||
authType: 'AccessKeySecretKey',
|
||||
source: 'AwsEcr',
|
||||
type: 'UPSTREAM',
|
||||
url: 'https://aws.ecr.com'
|
||||
},
|
||||
createdAt: '1738516362995',
|
||||
description: 'test description',
|
||||
identifier: 'docker-up-repo',
|
||||
labels: ['label1', 'label2', 'label3', 'label4'],
|
||||
modifiedAt: '1738516362995',
|
||||
packageType: 'DOCKER',
|
||||
url: ''
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getFormattedIntialValuesForCleanupPolicy', () => {
|
||||
const updatedValue = getFormattedIntialValuesForCleanupPolicy(mockUpstreamProxyData)
|
||||
expect(updatedValue).toEqual({
|
||||
cleanupPolicy: [],
|
||||
config: {
|
||||
auth: {
|
||||
authType: 'UserPassword',
|
||||
secretIdentifier: 'prod-shiv-pass',
|
||||
secretSpacePath: 'acc/org/project',
|
||||
userName: 'admin'
|
||||
},
|
||||
authType: 'UserPassword',
|
||||
source: 'Dockerhub',
|
||||
type: 'UPSTREAM',
|
||||
url: ''
|
||||
},
|
||||
identifier: 'test1',
|
||||
packageType: 'DOCKER',
|
||||
scanners: []
|
||||
})
|
||||
})
|
||||
|
||||
test('verify getSecretSpacePath', () => {
|
||||
let response = getSecretSpacePath('dummy')
|
||||
expect(response).toEqual(response)
|
||||
response = getSecretSpacePath('account.dummy', scope)
|
||||
expect(response).toEqual('acc')
|
||||
response = getSecretSpacePath('org.dummy', scope)
|
||||
expect(response).toEqual('acc/org')
|
||||
response = getSecretSpacePath('dummy', scope)
|
||||
expect(response).toEqual('acc/org/project')
|
||||
})
|
||||
|
||||
test('verify getReferenceStringFromSecretSpacePath', () => {
|
||||
let response = getReferenceStringFromSecretSpacePath('dummy', 'acc/org/project')
|
||||
expect(response).toEqual('dummy')
|
||||
response = getReferenceStringFromSecretSpacePath('dummy', 'acc/org')
|
||||
expect(response).toEqual('org.dummy')
|
||||
response = getReferenceStringFromSecretSpacePath('dummy', 'acc')
|
||||
expect(response).toEqual('account.dummy')
|
||||
response = getReferenceStringFromSecretSpacePath('dummy', '')
|
||||
expect(response).toEqual('dummy')
|
||||
})
|
||||
})
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* 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 { noop } from 'lodash-es'
|
||||
|
||||
import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes'
|
||||
import { useParentComponents } from '@ar/hooks'
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
|
||||
import type { UpstreamProxyActionProps } from './type'
|
||||
|
||||
export default function RestoreUpstreamProxy({ data }: UpstreamProxyActionProps): JSX.Element {
|
||||
const { getString } = useStrings()
|
||||
const { RbacMenuItem } = useParentComponents()
|
||||
return (
|
||||
<RbacMenuItem
|
||||
icon="command-rollback"
|
||||
text={getString('actions.restore')}
|
||||
onClick={noop}
|
||||
permission={{
|
||||
resource: {
|
||||
resourceType: ResourceType.ARTIFACT_REGISTRY,
|
||||
resourceIdentifier: data.identifier
|
||||
},
|
||||
permission: PermissionIdentifier.EDIT_ARTIFACT_REGISTRY
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* 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 { noop } from 'lodash-es'
|
||||
|
||||
import { useParentComponents } from '@ar/hooks'
|
||||
import { useStrings } from '@ar/frameworks/strings'
|
||||
import { PermissionIdentifier, ResourceType } from '@ar/common/permissionTypes'
|
||||
import type { UpstreamProxyActionProps } from './type'
|
||||
|
||||
export default function ScanUpstreamProxy({ data }: UpstreamProxyActionProps): JSX.Element {
|
||||
const { getString } = useStrings()
|
||||
const { RbacMenuItem } = useParentComponents()
|
||||
return (
|
||||
<RbacMenuItem
|
||||
icon="sto-grey"
|
||||
text={getString('actions.scan')}
|
||||
onClick={noop}
|
||||
permission={{
|
||||
resource: {
|
||||
resourceType: ResourceType.ARTIFACT_REGISTRY,
|
||||
resourceIdentifier: data.identifier
|
||||
},
|
||||
permission: PermissionIdentifier.EDIT_ARTIFACT_REGISTRY
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -42,7 +42,10 @@ export default function UpstreamProxyDetailsHeaderContent(props: UpstreamProxyDe
|
|||
const { getString } = useStrings()
|
||||
return (
|
||||
<Container>
|
||||
<Layout.Horizontal spacing="medium" flex={{ alignItems: 'center' }}>
|
||||
<Layout.Horizontal
|
||||
data-testid="upstream-registry-header-container"
|
||||
spacing="medium"
|
||||
flex={{ alignItems: 'center' }}>
|
||||
<RepositoryIcon packageType={packageType as RepositoryPackageType} iconProps={{ size: iconSize }} />
|
||||
<Layout.Vertical spacing="small" className={css.nameContainer}>
|
||||
<Layout.Horizontal spacing="small" flex={{ alignItems: 'center', justifyContent: 'flex-start' }}>
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export enum UpstreamProxyDetailsTab {
|
||||
PACKAGES = 'packages',
|
||||
CONFIGURATION = 'configuration'
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* 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, { createContext } from 'react'
|
||||
import type { FC, PropsWithChildren } from 'react'
|
||||
import { noop } from 'lodash-es'
|
||||
import { Page } from '@harnessio/uicore'
|
||||
import { useGetRegistryQuery } from '@harnessio/react-har-service-client'
|
||||
|
||||
import { useGetSpaceRef } from '@ar/hooks'
|
||||
import type { UpstreamRegistry } from '../types'
|
||||
|
||||
export interface UpstreamProxyConfigurationFormContextProps {
|
||||
data: UpstreamRegistry | undefined
|
||||
refetch: () => void
|
||||
}
|
||||
|
||||
export const UpstreamProxyConfigurationFormContext = createContext<UpstreamProxyConfigurationFormContextProps>({
|
||||
data: undefined,
|
||||
refetch: noop
|
||||
})
|
||||
|
||||
interface UpstreamProxyConfigurationFormProviderProps {
|
||||
repoKey: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
const UpstreamProxyConfigurationFormProvider: FC<PropsWithChildren<UpstreamProxyConfigurationFormProviderProps>> = ({
|
||||
children,
|
||||
repoKey,
|
||||
className
|
||||
}): JSX.Element => {
|
||||
const spaceRef = useGetSpaceRef(repoKey)
|
||||
|
||||
const {
|
||||
data: response,
|
||||
error,
|
||||
isFetching: loading,
|
||||
refetch
|
||||
} = useGetRegistryQuery({
|
||||
registry_ref: spaceRef
|
||||
})
|
||||
|
||||
return (
|
||||
<UpstreamProxyConfigurationFormContext.Provider
|
||||
value={{ data: response?.content?.data as UpstreamProxyConfigurationFormContextProps['data'], refetch }}>
|
||||
<Page.Body className={className} loading={loading} error={error?.message} retryOnError={() => refetch()}>
|
||||
{loading ? null : children}
|
||||
</Page.Body>
|
||||
</UpstreamProxyConfigurationFormContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export default UpstreamProxyConfigurationFormProvider
|
Loading…
Reference in New Issue