Commit 1fe1a2fa authored by Nick Kipling's avatar Nick Kipling Committed by Natalia Tepluhina

Adds PyPi support to frontend package details page

Created new pypi_installation component
Updated app component with small refactor
Updated utils and Vuex to support new package type
Updated package_helpers to provide urls
Added / updated tests
Updated gitlab.pot
parent c7140c77
...@@ -18,6 +18,7 @@ import ConanInstallation from './conan_installation.vue'; ...@@ -18,6 +18,7 @@ import ConanInstallation from './conan_installation.vue';
import MavenInstallation from './maven_installation.vue'; import MavenInstallation from './maven_installation.vue';
import NpmInstallation from './npm_installation.vue'; import NpmInstallation from './npm_installation.vue';
import NugetInstallation from './nuget_installation.vue'; import NugetInstallation from './nuget_installation.vue';
import PypiInstallation from './pypi_installation.vue';
import { numberToHumanSize } from '~/lib/utils/number_utils'; import { numberToHumanSize } from '~/lib/utils/number_utils';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import { generatePackageInfo } from '../utils'; import { generatePackageInfo } from '../utils';
...@@ -42,6 +43,7 @@ export default { ...@@ -42,6 +43,7 @@ export default {
MavenInstallation, MavenInstallation,
NpmInstallation, NpmInstallation,
NugetInstallation, NugetInstallation,
PypiInstallation,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -59,17 +61,21 @@ export default { ...@@ -59,17 +61,21 @@ export default {
'npmPath', 'npmPath',
'npmHelpPath', 'npmHelpPath',
]), ]),
isNpmPackage() { installationComponent() {
return this.packageEntity.package_type === PackageType.NPM; switch (this.packageEntity.package_type) {
}, case PackageType.CONAN:
isMavenPackage() { return ConanInstallation;
return this.packageEntity.package_type === PackageType.MAVEN; case PackageType.MAVEN:
}, return MavenInstallation;
isConanPackage() { case PackageType.NPM:
return this.packageEntity.package_type === PackageType.CONAN; return NpmInstallation;
}, case PackageType.NUGET:
isNugetPackage() { return NugetInstallation;
return this.packageEntity.package_type === PackageType.NUGET; case PackageType.PYPI:
return PypiInstallation;
default:
return null;
}
}, },
isValidPackage() { isValidPackage() {
return Boolean(this.packageEntity.name); return Boolean(this.packageEntity.name);
...@@ -203,16 +209,13 @@ export default { ...@@ -203,16 +209,13 @@ export default {
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<npm-installation <component
v-if="isNpmPackage" :is="installationComponent"
v-if="installationComponent"
:name="packageEntity.name" :name="packageEntity.name"
:registry-url="npmPath" :registry-url="npmPath"
:help-url="npmHelpPath" :help-url="npmHelpPath"
/> />
<maven-installation v-else-if="isMavenPackage" />
<conan-installation v-else-if="isConanPackage" />
<nuget-installation v-else-if="isNugetPackage" />
</div> </div>
</div> </div>
......
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import CodeInstruction from './code_instruction.vue';
import { TrackingActions, TrackingLabels } from '../constants';
import { mapGetters, mapState } from 'vuex';
import InstallationTabs from './installation_tabs.vue';
export default {
name: 'PyPiInstallation',
components: {
CodeInstruction,
GlLink,
GlSprintf,
InstallationTabs,
},
computed: {
...mapState(['pypiHelpPath']),
...mapGetters(['pypiPipCommand', 'pypiSetupCommand']),
},
i18n: {
setupText: s__(
`PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file.`,
),
helpText: s__(
'PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}.',
),
},
trackingActions: { ...TrackingActions },
trackingLabel: TrackingLabels.PYPI_INSTALLATION,
};
</script>
<template>
<installation-tabs :tracking-label="$options.trackingLabel">
<template #installation>
<p class="prepend-top-default font-weight-bold">
{{ s__('PackageRegistry|Pip Command') }}
</p>
<code-instruction
:instruction="pypiPipCommand"
:copy-text="s__('PackageRegistry|Copy Pip command')"
data-testid="pip-command"
:tracking-action="$options.trackingActions.COPY_PIP_INSTALL_COMMAND"
/>
</template>
<template #setup>
<p>
<gl-sprintf :message="$options.i18n.setupText">
<template #code="{ content }">
<code>{{ content }}</code>
</template>
</gl-sprintf>
</p>
<code-instruction
:instruction="pypiSetupCommand"
:copy-text="s__('PackageRegistry|Copy .pypirc content')"
data-testid="pypi-setup-content"
multiline
:tracking-action="$options.trackingActions.COPY_PYPI_SETUP_COMMAND"
/>
<gl-sprintf :message="$options.i18n.helpText">
<template #link="{ content }">
<gl-link :href="pypiHelpPath" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</template>
</installation-tabs>
</template>
...@@ -4,6 +4,7 @@ export const TrackingLabels = { ...@@ -4,6 +4,7 @@ export const TrackingLabels = {
MAVEN_INSTALLATION: 'maven_installation', MAVEN_INSTALLATION: 'maven_installation',
NPM_INSTALLATION: 'npm_installation', NPM_INSTALLATION: 'npm_installation',
NUGET_INSTALLATION: 'nuget_installation', NUGET_INSTALLATION: 'nuget_installation',
PYPI_INSTALLATION: 'pypi_installation',
}; };
export const TrackingActions = { export const TrackingActions = {
...@@ -25,6 +26,9 @@ export const TrackingActions = { ...@@ -25,6 +26,9 @@ export const TrackingActions = {
COPY_NUGET_INSTALL_COMMAND: 'copy_nuget_install_command', COPY_NUGET_INSTALL_COMMAND: 'copy_nuget_install_command',
COPY_NUGET_SETUP_COMMAND: 'copy_nuget_setup_command', COPY_NUGET_SETUP_COMMAND: 'copy_nuget_setup_command',
COPY_PIP_INSTALL_COMMAND: 'copy_pip_install_command',
COPY_PYPI_SETUP_COMMAND: 'copy_pypi_setup_command',
}; };
export const NpmManager = { export const NpmManager = {
......
import { generateConanRecipe } from '../utils'; import { generateConanRecipe } from '../utils';
import { getPackageType } from '../../shared/utils'; import { getPackageTypeLabel } from '../../shared/utils';
import { NpmManager } from '../constants'; import { NpmManager } from '../constants';
export const packagePipeline = ({ packageEntity }) => { export const packagePipeline = ({ packageEntity }) => {
...@@ -7,7 +7,7 @@ export const packagePipeline = ({ packageEntity }) => { ...@@ -7,7 +7,7 @@ export const packagePipeline = ({ packageEntity }) => {
}; };
export const packageTypeDisplay = ({ packageEntity }) => { export const packageTypeDisplay = ({ packageEntity }) => {
return getPackageType(packageEntity.package_type); return getPackageTypeLabel(packageEntity.package_type);
}; };
export const conanInstallationCommand = ({ packageEntity }) => { export const conanInstallationCommand = ({ packageEntity }) => {
...@@ -86,3 +86,12 @@ export const nugetInstallationCommand = ({ packageEntity }) => ...@@ -86,3 +86,12 @@ export const nugetInstallationCommand = ({ packageEntity }) =>
export const nugetSetupCommand = ({ nugetPath }) => export const nugetSetupCommand = ({ nugetPath }) =>
`nuget source Add -Name "GitLab" -Source "${nugetPath}" -UserName <your_username> -Password <your_token>`; `nuget source Add -Name "GitLab" -Source "${nugetPath}" -UserName <your_username> -Password <your_token>`;
export const pypiPipCommand = ({ pypiPath, packageEntity }) =>
// eslint-disable-next-line @gitlab/require-i18n-strings
`pip install ${packageEntity.name} --index-url ${pypiPath}`;
export const pypiSetupCommand = ({ pypiSetupPath }) => `[gitlab]
repository = ${pypiSetupPath}
username = __token__
password = <your personal access token>`;
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import PackageTags from '../../shared/components/package_tags.vue'; import PackageTags from '../../shared/components/package_tags.vue';
import PublishMethod from './publish_method.vue'; import PublishMethod from './publish_method.vue';
import { GlButton, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui'; import { GlButton, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from '@gitlab/ui';
import { getPackageType } from '../../shared/utils'; import { getPackageTypeLabel } from '../../shared/utils';
import timeagoMixin from '~/vue_shared/mixins/timeago'; import timeagoMixin from '~/vue_shared/mixins/timeago';
import { mapState } from 'vuex'; import { mapState } from 'vuex';
...@@ -31,7 +31,7 @@ export default { ...@@ -31,7 +31,7 @@ export default {
isGroupPage: state => state.config.isGroupPage, isGroupPage: state => state.config.isGroupPage,
}), }),
packageType() { packageType() {
return getPackageType(this.packageEntity.package_type); return getPackageTypeLabel(this.packageEntity.package_type);
}, },
hasPipeline() { hasPipeline() {
return Boolean(this.packageEntity.pipeline); return Boolean(this.packageEntity.pipeline);
......
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { TrackingCategories } from './constants'; import { PackageType, TrackingCategories } from './constants';
export const packageTypeToTrackCategory = type => export const packageTypeToTrackCategory = type =>
// eslint-disable-next-line @gitlab/require-i18n-strings // eslint-disable-next-line @gitlab/require-i18n-strings
...@@ -7,16 +7,18 @@ export const packageTypeToTrackCategory = type => ...@@ -7,16 +7,18 @@ export const packageTypeToTrackCategory = type =>
export const beautifyPath = path => (path ? path.split('/').join(' / ') : ''); export const beautifyPath = path => (path ? path.split('/').join(' / ') : '');
export const getPackageType = packageType => { export const getPackageTypeLabel = packageType => {
switch (packageType) { switch (packageType) {
case 'conan': case PackageType.CONAN:
return s__('PackageType|Conan'); return s__('PackageType|Conan');
case 'maven': case PackageType.MAVEN:
return s__('PackageType|Maven'); return s__('PackageType|Maven');
case 'npm': case PackageType.NPM:
return s__('PackageType|NPM'); return s__('PackageType|NPM');
case 'nuget': case PackageType.NUGET:
return s__('PackageType|NuGet'); return s__('PackageType|NuGet');
case PackageType.PYPI:
return s__('PackageType|PyPi');
default: default:
return null; return null;
......
...@@ -25,5 +25,10 @@ module EE ...@@ -25,5 +25,10 @@ module EE
presenter.detail_view.to_json presenter.detail_view.to_json
end end
def pypi_registry_url(project_id)
full_url = expose_url(api_v4_projects_packages_pypi_simple_package_name_path({ id: project_id, package_name: '' }, true))
full_url.sub!('://', '://__token__:<your_personal_token>@')
end
end end
end end
...@@ -16,4 +16,7 @@ ...@@ -16,4 +16,7 @@
conan_path: package_registry_instance_url(:conan), conan_path: package_registry_instance_url(:conan),
conan_help_path: help_page_path('user/packages/conan_repository/index'), conan_help_path: help_page_path('user/packages/conan_repository/index'),
nuget_path: nuget_package_registry_url(@project.id), nuget_path: nuget_package_registry_url(@project.id),
nuget_help_path: help_page_path('user/packages/nuget_repository/index') } } nuget_help_path: help_page_path('user/packages/nuget_repository/index'),
pypi_path: pypi_registry_url(@project.id),
pypi_setup_path: package_registry_project_url(@project.id, :pypi),
pypi_help_path: help_page_path('user/packages/pypi_repository/index') } }
---
title: Adds PyPi installation instructions to package details page
merge_request: 29935
author:
type: added
...@@ -2,6 +2,7 @@ import Vuex from 'vuex'; ...@@ -2,6 +2,7 @@ import Vuex from 'vuex';
import { mount, createLocalVue } from '@vue/test-utils'; import { mount, createLocalVue } from '@vue/test-utils';
import { GlEmptyState, GlModal } from '@gitlab/ui'; import { GlEmptyState, GlModal } from '@gitlab/ui';
import Tracking from '~/tracking'; import Tracking from '~/tracking';
import * as getters from 'ee/packages/details/store/getters';
import PackagesApp from 'ee/packages/details/components/app.vue'; import PackagesApp from 'ee/packages/details/components/app.vue';
import PackageTitle from 'ee/packages/details/components/package_title.vue'; import PackageTitle from 'ee/packages/details/components/package_title.vue';
import PackageInformation from 'ee/packages/details/components/information.vue'; import PackageInformation from 'ee/packages/details/components/information.vue';
...@@ -11,6 +12,7 @@ import * as SharedUtils from 'ee/packages/shared/utils'; ...@@ -11,6 +12,7 @@ import * as SharedUtils from 'ee/packages/shared/utils';
import { TrackingActions } from 'ee/packages/shared/constants'; import { TrackingActions } from 'ee/packages/shared/constants';
import ConanInstallation from 'ee/packages/details/components/conan_installation.vue'; import ConanInstallation from 'ee/packages/details/components/conan_installation.vue';
import NugetInstallation from 'ee/packages/details/components/nuget_installation.vue'; import NugetInstallation from 'ee/packages/details/components/nuget_installation.vue';
import PypiInstallation from 'ee/packages/details/components/pypi_installation.vue';
import { import {
conanPackage, conanPackage,
mavenPackage, mavenPackage,
...@@ -18,6 +20,7 @@ import { ...@@ -18,6 +20,7 @@ import {
npmPackage, npmPackage,
npmFiles, npmFiles,
nugetPackage, nugetPackage,
pypiPackage,
} from '../../mock_data'; } from '../../mock_data';
import stubChildren from 'helpers/stub_children'; import stubChildren from 'helpers/stub_children';
...@@ -40,6 +43,7 @@ describe('PackagesApp', () => { ...@@ -40,6 +43,7 @@ describe('PackagesApp', () => {
npmPath: 'foo', npmPath: 'foo',
npmHelpPath: 'foo', npmHelpPath: 'foo',
}, },
getters,
}); });
wrapper = mount(PackagesApp, { wrapper = mount(PackagesApp, {
...@@ -63,6 +67,7 @@ describe('PackagesApp', () => { ...@@ -63,6 +67,7 @@ describe('PackagesApp', () => {
const mavenInstallation = () => wrapper.find(MavenInstallation); const mavenInstallation = () => wrapper.find(MavenInstallation);
const conanInstallation = () => wrapper.find(ConanInstallation); const conanInstallation = () => wrapper.find(ConanInstallation);
const nugetInstallation = () => wrapper.find(NugetInstallation); const nugetInstallation = () => wrapper.find(NugetInstallation);
const pypiInstallation = () => wrapper.find(PypiInstallation);
const allFileRows = () => wrapper.findAll('.js-file-row'); const allFileRows = () => wrapper.findAll('.js-file-row');
const firstFileDownloadLink = () => wrapper.find('.js-file-download'); const firstFileDownloadLink = () => wrapper.find('.js-file-download');
const deleteButton = () => wrapper.find('.js-delete-button'); const deleteButton = () => wrapper.find('.js-delete-button');
...@@ -94,12 +99,6 @@ describe('PackagesApp', () => { ...@@ -94,12 +99,6 @@ describe('PackagesApp', () => {
expect(packageInformation(1)).toExist(); expect(packageInformation(1)).toExist();
}); });
it('renders package installation instructions for maven packages', () => {
createComponent();
expect(mavenInstallation()).toExist();
});
it('does not render package metadata for npm as npm packages do not contain metadata', () => { it('does not render package metadata for npm as npm packages do not contain metadata', () => {
createComponent(npmPackage, npmFiles); createComponent(npmPackage, npmFiles);
...@@ -107,16 +106,21 @@ describe('PackagesApp', () => { ...@@ -107,16 +106,21 @@ describe('PackagesApp', () => {
expect(allPackageInformation()).toHaveLength(1); expect(allPackageInformation()).toHaveLength(1);
}); });
it('renders package installation instructions for npm packages', () => { describe('installation instructions', () => {
createComponent(npmPackage, npmFiles); describe.each`
packageEntity | selector
expect(npmInstallation()).toExist(); ${conanPackage} | ${conanInstallation}
}); ${mavenPackage} | ${mavenInstallation}
${npmPackage} | ${npmInstallation}
it('does not render package installation instructions for non npm packages', () => { ${nugetPackage} | ${nugetInstallation}
createComponent(); ${pypiPackage} | ${pypiInstallation}
`('renders', ({ packageEntity, selector }) => {
expect(npmInstallation().exists()).toBe(false); it(`${packageEntity.package_type} instructions`, () => {
createComponent({ packageEntity });
expect(selector()).toExist();
});
});
}); });
it('renders a single file for an npm package as they only contain one file', () => { it('renders a single file for an npm package as they only contain one file', () => {
...@@ -190,20 +194,4 @@ describe('PackagesApp', () => { ...@@ -190,20 +194,4 @@ describe('PackagesApp', () => {
); );
}); });
}); });
it('renders package installation instructions for conan packages', () => {
createComponent({
packageEntity: conanPackage,
});
expect(conanInstallation()).toExist();
});
it('renders package installation instructions for nuget packages', () => {
createComponent({
packageEntity: nugetPackage,
});
expect(nugetInstallation()).toExist();
});
}); });
import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import PypiInstallation from 'ee/packages/details/components/pypi_installation.vue';
import InstallationTabs from 'ee/packages/details/components/installation_tabs.vue';
import { pypiPackage as packageEntity } from '../../mock_data';
import { GlTabs } from '@gitlab/ui';
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 findTabs = () => wrapper.find(GlTabs);
const pipCommand = () => wrapper.find('[data-testid="pip-command"]');
const setupInstruction = () => wrapper.find('[data-testid="pypi-setup-content"]');
function createComponent() {
wrapper = shallowMount(PypiInstallation, {
localVue,
store,
stubs: {
InstallationTabs,
},
});
}
beforeEach(() => {
createComponent();
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
describe('it renders', () => {
it('with GlTabs', () => {
expect(findTabs().exists()).toBe(true);
});
});
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);
});
});
});
...@@ -73,3 +73,8 @@ export const generateConanInformation = conanPackage => [ ...@@ -73,3 +73,8 @@ export const generateConanInformation = conanPackage => [
}, },
...generateCommonPackageInformation(conanPackage), ...generateCommonPackageInformation(conanPackage),
]; ];
export const pypiSetupCommandStr = `[gitlab]
repository = foo
username = __token__
password = <your personal access token>`;
...@@ -10,6 +10,8 @@ import { ...@@ -10,6 +10,8 @@ import {
npmSetupCommand, npmSetupCommand,
nugetInstallationCommand, nugetInstallationCommand,
nugetSetupCommand, nugetSetupCommand,
pypiPipCommand,
pypiSetupCommand,
} from 'ee/packages/details/store/getters'; } from 'ee/packages/details/store/getters';
import { import {
conanPackage, conanPackage,
...@@ -17,12 +19,14 @@ import { ...@@ -17,12 +19,14 @@ import {
nugetPackage, nugetPackage,
mockPipelineInfo, mockPipelineInfo,
mavenPackage as packageWithoutBuildInfo, mavenPackage as packageWithoutBuildInfo,
pypiPackage,
} from '../../mock_data'; } from '../../mock_data';
import { import {
generateMavenCommand, generateMavenCommand,
generateXmlCodeBlock, generateXmlCodeBlock,
generateMavenSetupXml, generateMavenSetupXml,
registryUrl, registryUrl,
pypiSetupCommandStr,
} from '../mock_data'; } from '../mock_data';
import { generateConanRecipe } from 'ee/packages/details/utils'; import { generateConanRecipe } from 'ee/packages/details/utils';
import { NpmManager } from 'ee/packages/details/constants'; import { NpmManager } from 'ee/packages/details/constants';
...@@ -36,6 +40,7 @@ describe('Getters PackageDetails Store', () => { ...@@ -36,6 +40,7 @@ describe('Getters PackageDetails Store', () => {
mavenPath: registryUrl, mavenPath: registryUrl,
npmPath: registryUrl, npmPath: registryUrl,
nugetPath: registryUrl, nugetPath: registryUrl,
pypiPath: registryUrl,
}; };
const setupState = (testState = {}) => { const setupState = (testState = {}) => {
...@@ -61,6 +66,8 @@ describe('Getters PackageDetails Store', () => { ...@@ -61,6 +66,8 @@ describe('Getters PackageDetails Store', () => {
const nugetInstallationCommandStr = `nuget install ${nugetPackage.name} -Source "GitLab"`; const nugetInstallationCommandStr = `nuget install ${nugetPackage.name} -Source "GitLab"`;
const nugetSetupCommandStr = `nuget source Add -Name "GitLab" -Source "${registryUrl}" -UserName <your_username> -Password <your_token>`; const nugetSetupCommandStr = `nuget source Add -Name "GitLab" -Source "${registryUrl}" -UserName <your_username> -Password <your_token>`;
const pypiPipCommandStr = `pip install ${pypiPackage.name} --index-url ${registryUrl}`;
describe('packagePipeline', () => { describe('packagePipeline', () => {
it('should return the pipeline info when pipeline exists', () => { it('should return the pipeline info when pipeline exists', () => {
setupState({ setupState({
...@@ -87,6 +94,7 @@ describe('Getters PackageDetails Store', () => { ...@@ -87,6 +94,7 @@ describe('Getters PackageDetails Store', () => {
${packageWithoutBuildInfo} | ${'Maven'} ${packageWithoutBuildInfo} | ${'Maven'}
${npmPackage} | ${'NPM'} ${npmPackage} | ${'NPM'}
${nugetPackage} | ${'NuGet'} ${nugetPackage} | ${'NuGet'}
${pypiPackage} | ${'PyPi'}
`(`package type`, ({ packageEntity, expectedResult }) => { `(`package type`, ({ packageEntity, expectedResult }) => {
beforeEach(() => setupState({ packageEntity })); beforeEach(() => setupState({ packageEntity }));
...@@ -100,13 +108,13 @@ describe('Getters PackageDetails Store', () => { ...@@ -100,13 +108,13 @@ describe('Getters PackageDetails Store', () => {
it('gets the correct conanInstallationCommand', () => { it('gets the correct conanInstallationCommand', () => {
setupState({ packageEntity: conanPackage }); setupState({ packageEntity: conanPackage });
expect(conanInstallationCommand(state)).toEqual(conanInstallationCommandStr); expect(conanInstallationCommand(state)).toBe(conanInstallationCommandStr);
}); });
it('gets the correct conanSetupCommand', () => { it('gets the correct conanSetupCommand', () => {
setupState({ packageEntity: conanPackage }); setupState({ packageEntity: conanPackage });
expect(conanSetupCommand(state)).toEqual(conanSetupCommandStr); expect(conanSetupCommand(state)).toBe(conanSetupCommandStr);
}); });
}); });
...@@ -114,19 +122,19 @@ describe('Getters PackageDetails Store', () => { ...@@ -114,19 +122,19 @@ describe('Getters PackageDetails Store', () => {
it('gets the correct mavenInstallationXml', () => { it('gets the correct mavenInstallationXml', () => {
setupState(); setupState();
expect(mavenInstallationXml(state)).toEqual(mavenInstallationXmlBlock); expect(mavenInstallationXml(state)).toBe(mavenInstallationXmlBlock);
}); });
it('gets the correct mavenInstallationCommand', () => { it('gets the correct mavenInstallationCommand', () => {
setupState(); setupState();
expect(mavenInstallationCommand(state)).toEqual(mavenCommandStr); expect(mavenInstallationCommand(state)).toBe(mavenCommandStr);
}); });
it('gets the correct mavenSetupXml', () => { it('gets the correct mavenSetupXml', () => {
setupState(); setupState();
expect(mavenSetupXml(state)).toEqual(mavenSetupXmlBlock); expect(mavenSetupXml(state)).toBe(mavenSetupXmlBlock);
}); });
}); });
...@@ -134,25 +142,25 @@ describe('Getters PackageDetails Store', () => { ...@@ -134,25 +142,25 @@ describe('Getters PackageDetails Store', () => {
it('gets the correct npmInstallationCommand for NPM', () => { it('gets the correct npmInstallationCommand for NPM', () => {
setupState({ packageEntity: npmPackage }); setupState({ packageEntity: npmPackage });
expect(npmInstallationCommand(state)(NpmManager.NPM)).toEqual(npmInstallStr); expect(npmInstallationCommand(state)(NpmManager.NPM)).toBe(npmInstallStr);
}); });
it('gets the correct npmSetupCommand for NPM', () => { it('gets the correct npmSetupCommand for NPM', () => {
setupState({ packageEntity: npmPackage }); setupState({ packageEntity: npmPackage });
expect(npmSetupCommand(state)(NpmManager.NPM)).toEqual(npmSetupStr); expect(npmSetupCommand(state)(NpmManager.NPM)).toBe(npmSetupStr);
}); });
it('gets the correct npmInstallationCommand for Yarn', () => { it('gets the correct npmInstallationCommand for Yarn', () => {
setupState({ packageEntity: npmPackage }); setupState({ packageEntity: npmPackage });
expect(npmInstallationCommand(state)(NpmManager.YARN)).toEqual(yarnInstallStr); expect(npmInstallationCommand(state)(NpmManager.YARN)).toBe(yarnInstallStr);
}); });
it('gets the correct npmSetupCommand for Yarn', () => { it('gets the correct npmSetupCommand for Yarn', () => {
setupState({ packageEntity: npmPackage }); setupState({ packageEntity: npmPackage });
expect(npmSetupCommand(state)(NpmManager.YARN)).toEqual(yarnSetupStr); expect(npmSetupCommand(state)(NpmManager.YARN)).toBe(yarnSetupStr);
}); });
}); });
...@@ -160,13 +168,27 @@ describe('Getters PackageDetails Store', () => { ...@@ -160,13 +168,27 @@ describe('Getters PackageDetails Store', () => {
it('gets the correct nugetInstallationCommand', () => { it('gets the correct nugetInstallationCommand', () => {
setupState({ packageEntity: nugetPackage }); setupState({ packageEntity: nugetPackage });
expect(nugetInstallationCommand(state)).toEqual(nugetInstallationCommandStr); expect(nugetInstallationCommand(state)).toBe(nugetInstallationCommandStr);
}); });
it('gets the correct nugetSetupCommand', () => { it('gets the correct nugetSetupCommand', () => {
setupState({ packageEntity: nugetPackage }); setupState({ packageEntity: nugetPackage });
expect(nugetSetupCommand(state)).toEqual(nugetSetupCommandStr); 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);
}); });
}); });
}); });
...@@ -99,6 +99,18 @@ export const nugetPackage = { ...@@ -99,6 +99,18 @@ export const nugetPackage = {
version: '1.0.0', version: '1.0.0',
}; };
export const pypiPackage = {
created_at: '2015-12-10',
id: 5,
name: 'PyPiPackage',
package_files: [],
package_type: 'pypi',
project_id: 1,
tags: [],
updated_at: '2015-12-10',
version: '1.0.0',
};
export const mockTags = [ export const mockTags = [
{ {
name: 'foo-1', name: 'foo-1',
......
import { packageTypeToTrackCategory, beautifyPath, getPackageType } from 'ee/packages/shared/utils'; import {
packageTypeToTrackCategory,
beautifyPath,
getPackageTypeLabel,
} from 'ee/packages/shared/utils';
import { PackageType, TrackingCategories } from 'ee/packages/shared/constants'; import { PackageType, TrackingCategories } from 'ee/packages/shared/constants';
describe('Packages shared utils', () => { describe('Packages shared utils', () => {
...@@ -24,17 +28,18 @@ describe('Packages shared utils', () => { ...@@ -24,17 +28,18 @@ describe('Packages shared utils', () => {
}); });
}); });
describe('getPackageType', () => { describe('getPackageTypeLabel', () => {
describe.each` describe.each`
packageType | expectedResult packageType | expectedResult
${'conan'} | ${'Conan'} ${'conan'} | ${'Conan'}
${'maven'} | ${'Maven'} ${'maven'} | ${'Maven'}
${'npm'} | ${'NPM'} ${'npm'} | ${'NPM'}
${'nuget'} | ${'NuGet'} ${'nuget'} | ${'NuGet'}
${'pypi'} | ${'PyPi'}
${'foo'} | ${null} ${'foo'} | ${null}
`(`package type`, ({ packageType, expectedResult }) => { `(`package type`, ({ packageType, expectedResult }) => {
it(`${packageType} should show as ${expectedResult}`, () => { it(`${packageType} should show as ${expectedResult}`, () => {
expect(getPackageType(packageType)).toBe(expectedResult); expect(getPackageTypeLabel(packageType)).toBe(expectedResult);
}); });
}); });
}); });
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
describe EE::PackagesHelper do describe EE::PackagesHelper do
let(:base_url) { "#{Gitlab.config.gitlab.url}/api/v4/" } let_it_be(:base_url) { "#{Gitlab.config.gitlab.url}/api/v4/" }
describe 'package_registry_instance_url' do describe 'package_registry_instance_url' do
it 'returns conant instance url when registry_type is conant' do it 'returns conant instance url when registry_type is conant' do
...@@ -32,4 +32,14 @@ describe EE::PackagesHelper do ...@@ -32,4 +32,14 @@ describe EE::PackagesHelper do
expect(url).to eq("#{base_url}projects/1/packages/npm") expect(url).to eq("#{base_url}projects/1/packages/npm")
end end
end end
describe 'pypi_registry_url' do
let_it_be(:base_url_with_token) { base_url.sub('://', '://__token__:<your_personal_token>@') }
it 'returns the pypi registry url' do
url = helper.pypi_registry_url(1)
expect(url).to eq("#{base_url_with_token}projects/1/packages/pypi/simple")
end
end
end end
...@@ -14470,6 +14470,9 @@ msgstr "" ...@@ -14470,6 +14470,9 @@ msgstr ""
msgid "PackageRegistry|Conan Command" msgid "PackageRegistry|Conan Command"
msgstr "" msgstr ""
msgid "PackageRegistry|Copy .pypirc content"
msgstr ""
msgid "PackageRegistry|Copy Conan Command" msgid "PackageRegistry|Copy Conan Command"
msgstr "" msgstr ""
...@@ -14491,6 +14494,9 @@ msgstr "" ...@@ -14491,6 +14494,9 @@ msgstr ""
msgid "PackageRegistry|Copy NuGet Setup Command" msgid "PackageRegistry|Copy NuGet Setup Command"
msgstr "" msgstr ""
msgid "PackageRegistry|Copy Pip command"
msgstr ""
msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block." msgid "PackageRegistry|Copy and paste this inside your %{codeStart}pom.xml%{codeEnd} %{codeStart}dependencies%{codeEnd} block."
msgstr "" msgstr ""
...@@ -14524,6 +14530,12 @@ msgstr "" ...@@ -14524,6 +14530,12 @@ msgstr ""
msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}." msgid "PackageRegistry|For more information on the NuGet registry, %{linkStart}see the documentation%{linkEnd}."
msgstr "" msgstr ""
msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}see the documentation%{linkEnd}."
msgstr ""
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
msgstr ""
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file." msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file."
msgstr "" msgstr ""
...@@ -14554,6 +14566,9 @@ msgstr "" ...@@ -14554,6 +14566,9 @@ msgstr ""
msgid "PackageRegistry|NuGet Command" msgid "PackageRegistry|NuGet Command"
msgstr "" msgstr ""
msgid "PackageRegistry|Pip Command"
msgstr ""
msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}" msgid "PackageRegistry|Pipeline %{linkStart}%{linkEnd} triggered %{timestamp} by %{author}"
msgstr "" msgstr ""
...@@ -14617,6 +14632,9 @@ msgstr "" ...@@ -14617,6 +14632,9 @@ msgstr ""
msgid "PackageType|NuGet" msgid "PackageType|NuGet"
msgstr "" msgstr ""
msgid "PackageType|PyPi"
msgstr ""
msgid "Packages" msgid "Packages"
msgstr "" msgstr ""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment