diff options
Diffstat (limited to 'spec/frontend/packages')
28 files changed, 7 insertions, 2988 deletions
diff --git a/spec/frontend/packages/details/components/__snapshots__/conan_installation_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/conan_installation_spec.js.snap deleted file mode 100644 index a3423e3f4d7..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/conan_installation_spec.js.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ConanInstallation renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object]" - packagetype="conan" - /> - - <code-instruction-stub - copytext="Copy Conan Command" - instruction="foo/command" - label="Conan Command" - trackingaction="copy_conan_command" - trackinglabel="code_instruction" - /> - - <h3 - class="gl-font-lg" - > - Registry setup - </h3> - - <code-instruction-stub - copytext="Copy Conan Setup Command" - instruction="foo/setup" - label="Add Conan Remote" - trackingaction="copy_conan_setup_command" - trackinglabel="code_instruction" - /> - - <gl-sprintf-stub - message="For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}." - /> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/dependency_row_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/dependency_row_spec.js.snap deleted file mode 100644 index 39469bf4fd0..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/dependency_row_spec.js.snap +++ /dev/null @@ -1,34 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DependencyRow renders full dependency 1`] = ` -<div - class="gl-responsive-table-row" -> - <div - class="table-section section-50" - > - <strong - class="gl-text-body" - > - Test.Dependency - </strong> - - <span - data-testid="target-framework" - > - (.NETStandard2.0) - </span> - </div> - - <div - class="table-section section-50 gl-display-flex gl-md-justify-content-end" - data-testid="version-pattern" - > - <span - class="gl-text-body" - > - 2.3.7 - </span> - </div> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap deleted file mode 100644 index 881d441e116..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/file_sha_spec.js.snap +++ /dev/null @@ -1,30 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`FileSha renders 1`] = ` -<div - class="gl-display-flex gl-align-items-center gl-font-monospace gl-font-sm gl-word-break-all gl-py-2 gl-border-b-solid gl-border-gray-100 gl-border-b-1" -> - <!----> - - <span> - <div - class="gl-px-4" - > - - bar: - foo - - <gl-button-stub - aria-label="Copy this value" - buttontextclasses="" - category="tertiary" - data-clipboard-text="foo" - icon="copy-to-clipboard" - size="small" - title="Copy SHA" - variant="default" - /> - </div> - </span> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/maven_installation_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/maven_installation_spec.js.snap deleted file mode 100644 index 8a2793c0010..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/maven_installation_spec.js.snap +++ /dev/null @@ -1,112 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`MavenInstallation groovy renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object],[object Object],[object Object]" - packagetype="maven" - /> - - <code-instruction-stub - class="gl-mb-5" - copytext="Copy Gradle Groovy DSL install command" - instruction="foo/gradle/groovy/install" - label="Gradle Groovy DSL install command" - trackingaction="copy_gradle_install_command" - trackinglabel="code_instruction" - /> - - <code-instruction-stub - copytext="Copy add Gradle Groovy DSL repository command" - instruction="foo/gradle/groovy/add/source" - label="Add Gradle Groovy DSL repository command" - multiline="true" - trackingaction="copy_gradle_add_to_source_command" - trackinglabel="code_instruction" - /> -</div> -`; - -exports[`MavenInstallation kotlin renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object],[object Object],[object Object]" - packagetype="maven" - /> - - <code-instruction-stub - class="gl-mb-5" - copytext="Copy Gradle Kotlin DSL install command" - instruction="foo/gradle/kotlin/install" - label="Gradle Kotlin DSL install command" - trackingaction="copy_kotlin_install_command" - trackinglabel="code_instruction" - /> - - <code-instruction-stub - copytext="Copy add Gradle Kotlin DSL repository command" - instruction="foo/gradle/kotlin/add/source" - label="Add Gradle Kotlin DSL repository command" - multiline="true" - trackingaction="copy_kotlin_add_to_source_command" - trackinglabel="code_instruction" - /> -</div> -`; - -exports[`MavenInstallation maven renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object],[object Object],[object Object]" - packagetype="maven" - /> - - <p> - <gl-sprintf-stub - message="Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block." - /> - </p> - - <code-instruction-stub - copytext="Copy Maven XML" - instruction="foo/xml" - label="" - multiline="true" - trackingaction="copy_maven_xml" - trackinglabel="code_instruction" - /> - - <code-instruction-stub - copytext="Copy Maven command" - instruction="foo/command" - label="Maven Command" - trackingaction="copy_maven_command" - trackinglabel="code_instruction" - /> - - <h3 - class="gl-font-lg" - > - Registry setup - </h3> - - <p> - <gl-sprintf-stub - message="If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file." - /> - </p> - - <code-instruction-stub - copytext="Copy Maven registry XML" - instruction="foo/setup" - label="" - multiline="true" - trackingaction="copy_maven_setup_xml" - trackinglabel="code_instruction" - /> - - <gl-sprintf-stub - message="For more information on the Maven registry, %{linkStart}see the documentation%{linkEnd}." - /> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/npm_installation_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/npm_installation_spec.js.snap deleted file mode 100644 index 015c7b94dde..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/npm_installation_spec.js.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NpmInstallation renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object],[object Object]" - packagetype="npm" - /> - - <code-instruction-stub - copytext="Copy npm command" - instruction="npm i @Test/package" - label="" - trackingaction="copy_npm_install_command" - trackinglabel="code_instruction" - /> - - <h3 - class="gl-font-lg" - > - Registry setup - </h3> - - <code-instruction-stub - copytext="Copy npm setup command" - instruction="echo @Test:registry=undefined/ >> .npmrc" - label="" - trackingaction="copy_npm_setup_command" - trackinglabel="code_instruction" - /> - - <gl-sprintf-stub - message="You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more." - /> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/nuget_installation_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/nuget_installation_spec.js.snap deleted file mode 100644 index 04532743952..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/nuget_installation_spec.js.snap +++ /dev/null @@ -1,36 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NugetInstallation renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object]" - packagetype="nuget" - /> - - <code-instruction-stub - copytext="Copy NuGet Command" - instruction="foo/command" - label="NuGet Command" - trackingaction="copy_nuget_install_command" - trackinglabel="code_instruction" - /> - - <h3 - class="gl-font-lg" - > - Registry setup - </h3> - - <code-instruction-stub - copytext="Copy NuGet Setup Command" - instruction="foo/setup" - label="Add NuGet Source" - trackingaction="copy_nuget_setup_command" - trackinglabel="code_instruction" - /> - - <gl-sprintf-stub - message="For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}." - /> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap deleted file mode 100644 index 318cea98b92..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/package_title_spec.js.snap +++ /dev/null @@ -1,168 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PackageTitle renders with tags 1`] = ` -<div - class="gl-display-flex gl-flex-direction-column" - data-qa-selector="package_title" -> - <div - class="gl-display-flex gl-justify-content-space-between gl-py-3" - > - <div - class="gl-flex-direction-column gl-flex-grow-1" - > - <div - class="gl-display-flex" - > - <!----> - - <div - class="gl-display-flex gl-flex-direction-column" - > - <h1 - class="gl-font-size-h1 gl-mt-3 gl-mb-2" - data-testid="title" - > - Test package - </h1> - - <div - class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1" - > - <gl-icon-stub - class="gl-mr-3" - name="eye" - size="16" - /> - - <gl-sprintf-stub - message="v%{version} published %{timeAgo}" - /> - </div> - </div> - </div> - - <div - class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3" - > - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <metadata-item-stub - data-testid="package-type" - icon="package" - link="" - size="s" - text="maven" - texttooltip="" - /> - </div> - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <metadata-item-stub - data-testid="package-size" - icon="disk" - link="" - size="s" - text="300 bytes" - texttooltip="" - /> - </div> - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <package-tags-stub - hidelabel="true" - tagdisplaylimit="2" - tags="[object Object],[object Object],[object Object],[object Object]" - /> - </div> - </div> - </div> - - <!----> - </div> - - <p /> -</div> -`; - -exports[`PackageTitle renders without tags 1`] = ` -<div - class="gl-display-flex gl-flex-direction-column" - data-qa-selector="package_title" -> - <div - class="gl-display-flex gl-justify-content-space-between gl-py-3" - > - <div - class="gl-flex-direction-column gl-flex-grow-1" - > - <div - class="gl-display-flex" - > - <!----> - - <div - class="gl-display-flex gl-flex-direction-column" - > - <h1 - class="gl-font-size-h1 gl-mt-3 gl-mb-2" - data-testid="title" - > - Test package - </h1> - - <div - class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-1" - > - <gl-icon-stub - class="gl-mr-3" - name="eye" - size="16" - /> - - <gl-sprintf-stub - message="v%{version} published %{timeAgo}" - /> - </div> - </div> - </div> - - <div - class="gl-display-flex gl-flex-wrap gl-align-items-center gl-mt-3" - > - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <metadata-item-stub - data-testid="package-type" - icon="package" - link="" - size="s" - text="maven" - texttooltip="" - /> - </div> - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <metadata-item-stub - data-testid="package-size" - icon="disk" - link="" - size="s" - text="300 bytes" - texttooltip="" - /> - </div> - </div> - </div> - - <!----> - </div> - - <p /> -</div> -`; diff --git a/spec/frontend/packages/details/components/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages/details/components/__snapshots__/pypi_installation_spec.js.snap deleted file mode 100644 index d5bb825d8d1..00000000000 --- a/spec/frontend/packages/details/components/__snapshots__/pypi_installation_spec.js.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PypiInstallation renders all the messages 1`] = ` -<div> - <installation-title-stub - options="[object Object]" - packagetype="pypi" - /> - - <code-instruction-stub - copytext="Copy Pip command" - data-testid="pip-command" - instruction="pip install" - label="Pip Command" - trackingaction="copy_pip_install_command" - trackinglabel="code_instruction" - /> - - <h3 - class="gl-font-lg" - > - Registry setup - </h3> - - <p> - <gl-sprintf-stub - message="If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file." - /> - </p> - - <code-instruction-stub - copytext="Copy .pypirc content" - data-testid="pypi-setup-content" - instruction="python setup" - label="" - multiline="true" - trackingaction="copy_pypi_setup_command" - trackinglabel="code_instruction" - /> - - <gl-sprintf-stub - message="For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}." - /> -</div> -`; diff --git a/spec/frontend/packages/details/components/additional_metadata_spec.js b/spec/frontend/packages/details/components/additional_metadata_spec.js deleted file mode 100644 index b339aa84348..00000000000 --- a/spec/frontend/packages/details/components/additional_metadata_spec.js +++ /dev/null @@ -1,119 +0,0 @@ -import { GlLink, GlSprintf } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import component from '~/packages/details/components/additional_metadata.vue'; -import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; - -import { mavenPackage, conanPackage, nugetPackage, npmPackage } from '../../mock_data'; - -describe('Package Additional Metadata', () => { - let wrapper; - const defaultProps = { - packageEntity: { ...mavenPackage }, - }; - - const mountComponent = (props) => { - wrapper = shallowMount(component, { - propsData: { ...defaultProps, ...props }, - stubs: { - DetailsRow, - GlSprintf, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - const findTitle = () => wrapper.find('[data-testid="title"]'); - const findMainArea = () => wrapper.find('[data-testid="main"]'); - const findNugetSource = () => wrapper.find('[data-testid="nuget-source"]'); - const findNugetLicense = () => wrapper.find('[data-testid="nuget-license"]'); - const findConanRecipe = () => wrapper.find('[data-testid="conan-recipe"]'); - const findMavenApp = () => wrapper.find('[data-testid="maven-app"]'); - const findMavenGroup = () => wrapper.find('[data-testid="maven-group"]'); - const findElementLink = (container) => container.find(GlLink); - - it('has the correct title', () => { - mountComponent(); - - const title = findTitle(); - - expect(title.exists()).toBe(true); - expect(title.text()).toBe('Additional Metadata'); - }); - - describe.each` - packageEntity | visible | metadata - ${mavenPackage} | ${true} | ${'maven_metadatum'} - ${conanPackage} | ${true} | ${'conan_metadatum'} - ${nugetPackage} | ${true} | ${'nuget_metadatum'} - ${npmPackage} | ${false} | ${null} - `('Component visibility', ({ packageEntity, visible, metadata }) => { - it(`Is ${visible} that the component markup is visible when the package is ${packageEntity.package_type}`, () => { - mountComponent({ packageEntity }); - - expect(findTitle().exists()).toBe(visible); - expect(findMainArea().exists()).toBe(visible); - }); - - it(`The component is hidden if ${metadata} is missing`, () => { - mountComponent({ packageEntity: { ...packageEntity, [metadata]: null } }); - - expect(findTitle().exists()).toBe(false); - expect(findMainArea().exists()).toBe(false); - }); - }); - - describe('nuget metadata', () => { - beforeEach(() => { - mountComponent({ packageEntity: nugetPackage }); - }); - - it.each` - name | finderFunction | text | link | icon - ${'source'} | ${findNugetSource} | ${'Source project located at project-foo-url'} | ${'project_url'} | ${'project'} - ${'license'} | ${findNugetLicense} | ${'License information located at license-foo-url'} | ${'license_url'} | ${'license'} - `('$name element', ({ finderFunction, text, link, icon }) => { - const element = finderFunction(); - expect(element.exists()).toBe(true); - expect(element.text()).toBe(text); - expect(element.props('icon')).toBe(icon); - expect(findElementLink(element).attributes('href')).toBe(nugetPackage.nuget_metadatum[link]); - }); - }); - - describe('conan metadata', () => { - beforeEach(() => { - mountComponent({ packageEntity: conanPackage }); - }); - - it.each` - name | finderFunction | text | icon - ${'recipe'} | ${findConanRecipe} | ${'Recipe: conan-package/1.0.0@conan+conan-package/stable'} | ${'information-o'} - `('$name element', ({ finderFunction, text, icon }) => { - const element = finderFunction(); - expect(element.exists()).toBe(true); - expect(element.text()).toBe(text); - expect(element.props('icon')).toBe(icon); - }); - }); - - describe('maven metadata', () => { - beforeEach(() => { - mountComponent(); - }); - - it.each` - name | finderFunction | text | icon - ${'app'} | ${findMavenApp} | ${'App name: test-app'} | ${'information-o'} - ${'group'} | ${findMavenGroup} | ${'App group: com.test.app'} | ${'information-o'} - `('$name element', ({ finderFunction, text, icon }) => { - const element = finderFunction(); - expect(element.exists()).toBe(true); - expect(element.text()).toBe(text); - expect(element.props('icon')).toBe(icon); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/app_spec.js b/spec/frontend/packages/details/components/app_spec.js deleted file mode 100644 index 377e7e05f09..00000000000 --- a/spec/frontend/packages/details/components/app_spec.js +++ /dev/null @@ -1,385 +0,0 @@ -import { GlEmptyState } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; -import { nextTick } from 'vue'; -import Vuex from 'vuex'; -import { useMockLocationHelper } from 'helpers/mock_window_location_helper'; -import stubChildren from 'helpers/stub_children'; - -import AdditionalMetadata from '~/packages/details/components/additional_metadata.vue'; -import PackagesApp from '~/packages/details/components/app.vue'; -import DependencyRow from '~/packages/details/components/dependency_row.vue'; -import InstallationCommands from '~/packages/details/components/installation_commands.vue'; -import PackageFiles from '~/packages/details/components/package_files.vue'; -import PackageHistory from '~/packages/details/components/package_history.vue'; -import PackageTitle from '~/packages/details/components/package_title.vue'; -import * as getters from '~/packages/details/store/getters'; -import PackageListRow from '~/packages/shared/components/package_list_row.vue'; -import PackagesListLoader from '~/packages/shared/components/packages_list_loader.vue'; -import { TrackingActions } from '~/packages/shared/constants'; -import * as SharedUtils from '~/packages/shared/utils'; -import Tracking from '~/tracking'; - -import { - composerPackage, - conanPackage, - mavenPackage, - mavenFiles, - npmPackage, - nugetPackage, -} from '../../mock_data'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -useMockLocationHelper(); - -describe('PackagesApp', () => { - let wrapper; - let store; - const fetchPackageVersions = jest.fn(); - const deletePackage = jest.fn(); - const deletePackageFile = jest.fn(); - const defaultProjectName = 'bar'; - - function createComponent({ - packageEntity = mavenPackage, - packageFiles = mavenFiles, - isLoading = false, - projectName = defaultProjectName, - } = {}) { - store = new Vuex.Store({ - state: { - isLoading, - packageEntity, - packageFiles, - canDelete: true, - emptySvgPath: 'empty-illustration', - npmPath: 'foo', - npmHelpPath: 'foo', - projectName, - projectListUrl: 'project_url', - groupListUrl: 'group_url', - }, - actions: { - deletePackage, - fetchPackageVersions, - deletePackageFile, - }, - getters, - }); - - wrapper = mount(PackagesApp, { - localVue, - store, - stubs: { - ...stubChildren(PackagesApp), - PackageTitle: false, - TitleArea: false, - GlButton: false, - GlModal: false, - GlTab: false, - GlTabs: false, - GlTable: false, - }, - }); - } - - const packageTitle = () => wrapper.find(PackageTitle); - const emptyState = () => wrapper.find(GlEmptyState); - const deleteButton = () => wrapper.find('.js-delete-button'); - const findDeleteModal = () => wrapper.find({ ref: 'deleteModal' }); - const findDeleteFileModal = () => wrapper.find({ ref: 'deleteFileModal' }); - const versionsTab = () => wrapper.find('.js-versions-tab > a'); - const packagesLoader = () => wrapper.find(PackagesListLoader); - const packagesVersionRows = () => wrapper.findAll(PackageListRow); - const noVersionsMessage = () => wrapper.find('[data-testid="no-versions-message"]'); - const dependenciesTab = () => wrapper.find('.js-dependencies-tab > a'); - const dependenciesCountBadge = () => wrapper.find('[data-testid="dependencies-badge"]'); - const noDependenciesMessage = () => wrapper.find('[data-testid="no-dependencies-message"]'); - const dependencyRows = () => wrapper.findAll(DependencyRow); - const findPackageHistory = () => wrapper.find(PackageHistory); - const findAdditionalMetadata = () => wrapper.find(AdditionalMetadata); - const findInstallationCommands = () => wrapper.find(InstallationCommands); - const findPackageFiles = () => wrapper.find(PackageFiles); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders the app and displays the package title', async () => { - createComponent(); - - await nextTick(); - - expect(packageTitle().exists()).toBe(true); - }); - - it('renders an empty state component when no an invalid package is passed as a prop', () => { - createComponent({ - packageEntity: {}, - }); - - expect(emptyState().exists()).toBe(true); - }); - - it('package history has the right props', () => { - createComponent(); - expect(findPackageHistory().exists()).toBe(true); - expect(findPackageHistory().props('packageEntity')).toEqual(wrapper.vm.packageEntity); - expect(findPackageHistory().props('projectName')).toEqual(wrapper.vm.projectName); - }); - - it('additional metadata has the right props', () => { - createComponent(); - expect(findAdditionalMetadata().exists()).toBe(true); - expect(findAdditionalMetadata().props('packageEntity')).toEqual(wrapper.vm.packageEntity); - }); - - it('installation commands has the right props', () => { - createComponent(); - expect(findInstallationCommands().exists()).toBe(true); - expect(findInstallationCommands().props('packageEntity')).toEqual(wrapper.vm.packageEntity); - }); - - it('hides the files table if package type is COMPOSER', () => { - createComponent({ packageEntity: composerPackage }); - expect(findPackageFiles().exists()).toBe(false); - }); - - describe('deleting packages', () => { - beforeEach(() => { - createComponent(); - deleteButton().trigger('click'); - }); - - it('shows the delete confirmation modal when delete is clicked', () => { - expect(findDeleteModal().exists()).toBe(true); - }); - }); - - describe('deleting package files', () => { - it('shows the delete confirmation modal when delete is clicked', () => { - createComponent(); - findPackageFiles().vm.$emit('delete-file', mavenFiles[0]); - - expect(findDeleteFileModal().exists()).toBe(true); - }); - }); - - describe('versions', () => { - describe('api call', () => { - beforeEach(() => { - createComponent(); - }); - - it('makes api request on first click of tab', () => { - versionsTab().trigger('click'); - - expect(fetchPackageVersions).toHaveBeenCalled(); - }); - }); - - it('displays the loader when state is loading', () => { - createComponent({ isLoading: true }); - - expect(packagesLoader().exists()).toBe(true); - }); - - it('displays the correct version count when the package has versions', () => { - createComponent({ packageEntity: npmPackage }); - - expect(packagesVersionRows()).toHaveLength(npmPackage.versions.length); - }); - - it('displays the no versions message when there are none', () => { - createComponent(); - - expect(noVersionsMessage().exists()).toBe(true); - }); - }); - - describe('dependency links', () => { - it('does not show the dependency links for a non nuget package', () => { - createComponent(); - - expect(dependenciesTab().exists()).toBe(false); - }); - - it('shows the dependencies tab with 0 count when a nuget package with no dependencies', () => { - createComponent({ - packageEntity: { - ...nugetPackage, - dependency_links: [], - }, - }); - - return wrapper.vm.$nextTick(() => { - const dependenciesBadge = dependenciesCountBadge(); - - expect(dependenciesTab().exists()).toBe(true); - expect(dependenciesBadge.exists()).toBe(true); - expect(dependenciesBadge.text()).toBe('0'); - expect(noDependenciesMessage().exists()).toBe(true); - }); - }); - - it('renders the correct number of dependency rows for a nuget package', () => { - createComponent({ packageEntity: nugetPackage }); - - return wrapper.vm.$nextTick(() => { - const dependenciesBadge = dependenciesCountBadge(); - - expect(dependenciesTab().exists()).toBe(true); - expect(dependenciesBadge.exists()).toBe(true); - expect(dependenciesBadge.text()).toBe(nugetPackage.dependency_links.length.toString()); - expect(dependencyRows()).toHaveLength(nugetPackage.dependency_links.length); - }); - }); - }); - - describe('tracking and delete', () => { - describe('delete package', () => { - const originalReferrer = document.referrer; - const setReferrer = (value = defaultProjectName) => { - Object.defineProperty(document, 'referrer', { - value, - configurable: true, - }); - }; - - afterEach(() => { - Object.defineProperty(document, 'referrer', { - value: originalReferrer, - configurable: true, - }); - }); - - it('calls the proper vuex action', () => { - createComponent({ packageEntity: npmPackage }); - findDeleteModal().vm.$emit('primary'); - expect(deletePackage).toHaveBeenCalled(); - }); - - it('when referrer contains project name calls window.replace with project url', async () => { - setReferrer(); - deletePackage.mockResolvedValue(); - createComponent({ packageEntity: npmPackage }); - findDeleteModal().vm.$emit('primary'); - await deletePackage(); - expect(window.location.replace).toHaveBeenCalledWith( - 'project_url?showSuccessDeleteAlert=true', - ); - }); - - it('when referrer does not contain project name calls window.replace with group url', async () => { - setReferrer('baz'); - deletePackage.mockResolvedValue(); - createComponent({ packageEntity: npmPackage }); - findDeleteModal().vm.$emit('primary'); - await deletePackage(); - expect(window.location.replace).toHaveBeenCalledWith( - 'group_url?showSuccessDeleteAlert=true', - ); - }); - }); - - describe('delete file', () => { - it('calls the proper vuex action', () => { - createComponent({ packageEntity: npmPackage }); - - findPackageFiles().vm.$emit('delete-file', mavenFiles[0]); - findDeleteFileModal().vm.$emit('primary'); - - expect(deletePackageFile).toHaveBeenCalled(); - }); - }); - - describe('tracking', () => { - let eventSpy; - let utilSpy; - const category = 'foo'; - - beforeEach(() => { - eventSpy = jest.spyOn(Tracking, 'event'); - utilSpy = jest.spyOn(SharedUtils, 'packageTypeToTrackCategory').mockReturnValue(category); - }); - - it('tracking category calls packageTypeToTrackCategory', () => { - createComponent({ packageEntity: conanPackage }); - expect(wrapper.vm.tracking.category).toBe(category); - expect(utilSpy).toHaveBeenCalledWith('conan'); - }); - - it(`delete button on delete modal call event with ${TrackingActions.DELETE_PACKAGE}`, () => { - createComponent({ packageEntity: npmPackage }); - findDeleteModal().vm.$emit('primary'); - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.DELETE_PACKAGE, - expect.any(Object), - ); - }); - - it(`canceling a package deletion tracks ${TrackingActions.CANCEL_DELETE_PACKAGE}`, () => { - createComponent({ packageEntity: npmPackage }); - - findDeleteModal().vm.$emit('canceled'); - - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.CANCEL_DELETE_PACKAGE, - expect.any(Object), - ); - }); - - it(`request a file deletion tracks ${TrackingActions.REQUEST_DELETE_PACKAGE_FILE}`, () => { - createComponent({ packageEntity: npmPackage }); - - findPackageFiles().vm.$emit('delete-file', mavenFiles[0]); - - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.REQUEST_DELETE_PACKAGE_FILE, - expect.any(Object), - ); - }); - - it(`confirming a file deletion tracks ${TrackingActions.DELETE_PACKAGE_FILE}`, () => { - createComponent({ packageEntity: npmPackage }); - - findPackageFiles().vm.$emit('delete-file', npmPackage); - findDeleteFileModal().vm.$emit('primary'); - - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.REQUEST_DELETE_PACKAGE_FILE, - expect.any(Object), - ); - }); - - it(`canceling a file deletion tracks ${TrackingActions.CANCEL_DELETE_PACKAGE_FILE}`, () => { - createComponent({ packageEntity: npmPackage }); - - findPackageFiles().vm.$emit('delete-file', npmPackage); - findDeleteFileModal().vm.$emit('canceled'); - - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.CANCEL_DELETE_PACKAGE_FILE, - expect.any(Object), - ); - }); - - it(`file download link call event with ${TrackingActions.PULL_PACKAGE}`, () => { - createComponent({ packageEntity: conanPackage }); - - findPackageFiles().vm.$emit('download-file'); - expect(eventSpy).toHaveBeenCalledWith( - category, - TrackingActions.PULL_PACKAGE, - expect.any(Object), - ); - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/composer_installation_spec.js b/spec/frontend/packages/details/components/composer_installation_spec.js deleted file mode 100644 index 18d11c7dd57..00000000000 --- a/spec/frontend/packages/details/components/composer_installation_spec.js +++ /dev/null @@ -1,133 +0,0 @@ -import { GlSprintf, GlLink } from '@gitlab/ui'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import { registryUrl as composerHelpPath } from 'jest/packages/details/mock_data'; -import { composerPackage as packageEntity } from 'jest/packages/mock_data'; -import ComposerInstallation from '~/packages/details/components/composer_installation.vue'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; - -import { TrackingActions } from '~/packages/details/constants'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('ComposerInstallation', () => { - let wrapper; - let store; - - const composerRegistryIncludeStr = 'foo/registry'; - const composerPackageIncludeStr = 'foo/package'; - - const createStore = (groupExists = true) => { - store = new Vuex.Store({ - state: { packageEntity, composerHelpPath }, - getters: { - composerRegistryInclude: () => composerRegistryIncludeStr, - composerPackageInclude: () => composerPackageIncludeStr, - groupExists: () => groupExists, - }, - }); - }; - - const findRootNode = () => wrapper.find('[data-testid="root-node"]'); - const findRegistryInclude = () => wrapper.find('[data-testid="registry-include"]'); - const findPackageInclude = () => wrapper.find('[data-testid="package-include"]'); - const findHelpText = () => wrapper.find('[data-testid="help-text"]'); - const findHelpLink = () => wrapper.find(GlLink); - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent() { - wrapper = shallowMount(ComposerInstallation, { - localVue, - store, - stubs: { - GlSprintf, - }, - }); - } - - afterEach(() => { - wrapper.destroy(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - createStore(); - createComponent(); - - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'composer', - options: [{ value: 'composer', label: 'Show Composer commands' }], - }); - }); - }); - - describe('registry include command', () => { - beforeEach(() => { - createStore(); - createComponent(); - }); - - it('uses code_instructions', () => { - const registryIncludeCommand = findRegistryInclude(); - expect(registryIncludeCommand.exists()).toBe(true); - expect(registryIncludeCommand.props()).toMatchObject({ - instruction: composerRegistryIncludeStr, - copyText: 'Copy registry include', - trackingAction: TrackingActions.COPY_COMPOSER_REGISTRY_INCLUDE_COMMAND, - }); - }); - - it('has the correct title', () => { - expect(findRegistryInclude().props('label')).toBe('Add composer registry'); - }); - }); - - describe('package include command', () => { - beforeEach(() => { - createStore(); - createComponent(); - }); - - it('uses code_instructions', () => { - const registryIncludeCommand = findPackageInclude(); - expect(registryIncludeCommand.exists()).toBe(true); - expect(registryIncludeCommand.props()).toMatchObject({ - instruction: composerPackageIncludeStr, - copyText: 'Copy require package include', - trackingAction: TrackingActions.COPY_COMPOSER_PACKAGE_INCLUDE_COMMAND, - }); - }); - - it('has the correct title', () => { - expect(findPackageInclude().props('label')).toBe('Install package version'); - }); - - it('has the correct help text', () => { - expect(findHelpText().text()).toBe( - 'For more information on Composer packages in GitLab, see the documentation.', - ); - expect(findHelpLink().attributes()).toMatchObject({ - href: composerHelpPath, - target: '_blank', - }); - }); - }); - - describe('root node', () => { - it('is normally rendered', () => { - createStore(); - createComponent(); - - expect(findRootNode().exists()).toBe(true); - }); - - it('is not rendered when the group does not exist', () => { - createStore(false); - createComponent(); - - expect(findRootNode().exists()).toBe(false); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/conan_installation_spec.js b/spec/frontend/packages/details/components/conan_installation_spec.js deleted file mode 100644 index 78a7d265a21..00000000000 --- a/spec/frontend/packages/details/components/conan_installation_spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import ConanInstallation from '~/packages/details/components/conan_installation.vue'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue'; -import { conanPackage as packageEntity } from '../../mock_data'; -import { registryUrl as conanPath } from '../mock_data'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('ConanInstallation', () => { - let wrapper; - - const conanInstallationCommandStr = 'foo/command'; - const conanSetupCommandStr = 'foo/setup'; - - const store = new Vuex.Store({ - state: { - packageEntity, - conanPath, - }, - getters: { - conanInstallationCommand: () => conanInstallationCommandStr, - conanSetupCommand: () => conanSetupCommandStr, - }, - }); - - const findCodeInstructions = () => wrapper.findAll(CodeInstructions); - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent() { - wrapper = shallowMount(ConanInstallation, { - localVue, - store, - }); - } - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'conan', - options: [{ value: 'conan', label: 'Show Conan commands' }], - }); - }); - }); - - describe('installation commands', () => { - it('renders the correct command', () => { - expect(findCodeInstructions().at(0).props('instruction')).toBe(conanInstallationCommandStr); - }); - }); - - describe('setup commands', () => { - it('renders the correct command', () => { - expect(findCodeInstructions().at(1).props('instruction')).toBe(conanSetupCommandStr); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/dependency_row_spec.js b/spec/frontend/packages/details/components/dependency_row_spec.js deleted file mode 100644 index 7d3ee92908d..00000000000 --- a/spec/frontend/packages/details/components/dependency_row_spec.js +++ /dev/null @@ -1,62 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import DependencyRow from '~/packages/details/components/dependency_row.vue'; -import { dependencyLinks } from '../../mock_data'; - -describe('DependencyRow', () => { - let wrapper; - - const { withoutFramework, withoutVersion, fullLink } = dependencyLinks; - - function createComponent({ dependencyLink = fullLink } = {}) { - wrapper = shallowMount(DependencyRow, { - propsData: { - dependency: dependencyLink, - }, - }); - } - - const dependencyVersion = () => wrapper.find('[data-testid="version-pattern"]'); - const dependencyFramework = () => wrapper.find('[data-testid="target-framework"]'); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('renders', () => { - it('full dependency', () => { - createComponent(); - - expect(wrapper.element).toMatchSnapshot(); - }); - }); - - describe('version', () => { - it('does not render any version information when not supplied', () => { - createComponent({ dependencyLink: withoutVersion }); - - expect(dependencyVersion().exists()).toBe(false); - }); - - it('does render version info when it exists', () => { - createComponent(); - - expect(dependencyVersion().exists()).toBe(true); - expect(dependencyVersion().text()).toBe(fullLink.version_pattern); - }); - }); - - describe('target framework', () => { - it('does not render any framework information when not supplied', () => { - createComponent({ dependencyLink: withoutFramework }); - - expect(dependencyFramework().exists()).toBe(false); - }); - - it('does render framework info when it exists', () => { - createComponent(); - - expect(dependencyFramework().exists()).toBe(true); - expect(dependencyFramework().text()).toBe(`(${fullLink.target_framework})`); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/file_sha_spec.js b/spec/frontend/packages/details/components/file_sha_spec.js deleted file mode 100644 index 7bfcf78baab..00000000000 --- a/spec/frontend/packages/details/components/file_sha_spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; - -import FileSha from '~/packages/details/components/file_sha.vue'; -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; -import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; - -describe('FileSha', () => { - let wrapper; - - const defaultProps = { sha: 'foo', title: 'bar' }; - - function createComponent() { - wrapper = shallowMount(FileSha, { - propsData: { - ...defaultProps, - }, - stubs: { - ClipboardButton, - DetailsRow, - }, - }); - } - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders', () => { - createComponent(); - - expect(wrapper.element).toMatchSnapshot(); - }); -}); diff --git a/spec/frontend/packages/details/components/installation_title_spec.js b/spec/frontend/packages/details/components/installation_title_spec.js deleted file mode 100644 index 14e990d3011..00000000000 --- a/spec/frontend/packages/details/components/installation_title_spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; - -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import PersistedDropdownSelection from '~/vue_shared/components/registry/persisted_dropdown_selection.vue'; - -describe('InstallationTitle', () => { - let wrapper; - - const defaultProps = { packageType: 'foo', options: [{ value: 'foo', label: 'bar' }] }; - - const findPersistedDropdownSelection = () => wrapper.findComponent(PersistedDropdownSelection); - const findTitle = () => wrapper.find('h3'); - - function createComponent({ props = {} } = {}) { - wrapper = shallowMount(InstallationTitle, { - propsData: { - ...defaultProps, - ...props, - }, - }); - } - - afterEach(() => { - wrapper.destroy(); - }); - - it('has a title', () => { - createComponent(); - - expect(findTitle().exists()).toBe(true); - expect(findTitle().text()).toBe('Installation'); - }); - - describe('persisted dropdown selection', () => { - it('exists', () => { - createComponent(); - - expect(findPersistedDropdownSelection().exists()).toBe(true); - }); - - it('has the correct props', () => { - createComponent(); - - expect(findPersistedDropdownSelection().props()).toMatchObject({ - storageKey: 'package_foo_installation_instructions', - options: defaultProps.options, - }); - }); - - it('on change event emits a change event', () => { - createComponent(); - - findPersistedDropdownSelection().vm.$emit('change', 'baz'); - - expect(wrapper.emitted('change')).toEqual([['baz']]); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/installations_commands_spec.js b/spec/frontend/packages/details/components/installations_commands_spec.js deleted file mode 100644 index 164f9f69741..00000000000 --- a/spec/frontend/packages/details/components/installations_commands_spec.js +++ /dev/null @@ -1,61 +0,0 @@ -import { shallowMount } from '@vue/test-utils'; -import ComposerInstallation from '~/packages/details/components/composer_installation.vue'; -import ConanInstallation from '~/packages/details/components/conan_installation.vue'; -import InstallationCommands from '~/packages/details/components/installation_commands.vue'; - -import MavenInstallation from '~/packages/details/components/maven_installation.vue'; -import NpmInstallation from '~/packages/details/components/npm_installation.vue'; -import NugetInstallation from '~/packages/details/components/nuget_installation.vue'; -import PypiInstallation from '~/packages/details/components/pypi_installation.vue'; -import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/components/terraform_installation.vue'; - -import { - conanPackage, - mavenPackage, - npmPackage, - nugetPackage, - pypiPackage, - composerPackage, - terraformModule, -} from '../../mock_data'; - -describe('InstallationCommands', () => { - let wrapper; - - function createComponent(propsData) { - wrapper = shallowMount(InstallationCommands, { - propsData, - }); - } - - const npmInstallation = () => wrapper.find(NpmInstallation); - const mavenInstallation = () => wrapper.find(MavenInstallation); - const conanInstallation = () => wrapper.find(ConanInstallation); - const nugetInstallation = () => wrapper.find(NugetInstallation); - const pypiInstallation = () => wrapper.find(PypiInstallation); - const composerInstallation = () => wrapper.find(ComposerInstallation); - const terraformInstallation = () => wrapper.findComponent(TerraformInstallation); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('installation instructions', () => { - describe.each` - packageEntity | selector - ${conanPackage} | ${conanInstallation} - ${mavenPackage} | ${mavenInstallation} - ${npmPackage} | ${npmInstallation} - ${nugetPackage} | ${nugetInstallation} - ${pypiPackage} | ${pypiInstallation} - ${composerPackage} | ${composerInstallation} - ${terraformModule} | ${terraformInstallation} - `('renders', ({ packageEntity, selector }) => { - it(`${packageEntity.package_type} instructions exist`, () => { - createComponent({ packageEntity }); - - expect(selector()).toExist(); - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/maven_installation_spec.js b/spec/frontend/packages/details/components/maven_installation_spec.js deleted file mode 100644 index 4972fe70a3d..00000000000 --- a/spec/frontend/packages/details/components/maven_installation_spec.js +++ /dev/null @@ -1,184 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { nextTick } from 'vue'; -import Vuex from 'vuex'; -import { registryUrl as mavenPath } from 'jest/packages/details/mock_data'; -import { mavenPackage as packageEntity } from 'jest/packages/mock_data'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import MavenInstallation from '~/packages/details/components/maven_installation.vue'; -import { TrackingActions } from '~/packages/details/constants'; -import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('MavenInstallation', () => { - let wrapper; - - const xmlCodeBlock = 'foo/xml'; - const mavenCommandStr = 'foo/command'; - const mavenSetupXml = 'foo/setup'; - const gradleGroovyInstallCommandText = 'foo/gradle/groovy/install'; - const gradleGroovyAddSourceCommandText = 'foo/gradle/groovy/add/source'; - const gradleKotlinInstallCommandText = 'foo/gradle/kotlin/install'; - const gradleKotlinAddSourceCommandText = 'foo/gradle/kotlin/add/source'; - - const store = new Vuex.Store({ - state: { - packageEntity, - mavenPath, - }, - getters: { - mavenInstallationXml: () => xmlCodeBlock, - mavenInstallationCommand: () => mavenCommandStr, - mavenSetupXml: () => mavenSetupXml, - gradleGroovyInstalCommand: () => gradleGroovyInstallCommandText, - gradleGroovyAddSourceCommand: () => gradleGroovyAddSourceCommandText, - gradleKotlinInstalCommand: () => gradleKotlinInstallCommandText, - gradleKotlinAddSourceCommand: () => gradleKotlinAddSourceCommandText, - }, - }); - - const findCodeInstructions = () => wrapper.findAll(CodeInstructions); - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent({ data = {} } = {}) { - wrapper = shallowMount(MavenInstallation, { - localVue, - store, - data() { - return data; - }, - }); - } - - afterEach(() => { - wrapper.destroy(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - createComponent(); - - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'maven', - options: [ - { value: 'maven', label: 'Maven XML' }, - { value: 'groovy', label: 'Gradle Groovy DSL' }, - { value: 'kotlin', label: 'Gradle Kotlin DSL' }, - ], - }); - }); - - it('on change event updates the instructions to show', async () => { - createComponent(); - - expect(findCodeInstructions().at(0).props('instruction')).toBe(xmlCodeBlock); - findInstallationTitle().vm.$emit('change', 'groovy'); - - await nextTick(); - - expect(findCodeInstructions().at(0).props('instruction')).toBe( - gradleGroovyInstallCommandText, - ); - }); - }); - - describe('maven', () => { - beforeEach(() => { - createComponent(); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('installation commands', () => { - it('renders the correct xml block', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: xmlCodeBlock, - multiline: true, - trackingAction: TrackingActions.COPY_MAVEN_XML, - }); - }); - - it('renders the correct maven command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: mavenCommandStr, - multiline: false, - trackingAction: TrackingActions.COPY_MAVEN_COMMAND, - }); - }); - }); - - describe('setup commands', () => { - it('renders the correct xml block', () => { - expect(findCodeInstructions().at(2).props()).toMatchObject({ - instruction: mavenSetupXml, - multiline: true, - trackingAction: TrackingActions.COPY_MAVEN_SETUP, - }); - }); - }); - }); - - describe('groovy', () => { - beforeEach(() => { - createComponent({ data: { instructionType: 'groovy' } }); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('installation commands', () => { - it('renders the gradle install command', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: gradleGroovyInstallCommandText, - multiline: false, - trackingAction: TrackingActions.COPY_GRADLE_INSTALL_COMMAND, - }); - }); - }); - - describe('setup commands', () => { - it('renders the correct gradle command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: gradleGroovyAddSourceCommandText, - multiline: true, - trackingAction: TrackingActions.COPY_GRADLE_ADD_TO_SOURCE_COMMAND, - }); - }); - }); - }); - - describe('kotlin', () => { - beforeEach(() => { - createComponent({ data: { instructionType: 'kotlin' } }); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('installation commands', () => { - it('renders the gradle install command', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: gradleKotlinInstallCommandText, - multiline: false, - trackingAction: TrackingActions.COPY_KOTLIN_INSTALL_COMMAND, - }); - }); - }); - - describe('setup commands', () => { - it('renders the correct gradle command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: gradleKotlinAddSourceCommandText, - multiline: true, - trackingAction: TrackingActions.COPY_KOTLIN_ADD_TO_SOURCE_COMMAND, - }); - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/npm_installation_spec.js b/spec/frontend/packages/details/components/npm_installation_spec.js deleted file mode 100644 index 1c49110bdf8..00000000000 --- a/spec/frontend/packages/details/components/npm_installation_spec.js +++ /dev/null @@ -1,123 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import { nextTick } from 'vue'; -import Vuex from 'vuex'; -import { registryUrl as nugetPath } from 'jest/packages/details/mock_data'; -import { npmPackage as packageEntity } from 'jest/packages/mock_data'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import NpmInstallation from '~/packages/details/components/npm_installation.vue'; -import { TrackingActions } from '~/packages/details/constants'; -import { npmInstallationCommand, npmSetupCommand } from '~/packages/details/store/getters'; -import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('NpmInstallation', () => { - let wrapper; - - const npmInstallationCommandLabel = 'npm i @Test/package'; - const yarnInstallationCommandLabel = 'yarn add @Test/package'; - - const findCodeInstructions = () => wrapper.findAll(CodeInstructions); - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent({ data = {} } = {}) { - const store = new Vuex.Store({ - state: { - packageEntity, - nugetPath, - }, - getters: { - npmInstallationCommand, - npmSetupCommand, - }, - }); - - wrapper = shallowMount(NpmInstallation, { - localVue, - store, - data() { - return data; - }, - }); - } - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'npm', - options: [ - { value: 'npm', label: 'Show NPM commands' }, - { value: 'yarn', label: 'Show Yarn commands' }, - ], - }); - }); - - it('on change event updates the instructions to show', async () => { - createComponent(); - - expect(findCodeInstructions().at(0).props('instruction')).toBe(npmInstallationCommandLabel); - findInstallationTitle().vm.$emit('change', 'yarn'); - - await nextTick(); - - expect(findCodeInstructions().at(0).props('instruction')).toBe(yarnInstallationCommandLabel); - }); - }); - - describe('npm', () => { - beforeEach(() => { - createComponent(); - }); - it('renders the correct installation command', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: npmInstallationCommandLabel, - multiline: false, - trackingAction: TrackingActions.COPY_NPM_INSTALL_COMMAND, - }); - }); - - it('renders the correct setup command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: 'echo @Test:registry=undefined/ >> .npmrc', - multiline: false, - trackingAction: TrackingActions.COPY_NPM_SETUP_COMMAND, - }); - }); - }); - - describe('yarn', () => { - beforeEach(() => { - createComponent({ data: { instructionType: 'yarn' } }); - }); - - it('renders the correct setup command', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: yarnInstallationCommandLabel, - multiline: false, - trackingAction: TrackingActions.COPY_YARN_INSTALL_COMMAND, - }); - }); - - it('renders the correct registry command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: 'echo \\"@Test:registry\\" \\"undefined/\\" >> .yarnrc', - multiline: false, - trackingAction: TrackingActions.COPY_YARN_SETUP_COMMAND, - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/nuget_installation_spec.js b/spec/frontend/packages/details/components/nuget_installation_spec.js deleted file mode 100644 index 8839a8f1108..00000000000 --- a/spec/frontend/packages/details/components/nuget_installation_spec.js +++ /dev/null @@ -1,79 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import { registryUrl as nugetPath } from 'jest/packages/details/mock_data'; -import { nugetPackage as packageEntity } from 'jest/packages/mock_data'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import NugetInstallation from '~/packages/details/components/nuget_installation.vue'; -import { TrackingActions } from '~/packages/details/constants'; -import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('NugetInstallation', () => { - let wrapper; - - const nugetInstallationCommandStr = 'foo/command'; - const nugetSetupCommandStr = 'foo/setup'; - - const store = new Vuex.Store({ - state: { - packageEntity, - nugetPath, - }, - getters: { - nugetInstallationCommand: () => nugetInstallationCommandStr, - nugetSetupCommand: () => nugetSetupCommandStr, - }, - }); - - const findCodeInstructions = () => wrapper.findAll(CodeInstructions); - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent() { - wrapper = shallowMount(NugetInstallation, { - localVue, - store, - }); - } - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'nuget', - options: [{ value: 'nuget', label: 'Show Nuget commands' }], - }); - }); - }); - - describe('installation commands', () => { - it('renders the correct command', () => { - expect(findCodeInstructions().at(0).props()).toMatchObject({ - instruction: nugetInstallationCommandStr, - trackingAction: TrackingActions.COPY_NUGET_INSTALL_COMMAND, - }); - }); - }); - - describe('setup commands', () => { - it('renders the correct command', () => { - expect(findCodeInstructions().at(1).props()).toMatchObject({ - instruction: nugetSetupCommandStr, - trackingAction: TrackingActions.COPY_NUGET_SETUP_COMMAND, - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/package_files_spec.js b/spec/frontend/packages/details/components/package_files_spec.js deleted file mode 100644 index e8e5a24d3a3..00000000000 --- a/spec/frontend/packages/details/components/package_files_spec.js +++ /dev/null @@ -1,259 +0,0 @@ -import { GlDropdown, GlButton } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; -import { nextTick } from 'vue/'; -import stubChildren from 'helpers/stub_children'; -import component from '~/packages/details/components/package_files.vue'; -import FileIcon from '~/vue_shared/components/file_icon.vue'; -import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; - -import { npmFiles, mavenFiles } from '../../mock_data'; - -describe('Package Files', () => { - let wrapper; - - const findAllRows = () => wrapper.findAll('[data-testid="file-row"'); - const findFirstRow = () => findAllRows().at(0); - const findSecondRow = () => findAllRows().at(1); - const findFirstRowDownloadLink = () => findFirstRow().find('[data-testid="download-link"]'); - const findFirstRowCommitLink = () => findFirstRow().find('[data-testid="commit-link"]'); - const findSecondRowCommitLink = () => findSecondRow().find('[data-testid="commit-link"]'); - const findFirstRowFileIcon = () => findFirstRow().find(FileIcon); - const findFirstRowCreatedAt = () => findFirstRow().find(TimeAgoTooltip); - const findFirstActionMenu = () => findFirstRow().findComponent(GlDropdown); - const findActionMenuDelete = () => findFirstActionMenu().find('[data-testid="delete-file"]'); - const findFirstToggleDetailsButton = () => findFirstRow().findComponent(GlButton); - const findFirstRowShaComponent = (id) => wrapper.find(`[data-testid="${id}"]`); - - const createComponent = ({ packageFiles = npmFiles, canDelete = true } = {}) => { - wrapper = mount(component, { - propsData: { - packageFiles, - canDelete, - }, - stubs: { - ...stubChildren(component), - GlTable: false, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('rows', () => { - it('renders a single file for an npm package', () => { - createComponent(); - - expect(findAllRows()).toHaveLength(1); - }); - - it('renders multiple files for a package that contains more than one file', () => { - createComponent({ packageFiles: mavenFiles }); - - expect(findAllRows()).toHaveLength(2); - }); - }); - - describe('link', () => { - it('exists', () => { - createComponent(); - - expect(findFirstRowDownloadLink().exists()).toBe(true); - }); - - it('has the correct attrs bound', () => { - createComponent(); - - expect(findFirstRowDownloadLink().attributes('href')).toBe(npmFiles[0].download_path); - }); - - it('emits "download-file" event on click', () => { - createComponent(); - - findFirstRowDownloadLink().vm.$emit('click'); - - expect(wrapper.emitted('download-file')).toEqual([[]]); - }); - }); - - describe('file-icon', () => { - it('exists', () => { - createComponent(); - - expect(findFirstRowFileIcon().exists()).toBe(true); - }); - - it('has the correct props bound', () => { - createComponent(); - - expect(findFirstRowFileIcon().props('fileName')).toBe(npmFiles[0].file_name); - }); - }); - - describe('time-ago tooltip', () => { - it('exists', () => { - createComponent(); - - expect(findFirstRowCreatedAt().exists()).toBe(true); - }); - - it('has the correct props bound', () => { - createComponent(); - - expect(findFirstRowCreatedAt().props('time')).toBe(npmFiles[0].created_at); - }); - }); - - describe('commit', () => { - describe('when package file has a pipeline associated', () => { - it('exists', () => { - createComponent(); - - expect(findFirstRowCommitLink().exists()).toBe(true); - }); - - it('the link points to the commit url', () => { - createComponent(); - - expect(findFirstRowCommitLink().attributes('href')).toBe( - npmFiles[0].pipelines[0].project.commit_url, - ); - }); - - it('the text is git_commit_message', () => { - createComponent(); - - expect(findFirstRowCommitLink().text()).toBe(npmFiles[0].pipelines[0].git_commit_message); - }); - }); - describe('when package file has no pipeline associated', () => { - it('does not exist', () => { - createComponent({ packageFiles: mavenFiles }); - - expect(findFirstRowCommitLink().exists()).toBe(false); - }); - }); - - describe('when only one file lacks an associated pipeline', () => { - it('renders the commit when it exists and not otherwise', () => { - createComponent({ packageFiles: [npmFiles[0], mavenFiles[0]] }); - - expect(findFirstRowCommitLink().exists()).toBe(true); - expect(findSecondRowCommitLink().exists()).toBe(false); - }); - }); - - describe('action menu', () => { - describe('when the user can delete', () => { - it('exists', () => { - createComponent(); - - expect(findFirstActionMenu().exists()).toBe(true); - }); - - describe('menu items', () => { - describe('delete file', () => { - it('exists', () => { - createComponent(); - - expect(findActionMenuDelete().exists()).toBe(true); - }); - - it('emits a delete event when clicked', () => { - createComponent(); - - findActionMenuDelete().vm.$emit('click'); - - const [[{ id }]] = wrapper.emitted('delete-file'); - expect(id).toBe(npmFiles[0].id); - }); - }); - }); - }); - - describe('when the user can not delete', () => { - const canDelete = false; - - it('does not exist', () => { - createComponent({ canDelete }); - - expect(findFirstActionMenu().exists()).toBe(false); - }); - }); - }); - }); - - describe('additional details', () => { - describe('details toggle button', () => { - it('exists', () => { - createComponent(); - - expect(findFirstToggleDetailsButton().exists()).toBe(true); - }); - - it('is hidden when no details is present', () => { - const [{ ...noShaFile }] = npmFiles; - noShaFile.file_sha256 = null; - noShaFile.file_md5 = null; - noShaFile.file_sha1 = null; - createComponent({ packageFiles: [noShaFile] }); - - expect(findFirstToggleDetailsButton().exists()).toBe(false); - }); - - it('toggles the details row', async () => { - createComponent(); - - expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down'); - - findFirstToggleDetailsButton().vm.$emit('click'); - await nextTick(); - - expect(findFirstRowShaComponent('sha-256').exists()).toBe(true); - expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-up'); - - findFirstToggleDetailsButton().vm.$emit('click'); - await nextTick(); - - expect(findFirstRowShaComponent('sha-256').exists()).toBe(false); - expect(findFirstToggleDetailsButton().props('icon')).toBe('angle-down'); - }); - }); - - describe('file shas', () => { - const showShaFiles = () => { - findFirstToggleDetailsButton().vm.$emit('click'); - return nextTick(); - }; - - it.each` - selector | title | sha - ${'sha-256'} | ${'SHA-256'} | ${'file_sha256'} - ${'md5'} | ${'MD5'} | ${'file_md5'} - ${'sha-1'} | ${'SHA-1'} | ${'file_sha1'} - `('has a $title row', async ({ selector, title, sha }) => { - createComponent(); - - await showShaFiles(); - - expect(findFirstRowShaComponent(selector).props()).toMatchObject({ - title, - sha, - }); - }); - - it('does not display a row when the data is missing', async () => { - const [{ ...missingMd5 }] = npmFiles; - missingMd5.file_md5 = null; - - createComponent({ packageFiles: [missingMd5] }); - - await showShaFiles(); - - expect(findFirstRowShaComponent('md5').exists()).toBe(false); - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/package_history_spec.js b/spec/frontend/packages/details/components/package_history_spec.js deleted file mode 100644 index 244805a9c82..00000000000 --- a/spec/frontend/packages/details/components/package_history_spec.js +++ /dev/null @@ -1,117 +0,0 @@ -import { GlLink, GlSprintf } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; -import { stubComponent } from 'helpers/stub_component'; -import component from '~/packages/details/components/package_history.vue'; -import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants'; -import HistoryItem from '~/vue_shared/components/registry/history_item.vue'; -import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; - -import { mavenPackage, mockPipelineInfo } from '../../mock_data'; - -describe('Package History', () => { - let wrapper; - const defaultProps = { - projectName: 'baz project', - packageEntity: { ...mavenPackage }, - }; - - const createPipelines = (amount) => - [...Array(amount)].map((x, index) => ({ ...mockPipelineInfo, id: index + 1 })); - - const mountComponent = (props) => { - wrapper = shallowMount(component, { - propsData: { ...defaultProps, ...props }, - stubs: { - HistoryItem: stubComponent(HistoryItem, { - template: '<div data-testid="history-element"><slot></slot></div>', - }), - GlSprintf, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - const findHistoryElement = (testId) => wrapper.find(`[data-testid="${testId}"]`); - const findElementLink = (container) => container.find(GlLink); - const findElementTimeAgo = (container) => container.find(TimeAgoTooltip); - const findTitle = () => wrapper.find('[data-testid="title"]'); - const findTimeline = () => wrapper.find('[data-testid="timeline"]'); - - it('has the correct title', () => { - mountComponent(); - - const title = findTitle(); - - expect(title.exists()).toBe(true); - expect(title.text()).toBe('History'); - }); - - it('has a timeline container', () => { - mountComponent(); - - const title = findTimeline(); - - expect(title.exists()).toBe(true); - expect(title.classes()).toEqual( - expect.arrayContaining(['timeline', 'main-notes-list', 'notes']), - ); - }); - describe.each` - name | amount | icon | text | timeAgoTooltip | link - ${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'Test package version 1.0.0 was first created'} | ${mavenPackage.created_at} | ${null} - ${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit #sha-baz on branch branch-name'} | ${null} | ${mockPipelineInfo.project.commit_url} - ${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by foo'} | ${mockPipelineInfo.created_at} | ${mockPipelineInfo.project.pipeline_url} - ${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${mavenPackage.created_at} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null} - ${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null} - ${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit #sha-baz on branch branch-name, built by pipeline #3, and published to the registry'} | ${mavenPackage.created_at} | ${mockPipelineInfo.project.commit_url} - `( - 'with $amount pipelines history element $name', - ({ name, icon, text, timeAgoTooltip, link, amount }) => { - let element; - - beforeEach(() => { - mountComponent({ - packageEntity: { ...mavenPackage, pipelines: createPipelines(amount) }, - }); - element = findHistoryElement(name); - }); - - it('exists', () => { - expect(element.exists()).toBe(true); - }); - - it('has the correct icon', () => { - expect(element.props('icon')).toBe(icon); - }); - - it('has the correct text', () => { - expect(element.text()).toBe(text); - }); - - it('time-ago tooltip', () => { - const timeAgo = findElementTimeAgo(element); - const exist = Boolean(timeAgoTooltip); - - expect(timeAgo.exists()).toBe(exist); - if (exist) { - expect(timeAgo.props('time')).toBe(timeAgoTooltip); - } - }); - - it('link', () => { - const linkElement = findElementLink(element); - const exist = Boolean(link); - - expect(linkElement.exists()).toBe(exist); - if (exist) { - expect(linkElement.attributes('href')).toBe(link); - } - }); - }, - ); -}); diff --git a/spec/frontend/packages/details/components/package_title_spec.js b/spec/frontend/packages/details/components/package_title_spec.js deleted file mode 100644 index 512cec85b40..00000000000 --- a/spec/frontend/packages/details/components/package_title_spec.js +++ /dev/null @@ -1,189 +0,0 @@ -import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import PackageTitle from '~/packages/details/components/package_title.vue'; -import PackageTags from '~/packages/shared/components/package_tags.vue'; -import TitleArea from '~/vue_shared/components/registry/title_area.vue'; -import { - conanPackage, - mavenFiles, - mavenPackage, - mockTags, - npmFiles, - npmPackage, - nugetPackage, -} from '../../mock_data'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('PackageTitle', () => { - let wrapper; - let store; - - function createComponent({ - packageEntity = mavenPackage, - packageFiles = mavenFiles, - icon = null, - } = {}) { - store = new Vuex.Store({ - state: { - packageEntity, - packageFiles, - }, - getters: { - packageTypeDisplay: ({ packageEntity: { package_type: type } }) => type, - packagePipeline: ({ packageEntity: { pipeline = null } }) => pipeline, - packageIcon: () => icon, - }, - }); - - wrapper = shallowMount(PackageTitle, { - localVue, - store, - stubs: { - TitleArea, - }, - }); - return wrapper.vm.$nextTick(); - } - - const findTitleArea = () => wrapper.find(TitleArea); - const packageType = () => wrapper.find('[data-testid="package-type"]'); - const packageSize = () => wrapper.find('[data-testid="package-size"]'); - const pipelineProject = () => wrapper.find('[data-testid="pipeline-project"]'); - const packageRef = () => wrapper.find('[data-testid="package-ref"]'); - const packageTags = () => wrapper.find(PackageTags); - const packageBadges = () => wrapper.findAll('[data-testid="tag-badge"]'); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('renders', () => { - it('without tags', async () => { - await createComponent(); - - expect(wrapper.element).toMatchSnapshot(); - }); - - it('with tags', async () => { - await createComponent({ packageEntity: { ...mavenPackage, tags: mockTags } }); - - expect(wrapper.element).toMatchSnapshot(); - }); - - it('with tags on mobile', async () => { - jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false); - await createComponent({ packageEntity: { ...mavenPackage, tags: mockTags } }); - await wrapper.vm.$nextTick(); - - expect(packageBadges()).toHaveLength(mockTags.length); - }); - }); - - describe('package title', () => { - it('is correctly bound', async () => { - await createComponent(); - - expect(findTitleArea().props('title')).toBe('Test package'); - }); - }); - - describe('package icon', () => { - const fakeSrc = 'a-fake-src'; - - it('binds an icon when provided one from vuex', async () => { - await createComponent({ icon: fakeSrc }); - - expect(findTitleArea().props('avatar')).toBe(fakeSrc); - }); - - it('do not binds an icon when not provided one', async () => { - await createComponent(); - - expect(findTitleArea().props('avatar')).toBe(null); - }); - }); - - describe.each` - packageEntity | text - ${conanPackage} | ${'conan'} - ${mavenPackage} | ${'maven'} - ${npmPackage} | ${'npm'} - ${nugetPackage} | ${'nuget'} - `(`package type`, ({ packageEntity, text }) => { - beforeEach(() => createComponent({ packageEntity })); - - it(`${packageEntity.package_type} should render from Vuex getters ${text}`, () => { - expect(packageType().props()).toEqual(expect.objectContaining({ text, icon: 'package' })); - }); - }); - - describe('calculates the package size', () => { - it('correctly calculates when there is only 1 file', async () => { - await createComponent({ packageEntity: npmPackage, packageFiles: npmFiles }); - - expect(packageSize().props()).toMatchObject({ text: '200 bytes', icon: 'disk' }); - }); - - it('correctly calulates when there are multiple files', async () => { - await createComponent(); - - expect(packageSize().props('text')).toBe('300 bytes'); - }); - }); - - describe('package tags', () => { - it('displays the package-tags component when the package has tags', async () => { - await createComponent({ - packageEntity: { - ...npmPackage, - tags: mockTags, - }, - }); - - expect(packageTags().exists()).toBe(true); - }); - - it('does not display the package-tags component when there are no tags', async () => { - await createComponent(); - - expect(packageTags().exists()).toBe(false); - }); - }); - - describe('package ref', () => { - it('does not display the ref if missing', async () => { - await createComponent(); - - expect(packageRef().exists()).toBe(false); - }); - - it('correctly shows the package ref if there is one', async () => { - await createComponent({ packageEntity: npmPackage }); - expect(packageRef().props()).toMatchObject({ - text: npmPackage.pipeline.ref, - icon: 'branch', - }); - }); - }); - - describe('pipeline project', () => { - it('does not display the project if missing', async () => { - await createComponent(); - - expect(pipelineProject().exists()).toBe(false); - }); - - it('correctly shows the pipeline project if there is one', async () => { - await createComponent({ packageEntity: npmPackage }); - - expect(pipelineProject().props()).toMatchObject({ - text: npmPackage.pipeline.project.name, - icon: 'review-list', - link: npmPackage.pipeline.project.web_url, - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/components/pypi_installation_spec.js b/spec/frontend/packages/details/components/pypi_installation_spec.js deleted file mode 100644 index 2cec84282d9..00000000000 --- a/spec/frontend/packages/details/components/pypi_installation_spec.js +++ /dev/null @@ -1,72 +0,0 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; -import { pypiPackage as packageEntity } from 'jest/packages/mock_data'; -import InstallationTitle from '~/packages/details/components/installation_title.vue'; -import PypiInstallation from '~/packages/details/components/pypi_installation.vue'; - -const localVue = createLocalVue(); -localVue.use(Vuex); - -describe('PypiInstallation', () => { - let wrapper; - - const pipCommandStr = 'pip install'; - const pypiSetupStr = 'python setup'; - - const store = new Vuex.Store({ - state: { - packageEntity, - pypiHelpPath: 'foo', - }, - getters: { - pypiPipCommand: () => pipCommandStr, - pypiSetupCommand: () => pypiSetupStr, - }, - }); - - const pipCommand = () => wrapper.find('[data-testid="pip-command"]'); - const setupInstruction = () => wrapper.find('[data-testid="pypi-setup-content"]'); - - const findInstallationTitle = () => wrapper.findComponent(InstallationTitle); - - function createComponent() { - wrapper = shallowMount(PypiInstallation, { - localVue, - store, - }); - } - - beforeEach(() => { - createComponent(); - }); - - afterEach(() => { - wrapper.destroy(); - }); - - describe('install command switch', () => { - it('has the installation title component', () => { - expect(findInstallationTitle().exists()).toBe(true); - expect(findInstallationTitle().props()).toMatchObject({ - packageType: 'pypi', - options: [{ value: 'pypi', label: 'Show PyPi commands' }], - }); - }); - }); - - it('renders all the messages', () => { - expect(wrapper.element).toMatchSnapshot(); - }); - - describe('installation commands', () => { - it('renders the correct pip command', () => { - expect(pipCommand().props('instruction')).toBe(pipCommandStr); - }); - }); - - describe('setup commands', () => { - it('renders the correct setup block', () => { - expect(setupInstruction().props('instruction')).toBe(pypiSetupStr); - }); - }); -}); diff --git a/spec/frontend/packages/details/mock_data.js b/spec/frontend/packages/details/mock_data.js deleted file mode 100644 index d43abcedb2e..00000000000 --- a/spec/frontend/packages/details/mock_data.js +++ /dev/null @@ -1,47 +0,0 @@ -export const registryUrl = 'foo/registry'; - -export const mavenMetadata = { - app_group: 'com.test.package.app', - app_name: 'test-package-app', - app_version: '1.0.0', -}; - -export const generateMavenCommand = ({ - app_group: appGroup = '', - app_name: appName = '', - app_version: appVersion = '', -}) => `mvn dependency:get -Dartifact=${appGroup}:${appName}:${appVersion}`; - -export const generateXmlCodeBlock = ({ - app_group: appGroup = '', - app_name: appName = '', - app_version: appVersion = '', -}) => `<dependency> - <groupId>${appGroup}</groupId> - <artifactId>${appName}</artifactId> - <version>${appVersion}</version> -</dependency>`; - -export const generateMavenSetupXml = () => `<repositories> - <repository> - <id>gitlab-maven</id> - <url>${registryUrl}</url> - </repository> -</repositories> - -<distributionManagement> - <repository> - <id>gitlab-maven</id> - <url>${registryUrl}</url> - </repository> - - <snapshotRepository> - <id>gitlab-maven</id> - <url>${registryUrl}</url> - </snapshotRepository> -</distributionManagement>`; - -export const pypiSetupCommandStr = `[gitlab] -repository = foo -username = __token__ -password = <your personal access token>`; diff --git a/spec/frontend/packages/details/store/actions_spec.js b/spec/frontend/packages/details/store/actions_spec.js deleted file mode 100644 index b16e50debc4..00000000000 --- a/spec/frontend/packages/details/store/actions_spec.js +++ /dev/null @@ -1,156 +0,0 @@ -import testAction from 'helpers/vuex_action_helper'; -import Api from '~/api'; -import createFlash from '~/flash'; -import { FETCH_PACKAGE_VERSIONS_ERROR } from '~/packages/details/constants'; -import { - fetchPackageVersions, - deletePackage, - deletePackageFile, -} from '~/packages/details/store/actions'; -import * as types from '~/packages/details/store/mutation_types'; -import { - DELETE_PACKAGE_ERROR_MESSAGE, - DELETE_PACKAGE_FILE_ERROR_MESSAGE, - DELETE_PACKAGE_FILE_SUCCESS_MESSAGE, -} from '~/packages/shared/constants'; -import { npmPackage as packageEntity } from '../../mock_data'; - -jest.mock('~/flash.js'); -jest.mock('~/api.js'); - -describe('Actions Package details store', () => { - describe('fetchPackageVersions', () => { - it('should fetch the package versions', (done) => { - Api.projectPackage = jest.fn().mockResolvedValue({ data: packageEntity }); - - testAction( - fetchPackageVersions, - undefined, - { packageEntity }, - [ - { type: types.SET_LOADING, payload: true }, - { type: types.SET_PACKAGE_VERSIONS, payload: packageEntity.versions }, - { type: types.SET_LOADING, payload: false }, - ], - [], - () => { - expect(Api.projectPackage).toHaveBeenCalledWith( - packageEntity.project_id, - packageEntity.id, - ); - done(); - }, - ); - }); - - it("does not set the versions if they don't exist", (done) => { - Api.projectPackage = jest.fn().mockResolvedValue({ data: { packageEntity, versions: null } }); - - testAction( - fetchPackageVersions, - undefined, - { packageEntity }, - [ - { type: types.SET_LOADING, payload: true }, - { type: types.SET_LOADING, payload: false }, - ], - [], - () => { - expect(Api.projectPackage).toHaveBeenCalledWith( - packageEntity.project_id, - packageEntity.id, - ); - done(); - }, - ); - }); - - it('should create flash on API error', (done) => { - Api.projectPackage = jest.fn().mockRejectedValue(); - - testAction( - fetchPackageVersions, - undefined, - { packageEntity }, - [ - { type: types.SET_LOADING, payload: true }, - { type: types.SET_LOADING, payload: false }, - ], - [], - () => { - expect(Api.projectPackage).toHaveBeenCalledWith( - packageEntity.project_id, - packageEntity.id, - ); - expect(createFlash).toHaveBeenCalledWith({ - message: FETCH_PACKAGE_VERSIONS_ERROR, - type: 'warning', - }); - done(); - }, - ); - }); - }); - - describe('deletePackage', () => { - it('should call Api.deleteProjectPackage', (done) => { - Api.deleteProjectPackage = jest.fn().mockResolvedValue(); - testAction(deletePackage, undefined, { packageEntity }, [], [], () => { - expect(Api.deleteProjectPackage).toHaveBeenCalledWith( - packageEntity.project_id, - packageEntity.id, - ); - done(); - }); - }); - it('should create flash on API error', (done) => { - Api.deleteProjectPackage = jest.fn().mockRejectedValue(); - - testAction(deletePackage, undefined, { packageEntity }, [], [], () => { - expect(createFlash).toHaveBeenCalledWith({ - message: DELETE_PACKAGE_ERROR_MESSAGE, - type: 'warning', - }); - done(); - }); - }); - }); - - describe('deletePackageFile', () => { - const fileId = 'a_file_id'; - - it('should call Api.deleteProjectPackageFile and commit the right data', (done) => { - const packageFiles = [{ id: 'foo' }, { id: fileId }]; - Api.deleteProjectPackageFile = jest.fn().mockResolvedValue(); - testAction( - deletePackageFile, - fileId, - { packageEntity, packageFiles }, - [{ type: types.UPDATE_PACKAGE_FILES, payload: [{ id: 'foo' }] }], - [], - () => { - expect(Api.deleteProjectPackageFile).toHaveBeenCalledWith( - packageEntity.project_id, - packageEntity.id, - fileId, - ); - expect(createFlash).toHaveBeenCalledWith({ - message: DELETE_PACKAGE_FILE_SUCCESS_MESSAGE, - type: 'success', - }); - done(); - }, - ); - }); - it('should create flash on API error', (done) => { - Api.deleteProjectPackageFile = jest.fn().mockRejectedValue(); - testAction(deletePackageFile, fileId, { packageEntity }, [], [], () => { - expect(createFlash).toHaveBeenCalledWith({ - message: DELETE_PACKAGE_FILE_ERROR_MESSAGE, - type: 'warning', - }); - done(); - }); - }); - }); -}); diff --git a/spec/frontend/packages/details/store/getters_spec.js b/spec/frontend/packages/details/store/getters_spec.js deleted file mode 100644 index 8210511bf8f..00000000000 --- a/spec/frontend/packages/details/store/getters_spec.js +++ /dev/null @@ -1,295 +0,0 @@ -import { NpmManager } from '~/packages/details/constants'; -import { - conanInstallationCommand, - conanSetupCommand, - packagePipeline, - packageTypeDisplay, - packageIcon, - mavenInstallationXml, - mavenInstallationCommand, - mavenSetupXml, - npmInstallationCommand, - npmSetupCommand, - nugetInstallationCommand, - nugetSetupCommand, - pypiPipCommand, - pypiSetupCommand, - composerRegistryInclude, - composerPackageInclude, - groupExists, - gradleGroovyInstalCommand, - gradleGroovyAddSourceCommand, - gradleKotlinInstalCommand, - gradleKotlinAddSourceCommand, -} from '~/packages/details/store/getters'; -import { - conanPackage, - npmPackage, - nugetPackage, - mockPipelineInfo, - mavenPackage as packageWithoutBuildInfo, - pypiPackage, - rubygemsPackage, -} from '../../mock_data'; -import { - generateMavenCommand, - generateXmlCodeBlock, - generateMavenSetupXml, - registryUrl, - pypiSetupCommandStr, -} from '../mock_data'; - -describe('Getters PackageDetails Store', () => { - let state; - - const defaultState = { - packageEntity: packageWithoutBuildInfo, - conanPath: registryUrl, - mavenPath: registryUrl, - npmPath: registryUrl, - nugetPath: registryUrl, - pypiPath: registryUrl, - }; - - const setupState = (testState = {}) => { - state = { - ...defaultState, - ...testState, - }; - }; - - const conanInstallationCommandStr = `conan install ${conanPackage.name} --remote=gitlab`; - const conanSetupCommandStr = `conan remote add gitlab ${registryUrl}`; - - const mavenCommandStr = generateMavenCommand(packageWithoutBuildInfo.maven_metadatum); - const mavenInstallationXmlBlock = generateXmlCodeBlock(packageWithoutBuildInfo.maven_metadatum); - const mavenSetupXmlBlock = generateMavenSetupXml(); - - const npmInstallStr = `npm i ${npmPackage.name}`; - const npmSetupStr = `echo @Test:registry=${registryUrl}/ >> .npmrc`; - const yarnInstallStr = `yarn add ${npmPackage.name}`; - const yarnSetupStr = `echo \\"@Test:registry\\" \\"${registryUrl}/\\" >> .yarnrc`; - - const nugetInstallationCommandStr = `nuget install ${nugetPackage.name} -Source "GitLab"`; - const nugetSetupCommandStr = `nuget source Add -Name "GitLab" -Source "${registryUrl}" -UserName <your_username> -Password <your_token>`; - - const pypiPipCommandStr = `pip install ${pypiPackage.name} --extra-index-url ${registryUrl}`; - const composerRegistryIncludeStr = - 'composer config repositories.gitlab.com/123 \'{"type": "composer", "url": "foo"}\''; - const composerPackageIncludeStr = `composer req ${[packageWithoutBuildInfo.name]}:${ - packageWithoutBuildInfo.version - }`; - - describe('packagePipeline', () => { - it('should return the pipeline info when pipeline exists', () => { - setupState({ - packageEntity: { - ...npmPackage, - pipeline: mockPipelineInfo, - }, - }); - - expect(packagePipeline(state)).toEqual(mockPipelineInfo); - }); - - it('should return null when build_info does not exist', () => { - setupState(); - - expect(packagePipeline(state)).toBe(null); - }); - }); - - describe('packageTypeDisplay', () => { - describe.each` - packageEntity | expectedResult - ${conanPackage} | ${'Conan'} - ${packageWithoutBuildInfo} | ${'Maven'} - ${npmPackage} | ${'npm'} - ${nugetPackage} | ${'NuGet'} - ${pypiPackage} | ${'PyPI'} - ${rubygemsPackage} | ${'RubyGems'} - `(`package type`, ({ packageEntity, expectedResult }) => { - beforeEach(() => setupState({ packageEntity })); - - it(`${packageEntity.package_type} should show as ${expectedResult}`, () => { - expect(packageTypeDisplay(state)).toBe(expectedResult); - }); - }); - }); - - describe('packageIcon', () => { - describe('nuget packages', () => { - it('should return nuget package icon', () => { - setupState({ packageEntity: nugetPackage }); - - expect(packageIcon(state)).toBe(nugetPackage.nuget_metadatum.icon_url); - }); - - it('should return null when nuget package does not have an icon', () => { - setupState({ packageEntity: { ...nugetPackage, nuget_metadatum: {} } }); - - expect(packageIcon(state)).toBe(null); - }); - }); - - it('should not find icons for other package types', () => { - setupState({ packageEntity: npmPackage }); - - expect(packageIcon(state)).toBe(null); - }); - }); - - describe('conan string getters', () => { - it('gets the correct conanInstallationCommand', () => { - setupState({ packageEntity: conanPackage }); - - expect(conanInstallationCommand(state)).toBe(conanInstallationCommandStr); - }); - - it('gets the correct conanSetupCommand', () => { - setupState({ packageEntity: conanPackage }); - - expect(conanSetupCommand(state)).toBe(conanSetupCommandStr); - }); - }); - - describe('maven string getters', () => { - it('gets the correct mavenInstallationXml', () => { - setupState(); - - expect(mavenInstallationXml(state)).toBe(mavenInstallationXmlBlock); - }); - - it('gets the correct mavenInstallationCommand', () => { - setupState(); - - expect(mavenInstallationCommand(state)).toBe(mavenCommandStr); - }); - - it('gets the correct mavenSetupXml', () => { - setupState(); - - expect(mavenSetupXml(state)).toBe(mavenSetupXmlBlock); - }); - }); - - describe('npm string getters', () => { - it('gets the correct npmInstallationCommand for npm', () => { - setupState({ packageEntity: npmPackage }); - - expect(npmInstallationCommand(state)(NpmManager.NPM)).toBe(npmInstallStr); - }); - - it('gets the correct npmSetupCommand for npm', () => { - setupState({ packageEntity: npmPackage }); - - expect(npmSetupCommand(state)(NpmManager.NPM)).toBe(npmSetupStr); - }); - - it('gets the correct npmInstallationCommand for Yarn', () => { - setupState({ packageEntity: npmPackage }); - - expect(npmInstallationCommand(state)(NpmManager.YARN)).toBe(yarnInstallStr); - }); - - it('gets the correct npmSetupCommand for Yarn', () => { - setupState({ packageEntity: npmPackage }); - - expect(npmSetupCommand(state)(NpmManager.YARN)).toBe(yarnSetupStr); - }); - }); - - describe('nuget string getters', () => { - it('gets the correct nugetInstallationCommand', () => { - setupState({ packageEntity: nugetPackage }); - - expect(nugetInstallationCommand(state)).toBe(nugetInstallationCommandStr); - }); - - it('gets the correct nugetSetupCommand', () => { - setupState({ packageEntity: nugetPackage }); - - expect(nugetSetupCommand(state)).toBe(nugetSetupCommandStr); - }); - }); - - describe('pypi string getters', () => { - it('gets the correct pypiPipCommand', () => { - setupState({ packageEntity: pypiPackage }); - - expect(pypiPipCommand(state)).toBe(pypiPipCommandStr); - }); - - it('gets the correct pypiSetupCommand', () => { - setupState({ pypiSetupPath: 'foo' }); - - expect(pypiSetupCommand(state)).toBe(pypiSetupCommandStr); - }); - }); - - describe('composer string getters', () => { - it('gets the correct composerRegistryInclude command', () => { - setupState({ composerPath: 'foo', composerConfigRepositoryName: 'gitlab.com/123' }); - - expect(composerRegistryInclude(state)).toBe(composerRegistryIncludeStr); - }); - - it('gets the correct composerPackageInclude command', () => { - setupState(); - - expect(composerPackageInclude(state)).toBe(composerPackageIncludeStr); - }); - }); - - describe('gradle groovy string getters', () => { - it('gets the correct gradleGroovyInstalCommand', () => { - setupState(); - - expect(gradleGroovyInstalCommand(state)).toMatchInlineSnapshot( - `"implementation 'com.test.app:test-app:1.0-SNAPSHOT'"`, - ); - }); - - it('gets the correct gradleGroovyAddSourceCommand', () => { - setupState(); - - expect(gradleGroovyAddSourceCommand(state)).toMatchInlineSnapshot(` - "maven { - url 'foo/registry' - }" - `); - }); - }); - - describe('gradle kotlin string getters', () => { - it('gets the correct gradleKotlinInstalCommand', () => { - setupState(); - - expect(gradleKotlinInstalCommand(state)).toMatchInlineSnapshot( - `"implementation(\\"com.test.app:test-app:1.0-SNAPSHOT\\")"`, - ); - }); - - it('gets the correct gradleKotlinAddSourceCommand', () => { - setupState(); - - expect(gradleKotlinAddSourceCommand(state)).toMatchInlineSnapshot( - `"maven(\\"foo/registry\\")"`, - ); - }); - }); - - describe('check if group', () => { - it('is set', () => { - setupState({ groupListUrl: '/groups/composer/-/packages' }); - - expect(groupExists(state)).toBe(true); - }); - - it('is not set', () => { - setupState({ groupListUrl: '' }); - - expect(groupExists(state)).toBe(false); - }); - }); -}); diff --git a/spec/frontend/packages/details/store/mutations_spec.js b/spec/frontend/packages/details/store/mutations_spec.js deleted file mode 100644 index 296ed02d786..00000000000 --- a/spec/frontend/packages/details/store/mutations_spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import * as types from '~/packages/details/store/mutation_types'; -import mutations from '~/packages/details/store/mutations'; -import { npmPackage as packageEntity } from '../../mock_data'; - -describe('Mutations package details Store', () => { - let mockState; - - beforeEach(() => { - mockState = { - packageEntity, - }; - }); - - describe('SET_LOADING', () => { - it('should set loading', () => { - mutations[types.SET_LOADING](mockState, true); - - expect(mockState.isLoading).toEqual(true); - }); - }); - - describe('SET_PACKAGE_VERSIONS', () => { - it('should set the package entity versions', () => { - const fakeVersions = [1, 2, 3]; - - mutations[types.SET_PACKAGE_VERSIONS](mockState, fakeVersions); - - expect(mockState.packageEntity.versions).toEqual(fakeVersions); - }); - }); - describe('UPDATE_PACKAGE_FILES', () => { - it('should update the packageFiles', () => { - const files = [1, 2, 3]; - - mutations[types.UPDATE_PACKAGE_FILES](mockState, files); - - expect(mockState.packageFiles).toEqual(files); - }); - }); -}); diff --git a/spec/frontend/packages/shared/components/package_list_row_spec.js b/spec/frontend/packages/shared/components/package_list_row_spec.js index bd15d48c4eb..5f2fc8ddfbd 100644 --- a/spec/frontend/packages/shared/components/package_list_row_spec.js +++ b/spec/frontend/packages/shared/components/package_list_row_spec.js @@ -1,5 +1,5 @@ import { GlLink } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import PackagesListRow from '~/packages/shared/components/package_list_row.vue'; @@ -19,14 +19,14 @@ describe('packages_list_row', () => { const InfrastructureIconAndName = { name: 'InfrastructureIconAndName', template: '<div></div>' }; const PackageIconAndName = { name: 'PackageIconAndName', template: '<div></div>' }; - const findPackageTags = () => wrapper.find(PackageTags); - const findPackagePath = () => wrapper.find(PackagePath); - const findDeleteButton = () => wrapper.find('[data-testid="action-delete"]'); - const findPackageIconAndName = () => wrapper.find(PackageIconAndName); + const findPackageTags = () => wrapper.findComponent(PackageTags); + const findPackagePath = () => wrapper.findComponent(PackagePath); + const findDeleteButton = () => wrapper.findByTestId('action-delete'); + const findPackageIconAndName = () => wrapper.findComponent(PackageIconAndName); const findInfrastructureIconAndName = () => wrapper.findComponent(InfrastructureIconAndName); const findListItem = () => wrapper.findComponent(ListItem); const findPackageLink = () => wrapper.findComponent(GlLink); - const findWarningIcon = () => wrapper.find('[data-testid="warning-icon"]'); + const findWarningIcon = () => wrapper.findByTestId('warning-icon'); const mountComponent = ({ isGroup = false, @@ -35,7 +35,7 @@ describe('packages_list_row', () => { disableDelete = false, provide, } = {}) => { - wrapper = shallowMount(PackagesListRow, { + wrapper = shallowMountExtended(PackagesListRow, { store, provide, stubs: { |