Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-25 15:09:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-25 15:09:24 +0300
commit7a3aca2b5b3bfdebbd7bb6353d5bdcdc422670da (patch)
treed3431811140c48c2ed31f2e8fdc90504f3bd4344 /spec
parent9c3a433b3176e895a23cf0f4b87411b44e264397 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap119
-rw-r--r--spec/frontend/repository/components/commit_info_spec.js87
-rw-r--r--spec/frontend/repository/components/last_commit_spec.js119
-rw-r--r--spec/initializers/gitlab_http_spec.rb47
-rw-r--r--spec/initializers/net_http_patch_spec.rb8
-rw-r--r--spec/initializers/net_http_response_patch_spec.rb3
-rw-r--r--spec/lib/container_registry/client_spec.rb27
-rw-r--r--spec/models/clusters/agent_token_spec.rb9
-rw-r--r--spec/requests/api/group_export_spec.rb7
-rw-r--r--spec/requests/api/npm_group_packages_spec.rb10
-rw-r--r--spec/requests/api/project_export_spec.rb14
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb52
-rw-r--r--spec/workers/merge_worker_spec.rb57
13 files changed, 341 insertions, 218 deletions
diff --git a/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap b/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
index 3f901dc61b8..e48041c1032 100644
--- a/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
+++ b/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
@@ -1,97 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Repository last commit component renders commit widget 1`] = `
-<div
- class="commit gl-display-flex gl-p-5 gl-w-full well-segment"
+<commit-info-stub
+ commit="[object Object]"
>
- <user-avatar-link-stub
- class="gl-mr-4 gl-my-2"
- imgalt=""
- imgcssclasses=""
- imgcsswrapperclasses=""
- imgsize="32"
- imgsrc="https://test.com"
- linkhref="/test"
- popoveruserid=""
- popoverusername=""
- tooltipplacement="top"
- tooltiptext=""
- username=""
- />
<div
- class="commit-detail flex-list gl-align-items-center gl-display-flex gl-flex-grow-1 gl-justify-content-space-between gl-min-w-0"
+ class="commit-actions gl-align-items-center gl-display-flex gl-flex-align gl-flex-direction-row"
>
<div
- class="commit-content"
- data-qa-selector="commit_content"
+ class="ci-status-link"
>
- <gl-link-stub
- class="commit-row-message item-title"
- href="/commit/123"
- >
- Commit title
- </gl-link-stub>
- <div
- class="committer"
- >
- <gl-link-stub
- class="commit-author-link js-user-link"
- href="/test"
- >
- Test
- </gl-link-stub>
- authored
- <timeago-tooltip-stub
- cssclass=""
- datetimeformat="DATE_WITH_TIME_FORMAT"
- time="2019-01-01"
- tooltipplacement="bottom"
- />
- </div>
+ <ci-badge-link-stub
+ aria-label="Pipeline: failed"
+ class="js-commit-pipeline"
+ details-path="https://test.com/pipeline"
+ size="lg"
+ status="[object Object]"
+ />
</div>
- <div
- class="gl-flex-grow-1"
- />
- <div
- class="commit-actions gl-align-items-center gl-display-flex gl-flex-align gl-flex-direction-row"
+ <gl-button-group-stub
+ class="gl-ml-4 js-commit-sha-group"
>
- <div
- class="ci-status-link"
- >
- <ci-badge-link-stub
- aria-label="Pipeline: failed"
- class="js-commit-pipeline"
- details-path="https://test.com/pipeline"
- size="lg"
- status="[object Object]"
- />
- </div>
- <gl-button-group-stub
- class="gl-ml-4 js-commit-sha-group"
+ <gl-button-stub
+ buttontextclasses=""
+ category="primary"
+ class="gl-font-monospace"
+ data-testid="last-commit-id-label"
+ icon=""
+ label="true"
+ size="medium"
+ variant="default"
>
- <gl-button-stub
- buttontextclasses=""
- category="primary"
- class="gl-font-monospace"
- data-testid="last-commit-id-label"
- icon=""
- label="true"
- size="medium"
- variant="default"
- >
- 12345678
- </gl-button-stub>
- <clipboard-button-stub
- category="secondary"
- class="input-group-text"
- size="medium"
- text="123456789"
- title="Copy commit SHA"
- tooltipplacement="top"
- variant="default"
- />
- </gl-button-group-stub>
- </div>
+ 12345678
+ </gl-button-stub>
+ <clipboard-button-stub
+ category="secondary"
+ class="input-group-text"
+ size="medium"
+ text="123456789"
+ title="Copy commit SHA"
+ tooltipplacement="top"
+ variant="default"
+ />
+ </gl-button-group-stub>
</div>
-</div>
+</commit-info-stub>
`;
diff --git a/spec/frontend/repository/components/commit_info_spec.js b/spec/frontend/repository/components/commit_info_spec.js
new file mode 100644
index 00000000000..34e941aa858
--- /dev/null
+++ b/spec/frontend/repository/components/commit_info_spec.js
@@ -0,0 +1,87 @@
+import { nextTick } from 'vue';
+import { GlButton } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import CommitInfo from '~/repository/components/commit_info.vue';
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+
+let wrapper;
+const commit = {
+ title: 'Commit title',
+ titleHtml: 'Commit title html',
+ message: 'Commit message',
+ authoredDate: '2019-01-01',
+ authorName: 'Test authorName',
+ author: { name: 'Test name', avatarUrl: 'https://test.com', webPath: '/test' },
+};
+
+const findTextExpander = () => wrapper.findComponent(GlButton);
+const findUserLink = () => wrapper.findByText(commit.author.name);
+const findUserAvatarLink = () => wrapper.findComponent(UserAvatarLink);
+const findAuthorName = () => wrapper.findByText(`${commit.authorName} authored`);
+const findCommitRowDescription = () => wrapper.find('pre');
+const findTitleHtml = () => wrapper.findByText(commit.titleHtml);
+
+const createComponent = async ({ commitMock = {} } = {}) => {
+ wrapper = shallowMountExtended(CommitInfo, {
+ propsData: { commit: { ...commit, ...commitMock } },
+ });
+
+ await nextTick();
+};
+
+describe('Repository last commit component', () => {
+ it('renders author info', () => {
+ createComponent();
+
+ expect(findUserLink().exists()).toBe(true);
+ expect(findUserAvatarLink().exists()).toBe(true);
+ });
+
+ it('hides author component when author does not exist', () => {
+ createComponent({ commitMock: { author: null } });
+
+ expect(findUserLink().exists()).toBe(false);
+ expect(findUserAvatarLink().exists()).toBe(false);
+ expect(findAuthorName().exists()).toBe(true);
+ });
+
+ it('does not render description expander when description is null', () => {
+ createComponent();
+
+ expect(findTextExpander().exists()).toBe(false);
+ expect(findCommitRowDescription().exists()).toBe(false);
+ });
+
+ describe('when the description is present', () => {
+ beforeEach(() => {
+ createComponent({ commitMock: { descriptionHtml: '&#x000A;Update ADOPTERS.md' } });
+ });
+
+ it('strips the first newline of the description', () => {
+ expect(findCommitRowDescription().html()).toBe(
+ '<pre class="commit-row-description gl-mb-3 gl-white-space-pre-line">Update ADOPTERS.md</pre>',
+ );
+ });
+
+ it('renders commit description collapsed by default', () => {
+ expect(findCommitRowDescription().classes('gl-display-block!')).toBe(false);
+ expect(findTextExpander().classes('open')).toBe(false);
+ expect(findTextExpander().props('selected')).toBe(false);
+ });
+
+ it('expands commit description when clicking expander', async () => {
+ findTextExpander().vm.$emit('click');
+ await nextTick();
+
+ expect(findCommitRowDescription().classes('gl-display-block!')).toBe(true);
+ expect(findTextExpander().classes('open')).toBe(true);
+ expect(findTextExpander().props('selected')).toBe(true);
+ });
+ });
+
+ it('sets correct CSS class if the commit message is empty', () => {
+ createComponent({ commitMock: { message: '' } });
+
+ expect(findTitleHtml().classes()).toContain('gl-font-style-italic');
+ });
+});
diff --git a/spec/frontend/repository/components/last_commit_spec.js b/spec/frontend/repository/components/last_commit_spec.js
index c207d32d61d..d5ec34b1f6d 100644
--- a/spec/frontend/repository/components/last_commit_spec.js
+++ b/spec/frontend/repository/components/last_commit_spec.js
@@ -1,29 +1,26 @@
import Vue, { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
import { GlLoadingIcon } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import LastCommit from '~/repository/components/last_commit.vue';
+import CommitInfo from '~/repository/components/commit_info.vue';
import SignatureBadge from '~/commit/components/signature_badge.vue';
-import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import eventHub from '~/repository/event_hub';
import pathLastCommitQuery from 'shared_queries/repository/path_last_commit.query.graphql';
import { FORK_UPDATED_EVENT } from '~/repository/constants';
import { refMock } from '../mock_data';
let wrapper;
+let commitData;
let mockResolver;
const findPipeline = () => wrapper.find('.js-commit-pipeline');
-const findTextExpander = () => wrapper.find('.text-expander');
-const findUserLink = () => wrapper.find('.js-user-link');
-const findUserAvatarLink = () => wrapper.findComponent(UserAvatarLink);
const findLastCommitLabel = () => wrapper.findByTestId('last-commit-id-label');
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
-const findCommitRowDescription = () => wrapper.find('.commit-row-description');
const findStatusBox = () => wrapper.findComponent(SignatureBadge);
-const findItemTitle = () => wrapper.find('.item-title');
+const findCommitInfo = () => wrapper.findComponent(CommitInfo);
const defaultPipelineEdges = [
{
@@ -44,23 +41,7 @@ const defaultPipelineEdges = [
},
];
-const defaultAuthor = {
- __typename: 'UserCore',
- id: 'gid://gitlab/User/1',
- name: 'Test',
- avatarUrl: 'https://test.com',
- webPath: '/test',
-};
-
-const defaultMessage = 'Commit title';
-
-const createCommitData = ({
- pipelineEdges = defaultPipelineEdges,
- author = defaultAuthor,
- descriptionHtml = '',
- signature = null,
- message = defaultMessage,
-}) => {
+const createCommitData = ({ pipelineEdges = defaultPipelineEdges, signature = null }) => {
return {
data: {
project: {
@@ -79,13 +60,19 @@ const createCommitData = ({
sha: '123456789',
title: 'Commit title',
titleHtml: 'Commit title',
- descriptionHtml,
- message,
+ descriptionHtml: '',
+ message: '',
webPath: '/commit/123',
authoredDate: '2019-01-01',
authorName: 'Test',
authorGravatar: 'https://test.com',
- author,
+ author: {
+ __typename: 'UserCore',
+ id: 'gid://gitlab/User/1',
+ name: 'Test',
+ avatarUrl: 'https://test.com',
+ webPath: '/test',
+ },
signature,
pipelines: {
__typename: 'PipelineConnection',
@@ -101,12 +88,13 @@ const createCommitData = ({
};
};
-const createComponent = (data = {}) => {
+const createComponent = async (data = {}) => {
Vue.use(VueApollo);
const currentPath = 'path';
- mockResolver = jest.fn().mockResolvedValue(createCommitData(data));
+ commitData = createCommitData(data);
+ mockResolver = jest.fn().mockResolvedValue(commitData);
wrapper = shallowMountExtended(LastCommit, {
apolloProvider: createMockApollo([[pathLastCommitQuery, mockResolver]]),
@@ -116,8 +104,13 @@ const createComponent = (data = {}) => {
SignatureBadge,
},
});
+
+ await waitForPromises();
+ await nextTick();
};
+beforeEach(() => createComponent());
+
afterEach(() => {
mockResolver = null;
});
@@ -137,17 +130,17 @@ describe('Repository last commit component', () => {
expect(findLoadingIcon().exists()).toBe(loading);
});
- it('renders commit widget', async () => {
- createComponent();
- await waitForPromises();
+ it('renders a CommitInfo component', () => {
+ const commit = { ...commitData.project?.repository.paginatedTree.nodes[0].lastCommit };
- expect(wrapper.element).toMatchSnapshot();
+ expect(findCommitInfo().props().commit).toMatchObject(commit);
});
- it('renders short commit ID', async () => {
- createComponent();
- await waitForPromises();
+ it('renders commit widget', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+ it('renders short commit ID', () => {
expect(findLastCommitLabel().text()).toBe('12345678');
});
@@ -158,29 +151,10 @@ describe('Repository last commit component', () => {
expect(findPipeline().exists()).toBe(false);
});
- it('renders pipeline components when pipeline exists', async () => {
- createComponent();
- await waitForPromises();
-
+ it('renders pipeline components when pipeline exists', () => {
expect(findPipeline().exists()).toBe(true);
});
- it('hides author component when author does not exist', async () => {
- createComponent({ author: null });
- await waitForPromises();
-
- expect(findUserLink().exists()).toBe(false);
- expect(findUserAvatarLink().exists()).toBe(false);
- });
-
- it('does not render description expander when description is null', async () => {
- createComponent();
- await waitForPromises();
-
- expect(findTextExpander().exists()).toBe(false);
- expect(findCommitRowDescription().exists()).toBe(false);
- });
-
describe('created', () => {
it('binds `epicsListScrolled` event listener via eventHub', () => {
jest.spyOn(eventHub, '$on').mockImplementation(() => {});
@@ -200,32 +174,6 @@ describe('Repository last commit component', () => {
});
});
- describe('when the description is present', () => {
- beforeEach(async () => {
- createComponent({ descriptionHtml: '&#x000A;Update ADOPTERS.md' });
- await waitForPromises();
- });
-
- it('strips the first newline of the description', () => {
- expect(findCommitRowDescription().html()).toBe(
- '<pre class="commit-row-description gl-mb-3 gl-white-space-pre-line">Update ADOPTERS.md</pre>',
- );
- });
-
- it('expands commit description when clicking expander', async () => {
- expect(findCommitRowDescription().classes('d-block')).toBe(false);
- expect(findTextExpander().classes('open')).toBe(false);
- expect(findTextExpander().props('selected')).toBe(false);
-
- findTextExpander().vm.$emit('click');
- await nextTick();
-
- expect(findCommitRowDescription().classes('d-block')).toBe(true);
- expect(findTextExpander().classes('open')).toBe(true);
- expect(findTextExpander().props('selected')).toBe(true);
- });
- });
-
it('renders the signature HTML as returned by the backend', async () => {
const signatureResponse = {
__typename: 'GpgSignature',
@@ -241,11 +189,4 @@ describe('Repository last commit component', () => {
expect(findStatusBox().props()).toMatchObject({ signature: signatureResponse });
});
-
- it('sets correct CSS class if the commit message is empty', async () => {
- createComponent({ message: '' });
- await waitForPromises();
-
- expect(findItemTitle().classes()).toContain('font-italic');
- });
});
diff --git a/spec/initializers/gitlab_http_spec.rb b/spec/initializers/gitlab_http_spec.rb
new file mode 100644
index 00000000000..7715112abf4
--- /dev/null
+++ b/spec/initializers/gitlab_http_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::HTTP_V2, feature_category: :shared do
+ it 'handles log_exception_proc' do
+ expect(Gitlab::HTTP_V2::Client).to receive(:httparty_perform_request)
+ .and_raise(Net::ReadTimeout)
+
+ expect(Gitlab::ErrorTracking).to receive(:log_exception)
+ .with(Net::ReadTimeout, {})
+
+ expect { described_class.get('http://example.org') }.to raise_error(Net::ReadTimeout)
+ end
+
+ context 'when silent_mode_enabled is true' do
+ before do
+ stub_application_setting(silent_mode_enabled: true)
+ end
+
+ context 'when sending a POST request' do
+ it 'handles silent_mode_log_info_proc' do
+ expect(::Gitlab::AppJsonLogger).to receive(:info).with(
+ message: "Outbound HTTP request blocked",
+ outbound_http_request_method: 'Net::HTTP::Post',
+ silent_mode_enabled: true
+ )
+
+ expect { described_class.post('http://example.org', silent_mode_enabled: true) }.to raise_error(
+ Gitlab::HTTP_V2::SilentModeBlockedError
+ )
+ end
+ end
+
+ context 'when sending a GET request' do
+ before do
+ stub_request(:get, 'http://example.org').to_return(body: 'hello')
+ end
+
+ it 'does not raise an error' do
+ expect(::Gitlab::AppJsonLogger).not_to receive(:info)
+
+ expect(described_class.get('http://example.org', silent_mode_enabled: true).body).to eq('hello')
+ end
+ end
+ end
+end
diff --git a/spec/initializers/net_http_patch_spec.rb b/spec/initializers/net_http_patch_spec.rb
index b9f5299b58c..959eae954c4 100644
--- a/spec/initializers/net_http_patch_spec.rb
+++ b/spec/initializers/net_http_patch_spec.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
-require 'net/http'
+# TODO: This spec file can be removed after fully migration to the gitlab-http gem.
+# It's already covered in gems/gitlab-http/spec/gitlab/http_v2/net_http_patch_spec.rb
-require_relative '../../config/initializers/net_http_patch'
+require 'spec_helper'
-RSpec.describe 'Net::HTTP patch proxy user and password encoding' do
+RSpec.describe 'Net::HTTP patch proxy user and password encoding', feature_category: :shared do
let(:net_http) { Net::HTTP.new('hostname.example') }
before do
diff --git a/spec/initializers/net_http_response_patch_spec.rb b/spec/initializers/net_http_response_patch_spec.rb
index cd261d7b997..8074047d6aa 100644
--- a/spec/initializers/net_http_response_patch_spec.rb
+++ b/spec/initializers/net_http_response_patch_spec.rb
@@ -1,5 +1,8 @@
# frozen_string_literal: true
+# TODO: This spec file can be removed after fully migration to the gitlab-http gem.
+# It's already covered in gems/gitlab-http/spec/gitlab/http_v2/net_http_response_patch_spec.rb
+
require 'spec_helper'
RSpec.describe 'Net::HTTPResponse patch header read timeout', feature_category: :shared do
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index a1425169dee..39409cf8d3a 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -89,13 +89,14 @@ RSpec.describe ContainerRegistry::Client do
it_behaves_like 'handling timeouts'
end
- shared_examples 'handling repository info' do
+ shared_examples 'handling registry info' do
context 'when the check is successful' do
context 'when using the GitLab container registry' do
before do
stub_registry_info(headers: {
'GitLab-Container-Registry-Version' => '2.9.1-gitlab',
- 'GitLab-Container-Registry-Features' => 'a,b,c'
+ 'GitLab-Container-Registry-Features' => 'a,b,c',
+ 'GitLab-Container-Registry-Database-Enabled' => 'true'
})
end
@@ -106,6 +107,10 @@ RSpec.describe ContainerRegistry::Client do
it 'identifies version and features' do
expect(subject).to include(version: '2.9.1-gitlab', features: %w[a b c])
end
+
+ it 'identifies the registry DB as enabled' do
+ expect(subject).to include(db_enabled: true)
+ end
end
context 'when using a third-party container registry' do
@@ -120,6 +125,10 @@ RSpec.describe ContainerRegistry::Client do
it 'does not identify version or features' do
expect(subject).to include(version: nil, features: [])
end
+
+ it 'does not identify the registry DB as enabled' do
+ expect(subject).to include(db_enabled: false)
+ end
end
end
@@ -130,6 +139,16 @@ RSpec.describe ContainerRegistry::Client do
expect(subject).to eq({})
end
end
+
+ context 'when the check returns an unexpected value in the database enabled header' do
+ it 'does not identify the registry DB as enabled' do
+ stub_registry_info(headers: {
+ 'GitLab-Container-Registry-Database-Enabled' => '123'
+ })
+
+ expect(subject).to include(db_enabled: false)
+ end
+ end
end
describe '#repository_manifest' do
@@ -360,7 +379,7 @@ RSpec.describe ContainerRegistry::Client do
describe '#registry_info' do
subject { client.registry_info }
- it_behaves_like 'handling repository info'
+ it_behaves_like 'handling registry info'
end
describe '.supports_tag_delete?' do
@@ -446,7 +465,7 @@ RSpec.describe ContainerRegistry::Client do
stub_container_registry_config(enabled: true, api_url: registry_api_url, key: 'spec/fixtures/x509_certificate_pk.key')
end
- it_behaves_like 'handling repository info'
+ it_behaves_like 'handling registry info'
end
def stub_upload(path, content, digest, status = 200)
diff --git a/spec/models/clusters/agent_token_spec.rb b/spec/models/clusters/agent_token_spec.rb
index bc158fc9117..5f731336b4b 100644
--- a/spec/models/clusters/agent_token_spec.rb
+++ b/spec/models/clusters/agent_token_spec.rb
@@ -95,6 +95,15 @@ RSpec.describe Clusters::AgentToken, feature_category: :deployment_management do
expect(agent_token.token).to start_with described_class::TOKEN_PREFIX
end
+
+ it 'is revoked on revoke!' do
+ agent_token = build(:cluster_agent_token, token_encrypted: nil)
+ agent_token.save!
+
+ agent_token.revoke!
+
+ expect(agent_token.active?).to be_falsey
+ end
end
describe '#to_ability_name' do
diff --git a/spec/requests/api/group_export_spec.rb b/spec/requests/api/group_export_spec.rb
index b4add2494b0..ddee2081bcf 100644
--- a/spec/requests/api/group_export_spec.rb
+++ b/spec/requests/api/group_export_spec.rb
@@ -325,8 +325,13 @@ RSpec.describe API::GroupExport, feature_category: :importers do
end
context 'when bulk import is disabled' do
+ before do
+ stub_application_setting(bulk_import_enabled: false)
+ end
+
it_behaves_like '404 response' do
- let(:request) { get api(path, user) }
+ let(:message) { '404 Not Found' }
+ let(:request) { post api(path, user) }
end
end
end
diff --git a/spec/requests/api/npm_group_packages_spec.rb b/spec/requests/api/npm_group_packages_spec.rb
index 7fba75b0630..12b2ccd1bf7 100644
--- a/spec/requests/api/npm_group_packages_spec.rb
+++ b/spec/requests/api/npm_group_packages_spec.rb
@@ -22,11 +22,11 @@ RSpec.describe API::NpmGroupPackages, feature_category: :package_registry do
where(:auth, :group_visibility, :project_visibility, :user_role, :expected_status) do
nil | :public | :public | nil | :ok
- nil | :public | :internal | nil | :not_found
- nil | :public | :private | nil | :not_found
- nil | :internal | :internal | nil | :not_found
- nil | :internal | :private | nil | :not_found
- nil | :private | :private | nil | :not_found
+ nil | :public | :internal | nil | :unauthorized
+ nil | :public | :private | nil | :unauthorized
+ nil | :internal | :internal | nil | :unauthorized
+ nil | :internal | :private | nil | :unauthorized
+ nil | :private | :private | nil | :unauthorized
:oauth | :public | :public | :guest | :ok
:oauth | :public | :internal | :guest | :ok
diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb
index 3603a71151e..8a47eb2dae1 100644
--- a/spec/requests/api/project_export_spec.rb
+++ b/spec/requests/api/project_export_spec.rb
@@ -708,6 +708,8 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
describe 'POST /projects/:id/export_relations' do
it_behaves_like '404 response' do
+ let(:message) { '404 Not Found' }
+
subject(:request) { post api(path, user) }
end
end
@@ -721,12 +723,16 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
end
it_behaves_like '404 response' do
- subject(:request) { post api(path, user) }
+ let(:message) { '404 Not Found' }
+
+ subject(:request) { get api(download_path, user) }
end
end
describe 'GET /projects/:id/export_relations/status' do
it_behaves_like '404 response' do
+ let(:message) { '404 Not Found' }
+
subject(:request) { get api(status_path, user) }
end
end
@@ -758,11 +764,5 @@ RSpec.describe API::ProjectExport, :aggregate_failures, :clean_gitlab_redis_cach
end
end
end
-
- context 'when bulk import is disabled' do
- it_behaves_like '404 response' do
- subject(:request) { get api(path, user) }
- end
- end
end
end
diff --git a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
index 5f043cdd996..a4091d6bceb 100644
--- a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
@@ -68,22 +68,22 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
nil | :unscoped | false | :public | nil | :accept | :ok
nil | :non_existing | true | :public | nil | :redirect | :redirected
nil | :non_existing | false | :public | nil | :reject | :not_found
- nil | :scoped_naming_convention | true | :private | nil | :reject | :not_found
- nil | :scoped_naming_convention | false | :private | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | true | :private | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | false | :private | nil | :reject | :not_found
- nil | :unscoped | true | :private | nil | :reject | :not_found
- nil | :unscoped | false | :private | nil | :reject | :not_found
+ nil | :scoped_naming_convention | true | :private | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | false | :private | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | true | :private | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | false | :private | nil | :reject | :unauthorized
+ nil | :unscoped | true | :private | nil | :reject | :unauthorized
+ nil | :unscoped | false | :private | nil | :reject | :unauthorized
nil | :non_existing | true | :private | nil | :redirect | :redirected
- nil | :non_existing | false | :private | nil | :reject | :not_found
- nil | :scoped_naming_convention | true | :internal | nil | :reject | :not_found
- nil | :scoped_naming_convention | false | :internal | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | true | :internal | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | false | :internal | nil | :reject | :not_found
- nil | :unscoped | true | :internal | nil | :reject | :not_found
- nil | :unscoped | false | :internal | nil | :reject | :not_found
+ nil | :non_existing | false | :private | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | true | :internal | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | false | :internal | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | true | :internal | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | false | :internal | nil | :reject | :unauthorized
+ nil | :unscoped | true | :internal | nil | :reject | :unauthorized
+ nil | :unscoped | false | :internal | nil | :reject | :unauthorized
nil | :non_existing | true | :internal | nil | :redirect | :redirected
- nil | :non_existing | false | :internal | nil | :reject | :not_found
+ nil | :non_existing | false | :internal | nil | :reject | :unauthorized
:oauth | :scoped_naming_convention | true | :public | :guest | :accept | :ok
:oauth | :scoped_naming_convention | true | :public | :reporter | :accept | :ok
@@ -280,11 +280,15 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
end
end
- if (scope == :group && params[:package_name_type] == :non_existing) &&
- (!params[:request_forward] || (!params[:auth] && params[:request_forward] && params[:visibility] != :public))
+ if scope == :group && params[:package_name_type] == :non_existing && !params[:request_forward] && params[:auth]
status = :not_found
end
+ if scope == :group && params[:package_name_type] == :non_existing && params[:request_forward] && !params[:auth] && params[:visibility] != :public
+ example_name = 'reject metadata request'
+ status = :unauthorized
+ end
+
# Check the error message for :not_found
example_name = 'returning response status with error' if status == :not_found
@@ -522,14 +526,14 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
nil | :scoped_no_naming_convention | :public | nil | :accept | :ok
nil | :unscoped | :public | nil | :accept | :ok
nil | :non_existing | :public | nil | :reject | :not_found
- nil | :scoped_naming_convention | :private | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | :private | nil | :reject | :not_found
- nil | :unscoped | :private | nil | :reject | :not_found
- nil | :non_existing | :private | nil | :reject | :not_found
- nil | :scoped_naming_convention | :internal | nil | :reject | :not_found
- nil | :scoped_no_naming_convention | :internal | nil | :reject | :not_found
- nil | :unscoped | :internal | nil | :reject | :not_found
- nil | :non_existing | :internal | nil | :reject | :not_found
+ nil | :scoped_naming_convention | :private | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | :private | nil | :reject | :unauthorized
+ nil | :unscoped | :private | nil | :reject | :unauthorized
+ nil | :non_existing | :private | nil | :reject | :unauthorized
+ nil | :scoped_naming_convention | :internal | nil | :reject | :unauthorized
+ nil | :scoped_no_naming_convention | :internal | nil | :reject | :unauthorized
+ nil | :unscoped | :internal | nil | :reject | :unauthorized
+ nil | :non_existing | :internal | nil | :reject | :unauthorized
:oauth | :scoped_naming_convention | :public | :guest | :accept | :ok
:oauth | :scoped_naming_convention | :public | :reporter | :accept | :ok
diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb
index 9c6a6564df6..48d8ea3ab16 100644
--- a/spec/workers/merge_worker_spec.rb
+++ b/spec/workers/merge_worker_spec.rb
@@ -48,4 +48,61 @@ RSpec.describe MergeWorker, feature_category: :source_code_management do
end
end
end
+
+ describe 'delegation to MergeRequests::MergeService' do
+ # Some ids that should be nonexistentn
+ let(:user_id) { -1 }
+ let(:merge_request_id) { -1 }
+ let(:params) { {} }
+
+ subject { described_class.new.perform(merge_request_id, user_id, params) }
+
+ context 'when user exists' do
+ let!(:user) { create(:user) }
+ let(:user_id) { user.id }
+
+ context 'and merge request exists' do
+ let!(:merge_request) { create(:merge_request, source_project: create(:project, :empty_repo)) }
+ let(:merge_request_id) { merge_request.id }
+ let(:user) { merge_request.author }
+ let(:merge_service_double) { instance_double(MergeRequests::MergeService) }
+
+ it 'delegates to MergeRequests::MergeService' do
+ expect(MergeRequests::MergeService).to receive(:new).with(
+ project: merge_request.target_project,
+ current_user: user,
+ params: { check_mergeability_retry_lease: true }
+ ).and_return(merge_service_double)
+
+ expect(merge_service_double).to receive(:execute)
+ subject
+ end
+
+ context 'and check_mergeability_retry_lease is specified' do
+ let(:params) { { check_mergeability_retry_lease: false } }
+
+ it 'does not change the check_mergeability_retry_lease parameter' do
+ expect(MergeRequests::MergeService).to receive(:new).with(
+ project: merge_request.target_project,
+ current_user: user,
+ params: params
+ ).and_return(merge_service_double)
+
+ expect(merge_service_double).to receive(:execute)
+ subject
+ end
+ end
+ end
+
+ it 'does not call MergeRequests::MergeService' do
+ expect(MergeRequests::MergeService).not_to receive(:new)
+ subject
+ end
+ end
+
+ it 'does not call MergeRequests::MergeService' do
+ expect(MergeRequests::MergeService).not_to receive(:new)
+ subject
+ end
+ end
end