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-08-09 12:10:54 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-09 12:10:54 +0300
commitc2de38f36d2fb75a17ce161fa69f2b8a5e670f3e (patch)
treed24a576c60f21055b8e2bc7f0d9954830d8a229c /spec
parent40338034578aca9d622651a060cbf157a941361b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb16
-rw-r--r--spec/features/projects/settings/repository_settings_spec.rb1
-rw-r--r--spec/frontend/comment_templates/components/form_spec.js12
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js4
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js112
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js37
-rw-r--r--spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb8
-rw-r--r--spec/models/application_setting_spec.rb8
-rw-r--r--spec/requests/projects/merge_requests/creations_spec.rb59
9 files changed, 218 insertions, 39 deletions
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 5f03d721fe7..4b091e9221e 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -373,7 +373,7 @@ RSpec.describe Projects::EnvironmentsController, feature_category: :continuous_d
end
context 'when stop action' do
- it 'returns action url for single stop action' do
+ it 'returns job url for a stop action when job is build' do
action = create(:ci_build, :manual)
allow_any_instance_of(Environment)
@@ -387,6 +387,20 @@ RSpec.describe Projects::EnvironmentsController, feature_category: :continuous_d
project_job_url(project, action) })
end
+ it 'returns pipeline url for a stop action when job is bridge' do
+ action = create(:ci_bridge, :manual)
+
+ allow_any_instance_of(Environment)
+ .to receive_messages(available?: true, stop_with_actions!: [action])
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq(
+ { 'redirect_url' =>
+ project_pipeline_url(project, action.pipeline_id) })
+ end
+
it 'returns environment url for multiple stop actions' do
actions = create_list(:ci_build, 2, :manual)
diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb
index d53aefe5a4e..838ac67ee3d 100644
--- a/spec/features/projects/settings/repository_settings_spec.rb
+++ b/spec/features/projects/settings/repository_settings_spec.rb
@@ -156,6 +156,7 @@ RSpec.describe 'Projects > Settings > Repository settings', feature_category: :g
before do
visit project_settings_repository_path(project)
+ click_button 'Add new'
end
it 'shows push mirror settings', :js do
diff --git a/spec/frontend/comment_templates/components/form_spec.js b/spec/frontend/comment_templates/components/form_spec.js
index 053a5099c37..b48feba5290 100644
--- a/spec/frontend/comment_templates/components/form_spec.js
+++ b/spec/frontend/comment_templates/components/form_spec.js
@@ -5,6 +5,7 @@ import VueApollo from 'vue-apollo';
import createdSavedReplyResponse from 'test_fixtures/graphql/comment_templates/create_saved_reply.mutation.graphql.json';
import createdSavedReplyErrorResponse from 'test_fixtures/graphql/comment_templates/create_saved_reply_with_errors.mutation.graphql.json';
import createMockApollo from 'helpers/mock_apollo_helper';
+import { mockTracking } from 'helpers/tracking_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Form from '~/comment_templates/components/form.vue';
import createSavedReplyMutation from '~/comment_templates/queries/create_saved_reply.mutation.graphql';
@@ -52,6 +53,12 @@ const findSubmitBtn = () => wrapper.find('[data-testid="comment-template-form-su
describe('Comment templates form component', () => {
describe('creates comment template', () => {
+ let trackingSpy;
+
+ beforeEach(() => {
+ trackingSpy = mockTracking(undefined, window.document, jest.spyOn);
+ });
+
it('calls apollo mutation', async () => {
wrapper = createComponent();
@@ -66,6 +73,11 @@ describe('Comment templates form component', () => {
content: 'Test content',
name: 'Test',
});
+ expect(trackingSpy).toHaveBeenCalledWith(
+ expect.any(String),
+ 'i_code_review_saved_replies_create',
+ expect.any(Object),
+ );
});
it('does not submit when form validation fails', async () => {
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
index 6a9e482a184..e9e7f7fdb88 100644
--- a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
@@ -45,7 +45,9 @@ describe('Deploy freeze table', () => {
it('displays empty', () => {
expect(findEmptyFreezePeriods().exists()).toBe(true);
expect(findEmptyFreezePeriods().text()).toBe(
- 'No deploy freezes exist for this project. To add one, select Add deploy freeze',
+ `No deploy freezes exist for this project. To add one, select
+ Add deploy freeze
+ above.`,
);
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
index 0cbb9eab018..8b8241f395f 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
@@ -9,6 +9,7 @@ import component from '~/packages_and_registries/container_registry/explorer/com
import TagsListRow from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue';
import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import PersistedPagination from '~/packages_and_registries/shared/components/persisted_pagination.vue';
import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
@@ -40,6 +41,7 @@ describe('Tags List', () => {
};
const findDeleteModal = () => wrapper.findComponent(DeleteModal);
+ const findPersistedPagination = () => wrapper.findComponent(PersistedPagination);
const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findTagsListRow = () => wrapper.findAllComponents(TagsListRow);
const findRegistryList = () => wrapper.findComponent(RegistryList);
@@ -47,7 +49,7 @@ describe('Tags List', () => {
const findTagsLoader = () => wrapper.findComponent(TagsLoader);
const fireFirstSortUpdate = () => {
- findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [], pageInfo: {} });
};
const waitForApolloRequestRender = async () => {
@@ -103,18 +105,24 @@ describe('Tags List', () => {
it('binds the correct props', () => {
expect(findRegistryList().props()).toMatchObject({
title: '2 tags',
- pagination: tagsPageInfo,
items: tags,
idProperty: 'name',
hiddenDelete: false,
});
});
+ it('has persisted pagination', () => {
+ expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo);
+ });
+
describe('events', () => {
- it('prev-page fetch the previous page', async () => {
- findRegistryList().vm.$emit('prev-page');
+ it('prev-page fetches the previous page', async () => {
+ findPersistedPagination().vm.$emit('prev');
await waitForPromises();
+ // we are fetching previous page after load,
+ // so we expect the resolver to have been called twice
+ expect(resolver).toHaveBeenCalledTimes(2);
expect(resolver).toHaveBeenCalledWith({
first: null,
name: '',
@@ -125,10 +133,13 @@ describe('Tags List', () => {
});
});
- it('next-page fetch the previous page', async () => {
- findRegistryList().vm.$emit('next-page');
+ it('next-page fetches the next page', async () => {
+ findPersistedPagination().vm.$emit('next');
await waitForPromises();
+ // we are fetching next page after load,
+ // so we expect the resolver to have been called twice
+ expect(resolver).toHaveBeenCalledTimes(2);
expect(resolver).toHaveBeenCalledWith({
after: tagsPageInfo.endCursor,
first: GRAPHQL_PAGE_SIZE,
@@ -182,6 +193,49 @@ describe('Tags List', () => {
});
});
+ describe('when persisted search emits update', () => {
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('with before calls resolver with pagination params', async () => {
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'NAME_ASC',
+ filters: [],
+ pageInfo: { before: tagsPageInfo.startCursor },
+ });
+ await waitForPromises();
+
+ expect(resolver).toHaveBeenCalledTimes(1);
+ expect(resolver).toHaveBeenCalledWith({
+ first: null,
+ name: '',
+ sort: 'NAME_ASC',
+ before: tagsPageInfo.startCursor,
+ last: GRAPHQL_PAGE_SIZE,
+ id: '1',
+ });
+ });
+
+ it('with after calls resolver with pagination params', async () => {
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'NAME_ASC',
+ filters: [],
+ pageInfo: { after: tagsPageInfo.endCursor },
+ });
+ await waitForPromises();
+
+ expect(resolver).toHaveBeenCalledTimes(1);
+ expect(resolver).toHaveBeenCalledWith({
+ after: tagsPageInfo.endCursor,
+ first: GRAPHQL_PAGE_SIZE,
+ name: '',
+ sort: 'NAME_ASC',
+ id: '1',
+ });
+ });
+ });
+
describe('list rows', () => {
it('one row exist for each tag', async () => {
mountComponent();
@@ -334,31 +388,44 @@ describe('Tags List', () => {
let mutationResolver;
describe('when mutation', () => {
- beforeEach(() => {
+ beforeEach(async () => {
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock);
mountComponent({ mutationResolver });
- return waitForApolloRequestRender();
- });
-
- it('is started renders loader', async () => {
+ await waitForApolloRequestRender();
findRegistryList().vm.$emit('delete', [tags[0]]);
findDeleteModal().vm.$emit('confirmDelete');
- await nextTick();
+ });
+
+ describe('starts', () => {
+ beforeEach(async () => {
+ await nextTick();
+ });
+
+ it('renders loader', () => {
+ expect(findTagsLoader().exists()).toBe(true);
+ expect(findTagsListRow().exists()).toBe(false);
+ });
- expect(findTagsLoader().exists()).toBe(true);
- expect(findTagsListRow().exists()).toBe(false);
+ it('hides pagination', () => {
+ expect(findPersistedPagination().exists()).toEqual(false);
+ });
});
- it('ends, loader is hidden', async () => {
- findRegistryList().vm.$emit('delete', [tags[0]]);
+ describe('is resolved', () => {
+ beforeEach(async () => {
+ await waitForPromises();
+ });
- findDeleteModal().vm.$emit('confirmDelete');
- await waitForPromises();
+ it('loader is hidden', () => {
+ expect(findTagsLoader().exists()).toBe(false);
+ expect(findTagsListRow().exists()).toBe(true);
+ });
- expect(findTagsLoader().exists()).toBe(false);
- expect(findTagsListRow().exists()).toBe(true);
+ it('pagination is shown', () => {
+ expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo);
+ });
});
});
@@ -495,6 +562,11 @@ describe('Tags List', () => {
expect(findTagsLoader().exists()).toBe(loadingVisible);
expect(findTagsListRow().exists()).toBe(!loadingVisible);
+ if (queryExecuting) {
+ expect(findPersistedPagination().props('pagination')).toEqual({});
+ } else {
+ expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo);
+ }
},
);
});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
index c039870b768..1f1f010e0c4 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
@@ -228,7 +228,7 @@ describe('List Page', () => {
expect(findPersistedPagination().props('pagination')).toEqual({});
});
- it('cli commands is not visible', () => {
+ it('cli commands are not visible', () => {
mountComponent();
expect(findCliCommands().exists()).toBe(false);
@@ -243,11 +243,42 @@ describe('List Page', () => {
});
});
+ describe('when mutation is loading', () => {
+ beforeEach(async () => {
+ mountComponent();
+ fireFirstSortUpdate();
+ await waitForApolloRequestRender();
+ findImageList().vm.$emit('delete', deletedContainerRepository);
+ findDeleteModal().vm.$emit('confirmDelete');
+ findDeleteImage().vm.$emit('start');
+ });
+
+ it('shows the skeleton loader', () => {
+ expect(findSkeletonLoader().exists()).toBe(true);
+ });
+
+ it('imagesList is not visible', () => {
+ expect(findImageList().exists()).toBe(false);
+ });
+
+ it('pagination is hidden', () => {
+ expect(findPersistedPagination().exists()).toBe(false);
+ });
+
+ it('cli commands are not visible', () => {
+ expect(findCliCommands().exists()).toBe(false);
+ });
+
+ it('title has the metadataLoading props set to true', () => {
+ expect(findRegistryHeader().props('metadataLoading')).toBe(true);
+ });
+ });
+
describe('list is empty', () => {
describe('project page', () => {
const resolver = jest.fn().mockResolvedValue(graphQLEmptyImageListMock);
- it('cli commands is not visible', async () => {
+ it('cli commands are not visible', async () => {
mountComponent({ resolver });
await waitForApolloRequestRender();
@@ -279,7 +310,7 @@ describe('List Page', () => {
expect(findGroupEmptyState().exists()).toBe(true);
});
- it('cli commands is not visible', async () => {
+ it('cli commands are not visible', async () => {
mountComponent({ resolver, config });
await waitForApolloRequestRender();
diff --git a/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb
index e0e3a0a7c23..a526d951db9 100644
--- a/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb
+++ b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg
let(:database_apdex_sli_query_ci) { 'Apdex query for ci' }
let(:database_apdex_slo_main) { 0.99 }
let(:database_apdex_slo_ci) { 0.95 }
- let(:database_apdex_settings) do
+ let(:prometheus_alert_db_indicators_settings) do
{
prometheus_api_url: prometheus_url,
apdex_sli_query: {
@@ -50,7 +50,7 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg
subject(:evaluate) { described_class.new(context).evaluate }
before do
- stub_application_setting(database_apdex_settings: database_apdex_settings)
+ stub_application_setting(prometheus_alert_db_indicators_settings: prometheus_alert_db_indicators_settings)
allow(Gitlab::PrometheusClient).to receive(:new).with(*prometheus_config).and_return(prometheus_client)
allow(prometheus_client).to receive(:ready?).and_return(client_ready)
@@ -69,8 +69,8 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg
expect(evaluate.reason).to include('indicator disabled')
end
- context 'without database_apdex_settings' do
- let(:database_apdex_settings) { nil }
+ context 'without prometheus_alert_db_indicators_settings' do
+ let(:prometheus_alert_db_indicators_settings) { nil }
it 'returns Unknown signal' do
expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown)
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index b2275be5893..f447278f812 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
let(:ftp) { 'ftp://example.com' }
let(:javascript) { 'javascript:alert(window.opener.document.location)' }
- let_it_be(:valid_database_apdex_settings) do
+ let_it_be(:valid_prometheus_alert_db_indicators_settings) do
{
prometheus_api_url: 'Prometheus URL',
apdex_sli_query: {
@@ -260,9 +260,9 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
it { is_expected.to allow_value(true, false).for(:gitlab_dedicated_instance) }
it { is_expected.not_to allow_value(nil).for(:gitlab_dedicated_instance) }
- it { is_expected.not_to allow_value(random: :value).for(:database_apdex_settings) }
- it { is_expected.to allow_value(nil).for(:database_apdex_settings) }
- it { is_expected.to allow_value(valid_database_apdex_settings).for(:database_apdex_settings) }
+ it { is_expected.not_to allow_value(random: :value).for(:prometheus_alert_db_indicators_settings) }
+ it { is_expected.to allow_value(nil).for(:prometheus_alert_db_indicators_settings) }
+ it { is_expected.to allow_value(valid_prometheus_alert_db_indicators_settings).for(:prometheus_alert_db_indicators_settings) }
it { is_expected.to allow_value([true, false]).for(:silent_mode_enabled) }
it { is_expected.not_to allow_value(nil).for(:silent_mode_enabled) }
diff --git a/spec/requests/projects/merge_requests/creations_spec.rb b/spec/requests/projects/merge_requests/creations_spec.rb
index e8a073fef5f..8f55aa90bee 100644
--- a/spec/requests/projects/merge_requests/creations_spec.rb
+++ b/spec/requests/projects/merge_requests/creations_spec.rb
@@ -10,6 +10,17 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl
let_it_be(:project) { create(:project, :repository, group: group) }
let_it_be(:user) { create(:user) }
+ let(:get_params) do
+ {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ merge_request: {
+ source_branch: 'two-commits',
+ target_branch: 'master'
+ }
+ }
+ end
+
before_all do
group.add_developer(user)
end
@@ -18,16 +29,52 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl
login_as(user)
end
- def get_new
- get namespace_project_new_merge_request_path(namespace_id: project.namespace, project_id: project)
+ def get_new(params = get_params)
+ get namespace_project_new_merge_request_path(params)
end
- it 'avoids N+1 DB queries even with forked projects' do
- control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_new }
+ describe 'GET new' do
+ context 'without merge_request params' do
+ it 'avoids N+1 DB queries even with forked projects' do
+ control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_new }
+
+ 5.times { fork_project(project, user) }
+
+ expect { get_new }.not_to exceed_query_limit(control)
+ end
+
+ it 'renders branch selection screen' do
+ get_new(get_params.except(:merge_request))
+
+ expect(response).to be_successful
+ expect(response).to render_template(partial: '_new_compare')
+ end
+ end
+
+ context 'with merge_request params' do
+ it 'renders new merge request widget template' do
+ get_new
+
+ expect(response).to be_successful
+ expect(response).to render_template(partial: '_new_submit')
+ expect(response).not_to render_template(partial: '_new_compare')
+ end
- 5.times { fork_project(project, user) }
+ context 'when existing merge request with same target and source branches' do
+ let_it_be(:existing_mr) { create(:merge_request) }
- expect { get_new }.not_to exceed_query_limit(control)
+ it 'renders branch selection screen' do
+ allow_next_instance_of(MergeRequest) do |instance|
+ allow(instance).to receive(:existing_mrs_targeting_same_branch).and_return([existing_mr])
+ end
+
+ get_new
+
+ expect(response).to be_successful
+ expect(response).to render_template(partial: '_new_compare')
+ end
+ end
+ end
end
it_behaves_like "observability csp policy", Projects::MergeRequests::CreationsController do