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>2020-11-12 18:09:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-12 18:09:09 +0300
commit6cf30e964d54d536b0ff861916745f0a4bb31ebb (patch)
treec29ef6911c9c8347cbcd5195583462e91121506a /spec
parent4a31b8786892820e8029844c34fd5296c52c37c0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/ci/lints_controller_spec.rb14
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb97
-rw-r--r--spec/factories/bulk_import/trackers.rb10
-rw-r--r--spec/features/groups/container_registry_spec.rb14
-rw-r--r--spec/features/groups/show_spec.rb10
-rw-r--r--spec/features/groups_spec.rb48
-rw-r--r--spec/features/projects/container_registry_spec.rb18
-rw-r--r--spec/features/projects/releases/user_views_releases_spec.rb2
-rw-r--r--spec/frontend/alerts_settings/alerts_integrations_list_spec.js11
-rw-r--r--spec/frontend/alerts_settings/alerts_settings_form_new_spec.js6
-rw-r--r--spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js2
-rw-r--r--spec/frontend/registry/explorer/stores/actions_spec.js11
-rw-r--r--spec/frontend/registry/explorer/utils_spec.js14
-rw-r--r--spec/frontend/releases/__snapshots__/util_spec.js.snap16
-rw-r--r--spec/graphql/mutations/commits/create_spec.rb29
-rw-r--r--spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb53
-rw-r--r--spec/migrations/schedule_merge_request_cleanup_schedules_backfill_spec.rb41
-rw-r--r--spec/models/bulk_imports/tracker_spec.rb27
-rw-r--r--spec/models/design_management/design_spec.rb8
-rw-r--r--spec/requests/api/graphql/mutations/commits/create_spec.rb38
-rw-r--r--spec/requests/api/graphql/mutations/releases/create_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/release_spec.rb2
-rw-r--r--spec/requests/api/release/links_spec.rb2
-rw-r--r--spec/requests/projects/releases_controller_spec.rb60
-rw-r--r--spec/services/notification_service_spec.rb17
25 files changed, 357 insertions, 195 deletions
diff --git a/spec/controllers/projects/ci/lints_controller_spec.rb b/spec/controllers/projects/ci/lints_controller_spec.rb
index 24048aea838..c4e040b0287 100644
--- a/spec/controllers/projects/ci/lints_controller_spec.rb
+++ b/spec/controllers/projects/ci/lints_controller_spec.rb
@@ -123,20 +123,6 @@ RSpec.describe Projects::Ci::LintsController do
subject
end
-
- context 'when dry_run feature flag is disabled' do
- before do
- stub_feature_flags(ci_lint_creates_pipeline_with_dry_run: false)
- end
-
- it_behaves_like 'returns a successful validation'
-
- it 'runs validations through YamlProcessor' do
- expect(Gitlab::Ci::YamlProcessor).to receive(:new).and_call_original
-
- subject
- end
- end
end
end
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 420d818daeb..07fb03b39c6 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -201,102 +201,7 @@ RSpec.describe Projects::ReleasesController do
end
end
- context 'GET #downloads' do
- subject do
- get :downloads, params: { namespace_id: project.namespace, project_id: project, tag: tag, filepath: filepath }
- end
-
- before do
- sign_in(user)
- end
-
- let(:release) { create(:release, project: project, tag: tag ) }
- let!(:link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: '/binaries/linux-amd64', url: 'https://downloads.example.com/bin/gitlab-linux-amd64') }
- let(:tag) { 'v11.9.0-rc2' }
-
- context 'valid filepath' do
- let(:filepath) { CGI.escape('/binaries/linux-amd64') }
-
- it 'redirects to the asset direct link' do
- subject
-
- expect(response).to redirect_to('https://downloads.example.com/bin/gitlab-linux-amd64')
- end
-
- it 'redirects with a status of 302' do
- subject
-
- expect(response).to have_gitlab_http_status(:redirect)
- end
- end
-
- context 'invalid filepath' do
- let(:filepath) { CGI.escape('/binaries/win32') }
-
- it 'is not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- context 'GET #downloads' do
- subject do
- get :downloads, params: {
- namespace_id: project.namespace,
- project_id: project,
- tag: tag,
- filepath: filepath
- }
- end
-
- before do
- sign_in(user)
- end
-
- let(:release) { create(:release, project: project, tag: tag ) }
- let(:tag) { 'v11.9.0-rc2' }
- let(:db_filepath) { '/binaries/linux-amd64' }
- let!(:link) do
- create :release_link,
- release: release,
- name: 'linux-amd64 binaries',
- filepath: db_filepath,
- url: 'https://downloads.example.com/bin/gitlab-linux-amd64'
- end
-
- context 'valid filepath' do
- let(:filepath) { CGI.escape('/binaries/linux-amd64') }
-
- it 'redirects to the asset direct link' do
- subject
-
- expect(response).to redirect_to(link.url)
- end
- end
-
- context 'invalid filepath' do
- let(:filepath) { CGI.escape('/binaries/win32') }
-
- it 'is not found' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'ignores filepath extension' do
- let(:db_filepath) { '/binaries/linux-amd64.json' }
- let(:filepath) { CGI.escape(db_filepath) }
-
- it 'redirects to the asset direct link' do
- subject
-
- expect(response).to redirect_to(link.url)
- end
- end
- end
+ # `GET #downloads` is addressed in spec/requests/projects/releases_controller_spec.rb
private
diff --git a/spec/factories/bulk_import/trackers.rb b/spec/factories/bulk_import/trackers.rb
new file mode 100644
index 00000000000..7a1fa0849fc
--- /dev/null
+++ b/spec/factories/bulk_import/trackers.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :bulk_import_tracker, class: 'BulkImports::Tracker' do
+ association :entity, factory: :bulk_import_entity
+
+ relation { :relation }
+ has_next_page { false }
+ end
+end
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index acac8724edf..1b23b8b4bf9 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -89,6 +89,20 @@ RSpec.describe 'Container Registry', :js do
end
end
+ context 'when an image has the same name as the subgroup' do
+ before do
+ stub_container_registry_tags(tags: %w[latest], with_manifest: true)
+ project.container_repositories << create(:container_repository, name: group.name)
+ visit_container_registry
+ end
+
+ it 'details page loads properly' do
+ find('a[data-testid="details-link"]').click
+
+ expect(page).to have_content 'latest'
+ end
+ end
+
def visit_container_registry
visit group_container_registries_path(group)
end
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index 304573ecd6e..97732374eb9 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -81,8 +81,7 @@ RSpec.describe 'Group show page' do
it 'allows creating subgroups' do
visit path
- expect(page)
- .to have_css("li[data-text='New subgroup']", visible: false)
+ expect(page).to have_link('New subgroup')
end
end
end
@@ -102,8 +101,7 @@ RSpec.describe 'Group show page' do
path = group_path(relaxed_group)
visit path
- expect(page)
- .to have_css("li[data-text='New subgroup']", visible: false)
+ expect(page).to have_link('New subgroup')
end
end
@@ -116,9 +114,7 @@ RSpec.describe 'Group show page' do
path = group_path(restricted_group)
visit path
- expect(page)
- .not_to have_selector("li[data-text='New subgroup']",
- visible: false)
+ expect(page).not_to have_link('New subgroup')
end
end
end
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 8264ec2eddd..b9fd3a1a5cc 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -294,35 +294,43 @@ RSpec.describe 'Group' do
describe 'new subgroup / project button' do
let(:group) { create(:group, project_creation_level: Gitlab::Access::NO_ONE_PROJECT_ACCESS, subgroup_creation_level: Gitlab::Access::OWNER_SUBGROUP_ACCESS) }
- it 'new subgroup button is displayed without project creation permission' do
- visit group_path(group)
+ context 'when user has subgroup creation permissions but not project creation permissions' do
+ it 'only displays "New subgroup" button' do
+ visit group_path(group)
- page.within '.group-buttons' do
- expect(page).to have_link('New subgroup')
+ page.within '[data-testid="group-buttons"]' do
+ expect(page).to have_link('New subgroup')
+ expect(page).not_to have_link('New project')
+ end
end
end
- it 'new subgroup button is displayed together with new project button when having project creation permission' do
- group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
- visit group_path(group)
+ context 'when user has project creation permissions but not subgroup creation permissions' do
+ it 'only displays "New project" button' do
+ group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
+ user = create(:user)
- page.within '.group-buttons' do
- expect(page).to have_css("li[data-text='New subgroup']", visible: false)
- expect(page).to have_css("li[data-text='New project']", visible: false)
+ group.add_maintainer(user)
+ sign_out(:user)
+ sign_in(user)
+
+ visit group_path(group)
+ page.within '[data-testid="group-buttons"]' do
+ expect(page).to have_link('New project')
+ expect(page).not_to have_link('New subgroup')
+ end
end
end
- it 'new project button is displayed without subgroup creation permission' do
- group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
- user = create(:user)
-
- group.add_maintainer(user)
- sign_out(:user)
- sign_in(user)
+ context 'when user has project and subgroup creation permissions' do
+ it 'displays "New subgroup" and "New project" buttons' do
+ group.update!(project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
+ visit group_path(group)
- visit group_path(group)
- page.within '.group-buttons' do
- expect(page).to have_link('New project')
+ page.within '[data-testid="group-buttons"]' do
+ expect(page).to have_link('New subgroup')
+ expect(page).to have_link('New project')
+ end
end
end
end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 7514a26f020..45bf35a6aab 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -10,6 +10,10 @@ RSpec.describe 'Container Registry', :js do
create(:container_repository, name: 'my/image')
end
+ let(:nameless_container_repository) do
+ create(:container_repository, name: '')
+ end
+
before do
sign_in(user)
project.add_developer(user)
@@ -96,6 +100,20 @@ RSpec.describe 'Container Registry', :js do
end
end
+ describe 'image repo details when image has no name' do
+ before do
+ stub_container_registry_tags(tags: %w[latest], with_manifest: true)
+ project.container_repositories << nameless_container_repository
+ visit_container_registry
+ end
+
+ it 'renders correctly' do
+ find('a[data-testid="details-link"]').click
+
+ expect(page).to have_content 'latest'
+ end
+ end
+
context 'when there are more than 10 images' do
before do
create_list(:container_repository, 12, project: project)
diff --git a/spec/features/projects/releases/user_views_releases_spec.rb b/spec/features/projects/releases/user_views_releases_spec.rb
index 6ca5073c5a4..aabbc8cea7b 100644
--- a/spec/features/projects/releases/user_views_releases_spec.rb
+++ b/spec/features/projects/releases/user_views_releases_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'User views releases', :js do
context 'when there is a link as an asset' do
let!(:release_link) { create(:release_link, release: release_v1, url: url ) }
let(:url) { "#{project.web_url}/-/jobs/1/artifacts/download" }
- let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << release_link.filepath }
+ let(:direct_asset_link) { Gitlab::Routing.url_helpers.project_release_url(project, release_v1) << "/downloads#{release_link.filepath}" }
it 'sees the link' do
page.within("##{release_v1.tag} .js-assets-list") do
diff --git a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
index c7a9db82bea..04ecefa7140 100644
--- a/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
+++ b/spec/frontend/alerts_settings/alerts_integrations_list_spec.js
@@ -24,11 +24,14 @@ const mockIntegrations = [
describe('AlertIntegrationsList', () => {
let wrapper;
- function mountComponent(propsData = {}) {
+ function mountComponent({ data = {}, props = {} } = {}) {
wrapper = mount(AlertIntegrationsList, {
+ data() {
+ return { ...data };
+ },
propsData: {
integrations: mockIntegrations,
- ...propsData,
+ ...props,
},
stubs: {
GlIcon: true,
@@ -57,7 +60,7 @@ describe('AlertIntegrationsList', () => {
});
it('renders an empty state when no integrations provided', () => {
- mountComponent({ integrations: [] });
+ mountComponent({ props: { integrations: [] } });
expect(findTableComponent().text()).toContain(i18n.emptyState);
});
@@ -66,7 +69,7 @@ describe('AlertIntegrationsList', () => {
});
it('renders an highlighted row when a current integration is selected to edit', () => {
- mountComponent({ currentIntegration: { id: '1' } });
+ mountComponent({ data: { currentIntegration: { id: '1' } } });
expect(
findTableComponentRows()
.at(0)
diff --git a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js
index d5a1239f701..97a53c20b6b 100644
--- a/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js
+++ b/spec/frontend/alerts_settings/alerts_settings_form_new_spec.js
@@ -152,9 +152,9 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.http,
+ currentIntegration: { id: '1', name: 'Test integration pre' },
},
props: {
- currentIntegration: { id: '1', name: 'Test integration pre' },
loading: false,
},
});
@@ -183,9 +183,9 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.prometheus,
+ currentIntegration: { id: '1', apiUrl: 'https://test-pre.com' },
},
props: {
- currentIntegration: { id: '1', apiUrl: 'https://test-pre.com' },
loading: false,
},
});
@@ -219,10 +219,10 @@ describe('AlertsSettingsFormNew', () => {
createComponent({
data: {
selectedIntegration: typeSet.http,
+ currentIntegration: { id: '1', name: 'Test' },
active: true,
},
props: {
- currentIntegration: { id: '1', name: 'Test' },
loading: false,
},
});
diff --git a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
index e85ee39f165..9f7a2758ae1 100644
--- a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
+++ b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
@@ -19,7 +19,7 @@ describe('Image List Row', () => {
let wrapper;
const item = imagesListResponse.data[0];
- const findDetailsLink = () => wrapper.find('[data-testid="detailsLink"]');
+ const findDetailsLink = () => wrapper.find('[data-testid="details-link"]');
const findTagsCount = () => wrapper.find('[data-testid="tagsCount"]');
const findDeleteBtn = () => wrapper.find(DeleteButton);
const findClipboardButton = () => wrapper.find(ClipboardButton);
diff --git a/spec/frontend/registry/explorer/stores/actions_spec.js b/spec/frontend/registry/explorer/stores/actions_spec.js
index 17ce6a7054d..dcd4d8015a4 100644
--- a/spec/frontend/registry/explorer/stores/actions_spec.js
+++ b/spec/frontend/registry/explorer/stores/actions_spec.js
@@ -8,6 +8,11 @@ import * as actions from '~/registry/explorer/stores/actions';
import * as types from '~/registry/explorer/stores/mutation_types';
import { reposServerResponse, registryServerResponse } from '../mock_data';
import * as utils from '~/registry/explorer/utils';
+import {
+ FETCH_IMAGES_LIST_ERROR_MESSAGE,
+ FETCH_TAGS_LIST_ERROR_MESSAGE,
+ FETCH_IMAGE_DETAILS_ERROR_MESSAGE,
+} from '~/registry/explorer/constants/index';
jest.mock('~/flash.js');
jest.mock('~/registry/explorer/utils');
@@ -129,7 +134,7 @@ describe('Actions RegistryExplorer Store', () => {
],
[],
() => {
- expect(createFlash).toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({ message: FETCH_IMAGES_LIST_ERROR_MESSAGE });
done();
},
);
@@ -169,7 +174,7 @@ describe('Actions RegistryExplorer Store', () => {
],
[],
() => {
- expect(createFlash).toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({ message: FETCH_TAGS_LIST_ERROR_MESSAGE });
done();
},
);
@@ -261,7 +266,7 @@ describe('Actions RegistryExplorer Store', () => {
],
[],
() => {
- expect(createFlash).toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({ message: FETCH_IMAGE_DETAILS_ERROR_MESSAGE });
done();
},
);
diff --git a/spec/frontend/registry/explorer/utils_spec.js b/spec/frontend/registry/explorer/utils_spec.js
index 365bfc9ea19..0cd4a1cec29 100644
--- a/spec/frontend/registry/explorer/utils_spec.js
+++ b/spec/frontend/registry/explorer/utils_spec.js
@@ -16,6 +16,20 @@ describe('Utils', () => {
expect(pathGenerator(imageDetails, '/foo')).toBe('/foo/bar/registry/repository/1/tags/foo');
});
+ it.each`
+ path | name | result
+ ${'foo/foo'} | ${''} | ${'/foo/foo/registry/repository/1/tags?format=json'}
+ ${'foo/foo/foo'} | ${'foo'} | ${'/foo/foo/registry/repository/1/tags?format=json'}
+ ${'baz/foo/foo/foo'} | ${'foo'} | ${'/baz/foo/foo/registry/repository/1/tags?format=json'}
+ ${'baz/foo/foo/foo'} | ${'foo'} | ${'/baz/foo/foo/registry/repository/1/tags?format=json'}
+ ${'foo/foo/baz/foo/foo'} | ${'foo/foo'} | ${'/foo/foo/baz/registry/repository/1/tags?format=json'}
+ ${'foo/foo/baz/foo/bar'} | ${'foo/bar'} | ${'/foo/foo/baz/registry/repository/1/tags?format=json'}
+ ${'baz/foo/foo'} | ${'foo'} | ${'/baz/foo/registry/repository/1/tags?format=json'}
+ ${'baz/foo/bar'} | ${'foo'} | ${'/baz/foo/bar/registry/repository/1/tags?format=json'}
+ `('returns the correct path when path is $path and name is $name', ({ name, path, result }) => {
+ expect(pathGenerator({ id: 1, name, path })).toBe(result);
+ });
+
it('returns the url unchanged when imageDetails have no name', () => {
const imageDetailsWithoutName = {
path: 'foo/bar/baz',
diff --git a/spec/frontend/releases/__snapshots__/util_spec.js.snap b/spec/frontend/releases/__snapshots__/util_spec.js.snap
index aefd1edb87e..f49d3d7b716 100644
--- a/spec/frontend/releases/__snapshots__/util_spec.js.snap
+++ b/spec/frontend/releases/__snapshots__/util_spec.js.snap
@@ -18,7 +18,7 @@ Object {
"count": 8,
"links": Array [
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-3",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-3",
"external": true,
"id": "gid://gitlab/Releases::Link/13",
"linkType": "image",
@@ -26,7 +26,7 @@ Object {
"url": "https://example.com/image",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-2",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-2",
"external": true,
"id": "gid://gitlab/Releases::Link/12",
"linkType": "package",
@@ -34,7 +34,7 @@ Object {
"url": "https://example.com/package",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-1",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-1",
"external": false,
"id": "gid://gitlab/Releases::Link/11",
"linkType": "runbook",
@@ -42,7 +42,7 @@ Object {
"url": "http://localhost/releases-namespace/releases-project/runbook",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/linux-amd64",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/linux-amd64",
"external": true,
"id": "gid://gitlab/Releases::Link/10",
"linkType": "other",
@@ -146,7 +146,7 @@ Object {
"count": 8,
"links": Array [
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-3",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-3",
"external": true,
"id": "gid://gitlab/Releases::Link/13",
"linkType": "image",
@@ -154,7 +154,7 @@ Object {
"url": "https://example.com/image",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-2",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-2",
"external": true,
"id": "gid://gitlab/Releases::Link/12",
"linkType": "package",
@@ -162,7 +162,7 @@ Object {
"url": "https://example.com/package",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/awesome-app-1",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/awesome-app-1",
"external": false,
"id": "gid://gitlab/Releases::Link/11",
"linkType": "runbook",
@@ -170,7 +170,7 @@ Object {
"url": "http://localhost/releases-namespace/releases-project/runbook",
},
Object {
- "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/binaries/linux-amd64",
+ "directAssetUrl": "http://localhost/releases-namespace/releases-project/-/releases/v1.1/downloads/binaries/linux-amd64",
"external": true,
"id": "gid://gitlab/Releases::Link/10",
"linkType": "other",
diff --git a/spec/graphql/mutations/commits/create_spec.rb b/spec/graphql/mutations/commits/create_spec.rb
index fb1baafe7bd..82a5e3a62f5 100644
--- a/spec/graphql/mutations/commits/create_spec.rb
+++ b/spec/graphql/mutations/commits/create_spec.rb
@@ -5,8 +5,9 @@ require 'spec_helper'
RSpec.describe Mutations::Commits::Create do
subject(:mutation) { described_class.new(object: nil, context: context, field: nil) }
- let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+
let(:context) do
GraphQL::Query::Context.new(
query: OpenStruct.new(schema: nil),
@@ -18,9 +19,10 @@ RSpec.describe Mutations::Commits::Create do
specify { expect(described_class).to require_graphql_authorizations(:push_code) }
describe '#resolve' do
- subject { mutation.resolve(project_path: project.full_path, branch: branch, message: message, actions: actions) }
+ subject { mutation.resolve(project_path: project.full_path, branch: branch, start_branch: start_branch, message: message, actions: actions) }
let(:branch) { 'master' }
+ let(:start_branch) { nil }
let(:message) { 'Commit message' }
let(:actions) do
[
@@ -142,6 +144,29 @@ RSpec.describe Mutations::Commits::Create do
end
end
+ context 'when branch does not exist and a start branch is provided' do
+ let(:branch) { 'my-branch' }
+ let(:start_branch) { 'master' }
+ let(:actions) do
+ [
+ {
+ action: 'create',
+ file_path: 'ANOTHER_FILE.md',
+ content: 'Bye'
+ }
+ ]
+ end
+
+ it 'returns a new commit' do
+ expect(mutated_commit).to have_attributes(message: message, project: project)
+ expect(subject[:errors]).to be_empty
+
+ expect_to_contain_deltas([
+ a_hash_including(a_mode: '0', b_mode: '100644', new_file: true, new_path: 'ANOTHER_FILE.md')
+ ])
+ end
+ end
+
context 'when message is not set' do
let(:message) { nil }
diff --git a/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb b/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb
new file mode 100644
index 00000000000..c2daa35703d
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_merge_request_cleanup_schedules_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillMergeRequestCleanupSchedules, schema: 20201103110018 do
+ let(:merge_requests) { table(:merge_requests) }
+ let(:cleanup_schedules) { table(:merge_request_cleanup_schedules) }
+ let(:metrics) { table(:merge_request_metrics) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'name', path: 'path') }
+ let(:project) { table(:projects).create!(namespace_id: namespace.id) }
+
+ subject { described_class.new }
+
+ describe '#perform' do
+ let!(:open_mr) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master') }
+
+ let!(:closed_mr_1) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 2) }
+ let!(:closed_mr_2) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 2) }
+ let!(:closed_mr_1_metrics) { metrics.create!(merge_request_id: closed_mr_1.id, target_project_id: project.id, latest_closed_at: Time.current, created_at: Time.current, updated_at: Time.current) }
+ let!(:closed_mr_2_metrics) { metrics.create!(merge_request_id: closed_mr_2.id, target_project_id: project.id, latest_closed_at: Time.current, created_at: Time.current, updated_at: Time.current) }
+ let!(:closed_mr_2_cleanup_schedule) { cleanup_schedules.create!(merge_request_id: closed_mr_2.id, scheduled_at: Time.current) }
+
+ let!(:merged_mr_1) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 3) }
+ let!(:merged_mr_2) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 3, updated_at: Time.current) }
+ let!(:merged_mr_1_metrics) { metrics.create!(merge_request_id: merged_mr_1.id, target_project_id: project.id, merged_at: Time.current, created_at: Time.current, updated_at: Time.current) }
+
+ let!(:closed_mr_3) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 2) }
+ let!(:closed_mr_3_metrics) { metrics.create!(merge_request_id: closed_mr_3.id, target_project_id: project.id, latest_closed_at: Time.current, created_at: Time.current, updated_at: Time.current) }
+
+ it 'creates records for all closed and merged merge requests in range' do
+ expect(Gitlab::BackgroundMigration::Logger).to receive(:info).with(
+ message: 'Backfilled merge_request_cleanup_schedules records',
+ count: 3
+ )
+
+ subject.perform(open_mr.id, merged_mr_2.id)
+
+ aggregate_failures do
+ expect(cleanup_schedules.all.pluck(:merge_request_id))
+ .to contain_exactly(closed_mr_1.id, closed_mr_2.id, merged_mr_1.id, merged_mr_2.id)
+ expect(cleanup_schedules.find_by(merge_request_id: closed_mr_1.id).scheduled_at.to_s)
+ .to eq((closed_mr_1_metrics.latest_closed_at + 14.days).to_s)
+ expect(cleanup_schedules.find_by(merge_request_id: closed_mr_2.id).scheduled_at.to_s)
+ .to eq(closed_mr_2_cleanup_schedule.scheduled_at.to_s)
+ expect(cleanup_schedules.find_by(merge_request_id: merged_mr_1.id).scheduled_at.to_s)
+ .to eq((merged_mr_1_metrics.merged_at + 14.days).to_s)
+ expect(cleanup_schedules.find_by(merge_request_id: merged_mr_2.id).scheduled_at.to_s)
+ .to eq((merged_mr_2.updated_at + 14.days).to_s)
+ end
+ end
+ end
+end
diff --git a/spec/migrations/schedule_merge_request_cleanup_schedules_backfill_spec.rb b/spec/migrations/schedule_merge_request_cleanup_schedules_backfill_spec.rb
new file mode 100644
index 00000000000..fa8dd38619a
--- /dev/null
+++ b/spec/migrations/schedule_merge_request_cleanup_schedules_backfill_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe ScheduleMergeRequestCleanupSchedulesBackfill, :sidekiq, schema: 20201023114628 do
+ let(:merge_requests) { table(:merge_requests) }
+ let(:cleanup_schedules) { table(:merge_request_cleanup_schedules) }
+
+ let(:namespace) { table(:namespaces).create!(name: 'name', path: 'path') }
+ let(:project) { table(:projects).create!(namespace_id: namespace.id) }
+
+ describe '#up' do
+ let!(:open_mr) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master') }
+
+ let!(:closed_mr_1) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 2) }
+ let!(:closed_mr_2) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 2) }
+
+ let!(:merged_mr_1) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 3) }
+ let!(:merged_mr_2) { merge_requests.create!(target_project_id: project.id, source_branch: 'master', target_branch: 'master', state_id: 3) }
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+ end
+
+ it 'schdules BackfillMergeRequestCleanupSchedules background jobs' do
+ Sidekiq::Testing.fake! do
+ migrate!
+
+ aggregate_failures do
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(2.minutes, closed_mr_1.id, closed_mr_2.id)
+ expect(described_class::MIGRATION)
+ .to be_scheduled_delayed_migration(4.minutes, merged_mr_1.id, merged_mr_2.id)
+ expect(BackgroundMigrationWorker.jobs.size).to eq(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/bulk_imports/tracker_spec.rb b/spec/models/bulk_imports/tracker_spec.rb
new file mode 100644
index 00000000000..8eb5a6c27dd
--- /dev/null
+++ b/spec/models/bulk_imports/tracker_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BulkImports::Tracker, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:entity).required }
+ end
+
+ describe 'validations' do
+ before do
+ create(:bulk_import_tracker)
+ end
+
+ it { is_expected.to validate_presence_of(:relation) }
+ it { is_expected.to validate_uniqueness_of(:relation).scoped_to(:bulk_import_entity_id) }
+
+ context 'when has_next_page is true' do
+ it "validates presence of `next_page`" do
+ tracker = build(:bulk_import_tracker, has_next_page: true)
+
+ expect(tracker).not_to be_valid
+ expect(tracker.errors).to include(:next_page)
+ end
+ end
+ end
+end
diff --git a/spec/models/design_management/design_spec.rb b/spec/models/design_management/design_spec.rb
index 946541a0602..d3ce2f2d48f 100644
--- a/spec/models/design_management/design_spec.rb
+++ b/spec/models/design_management/design_spec.rb
@@ -375,14 +375,6 @@ RSpec.describe DesignManagement::Design do
end
it { is_expected.to contain_exactly(version_author, note_author, mentioned_user) }
-
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(design_management_design_notification_participants: false)
- end
-
- it { is_expected.to be_empty }
- end
end
end
diff --git a/spec/requests/api/graphql/mutations/commits/create_spec.rb b/spec/requests/api/graphql/mutations/commits/create_spec.rb
index ac4fa7cfe83..375d4f10b40 100644
--- a/spec/requests/api/graphql/mutations/commits/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/commits/create_spec.rb
@@ -23,6 +23,18 @@ RSpec.describe 'Creation of a new commit' do
let(:mutation) { graphql_mutation(:commit_create, input) }
let(:mutation_response) { graphql_mutation_response(:commit_create) }
+ shared_examples 'a commit is successful' do
+ it 'creates a new commit' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(response).to have_gitlab_http_status(:success)
+
+ expect(mutation_response['commit']).to include(
+ 'title' => message
+ )
+ end
+ end
+
context 'the user is not allowed to create a commit' do
it_behaves_like 'a mutation that returns a top-level access error'
end
@@ -32,14 +44,7 @@ RSpec.describe 'Creation of a new commit' do
project.add_developer(current_user)
end
- it 'creates a new commit' do
- post_graphql_mutation(mutation, current_user: current_user)
-
- expect(response).to have_gitlab_http_status(:success)
- expect(mutation_response['commit']).to include(
- 'title' => message
- )
- end
+ it_behaves_like 'a commit is successful'
context 'when branch is not correct' do
let(:branch) { 'unknown' }
@@ -47,5 +52,22 @@ RSpec.describe 'Creation of a new commit' do
it_behaves_like 'a mutation that returns errors in the response',
errors: ['You can only create or edit files when you are on a branch']
end
+
+ context 'when branch is new, and a start_branch is defined' do
+ let(:input) { { project_path: project.full_path, branch: branch, start_branch: start_branch, message: message, actions: actions } }
+ let(:branch) { 'new-branch' }
+ let(:start_branch) { 'master' }
+ let(:actions) do
+ [
+ {
+ action: 'CREATE',
+ filePath: 'ANOTHER_FILE.md',
+ content: 'Bye'
+ }
+ ]
+ end
+
+ it_behaves_like 'a commit is successful'
+ end
end
end
diff --git a/spec/requests/api/graphql/mutations/releases/create_spec.rb b/spec/requests/api/graphql/mutations/releases/create_spec.rb
index 2402cf62a49..d745eb3083d 100644
--- a/spec/requests/api/graphql/mutations/releases/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/releases/create_spec.rb
@@ -121,7 +121,7 @@ RSpec.describe 'Creation of a new release' do
create_release
release = mutation_response[:release]
- expected_direct_asset_url = Gitlab::Routing.url_helpers.project_release_url(project, Release.find_by(tag: tag_name)) << asset_link[:directAssetPath]
+ expected_direct_asset_url = Gitlab::Routing.url_helpers.project_release_url(project, Release.find_by(tag: tag_name)) << "/downloads#{asset_link[:directAssetPath]}"
expected_attributes = {
tagName: tag_name,
diff --git a/spec/requests/api/graphql/project/release_spec.rb b/spec/requests/api/graphql/project/release_spec.rb
index 57b620dbdf7..57dbe258ce4 100644
--- a/spec/requests/api/graphql/project/release_spec.rb
+++ b/spec/requests/api/graphql/project/release_spec.rb
@@ -147,7 +147,7 @@ RSpec.describe 'Query.project(fullPath).release(tagName)' do
'name' => link.name,
'url' => link.url,
'external' => link.external?,
- 'directAssetUrl' => link.filepath ? Gitlab::Routing.url_helpers.project_release_url(project, release) << link.filepath : link.url
+ 'directAssetUrl' => link.filepath ? Gitlab::Routing.url_helpers.project_release_url(project, release) << "/downloads#{link.filepath}" : link.url
}
end
diff --git a/spec/requests/api/release/links_spec.rb b/spec/requests/api/release/links_spec.rb
index 82d0d64eba4..c03dd0331cf 100644
--- a/spec/requests/api/release/links_spec.rb
+++ b/spec/requests/api/release/links_spec.rb
@@ -146,7 +146,7 @@ RSpec.describe API::Release::Links do
specify do
get api("/projects/#{project.id}/releases/v0.1/assets/links/#{link.id}", maintainer)
- expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.namespace.path}/#{project.name}/-/releases/#{release.tag}/bin/bigfile.exe")
+ expect(json_response['direct_asset_url']).to eq("http://localhost/#{project.namespace.path}/#{project.name}/-/releases/#{release.tag}/downloads/bin/bigfile.exe")
end
end
diff --git a/spec/requests/projects/releases_controller_spec.rb b/spec/requests/projects/releases_controller_spec.rb
new file mode 100644
index 00000000000..8e492125ace
--- /dev/null
+++ b/spec/requests/projects/releases_controller_spec.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects::ReleasesController' do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ login_as(user)
+ end
+
+ # Added as a request spec because of https://gitlab.com/gitlab-org/gitlab/-/issues/232386
+ describe 'GET #downloads' do
+ context 'filepath redirection' do
+ let_it_be(:release) { create(:release, project: project, tag: 'v11.9.0-rc2' ) }
+ let!(:link) { create(:release_link, release: release, name: 'linux-amd64 binaries', filepath: filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
+ let_it_be(:url) { "#{project_releases_path(project)}/#{release.tag}/downloads/bin/darwin-amd64" }
+
+ let(:subject) { get url }
+
+ context 'valid filepath' do
+ let(:filepath) { '/bin/darwin-amd64' }
+
+ it 'redirects to the asset direct link' do
+ subject
+
+ expect(response).to redirect_to('https://aws.example.com/s3/project/bin/hello-darwin-amd64')
+ end
+
+ it 'redirects with a status of 302' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ end
+ end
+
+ context 'invalid filepath' do
+ let(:filepath) { '/binaries/win32' }
+
+ it 'is not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ context 'invalid filepath' do
+ let(:invalid_filepath) { 'bin/darwin-amd64' }
+
+ let(:subject) { create(:release_link, name: 'linux-amd64 binaries', filepath: invalid_filepath, url: 'https://aws.example.com/s3/project/bin/hello-darwin-amd64') }
+
+ it 'cannot create an invalid filepath' do
+ expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+ end
+end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index e4ec3e56c20..6f7225fadbf 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -867,23 +867,6 @@ RSpec.describe NotificationService, :mailer do
should_not_email(non_member_and_mentioned)
should_not_email(note.author)
end
-
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(design_management_design_notification_participants: false)
- end
-
- it 'sends a new note notification only to the mentioned member', :aggregate_failures do
- notification.new_note(note)
-
- should_email(member_and_mentioned)
- should_not_email(design.authors.first)
- should_not_email(member_and_author_of_second_note)
- should_not_email(member_and_not_mentioned)
- should_not_email(non_member_and_mentioned)
- should_not_email(note.author)
- end
- end
end
context 'design management is disabled' do