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>2021-09-15 21:11:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-15 21:11:29 +0300
commit27d1ed4ddff6c2649544a968c2842140272d9c9d (patch)
tree93a68b94ece233b47284a9c7ad8cabf31465212c /spec
parent6e2dde590e694c13efdd441e058a925dcff17258 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb63
-rw-r--r--spec/features/admin/admin_users_impersonation_tokens_spec.rb10
-rw-r--r--spec/features/groups/settings/repository_spec.rb2
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb2
-rw-r--r--spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb2
-rw-r--r--spec/features/profiles/personal_access_tokens_spec.rb14
-rw-r--r--spec/features/projects/settings/access_tokens_spec.rb14
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb2
-rw-r--r--spec/finders/projects_finder_spec.rb26
-rw-r--r--spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js2
-rw-r--r--spec/frontend/deprecated_jquery_dropdown_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap4
-rw-r--r--spec/frontend/header_search/components/app_spec.js76
-rw-r--r--spec/frontend/header_search/components/header_search_scoped_items_spec.js61
-rw-r--r--spec/frontend/header_search/mock_data.js40
-rw-r--r--spec/frontend/header_search/store/actions_spec.js28
-rw-r--r--spec/frontend/header_search/store/getters_spec.js119
-rw-r--r--spec/frontend/header_search/store/mutations_spec.js20
-rw-r--r--spec/frontend/header_spec.js4
-rw-r--r--spec/frontend/invite_members/components/invite_members_trigger_spec.js4
-rw-r--r--spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js2
-rw-r--r--spec/frontend/sidebar/track_invite_members_spec.js2
-rw-r--r--spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js49
-rw-r--r--spec/helpers/nav/new_dropdown_helper_spec.rb18
-rw-r--r--spec/helpers/nav/top_nav_helper_spec.rb4
-rw-r--r--spec/lib/gitlab/github_import/user_finder_spec.rb12
-rw-r--r--spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb17
-rw-r--r--spec/support/shared_examples/features/deploy_token_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/features/discussion_comments_shared_example.rb2
-rw-r--r--spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb2
-rw-r--r--spec/views/projects/empty.html.haml_spec.rb2
-rw-r--r--spec/views/search/_results.html.haml_spec.rb8
-rw-r--r--spec/views/shared/access_tokens/_table.html.haml_spec.rb2
33 files changed, 590 insertions, 48 deletions
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index a2b62aa49d2..02ed954508e 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -200,6 +200,24 @@ RSpec.describe Explore::ProjectsController do
let(:sorting_param) { 'created_asc' }
end
end
+
+ describe 'GET #index' do
+ let(:controller_action) { :index }
+ let(:params_with_name) { { name: 'some project' } }
+
+ context 'when disable_anonymous_search is enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'does not show a flash message' do
+ sign_in(create(:user))
+ get controller_action, params: params_with_name
+
+ expect(flash[:notice]).to be_nil
+ end
+ end
+ end
end
context 'when user is not signed in' do
@@ -229,5 +247,50 @@ RSpec.describe Explore::ProjectsController do
expect(response).to redirect_to new_user_session_path
end
end
+
+ describe 'GET #index' do
+ let(:controller_action) { :index }
+ let(:params_with_name) { { name: 'some project' } }
+
+ context 'when disable_anonymous_search is enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'shows a flash message' do
+ get controller_action, params: params_with_name
+
+ expect(flash[:notice]).to eq('You must sign in to search for specific projects.')
+ end
+
+ context 'when search param is not given' do
+ it 'does not show a flash message' do
+ get controller_action
+
+ expect(flash[:notice]).to be_nil
+ end
+ end
+
+ context 'when format is not HTML' do
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_name.merge(format: :atom)
+
+ expect(flash[:notice]).to be_nil
+ end
+ end
+ end
+
+ context 'when disable_anonymous_search is disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'does not show a flash message' do
+ get controller_action, params: params_with_name
+
+ expect(flash[:notice]).to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
index 7466150addf..0966032ff37 100644
--- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb
+++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
click_on "Create impersonation token"
expect(active_impersonation_tokens).to have_text(name)
- expect(active_impersonation_tokens).to have_text('In')
+ expect(active_impersonation_tokens).to have_text('in')
expect(active_impersonation_tokens).to have_text('api')
expect(active_impersonation_tokens).to have_text('read_user')
expect(PersonalAccessTokensFinder.new(impersonation: true).execute.count).to equal(1)
@@ -59,6 +59,14 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do
expect(active_impersonation_tokens).to have_text(impersonation_token.name)
expect(active_impersonation_tokens).not_to have_text(personal_access_token.name)
+ expect(active_impersonation_tokens).to have_text('in')
+ end
+
+ it 'shows absolute times' do
+ admin.update!(time_display_relative: false)
+ visit admin_user_impersonation_tokens_path(user_id: user.username)
+
+ expect(active_impersonation_tokens).to have_text(personal_access_token.expires_at.strftime('%b %d'))
end
end
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index 7082b2b20bd..d95eaf3c92c 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -18,11 +18,11 @@ RSpec.describe 'Group Repository settings' do
before do
stub_container_registry_config(enabled: true)
- visit group_settings_repository_path(group)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'group' }
+ let(:page_path) { group_settings_repository_path(group) }
end
end
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index e198d9d4ebb..bd4be755a92 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -117,7 +117,7 @@ RSpec.describe 'Issue Sidebar' do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_assignee"]')
end
diff --git a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
index 45ee914de9d..caf0c609f64 100644
--- a/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Merge request > User edits reviewers sidebar', :js do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite Members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_reviewer"]')
end
diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb
index de511e99182..8025db9f86d 100644
--- a/spec/features/profiles/personal_access_tokens_spec.rb
+++ b/spec/features/profiles/personal_access_tokens_spec.rb
@@ -56,7 +56,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
click_on "Create personal access token"
expect(active_personal_access_tokens).to have_text(name)
- expect(active_personal_access_tokens).to have_text('In')
+ expect(active_personal_access_tokens).to have_text('in')
expect(active_personal_access_tokens).to have_text('api')
expect(active_personal_access_tokens).to have_text('read_user')
expect(created_personal_access_token).not_to be_empty
@@ -85,6 +85,18 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do
expect(active_personal_access_tokens).to have_text(personal_access_token.name)
expect(active_personal_access_tokens).not_to have_text(impersonation_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit profile_personal_access_tokens_path
+
+ expect(active_personal_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe "inactive tokens" do
diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb
index 33e2623522e..deeab084c5f 100644
--- a/spec/features/projects/settings/access_tokens_spec.rb
+++ b/spec/features/projects/settings/access_tokens_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
click_on 'Create project access token'
expect(active_project_access_tokens).to have_text(name)
- expect(active_project_access_tokens).to have_text('In')
+ expect(active_project_access_tokens).to have_text('in')
expect(active_project_access_tokens).to have_text('api')
expect(active_project_access_tokens).to have_text('read_api')
expect(active_project_access_tokens).to have_text('Maintainer')
@@ -156,6 +156,18 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do
expect(active_project_access_tokens).to have_text(project_access_token.name)
end
+
+ context 'when User#time_display_relative is false' do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit project_settings_access_tokens_path(project)
+
+ expect(active_project_access_tokens).to have_text(PersonalAccessToken.last.expires_at.strftime('%b %d'))
+ end
+ end
end
describe 'inactive tokens' do
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index f420a8a76b9..4e1b55d3d70 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -31,11 +31,11 @@ RSpec.describe 'Projects > Settings > Repository settings' do
before do
stub_container_registry_config(enabled: true)
stub_feature_flags(ajax_new_deploy_token: project)
- visit project_settings_repository_path(project)
end
it_behaves_like 'a deploy token in settings' do
let(:entity_type) { 'project' }
+ let(:page_path) { project_settings_repository_path(project) }
end
end
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 1fdc05ca2d2..de244856e12 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -190,6 +190,32 @@ RSpec.describe ProjectsFinder do
it { is_expected.to eq([public_project]) }
end
+ context 'with anonymous user' do
+ let(:public_project_2) { create(:project, :public, group: group, name: 'E', path: 'E') }
+ let(:current_user) { nil }
+ let(:params) { { search: 'C' } }
+
+ context 'with disable_anonymous_search feature flag enabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: true)
+ end
+
+ it 'does not perform search' do
+ is_expected.to eq([public_project_2, public_project])
+ end
+ end
+
+ context 'with disable_anonymous_search feature flag disabled' do
+ before do
+ stub_feature_flags(disable_anonymous_search: false)
+ end
+
+ it 'finds one public project' do
+ is_expected.to eq([public_project])
+ end
+ end
+ end
+
describe 'filter by name for backward compatibility' do
let(:params) { { name: 'C' } }
diff --git a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
index b77def195b6..2dcc537809f 100644
--- a/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
+++ b/spec/frontend/authentication/two_factor_auth/components/recovery_codes_spec.js
@@ -78,7 +78,7 @@ describe('RecoveryCodes', () => {
it('fires Snowplow event', () => {
expect(findProceedButton().attributes()).toMatchObject({
- 'data-track-event': 'click_button',
+ 'data-track-action': 'click_button',
'data-track-label': '2fa_recovery_codes_proceed_button',
});
});
diff --git a/spec/frontend/deprecated_jquery_dropdown_spec.js b/spec/frontend/deprecated_jquery_dropdown_spec.js
index 7858f88f8c3..4a6dee31cd5 100644
--- a/spec/frontend/deprecated_jquery_dropdown_spec.js
+++ b/spec/frontend/deprecated_jquery_dropdown_spec.js
@@ -323,7 +323,7 @@ describe('deprecatedJQueryDropdown', () => {
const li = dropdown.renderItem(item, null, 3);
const link = li.querySelector('a');
- expect(link).toHaveAttr('data-track-event', 'click_text');
+ expect(link).toHaveAttr('data-track-action', 'click_text');
expect(link).toHaveAttr('data-track-label', 'some_value_for_label');
expect(link).toHaveAttr('data-track-value', '3');
expect(link).toHaveAttr('data-track-property', 'suggestion-category');
diff --git a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
index d9f5ba0bade..4dc8eaea174 100644
--- a/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
+++ b/spec/frontend/design_management/components/design_notes/__snapshots__/design_reply_form_spec.js.snap
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Design reply form component renders button text as "Comment" when creating a comment 1`] = `
-"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
+"<button data-track-action=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">
Comment
@@ -9,7 +9,7 @@ exports[`Design reply form component renders button text as "Comment" when creat
`;
exports[`Design reply form component renders button text as "Save comment" when creating a comment 1`] = `
-"<button data-track-event=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
+"<button data-track-action=\\"click_button\\" data-qa-selector=\\"save_comment_button\\" type=\\"submit\\" disabled=\\"disabled\\" class=\\"btn gl-mr-3 gl-w-auto! btn-confirm btn-md disabled gl-button\\">
<!---->
<!----> <span class=\\"gl-button-text\\">
Save comment
diff --git a/spec/frontend/header_search/components/app_spec.js b/spec/frontend/header_search/components/app_spec.js
index 523d3bd7b23..2cbcb73ce5b 100644
--- a/spec/frontend/header_search/components/app_spec.js
+++ b/spec/frontend/header_search/components/app_spec.js
@@ -1,14 +1,41 @@
import { GlSearchBoxByType } from '@gitlab/ui';
+import Vue from 'vue';
+import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import HeaderSearchApp from '~/header_search/components/app.vue';
-import { ESC_KEY } from '~/lib/utils/keys';
-import { MOCK_USERNAME } from '../mock_data';
+import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue';
+import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
+import { ENTER_KEY, ESC_KEY } from '~/lib/utils/keys';
+import { visitUrl } from '~/lib/utils/url_utility';
+import { MOCK_SEARCH, MOCK_SEARCH_QUERY, MOCK_USERNAME } from '../mock_data';
+
+Vue.use(Vuex);
+
+jest.mock('~/lib/utils/url_utility', () => ({
+ visitUrl: jest.fn(),
+}));
describe('HeaderSearchApp', () => {
let wrapper;
- const createComponent = () => {
- wrapper = shallowMountExtended(HeaderSearchApp);
+ const actionSpies = {
+ setSearch: jest.fn(),
+ };
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ ...initialState,
+ },
+ actions: actionSpies,
+ getters: {
+ searchQuery: () => MOCK_SEARCH_QUERY,
+ },
+ });
+
+ wrapper = shallowMountExtended(HeaderSearchApp, {
+ store,
+ });
};
afterEach(() => {
@@ -17,6 +44,8 @@ describe('HeaderSearchApp', () => {
const findHeaderSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
const findHeaderSearchDropdown = () => wrapper.findByTestId('header-search-dropdown-menu');
+ const findHeaderSearchDefaultItems = () => wrapper.findComponent(HeaderSearchDefaultItems);
+ const findHeaderSearchScopedItems = () => wrapper.findComponent(HeaderSearchScopedItems);
describe('template', () => {
it('always renders Header Search Input', () => {
@@ -43,6 +72,29 @@ describe('HeaderSearchApp', () => {
});
});
});
+
+ describe.each`
+ search | showDefault | showScoped
+ ${null} | ${true} | ${false}
+ ${''} | ${true} | ${false}
+ ${MOCK_SEARCH} | ${false} | ${true}
+ `('Header Search Dropdown Items', ({ search, showDefault, showScoped }) => {
+ describe(`when search is ${search}`, () => {
+ beforeEach(() => {
+ createComponent({ search });
+ window.gon.current_username = MOCK_USERNAME;
+ wrapper.setData({ showDropdown: true });
+ });
+
+ it(`should${showDefault ? '' : ' not'} render the Default Dropdown Items`, () => {
+ expect(findHeaderSearchDefaultItems().exists()).toBe(showDefault);
+ });
+
+ it(`should${showScoped ? '' : ' not'} render the Scoped Dropdown Items`, () => {
+ expect(findHeaderSearchScopedItems().exists()).toBe(showScoped);
+ });
+ });
+ });
});
describe('events', () => {
@@ -86,6 +138,22 @@ describe('HeaderSearchApp', () => {
expect(findHeaderSearchDropdown().exists()).toBe(false);
});
});
+
+ it('calls setSearch when search input event is fired', async () => {
+ findHeaderSearchInput().vm.$emit('input', MOCK_SEARCH);
+
+ await wrapper.vm.$nextTick();
+
+ expect(actionSpies.setSearch).toHaveBeenCalledWith(expect.any(Object), MOCK_SEARCH);
+ });
+
+ it('submits a search onKey-Enter', async () => {
+ findHeaderSearchInput().vm.$emit('keydown', new KeyboardEvent({ key: ENTER_KEY }));
+
+ await wrapper.vm.$nextTick();
+
+ expect(visitUrl).toHaveBeenCalledWith(MOCK_SEARCH_QUERY);
+ });
});
});
});
diff --git a/spec/frontend/header_search/components/header_search_scoped_items_spec.js b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
new file mode 100644
index 00000000000..f0e5e182ec4
--- /dev/null
+++ b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
@@ -0,0 +1,61 @@
+import { GlDropdownItem } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { trimText } from 'helpers/text_helper';
+import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
+import { MOCK_SEARCH, MOCK_SCOPED_SEARCH_OPTIONS } from '../mock_data';
+
+Vue.use(Vuex);
+
+describe('HeaderSearchScopedItems', () => {
+ let wrapper;
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ search: MOCK_SEARCH,
+ ...initialState,
+ },
+ getters: {
+ scopedSearchOptions: () => MOCK_SCOPED_SEARCH_OPTIONS,
+ },
+ });
+
+ wrapper = shallowMount(HeaderSearchScopedItems, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findDropdownItemTitles = () => findDropdownItems().wrappers.map((w) => trimText(w.text()));
+ const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
+
+ describe('template', () => {
+ describe('Dropdown items', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders item for each option in scopedSearchOptions', () => {
+ expect(findDropdownItems()).toHaveLength(MOCK_SCOPED_SEARCH_OPTIONS.length);
+ });
+
+ it('renders titles correctly', () => {
+ const expectedTitles = MOCK_SCOPED_SEARCH_OPTIONS.map((o) =>
+ trimText(`"${MOCK_SEARCH}" ${o.description} ${o.scope || ''}`),
+ );
+ expect(findDropdownItemTitles()).toStrictEqual(expectedTitles);
+ });
+
+ it('renders links correctly', () => {
+ const expectedLinks = MOCK_SCOPED_SEARCH_OPTIONS.map((o) => o.url);
+ expect(findDropdownItemLinks()).toStrictEqual(expectedLinks);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/mock_data.js b/spec/frontend/header_search/mock_data.js
index 680b6522d98..5963ad9c279 100644
--- a/spec/frontend/header_search/mock_data.js
+++ b/spec/frontend/header_search/mock_data.js
@@ -4,14 +4,37 @@ import {
MSG_MR_ASSIGNED_TO_ME,
MSG_MR_IM_REVIEWER,
MSG_MR_IVE_CREATED,
+ MSG_IN_PROJECT,
+ MSG_IN_GROUP,
+ MSG_IN_ALL_GITLAB,
} from '~/header_search/constants';
export const MOCK_USERNAME = 'anyone';
+export const MOCK_SEARCH_PATH = '/search';
+
export const MOCK_ISSUE_PATH = '/dashboard/issues';
export const MOCK_MR_PATH = '/dashboard/merge_requests';
+export const MOCK_ALL_PATH = '/';
+
+export const MOCK_PROJECT = {
+ id: 123,
+ name: 'MockProject',
+ path: '/mock-project',
+};
+
+export const MOCK_GROUP = {
+ id: 321,
+ name: 'MockGroup',
+ path: '/mock-group',
+};
+
+export const MOCK_SEARCH_QUERY = 'http://gitlab.com/search?search=test';
+
+export const MOCK_SEARCH = 'test';
+
export const MOCK_SEARCH_CONTEXT = {
project: null,
project_metadata: {},
@@ -41,3 +64,20 @@ export const MOCK_DEFAULT_SEARCH_OPTIONS = [
url: `${MOCK_MR_PATH}/?author_username=${MOCK_USERNAME}`,
},
];
+
+export const MOCK_SCOPED_SEARCH_OPTIONS = [
+ {
+ scope: MOCK_PROJECT.name,
+ description: MSG_IN_PROJECT,
+ url: MOCK_PROJECT.path,
+ },
+ {
+ scope: MOCK_GROUP.name,
+ description: MSG_IN_GROUP,
+ url: MOCK_GROUP.path,
+ },
+ {
+ description: MSG_IN_ALL_GITLAB,
+ url: MOCK_ALL_PATH,
+ },
+];
diff --git a/spec/frontend/header_search/store/actions_spec.js b/spec/frontend/header_search/store/actions_spec.js
new file mode 100644
index 00000000000..4530df0d91c
--- /dev/null
+++ b/spec/frontend/header_search/store/actions_spec.js
@@ -0,0 +1,28 @@
+import testAction from 'helpers/vuex_action_helper';
+import * as actions from '~/header_search/store/actions';
+import * as types from '~/header_search/store/mutation_types';
+import createState from '~/header_search/store/state';
+import { MOCK_SEARCH } from '../mock_data';
+
+describe('Header Search Store Actions', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState({});
+ });
+
+ afterEach(() => {
+ state = null;
+ });
+
+ describe('setSearch', () => {
+ it('calls the SET_SEARCH mutation', () => {
+ return testAction({
+ action: actions.setSearch,
+ payload: MOCK_SEARCH,
+ state,
+ expectedMutations: [{ type: types.SET_SEARCH, payload: MOCK_SEARCH }],
+ });
+ });
+ });
+});
diff --git a/spec/frontend/header_search/store/getters_spec.js b/spec/frontend/header_search/store/getters_spec.js
index f87a58a0560..2ad0a082f6a 100644
--- a/spec/frontend/header_search/store/getters_spec.js
+++ b/spec/frontend/header_search/store/getters_spec.js
@@ -2,10 +2,16 @@ import * as getters from '~/header_search/store/getters';
import initState from '~/header_search/store/state';
import {
MOCK_USERNAME,
+ MOCK_SEARCH_PATH,
MOCK_ISSUE_PATH,
MOCK_MR_PATH,
MOCK_SEARCH_CONTEXT,
MOCK_DEFAULT_SEARCH_OPTIONS,
+ MOCK_SCOPED_SEARCH_OPTIONS,
+ MOCK_PROJECT,
+ MOCK_GROUP,
+ MOCK_ALL_PATH,
+ MOCK_SEARCH,
} from '../mock_data';
describe('Header Search Store Getters', () => {
@@ -13,6 +19,7 @@ describe('Header Search Store Getters', () => {
const createState = (initialState) => {
state = initState({
+ searchPath: MOCK_SEARCH_PATH,
issuesPath: MOCK_ISSUE_PATH,
mrPath: MOCK_MR_PATH,
searchContext: MOCK_SEARCH_CONTEXT,
@@ -25,6 +32,30 @@ describe('Header Search Store Getters', () => {
});
describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=undefined&group_id=undefined&scope=issues`}
+ ${MOCK_GROUP} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=undefined&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('searchQuery', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.searchQuery(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
group | group_metadata | project | project_metadata | expectedPath
${null} | ${null} | ${null} | ${null} | ${MOCK_ISSUE_PATH}
${{ name: 'Test Group' }} | ${{ issues_path: 'group/path' }} | ${null} | ${null} | ${'group/path'}
@@ -72,6 +103,71 @@ describe('Header Search Store Getters', () => {
});
});
+ describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${null}
+ ${MOCK_GROUP} | ${null} | ${null}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('projectUrl', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.projectUrl(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe.each`
+ group | project | expectedPath
+ ${null} | ${null} | ${null}
+ ${MOCK_GROUP} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
+ `('groupUrl', ({ group, project, expectedPath }) => {
+ describe(`when group is ${group?.name} and project is ${project?.name}`, () => {
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ group,
+ project,
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.groupUrl(state)).toBe(expectedPath);
+ });
+ });
+ });
+
+ describe('allUrl', () => {
+ const expectedPath = `${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues`;
+
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ scope: 'issues',
+ },
+ });
+ state.search = MOCK_SEARCH;
+ });
+
+ it(`should return ${expectedPath}`, () => {
+ expect(getters.allUrl(state)).toBe(expectedPath);
+ });
+ });
+
describe('defaultSearchOptions', () => {
const mockGetters = {
scopedIssuesPath: MOCK_ISSUE_PATH,
@@ -89,4 +185,27 @@ describe('Header Search Store Getters', () => {
);
});
});
+
+ describe('scopedSearchOptions', () => {
+ const mockGetters = {
+ projectUrl: MOCK_PROJECT.path,
+ groupUrl: MOCK_GROUP.path,
+ allUrl: MOCK_ALL_PATH,
+ };
+
+ beforeEach(() => {
+ createState({
+ searchContext: {
+ project: MOCK_PROJECT,
+ group: MOCK_GROUP,
+ },
+ });
+ });
+
+ it('returns the correct array', () => {
+ expect(getters.scopedSearchOptions(state, mockGetters)).toStrictEqual(
+ MOCK_SCOPED_SEARCH_OPTIONS,
+ );
+ });
+ });
});
diff --git a/spec/frontend/header_search/store/mutations_spec.js b/spec/frontend/header_search/store/mutations_spec.js
new file mode 100644
index 00000000000..8196c06099d
--- /dev/null
+++ b/spec/frontend/header_search/store/mutations_spec.js
@@ -0,0 +1,20 @@
+import * as types from '~/header_search/store/mutation_types';
+import mutations from '~/header_search/store/mutations';
+import createState from '~/header_search/store/state';
+import { MOCK_SEARCH } from '../mock_data';
+
+describe('Header Search Store Mutations', () => {
+ let state;
+
+ beforeEach(() => {
+ state = createState({});
+ });
+
+ describe('SET_SEARCH', () => {
+ it('sets search to value', () => {
+ mutations[types.SET_SEARCH](state, MOCK_SEARCH);
+
+ expect(state.search).toBe(MOCK_SEARCH);
+ });
+ });
+});
diff --git a/spec/frontend/header_spec.js b/spec/frontend/header_spec.js
index 4ca6d7259bd..0d43accb7e5 100644
--- a/spec/frontend/header_spec.js
+++ b/spec/frontend/header_spec.js
@@ -59,8 +59,8 @@ describe('Header', () => {
beforeEach(() => {
setFixtures(`
<li class="js-nav-user-dropdown">
- <a class="js-buy-pipeline-minutes-link" data-track-event="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy Pipeline minutes</a>
- <a class="js-upgrade-plan-link" data-track-event="click_upgrade_link" data-track-label="free" data-track-property="user_dropdown">Upgrade</a>
+ <a class="js-buy-pipeline-minutes-link" data-track-action="click_buy_ci_minutes" data-track-label="free" data-track-property="user_dropdown">Buy Pipeline minutes</a>
+ <a class="js-upgrade-plan-link" data-track-action="click_upgrade_link" data-track-label="free" data-track-property="user_dropdown">Upgrade</a>
</li>`);
trackingSpy = mockTracking('_category_', $('.js-nav-user-dropdown').element, jest.spyOn);
diff --git a/spec/frontend/invite_members/components/invite_members_trigger_spec.js b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
index f57af61ad5b..b2ebb9e4a47 100644
--- a/spec/frontend/invite_members/components/invite_members_trigger_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
@@ -79,14 +79,14 @@ describe.each(['button', 'anchor'])('with triggerElement as %s', (triggerElement
it('does not add tracking attributes', () => {
createComponent();
- expect(findButton().attributes('data-track-event')).toBeUndefined();
+ expect(findButton().attributes('data-track-action')).toBeUndefined();
expect(findButton().attributes('data-track-label')).toBeUndefined();
});
it('adds tracking attributes', () => {
createComponent({ label: '_label_', event: '_event_' });
- expect(findButton().attributes('data-track-event')).toBe('_event_');
+ expect(findButton().attributes('data-track-action')).toBe('_event_');
expect(findButton().attributes('data-track-label')).toBe('_label_');
});
});
diff --git a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
index 63c1260560b..f84800d8266 100644
--- a/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
+++ b/spec/frontend/pages/dashboard/projects/index/components/customize_homepage_banner_spec.js
@@ -65,7 +65,7 @@ describe('CustomizeHomepageBanner', () => {
await wrapper.vm.$nextTick();
const button = wrapper.find(`[href='${wrapper.vm.preferencesBehaviorPath}']`);
- expect(button.attributes('data-track-event')).toEqual(preferencesTrackingEvent);
+ expect(button.attributes('data-track-action')).toEqual(preferencesTrackingEvent);
expect(button.attributes('data-track-label')).toEqual(provide.trackLabel);
});
diff --git a/spec/frontend/sidebar/track_invite_members_spec.js b/spec/frontend/sidebar/track_invite_members_spec.js
index 6c96e4cfc76..5946e3320c4 100644
--- a/spec/frontend/sidebar/track_invite_members_spec.js
+++ b/spec/frontend/sidebar/track_invite_members_spec.js
@@ -10,7 +10,7 @@ describe('Track user dropdown open', () => {
document.body.innerHTML = `
<div id="dummy-wrapper-element">
<div class="js-sidebar-assignee-dropdown">
- <div class="js-invite-members-track" data-track-event="_track_event_" data-track-label="_track_label_">
+ <div class="js-invite-members-track" data-track-action="_track_event_" data-track-label="_track_label_">
</div>
</div>
</div>
diff --git a/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
new file mode 100644
index 00000000000..bdad0bada5f
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/states/merge_checks_failed_spec.js
@@ -0,0 +1,49 @@
+import { shallowMount } from '@vue/test-utils';
+import MergeChecksFailed from '~/vue_merge_request_widget/components/states/merge_checks_failed.vue';
+
+let wrapper;
+
+function factory(propsData = {}) {
+ wrapper = shallowMount(MergeChecksFailed, {
+ propsData,
+ });
+}
+
+describe('Merge request widget merge checks failed state component', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it.each`
+ mrState | displayText
+ ${{ isPipelineFailed: true }} | ${'pipelineFailed'}
+ ${{ approvals: true, isApproved: false }} | ${'approvalNeeded'}
+ ${{ hasMergeableDiscussionsState: true }} | ${'unresolvedDiscussions'}
+ `('display $displayText text for $mrState', ({ mrState, displayText }) => {
+ factory({ mr: mrState });
+
+ expect(wrapper.text()).toContain(MergeChecksFailed.i18n[displayText]);
+ });
+
+ describe('unresolved discussions', () => {
+ it('renders jump to button', () => {
+ factory({ mr: { hasMergeableDiscussionsState: true } });
+
+ expect(wrapper.find('[data-testid="jumpToUnresolved"]').exists()).toBe(true);
+ });
+
+ it('renders resolve thread button', () => {
+ factory({
+ mr: {
+ hasMergeableDiscussionsState: true,
+ createIssueToResolveDiscussionsPath: 'https://gitlab.com',
+ },
+ });
+
+ expect(wrapper.find('[data-testid="resolveIssue"]').exists()).toBe(true);
+ expect(wrapper.find('[data-testid="resolveIssue"]').attributes('href')).toBe(
+ 'https://gitlab.com',
+ );
+ });
+ });
+});
diff --git a/spec/helpers/nav/new_dropdown_helper_spec.rb b/spec/helpers/nav/new_dropdown_helper_spec.rb
index 79b49be92a5..64f4d5ff797 100644
--- a/spec/helpers/nav/new_dropdown_helper_spec.rb
+++ b/spec/helpers/nav/new_dropdown_helper_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe Nav::NewDropdownHelper do
title: 'Invite members',
href: expected_href,
data: {
- track_event: 'click_link',
+ track_action: 'click_link',
track_label: 'test_tracking_label',
track_property: :invite_members_new_dropdown
}
@@ -104,7 +104,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'general_new_project',
title: 'New project/repository',
href: '/projects/new',
- data: { track_event: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
+ data: { track_action: 'click_link_new_project', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_project_link' }
)
)
)
@@ -122,7 +122,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'general_new_group',
title: 'New group',
href: '/groups/new',
- data: { track_event: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_group', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -140,7 +140,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'general_new_snippet',
title: 'New snippet',
href: '/-/snippets/new',
- data: { track_event: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
+ data: { track_action: 'click_link_new_snippet_parent', track_label: 'plus_menu_dropdown', qa_selector: 'global_new_snippet_link' }
)
)
)
@@ -178,7 +178,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_project',
title: 'New project/repository',
href: "/projects/new?namespace_id=#{group.id}",
- data: { track_event: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_project_group', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -196,7 +196,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_subgroup',
title: 'New subgroup',
href: "/groups/new?parent_id=#{group.id}",
- data: { track_event: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_subgroup', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -245,7 +245,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_issue',
title: 'New issue',
href: "/#{project.path_with_namespace}/-/issues/new",
- data: { track_event: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
+ data: { track_action: 'click_link_new_issue', track_label: 'plus_menu_dropdown', qa_selector: 'new_issue_link' }
)
)
)
@@ -263,7 +263,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_mr',
title: 'New merge request',
href: "/#{merge_project.path_with_namespace}/-/merge_requests/new",
- data: { track_event: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_mr', track_label: 'plus_menu_dropdown' }
)
)
)
@@ -281,7 +281,7 @@ RSpec.describe Nav::NewDropdownHelper do
id: 'new_snippet',
title: 'New snippet',
href: "/#{project.path_with_namespace}/-/snippets/new",
- data: { track_event: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
+ data: { track_action: 'click_link_new_snippet_project', track_label: 'plus_menu_dropdown' }
)
)
)
diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb
index 4d6da258536..da7e5d5dce2 100644
--- a/spec/helpers/nav/top_nav_helper_spec.rb
+++ b/spec/helpers/nav/top_nav_helper_spec.rb
@@ -142,7 +142,7 @@ RSpec.describe Nav::TopNavHelper do
expected_primary = ::Gitlab::Nav::TopNavMenuItem.build(
css_class: 'qa-projects-dropdown',
data: {
- track_event: 'click_dropdown',
+ track_action: 'click_dropdown',
track_label: 'projects_dropdown'
},
icon: 'project',
@@ -248,7 +248,7 @@ RSpec.describe Nav::TopNavHelper do
expected_primary = ::Gitlab::Nav::TopNavMenuItem.build(
css_class: 'qa-groups-dropdown',
data: {
- track_event: 'click_dropdown',
+ track_action: 'click_dropdown',
track_label: 'groups_dropdown'
},
icon: 'group',
diff --git a/spec/lib/gitlab/github_import/user_finder_spec.rb b/spec/lib/gitlab/github_import/user_finder_spec.rb
index f81fa3b1e2e..8eb6eedd72d 100644
--- a/spec/lib/gitlab/github_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/github_import/user_finder_spec.rb
@@ -195,7 +195,7 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
expect(Gitlab::Cache::Import::Caching)
.to receive(:write)
- .with(an_instance_of(String), email)
+ .with(an_instance_of(String), email, timeout: Gitlab::Cache::Import::Caching::TIMEOUT)
finder.email_for_github_username('kittens')
end
@@ -211,6 +211,16 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
expect(finder.email_for_github_username('kittens')).to be_nil
end
+
+ it 'shortens the timeout for Email address in cache when an Email address is private/nil from GitHub' do
+ user = double(:user, email: nil)
+ expect(client).to receive(:user).with('kittens').and_return(user)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:write).with(an_instance_of(String), nil, timeout: Gitlab::Cache::Import::Caching::SHORTER_TIMEOUT)
+
+ expect(finder.email_for_github_username('kittens')).to be_nil
+ end
end
end
diff --git a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
index 6b49a415889..2b810e790f0 100644
--- a/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
+++ b/spec/support/shared_contexts/services/service_ping/stubbed_service_ping_metrics_definitions_shared_context.rb
@@ -6,21 +6,25 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do
let(:metrics_definitions) { standard_metrics + subscription_metrics + operational_metrics + optional_metrics }
let(:standard_metrics) do
[
- metric_attributes('uuid', "standard")
+ metric_attributes('uuid', 'standard'),
+ metric_attributes('recorded_at', 'standard'),
+ metric_attributes('settings.collected_data_categories', 'standard', 'object')
]
end
let(:operational_metrics) do
[
- metric_attributes('counts.merge_requests', "operational"),
+ metric_attributes('counts.merge_requests', 'operational'),
metric_attributes('counts.todos', "operational")
]
end
let(:optional_metrics) do
[
- metric_attributes('counts.boards', "optional"),
- metric_attributes('gitaly.filesystems', '').except('data_category')
+ metric_attributes('counts.boards', 'optional', 'number'),
+ metric_attributes('gitaly.filesystems', '').except('data_category'),
+ metric_attributes('usage_activity_by_stage.monitor.projects_with_enabled_alert_integrations_histogram', 'optional', 'object'),
+ metric_attributes('topology', 'optional', 'object')
]
end
@@ -34,10 +38,11 @@ RSpec.shared_context 'stubbed service ping metrics definitions' do
)
end
- def metric_attributes(key_path, category)
+ def metric_attributes(key_path, category, value_type = 'string')
{
'key_path' => key_path,
- 'data_category' => category
+ 'data_category' => category,
+ 'value_type' => value_type
}
end
end
diff --git a/spec/support/shared_examples/features/deploy_token_shared_examples.rb b/spec/support/shared_examples/features/deploy_token_shared_examples.rb
index fd77297a490..e70f9b52c09 100644
--- a/spec/support/shared_examples/features/deploy_token_shared_examples.rb
+++ b/spec/support/shared_examples/features/deploy_token_shared_examples.rb
@@ -1,15 +1,22 @@
# frozen_string_literal: true
RSpec.shared_examples 'a deploy token in settings' do
- it 'view deploy tokens' do
+ it 'view deploy tokens', :js do
+ user.update!(time_display_relative: true)
+
+ visit page_path
+
within('.deploy-tokens') do
expect(page).to have_content(deploy_token.name)
expect(page).to have_content('read_repository')
expect(page).to have_content('read_registry')
+ expect(page).to have_content('in 4 days')
end
end
it 'add a new deploy token' do
+ visit page_path
+
fill_in 'deploy_token_name', with: 'new_deploy_key'
fill_in 'deploy_token_expires_at', with: (Date.today + 1.month).to_s
fill_in 'deploy_token_username', with: 'deployer'
@@ -24,4 +31,18 @@ RSpec.shared_examples 'a deploy token in settings' do
expect(page).to have_selector("input[name='deploy-token'][readonly='readonly']")
end
end
+
+ context 'when User#time_display_relative is false', :js do
+ before do
+ user.update!(time_display_relative: false)
+ end
+
+ it 'shows absolute times for expires_at' do
+ visit page_path
+
+ within('.deploy-tokens') do
+ expect(page).to have_content(deploy_token.expires_at.strftime('%b %d'))
+ end
+ end
+ end
end
diff --git a/spec/support/shared_examples/features/discussion_comments_shared_example.rb b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
index fb2e422559d..99004e8283c 100644
--- a/spec/support/shared_examples/features/discussion_comments_shared_example.rb
+++ b/spec/support/shared_examples/features/discussion_comments_shared_example.rb
@@ -197,6 +197,8 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
find(submit_button_selector).click
+ wait_for_all_requests
+
expect(page).to have_content(comment)
new_comment = all(comments_selector).last
diff --git a/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb b/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
index c0cfc27ceaf..149486320ae 100644
--- a/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
+++ b/spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb
@@ -15,7 +15,7 @@ RSpec.shared_examples 'issuable invite members' do
page.within '.dropdown-menu-user' do
expect(page).to have_link('Invite Members')
- expect(page).to have_selector('[data-track-event="click_invite_members"]')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
expect(page).to have_selector('[data-track-label="edit_assignee"]')
end
diff --git a/spec/views/projects/empty.html.haml_spec.rb b/spec/views/projects/empty.html.haml_spec.rb
index 70da4fc9e27..416dfc10174 100644
--- a/spec/views/projects/empty.html.haml_spec.rb
+++ b/spec/views/projects/empty.html.haml_spec.rb
@@ -53,7 +53,7 @@ RSpec.describe 'projects/empty' do
it 'shows invite members info', :aggregate_failures do
render
- expect(rendered).to have_selector('[data-track-event=render]')
+ expect(rendered).to have_selector('[data-track-action=render]')
expect(rendered).to have_selector('[data-track-label=invite_members_empty_project]')
expect(rendered).to have_content('Invite your team')
expect(rendered).to have_content('Add members to this project and start collaborating with your team.')
diff --git a/spec/views/search/_results.html.haml_spec.rb b/spec/views/search/_results.html.haml_spec.rb
index ecfcf74edc1..dcf1f46b46c 100644
--- a/spec/views/search/_results.html.haml_spec.rb
+++ b/spec/views/search/_results.html.haml_spec.rb
@@ -74,7 +74,7 @@ RSpec.describe 'search/_results' do
it 'renders the click text event tracking attributes' do
render
- expect(rendered).to have_selector('[data-track-event=click_text]')
+ expect(rendered).to have_selector('[data-track-action=click_text]')
expect(rendered).to have_selector('[data-track-property=search_result]')
end
end
@@ -83,7 +83,7 @@ RSpec.describe 'search/_results' do
it 'does not render the click text event tracking attributes' do
render
- expect(rendered).not_to have_selector('[data-track-event=click_text]')
+ expect(rendered).not_to have_selector('[data-track-action=click_text]')
expect(rendered).not_to have_selector('[data-track-property=search_result]')
end
end
@@ -105,7 +105,7 @@ RSpec.describe 'search/_results' do
it 'renders the click text event tracking attributes' do
render
- expect(rendered).to have_selector('[data-track-event=click_text]')
+ expect(rendered).to have_selector('[data-track-action=click_text]')
expect(rendered).to have_selector('[data-track-property=search_result]')
end
end
@@ -114,7 +114,7 @@ RSpec.describe 'search/_results' do
it 'does not render the click text event tracking attributes' do
render
- expect(rendered).not_to have_selector('[data-track-event=click_text]')
+ expect(rendered).not_to have_selector('[data-track-action=click_text]')
expect(rendered).not_to have_selector('[data-track-property=search_result]')
end
end
diff --git a/spec/views/shared/access_tokens/_table.html.haml_spec.rb b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
index 489675b5683..0a23768b4f1 100644
--- a/spec/views/shared/access_tokens/_table.html.haml_spec.rb
+++ b/spec/views/shared/access_tokens/_table.html.haml_spec.rb
@@ -19,7 +19,6 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
allow(view).to receive(:personal_access_token_expiration_enforced?).and_return(token_expiry_enforced?)
allow(view).to receive(:show_profile_token_expiry_notification?).and_return(true)
- allow(view).to receive(:distance_of_time_in_words_to_now).and_return('4 days')
if project
project.add_maintainer(user)
@@ -140,7 +139,6 @@ RSpec.describe 'shared/access_tokens/_table.html.haml' do
# Expiry
expect(rendered).to have_content 'Expired', count: 2
- expect(rendered).to have_content 'In 4 days'
# Revoke buttons
expect(rendered).to have_link 'Revoke', href: 'path/', class: 'btn-danger-secondary', count: 1