summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/db/schema_spec.rb1
-rw-r--r--spec/frontend/editor/editor_ci_schema_ext_spec.js7
-rw-r--r--spec/frontend/members/mock_data.js1
-rw-r--r--spec/frontend/packages/details/components/app_spec.js5
-rw-r--r--spec/frontend/packages/details/components/installations_commands_spec.js4
-rw-r--r--spec/frontend/packages/mock_data.js14
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap44
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js93
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js61
-rw-r--r--spec/frontend/pipeline_editor/components/editor/text_editor_spec.js2
-rw-r--r--spec/lib/gitlab/database_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/models/merge_request_diff_spec.rb55
-rw-r--r--spec/requests/api/debian_group_packages_spec.rb14
-rw-r--r--spec/requests/api/debian_project_packages_spec.rb14
-rw-r--r--spec/requests/api/project_debian_distributions_spec.rb66
-rw-r--r--spec/requests/users_controller_spec.rb42
-rw-r--r--spec/services/packages/debian/create_distribution_service_spec.rb9
-rw-r--r--spec/services/packages/debian/destroy_distribution_service_spec.rb78
-rw-r--r--spec/services/packages/debian/update_distribution_service_spec.rb2
-rw-r--r--spec/services/packages/nuget/metadata_extraction_service_spec.rb17
-rw-r--r--spec/services/packages/nuget/update_package_from_metadata_service_spec.rb279
-rw-r--r--spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb211
23 files changed, 698 insertions, 327 deletions
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 325d675a68c..8b02cfa30ab 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -74,6 +74,7 @@ RSpec.describe 'Database schema' do
slack_integrations: %w[team_id user_id],
snippets: %w[author_id],
spam_logs: %w[user_id],
+ status_check_responses: %w[external_approval_rule_id],
subscriptions: %w[user_id subscribable_id],
suggestions: %w[commit_id],
taggings: %w[tag_id taggable_id tagger_id],
diff --git a/spec/frontend/editor/editor_ci_schema_ext_spec.js b/spec/frontend/editor/editor_ci_schema_ext_spec.js
index 17a9ae7335f..2f0ecfb151e 100644
--- a/spec/frontend/editor/editor_ci_schema_ext_spec.js
+++ b/spec/frontend/editor/editor_ci_schema_ext_spec.js
@@ -4,6 +4,8 @@ import { EXTENSION_CI_SCHEMA_FILE_NAME_MATCH } from '~/editor/constants';
import EditorLite from '~/editor/editor_lite';
import { CiSchemaExtension } from '~/editor/extensions/editor_ci_schema_ext';
+const mockRef = 'AABBCCDD';
+
describe('~/editor/editor_ci_config_ext', () => {
const defaultBlobPath = '.gitlab-ci.yml';
@@ -75,8 +77,6 @@ describe('~/editor/editor_ci_config_ext', () => {
});
it('with an schema uri that contains project and ref', () => {
- const mockRef = 'AABBCCDD';
-
instance.registerCiSchema({
projectNamespace: mockProjectNamespace,
projectPath: mockProjectPath,
@@ -95,10 +95,11 @@ describe('~/editor/editor_ci_config_ext', () => {
instance.registerCiSchema({
projectNamespace: mockProjectNamespace,
projectPath: mockProjectPath,
+ ref: mockRef,
});
expect(getConfiguredYmlSchema()).toEqual({
- uri: `${TEST_HOST}/${mockProjectNamespace}/${mockProjectPath}/-/schema/master/${EXTENSION_CI_SCHEMA_FILE_NAME_MATCH}`,
+ uri: `${TEST_HOST}/${mockProjectNamespace}/${mockProjectPath}/-/schema/${mockRef}/${EXTENSION_CI_SCHEMA_FILE_NAME_MATCH}`,
fileMatch: ['another-ci-filename.yml'],
});
});
diff --git a/spec/frontend/members/mock_data.js b/spec/frontend/members/mock_data.js
index 678cea87dba..4275db5fa9f 100644
--- a/spec/frontend/members/mock_data.js
+++ b/spec/frontend/members/mock_data.js
@@ -30,6 +30,7 @@ export const member = {
usingLicense: false,
groupSso: false,
groupManagedAccount: false,
+ provisionedByThisGroup: false,
validRoles: {
Guest: 10,
Reporter: 20,
diff --git a/spec/frontend/packages/details/components/app_spec.js b/spec/frontend/packages/details/components/app_spec.js
index 4b890f868f4..3132ec61942 100644
--- a/spec/frontend/packages/details/components/app_spec.js
+++ b/spec/frontend/packages/details/components/app_spec.js
@@ -1,5 +1,6 @@
import { GlEmptyState } from '@gitlab/ui';
import { mount, createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
@@ -109,9 +110,11 @@ describe('PackagesApp', () => {
window.location = location;
});
- it('renders the app and displays the package title', () => {
+ it('renders the app and displays the package title', async () => {
createComponent();
+ await nextTick();
+
expect(packageTitle().exists()).toBe(true);
});
diff --git a/spec/frontend/packages/details/components/installations_commands_spec.js b/spec/frontend/packages/details/components/installations_commands_spec.js
index 065bf503585..164f9f69741 100644
--- a/spec/frontend/packages/details/components/installations_commands_spec.js
+++ b/spec/frontend/packages/details/components/installations_commands_spec.js
@@ -7,6 +7,7 @@ import MavenInstallation from '~/packages/details/components/maven_installation.
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,
@@ -15,6 +16,7 @@ import {
nugetPackage,
pypiPackage,
composerPackage,
+ terraformModule,
} from '../../mock_data';
describe('InstallationCommands', () => {
@@ -32,6 +34,7 @@ describe('InstallationCommands', () => {
const nugetInstallation = () => wrapper.find(NugetInstallation);
const pypiInstallation = () => wrapper.find(PypiInstallation);
const composerInstallation = () => wrapper.find(ComposerInstallation);
+ const terraformInstallation = () => wrapper.findComponent(TerraformInstallation);
afterEach(() => {
wrapper.destroy();
@@ -46,6 +49,7 @@ describe('InstallationCommands', () => {
${nugetPackage} | ${nugetInstallation}
${pypiPackage} | ${pypiInstallation}
${composerPackage} | ${composerInstallation}
+ ${terraformModule} | ${terraformInstallation}
`('renders', ({ packageEntity, selector }) => {
it(`${packageEntity.package_type} instructions exist`, () => {
createComponent({ packageEntity });
diff --git a/spec/frontend/packages/mock_data.js b/spec/frontend/packages/mock_data.js
index 46ccf5994b9..33b47cca68b 100644
--- a/spec/frontend/packages/mock_data.js
+++ b/spec/frontend/packages/mock_data.js
@@ -178,6 +178,20 @@ export const composerPackage = {
version: '1.0.0',
};
+export const terraformModule = {
+ created_at: '2015-12-10',
+ id: 2,
+ name: 'Test/system-22',
+ package_type: 'terraform_module',
+ project_path: 'foo/bar/baz',
+ projectPathName: 'foo/bar/baz',
+ project_id: 1,
+ updated_at: '2015-12-10',
+ version: '0.1',
+ versions: [],
+ _links,
+};
+
export const mockTags = [
{
name: 'foo-1',
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap
new file mode 100644
index 00000000000..427160b45e3
--- /dev/null
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/__snapshots__/terraform_installation_spec.js.snap
@@ -0,0 +1,44 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TerraformInstallation renders all the messages 1`] = `
+<div>
+ <h3
+ class="gl-font-lg"
+ >
+ Provision instructions
+ </h3>
+
+ <code-instruction-stub
+ copytext="Copy Terraform Command"
+ instruction="module \\"Test/system-22\\" {
+ source = \\"foo/Test/system-22\\"
+ version = \\"0.1\\"
+}"
+ label="Copy and paste into your Terraform configuration, insert the variables, and run Terraform init:"
+ multiline="true"
+ trackingaction=""
+ trackinglabel=""
+ />
+
+ <h3
+ class="gl-font-lg"
+ >
+ Registry setup
+ </h3>
+
+ <code-instruction-stub
+ copytext="Copy Terraform Setup Command"
+ instruction="credentials \\"gitlab.com\\" {
+ token = \\"<TOKEN>\\"
+}"
+ label="To authorize access to the Terraform registry:"
+ multiline="true"
+ trackingaction=""
+ trackinglabel=""
+ />
+
+ <gl-sprintf-stub
+ message="For more information on the Terraform registry, %{linkStart}see our documentation%{linkEnd}."
+ />
+</div>
+`;
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js
new file mode 100644
index 00000000000..87e0059344c
--- /dev/null
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details_title_spec.js
@@ -0,0 +1,93 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { terraformModule, mavenFiles, npmPackage } from 'jest/packages/mock_data';
+import component from '~/packages_and_registries/infrastructure_registry/components/details_title.vue';
+import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('PackageTitle', () => {
+ let wrapper;
+ let store;
+
+ function createComponent({ packageFiles = mavenFiles, packageEntity = terraformModule } = {}) {
+ store = new Vuex.Store({
+ state: {
+ packageEntity,
+ packageFiles,
+ },
+ getters: {
+ packagePipeline: ({ packageEntity: { pipeline = null } }) => pipeline,
+ },
+ });
+
+ wrapper = shallowMount(component, {
+ localVue,
+ store,
+ stubs: {
+ TitleArea,
+ },
+ });
+ return wrapper.vm.$nextTick();
+ }
+
+ const findTitleArea = () => wrapper.findComponent(TitleArea);
+ const packageSize = () => wrapper.find('[data-testid="package-size"]');
+ const pipelineProject = () => wrapper.find('[data-testid="pipeline-project"]');
+ const packageRef = () => wrapper.find('[data-testid="package-ref"]');
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('module title', () => {
+ it('is correctly bound', async () => {
+ await createComponent();
+
+ expect(findTitleArea().props('title')).toBe(terraformModule.name);
+ });
+ });
+
+ describe('calculates the package size', () => {
+ it('correctly calculates the size', async () => {
+ await createComponent();
+
+ expect(packageSize().props('text')).toBe('300 bytes');
+ });
+ });
+
+ 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_and_registries/infrastructure_registry/components/terraform_installation_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js
new file mode 100644
index 00000000000..7a129794d54
--- /dev/null
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/terraform_installation_spec.js
@@ -0,0 +1,61 @@
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { terraformModule as packageEntity } from 'jest/packages/mock_data';
+import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/components/terraform_installation.vue';
+import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('TerraformInstallation', () => {
+ let wrapper;
+
+ const store = new Vuex.Store({
+ state: {
+ packageEntity,
+ projectPath: 'foo',
+ },
+ });
+
+ const findCodeInstructions = () => wrapper.findAllComponents(CodeInstructions);
+
+ function createComponent() {
+ wrapper = shallowMount(TerraformInstallation, {
+ localVue,
+ store,
+ });
+ }
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders all the messages', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ describe('installation commands', () => {
+ it('renders the correct command', () => {
+ expect(findCodeInstructions().at(0).props('instruction')).toMatchInlineSnapshot(`
+ "module \\"Test/system-22\\" {
+ source = \\"foo/Test/system-22\\"
+ version = \\"0.1\\"
+ }"
+ `);
+ });
+ });
+
+ describe('setup commands', () => {
+ it('renders the correct command', () => {
+ expect(findCodeInstructions().at(1).props('instruction')).toMatchInlineSnapshot(`
+ "credentials \\"gitlab.com\\" {
+ token = \\"<TOKEN>\\"
+ }"
+ `);
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
index 756b8dd980c..6f9245e39aa 100644
--- a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
+++ b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
@@ -9,6 +9,7 @@ import {
mockCommitSha,
mockProjectPath,
mockProjectNamespace,
+ mockDefaultBranch,
} from '../../mock_data';
describe('Pipeline Editor | Text editor component', () => {
@@ -38,6 +39,7 @@ describe('Pipeline Editor | Text editor component', () => {
projectPath: mockProjectPath,
projectNamespace: mockProjectNamespace,
ciConfigPath: mockCiConfigPath,
+ defaultBranch: mockDefaultBranch,
glFeatures,
},
attrs: {
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 5c9af1206c0..847f7ec2d74 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -125,10 +125,10 @@ RSpec.describe Gitlab::Database do
expect(described_class.postgresql_minimum_supported_version?).to eq(false)
end
- it 'returns true when using PostgreSQL 11' do
+ it 'returns false when using PostgreSQL 11' do
allow(described_class).to receive(:version).and_return('11')
- expect(described_class.postgresql_minimum_supported_version?).to eq(true)
+ expect(described_class.postgresql_minimum_supported_version?).to eq(false)
end
it 'returns true when using PostgreSQL 12' do
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 8d27e61450b..085b0b4e259 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -342,7 +342,7 @@ container_repositories:
- project
- name
project:
-- external_approval_rules
+- external_status_checks
- taggings
- base_tags
- topic_taggings
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index 4075eb96fc2..3741e01e99a 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -418,8 +418,8 @@ RSpec.describe MergeRequestDiff do
shared_examples_for 'fetching full diffs' do
it 'returns diffs from repository comparison' do
expect_next_instance_of(Compare) do |comparison|
- expect(comparison).to receive(:diffs_in_batch)
- .with(1, 10, diff_options: diff_options)
+ expect(comparison).to receive(:diffs)
+ .with(diff_options)
.and_call_original
end
@@ -448,13 +448,13 @@ RSpec.describe MergeRequestDiff do
end
it_behaves_like 'fetching full diffs'
- end
- context 'when diff_options include ignore_whitespace_change' do
- it_behaves_like 'fetching full diffs' do
+ context 'when diff_options include ignore_whitespace_change' do
let(:diff_options) do
{ ignore_whitespace_change: true }
end
+
+ it_behaves_like 'fetching full diffs'
end
end
@@ -485,6 +485,51 @@ RSpec.describe MergeRequestDiff do
'files/whitespace'
])
end
+
+ context 'when diff_options include ignore_whitespace_change' do
+ let(:diff_options) do
+ { ignore_whitespace_change: true }
+ end
+
+ it 'returns a Gitlab::Diff::FileCollection::Compare with paginated diffs' do
+ diffs = diff_with_commits.diffs_in_batch(1, 10, diff_options: diff_options)
+
+ expect(diffs).to be_a(Gitlab::Diff::FileCollection::Compare)
+ expect(diffs.diff_files.size).to eq 10
+ expect(diffs.pagination_data).to eq(current_page: 1, next_page: 2, total_pages: 2)
+ end
+
+ it 'returns an empty MergeRequestBatch with empty pagination data when the batch is empty' do
+ diffs = diff_with_commits.diffs_in_batch(3, 10, diff_options: diff_options)
+
+ expect(diffs).to be_a(Gitlab::Diff::FileCollection::MergeRequestDiffBatch)
+ expect(diffs.diff_files.size).to eq 0
+ expect(diffs.pagination_data).to eq(current_page: nil, next_page: nil, total_pages: nil)
+ end
+
+ context 'with gradual load enabled' do
+ before do
+ stub_feature_flags(diffs_gradual_load: true)
+ end
+
+ it 'returns pagination data from MergeRequestDiffBatch' do
+ diffs = diff_with_commits.diffs_in_batch(1, 10, diff_options: diff_options)
+ file_count = diff_with_commits.merge_request_diff_files.count
+
+ expect(diffs).to be_a(Gitlab::Diff::FileCollection::Compare)
+ expect(diffs.diff_files.size).to eq 10
+ expect(diffs.pagination_data).to eq(current_page: nil, next_page: nil, total_pages: file_count)
+ end
+
+ it 'returns an empty MergeRequestBatch with empty pagination data when the batch is empty' do
+ diffs = diff_with_commits.diffs_in_batch(30, 10, diff_options: diff_options)
+
+ expect(diffs).to be_a(Gitlab::Diff::FileCollection::MergeRequestDiffBatch)
+ expect(diffs.diff_files.size).to eq 0
+ expect(diffs.pagination_data).to eq(current_page: nil, next_page: nil, total_pages: nil)
+ end
+ end
+ end
end
end
diff --git a/spec/requests/api/debian_group_packages_spec.rb b/spec/requests/api/debian_group_packages_spec.rb
index 42c6c987872..c3abb06c5c1 100644
--- a/spec/requests/api/debian_group_packages_spec.rb
+++ b/spec/requests/api/debian_group_packages_spec.rb
@@ -7,33 +7,33 @@ RSpec.describe API::DebianGroupPackages do
include_context 'Debian repository shared context', :group, false do
describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release.gpg' do
- let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution}/Release.gpg" }
+ let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/Release.gpg" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
end
describe 'GET groups/:id/-/packages/debian/dists/*distribution/Release' do
- let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution}/Release" }
+ let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/Release" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO Release'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Release$/
end
describe 'GET groups/:id/-/packages/debian/dists/*distribution/InRelease' do
- let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution}/InRelease" }
+ let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/InRelease" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
end
describe 'GET groups/:id/-/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
- let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
+ let(:url) { "/groups/#{container.id}/-/packages/debian/dists/#{distribution.codename}/#{component}/binary-#{architecture}/Packages" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO Packages'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Packages$/
end
describe 'GET groups/:id/-/packages/debian/pool/:component/:letter/:source_package/:file_name' do
let(:url) { "/groups/#{container.id}/-/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO File'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/
end
end
end
diff --git a/spec/requests/api/debian_project_packages_spec.rb b/spec/requests/api/debian_project_packages_spec.rb
index 023904cb2b8..c11c4ecc12a 100644
--- a/spec/requests/api/debian_project_packages_spec.rb
+++ b/spec/requests/api/debian_project_packages_spec.rb
@@ -7,33 +7,33 @@ RSpec.describe API::DebianProjectPackages do
include_context 'Debian repository shared context', :project, true do
describe 'GET projects/:id/packages/debian/dists/*distribution/Release.gpg' do
- let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution}/Release.gpg" }
+ let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/Release.gpg" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
end
describe 'GET projects/:id/packages/debian/dists/*distribution/Release' do
- let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution}/Release" }
+ let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/Release" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO Release'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Release$/
end
describe 'GET projects/:id/packages/debian/dists/*distribution/InRelease' do
- let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution}/InRelease" }
+ let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/InRelease" }
it_behaves_like 'Debian repository read endpoint', 'GET request', :not_found
end
describe 'GET projects/:id/packages/debian/dists/*distribution/:component/binary-:architecture/Packages' do
- let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution}/#{component}/binary-#{architecture}/Packages" }
+ let(:url) { "/projects/#{container.id}/packages/debian/dists/#{distribution.codename}/#{component}/binary-#{architecture}/Packages" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO Packages'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO Packages$/
end
describe 'GET projects/:id/packages/debian/pool/:component/:letter/:source_package/:file_name' do
let(:url) { "/projects/#{container.id}/packages/debian/pool/#{component}/#{letter}/#{source_package}/#{package_name}_#{package_version}_#{architecture}.deb" }
- it_behaves_like 'Debian repository read endpoint', 'GET request', :success, 'TODO File'
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^TODO File$/
end
describe 'PUT projects/:id/packages/debian/:file_name' do
diff --git a/spec/requests/api/project_debian_distributions_spec.rb b/spec/requests/api/project_debian_distributions_spec.rb
new file mode 100644
index 00000000000..de7362758f7
--- /dev/null
+++ b/spec/requests/api/project_debian_distributions_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe API::ProjectDebianDistributions do
+ include HttpBasicAuthHelpers
+ include WorkhorseHelpers
+
+ include_context 'Debian repository shared context', :project, true do
+ describe 'POST projects/:id/debian_distributions' do
+ let(:method) { :post }
+ let(:url) { "/projects/#{container.id}/debian_distributions" }
+ let(:api_params) { { 'codename': 'my-codename' } }
+
+ it_behaves_like 'Debian repository write endpoint', 'POST distribution request', :created, /^{.*"codename":"my-codename",.*"components":\["main"\],.*"architectures":\["all","amd64"\]/, authenticate_non_public: false
+
+ context 'with invalid parameters' do
+ let(:api_params) { { codename: distribution.codename } }
+
+ it_behaves_like 'Debian repository write endpoint', 'GET request', :bad_request, /^{"message":{"codename":\["has already been taken"\]}}$/, authenticate_non_public: false
+ end
+ end
+
+ describe 'GET projects/:id/debian_distributions' do
+ let(:url) { "/projects/#{container.id}/debian_distributions" }
+
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^\[{.*"codename":"existing-codename\",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/, authenticate_non_public: false
+ end
+
+ describe 'GET projects/:id/debian_distributions/:codename' do
+ let(:url) { "/projects/#{container.id}/debian_distributions/#{distribution.codename}" }
+
+ it_behaves_like 'Debian repository read endpoint', 'GET request', :success, /^{.*"codename":"existing-codename\",.*"components":\["existing-component"\],.*"architectures":\["all","existing-arch"\]/, authenticate_non_public: false
+ end
+
+ describe 'PUT projects/:id/debian_distributions/:codename' do
+ let(:method) { :put }
+ let(:url) { "/projects/#{container.id}/debian_distributions/#{distribution.codename}" }
+ let(:api_params) { { suite: 'my-suite' } }
+
+ it_behaves_like 'Debian repository write endpoint', 'PUT distribution request', :success, /^{.*"codename":"existing-codename",.*"suite":"my-suite",/, authenticate_non_public: false
+
+ context 'with invalid parameters' do
+ let(:api_params) { { suite: distribution.codename } }
+
+ it_behaves_like 'Debian repository write endpoint', 'GET request', :bad_request, /^{"message":{"suite":\["has already been taken as Codename"\]}}$/, authenticate_non_public: false
+ end
+ end
+
+ describe 'DELETE projects/:id/debian_distributions/:codename' do
+ let(:method) { :delete }
+ let(:url) { "/projects/#{container.id}/debian_distributions/#{distribution.codename}" }
+
+ it_behaves_like 'Debian repository maintainer write endpoint', 'DELETE distribution request', :success, /^{\"message\":\"202 Accepted\"}$/, authenticate_non_public: false
+
+ context 'when destroy fails' do
+ before do
+ allow_next_found_instance_of(::Packages::Debian::ProjectDistribution) do |distribution|
+ expect(distribution).to receive(:destroy).and_return(false)
+ end
+ end
+
+ it_behaves_like 'Debian repository maintainer write endpoint', 'GET request', :bad_request, /^{"message":"Failed to delete distribution"}$/, authenticate_non_public: false
+ end
+ end
+ end
+end
diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb
index f092cbf26a4..5a38f92221f 100644
--- a/spec/requests/users_controller_spec.rb
+++ b/spec/requests/users_controller_spec.rb
@@ -675,48 +675,6 @@ RSpec.describe UsersController do
end
end
- describe 'GET #suggests' do
- context 'when user exists' do
- it 'returns JSON indicating the user exists and a suggestion' do
- get user_suggests_url user.username
-
- expected_json = { exists: true, suggests: ["#{user.username}1"] }.to_json
- expect(response.body).to eq(expected_json)
- end
-
- context 'when the casing is different' do
- let(:user) { create(:user, username: 'CamelCaseUser') }
-
- it 'returns JSON indicating the user exists and a suggestion' do
- get user_suggests_url user.username.downcase
-
- expected_json = { exists: true, suggests: ["#{user.username.downcase}1"] }.to_json
- expect(response.body).to eq(expected_json)
- end
- end
- end
-
- context 'when the user does not exist' do
- it 'returns JSON indicating the user does not exist' do
- get user_suggests_url 'foo'
-
- expected_json = { exists: false, suggests: [] }.to_json
- expect(response.body).to eq(expected_json)
- end
-
- context 'when a user changed their username' do
- let(:redirect_route) { user.namespace.redirect_routes.create!(path: 'old-username') }
-
- it 'returns JSON indicating a user by that username does not exist' do
- get user_suggests_url 'old-username'
-
- expected_json = { exists: false, suggests: [] }.to_json
- expect(response.body).to eq(expected_json)
- end
- end
- end
- end
-
describe '#ensure_canonical_path' do
before do
sign_in(user)
diff --git a/spec/services/packages/debian/create_distribution_service_spec.rb b/spec/services/packages/debian/create_distribution_service_spec.rb
index 87cf1070075..ecf82c6a1db 100644
--- a/spec/services/packages/debian/create_distribution_service_spec.rb
+++ b/spec/services/packages/debian/create_distribution_service_spec.rb
@@ -4,8 +4,12 @@ require 'spec_helper'
RSpec.describe Packages::Debian::CreateDistributionService do
RSpec.shared_examples 'Create Debian Distribution' do |expected_message, expected_components, expected_architectures|
+ let_it_be(:container) { create(container_type) } # rubocop:disable Rails/SaveBang
+
it 'returns ServiceResponse', :aggregate_failures do
if expected_message.nil?
+ expect(::Packages::Debian::GenerateDistributionWorker).to receive(:perform_async).with(container_type, an_instance_of(Integer))
+
expect { response }
.to change { container.debian_distributions.klass.all.count }
.from(0).to(1)
@@ -18,6 +22,7 @@ RSpec.describe Packages::Debian::CreateDistributionService do
.and not_change { Packages::Debian::ProjectComponentFile.count }
.and not_change { Packages::Debian::GroupComponentFile.count }
else
+ expect(::Packages::Debian::GenerateDistributionWorker).not_to receive(:perform_async)
expect { response }
.to not_change { container.debian_distributions.klass.all.count }
.and not_change { container.debian_distributions.count }
@@ -109,13 +114,13 @@ RSpec.describe Packages::Debian::CreateDistributionService do
let(:response) { subject.execute }
context 'within a projet' do
- let_it_be(:container) { create(:project) }
+ let_it_be(:container_type) { :project }
it_behaves_like 'Debian Create Distribution Service'
end
context 'within a group' do
- let_it_be(:container) { create(:group) }
+ let_it_be(:container_type) { :group }
it_behaves_like 'Debian Create Distribution Service'
end
diff --git a/spec/services/packages/debian/destroy_distribution_service_spec.rb b/spec/services/packages/debian/destroy_distribution_service_spec.rb
deleted file mode 100644
index e4c43884bb4..00000000000
--- a/spec/services/packages/debian/destroy_distribution_service_spec.rb
+++ /dev/null
@@ -1,78 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Packages::Debian::DestroyDistributionService do
- RSpec.shared_examples 'Destroy Debian Distribution' do |expected_message|
- it 'returns ServiceResponse', :aggregate_failures do
- if expected_message.nil?
- expect { response }
- .to change { container.debian_distributions.klass.all.count }
- .from(1).to(0)
- .and change { container.debian_distributions.count }
- .from(1).to(0)
- .and change { component1.class.all.count }
- .from(2).to(0)
- .and change { architecture1.class.all.count }
- .from(3).to(0)
- .and change { component_file1.class.all.count }
- .from(4).to(0)
- else
- expect { response }
- .to not_change { container.debian_distributions.klass.all.count }
- .and not_change { container.debian_distributions.count }
- .and not_change { component1.class.all.count }
- .and not_change { architecture1.class.all.count }
- .and not_change { component_file1.class.all.count }
- end
-
- expect(response).to be_a(ServiceResponse)
- expect(response.success?).to eq(expected_message.nil?)
- expect(response.error?).to eq(!expected_message.nil?)
- expect(response.message).to eq(expected_message)
-
- if expected_message.nil?
- expect(response.payload).to eq({})
- else
- expect(response.payload).to eq(distribution: distribution)
- end
- end
- end
-
- RSpec.shared_examples 'Debian Destroy Distribution Service' do |container_type, can_freeze|
- context "with a Debian #{container_type} distribution" do
- let_it_be(:container, freeze: can_freeze) { create(container_type) } # rubocop:disable Rails/SaveBang
- let_it_be(:distribution, freeze: can_freeze) { create("debian_#{container_type}_distribution", container: container) }
- let_it_be(:component1, freeze: can_freeze) { create("debian_#{container_type}_component", distribution: distribution, name: 'component1') }
- let_it_be(:component2, freeze: can_freeze) { create("debian_#{container_type}_component", distribution: distribution, name: 'component2') }
- let_it_be(:architecture0, freeze: true) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'all') }
- let_it_be(:architecture1, freeze: can_freeze) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'architecture1') }
- let_it_be(:architecture2, freeze: can_freeze) { create("debian_#{container_type}_architecture", distribution: distribution, name: 'architecture2') }
- let_it_be(:component_file1, freeze: can_freeze) { create("debian_#{container_type}_component_file", :source, component: component1) }
- let_it_be(:component_file2, freeze: can_freeze) { create("debian_#{container_type}_component_file", component: component1, architecture: architecture1) }
- let_it_be(:component_file3, freeze: can_freeze) { create("debian_#{container_type}_component_file", :source, component: component2) }
- let_it_be(:component_file4, freeze: can_freeze) { create("debian_#{container_type}_component_file", component: component2, architecture: architecture2) }
-
- subject { described_class.new(distribution) }
-
- let(:response) { subject.execute }
-
- context 'with a distribution' do
- it_behaves_like 'Destroy Debian Distribution'
- end
-
- context 'when destroy fails' do
- let(:distribution) { create("debian_#{container_type}_distribution", container: container) }
-
- before do
- expect(distribution).to receive(:destroy).and_return(false)
- end
-
- it_behaves_like 'Destroy Debian Distribution', "Unable to destroy Debian #{container_type} distribution"
- end
- end
- end
-
- it_behaves_like 'Debian Destroy Distribution Service', :project, true
- it_behaves_like 'Debian Destroy Distribution Service', :group, false
-end
diff --git a/spec/services/packages/debian/update_distribution_service_spec.rb b/spec/services/packages/debian/update_distribution_service_spec.rb
index 852fc713e34..2aa34a62111 100644
--- a/spec/services/packages/debian/update_distribution_service_spec.rb
+++ b/spec/services/packages/debian/update_distribution_service_spec.rb
@@ -6,6 +6,8 @@ RSpec.describe Packages::Debian::UpdateDistributionService do
RSpec.shared_examples 'Update Debian Distribution' do |expected_message, expected_components, expected_architectures, component_file_delta = 0|
it 'returns ServiceResponse', :aggregate_failures do
expect(distribution).to receive(:update).with(simple_params).and_call_original if expected_message.nil?
+ expect(::Packages::Debian::GenerateDistributionWorker).to receive(:perform_async).with(distribution.class.container_type, distribution.id).and_call_original if expected_message.nil?
+ expect(::Packages::Debian::GenerateDistributionWorker).not_to receive(:perform_async) unless expected_message.nil?
if component_file_delta.zero?
expect { response }
diff --git a/spec/services/packages/nuget/metadata_extraction_service_spec.rb b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
index b3980d3b7fa..79428b58bd9 100644
--- a/spec/services/packages/nuget/metadata_extraction_service_spec.rb
+++ b/spec/services/packages/nuget/metadata_extraction_service_spec.rb
@@ -24,22 +24,7 @@ RSpec.describe Packages::Nuget::MetadataExtractionService do
package_tags: []
}
- context 'with packages_nuget_archive_new_file_reader enabled' do
- before do
- expect(service).to receive(:with_new_file_reader).and_call_original
- end
-
- it { is_expected.to eq(expected_metadata) }
- end
-
- context 'with packages_nuget_archive_new_file_reader disabled' do
- before do
- stub_feature_flags(packages_nuget_archive_new_file_reader: false)
- expect(service).to receive(:with_legacy_file_reader).and_call_original
- end
-
- it { is_expected.to eq(expected_metadata) }
- end
+ it { is_expected.to eq(expected_metadata) }
end
context 'with nuspec file' do
diff --git a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
index e41475f786d..ffe1a5b7646 100644
--- a/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
+++ b/spec/services/packages/nuget/update_package_from_metadata_service_spec.rb
@@ -63,191 +63,178 @@ RSpec.describe Packages::Nuget::UpdatePackageFromMetadataService, :clean_gitlab_
end
end
- shared_examples 'handling all conditions' do
- context 'with no existing package' do
- let(:package_id) { package.id }
-
- it 'updates package and package file' do
- expect { subject }
- .to change { ::Packages::Package.count }.by(1)
- .and change { Packages::Dependency.count }.by(1)
- .and change { Packages::DependencyLink.count }.by(1)
- .and change { ::Packages::Nuget::Metadatum.count }.by(0)
-
- expect(package.reload.name).to eq(package_name)
- expect(package.version).to eq(package_version)
- expect(package).to be_default
- expect(package_file.reload.file_name).to eq(package_file_name)
- # hard reset needed to properly reload package_file.file
- expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
- end
-
- it_behaves_like 'taking the lease'
-
- it_behaves_like 'not updating the package if the lease is taken'
+ context 'with no existing package' do
+ let(:package_id) { package.id }
+
+ it 'updates package and package file' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { Packages::Dependency.count }.by(1)
+ .and change { Packages::DependencyLink.count }.by(1)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package).to be_default
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
end
- context 'with existing package' do
- let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
- let(:package_id) { existing_package.id }
+ it_behaves_like 'taking the lease'
- it 'link existing package and updates package file' do
- expect(service).to receive(:try_obtain_lease).and_call_original
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
- expect { subject }
- .to change { ::Packages::Package.count }.by(-1)
- .and change { Packages::Dependency.count }.by(0)
- .and change { Packages::DependencyLink.count }.by(0)
- .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
- .and change { ::Packages::Nuget::Metadatum.count }.by(0)
- expect(package_file.reload.file_name).to eq(package_file_name)
- expect(package_file.package).to eq(existing_package)
- end
+ context 'with existing package' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: package_name, version: package_version) }
+ let(:package_id) { existing_package.id }
- it_behaves_like 'taking the lease'
+ it 'link existing package and updates package file' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
- it_behaves_like 'not updating the package if the lease is taken'
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(-1)
+ .and change { Packages::Dependency.count }.by(0)
+ .and change { Packages::DependencyLink.count }.by(0)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(0)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(0)
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ expect(package_file.package).to eq(existing_package)
end
- context 'with a nuspec file with metadata' do
- let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
- let(:expected_tags) { %w(foo bar test tag1 tag2 tag3 tag4 tag5) }
+ it_behaves_like 'taking the lease'
- before do
- allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
- allow(service)
- .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
- end
- end
+ it_behaves_like 'not updating the package if the lease is taken'
+ end
- it 'creates tags' do
- expect(service).to receive(:try_obtain_lease).and_call_original
- expect { subject }.to change { ::Packages::Tag.count }.by(8)
- expect(package.reload.tags.map(&:name)).to contain_exactly(*expected_tags)
- end
+ context 'with a nuspec file with metadata' do
+ let(:nuspec_filepath) { 'packages/nuget/with_metadata.nuspec' }
+ let(:expected_tags) { %w(foo bar test tag1 tag2 tag3 tag4 tag5) }
- context 'with existing package and tags' do
- let!(:existing_package) { create(:nuget_package, project: package.project, name: 'DummyProject.WithMetadata', version: '1.2.3') }
- let!(:tag1) { create(:packages_tag, package: existing_package, name: 'tag1') }
- let!(:tag2) { create(:packages_tag, package: existing_package, name: 'tag2') }
- let!(:tag3) { create(:packages_tag, package: existing_package, name: 'tag_not_in_metadata') }
-
- it 'creates tags and deletes those not in metadata' do
- expect(service).to receive(:try_obtain_lease).and_call_original
- expect { subject }.to change { ::Packages::Tag.count }.by(5)
- expect(existing_package.tags.map(&:name)).to contain_exactly(*expected_tags)
- end
+ before do
+ allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
+ allow(service)
+ .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
end
+ end
- it 'creates nuget metadatum' do
- expect { subject }
- .to change { ::Packages::Package.count }.by(1)
- .and change { ::Packages::Nuget::Metadatum.count }.by(1)
+ it 'creates tags' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect { subject }.to change { ::Packages::Tag.count }.by(8)
+ expect(package.reload.tags.map(&:name)).to contain_exactly(*expected_tags)
+ end
- metadatum = package_file.reload.package.nuget_metadatum
- expect(metadatum.license_url).to eq('https://opensource.org/licenses/MIT')
- expect(metadatum.project_url).to eq('https://gitlab.com/gitlab-org/gitlab')
- expect(metadatum.icon_url).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png')
+ context 'with existing package and tags' do
+ let!(:existing_package) { create(:nuget_package, project: package.project, name: 'DummyProject.WithMetadata', version: '1.2.3') }
+ let!(:tag1) { create(:packages_tag, package: existing_package, name: 'tag1') }
+ let!(:tag2) { create(:packages_tag, package: existing_package, name: 'tag2') }
+ let!(:tag3) { create(:packages_tag, package: existing_package, name: 'tag_not_in_metadata') }
+
+ it 'creates tags and deletes those not in metadata' do
+ expect(service).to receive(:try_obtain_lease).and_call_original
+ expect { subject }.to change { ::Packages::Tag.count }.by(5)
+ expect(existing_package.tags.map(&:name)).to contain_exactly(*expected_tags)
end
+ end
- context 'with too long url' do
- let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
+ it 'creates nuget metadatum' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { ::Packages::Nuget::Metadatum.count }.by(1)
- let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
+ metadatum = package_file.reload.package.nuget_metadatum
+ expect(metadatum.license_url).to eq('https://opensource.org/licenses/MIT')
+ expect(metadatum.project_url).to eq('https://gitlab.com/gitlab-org/gitlab')
+ expect(metadatum.icon_url).to eq('https://opensource.org/files/osi_keyhole_300X300_90ppi_0.png')
+ end
+
+ context 'with too long url' do
+ let_it_be(:too_long_url) { "http://localhost/#{'bananas' * 50}" }
- before do
- allow(service).to receive(:metadata).and_return(metadata)
- end
+ let(:metadata) { { package_name: package_name, package_version: package_version, license_url: too_long_url } }
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ before do
+ allow(service).to receive(:metadata).and_return(metadata)
end
+
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
end
+ end
- context 'with nuspec file with dependencies' do
- let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
- let(:package_name) { 'Test.Package' }
- let(:package_version) { '3.5.2' }
- let(:package_file_name) { 'test.package.3.5.2.nupkg' }
+ context 'with nuspec file with dependencies' do
+ let(:nuspec_filepath) { 'packages/nuget/with_dependencies.nuspec' }
+ let(:package_name) { 'Test.Package' }
+ let(:package_version) { '3.5.2' }
+ let(:package_file_name) { 'test.package.3.5.2.nupkg' }
- before do
- allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
- allow(service)
- .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
- end
+ before do
+ allow_next_instance_of(Packages::Nuget::MetadataExtractionService) do |service|
+ allow(service)
+ .to receive(:nuspec_file_content).and_return(fixture_file(nuspec_filepath))
end
+ end
- it 'updates package and package file' do
- expect { subject }
- .to change { ::Packages::Package.count }.by(1)
- .and change { Packages::Dependency.count }.by(4)
- .and change { Packages::DependencyLink.count }.by(4)
- .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(2)
-
- expect(package.reload.name).to eq(package_name)
- expect(package.version).to eq(package_version)
- expect(package).to be_default
- expect(package_file.reload.file_name).to eq(package_file_name)
- # hard reset needed to properly reload package_file.file
- expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
- end
+ it 'updates package and package file' do
+ expect { subject }
+ .to change { ::Packages::Package.count }.by(1)
+ .and change { Packages::Dependency.count }.by(4)
+ .and change { Packages::DependencyLink.count }.by(4)
+ .and change { Packages::Nuget::DependencyLinkMetadatum.count }.by(2)
+
+ expect(package.reload.name).to eq(package_name)
+ expect(package.version).to eq(package_version)
+ expect(package).to be_default
+ expect(package_file.reload.file_name).to eq(package_file_name)
+ # hard reset needed to properly reload package_file.file
+ expect(Packages::PackageFile.find(package_file.id).file.size).not_to eq 0
end
+ end
- context 'with package file not containing a nuspec file' do
- before do
- allow_next_instance_of(Zip::File) do |file|
- allow(file).to receive(:glob).and_return([])
- end
+ context 'with package file not containing a nuspec file' do
+ before do
+ allow_next_instance_of(Zip::File) do |file|
+ allow(file).to receive(:glob).and_return([])
end
-
- it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
end
- context 'with an invalid package name' do
- invalid_names = [
- '',
- 'My/package',
- '../../../my_package',
- '%2e%2e%2fmy_package'
- ]
+ it_behaves_like 'raising an', ::Packages::Nuget::MetadataExtractionService::ExtractionError
+ end
- invalid_names.each do |invalid_name|
- before do
- allow(service).to receive(:package_name).and_return(invalid_name)
- end
+ context 'with an invalid package name' do
+ invalid_names = [
+ '',
+ 'My/package',
+ '../../../my_package',
+ '%2e%2e%2fmy_package'
+ ]
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
+ invalid_names.each do |invalid_name|
+ before do
+ allow(service).to receive(:package_name).and_return(invalid_name)
end
- end
- context 'with an invalid package version' do
- invalid_versions = [
- '',
- '555',
- '1.2',
- '1./2.3',
- '../../../../../1.2.3',
- '%2e%2e%2f1.2.3'
- ]
-
- invalid_versions.each do |invalid_version|
- before do
- allow(service).to receive(:package_version).and_return(invalid_version)
- end
-
- it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
- end
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
end
end
- it_behaves_like 'handling all conditions'
+ context 'with an invalid package version' do
+ invalid_versions = [
+ '',
+ '555',
+ '1.2',
+ '1./2.3',
+ '../../../../../1.2.3',
+ '%2e%2e%2f1.2.3'
+ ]
+
+ invalid_versions.each do |invalid_version|
+ before do
+ allow(service).to receive(:package_version).and_return(invalid_version)
+ end
- context 'with packages_nuget_archive_new_file_reader disabled' do
- before do
- stub_feature_flags(packages_nuget_archive_new_file_reader: false)
- stub_package_file_object_storage(enabled: true, direct_upload: true)
+ it_behaves_like 'raising an', ::Packages::Nuget::UpdatePackageFromMetadataService::InvalidMetadataError
end
-
- it_behaves_like 'handling all conditions'
end
end
end
diff --git a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
index 7c47b900dc0..0530aa8c760 100644
--- a/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/debian_packages_shared_examples.rb
@@ -12,7 +12,35 @@ RSpec.shared_context 'Debian repository shared context' do |container_type, can_
let_it_be(:user, freeze: true) { create(:user) }
let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, user: user) }
- let(:distribution) { 'bullseye' }
+ let_it_be(:private_distribution, freeze: true) { create("debian_#{container_type}_distribution", container: private_container, codename: 'existing-codename') }
+ let_it_be(:private_component, freeze: true) { create("debian_#{container_type}_component", distribution: private_distribution, name: 'existing-component') }
+ let_it_be(:private_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'all') }
+ let_it_be(:private_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: private_distribution, name: 'existing-arch') }
+
+ let_it_be(:public_distribution, freeze: true) { create("debian_#{container_type}_distribution", container: public_container, codename: 'existing-codename') }
+ let_it_be(:public_component, freeze: true) { create("debian_#{container_type}_component", distribution: public_distribution, name: 'existing-component') }
+ let_it_be(:public_architecture_all, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'all') }
+ let_it_be(:public_architecture, freeze: true) { create("debian_#{container_type}_architecture", distribution: public_distribution, name: 'existing-arch') }
+
+ if container_type == :group
+ let_it_be(:private_project) { create(:project, :private, group: private_container) }
+ let_it_be(:public_project) { create(:project, :public, group: public_container) }
+ let_it_be(:private_project_distribution) { create(:debian_project_distribution, container: private_project, codename: 'existing-codename') }
+ let_it_be(:public_project_distribution) { create(:debian_project_distribution, container: public_project, codename: 'existing-codename') }
+ else
+ let_it_be(:private_project) { private_container }
+ let_it_be(:public_project) { public_container }
+ let_it_be(:private_project_distribution) { private_distribution }
+ let_it_be(:public_project_distribution) { public_distribution }
+ end
+
+ let_it_be(:private_package) { create(:debian_package, project: private_project, published_in: private_project_distribution) }
+ let_it_be(:public_package) { create(:debian_package, project: public_project, published_in: public_project_distribution) }
+
+ let(:visibility_level) { :public }
+
+ let(:distribution) { { private: private_distribution, public: public_distribution }[visibility_level] }
+
let(:component) { 'main' }
let(:architecture) { 'amd64' }
let(:source_package) { 'sample' }
@@ -97,7 +125,7 @@ RSpec.shared_examples 'Debian repository GET request' do |status, body = nil|
expect(response).to have_gitlab_http_status(status)
unless body.nil?
- expect(response.body).to eq(body)
+ expect(response.body).to match(body)
end
end
end
@@ -125,7 +153,7 @@ RSpec.shared_examples 'Debian repository upload request' do |status, body = nil|
expect(response.media_type).to eq('text/plain')
unless body.nil?
- expect(response.body).to eq(body)
+ expect(response.body).to match(body)
end
end
it_behaves_like 'a package tracking event', described_class.name, 'push_package'
@@ -136,7 +164,7 @@ RSpec.shared_examples 'Debian repository upload request' do |status, body = nil|
expect(response).to have_gitlab_http_status(status)
unless body.nil?
- expect(response.body).to eq(body)
+ expect(response.body).to match(body)
end
end
end
@@ -182,18 +210,112 @@ RSpec.shared_examples 'Debian repository upload authorize request' do |status, b
expect(response).to have_gitlab_http_status(status)
unless body.nil?
- expect(response.body).to eq(body)
+ expect(response.body).to match(body)
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'Debian repository POST distribution request' do |status, body|
+ and_body = body.nil? ? '' : ' and expected body'
+
+ if status == :created
+ it 'creates distribution', :aggregate_failures do
+ expect(::Packages::Debian::CreateDistributionService).to receive(:new).with(container, user, api_params).and_call_original
+
+ expect { subject }
+ .to change { Packages::Debian::GroupDistribution.all.count + Packages::Debian::ProjectDistribution.all.count }.by(1)
+ .and change { Packages::Debian::GroupComponent.all.count + Packages::Debian::ProjectComponent.all.count }.by(1)
+ .and change { Packages::Debian::GroupArchitecture.all.count + Packages::Debian::ProjectArchitecture.all.count }.by(2)
+
+ expect(response).to have_gitlab_http_status(status)
+ expect(response.media_type).to eq('application/json')
+
+ unless body.nil?
+ expect(response.body).to match(body)
+ end
+ end
+ else
+ it "returns #{status}#{and_body}", :aggregate_failures do
+ subject
+
+ expect(response).to have_gitlab_http_status(status)
+
+ unless body.nil?
+ expect(response.body).to match(body)
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'Debian repository PUT distribution request' do |status, body|
+ and_body = body.nil? ? '' : ' and expected body'
+
+ if status == :success
+ it 'updates distribution', :aggregate_failures do
+ expect(::Packages::Debian::UpdateDistributionService).to receive(:new).with(distribution, api_params.except(:codename)).and_call_original
+
+ expect { subject }
+ .to not_change { Packages::Debian::GroupDistribution.all.count + Packages::Debian::ProjectDistribution.all.count }
+ .and not_change { Packages::Debian::GroupComponent.all.count + Packages::Debian::ProjectComponent.all.count }
+ .and not_change { Packages::Debian::GroupArchitecture.all.count + Packages::Debian::ProjectArchitecture.all.count }
+
+ expect(response).to have_gitlab_http_status(status)
+ expect(response.media_type).to eq('application/json')
+
+ unless body.nil?
+ expect(response.body).to match(body)
+ end
+ end
+ else
+ it "returns #{status}#{and_body}", :aggregate_failures do
+ subject
+
+ expect(response).to have_gitlab_http_status(status)
+
+ unless body.nil?
+ expect(response.body).to match(body)
end
end
end
end
-RSpec.shared_examples 'rejects Debian access with unknown container id' do
+RSpec.shared_examples 'Debian repository DELETE distribution request' do |status, body|
+ and_body = body.nil? ? '' : ' and expected body'
+
+ if status == :success
+ it 'updates distribution', :aggregate_failures do
+ expect { subject }
+ .to change { Packages::Debian::GroupDistribution.all.count + Packages::Debian::ProjectDistribution.all.count }.by(-1)
+ .and change { Packages::Debian::GroupComponent.all.count + Packages::Debian::ProjectComponent.all.count }.by(-1)
+ .and change { Packages::Debian::GroupArchitecture.all.count + Packages::Debian::ProjectArchitecture.all.count }.by(-2)
+
+ expect(response).to have_gitlab_http_status(status)
+ expect(response.media_type).to eq('application/json')
+
+ unless body.nil?
+ expect(response.body).to match(body)
+ end
+ end
+ else
+ it "returns #{status}#{and_body}", :aggregate_failures do
+ subject
+
+ expect(response).to have_gitlab_http_status(status)
+
+ unless body.nil?
+ expect(response.body).to match(body)
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'rejects Debian access with unknown container id' do |hidden_status|
context 'with an unknown container' do
let(:container) { double(id: non_existing_record_id) }
context 'as anonymous' do
- it_behaves_like 'Debian repository GET request', :unauthorized, nil
+ it_behaves_like 'Debian repository GET request', hidden_status, nil
end
context 'as authenticated user' do
@@ -204,19 +326,25 @@ RSpec.shared_examples 'rejects Debian access with unknown container id' do
end
end
-RSpec.shared_examples 'Debian repository read endpoint' do |desired_behavior, success_status, success_body|
+RSpec.shared_examples 'Debian repository read endpoint' do |desired_behavior, success_status, success_body, authenticate_non_public: true|
+ hidden_status = if authenticate_non_public
+ :unauthorized
+ else
+ :not_found
+ end
+
context 'with valid container' do
using RSpec::Parameterized::TableSyntax
where(:visibility_level, :user_role, :member, :user_token, :expected_status, :expected_body) do
:public | :developer | true | true | success_status | success_body
:public | :guest | true | true | success_status | success_body
- :public | :developer | true | false | success_status | success_body
- :public | :guest | true | false | success_status | success_body
+ :public | :developer | true | false | :unauthorized | nil
+ :public | :guest | true | false | :unauthorized | nil
:public | :developer | false | true | success_status | success_body
:public | :guest | false | true | success_status | success_body
- :public | :developer | false | false | success_status | success_body
- :public | :guest | false | false | success_status | success_body
+ :public | :developer | false | false | :unauthorized | nil
+ :public | :guest | false | false | :unauthorized | nil
:public | :anonymous | false | true | success_status | success_body
:private | :developer | true | true | success_status | success_body
:private | :guest | true | true | :forbidden | nil
@@ -226,7 +354,7 @@ RSpec.shared_examples 'Debian repository read endpoint' do |desired_behavior, su
:private | :guest | false | true | :not_found | nil
:private | :developer | false | false | :unauthorized | nil
:private | :guest | false | false | :unauthorized | nil
- :private | :anonymous | false | true | :unauthorized | nil
+ :private | :anonymous | false | true | hidden_status | nil
end
with_them do
@@ -236,10 +364,16 @@ RSpec.shared_examples 'Debian repository read endpoint' do |desired_behavior, su
end
end
- it_behaves_like 'rejects Debian access with unknown container id'
+ it_behaves_like 'rejects Debian access with unknown container id', hidden_status
end
-RSpec.shared_examples 'Debian repository write endpoint' do |desired_behavior, success_status, success_body|
+RSpec.shared_examples 'Debian repository write endpoint' do |desired_behavior, success_status, success_body, authenticate_non_public: true|
+ hidden_status = if authenticate_non_public
+ :unauthorized
+ else
+ :not_found
+ end
+
context 'with valid container' do
using RSpec::Parameterized::TableSyntax
@@ -261,7 +395,50 @@ RSpec.shared_examples 'Debian repository write endpoint' do |desired_behavior, s
:private | :guest | false | true | :not_found | nil
:private | :developer | false | false | :unauthorized | nil
:private | :guest | false | false | :unauthorized | nil
- :private | :anonymous | false | true | :unauthorized | nil
+ :private | :anonymous | false | true | hidden_status | nil
+ end
+
+ with_them do
+ include_context 'Debian repository access', params[:visibility_level], params[:user_role], params[:member], params[:user_token], :basic do
+ it_behaves_like "Debian repository #{desired_behavior}", params[:expected_status], params[:expected_body]
+ end
+ end
+ end
+
+ it_behaves_like 'rejects Debian access with unknown container id', hidden_status
+end
+
+RSpec.shared_examples 'Debian repository maintainer write endpoint' do |desired_behavior, success_status, success_body, authenticate_non_public: true|
+ hidden_status = if authenticate_non_public
+ :unauthorized
+ else
+ :not_found
+ end
+
+ context 'with valid container' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:visibility_level, :user_role, :member, :user_token, :expected_status, :expected_body) do
+ :public | :maintainer | true | true | success_status | success_body
+ :public | :developer | true | true | :forbidden | nil
+ :public | :guest | true | true | :forbidden | nil
+ :public | :maintainer | true | false | :unauthorized | nil
+ :public | :guest | true | false | :unauthorized | nil
+ :public | :maintainer | false | true | :forbidden | nil
+ :public | :guest | false | true | :forbidden | nil
+ :public | :maintainer | false | false | :unauthorized | nil
+ :public | :guest | false | false | :unauthorized | nil
+ :public | :anonymous | false | true | :unauthorized | nil
+ :private | :maintainer | true | true | success_status | success_body
+ :private | :developer | true | true | :forbidden | nil
+ :private | :guest | true | true | :forbidden | nil
+ :private | :maintainer | true | false | :unauthorized | nil
+ :private | :guest | true | false | :unauthorized | nil
+ :private | :maintainer | false | true | :not_found | nil
+ :private | :guest | false | true | :not_found | nil
+ :private | :maintainer | false | false | :unauthorized | nil
+ :private | :guest | false | false | :unauthorized | nil
+ :private | :anonymous | false | true | hidden_status | nil
end
with_them do
@@ -271,5 +448,5 @@ RSpec.shared_examples 'Debian repository write endpoint' do |desired_behavior, s
end
end
- it_behaves_like 'rejects Debian access with unknown container id'
+ it_behaves_like 'rejects Debian access with unknown container id', hidden_status
end