diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-10 21:10:41 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-10 21:10:41 +0300 |
commit | 7f04cb580bc7895145fc1df51907582f80adbbca (patch) | |
tree | 31eb03182fcd84002895e3befb3d453bbcf048b4 /spec | |
parent | bd5eb9f0201cf39ecfb0e754787a2297d5fdf051 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
34 files changed, 629 insertions, 173 deletions
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb index c839c35450e..c5e6479ec51 100644 --- a/spec/features/groups/members/manage_members_spec.rb +++ b/spec/features/groups/members/manage_members_spec.rb @@ -26,6 +26,18 @@ RSpec.describe 'Groups > Members > Manage members' do end end + shared_examples 'does not include either invite modal or either invite form' do + it 'does not include either of the invite members or invite group modal buttons' do + expect(page).not_to have_selector '.js-invite-members-modal' + expect(page).not_to have_selector '.js-invite-group-modal' + end + + it 'does not include either of the invite users or invite group forms' do + expect(page).not_to have_selector '.invite-users-form' + expect(page).not_to have_selector '.invite-group-form' + end + end + context 'when Invite Members modal is enabled' do it_behaves_like 'includes the correct Invite link', '.js-invite-members-trigger', '.invite-users-form' it_behaves_like 'includes the correct Invite link', '.js-invite-group-trigger', '.invite-group-form' @@ -165,23 +177,46 @@ RSpec.describe 'Groups > Members > Manage members' do end end - it 'guest can not manage other users', :js do - group.add_guest(user1) - group.add_developer(user2) + context 'as a guest', :js do + before do + group.add_guest(user1) + group.add_developer(user2) - visit group_group_members_path(group) + visit group_group_members_path(group) + end - expect(page).not_to have_selector '.invite-users-form' - expect(page).not_to have_selector '.invite-group-form' - expect(page).not_to have_selector '.js-invite-members-modal' - expect(page).not_to have_selector '.js-invite-group-modal' + it_behaves_like 'does not include either invite modal or either invite form' - page.within(second_row) do - # Can not modify user2 role - expect(page).not_to have_button 'Developer' + it 'does not include a button on the members page list to manage or remove the existing member', :js do + page.within(second_row) do + # Can not modify user2 role + expect(page).not_to have_button 'Developer' + + # Can not remove user2 + expect(page).not_to have_selector 'button[title="Remove member"]' + end + end + end + + context 'As a guest when the :invite_members_group_modal feature flag is disabled', :js do + before do + stub_feature_flags(invite_members_group_modal: false) + group.add_guest(user1) + group.add_developer(user2) + + visit group_group_members_path(group) + end + + it_behaves_like 'does not include either invite modal or either invite form' + + it 'does not include a button on the members page list to manage or remove the existing member', :js do + page.within(second_row) do + # Can not modify user2 role + expect(page).not_to have_button 'Developer' - # Can not remove user2 - expect(page).not_to have_selector 'button[title="Remove member"]' + # Can not remove user2 + expect(page).not_to have_selector 'button[title="Remove member"]' + end end end end diff --git a/spec/features/projects/services/user_activates_asana_spec.rb b/spec/features/projects/integrations/user_activates_asana_spec.rb index cf2290383e8..cf2290383e8 100644 --- a/spec/features/projects/services/user_activates_asana_spec.rb +++ b/spec/features/projects/integrations/user_activates_asana_spec.rb diff --git a/spec/features/projects/services/user_activates_assembla_spec.rb b/spec/features/projects/integrations/user_activates_assembla_spec.rb index 63cc424a641..63cc424a641 100644 --- a/spec/features/projects/services/user_activates_assembla_spec.rb +++ b/spec/features/projects/integrations/user_activates_assembla_spec.rb diff --git a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb b/spec/features/projects/integrations/user_activates_atlassian_bamboo_ci_spec.rb index 91db375be3a..91db375be3a 100644 --- a/spec/features/projects/services/user_activates_atlassian_bamboo_ci_spec.rb +++ b/spec/features/projects/integrations/user_activates_atlassian_bamboo_ci_spec.rb diff --git a/spec/frontend/groups/components/invite_members_banner_spec.js b/spec/frontend/groups/components/invite_members_banner_spec.js index 9a2068a27a1..0da2f84f2a1 100644 --- a/spec/frontend/groups/components/invite_members_banner_spec.js +++ b/spec/frontend/groups/components/invite_members_banner_spec.js @@ -2,6 +2,7 @@ import { GlBanner, GlButton } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import InviteMembersBanner from '~/groups/components/invite_members_banner.vue'; +import eventHub from '~/invite_members/event_hub'; import { setCookie, parseBoolean } from '~/lib/utils/common_utils'; jest.mock('~/lib/utils/common_utils'); @@ -58,12 +59,23 @@ describe('InviteMembersBanner', () => { }); }); - it('sets the button attributes for the buttonClickEvent', () => { - const button = wrapper.find(`[href='${wrapper.vm.inviteMembersPath}']`); + describe('when the button is clicked', () => { + beforeEach(() => { + jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); + wrapper.find(GlBanner).vm.$emit('primary'); + }); + + it('calls openModal through the eventHub', () => { + expect(eventHub.$emit).toHaveBeenCalledWith('openModal', { + inviteeType: 'members', + source: 'invite_members_banner', + }); + }); - expect(button.attributes()).toMatchObject({ - 'data-track-event': buttonClickEvent, - 'data-track-label': trackLabel, + it('sends the buttonClickEvent with correct trackCategory and trackLabel', () => { + expect(trackingSpy).toHaveBeenCalledWith(trackCategory, buttonClickEvent, { + label: trackLabel, + }); }); }); @@ -100,10 +112,6 @@ describe('InviteMembersBanner', () => { it('uses the button_text text from options for buttontext', () => { expect(findBanner().attributes('buttontext')).toBe(buttonText); }); - - it('uses the href from inviteMembersPath for buttonlink', () => { - expect(findBanner().attributes('buttonlink')).toBe(inviteMembersPath); - }); }); describe('dismissing', () => { diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js index 077c2174571..fec6abc9639 100644 --- a/spec/frontend/vue_shared/components/markdown/header_spec.js +++ b/spec/frontend/vue_shared/components/markdown/header_spec.js @@ -48,6 +48,7 @@ describe('Markdown field header component', () => { 'Add a bullet list', 'Add a numbered list', 'Add a task list', + 'Add a collapsible section', 'Add a table', 'Go full screen', ]; @@ -133,6 +134,14 @@ describe('Markdown field header component', () => { ); }); + it('renders collapsible section template', () => { + const detailsBlockButton = findToolbarButtonByProp('icon', 'details-block'); + + expect(detailsBlockButton.props('tag')).toEqual( + '<details><summary>Click to expand</summary>\n{text}\n</details>', + ); + }); + it('does not render suggestion button if `canSuggest` is set to false', () => { createWrapper({ canSuggest: false, diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb index 3edab40ac3f..122f2339b28 100644 --- a/spec/helpers/invite_members_helper_spec.rb +++ b/spec/helpers/invite_members_helper_spec.rb @@ -80,49 +80,6 @@ RSpec.describe InviteMembersHelper do context 'with group' do let_it_be(:group) { create(:group) } - describe "#can_invite_members_for_group?" do - include Devise::Test::ControllerHelpers - - let_it_be(:user) { create(:user) } - - before do - sign_in(user) - allow(helper).to receive(:current_user) { user } - end - - context 'when the user can admin_group_member' do - before do - allow(helper).to receive(:can?).with(user, :admin_group_member, group).and_return(true) - end - - it 'returns true' do - expect(helper.can_invite_members_for_group?(group)).to eq true - expect(helper).to have_received(:can?).with(user, :admin_group_member, group) - end - - context 'when feature flag is disabled' do - before do - stub_feature_flags(invite_members_group_modal: false) - end - - it 'returns false' do - expect(helper.can_invite_members_for_group?(group)).to eq false - expect(helper).not_to have_received(:can?) - end - end - end - - context 'when the user can not admin_group_member' do - before do - expect(helper).to receive(:can?).with(user, :admin_group_member, group).and_return(false) - end - - it 'returns false' do - expect(helper.can_invite_members_for_group?(group)).to eq false - end - end - end - describe "#invite_group_members?" do context 'when the user is an owner' do before do diff --git a/spec/helpers/namespaces_helper_spec.rb b/spec/helpers/namespaces_helper_spec.rb index 8c08b06d8a8..a8a918cbc74 100644 --- a/spec/helpers/namespaces_helper_spec.rb +++ b/spec/helpers/namespaces_helper_spec.rb @@ -265,4 +265,32 @@ RSpec.describe NamespacesHelper do end end end + + describe '#cascading_namespace_setting_locked?' do + let(:attribute) { :delayed_project_removal } + + context 'when `group` argument is `nil`' do + it 'returns `false`' do + expect(helper.cascading_namespace_setting_locked?(attribute, nil)).to eq(false) + end + end + + context 'when `*_locked?` method does not exist' do + it 'returns `false`' do + expect(helper.cascading_namespace_setting_locked?(:attribute_that_does_not_exist, admin_group)).to eq(false) + end + end + + context 'when `*_locked?` method does exist' do + before do + allow(admin_group.namespace_settings).to receive(:delayed_project_removal_locked?).and_return(true) + end + + it 'calls corresponding `*_locked?` method' do + helper.cascading_namespace_setting_locked?(attribute, admin_group, include_self: true) + + expect(admin_group.namespace_settings).to have_received(:delayed_project_removal_locked?).with(include_self: true) + end + end + end end diff --git a/spec/lib/gitlab/integrations/sti_type_spec.rb b/spec/lib/gitlab/integrations/sti_type_spec.rb new file mode 100644 index 00000000000..7a023d6041c --- /dev/null +++ b/spec/lib/gitlab/integrations/sti_type_spec.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Integrations::StiType do + let(:types) { ['AsanaService', 'Integrations::Asana', Integrations::Asana] } + + describe '#serialize' do + context 'SQL SELECT' do + let(:expected_sql) do + <<~SQL.strip + SELECT "services".* FROM "services" WHERE "services"."type" = 'AsanaService' + SQL + end + + it 'forms SQL SELECT statements correctly' do + sql_statements = types.map do |type| + Service.where(type: type).to_sql + end + + expect(sql_statements).to all(eq(expected_sql)) + end + end + + context 'SQL CREATE' do + let(:expected_sql) do + <<~SQL.strip + INSERT INTO "services" ("type") VALUES ('AsanaService') + SQL + end + + it 'forms SQL CREATE statements correctly' do + sql_statements = types.map do |type| + record = ActiveRecord::QueryRecorder.new { Service.insert({ type: type }) } + record.log.first + end + + expect(sql_statements).to all(include(expected_sql)) + end + end + + context 'SQL UPDATE' do + let(:expected_sql) do + <<~SQL.strip + UPDATE "services" SET "type" = 'AsanaService' + SQL + end + + let_it_be(:service) { create(:service) } + + it 'forms SQL UPDATE statements correctly' do + sql_statements = types.map do |type| + record = ActiveRecord::QueryRecorder.new { service.update_column(:type, type) } + record.log.first + end + + expect(sql_statements).to all(include(expected_sql)) + end + end + + context 'SQL DELETE' do + let(:expected_sql) do + <<~SQL.strip + DELETE FROM "services" WHERE "services"."type" = 'AsanaService' + SQL + end + + let(:service) { create(:service) } + + it 'forms SQL DELETE statements correctly' do + sql_statements = types.map do |type| + record = ActiveRecord::QueryRecorder.new { Service.delete_by(type: type) } + record.log.first + end + + expect(sql_statements).to all(match(expected_sql)) + end + end + end + + describe '#deserialize' do + specify 'it deserializes type correctly', :aggregate_failures do + types.each do |type| + service = create(:service, type: type) + + expect(service.type).to eq('AsanaService') + end + end + end + + describe '#cast' do + it 'casts type as model correctly', :aggregate_failures do + create(:service, type: 'AsanaService') + + types.each do |type| + expect(Service.find_by(type: type)).to be_kind_of(Integrations::Asana) + end + end + end + + describe '#changed?' do + it 'detects changes correctly', :aggregate_failures do + service = create(:service, type: 'AsanaService') + + types.each do |type| + service.type = type + + expect(service).not_to be_changed + end + + service.type = 'NewType' + + expect(service).to be_changed + end + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_users_using_approve_quick_action_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_users_using_approve_quick_action_metric_spec.rb new file mode 100644 index 00000000000..7adba825a13 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_users_using_approve_quick_action_metric_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountUsersUsingApproveQuickActionMetric, :clean_gitlab_redis_shared_state do + before do + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(:i_quickactions_approve, values: 1, time: 1.week.ago) + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(:i_quickactions_approve, values: 1, time: 2.weeks.ago) + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(:i_quickactions_approve, values: 2, time: 2.weeks.ago) + Gitlab::UsageDataCounters::HLLRedisCounter.track_event(:i_quickactions_approve, values: 2, time: 2.months.ago) + end + + it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', data_source: 'redis_hll' }, 2 + it_behaves_like 'a correct instrumented metric value', { time_frame: '7d', data_source: 'redis_hll' }, 1 +end diff --git a/spec/lib/gitlab/usage_data_metrics_spec.rb b/spec/lib/gitlab/usage_data_metrics_spec.rb index 684f0bf17a1..2692e70cabf 100644 --- a/spec/lib/gitlab/usage_data_metrics_spec.rb +++ b/spec/lib/gitlab/usage_data_metrics_spec.rb @@ -25,6 +25,11 @@ RSpec.describe Gitlab::UsageDataMetrics do it 'includes counts keys' do expect(subject[:counts]).to include(:boards) end + + it 'includes i_quickactions_approve monthly and weekly key' do + expect(subject[:redis_hll_counters][:quickactions]).to include(:i_quickactions_approve_monthly) + expect(subject[:redis_hll_counters][:quickactions]).to include(:i_quickactions_approve_weekly) + end end end end diff --git a/spec/lib/sidebars/menu_spec.rb b/spec/lib/sidebars/menu_spec.rb index 53483f0c924..7dcf1940442 100644 --- a/spec/lib/sidebars/menu_spec.rb +++ b/spec/lib/sidebars/menu_spec.rb @@ -5,15 +5,18 @@ require 'spec_helper' RSpec.describe Sidebars::Menu do let(:menu) { described_class.new(context) } let(:context) { Sidebars::Context.new(current_user: nil, container: nil) } + let(:nil_menu_item) { Sidebars::NilMenuItem.new(item_id: :foo) } describe '#all_active_routes' do it 'gathers all active routes of items and the current menu' do menu.add_item(Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: { path: %w(bar test) })) menu.add_item(Sidebars::MenuItem.new(title: 'foo2', link: 'foo2', active_routes: { controller: 'fooc' })) menu.add_item(Sidebars::MenuItem.new(title: 'foo3', link: 'foo3', active_routes: { controller: 'barc' })) + menu.add_item(nil_menu_item) allow(menu).to receive(:active_routes).and_return({ path: 'foo' }) + expect(menu).to receive(:renderable_items).and_call_original expect(menu.all_active_routes).to eq({ path: %w(foo bar test), controller: %w(fooc barc) }) end end @@ -31,6 +34,60 @@ RSpec.describe Sidebars::Menu do expect(menu.render?).to be true end + + context 'when menu items are NilMenuItem' do + it 'returns false' do + menu.add_item(nil_menu_item) + + expect(menu.render?).to be false + end + end + end + end + + describe '#has_items?' do + it 'returns true when there are regular menu items' do + menu.add_item(Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {})) + + expect(menu.has_items?).to be true + end + + it 'returns true when there are nil menu items' do + menu.add_item(nil_menu_item) + + expect(menu.has_items?).to be true + end + end + + describe '#has_renderable_items?' do + it 'returns true when there are regular menu items' do + menu.add_item(Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {})) + + expect(menu.has_renderable_items?).to be true + end + + it 'returns false when there are nil menu items' do + menu.add_item(nil_menu_item) + + expect(menu.has_renderable_items?).to be false + end + + it 'returns true when there are both regular and nil menu items' do + menu.add_item(Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {})) + menu.add_item(nil_menu_item) + + expect(menu.has_renderable_items?).to be true + end + end + + describe '#renderable_items' do + it 'returns only regular menu items' do + item = Sidebars::MenuItem.new(title: 'foo1', link: 'foo1', active_routes: {}) + menu.add_item(item) + menu.add_item(nil_menu_item) + + expect(menu.renderable_items.size).to eq 1 + expect(menu.renderable_items.first).to eq item end end diff --git a/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb b/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb index c109631fabe..87ef9e162e2 100644 --- a/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/analytics_menu_spec.rb @@ -26,7 +26,7 @@ RSpec.describe Sidebars::Projects::Menus::AnalyticsMenu do context 'when menu does not have any menu items' do it 'returns false' do - allow(subject).to receive(:has_items?).and_return(false) + allow(subject).to receive(:has_renderable_items?).and_return(false) expect(subject.render?).to be false end @@ -49,13 +49,13 @@ RSpec.describe Sidebars::Projects::Menus::AnalyticsMenu do it 'returns link to the the first visible menu item' do allow(subject).to receive(:cycle_analytics_menu_item).and_return(nil) - expect(subject.link).to eq subject.items.first.link + expect(subject.link).to eq subject.renderable_items.first.link end end end describe 'Menu items' do - subject { described_class.new(context).items.index { |e| e.item_id == item_id } } + subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } describe 'CI/CD' do let(:item_id) { :ci_cd_analytics } diff --git a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb index 89b03e1c918..dee2716e4c2 100644 --- a/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/ci_cd_menu_spec.rb @@ -26,40 +26,44 @@ RSpec.describe Sidebars::Projects::Menus::CiCdMenu do end end - describe 'Pipelines Editor' do - subject { described_class.new(context).items.index { |e| e.item_id == :pipelines_editor } } + describe 'Menu items' do + subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } - context 'when user cannot view pipeline editor' do - let(:can_view_pipeline_editor) { false } + describe 'Pipelines Editor' do + let(:item_id) { :pipelines_editor } - it 'does not include pipeline editor menu item' do - is_expected.to be_nil + context 'when user cannot view pipeline editor' do + let(:can_view_pipeline_editor) { false } + + it 'does not include pipeline editor menu item' do + is_expected.to be_nil + end end - end - context 'when user can view pipeline editor' do - it 'includes pipeline editor menu item' do - is_expected.not_to be_nil + context 'when user can view pipeline editor' do + it 'includes pipeline editor menu item' do + is_expected.not_to be_nil + end end end - end - describe 'Artifacts' do - subject { described_class.new(context).items.index { |e| e.item_id == :artifacts } } + describe 'Artifacts' do + let(:item_id) { :artifacts } - context 'when feature flag :artifacts_management_page is disabled' do - it 'does not include artifacts menu item' do - stub_feature_flags(artifacts_management_page: false) + context 'when feature flag :artifacts_management_page is disabled' do + it 'does not include artifacts menu item' do + stub_feature_flags(artifacts_management_page: false) - is_expected.to be_nil + is_expected.to be_nil + end end - end - context 'when feature flag :artifacts_management_page is enabled' do - it 'includes artifacts menu item' do - stub_feature_flags(artifacts_management_page: true) + context 'when feature flag :artifacts_management_page is enabled' do + it 'includes artifacts menu item' do + stub_feature_flags(artifacts_management_page: true) - is_expected.not_to be_nil + is_expected.not_to be_nil + end end end end diff --git a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb index c50696f0883..0ecb328efd1 100644 --- a/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/confluence_menu_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Sidebars::Projects::Menus::ConfluenceMenu do end it 'does not contain any sub menu' do - expect(subject.items).to be_empty + expect(subject.has_items?).to be false end end end diff --git a/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb b/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb index 65d2a866393..5d62eebca1c 100644 --- a/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/external_issue_tracker_menu_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Sidebars::Projects::Menus::ExternalIssueTrackerMenu do subject { described_class.new(context) } it 'does not contain any sub menu' do - expect(subject.items).to be_empty + expect(subject.has_items?).to be false end describe '#render?' do diff --git a/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb b/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb index b12f31017be..19efd2bbd6b 100644 --- a/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/external_wiki_menu_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Sidebars::Projects::Menus::ExternalWikiMenu do subject { described_class.new(context) } it 'does not contain any sub menu' do - expect(subject.items).to be_empty + expect(subject.has_items?).to be false end describe '#render?' do diff --git a/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb b/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb index f7cb0adbb66..44013898721 100644 --- a/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/hidden_menu_spec.rb @@ -13,7 +13,7 @@ RSpec.describe Sidebars::Projects::Menus::HiddenMenu do context 'when menu does not have any menu items' do it 'returns false' do - allow(subject).to receive(:has_items?).and_return(false) + allow(subject).to receive(:has_renderable_items?).and_return(false) expect(subject.render?).to be false end @@ -27,7 +27,7 @@ RSpec.describe Sidebars::Projects::Menus::HiddenMenu do end describe 'Menu items' do - subject { described_class.new(context).items.index { |e| e.item_id == item_id } } + subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } shared_examples 'access rights checks' do specify { is_expected.not_to be_nil } diff --git a/spec/lib/sidebars/projects/menus/labels_menu_spec.rb b/spec/lib/sidebars/projects/menus/labels_menu_spec.rb index 58d82293b13..588119746cf 100644 --- a/spec/lib/sidebars/projects/menus/labels_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/labels_menu_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Sidebars::Projects::Menus::LabelsMenu do subject { described_class.new(context) } it 'does not contain any sub menu' do - expect(subject.items).to be_empty + expect(subject.has_items?).to eq false end describe '#render?' do diff --git a/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb b/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb index dc1aecc6546..ef5ae550551 100644 --- a/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Sidebars::Projects::Menus::LearnGitlabMenu do subject { described_class.new(context) } it 'does not contain any sub menu' do - expect(subject.instance_variable_get(:@items)).to be_empty + expect(subject.has_items?).to be false end describe '#nav_link_html_options' do diff --git a/spec/lib/sidebars/projects/menus/operations_menu_spec.rb b/spec/lib/sidebars/projects/menus/operations_menu_spec.rb index 6e764dbb83a..5f52ae0fd7a 100644 --- a/spec/lib/sidebars/projects/menus/operations_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/operations_menu_spec.rb @@ -21,9 +21,9 @@ RSpec.describe Sidebars::Projects::Menus::OperationsMenu do end context 'when operation feature is enabled' do - context 'when menu does not have any menu items' do + context 'when menu does not have any renderable menu items' do it 'returns false' do - allow(subject).to receive(:has_items?).and_return(false) + allow(subject).to receive(:has_renderable_items?).and_return(false) expect(subject.render?).to be false end @@ -54,7 +54,7 @@ RSpec.describe Sidebars::Projects::Menus::OperationsMenu do end context 'Menu items' do - subject { described_class.new(context).items.index { |e| e.item_id == item_id } } + subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } describe 'Metrics Dashboard' do let(:item_id) { :metrics } diff --git a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb index fc0d7710a5e..731dd5eca23 100644 --- a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do describe '#render?' do context 'when menu does not have any menu item to show' do it 'returns false' do - allow(subject).to receive(:has_items?).and_return(false) + allow(subject).to receive(:has_renderable_items?).and_return(false) expect(subject.render?).to eq false end @@ -36,7 +36,7 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do context 'when Packages Registry is visible' do it 'menu link points to Packages Registry page' do - expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :packages_registry }.link + expect(subject.link).to eq described_class.new(context).renderable_items.find { |i| i.item_id == :packages_registry }.link end end @@ -44,95 +44,99 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do let(:packages_enabled) { false } it 'menu link points to Container Registry page' do - expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :container_registry }.link + expect(subject.link).to eq described_class.new(context).renderable_items.find { |i| i.item_id == :container_registry }.link end context 'when Container Registry is not visible' do let(:registry_enabled) { false } it 'menu link points to Infrastructure Registry page' do - expect(subject.link).to eq described_class.new(context).items.find { |i| i.item_id == :infrastructure_registry }.link + expect(subject.link).to eq described_class.new(context).renderable_items.find { |i| i.item_id == :infrastructure_registry }.link end end end end - describe 'Packages Registry' do - subject { described_class.new(context).items.find { |i| i.item_id == :packages_registry }} + describe 'Menu items' do + subject { described_class.new(context).renderable_items.find { |i| i.item_id == item_id } } - context 'when user can read packages' do - context 'when config package setting is disabled' do - it 'the menu item is not added to list of menu items' do - stub_config(packages: { enabled: false }) + describe 'Packages Registry' do + let(:item_id) { :packages_registry } - is_expected.to be_nil + context 'when user can read packages' do + context 'when config package setting is disabled' do + it 'the menu item is not added to list of menu items' do + stub_config(packages: { enabled: false }) + + is_expected.to be_nil + end end - end - context 'when config package setting is enabled' do - it 'the menu item is added to list of menu items' do - stub_config(packages: { enabled: true }) + context 'when config package setting is enabled' do + it 'the menu item is added to list of menu items' do + stub_config(packages: { enabled: true }) - is_expected.not_to be_nil + is_expected.not_to be_nil + end end end - end - context 'when user cannot read packages' do - let(:user) { nil } + context 'when user cannot read packages' do + let(:user) { nil } - it 'the menu item is not added to list of menu items' do - is_expected.to be_nil + it 'the menu item is not added to list of menu items' do + is_expected.to be_nil + end end end - end - describe 'Container Registry' do - subject { described_class.new(context).items.find { |i| i.item_id == :container_registry }} + describe 'Container Registry' do + let(:item_id) { :container_registry } - context 'when user can read container images' do - context 'when config registry setting is disabled' do - it 'the menu item is not added to list of menu items' do - stub_container_registry_config(enabled: false) + context 'when user can read container images' do + context 'when config registry setting is disabled' do + it 'the menu item is not added to list of menu items' do + stub_container_registry_config(enabled: false) - is_expected.to be_nil + is_expected.to be_nil + end end - end - context 'when config registry setting is enabled' do - it 'the menu item is added to list of menu items' do - stub_container_registry_config(enabled: true) + context 'when config registry setting is enabled' do + it 'the menu item is added to list of menu items' do + stub_container_registry_config(enabled: true) - is_expected.not_to be_nil + is_expected.not_to be_nil + end end end - end - context 'when user cannot read container images' do - let(:user) { nil } + context 'when user cannot read container images' do + let(:user) { nil } - it 'the menu item is not added to list of menu items' do - is_expected.to be_nil + it 'the menu item is not added to list of menu items' do + is_expected.to be_nil + end end end - end - describe 'Infrastructure Registry' do - subject { described_class.new(context).items.find { |i| i.item_id == :infrastructure_registry }} + describe 'Infrastructure Registry' do + let(:item_id) { :infrastructure_registry } - context 'when feature flag :infrastructure_registry_page is enabled' do - it 'the menu item is added to list of menu items' do - stub_feature_flags(infrastructure_registry_page: true) + context 'when feature flag :infrastructure_registry_page is enabled' do + it 'the menu item is added to list of menu items' do + stub_feature_flags(infrastructure_registry_page: true) - is_expected.not_to be_nil + is_expected.not_to be_nil + end end - end - context 'when feature flag :infrastructure_registry_page is disabled' do - it 'the menu item is not added to list of menu items' do - stub_feature_flags(infrastructure_registry_page: false) + context 'when feature flag :infrastructure_registry_page is disabled' do + it 'the menu item is not added to list of menu items' do + stub_feature_flags(infrastructure_registry_page: false) - is_expected.to be_nil + is_expected.to be_nil + end end end end diff --git a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb index ddf9e779219..ed162910bdd 100644 --- a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) } describe 'Releases' do - subject { described_class.new(context).items.index { |e| e.item_id == :releases } } + subject { described_class.new(context).renderable_items.index { |e| e.item_id == :releases } } context 'when project repository is empty' do it 'does not include releases menu item' do diff --git a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb index 85de46d1583..b87d991e434 100644 --- a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb @@ -11,14 +11,14 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu do describe '#render?' do it 'returns false when menu does not have any menu items' do - allow(subject).to receive(:has_items?).and_return(false) + allow(subject).to receive(:has_renderable_items?).and_return(false) expect(subject.render?).to be false end end describe 'Menu items' do - subject { described_class.new(context).items.index { |e| e.item_id == item_id } } + subject { described_class.new(context).renderable_items.index { |e| e.item_id == item_id } } shared_examples 'access rights checks' do specify { is_expected.not_to be_nil } diff --git a/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb b/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb index 21336d70ad2..41447ee24a9 100644 --- a/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/wiki_menu_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Sidebars::Projects::Menus::WikiMenu do subject { described_class.new(context) } it 'does not contain any sub menu' do - expect(subject.items).to be_empty + expect(subject.has_items?).to be false end describe '#render?' do diff --git a/spec/models/project_services/asana_service_spec.rb b/spec/models/integrations/asana_spec.rb index 7a6fe4b1537..4473478910a 100644 --- a/spec/models/project_services/asana_service_spec.rb +++ b/spec/models/integrations/asana_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe AsanaService do +RSpec.describe Integrations::Asana do describe 'Associations' do it { is_expected.to belong_to :project } it { is_expected.to have_one :service_hook } @@ -54,7 +54,7 @@ RSpec.describe AsanaService do d1 = double('Asana::Resources::Task') expect(d1).to receive(:add_comment).with(text: expected_message) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, gid).once.and_return(d1) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, gid).once.and_return(d1) @asana.execute(data) end @@ -64,7 +64,7 @@ RSpec.describe AsanaService do d1 = double('Asana::Resources::Task') expect(d1).to receive(:add_comment) expect(d1).to receive(:update).with(completed: true) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(d1) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456789').once.and_return(d1) @asana.execute(data) end @@ -74,7 +74,7 @@ RSpec.describe AsanaService do d1 = double('Asana::Resources::Task') expect(d1).to receive(:add_comment) expect(d1).to receive(:update).with(completed: true) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d1) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d1) @asana.execute(data) end @@ -88,25 +88,25 @@ RSpec.describe AsanaService do d1 = double('Asana::Resources::Task') expect(d1).to receive(:add_comment) expect(d1).to receive(:update).with(completed: true) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '123').once.and_return(d1) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '123').once.and_return(d1) d2 = double('Asana::Resources::Task') expect(d2).to receive(:add_comment) expect(d2).to receive(:update).with(completed: true) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '456').once.and_return(d2) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '456').once.and_return(d2) d3 = double('Asana::Resources::Task') expect(d3).to receive(:add_comment) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '789').once.and_return(d3) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '789').once.and_return(d3) d4 = double('Asana::Resources::Task') expect(d4).to receive(:add_comment) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d4) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '42').once.and_return(d4) d5 = double('Asana::Resources::Task') expect(d5).to receive(:add_comment) expect(d5).to receive(:update).with(completed: true) - expect(Asana::Resources::Task).to receive(:find_by_id).with(anything, '12').once.and_return(d5) + expect(::Asana::Resources::Task).to receive(:find_by_id).with(anything, '12').once.and_return(d5) @asana.execute(data) end diff --git a/spec/models/project_services/assembla_service_spec.rb b/spec/models/integrations/assembla_spec.rb index 207add6f090..bf9033416e9 100644 --- a/spec/models/project_services/assembla_service_spec.rb +++ b/spec/models/integrations/assembla_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe AssemblaService do +RSpec.describe Integrations::Assembla do include StubRequests describe "Associations" do diff --git a/spec/models/project_services/bamboo_service_spec.rb b/spec/models/integrations/bamboo_spec.rb index 45afbcca96d..0ba1595bbd8 100644 --- a/spec/models/project_services/bamboo_service_spec.rb +++ b/spec/models/integrations/bamboo_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BambooService, :use_clean_rails_memory_store_caching do +RSpec.describe Integrations::Bamboo, :use_clean_rails_memory_store_caching do include ReactiveCachingHelpers include StubRequests diff --git a/spec/models/project_services/chat_notification_service_spec.rb b/spec/models/project_services/chat_notification_service_spec.rb index 7f06c8a87eb..62f97873a06 100644 --- a/spec/models/project_services/chat_notification_service_spec.rb +++ b/spec/models/project_services/chat_notification_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe ChatNotificationService do end describe 'validations' do - it { is_expected.to validate_inclusion_of(:labels_to_be_notified_behavior).in_array(%w[match_any match_all]) } + it { is_expected.to validate_inclusion_of(:labels_to_be_notified_behavior).in_array(%w[match_any match_all]).allow_blank } end describe '#can_test?' do @@ -127,6 +127,22 @@ RSpec.describe ChatNotificationService do end end + context 'when labels_to_be_notified_behavior is blank' do + subject(:chat_service) { described_class.new(labels_to_be_notified: label_filter, labels_to_be_notified_behavior: '') } + + context 'no matching labels' do + let(:label_filter) { '~some random label' } + + it_behaves_like 'does not notify the chat service' + end + + context 'only one label matches' do + let(:label_filter) { '~some random label, ~Bug' } + + it_behaves_like 'notifies the chat service' + end + end + context 'when labels_to_be_notified_behavior is match_any' do subject(:chat_service) do described_class.new( diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 6b18d1f0cfa..e471e50498d 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -248,7 +248,7 @@ RSpec.describe Service do describe '.find_or_initialize_all_non_project_specific' do shared_examples 'service instances' do it 'returns the available service instances' do - expect(Service.find_or_initialize_all_non_project_specific(Service.for_instance).pluck(:type)).to match_array(Service.available_services_types(include_project_specific: false)) + expect(Service.find_or_initialize_all_non_project_specific(Service.for_instance).map(&:to_param)).to match_array(Service.available_services_names(include_project_specific: false)) end it 'does not create service instances' do @@ -666,9 +666,22 @@ RSpec.describe Service do end end + describe '.service_name_to_model' do + it 'returns the model for the given service name', :aggregate_failures do + expect(described_class.service_name_to_model('asana')).to eq(Integrations::Asana) + # TODO We can remove this test when all models have been namespaced: + # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60968#note_570994955 + expect(described_class.service_name_to_model('youtrack')).to eq(YoutrackService) + end + + it 'raises an error if service name is invalid' do + expect { described_class.service_name_to_model('foo') }.to raise_exception(NameError, /uninitialized constant FooService/) + end + end + describe "{property}_changed?" do let(:service) do - BambooService.create( + Integrations::Bamboo.create( project: project, properties: { bamboo_url: 'http://gitlab.com', @@ -708,7 +721,7 @@ RSpec.describe Service do describe "{property}_touched?" do let(:service) do - BambooService.create( + Integrations::Bamboo.create( project: project, properties: { bamboo_url: 'http://gitlab.com', @@ -748,7 +761,7 @@ RSpec.describe Service do describe "{property}_was" do let(:service) do - BambooService.create( + Integrations::Bamboo.create( project: project, properties: { bamboo_url: 'http://gitlab.com', diff --git a/spec/services/admin/propagate_service_template_spec.rb b/spec/services/admin/propagate_service_template_spec.rb index d95d31ceaea..b3ca7601cd6 100644 --- a/spec/services/admin/propagate_service_template_spec.rb +++ b/spec/services/admin/propagate_service_template_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Admin::PropagateServiceTemplate do context 'with a project that has another service' do before do - BambooService.create!( + Integrations::Bamboo.create!( active: true, project: project, properties: { diff --git a/spec/support/shared_contexts/services_shared_context.rb b/spec/support/shared_contexts/services_shared_context.rb index 4e943a40034..13b6b9283c3 100644 --- a/spec/support/shared_contexts/services_shared_context.rb +++ b/spec/support/shared_contexts/services_shared_context.rb @@ -6,7 +6,7 @@ Service.available_services_names.each do |service| let(:dashed_service) { service.dasherize } let(:service_method) { "#{service}_service".to_sym } - let(:service_klass) { "#{service}_service".classify.constantize } + let(:service_klass) { Service.service_name_to_model(service) } let(:service_instance) { service_klass.new } let(:service_fields) { service_instance.fields } let(:service_attrs_list) { service_fields.inject([]) {|arr, hash| arr << hash[:name].to_sym } } diff --git a/spec/views/devise/shared/_signup_box.html.haml_spec.rb b/spec/views/devise/shared/_signup_box.html.haml_spec.rb new file mode 100644 index 00000000000..b73e32fa765 --- /dev/null +++ b/spec/views/devise/shared/_signup_box.html.haml_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'devise/shared/_signup_box' do + before do + stub_devise + allow(view).to receive(:show_omniauth_providers).and_return(false) + allow(view).to receive(:url).and_return('_url_') + allow(view).to receive(:terms_path).and_return('_terms_path_') + allow(view).to receive(:button_text).and_return('_button_text_') + allow(view).to receive(:suggestion_path).and_return('_suggestion_path_') + stub_template 'devise/shared/_error_messages.html.haml' => '' + end + + context 'when terms are enforced' do + before do + allow(Gitlab::CurrentSettings.current_application_settings).to receive(:enforce_terms?).and_return(true) + end + + it 'shows expected text with placeholders' do + render + + expect(rendered).to have_content('By clicking _button_text_') + expect(rendered).to have_link('Terms of Use and Privacy Policy') + end + + context 'when on .com' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return(true) + end + + it 'shows expected GitLab text' do + render + + expect(rendered).to have_content('I have read and accepted the GitLab Terms') + end + end + + context 'when not on .com' do + before do + allow(Gitlab).to receive(:dev_env_or_com?).and_return(false) + end + + it 'shows expected text without GitLab' do + render + + expect(rendered).to have_content('I have read and accepted the Terms') + end + end + end + + context 'when terms are not enforced' do + before do + allow(Gitlab::CurrentSettings.current_application_settings).to receive(:enforce_terms?).and_return(false) + allow(Gitlab).to receive(:dev_env_or_com?).and_return(true) + end + + it 'shows expected text with placeholders' do + render + + expect(rendered).not_to have_content('By clicking') + end + end + + def stub_devise + allow(view).to receive(:devise_mapping).and_return(Devise.mappings[:user]) + allow(view).to receive(:resource).and_return(spy) + allow(view).to receive(:resource_name).and_return(:user) + end +end diff --git a/spec/views/groups/show.html.haml_spec.rb b/spec/views/groups/show.html.haml_spec.rb new file mode 100644 index 00000000000..f40b03fda2a --- /dev/null +++ b/spec/views/groups/show.html.haml_spec.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'groups/edit.html.haml' do + include Devise::Test::ControllerHelpers + + describe '"Share with group lock" setting' do + let(:root_owner) { create(:user) } + let(:root_group) { create(:group) } + + before do + root_group.add_owner(root_owner) + end + + shared_examples_for '"Share with group lock" setting' do |checkbox_options| + it 'has the correct label, help text, and checkbox options' do + assign(:group, test_group) + allow(view).to receive(:can?).with(test_user, :admin_group, test_group).and_return(true) + allow(view).to receive(:can_change_group_visibility_level?).and_return(false) + allow(view).to receive(:current_user).and_return(test_user) + expect(view).to receive(:can_change_share_with_group_lock?).and_return(!checkbox_options[:disabled]) + expect(view).to receive(:share_with_group_lock_help_text).and_return('help text here') + + render + + expect(rendered).to have_content("Prevent sharing a project within #{test_group.name} with other groups") + expect(rendered).to have_css('.js-descr', text: 'help text here') + expect(rendered).to have_field('group_share_with_group_lock', **checkbox_options) + end + end + + context 'for a root group' do + let(:test_group) { root_group } + let(:test_user) { root_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false } + end + + context 'for a subgroup' do + let!(:subgroup) { create(:group, parent: root_group) } + let(:sub_owner) { create(:user) } + let(:test_group) { subgroup } + + context 'when the root_group has "Share with group lock" disabled' do + context 'when the subgroup has "Share with group lock" disabled' do + context 'as the root_owner' do + let(:test_user) { root_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false } + end + + context 'as the sub_owner' do + let(:test_user) { sub_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false } + end + end + + context 'when the subgroup has "Share with group lock" enabled' do + before do + subgroup.update_column(:share_with_group_lock, true) + end + + context 'as the root_owner' do + let(:test_user) { root_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: true } + end + + context 'as the sub_owner' do + let(:test_user) { sub_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: true } + end + end + end + + context 'when the root_group has "Share with group lock" enabled' do + before do + root_group.update_column(:share_with_group_lock, true) + end + + context 'when the subgroup has "Share with group lock" disabled (parent overridden)' do + context 'as the root_owner' do + let(:test_user) { root_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false } + end + + context 'as the sub_owner' do + let(:test_user) { sub_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: false } + end + end + + context 'when the subgroup has "Share with group lock" enabled (same as parent)' do + before do + subgroup.update_column(:share_with_group_lock, true) + end + + context 'as the root_owner' do + let(:test_user) { root_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: false, checked: true } + end + + context 'as the sub_owner' do + let(:test_user) { sub_owner } + + it_behaves_like '"Share with group lock" setting', { disabled: true, checked: true } + end + end + end + end + end +end |