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-06-02 00:07:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-06-02 00:07:58 +0300
commit3ddb72a5ab59d56cb9e9cb27a5abb92bc5074544 (patch)
tree222afa7cff12916d6de0b8e10cc7cd12be886082 /spec
parent1bafcd6a59a26557e5752dd3ec6fa9e793986036 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/merge_requests_diff_llm_summary.rb2
-rw-r--r--spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/user_autocomplete_item_spec.js.snap34
-rw-r--r--spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js117
-rw-r--r--spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js25
-rw-r--r--spec/frontend/super_sidebar/components/global_search/command_palette/user_autocomplete_item_spec.js25
-rw-r--r--spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js29
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js34
-rw-r--r--spec/graphql/types/ci/job_type_spec.rb6
-rw-r--r--spec/requests/api/graphql/ci/jobs_spec.rb2
-rw-r--r--spec/requests/api/graphql/ci/stages_spec.rb6
-rw-r--r--spec/requests/api/graphql/jobs_query_spec.rb2
-rw-r--r--spec/requests/api/graphql/project/pipeline_spec.rb17
12 files changed, 248 insertions, 51 deletions
diff --git a/spec/factories/merge_requests_diff_llm_summary.rb b/spec/factories/merge_requests_diff_llm_summary.rb
index c72ce97efcb..fc67f8442ca 100644
--- a/spec/factories/merge_requests_diff_llm_summary.rb
+++ b/spec/factories/merge_requests_diff_llm_summary.rb
@@ -5,6 +5,6 @@ FactoryBot.define do
association :user, factory: :user
association :merge_request_diff, factory: :merge_request_diff
provider { 0 }
- content { 'test' }
+ content { FFaker::Lorem.sentence }
end
end
diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/user_autocomplete_item_spec.js.snap b/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/user_autocomplete_item_spec.js.snap
new file mode 100644
index 00000000000..431cdce2955
--- /dev/null
+++ b/spec/frontend/super_sidebar/components/global_search/command_palette/__snapshots__/user_autocomplete_item_spec.js.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`UserAutocompleteItem should render user item 1`] = `
+<div
+ class="gl-display-flex gl-align-items-center"
+>
+ <gl-avatar-stub
+ alt="avatar"
+ aria-hidden="true"
+ class="gl-mr-3"
+ entityid="37"
+ entityname="Cole Dickinson"
+ shape="rect"
+ size="16"
+ src="https://www.gravatar.com/avatar/a9638f4ec70148d51e56bf05ad41e993?s=80&d=identicon"
+ />
+
+ <span
+ class="gl-display-flex gl-flex-direction-column"
+ >
+ <span
+ class="gl-text-gray-900"
+ >
+ Cole Dickinson
+ </span>
+
+ <span
+ class="gl-font-sm gl-text-gray-500"
+ >
+ reported_user_14
+ </span>
+ </span>
+</div>
+`;
diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js
index a079188190a..df5b7de78f7 100644
--- a/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/command_palette/command_palette_items_spec.js
@@ -1,14 +1,21 @@
import fuzzaldrinPlus from 'fuzzaldrin-plus';
-import { GlDisclosureDropdownGroup, GlDisclosureDropdownItem } from '@gitlab/ui';
+import { GlDisclosureDropdownGroup, GlDisclosureDropdownItem, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
import CommandPaletteItems from '~/super_sidebar/components/global_search/command_palette/command_palette_items.vue';
import {
COMMAND_HANDLE,
COMMANDS_GROUP_TITLE,
+ USERS_GROUP_TITLE,
+ USER_HANDLE,
} from '~/super_sidebar/components/global_search/command_palette/constants';
-import { COMMAND_PALETTE_COMMANDS } from './mock_data';
+import { userMapper } from '~/super_sidebar/components/global_search/command_palette/utils';
+import axios from '~/lib/utils/axios_utils';
+import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
+import waitForPromises from 'helpers/wait_for_promises';
+import { COMMANDS, USERS } from './mock_data';
-const commands = COMMAND_PALETTE_COMMANDS.map(({ text, href, keywords }) => ({
+const commands = COMMANDS.map(({ text, href, keywords }) => ({
text,
href,
keywords: keywords.join(''),
@@ -29,41 +36,101 @@ describe('CommandPaletteItems', () => {
GlDisclosureDropdownItem,
},
provide: {
- commandPaletteData: COMMAND_PALETTE_COMMANDS,
+ commandPaletteData: COMMANDS,
},
});
};
const findItems = () => wrapper.findAllComponents(GlDisclosureDropdownItem);
const findGroup = () => wrapper.findComponent(GlDisclosureDropdownGroup);
+ const findLoader = () => wrapper.findComponent(GlLoadingIcon);
- it('renders all commands initially', () => {
- createComponent();
- expect(findItems()).toHaveLength(COMMAND_PALETTE_COMMANDS.length);
- expect(findGroup().props('group')).toEqual({
- name: COMMANDS_GROUP_TITLE,
- items: commands,
+ describe('COMMANDS', () => {
+ it('renders all commands initially', () => {
+ createComponent();
+ expect(findItems()).toHaveLength(COMMANDS.length);
+ expect(findGroup().props('group')).toEqual({
+ name: COMMANDS_GROUP_TITLE,
+ items: commands,
+ });
+ });
+
+ describe('with search query', () => {
+ it('should filter by the search query', async () => {
+ jest.spyOn(fuzzaldrinPlus, 'filter');
+ createComponent({ searchQuery: 'mr' });
+ const searchQuery = 'todo';
+ await wrapper.setProps({ searchQuery });
+ expect(fuzzaldrinPlus.filter).toHaveBeenCalledWith(
+ commands,
+ searchQuery,
+ expect.objectContaining({ key: 'keywords' }),
+ );
+ });
+
+ it('should display no results message when no command matched the search query', async () => {
+ jest.spyOn(fuzzaldrinPlus, 'filter').mockReturnValue([]);
+ createComponent({ searchQuery: 'mr' });
+ const searchQuery = 'todo';
+ await wrapper.setProps({ searchQuery });
+ expect(wrapper.text()).toBe('No results found');
+ });
});
});
- describe('with search query', () => {
- it('should filter by the search query', async () => {
- jest.spyOn(fuzzaldrinPlus, 'filter');
- createComponent({ searchQuery: 'mr' });
- const searchQuery = 'todo';
- await wrapper.setProps({ searchQuery });
- expect(fuzzaldrinPlus.filter).toHaveBeenCalledWith(
- commands,
- searchQuery,
- expect.objectContaining({ key: 'keywords' }),
+ describe('USERS', () => {
+ let mockAxios;
+
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ });
+
+ it('should NOT start search for users by the search query which is less than 3 chars', () => {
+ jest.spyOn(axios, 'get');
+ const searchQuery = 'us';
+ createComponent({ handle: USER_HANDLE, searchQuery });
+
+ expect(axios.get).not.toHaveBeenCalled();
+
+ expect(findLoader().exists()).toBe(false);
+ });
+
+ it('should start search for users by the search query with 3+ chars and display a loader', () => {
+ jest.spyOn(axios, 'get');
+ const searchQuery = 'user';
+ createComponent({ handle: USER_HANDLE, searchQuery });
+
+ expect(axios.get).toHaveBeenCalledWith(
+ expect.any(String),
+ expect.objectContaining({
+ params: {
+ search: searchQuery,
+ },
+ }),
);
+
+ expect(findLoader().exists()).toBe(true);
+ });
+
+ it('should render returned users', async () => {
+ mockAxios.onGet().replyOnce(HTTP_STATUS_OK, USERS);
+
+ const searchQuery = 'user';
+ createComponent({ handle: USER_HANDLE, searchQuery });
+
+ await waitForPromises();
+ expect(findItems()).toHaveLength(USERS.length);
+ expect(findGroup().props('group')).toEqual({
+ name: USERS_GROUP_TITLE,
+ items: USERS.map(userMapper),
+ });
});
- it('should display no results message when no command matched the search qery', async () => {
- jest.spyOn(fuzzaldrinPlus, 'filter').mockReturnValue([]);
- createComponent({ searchQuery: 'mr' });
- const searchQuery = 'todo';
- await wrapper.setProps({ searchQuery });
+ it('should display no results message when no users matched the search query', async () => {
+ mockAxios.onGet().replyOnce(HTTP_STATUS_OK, []);
+ const searchQuery = 'user';
+ createComponent({ handle: USER_HANDLE, searchQuery });
+ await waitForPromises();
expect(wrapper.text()).toBe('No results found');
});
});
diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js b/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js
index 7469154e363..e924efd56af 100644
--- a/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js
+++ b/spec/frontend/super_sidebar/components/global_search/command_palette/mock_data.js
@@ -1,4 +1,4 @@
-export const COMMAND_PALETTE_COMMANDS = [
+export const COMMANDS = [
{
text: 'New project/repository',
href: '/projects/new',
@@ -15,3 +15,26 @@ export const COMMAND_PALETTE_COMMANDS = [
keywords: ['new', 'snippet'],
},
];
+
+export const USERS = [
+ {
+ id: 37,
+ username: 'reported_user_14',
+ name: 'Cole Dickinson',
+ web_url: 'http://127.0.0.1:3000/reported_user_14',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/a9638f4ec70148d51e56bf05ad41e993?s=80\u0026d=identicon',
+ },
+ {
+ id: 47,
+ username: 'sharlatenok',
+ name: 'Olena Horal-Koretska',
+ web_url: 'http://127.0.0.1:3000/sharlatenok',
+ },
+ {
+ id: 30,
+ username: 'reported_user_7',
+ name: 'Violeta Feeney',
+ web_url: 'http://127.0.0.1:3000/reported_user_7',
+ },
+];
diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/user_autocomplete_item_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/user_autocomplete_item_spec.js
new file mode 100644
index 00000000000..5abb56228a4
--- /dev/null
+++ b/spec/frontend/super_sidebar/components/global_search/command_palette/user_autocomplete_item_spec.js
@@ -0,0 +1,25 @@
+import { shallowMount } from '@vue/test-utils';
+import UserAutocompleteItem from '~/super_sidebar/components/global_search/command_palette/user_autocomplete_item.vue';
+import { userMapper } from '~/super_sidebar/components/global_search/command_palette/utils';
+import { USERS } from './mock_data';
+
+describe('UserAutocompleteItem', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMount(UserAutocompleteItem, {
+ propsData: {
+ user: USERS.map(userMapper)[0],
+ searchQuery: 'root',
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('should render user item', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+});
diff --git a/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js b/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js
new file mode 100644
index 00000000000..5bcf5e95793
--- /dev/null
+++ b/spec/frontend/super_sidebar/components/global_search/command_palette/utils_spec.js
@@ -0,0 +1,29 @@
+import {
+ userMapper,
+ commandMapper,
+} from '~/super_sidebar/components/global_search/command_palette/utils';
+import { COMMANDS, USERS } from './mock_data';
+
+describe('userMapper', () => {
+ it('should transform users response', () => {
+ const user = USERS[0];
+ expect(userMapper(user)).toEqual({
+ id: user.id,
+ username: user.username,
+ text: user.name,
+ href: user.web_url,
+ avatar_url: user.avatar_url,
+ });
+ });
+});
+
+describe('commandMapper', () => {
+ it('should transform commands response', () => {
+ const command = COMMANDS[0];
+ expect(commandMapper(command)).toEqual({
+ href: command.href,
+ text: command.text,
+ keywords: command.keywords.join(''),
+ });
+ });
+});
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
index fd79e274ff6..0a6d5919207 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
@@ -12,6 +12,7 @@ import CommandPaletteItems from '~/super_sidebar/components/global_search/comman
import {
SEARCH_OR_COMMAND_MODE_PLACEHOLDER,
COMMAND_HANDLE,
+ USER_HANDLE,
} from '~/super_sidebar/components/global_search/command_palette/constants';
import {
SEARCH_INPUT_DESCRIPTION,
@@ -319,24 +320,27 @@ describe('GlobalSearchModal', () => {
});
});
- describe('when FF `command_palette` is enabled', () => {
- beforeEach(() => {
- createComponent({ search: COMMAND_HANDLE }, undefined, undefined, {
- commandPalette: true,
+ describe.each([COMMAND_HANDLE, USER_HANDLE])(
+ 'when FF `command_palette` is enabled',
+ (handle) => {
+ beforeEach(() => {
+ createComponent({ search: handle }, undefined, undefined, {
+ commandPalette: true,
+ });
});
- });
- it('should render command mode components', () => {
- expect(findCommandPaletteItems().exists()).toBe(true);
- expect(findFakeSearchInput().exists()).toBe(true);
- });
+ it('should render command mode components', () => {
+ expect(findCommandPaletteItems().exists()).toBe(true);
+ expect(findFakeSearchInput().exists()).toBe(true);
+ });
- it('should provide an alternative placeholder to the search input', () => {
- expect(findGlobalSearchInput().attributes('placeholder')).toBe(
- SEARCH_OR_COMMAND_MODE_PLACEHOLDER,
- );
- });
- });
+ it('should provide an alternative placeholder to the search input', () => {
+ expect(findGlobalSearchInput().attributes('placeholder')).toBe(
+ SEARCH_OR_COMMAND_MODE_PLACEHOLDER,
+ );
+ });
+ },
+ );
});
});
diff --git a/spec/graphql/types/ci/job_type_spec.rb b/spec/graphql/types/ci/job_type_spec.rb
index e927bac431c..f31c0d5255c 100644
--- a/spec/graphql/types/ci/job_type_spec.rb
+++ b/spec/graphql/types/ci/job_type_spec.rb
@@ -60,6 +60,12 @@ RSpec.describe Types::Ci::JobType, feature_category: :continuous_integration do
failure_message
]
+ if Gitlab.ee?
+ expected_fields += %i[
+ aiFailureAnalysis
+ ]
+ end
+
expect(described_class).to have_graphql_fields(*expected_fields)
end
diff --git a/spec/requests/api/graphql/ci/jobs_spec.rb b/spec/requests/api/graphql/ci/jobs_spec.rb
index 0d5ac725edd..f237516021d 100644
--- a/spec/requests/api/graphql/ci/jobs_spec.rb
+++ b/spec/requests/api/graphql/ci/jobs_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe 'Query.project.pipeline', feature_category: :continuous_integrati
#{all_graphql_fields_for('CiBuildNeed')}
}
... on CiJob {
- #{all_graphql_fields_for('CiJob')}
+ #{all_graphql_fields_for('CiJob', excluded: %w[aiFailureAnalysis])}
}
}
}
diff --git a/spec/requests/api/graphql/ci/stages_spec.rb b/spec/requests/api/graphql/ci/stages_spec.rb
index f4e1a69d455..2d646a0e1c3 100644
--- a/spec/requests/api/graphql/ci/stages_spec.rb
+++ b/spec/requests/api/graphql/ci/stages_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'Query.project.pipeline.stages', feature_category: :continuous_in
let(:fields) do
<<~QUERY
nodes {
- #{all_graphql_fields_for('CiStage')}
+ #{all_graphql_fields_for('CiStage', max_depth: 2)}
}
QUERY
end
@@ -37,7 +37,7 @@ RSpec.describe 'Query.project.pipeline.stages', feature_category: :continuous_in
before_all do
create(:ci_stage, pipeline: pipeline, name: 'deploy')
- create_list(:ci_build, 2, pipeline: pipeline, stage: 'deploy')
+ create(:ci_build, pipeline: pipeline, stage: 'deploy')
end
it_behaves_like 'a working graphql query' do
@@ -58,7 +58,7 @@ RSpec.describe 'Query.project.pipeline.stages', feature_category: :continuous_in
it 'returns up to default limit jobs per stage' do
post_query
- expect(job_nodes.count).to eq(2)
+ expect(job_nodes.count).to eq(1)
end
context 'when the limit is manually set' do
diff --git a/spec/requests/api/graphql/jobs_query_spec.rb b/spec/requests/api/graphql/jobs_query_spec.rb
index 7607aeac6e0..4248a03fa74 100644
--- a/spec/requests/api/graphql/jobs_query_spec.rb
+++ b/spec/requests/api/graphql/jobs_query_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'getting job information', feature_category: :continuous_integrat
:jobs, {}, %(
count
nodes {
- #{all_graphql_fields_for(::Types::Ci::JobType, max_depth: 1)}
+ #{all_graphql_fields_for(::Types::Ci::JobType, max_depth: 1, excluded: %w[aiFailureAnalysis])}
})
)
end
diff --git a/spec/requests/api/graphql/project/pipeline_spec.rb b/spec/requests/api/graphql/project/pipeline_spec.rb
index abfdf07c288..fb1489372fc 100644
--- a/spec/requests/api/graphql/project/pipeline_spec.rb
+++ b/spec/requests/api/graphql/project/pipeline_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
let(:path) { %i[project pipeline] }
let(:pipeline_graphql_data) { graphql_data_at(*path) }
let(:depth) { 3 }
- let(:excluded) { %w[job project] } # Project is very expensive, due to the number of fields
+ let(:excluded) { %w[job project jobs] } # Project is very expensive, due to the number of fields
let(:fields) { all_graphql_fields_for('Pipeline', excluded: excluded, max_depth: depth) }
let(:query) do
@@ -82,7 +82,11 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
context 'when enough data is requested' do
let(:fields) do
query_graphql_field(:jobs, nil,
- query_graphql_field(:nodes, {}, all_graphql_fields_for('CiJob', max_depth: 3)))
+ query_graphql_field(
+ :nodes, {},
+ all_graphql_fields_for('CiJob', excluded: %w[aiFailureAnalysis], max_depth: 3)
+ )
+ )
end
it 'contains jobs' do
@@ -116,7 +120,12 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
let(:fields) do
query_graphql_field(:jobs, { retried: retried_argument },
- query_graphql_field(:nodes, {}, all_graphql_fields_for('CiJob', max_depth: 3)))
+ query_graphql_field(
+ :nodes,
+ {},
+ all_graphql_fields_for('CiJob', excluded: %w[aiFailureAnalysis], max_depth: 3)
+ )
+ )
end
context 'when we filter out retried jobs' do
@@ -177,7 +186,7 @@ RSpec.describe 'getting pipeline information nested in a project', feature_categ
pipeline(iid: $pipelineIID) {
jobs(statuses: [$status]) {
nodes {
- #{all_graphql_fields_for('CiJob', max_depth: 1)}
+ #{all_graphql_fields_for('CiJob', excluded: %w[aiFailureAnalysis], max_depth: 3)}
}
}
}