summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-09-08 15:08:41 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-09-08 15:08:41 +0000
commitdc47d7f5c0f1a402463e9c1adaffecf3f465bc7f (patch)
tree5fbe362a06ef1841c73d6b377dbccc5dfc7fcece /spec
parenta0158b1a9c21f648fdbf79765bbc1e19e776b5d9 (diff)
downloadgitlab-ce-dc47d7f5c0f1a402463e9c1adaffecf3f465bc7f.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/concerns/redis_tracking_spec.rb10
-rw-r--r--spec/factories/audit_events.rb2
-rw-r--r--spec/factories/packages.rb1
-rw-r--r--spec/features/issues/issue_detail_spec.rb13
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js42
-rw-r--r--spec/frontend/environments/environment_rollback_spec.js4
-rw-r--r--spec/frontend/packages/mock_data.js3
-rw-r--r--spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap30
-rw-r--r--spec/frontend/packages/shared/components/packages_list_loader_spec.js33
-rw-r--r--spec/frontend/repository/log_tree_spec.js44
-rw-r--r--spec/graphql/types/user_type_spec.rb1
-rw-r--r--spec/lib/gitlab/ci/pipeline_object_hierarchy_spec.rb111
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/ci/pipeline_spec.rb47
-rw-r--r--spec/models/packages/package_spec.rb1
-rw-r--r--spec/requests/api/graphql/user/starred_projects_query_spec.rb73
-rw-r--r--spec/services/admin/propagate_service_template_spec.rb (renamed from spec/services/projects/propagate_service_template_spec.rb)11
-rw-r--r--spec/services/ci/create_downstream_pipeline_service_spec.rb47
-rw-r--r--spec/services/packages/composer/create_package_service_spec.rb10
-rw-r--r--spec/services/packages/conan/create_package_service_spec.rb10
-rw-r--r--spec/services/packages/maven/create_package_service_spec.rb4
-rw-r--r--spec/services/packages/npm/create_package_service_spec.rb4
-rw-r--r--spec/services/packages/nuget/create_package_service_spec.rb7
-rw-r--r--spec/services/packages/pypi/create_package_service_spec.rb4
-rw-r--r--spec/support/shared_examples/services/packages_shared_examples.rb8
-rw-r--r--spec/views/shared/deploy_tokens/_form.html.haml_spec.rb62
-rw-r--r--spec/workers/personal_access_tokens/expired_notification_worker_spec.rb28
-rw-r--r--spec/workers/propagate_service_template_worker_spec.rb2
28 files changed, 519 insertions, 94 deletions
diff --git a/spec/controllers/concerns/redis_tracking_spec.rb b/spec/controllers/concerns/redis_tracking_spec.rb
index 09ea9bd726f..3795fca5576 100644
--- a/spec/controllers/concerns/redis_tracking_spec.rb
+++ b/spec/controllers/concerns/redis_tracking_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe RedisTracking do
include RedisTracking
skip_before_action :authenticate_user!, only: :show
- track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score', feature: :g_compliance_dashboard_feature
+ track_redis_hll_event :index, :show, name: 'i_analytics_dev_ops_score', feature: :g_compliance_dashboard_feature, feature_default_enabled: true
def index
render html: 'index'
@@ -61,6 +61,14 @@ RSpec.describe RedisTracking do
get :index
end
+
+ it 'passes default_enabled flag' do
+ sign_in(user)
+
+ expect(controller).to receive(:metric_feature_enabled?).with(feature.to_sym, true)
+
+ get :index
+ end
end
context 'when user is not logged in and there is a visitor_id' do
diff --git a/spec/factories/audit_events.rb b/spec/factories/audit_events.rb
index 9a450797df7..5497648273c 100644
--- a/spec/factories/audit_events.rb
+++ b/spec/factories/audit_events.rb
@@ -36,7 +36,7 @@ FactoryBot.define do
ip_address { IPAddr.new '127.0.0.1' }
details do
{
- change: 'packges_enabled',
+ change: 'packages_enabled',
from: true,
to: false,
author_name: user.name,
diff --git a/spec/factories/packages.rb b/spec/factories/packages.rb
index ee9079579e0..52b2a32cd3b 100644
--- a/spec/factories/packages.rb
+++ b/spec/factories/packages.rb
@@ -2,6 +2,7 @@
FactoryBot.define do
factory :package, class: 'Packages::Package' do
project
+ creator { project&.creator }
name { 'my/company/app/my-app' }
sequence(:version) { |n| "1.#{n}-SNAPSHOT" }
package_type { :maven }
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index 9879703c8bf..1c8da227412 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -20,6 +20,19 @@ RSpec.describe 'Issue Detail', :js do
end
end
+ context 'when user displays the issue as an incident' do
+ let(:issue) { create(:incident, project: project, author: user) }
+
+ before do
+ visit project_issue_path(project, issue)
+ wait_for_requests
+ end
+
+ it 'does not show design management' do
+ expect(page).not_to have_selector('.js-design-management')
+ end
+ end
+
context 'when issue description has xss snippet' do
before do
issue.update!(description: '![xss" onload=alert(1);//](a)')
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index 5a4f703f72e..f80236afacd 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -190,6 +190,48 @@ describe('Board Store Mutations', () => {
});
});
+ describe('UPDATE_ISSUE_BY_ID', () => {
+ const issueId = '1';
+ const prop = 'id';
+ const value = '2';
+ const issue = { [issueId]: { id: 1, title: 'Issue' } };
+
+ beforeEach(() => {
+ state = {
+ ...state,
+ isLoadingIssues: true,
+ error: undefined,
+ issues: {
+ ...issue,
+ },
+ };
+ });
+
+ describe('when the issue is in state', () => {
+ it('updates the property of the correct issue', () => {
+ mutations.UPDATE_ISSUE_BY_ID(state, {
+ issueId,
+ prop,
+ value,
+ });
+
+ expect(state.issues[issueId]).toEqual({ ...issue[issueId], id: '2' });
+ });
+ });
+
+ describe('when the issue is not in state', () => {
+ it('throws an error', () => {
+ expect(() => {
+ mutations.UPDATE_ISSUE_BY_ID(state, {
+ issueId: '3',
+ prop,
+ value,
+ });
+ }).toThrow(new Error('No issue found.'));
+ });
+ });
+ });
+
describe('RECEIVE_ADD_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_SUCCESS);
});
diff --git a/spec/frontend/environments/environment_rollback_spec.js b/spec/frontend/environments/environment_rollback_spec.js
index f25e05f9cd8..fb62a096c3d 100644
--- a/spec/frontend/environments/environment_rollback_spec.js
+++ b/spec/frontend/environments/environment_rollback_spec.js
@@ -1,5 +1,5 @@
import { shallowMount, mount } from '@vue/test-utils';
-import { GlDeprecatedButton } from '@gitlab/ui';
+import { GlButton } from '@gitlab/ui';
import eventHub from '~/environments/event_hub';
import RollbackComponent from '~/environments/components/environment_rollback.vue';
@@ -40,7 +40,7 @@ describe('Rollback Component', () => {
},
},
});
- const button = wrapper.find(GlDeprecatedButton);
+ const button = wrapper.find(GlButton);
button.vm.$emit('click');
diff --git a/spec/frontend/packages/mock_data.js b/spec/frontend/packages/mock_data.js
index 86205b0744c..b95d06428ff 100644
--- a/spec/frontend/packages/mock_data.js
+++ b/spec/frontend/packages/mock_data.js
@@ -30,6 +30,7 @@ export const mavenPackage = {
name: 'Test package',
package_type: 'maven',
project_path: 'foo/bar/baz',
+ projectPathName: 'foo/bar/baz',
project_id: 1,
updated_at: '2015-12-10',
version: '1.0.0',
@@ -59,6 +60,7 @@ export const npmPackage = {
name: '@Test/package',
package_type: 'npm',
project_path: 'foo/bar/baz',
+ projectPathName: 'foo/bar/baz',
project_id: 1,
updated_at: '2015-12-10',
version: '',
@@ -86,6 +88,7 @@ export const conanPackage = {
id: 3,
name: 'conan-package',
project_path: 'foo/bar/baz',
+ projectPathName: 'foo/bar/baz',
package_files: [],
package_type: 'conan',
project_id: 1,
diff --git a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
index eb9d4faa964..4b1346925cc 100644
--- a/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
+++ b/spec/frontend/packages/shared/components/__snapshots__/package_list_row_spec.js.snap
@@ -14,22 +14,23 @@ exports[`packages_list_row renders 1`] = `
class="gl-display-flex gl-xs-flex-direction-column gl-justify-content-space-between gl-align-items-stretch gl-flex-fill-1"
>
<div
- class="gl-display-flex gl-flex-direction-column gl-justify-content-space-between gl-xs-mb-3"
+ class="gl-display-flex gl-flex-direction-column gl-justify-content-space-between gl-xs-mb-3 gl-min-w-0 gl-flex-grow-1"
>
<div
- class="gl-display-flex gl-align-items-center gl-text-body gl-font-weight-bold gl-min-h-6"
+ class="gl-display-flex gl-align-items-center gl-text-body gl-font-weight-bold gl-min-h-6 gl-min-w-0"
>
<div
- class="gl-display-flex gl-align-items-center gl-mr-3"
+ class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0"
>
<gl-link-stub
- class="gl-text-body"
+ class="gl-text-body gl-min-w-0"
data-qa-selector="package_link"
href="foo"
>
-
- Test package
-
+ <gl-truncate-stub
+ position="end"
+ text="Test package"
+ />
</gl-link-stub>
<!---->
@@ -39,7 +40,7 @@ exports[`packages_list_row renders 1`] = `
</div>
<div
- class="gl-text-gray-500 gl-mt-1 gl-min-h-6"
+ class="gl-text-gray-500 gl-mt-1 gl-min-h-6 gl-min-w-0 gl-flex-fill-1"
>
<div
class="gl-display-flex"
@@ -54,19 +55,20 @@ exports[`packages_list_row renders 1`] = `
class="gl-display-flex gl-align-items-center"
>
<gl-icon-stub
- class="gl-ml-3 gl-mr-2"
+ class="gl-ml-3 gl-mr-2 gl-min-w-0"
name="review-list"
size="16"
/>
<gl-link-stub
- class="gl-text-body"
+ class="gl-text-body gl-min-w-0"
data-testid="packages-row-project"
href="/foo/bar/baz"
>
-
-
-
+ <gl-truncate-stub
+ position="end"
+ text="foo/bar/baz"
+ />
</gl-link-stub>
</div>
@@ -89,7 +91,7 @@ exports[`packages_list_row renders 1`] = `
</div>
<div
- class="gl-display-flex gl-flex-direction-column gl-sm-align-items-flex-end gl-justify-content-space-between gl-text-gray-500"
+ class="gl-display-flex gl-flex-direction-column gl-sm-align-items-flex-end gl-justify-content-space-between gl-text-gray-500 gl-flex-shrink-0"
>
<div
class="gl-sm-text-body gl-sm-font-weight-bold gl-min-h-6"
diff --git a/spec/frontend/packages/shared/components/packages_list_loader_spec.js b/spec/frontend/packages/shared/components/packages_list_loader_spec.js
index c8c2e2a4ba4..115a3a7095d 100644
--- a/spec/frontend/packages/shared/components/packages_list_loader_spec.js
+++ b/spec/frontend/packages/shared/components/packages_list_loader_spec.js
@@ -12,8 +12,8 @@ describe('PackagesListLoader', () => {
});
};
- const getShapes = () => wrapper.vm.desktopShapes;
- const findSquareButton = () => wrapper.find({ ref: 'button-loader' });
+ const findDesktopShapes = () => wrapper.find('[data-testid="desktop-loader"]');
+ const findMobileShapes = () => wrapper.find('[data-testid="mobile-loader"]');
beforeEach(createComponent);
@@ -22,21 +22,30 @@ describe('PackagesListLoader', () => {
wrapper = null;
});
- describe('when used for projects', () => {
- it('should return 5 rects with last one being a square', () => {
- expect(getShapes()).toHaveLength(5);
- expect(findSquareButton().exists()).toBe(true);
+ describe('desktop loader', () => {
+ it('produces the right loader', () => {
+ expect(findDesktopShapes().findAll('rect[width="1000"]')).toHaveLength(20);
+ });
+
+ it('has the correct classes', () => {
+ expect(findDesktopShapes().classes()).toEqual([
+ 'gl-display-none',
+ 'gl-display-sm-flex',
+ 'gl-flex-direction-column',
+ ]);
});
});
- describe('when used for groups', () => {
- beforeEach(() => {
- createComponent({ isGroup: true });
+ describe('mobile loader', () => {
+ it('produces the right loader', () => {
+ expect(findMobileShapes().findAll('rect[height="170"]')).toHaveLength(5);
});
- it('should return 5 rects with no square', () => {
- expect(getShapes()).toHaveLength(5);
- expect(findSquareButton().exists()).toBe(false);
+ it('has the correct classes', () => {
+ expect(findMobileShapes().classes()).toEqual([
+ 'gl-flex-direction-column',
+ 'gl-display-sm-none',
+ ]);
});
});
});
diff --git a/spec/frontend/repository/log_tree_spec.js b/spec/frontend/repository/log_tree_spec.js
index 5637d0be957..47f02db5f91 100644
--- a/spec/frontend/repository/log_tree_spec.js
+++ b/spec/frontend/repository/log_tree_spec.js
@@ -100,24 +100,28 @@ describe('fetchLogsTree', () => {
);
}));
- it('writes query to client', () =>
- fetchLogsTree(client, '', '0', resolver).then(() => {
- expect(client.writeQuery).toHaveBeenCalledWith({
- query: expect.anything(),
- data: {
- commits: [
- expect.objectContaining({
- __typename: 'LogTreeCommit',
- commitPath: 'https://test.com',
- committedDate: '2019-01-01',
- fileName: 'index.js',
- filePath: '/index.js',
- message: 'testing message',
- sha: '123',
- type: 'blob',
- }),
- ],
- },
- });
- }));
+ it('writes query to client', async () => {
+ await fetchLogsTree(client, '', '0', resolver);
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ query: expect.anything(),
+ data: {
+ projectPath: 'gitlab-org/gitlab-foss',
+ escapedRef: 'master',
+ commits: [
+ expect.objectContaining({
+ __typename: 'LogTreeCommit',
+ commitPath: 'https://test.com',
+ committedDate: '2019-01-01',
+ fileName: 'index.js',
+ filePath: '/index.js',
+ lockLabel: false,
+ message: 'testing message',
+ sha: '123',
+ titleHtml: undefined,
+ type: 'blob',
+ }),
+ ],
+ },
+ });
+ });
});
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index 7710b8efefe..1d5af24b3d9 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -25,6 +25,7 @@ RSpec.describe GitlabSchema.types['User'] do
assignedMergeRequests
groupMemberships
projectMemberships
+ starredProjects
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/lib/gitlab/ci/pipeline_object_hierarchy_spec.rb b/spec/lib/gitlab/ci/pipeline_object_hierarchy_spec.rb
new file mode 100644
index 00000000000..31c373d14d3
--- /dev/null
+++ b/spec/lib/gitlab/ci/pipeline_object_hierarchy_spec.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::PipelineObjectHierarchy do
+ let_it_be(:project) { create_default(:project, :repository) }
+ let_it_be(:pipeline) { create(:ci_empty_pipeline, status: :created, project: project) }
+ let_it_be(:ancestor) { create(:ci_pipeline, project: pipeline.project) }
+ let_it_be(:parent) { create(:ci_pipeline, project: pipeline.project) }
+ let_it_be(:child) { create(:ci_pipeline, project: pipeline.project) }
+ let_it_be(:cousin_parent) { create(:ci_pipeline, project: pipeline.project) }
+ let_it_be(:cousin) { create(:ci_pipeline, project: pipeline.project) }
+
+ before_all do
+ create_source_relation(ancestor, parent)
+ create_source_relation(ancestor, cousin_parent)
+ create_source_relation(parent, child)
+ create_source_relation(cousin_parent, cousin)
+ end
+
+ describe '#base_and_ancestors' do
+ it 'includes the base and its ancestors' do
+ relation = described_class.new(::Ci::Pipeline.where(id: parent.id)).base_and_ancestors
+
+ expect(relation).to contain_exactly(ancestor, parent)
+ end
+
+ it 'can find ancestors upto a certain level' do
+ relation = described_class.new(::Ci::Pipeline.where(id: child.id)).base_and_ancestors(upto: ancestor.id)
+
+ expect(relation).to contain_exactly(parent, child)
+ end
+
+ describe 'hierarchy_order option' do
+ let(:relation) do
+ described_class.new(::Ci::Pipeline.where(id: child.id)).base_and_ancestors(hierarchy_order: hierarchy_order)
+ end
+
+ context ':asc' do
+ let(:hierarchy_order) { :asc }
+
+ it 'orders by child to ancestor' do
+ expect(relation).to eq([child, parent, ancestor])
+ end
+ end
+
+ context ':desc' do
+ let(:hierarchy_order) { :desc }
+
+ it 'orders by ancestor to child' do
+ expect(relation).to eq([ancestor, parent, child])
+ end
+ end
+ end
+ end
+
+ describe '#base_and_descendants' do
+ it 'includes the base and its descendants' do
+ relation = described_class.new(::Ci::Pipeline.where(id: parent.id)).base_and_descendants
+
+ expect(relation).to contain_exactly(parent, child)
+ end
+
+ context 'when with_depth is true' do
+ let(:relation) do
+ described_class.new(::Ci::Pipeline.where(id: ancestor.id)).base_and_descendants(with_depth: true)
+ end
+
+ it 'includes depth in the results' do
+ object_depths = {
+ ancestor.id => 1,
+ parent.id => 2,
+ cousin_parent.id => 2,
+ child.id => 3,
+ cousin.id => 3
+ }
+
+ relation.each do |object|
+ expect(object.depth).to eq(object_depths[object.id])
+ end
+ end
+ end
+ end
+
+ describe '#all_objects' do
+ it 'includes its ancestors and descendants' do
+ relation = described_class.new(::Ci::Pipeline.where(id: parent.id)).all_objects
+
+ expect(relation).to contain_exactly(ancestor, parent, child)
+ end
+
+ it 'returns all family tree' do
+ relation = described_class.new(
+ ::Ci::Pipeline.where(id: child.id),
+ described_class.new(::Ci::Pipeline.where(id: child.id)).base_and_ancestors
+ ).all_objects
+
+ expect(relation).to contain_exactly(ancestor, parent, cousin_parent, child, cousin)
+ end
+ end
+
+ private
+
+ def create_source_relation(parent, child)
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: parent),
+ source_project: parent.project,
+ pipeline: child,
+ project: child.project)
+ end
+end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index d0ffda61cc1..de538c6c263 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -539,6 +539,7 @@ timelogs:
- issue
- merge_request
- user
+- note
push_event_payload:
- event
issue_assignees:
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 58ceaad1063..955f146270e 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -2616,11 +2616,11 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
describe '#same_family_pipeline_ids' do
- subject(:same_family_pipeline_ids) { pipeline.same_family_pipeline_ids }
+ subject { pipeline.same_family_pipeline_ids.map(&:id) }
context 'when pipeline is not child nor parent' do
it 'returns just the pipeline id' do
- expect(same_family_pipeline_ids).to contain_exactly(pipeline.id)
+ expect(subject).to contain_exactly(pipeline.id)
end
end
@@ -2643,7 +2643,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
it 'returns parent sibling and self ids' do
- expect(same_family_pipeline_ids).to contain_exactly(parent.id, pipeline.id, sibling.id)
+ expect(subject).to contain_exactly(parent.id, pipeline.id, sibling.id)
end
end
@@ -2659,7 +2659,46 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
it 'returns self and child ids' do
- expect(same_family_pipeline_ids).to contain_exactly(pipeline.id, child.id)
+ expect(subject).to contain_exactly(pipeline.id, child.id)
+ end
+ end
+
+ context 'when pipeline is a child of a child pipeline' do
+ let(:ancestor) { create(:ci_pipeline, project: pipeline.project) }
+ let(:parent) { create(:ci_pipeline, project: pipeline.project) }
+ let(:cousin_parent) { create(:ci_pipeline, project: pipeline.project) }
+ let(:cousin) { create(:ci_pipeline, project: pipeline.project) }
+
+ before do
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: ancestor),
+ source_project: ancestor.project,
+ pipeline: parent,
+ project: parent.project)
+
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: ancestor),
+ source_project: ancestor.project,
+ pipeline: cousin_parent,
+ project: cousin_parent.project)
+
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: parent),
+ source_project: parent.project,
+ pipeline: pipeline,
+ project: pipeline.project)
+
+ create(:ci_sources_pipeline,
+ source_job: create(:ci_build, pipeline: cousin_parent),
+ source_project: cousin_parent.project,
+ pipeline: cousin,
+ project: cousin.project)
+ end
+
+ it 'returns all family ids' do
+ expect(subject).to contain_exactly(
+ ancestor.id, parent.id, cousin_parent.id, cousin.id, pipeline.id
+ )
end
end
end
diff --git a/spec/models/packages/package_spec.rb b/spec/models/packages/package_spec.rb
index 7fb6e6d63c6..ea1f75d04e7 100644
--- a/spec/models/packages/package_spec.rb
+++ b/spec/models/packages/package_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe Packages::Package, type: :model do
describe 'relationships' do
it { is_expected.to belong_to(:project) }
+ it { is_expected.to belong_to(:creator) }
it { is_expected.to have_many(:package_files).dependent(:destroy) }
it { is_expected.to have_many(:dependency_links).inverse_of(:package) }
it { is_expected.to have_many(:tags).inverse_of(:package) }
diff --git a/spec/requests/api/graphql/user/starred_projects_query_spec.rb b/spec/requests/api/graphql/user/starred_projects_query_spec.rb
new file mode 100644
index 00000000000..8a1bd3d172f
--- /dev/null
+++ b/spec/requests/api/graphql/user/starred_projects_query_spec.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Getting starredProjects of the user' do
+ include GraphqlHelpers
+
+ let(:query) do
+ graphql_query_for(:user, user_params, user_fields)
+ end
+
+ let(:user_params) { { username: user.username } }
+
+ let_it_be(:project_a) { create(:project, :public) }
+ let_it_be(:project_b) { create(:project, :private) }
+ let_it_be(:project_c) { create(:project, :private) }
+ let_it_be(:user, reload: true) { create(:user) }
+
+ let(:user_fields) { 'starredProjects { nodes { id } }' }
+ let(:starred_projects) { graphql_data_at(:user, :starred_projects, :nodes) }
+
+ before do
+ project_b.add_reporter(user)
+ project_c.add_reporter(user)
+
+ user.toggle_star(project_a)
+ user.toggle_star(project_b)
+ user.toggle_star(project_c)
+
+ post_graphql(query)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'found only public project' do
+ expect(starred_projects).to contain_exactly(
+ a_hash_including('id' => global_id_of(project_a))
+ )
+ end
+
+ context 'the current user is the user' do
+ let(:current_user) { user }
+
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'found all projects' do
+ expect(starred_projects).to contain_exactly(
+ a_hash_including('id' => global_id_of(project_a)),
+ a_hash_including('id' => global_id_of(project_b)),
+ a_hash_including('id' => global_id_of(project_c))
+ )
+ end
+ end
+
+ context 'the current user is a member of a private project the user starred' do
+ let_it_be(:other_user) { create(:user) }
+
+ before do
+ project_b.add_reporter(other_user)
+
+ post_graphql(query, current_user: other_user)
+ end
+
+ it 'finds public and member projects' do
+ expect(starred_projects).to contain_exactly(
+ a_hash_including('id' => global_id_of(project_a)),
+ a_hash_including('id' => global_id_of(project_b))
+ )
+ end
+ end
+end
diff --git a/spec/services/projects/propagate_service_template_spec.rb b/spec/services/admin/propagate_service_template_spec.rb
index 8f206046b0a..15654653095 100644
--- a/spec/services/projects/propagate_service_template_spec.rb
+++ b/spec/services/admin/propagate_service_template_spec.rb
@@ -2,10 +2,10 @@
require 'spec_helper'
-RSpec.describe Projects::PropagateServiceTemplate do
+RSpec.describe Admin::PropagateServiceTemplate do
describe '.propagate' do
let!(:service_template) do
- PushoverService.create(
+ PushoverService.create!(
template: true,
active: true,
push_events: false,
@@ -31,8 +31,7 @@ RSpec.describe Projects::PropagateServiceTemplate do
end
it 'creates services for a project that has another service' do
- BambooService.create(
- template: true,
+ BambooService.create!(
active: true,
project: project,
properties: {
@@ -51,7 +50,7 @@ RSpec.describe Projects::PropagateServiceTemplate do
end
it 'does not create the service if it exists already' do
- other_service = BambooService.create(
+ other_service = BambooService.create!(
template: true,
active: true,
properties: {
@@ -110,7 +109,7 @@ RSpec.describe Projects::PropagateServiceTemplate do
let(:project_total) { 5 }
before do
- stub_const 'Projects::PropagateServiceTemplate::BATCH_SIZE', 3
+ stub_const('Admin::PropagateServiceTemplate::BATCH_SIZE', 3)
project_total.times { create(:project) }
diff --git a/spec/services/ci/create_downstream_pipeline_service_spec.rb b/spec/services/ci/create_downstream_pipeline_service_spec.rb
index f26f9eeb6f0..69f44724ce0 100644
--- a/spec/services/ci/create_downstream_pipeline_service_spec.rb
+++ b/spec/services/ci/create_downstream_pipeline_service_spec.rb
@@ -311,7 +311,7 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
end
end
- context 'when upstream pipeline is a child pipeline' do
+ context 'when upstream pipeline is a first descendant pipeline' do
let!(:pipeline_source) do
create(:ci_sources_pipeline,
source_pipeline: create(:ci_pipeline, project: upstream_pipeline.project),
@@ -323,12 +323,53 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
upstream_pipeline.update!(source: :parent_pipeline)
end
- it 'does not create a further child pipeline' do
+ it 'creates the pipeline' do
+ expect { service.execute(bridge) }
+ .to change { Ci::Pipeline.count }.by(1)
+
+ expect(bridge.reload).to be_success
+ end
+
+ context 'when FF ci_child_of_child_pipeline is disabled' do
+ before do
+ stub_feature_flags(ci_child_of_child_pipeline: false)
+ end
+
+ it 'does not create a further child pipeline' do
+ expect { service.execute(bridge) }
+ .not_to change { Ci::Pipeline.count }
+
+ expect(bridge.reload).to be_failed
+ expect(bridge.failure_reason).to eq 'bridge_pipeline_is_child_pipeline'
+ end
+ end
+ end
+
+ context 'when upstream pipeline is a second descendant pipeline' do
+ let!(:pipeline_source) do
+ parent_of_upstream_pipeline = create(:ci_pipeline, project: upstream_pipeline.project)
+
+ create(:ci_sources_pipeline,
+ source_pipeline: create(:ci_pipeline, project: upstream_pipeline.project),
+ pipeline: parent_of_upstream_pipeline
+ )
+
+ create(:ci_sources_pipeline,
+ source_pipeline: parent_of_upstream_pipeline,
+ pipeline: upstream_pipeline
+ )
+ end
+
+ before do
+ upstream_pipeline.update!(source: :parent_pipeline)
+ end
+
+ it 'does not create a second descendant pipeline' do
expect { service.execute(bridge) }
.not_to change { Ci::Pipeline.count }
expect(bridge.reload).to be_failed
- expect(bridge.failure_reason).to eq 'bridge_pipeline_is_child_pipeline'
+ expect(bridge.failure_reason).to eq 'reached_max_descendant_pipelines_depth'
end
end
end
diff --git a/spec/services/packages/composer/create_package_service_spec.rb b/spec/services/packages/composer/create_package_service_spec.rb
index 3f9da31cf6e..a1fe9a1b918 100644
--- a/spec/services/packages/composer/create_package_service_spec.rb
+++ b/spec/services/packages/composer/create_package_service_spec.rb
@@ -37,12 +37,16 @@ RSpec.describe Packages::Composer::CreatePackageService do
expect(created_package.composer_metadatum.target_sha).to eq branch.target
expect(created_package.composer_metadatum.composer_json.to_json).to eq json
end
+
+ it_behaves_like 'assigns the package creator' do
+ let(:package) { created_package }
+ end
end
context 'with a tag' do
let(:tag) { project.repository.find_tag('v1.2.3') }
- before do
+ before(:all) do
project.repository.add_tag(user, 'v1.2.3', 'master')
end
@@ -54,6 +58,10 @@ RSpec.describe Packages::Composer::CreatePackageService do
expect(created_package.name).to eq package_name
expect(created_package.version).to eq '1.2.3'
end
+
+ it_behaves_like 'assigns the package creator' do
+ let(:package) { created_package }
+ end
end
end
diff --git a/spec/services/packages/conan/create_package_service_spec.rb b/spec/services/packages/conan/create_package_service_spec.rb
index f8068f6e57b..b217e570aba 100644
--- a/spec/services/packages/conan/create_package_service_spec.rb
+++ b/spec/services/packages/conan/create_package_service_spec.rb
@@ -5,9 +5,11 @@ RSpec.describe Packages::Conan::CreatePackageService do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
- subject { described_class.new(project, user, params) }
+ subject(:service) { described_class.new(project, user, params) }
describe '#execute' do
+ subject(:package) { service.execute }
+
context 'valid params' do
let(:params) do
{
@@ -19,8 +21,6 @@ RSpec.describe Packages::Conan::CreatePackageService do
end
it 'creates a new package' do
- package = subject.execute
-
expect(package).to be_valid
expect(package.name).to eq(params[:package_name])
expect(package.version).to eq(params[:package_version])
@@ -28,6 +28,8 @@ RSpec.describe Packages::Conan::CreatePackageService do
expect(package.conan_metadatum.package_username).to eq(params[:package_username])
expect(package.conan_metadatum.package_channel).to eq(params[:package_channel])
end
+
+ it_behaves_like 'assigns the package creator'
end
context 'invalid params' do
@@ -41,7 +43,7 @@ RSpec.describe Packages::Conan::CreatePackageService do
end
it 'fails' do
- expect { subject.execute }.to raise_exception(ActiveRecord::RecordInvalid)
+ expect { package }.to raise_exception(ActiveRecord::RecordInvalid)
end
end
end
diff --git a/spec/services/packages/maven/create_package_service_spec.rb b/spec/services/packages/maven/create_package_service_spec.rb
index bfdf62008ba..7ec368aa00f 100644
--- a/spec/services/packages/maven/create_package_service_spec.rb
+++ b/spec/services/packages/maven/create_package_service_spec.rb
@@ -34,6 +34,8 @@ RSpec.describe Packages::Maven::CreatePackageService do
end
it_behaves_like 'assigns build to package'
+
+ it_behaves_like 'assigns the package creator'
end
context 'without version' do
@@ -57,6 +59,8 @@ RSpec.describe Packages::Maven::CreatePackageService do
expect(package.maven_metadatum.app_name).to eq(app_name)
expect(package.maven_metadatum.app_version).to be nil
end
+
+ it_behaves_like 'assigns the package creator'
end
context 'path is missing' do
diff --git a/spec/services/packages/npm/create_package_service_spec.rb b/spec/services/packages/npm/create_package_service_spec.rb
index 895c46735ed..c8431c640da 100644
--- a/spec/services/packages/npm/create_package_service_spec.rb
+++ b/spec/services/packages/npm/create_package_service_spec.rb
@@ -27,6 +27,10 @@ RSpec.describe Packages::Npm::CreatePackageService do
.and change { Packages::Tag.count }.by(1)
end
+ it_behaves_like 'assigns the package creator' do
+ let(:package) { subject }
+ end
+
it { is_expected.to be_valid }
it 'creates a package with name and version' do
diff --git a/spec/services/packages/nuget/create_package_service_spec.rb b/spec/services/packages/nuget/create_package_service_spec.rb
index 1579b42d9ad..e51bc03f311 100644
--- a/spec/services/packages/nuget/create_package_service_spec.rb
+++ b/spec/services/packages/nuget/create_package_service_spec.rb
@@ -9,9 +9,10 @@ RSpec.describe Packages::Nuget::CreatePackageService do
describe '#execute' do
subject { described_class.new(project, user, params).execute }
+ let(:package) { Packages::Package.last }
+
it 'creates the package' do
expect { subject }.to change { Packages::Package.count }.by(1)
- package = Packages::Package.last
expect(package).to be_valid
expect(package.name).to eq(Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME)
@@ -23,12 +24,12 @@ RSpec.describe Packages::Nuget::CreatePackageService do
expect { subject }.to change { Packages::Package.count }.by(1)
expect { described_class.new(project, user, params).execute }.to change { Packages::Package.count }.by(1)
- package = Packages::Package.last
-
expect(package).to be_valid
expect(package.name).to eq(Packages::Nuget::CreatePackageService::TEMPORARY_PACKAGE_NAME)
expect(package.version).to start_with(Packages::Nuget::CreatePackageService::PACKAGE_VERSION)
expect(package.package_type).to eq('nuget')
end
+
+ it_behaves_like 'assigns the package creator'
end
end
diff --git a/spec/services/packages/pypi/create_package_service_spec.rb b/spec/services/packages/pypi/create_package_service_spec.rb
index 69905478879..fa1af1e3f3d 100644
--- a/spec/services/packages/pypi/create_package_service_spec.rb
+++ b/spec/services/packages/pypi/create_package_service_spec.rb
@@ -47,6 +47,10 @@ RSpec.describe Packages::Pypi::CreatePackageService do
end
end
+ it_behaves_like 'assigns the package creator' do
+ let(:package) { created_package }
+ end
+
context 'with an existing package' do
before do
described_class.new(project, user, params).execute
diff --git a/spec/support/shared_examples/services/packages_shared_examples.rb b/spec/support/shared_examples/services/packages_shared_examples.rb
index 836997e78f5..7fd59c3d963 100644
--- a/spec/support/shared_examples/services/packages_shared_examples.rb
+++ b/spec/support/shared_examples/services/packages_shared_examples.rb
@@ -14,6 +14,14 @@ RSpec.shared_examples 'assigns build to package' do
end
end
+RSpec.shared_examples 'assigns the package creator' do
+ it 'assigns the package creator' do
+ subject
+
+ expect(package.creator).to eq user
+ end
+end
+
RSpec.shared_examples 'returns packages' do |container_type, user_type|
context "for #{user_type}" do
before do
diff --git a/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb b/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb
new file mode 100644
index 00000000000..3508ba8cca9
--- /dev/null
+++ b/spec/views/shared/deploy_tokens/_form.html.haml_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'shared/deploy_tokens/_form.html.haml' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { build(:deploy_token) }
+
+ RSpec.shared_examples "display deploy token settings" do |role, shows_package_registry_permissions|
+ before do
+ subject.add_user(user, role)
+ allow(view).to receive(:current_user).and_return(user)
+ stub_config(packages: { enabled: packages_enabled })
+ end
+
+ it "correctly renders the form" do
+ render 'shared/deploy_tokens/form', token: token, group_or_project: subject
+
+ if shows_package_registry_permissions
+ expect(rendered).to have_content('Allows read access to the package registry')
+ else
+ expect(rendered).not_to have_content('Allows read access to the package registry')
+ end
+ end
+ end
+
+ context "when the subject is a project" do
+ let_it_be(:subject, refind: true) { create(:project, :private) }
+
+ where(:packages_enabled, :feature_enabled, :role, :shows_package_registry_permissions) do
+ true | true | :maintainer | true
+ false | true | :maintainer | false
+ true | false | :maintainer | false
+ false | false | :maintainer | false
+ end
+
+ with_them do
+ before do
+ subject.update!(packages_enabled: feature_enabled)
+ end
+
+ it_behaves_like 'display deploy token settings', params[:role], params[:shows_package_registry_permissions]
+ end
+ end
+
+ context "when the subject is a group" do
+ let_it_be(:subject, refind: true) { create(:group, :private) }
+
+ where(:packages_enabled, :role, :shows_package_registry_permissions) do
+ true | :owner | true
+ false | :owner | false
+ true | :maintainer | true
+ false | :maintainer | false
+ end
+
+ with_them do
+ it_behaves_like 'display deploy token settings', params[:role], params[:shows_package_registry_permissions]
+ end
+ end
+end
diff --git a/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb b/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
index 676a419553f..3ff67f47523 100644
--- a/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
+++ b/spec/workers/personal_access_tokens/expired_notification_worker_spec.rb
@@ -9,32 +9,16 @@ RSpec.describe PersonalAccessTokens::ExpiredNotificationWorker, type: :worker do
context 'when a token has expired' do
let(:expired_today) { create(:personal_access_token, expires_at: Date.current) }
- context 'when feature is enabled' do
- it 'uses notification service to send email to the user' do
- expect_next_instance_of(NotificationService) do |notification_service|
- expect(notification_service).to receive(:access_token_expired).with(expired_today.user)
- end
-
- worker.perform
+ it 'uses notification service to send email to the user' do
+ expect_next_instance_of(NotificationService) do |notification_service|
+ expect(notification_service).to receive(:access_token_expired).with(expired_today.user)
end
- it 'updates notified column' do
- expect { worker.perform }.to change { expired_today.reload.after_expiry_notification_delivered }.from(false).to(true)
- end
+ worker.perform
end
- context 'when feature is disabled' do
- before do
- stub_feature_flags(expired_pat_email_notification: false)
- end
-
- it 'does not update notified column' do
- expect { worker.perform }.not_to change { expired_today.reload.after_expiry_notification_delivered }
- end
-
- it 'does not trigger email' do
- expect { worker.perform }.not_to change { ActionMailer::Base.deliveries.count }
- end
+ it 'updates notified column' do
+ expect { worker.perform }.to change { expired_today.reload.after_expiry_notification_delivered }.from(false).to(true)
end
end
diff --git a/spec/workers/propagate_service_template_worker_spec.rb b/spec/workers/propagate_service_template_worker_spec.rb
index 48151b25d4b..793f0b9b08c 100644
--- a/spec/workers/propagate_service_template_worker_spec.rb
+++ b/spec/workers/propagate_service_template_worker_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe PropagateServiceTemplateWorker do
stub_exclusive_lease("propagate_service_template_worker:#{template.id}",
timeout: PropagateServiceTemplateWorker::LEASE_TIMEOUT)
- expect(Projects::PropagateServiceTemplate)
+ expect(Admin::PropagateServiceTemplate)
.to receive(:propagate)
.with(template)