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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-10-19 21:07:43 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-10-19 21:07:43 +0300
commit1e1012d3d28c426637eecc0909c415fe2c8b7c3a (patch)
treed230780752bb3b98cf4f3ede1c6f8e98c9a238c7 /spec
parent3c55affa6684311ca73bc4e3d3bfb17b7541f63b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/profiles_controller_spec.rb10
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb4
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb17
-rw-r--r--spec/features/users/signup_spec.rb2
-rw-r--r--spec/finders/projects/ml/model_finder_spec.rb55
-rw-r--r--spec/frontend/ml/model_registry/routes/models/index/components/ml_models_index_spec.js11
-rw-r--r--spec/frontend/ml/model_registry/routes/models/index/components/search_bar_spec.js86
-rw-r--r--spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap2
-rw-r--r--spec/frontend/silent_mode_settings/components/app_spec.js13
-rw-r--r--spec/helpers/application_helper_spec.rb15
-rw-r--r--spec/helpers/ci/status_helper_spec.rb4
-rw-r--r--spec/lib/gitlab/group_search_results_spec.rb2
-rw-r--r--spec/lib/gitlab/search_results_spec.rb2
-rw-r--r--spec/models/user_detail_spec.rb23
-rw-r--r--spec/models/user_spec.rb3
-rw-r--r--spec/requests/projects/ml/models_controller_spec.rb18
-rw-r--r--spec/rubocop/cop/gitlab/feature_available_usage_spec.rb2
-rw-r--r--spec/support/helpers/stub_saas_features.rb4
-rw-r--r--spec/support/shared_examples/features/content_editor_shared_examples.rb38
-rw-r--r--spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb5
-rw-r--r--spec/support_specs/helpers/stub_saas_features_spec.rb6
21 files changed, 280 insertions, 42 deletions
diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb
index 2bcb47f97ab..4f350ddf1ef 100644
--- a/spec/controllers/profiles_controller_spec.rb
+++ b/spec/controllers/profiles_controller_spec.rb
@@ -128,6 +128,16 @@ RSpec.describe ProfilesController, :request_store do
expect(user.reload.discord).to eq(discord_user_id)
expect(response).to have_gitlab_http_status(:found)
end
+
+ it 'allows updating user specified mastodon username', :aggregate_failures do
+ mastodon_username = '@robin@example.com'
+ sign_in(user)
+
+ put :update, params: { user: { mastodon: mastodon_username } }
+
+ expect(user.reload.mastodon).to eq(mastodon_username)
+ expect(response).to have_gitlab_http_status(:found)
+ end
end
describe 'GET audit_log' do
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index a81a99771cc..d27f3ffebe6 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -33,7 +33,9 @@ RSpec.describe "User comments on issue", :js, feature_category: :team_planning d
end
end
- it_behaves_like 'edits content using the content editor'
+ # do not test quick actions here since guest users don't have permission
+ # to execute all quick actions
+ it_behaves_like 'edits content using the content editor', { with_quick_actions: false }
it "adds comment with code block" do
code_block_content = "Command [1]: /usr/local/bin/git , see [text](doc/text)"
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 29b44bf165d..a407e7fd112 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -139,8 +139,6 @@ RSpec.describe "User creates issue", feature_category: :team_planning do
end
end
- it_behaves_like 'edits content using the content editor'
-
context 'dropzone upload file', :js do
before do
visit new_project_issue_path(project)
@@ -308,6 +306,21 @@ RSpec.describe "User creates issue", feature_category: :team_planning do
end
end
+ context 'when signed in as a maintainer', :js do
+ let_it_be(:project) { create(:project) }
+
+ before_all do
+ project.add_maintainer(user)
+ end
+
+ before do
+ sign_in(user)
+ visit(new_project_issue_path(project))
+ end
+
+ it_behaves_like 'edits content using the content editor'
+ end
+
context "when signed in as user with special characters in their name" do
let(:user_special) { create(:user, name: "Jon O'Shea") }
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index 968308938d1..d873c4846fd 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -54,7 +54,7 @@ RSpec.shared_examples 'Signup name validation' do |field, max_length, label|
end
end
-RSpec.describe 'Signup', :js, feature_category: :user_profile do
+RSpec.describe 'Signup', :js, feature_category: :user_management do
include TermsHelper
let(:new_user) { build_stubbed(:user) }
diff --git a/spec/finders/projects/ml/model_finder_spec.rb b/spec/finders/projects/ml/model_finder_spec.rb
index 1d869e1792d..4104507445e 100644
--- a/spec/finders/projects/ml/model_finder_spec.rb
+++ b/spec/finders/projects/ml/model_finder_spec.rb
@@ -6,24 +6,55 @@ RSpec.describe Projects::Ml::ModelFinder, feature_category: :mlops do
let_it_be(:project) { create(:project) }
let_it_be(:model1) { create(:ml_models, :with_versions, project: project) }
let_it_be(:model2) { create(:ml_models, :with_versions, project: project) }
- let_it_be(:model3) { create(:ml_models) }
+ let_it_be(:model3) { create(:ml_models, name: "#{model1.name}_1", project: project) }
+ let_it_be(:other_model) { create(:ml_models) }
+ let_it_be(:project_models) { [model1, model2, model3] }
- subject(:models) { described_class.new(project).execute.to_a }
+ let(:params) { {} }
- it 'returns models for project' do
- is_expected.to match_array([model1, model2])
- end
+ subject(:models) { described_class.new(project, params).execute.to_a }
+
+ describe 'default params' do
+ it 'returns models for project ordered by id' do
+ is_expected.to eq([model3, model2, model1])
+ end
+
+ it 'including the latest version', :aggregate_failures do
+ expect(models[0].association_cached?(:latest_version)).to be(true)
+ expect(models[1].association_cached?(:latest_version)).to be(true)
+ end
+
+ it 'does not return models belonging to a different project' do
+ is_expected.not_to include(other_model)
+ end
- it 'including the latest version', :aggregate_failures do
- expect(models[0].association_cached?(:latest_version)).to be(true)
- expect(models[1].association_cached?(:latest_version)).to be(true)
+ it 'includes version count' do
+ expect(models[0].version_count).to be(models[0].versions.count)
+ end
end
- it 'does not return models belonging to a different project' do
- is_expected.not_to include(model3)
+ context 'when name is passed' do
+ let(:params) { { name: model1.name } }
+
+ it 'searches by name' do
+ is_expected.to match_array([model1, model3])
+ end
end
- it 'includes version count' do
- expect(models[0].version_count).to be(models[0].versions.count)
+ describe 'sorting' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:test_case, :order_by, :direction, :expected_order) do
+ 'default params' | nil | nil | [2, 1, 0]
+ 'ascending order' | 'id' | 'ASC' | [0, 1, 2]
+ 'by column' | 'name' | 'ASC' | [0, 2, 1]
+ 'invalid sort' | nil | 'UP' | [2, 1, 0]
+ 'invalid order by' | 'INVALID' | nil | [2, 1, 0]
+ end
+ with_them do
+ let(:params) { { order_by: order_by, sort: direction } }
+
+ it { expect(subject).to eq(project_models.values_at(*expected_order)) }
+ end
end
end
diff --git a/spec/frontend/ml/model_registry/routes/models/index/components/ml_models_index_spec.js b/spec/frontend/ml/model_registry/routes/models/index/components/ml_models_index_spec.js
index c1b9aef9634..fc8e7aef73e 100644
--- a/spec/frontend/ml/model_registry/routes/models/index/components/ml_models_index_spec.js
+++ b/spec/frontend/ml/model_registry/routes/models/index/components/ml_models_index_spec.js
@@ -3,6 +3,8 @@ import MlModelsIndexApp from '~/ml/model_registry/routes/models/index';
import ModelRow from '~/ml/model_registry/routes/models/index/components/model_row.vue';
import { TITLE_LABEL, NO_MODELS_LABEL } from '~/ml/model_registry/routes/models/index/translations';
import Pagination from '~/vue_shared/components/incubation/pagination.vue';
+import SearchBar from '~/ml/model_registry/routes/models/index/components/search_bar.vue';
+import { BASE_SORT_FIELDS } from '~/ml/model_registry/routes/models/index/constants';
import { mockModels, startCursor, defaultPageInfo } from './mock_data';
let wrapper;
@@ -14,6 +16,7 @@ const findModelRow = (index) => wrapper.findAllComponents(ModelRow).at(index);
const findPagination = () => wrapper.findComponent(Pagination);
const findTitle = () => wrapper.findByText(TITLE_LABEL);
const findEmptyLabel = () => wrapper.findByText(NO_MODELS_LABEL);
+const findSearchBar = () => wrapper.findComponent(SearchBar);
describe('MlModelsIndex', () => {
describe('empty state', () => {
@@ -26,6 +29,10 @@ describe('MlModelsIndex', () => {
it('does not show pagination', () => {
expect(findPagination().exists()).toBe(false);
});
+
+ it('does not show search bar', () => {
+ expect(findSearchBar().exists()).toBe(false);
+ });
});
describe('with data', () => {
@@ -43,6 +50,10 @@ describe('MlModelsIndex', () => {
});
});
+ it('adds a search bar', () => {
+ expect(findSearchBar().props()).toMatchObject({ sortableFields: BASE_SORT_FIELDS });
+ });
+
describe('model list', () => {
it('displays the models', () => {
expect(findModelRow(0).props('model')).toMatchObject(mockModels[0]);
diff --git a/spec/frontend/ml/model_registry/routes/models/index/components/search_bar_spec.js b/spec/frontend/ml/model_registry/routes/models/index/components/search_bar_spec.js
new file mode 100644
index 00000000000..ac8c74bce7f
--- /dev/null
+++ b/spec/frontend/ml/model_registry/routes/models/index/components/search_bar_spec.js
@@ -0,0 +1,86 @@
+import { shallowMount } from '@vue/test-utils';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import * as urlHelpers from '~/lib/utils/url_utility';
+import SearchBar from '~/ml/model_registry/routes/models/index/components/search_bar.vue';
+import { BASE_SORT_FIELDS } from '~/ml/model_registry/routes/models/index/constants';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+
+let wrapper;
+
+const makeUrl = ({ filter = 'query', orderBy = 'name', sort = 'asc' } = {}) =>
+ `https://blah.com/?name=${filter}&orderBy=${orderBy}&sort=${sort}`;
+
+const createWrapper = () => {
+ wrapper = shallowMount(SearchBar, { propsData: { sortableFields: BASE_SORT_FIELDS } });
+};
+
+const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+
+describe('SearchBar', () => {
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ it('passes default filter and sort by to registry search', () => {
+ expect(findRegistrySearch().props()).toMatchObject({
+ filters: [],
+ sorting: {
+ orderBy: 'created_at',
+ sort: 'desc',
+ },
+ sortableFields: BASE_SORT_FIELDS,
+ });
+ });
+
+ it('sets the component filters based on the querystring', () => {
+ const filter = 'A';
+ setWindowLocation(makeUrl({ filter }));
+
+ createWrapper();
+
+ expect(findRegistrySearch().props('filters')).toMatchObject([{ value: { data: filter } }]);
+ });
+
+ it('sets the registry search sort based on the querystring', () => {
+ const orderBy = 'B';
+ const sort = 'C';
+
+ setWindowLocation(makeUrl({ orderBy, sort }));
+
+ createWrapper();
+
+ expect(findRegistrySearch().props('sorting')).toMatchObject({ orderBy, sort: 'c' });
+ });
+
+ describe('Search submit', () => {
+ beforeEach(() => {
+ setWindowLocation(makeUrl());
+ jest.spyOn(urlHelpers, 'visitUrl').mockImplementation(() => {});
+
+ createWrapper();
+ });
+
+ it('On submit, resets the cursor and reloads to correct page', () => {
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(urlHelpers.visitUrl).toHaveBeenCalledTimes(1);
+ expect(urlHelpers.visitUrl).toHaveBeenCalledWith(makeUrl());
+ });
+
+ it('On sorting changed, resets cursor and reloads to correct page', () => {
+ const orderBy = 'created_at';
+ findRegistrySearch().vm.$emit('sorting:changed', { orderBy });
+
+ expect(urlHelpers.visitUrl).toHaveBeenCalledTimes(1);
+ expect(urlHelpers.visitUrl).toHaveBeenCalledWith(makeUrl({ orderBy }));
+ });
+
+ it('On direction changed, reloads to correct page', () => {
+ const sort = 'asc';
+ findRegistrySearch().vm.$emit('sorting:changed', { sort });
+
+ expect(urlHelpers.visitUrl).toHaveBeenCalledTimes(1);
+ expect(urlHelpers.visitUrl).toHaveBeenCalledWith(makeUrl({ sort }));
+ });
+ });
+});
diff --git a/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap b/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
index 1a5301c5525..44b9b44fc77 100644
--- a/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
+++ b/spec/frontend/repository/components/__snapshots__/last_commit_spec.js.snap
@@ -8,7 +8,7 @@ exports[`Repository last commit component renders commit widget 1`] = `
class="commit-actions gl-align-items-center gl-display-flex gl-flex-align gl-flex-direction-row"
>
<div
- class="ci-status-link"
+ class="gl-ml-5"
>
<ci-badge-link-stub
aria-label="Pipeline: failed"
diff --git a/spec/frontend/silent_mode_settings/components/app_spec.js b/spec/frontend/silent_mode_settings/components/app_spec.js
index 5997bfd1b5f..dfa2b1bfcbb 100644
--- a/spec/frontend/silent_mode_settings/components/app_spec.js
+++ b/spec/frontend/silent_mode_settings/components/app_spec.js
@@ -1,4 +1,4 @@
-import { GlToggle, GlBadge } from '@gitlab/ui';
+import { GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/alert';
@@ -29,19 +29,8 @@ describe('SilentModeSettingsApp', () => {
};
const findGlToggle = () => wrapper.findComponent(GlToggle);
- const findGlBadge = () => wrapper.findComponent(GlBadge);
describe('template', () => {
- describe('experiment badge', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders properly', () => {
- expect(findGlBadge().exists()).toBe(true);
- });
- });
-
describe('when silent mode is already enabled', () => {
beforeEach(() => {
createComponent({ isSilentModeEnabled: true });
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 7cf64c6e049..3e95cb25b12 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -637,6 +637,21 @@ RSpec.describe ApplicationHelper do
expect(discord).to eq('https://discord.com/users/1234567890123456789')
end
end
+
+ context 'when mastodon is set' do
+ let_it_be(:user) { build(:user) }
+ let(:mastodon) { mastodon_url(user) }
+
+ it 'returns an empty string if mastodon username is not set' do
+ expect(mastodon).to eq('')
+ end
+
+ it 'returns mastodon url when mastodon username is set' do
+ user.mastodon = '@robin@example.com'
+
+ expect(mastodon).to eq('https://example.com/@robin')
+ end
+ end
end
describe '#gitlab_ui_form_for' do
diff --git a/spec/helpers/ci/status_helper_spec.rb b/spec/helpers/ci/status_helper_spec.rb
index 17fe474b360..dc56ec96e3b 100644
--- a/spec/helpers/ci/status_helper_spec.rb
+++ b/spec/helpers/ci/status_helper_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Ci::StatusHelper do
subject { helper.render_status_with_link("success") }
it "renders a passed status icon" do
- is_expected.to include("<span class=\"ci-status-link ci-status-icon-success d-inline-flex")
+ is_expected.to include("<span class=\"js-ci-status-badge-legacy ci-status-icon-success d-inline-flex")
end
it "has 'Pipeline' as the status type in the title" do
@@ -84,7 +84,7 @@ RSpec.describe Ci::StatusHelper do
subject { helper.render_status_with_link("success", cssclass: "extra-class") }
it "has appended extra class to icon classes" do
- is_expected.to include('class="ci-status-link ci-status-icon-success d-inline-flex ' \
+ is_expected.to include('class="js-ci-status-badge-legacy ci-status-icon-success d-inline-flex ' \
'gl-line-height-1 extra-class"')
end
end
diff --git a/spec/lib/gitlab/group_search_results_spec.rb b/spec/lib/gitlab/group_search_results_spec.rb
index 84a2a0549d5..8466e8a1bb5 100644
--- a/spec/lib/gitlab/group_search_results_spec.rb
+++ b/spec/lib/gitlab/group_search_results_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe Gitlab::GroupSearchResults, feature_category: :global_search do
end
include_examples 'search results filtered by state'
- include_examples 'search results filtered by archived', 'search_merge_requests_hide_archived_projects'
+ include_examples 'search results filtered by archived'
end
describe 'milestones search' do
diff --git a/spec/lib/gitlab/search_results_spec.rb b/spec/lib/gitlab/search_results_spec.rb
index e8604256f71..b27c8d13c37 100644
--- a/spec/lib/gitlab/search_results_spec.rb
+++ b/spec/lib/gitlab/search_results_spec.rb
@@ -197,7 +197,7 @@ RSpec.describe Gitlab::SearchResults, feature_category: :global_search do
let(:query) { 'foo' }
include_examples 'search results filtered by state'
- include_examples 'search results filtered by archived', 'search_merge_requests_hide_archived_projects'
+ include_examples 'search results filtered by archived'
end
context 'ordering' do
diff --git a/spec/models/user_detail_spec.rb b/spec/models/user_detail_spec.rb
index 428fd5470c3..b443988cde9 100644
--- a/spec/models/user_detail_spec.rb
+++ b/spec/models/user_detail_spec.rb
@@ -59,6 +59,27 @@ RSpec.describe UserDetail do
end
end
+ describe '#mastodon' do
+ it { is_expected.to validate_length_of(:mastodon).is_at_most(500) }
+
+ context 'when mastodon is set' do
+ let_it_be(:user_detail) { create(:user_detail) }
+
+ it 'accepts a valid mastodon username' do
+ user_detail.mastodon = '@robin@example.com'
+
+ expect(user_detail).to be_valid
+ end
+
+ it 'throws an error when mastodon username format is wrong' do
+ user_detail.mastodon = '@robin'
+
+ expect(user_detail).not_to be_valid
+ expect(user_detail.errors.full_messages).to match_array([_('Mastodon must contain only a mastodon username.')])
+ end
+ end
+ end
+
describe '#location' do
it { is_expected.to validate_length_of(:location).is_at_most(500) }
end
@@ -97,6 +118,7 @@ RSpec.describe UserDetail do
discord: '1234567890123456789',
linkedin: 'linkedin',
location: 'location',
+ mastodon: '@robin@example.com',
organization: 'organization',
skype: 'skype',
twitter: 'twitter',
@@ -117,6 +139,7 @@ RSpec.describe UserDetail do
it_behaves_like 'prevents `nil` value', :discord
it_behaves_like 'prevents `nil` value', :linkedin
it_behaves_like 'prevents `nil` value', :location
+ it_behaves_like 'prevents `nil` value', :mastodon
it_behaves_like 'prevents `nil` value', :organization
it_behaves_like 'prevents `nil` value', :skype
it_behaves_like 'prevents `nil` value', :twitter
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 947d83badf6..c9da1a31c86 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -113,6 +113,9 @@ RSpec.describe User, feature_category: :user_profile do
it { is_expected.to delegate_method(:linkedin).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:linkedin=).to(:user_detail).with_arguments(:args).allow_nil }
+ it { is_expected.to delegate_method(:mastodon).to(:user_detail).allow_nil }
+ it { is_expected.to delegate_method(:mastodon=).to(:user_detail).with_arguments(:args).allow_nil }
+
it { is_expected.to delegate_method(:twitter).to(:user_detail).allow_nil }
it { is_expected.to delegate_method(:twitter=).to(:user_detail).with_arguments(:args).allow_nil }
diff --git a/spec/requests/projects/ml/models_controller_spec.rb b/spec/requests/projects/ml/models_controller_spec.rb
index b4402ad9a27..936aed59e39 100644
--- a/spec/requests/projects/ml/models_controller_spec.rb
+++ b/spec/requests/projects/ml/models_controller_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Projects::Ml::ModelsController, feature_category: :mlops do
end
it 'fetches the models using the finder' do
- expect(::Projects::Ml::ModelFinder).to receive(:new).with(project).and_call_original
+ expect(::Projects::Ml::ModelFinder).to receive(:new).with(project, {}).and_call_original
index_request
end
@@ -61,6 +61,22 @@ RSpec.describe Projects::Ml::ModelsController, feature_category: :mlops do
end
end
+ context 'with search params' do
+ let(:params) { { name: 'some_name', order_by: 'name', sort: 'asc' } }
+
+ it 'passes down params to the finder' do
+ expect(Projects::Ml::ModelFinder).to receive(:new).and_call_original do |_exp, params|
+ expect(params.to_h).to include({
+ name: 'some_name',
+ order_by: 'name',
+ sort: 'asc'
+ })
+ end
+
+ index_request
+ end
+ end
+
describe 'pagination' do
before do
stub_const("Projects::Ml::ModelsController::MAX_MODELS_PER_PAGE", 2)
diff --git a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
index 184f2c3ee92..263cd8244b0 100644
--- a/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
+++ b/spec/rubocop/cop/gitlab/feature_available_usage_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe RuboCop::Cop::Gitlab::FeatureAvailableUsage do
end
it 'does not flag the use of Gitlab::Saas.feature_available?' do
- expect_no_offenses('Gitlab::Saas.feature_available?("some/feature")')
+ expect_no_offenses('Gitlab::Saas.feature_available?(:some_feature)')
end
it 'flags the use with a dynamic feature as nil' do
diff --git a/spec/support/helpers/stub_saas_features.rb b/spec/support/helpers/stub_saas_features.rb
index e344888cb8c..d0aa7108a6a 100644
--- a/spec/support/helpers/stub_saas_features.rb
+++ b/spec/support/helpers/stub_saas_features.rb
@@ -6,9 +6,9 @@ module StubSaasFeatures
# @param [Hash] features where key is feature name and value is boolean whether enabled or not.
#
# Examples
- # - `stub_saas_features('onboarding' => false)` ... Disable `onboarding`
+ # - `stub_saas_features(onboarding: false)` ... Disable `onboarding`
# SaaS feature globally.
- # - `stub_saas_features('onboarding' => true)` ... Enable `onboarding`
+ # - `stub_saas_features(onboarding: true)` ... Enable `onboarding`
# SaaS feature globally.
def stub_saas_features(features)
features.each do |feature_name, value|
diff --git a/spec/support/shared_examples/features/content_editor_shared_examples.rb b/spec/support/shared_examples/features/content_editor_shared_examples.rb
index 3e81f969462..334dbf9c899 100644
--- a/spec/support/shared_examples/features/content_editor_shared_examples.rb
+++ b/spec/support/shared_examples/features/content_editor_shared_examples.rb
@@ -2,7 +2,10 @@
require 'spec_helper'
-RSpec.shared_examples 'edits content using the content editor' do |params = { with_expanded_references: true }|
+RSpec.shared_examples 'edits content using the content editor' do |params = {
+ with_expanded_references: true,
+ with_quick_actions: true
+}|
include ContentEditorHelpers
let(:content_editor_testid) { '[data-testid="content-editor"] [contenteditable].ProseMirror' }
@@ -546,6 +549,39 @@ RSpec.shared_examples 'edits content using the content editor' do |params = { wi
end
end
+ if params[:with_quick_actions]
+ it 'shows suggestions for quick actions' do
+ type_in_content_editor '/a'
+
+ expect(find(suggestions_dropdown)).to have_text('/assign')
+ expect(find(suggestions_dropdown)).to have_text('/label')
+ end
+
+ it 'adds the correct prefix for /assign' do
+ type_in_content_editor '/assign'
+
+ send_keys [:arrow_down, :enter]
+
+ expect(page).to have_text('/assign @')
+ end
+
+ it 'adds the correct prefix for /label' do
+ type_in_content_editor '/label'
+
+ send_keys [:arrow_down, :enter]
+
+ expect(page).to have_text('/label ~')
+ end
+
+ it 'adds the correct prefix for /milestone' do
+ type_in_content_editor '/milestone'
+
+ send_keys [:arrow_down, :enter]
+
+ expect(page).to have_text('/milestone %')
+ end
+ end
+
it 'shows suggestions for members with descriptions' do
type_in_content_editor '@a'
diff --git a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
index 784de102f4f..63438a9c379 100644
--- a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
@@ -149,7 +149,10 @@ RSpec.shared_examples 'User updates wiki page' do
end
end
- it_behaves_like 'edits content using the content editor', { with_expanded_references: false }
+ it_behaves_like 'edits content using the content editor', {
+ with_expanded_references: false,
+ with_quick_actions: false
+ }
it_behaves_like 'inserts diagrams.net diagram using the content editor'
it_behaves_like 'autocompletes items'
end
diff --git a/spec/support_specs/helpers/stub_saas_features_spec.rb b/spec/support_specs/helpers/stub_saas_features_spec.rb
index ed973071a6d..c3cec3f47aa 100644
--- a/spec/support_specs/helpers/stub_saas_features_spec.rb
+++ b/spec/support_specs/helpers/stub_saas_features_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe StubSaasFeatures, feature_category: :shared do
describe '#stub_saas_features' do
using RSpec::Parameterized::TableSyntax
- let(:feature_name) { '_some_saas_feature_' }
+ let(:feature_name) { :some_saas_feature }
context 'when checking global state' do
where(:feature_value) do
@@ -41,10 +41,10 @@ RSpec.describe StubSaasFeatures, feature_category: :shared do
end
it 'handles multiple features' do
- stub_saas_features(feature_name => false, '_some_new_feature_' => true)
+ stub_saas_features(feature_name => false, some_new_feature: true)
expect(::Gitlab::Saas.feature_available?(feature_name)).to eq(false)
- expect(::Gitlab::Saas.feature_available?('_some_new_feature_')).to eq(true)
+ expect(::Gitlab::Saas.feature_available?(:some_new_feature)).to eq(true)
end
end
end