From c8cc2fe990c52cabcb9912b2b01b5bf16b33d88f Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Fri, 18 Jun 2021 15:10:16 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../admin/integrations_controller_spec.rb | 8 +- spec/controllers/admin/services_controller_spec.rb | 4 +- .../settings/integrations_controller_spec.rb | 8 +- .../projects/import/jira_controller_spec.rb | 12 +- .../controllers/projects/issues_controller_spec.rb | 2 +- .../projects/prometheus/metrics_controller_spec.rb | 4 +- .../projects/runners_controller_spec.rb | 2 +- .../projects/services_controller_spec.rb | 18 +- spec/factories/integration_data.rb | 2 +- spec/factories/integrations.rb | 11 +- spec/factories/projects.rb | 4 +- spec/factories/usage_data.rb | 8 +- .../admin_visits_service_templates_spec.rb | 14 +- .../issuables/markdown_references/jira_spec.rb | 8 +- .../features/issues/user_bulk_edits_issues_spec.rb | 8 +- .../merge_requests/user_mass_updates_spec.rb | 6 +- .../integrations/user_activates_jira_spec.rb | 12 +- .../user_activates_slack_notifications_spec.rb | 10 +- .../components/status_select_spec.js | 77 +++ spec/frontend/issuable_spec.js | 2 +- .../merge_request_artifact_download_spec.js | 4 +- .../security_report_download_dropdown_spec.js | 37 +- .../vue_shared/security_reports/mock_data.js | 11 +- .../security_reports/security_reports_app_spec.js | 10 +- .../prometheus_integration/create_spec.rb | 2 +- .../projects/jira_projects_resolver_spec.rb | 6 +- .../resolvers/projects/services_resolver_spec.rb | 2 +- spec/graphql/types/projects/service_type_spec.rb | 2 +- spec/helpers/operations_helper_spec.rb | 2 +- spec/helpers/services_helper_spec.rb | 10 +- .../external_issue_reference_filter_spec.rb | 4 +- .../backfill_jira_tracker_deployment_type2_spec.rb | 6 +- .../migrate_issue_trackers_sensitive_data_spec.rb | 22 +- .../self_monitoring/project/create_service_spec.rb | 2 +- spec/lib/gitlab/import_export/all_models.yml | 12 +- spec/lib/gitlab/jira_import/base_importer_spec.rb | 4 +- .../lib/gitlab/jira_import/issues_importer_spec.rb | 4 +- .../lib/gitlab/jira_import/labels_importer_spec.rb | 4 +- spec/lib/gitlab/jira_import_spec.rb | 16 +- spec/lib/gitlab/reference_extractor_spec.rb | 2 +- spec/lib/gitlab/usage_data_spec.rb | 4 +- ...90924152703_migrate_issue_trackers_data_spec.rb | 6 +- ..._reschedule_migrate_issue_trackers_data_spec.rb | 6 +- ...te_template_services_duplicated_by_type_spec.rb | 6 +- spec/models/ci/pipeline_schedule_spec.rb | 9 +- spec/models/concerns/has_integrations_spec.rb | 12 +- .../concerns/integrations/has_data_fields_spec.rb | 43 +- spec/models/deployment_metrics_spec.rb | 8 +- spec/models/group_spec.rb | 6 +- spec/models/integration_spec.rb | 91 ++-- spec/models/integrations/jenkins_spec.rb | 82 ++-- spec/models/integrations/jira_spec.rb | 126 +++-- spec/models/integrations/prometheus_spec.rb | 542 +++++++++++++++++++++ .../integrations/slack_slash_commands_spec.rb | 2 +- spec/models/integrations/slack_spec.rb | 8 +- spec/models/integrations/teamcity_spec.rb | 79 ++- spec/models/merge_request_spec.rb | 4 +- .../project_services/prometheus_service_spec.rb | 542 --------------------- spec/models/project_spec.rb | 32 +- spec/policies/project_policy_spec.rb | 2 +- .../prometheus_integration/create_spec.rb | 2 +- .../graphql/mutations/jira_import/start_spec.rb | 8 +- .../api/graphql/project/base_service_spec.rb | 4 +- .../api/graphql/project/jira_service_spec.rb | 2 +- spec/requests/api/projects_spec.rb | 2 +- spec/requests/api/services_spec.rb | 6 +- spec/serializers/merge_request_diff_entity_spec.rb | 2 +- spec/serializers/service_event_entity_spec.rb | 6 +- spec/serializers/service_field_entity_spec.rb | 19 +- .../admin/propagate_integration_service_spec.rb | 14 +- .../bulk_create_integration_service_spec.rb | 16 +- .../bulk_update_integration_service_spec.rb | 2 +- spec/services/git/branch_push_service_spec.rb | 8 +- spec/services/groups/transfer_service_spec.rb | 8 +- .../integrations/test/project_service_spec.rb | 5 +- spec/services/issues/close_service_spec.rb | 4 +- .../jira/requests/projects/list_service_spec.rb | 16 +- .../jira_import/start_import_service_spec.rb | 4 +- spec/services/jira_import/users_importer_spec.rb | 12 +- spec/services/merge_requests/build_service_spec.rb | 12 +- spec/services/merge_requests/merge_service_spec.rb | 6 +- spec/services/projects/create_service_spec.rb | 8 +- spec/services/projects/transfer_service_spec.rb | 12 +- spec/services/projects/update_service_spec.rb | 4 +- spec/services/prometheus/proxy_service_spec.rb | 2 +- spec/services/system_note_service_spec.rb | 6 +- .../system_notes/issuables_service_spec.rb | 2 +- spec/support/helpers/jira_service_helper.rb | 4 +- .../integrations/integrations_shared_context.rb | 2 +- .../graphql/jira_import/jira_projects_context.rb | 4 +- .../slack_mattermost_notifier_shared_examples.rb | 2 +- .../issue_tracker_service_shared_examples.rb | 8 +- .../user_mapper_services_shared_examples.rb | 2 +- .../layouts/nav/sidebar/_project.html.haml_spec.rb | 2 +- spec/views/projects/services/_form.haml_spec.rb | 2 +- .../jira_import/stage/import_issues_worker_spec.rb | 4 +- .../jira_import/stage/import_labels_worker_spec.rb | 4 +- spec/workers/projects/post_creation_worker_spec.rb | 8 +- .../propagate_integration_group_worker_spec.rb | 4 +- ...e_integration_inherit_descendant_worker_spec.rb | 4 +- .../propagate_integration_inherit_worker_spec.rb | 6 +- .../propagate_integration_project_worker_spec.rb | 4 +- 102 files changed, 1215 insertions(+), 1029 deletions(-) create mode 100644 spec/frontend/issuable_bulk_update_sidebar/components/status_select_spec.js create mode 100644 spec/models/integrations/prometheus_spec.rb delete mode 100644 spec/models/project_services/prometheus_service_spec.rb (limited to 'spec') diff --git a/spec/controllers/admin/integrations_controller_spec.rb b/spec/controllers/admin/integrations_controller_spec.rb index 79c39784173..ae01c814f20 100644 --- a/spec/controllers/admin/integrations_controller_spec.rb +++ b/spec/controllers/admin/integrations_controller_spec.rb @@ -37,10 +37,10 @@ RSpec.describe Admin::IntegrationsController do describe '#update' do include JiraServiceHelper - let(:integration) { create(:jira_service, :instance) } + let(:integration) { create(:jira_integration, :instance) } before do - stub_jira_service_test + stub_jira_integration_test allow(PropagateIntegrationWorker).to receive(:perform_async) put :update, params: { id: integration.class.to_param, service: { url: url } } @@ -75,8 +75,8 @@ RSpec.describe Admin::IntegrationsController do end describe '#reset' do - let_it_be(:integration) { create(:jira_service, :instance) } - let_it_be(:inheriting_integration) { create(:jira_service, inherit_from_id: integration.id) } + let_it_be(:integration) { create(:jira_integration, :instance) } + let_it_be(:inheriting_integration) { create(:jira_integration, inherit_from_id: integration.id) } subject do post :reset, params: { id: integration.class.to_param } diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb index 995282ca4bb..06ff8f0db94 100644 --- a/spec/controllers/admin/services_controller_spec.rb +++ b/spec/controllers/admin/services_controller_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Admin::ServicesController do describe 'GET #edit' do let(:service) do - create(:jira_service, :template) + create(:jira_integration, :template) end it 'successfully displays the template' do @@ -30,7 +30,7 @@ RSpec.describe Admin::ServicesController do context 'when instance integration exists' do before do - create(:jira_service, :instance) + create(:jira_integration, :instance) end it 'redirects to the admin application integration page' do diff --git a/spec/controllers/groups/settings/integrations_controller_spec.rb b/spec/controllers/groups/settings/integrations_controller_spec.rb index 4f1f6dcaae4..a6ef0223491 100644 --- a/spec/controllers/groups/settings/integrations_controller_spec.rb +++ b/spec/controllers/groups/settings/integrations_controller_spec.rb @@ -63,11 +63,11 @@ RSpec.describe Groups::Settings::IntegrationsController do describe '#update' do include JiraServiceHelper - let(:integration) { create(:jira_service, project: nil, group_id: group.id) } + let(:integration) { create(:jira_integration, project: nil, group_id: group.id) } before do group.add_owner(user) - stub_jira_service_test + stub_jira_integration_test put :update, params: { group_id: group, id: integration.class.to_param, service: { url: url } } end @@ -93,8 +93,8 @@ RSpec.describe Groups::Settings::IntegrationsController do end describe '#reset' do - let_it_be(:integration) { create(:jira_service, group: group, project: nil) } - let_it_be(:inheriting_integration) { create(:jira_service, inherit_from_id: integration.id) } + let_it_be(:integration) { create(:jira_integration, group: group, project: nil) } + let_it_be(:inheriting_integration) { create(:jira_integration, inherit_from_id: integration.id) } subject do post :reset, params: { group_id: group, id: integration.class.to_param } diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb index 37a7fce0c23..5288c0fcf21 100644 --- a/spec/controllers/projects/import/jira_controller_spec.rb +++ b/spec/controllers/projects/import/jira_controller_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Projects::Import::JiraController do def ensure_correct_config sign_in(user) project.add_maintainer(user) - stub_jira_service_test + stub_jira_integration_test end shared_examples 'redirect with error' do |error| @@ -54,8 +54,8 @@ RSpec.describe Projects::Import::JiraController do context 'when loged user is a developer' do before do - create(:jira_service, project: project) - stub_jira_service_test + create(:jira_integration, project: project) + stub_jira_integration_test sign_in(user) project.add_developer(user) @@ -72,7 +72,7 @@ RSpec.describe Projects::Import::JiraController do it_behaves_like 'users without permissions' - context 'jira service configuration' do + context 'jira integration configuration' do before do sign_in(user) project.add_maintainer(user) @@ -80,14 +80,14 @@ RSpec.describe Projects::Import::JiraController do context 'when Jira service is not enabled for the project' do it 'does not query Jira service' do - expect(project).not_to receive(:jira_service) + expect(project).not_to receive(:jira_integration) end it_behaves_like 'template with no message' end context 'when Jira service is not configured correctly for the project' do - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } before do WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb index 7569a18baeb..3385505bb62 100644 --- a/spec/controllers/projects/issues_controller_spec.rb +++ b/spec/controllers/projects/issues_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Projects::IssuesController do before do sign_in(user) project.add_developer(user) - create(:jira_service, project: project) + create(:jira_integration, project: project) end context 'when GitLab issues disabled' do diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb index c7c3be20f29..5338b77bd08 100644 --- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb +++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb @@ -141,7 +141,7 @@ RSpec.describe Projects::Prometheus::MetricsController do expect(flash[:notice]).to include('Metric was successfully added.') - expect(response).to redirect_to(edit_project_service_path(project, PrometheusService)) + expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus)) end end @@ -164,7 +164,7 @@ RSpec.describe Projects::Prometheus::MetricsController do it 'destroys the metric' do delete :destroy, params: project_params(id: metric.id) - expect(response).to redirect_to(edit_project_service_path(project, PrometheusService)) + expect(response).to redirect_to(edit_project_service_path(project, ::Integrations::Prometheus)) expect(PrometheusMetric.find_by(id: metric.id)).to be_nil end end diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb index 39b45a7133c..70ff77d7ff0 100644 --- a/spec/controllers/projects/runners_controller_spec.rb +++ b/spec/controllers/projects/runners_controller_spec.rb @@ -111,7 +111,7 @@ RSpec.describe Projects::RunnersController do expect(response).to have_gitlab_http_status(:unauthorized) expect(project.shared_runners_enabled).to eq(false) - expect(json_response['error']).to eq('Cannot enable shared runners because parent group does not allow it') + expect(json_response['error']).to eq('Shared runners enabled cannot be enabled because parent group does not allow it') end end end diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb index bd8a4da76ae..aad65880795 100644 --- a/spec/controllers/projects/services_controller_spec.rb +++ b/spec/controllers/projects/services_controller_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Projects::ServicesController do let(:project) { create(:project, :repository) } let(:user) { create(:user) } - let(:service) { create(:jira_service, project: project) } + let(:service) { create(:jira_integration, project: project) } let(:service_params) { { username: 'username', password: 'password', url: 'http://example.com' } } before do @@ -56,7 +56,7 @@ RSpec.describe Projects::ServicesController do end it 'returns success' do - stub_jira_service_test + stub_jira_integration_test expect(Gitlab::HTTP).to receive(:get).with('/rest/api/2/serverInfo', any_args).and_call_original @@ -67,7 +67,7 @@ RSpec.describe Projects::ServicesController do end it 'returns success' do - stub_jira_service_test + stub_jira_integration_test expect(Gitlab::HTTP).to receive(:get).with('/rest/api/2/serverInfo', any_args).and_call_original @@ -130,7 +130,9 @@ RSpec.describe Projects::ServicesController do end context 'with the Slack integration' do - let_it_be(:service) { build(:slack_service) } + let_it_be(:integration) { build(:integrations_slack) } + + let(:service) { integration } # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete it 'returns an error response when the URL is blocked' do put :test, params: project_params(service: { webhook: 'http://127.0.0.1' }) @@ -210,7 +212,7 @@ RSpec.describe Projects::ServicesController do it_behaves_like 'service update' end - context 'wehn param `inherit_from_id` is set to empty string' do + context 'when param `inherit_from_id` is set to empty string' do let(:service_params) { { inherit_from_id: '' } } it 'sets inherit_from_id to nil' do @@ -218,8 +220,8 @@ RSpec.describe Projects::ServicesController do end end - context 'wehn param `inherit_from_id` is set to some value' do - let(:instance_service) { create(:jira_service, :instance) } + context 'when param `inherit_from_id` is set to some value' do + let(:instance_service) { create(:jira_integration, :instance) } let(:service_params) { { inherit_from_id: instance_service.id } } it 'sets inherit_from_id to value' do @@ -230,7 +232,7 @@ RSpec.describe Projects::ServicesController do describe 'as JSON' do before do - stub_jira_service_test + stub_jira_integration_test put :update, params: project_params(service: service_params, format: :json) end diff --git a/spec/factories/integration_data.rb b/spec/factories/integration_data.rb index a6b2693b8df..a7406794437 100644 --- a/spec/factories/integration_data.rb +++ b/spec/factories/integration_data.rb @@ -4,7 +4,7 @@ # The factories are used when creating integrations. FactoryBot.define do factory :jira_tracker_data, class: 'Integrations::JiraTrackerData' do - integration factory: :jira_service + integration factory: :jira_integration end factory :issue_tracker_data, class: 'Integrations::IssueTrackerData' do diff --git a/spec/factories/integrations.rb b/spec/factories/integrations.rb index a64d047c89b..47c9f885845 100644 --- a/spec/factories/integrations.rb +++ b/spec/factories/integrations.rb @@ -27,7 +27,7 @@ FactoryBot.define do end end - factory :prometheus_service do + factory :prometheus_service, class: 'Integrations::Prometheus' do project active { true } properties do @@ -45,7 +45,7 @@ FactoryBot.define do token { 'test' } end - factory :jira_service, class: 'Integrations::Jira' do + factory :jira_integration, class: 'Integrations::Jira' do project active { true } type { 'JiraService' } @@ -91,7 +91,7 @@ FactoryBot.define do issue_tracker end - factory :redmine_service, class: 'Integrations::Redmine' do + factory :redmine_integration, class: 'Integrations::Redmine' do project active { true } issue_tracker @@ -160,14 +160,15 @@ FactoryBot.define do password { 'my-secret-password' } end - factory :slack_service, class: 'Integrations::Slack' do + # avoids conflict with slack_integration factory + factory :integrations_slack, class: 'Integrations::Slack' do project active { true } webhook { 'https://slack.service.url' } type { 'SlackService' } end - factory :slack_slash_commands_service, class: 'Integrations::SlackSlashCommands' do + factory :slack_slash_commands_integration, class: 'Integrations::SlackSlashCommands' do project active { true } type { 'SlackSlashCommandsService' } diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 6641d8749f9..b2f6ae5573d 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -396,7 +396,7 @@ FactoryBot.define do factory :redmine_project, parent: :project do has_external_issue_tracker { true } - redmine_service + redmine_integration end factory :youtrack_project, parent: :project do @@ -408,7 +408,7 @@ FactoryBot.define do factory :jira_project, parent: :project do has_external_issue_tracker { true } - jira_service + jira_integration end factory :prometheus_project, parent: :project do diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb index 2aa926e4dd8..de1e4aa82fa 100644 --- a/spec/factories/usage_data.rb +++ b/spec/factories/usage_data.rb @@ -9,10 +9,10 @@ FactoryBot.define do projects << create(:project, :repository) group = create(:group) create(:board, project: projects[0]) - create(:jira_service, project: projects[0]) - create(:jira_service, :without_properties_callback, project: projects[1]) - create(:jira_service, :jira_cloud_service, project: projects[2]) - create(:jira_service, :without_properties_callback, project: projects[3], properties: { url: 'https://mysite.atlassian.net' }) + create(:jira_integration, project: projects[0]) + create(:jira_integration, :without_properties_callback, project: projects[1]) + create(:jira_integration, :jira_cloud_service, project: projects[2]) + create(:jira_integration, :without_properties_callback, project: projects[3], properties: { url: 'https://mysite.atlassian.net' }) jira_label = create(:label, project: projects[0]) create(:jira_import_state, :finished, project: projects[0], label: jira_label, failed_to_import_count: 2, imported_issues_count: 7, total_issue_count: 9) create(:jira_import_state, :finished, project: projects[1], label: jira_label, imported_issues_count: 3, total_issue_count: 3) diff --git a/spec/features/admin/services/admin_visits_service_templates_spec.rb b/spec/features/admin/services/admin_visits_service_templates_spec.rb index 9d011b97f63..d367867ebb5 100644 --- a/spec/features/admin/services/admin_visits_service_templates_spec.rb +++ b/spec/features/admin/services/admin_visits_service_templates_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin visits service templates' do let(:admin) { create(:user, :admin) } - let(:slack_service) { Integration.for_template.find { |s| s.type == 'SlackService' } } + let(:slack_integration) { Integration.for_template.find { |s| s.type == 'SlackService' } } before do sign_in(admin) @@ -23,7 +23,7 @@ RSpec.describe 'Admin visits service templates' do context 'with an active service template' do before do - create(:slack_service, :template, active: true) + create(:integrations_slack, :template, active: true) visit(admin_application_settings_services_path) end @@ -33,20 +33,20 @@ RSpec.describe 'Admin visits service templates' do context 'without instance-level integration' do it 'shows a link to service template' do - expect(page).to have_link('Slack', href: edit_admin_application_settings_service_path(slack_service.id)) - expect(page).not_to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_service)) + expect(page).to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id)) + expect(page).not_to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration)) end end context 'with instance-level integration' do before do - create(:slack_service, instance: true, project: nil) + create(:integrations_slack, instance: true, project: nil) visit(admin_application_settings_services_path) end it 'shows a link to instance-level integration' do - expect(page).not_to have_link('Slack', href: edit_admin_application_settings_service_path(slack_service.id)) - expect(page).to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_service)) + expect(page).not_to have_link('Slack', href: edit_admin_application_settings_service_path(slack_integration.id)) + expect(page).to have_link('Slack', href: edit_admin_application_settings_integration_path(slack_integration)) end end end diff --git a/spec/features/issuables/markdown_references/jira_spec.rb b/spec/features/issuables/markdown_references/jira_spec.rb index a3a259e21a1..ae9c8d31c02 100644 --- a/spec/features/issuables/markdown_references/jira_spec.rb +++ b/spec/features/issuables/markdown_references/jira_spec.rb @@ -81,7 +81,7 @@ RSpec.describe "Jira", :js do context "when both external and internal issues trackers are enabled for the actual project" do before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -94,7 +94,7 @@ RSpec.describe "Jira", :js do let(:actual_project) { create(:project, :public, :repository, :issues_disabled) } before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -125,7 +125,7 @@ RSpec.describe "Jira", :js do context "when both external and internal issues trackers are enabled for the actual project" do before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do @@ -138,7 +138,7 @@ RSpec.describe "Jira", :js do let(:actual_project) { create(:project, :public, :repository, :issues_disabled) } before do - create(:jira_service, project: actual_project) + create(:jira_integration, project: actual_project) end include_examples "correct references" do diff --git a/spec/features/issues/user_bulk_edits_issues_spec.rb b/spec/features/issues/user_bulk_edits_issues_spec.rb index e34c16e27ba..44c23813e3c 100644 --- a/spec/features/issues/user_bulk_edits_issues_spec.rb +++ b/spec/features/issues/user_bulk_edits_issues_spec.rb @@ -13,26 +13,26 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do end context 'status' do - it 'sets to closed' do + it 'sets to closed', :js do visit project_issues_path(project) click_button 'Edit issues' check 'Select all' click_button 'Select status' - click_link 'Closed' + click_button 'Closed' click_update_issues_button expect(page).to have_selector('.issue', count: 0) end - it 'sets to open' do + it 'sets to open', :js do create_closed visit project_issues_path(project, state: 'closed') click_button 'Edit issues' check 'Select all' click_button 'Select status' - click_link 'Open' + click_button 'Open' click_update_issues_button expect(page).to have_selector('.issue', count: 0) diff --git a/spec/features/merge_requests/user_mass_updates_spec.rb b/spec/features/merge_requests/user_mass_updates_spec.rb index 0fe69c5ca5b..46c12784ea8 100644 --- a/spec/features/merge_requests/user_mass_updates_spec.rb +++ b/spec/features/merge_requests/user_mass_updates_spec.rb @@ -18,7 +18,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do visit project_merge_requests_path(project) end - it 'closes merge request' do + it 'closes merge request', :js do change_status('Closed') expect(page).to have_selector('.merge-request', count: 0) @@ -31,7 +31,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do visit project_merge_requests_path(project, state: 'closed') end - it 'reopens merge request' do + it 'reopens merge request', :js do change_status('Open') expect(page).to have_selector('.merge-request', count: 0) @@ -109,7 +109,7 @@ RSpec.describe 'Merge requests > User mass updates', :js do click_button 'Edit merge requests' check 'Select all' click_button 'Select status' - click_link text + click_button text click_update_merge_requests_button end diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb index 10f84aae93f..d7679d38cae 100644 --- a/spec/features/projects/integrations/user_activates_jira_spec.rb +++ b/spec/features/projects/integrations/user_activates_jira_spec.rb @@ -65,7 +65,7 @@ RSpec.describe 'User activates Jira', :js do include JiraServiceHelper before do - stub_jira_service_test + stub_jira_integration_test visit_project_integration('Jira') fill_form(disable: true) click_save_integration @@ -105,14 +105,14 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3' ) end it 'using automatic transitions' do - create(:jira_service, project: project, jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3') + create(:jira_integration, project: project, jira_issue_transition_automatic: false, jira_issue_transition_id: '1, 2, 3') visit_project_integration('Jira') expect(page).to have_field('Enable Jira transitions', checked: true) @@ -123,14 +123,14 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: true, jira_issue_transition_id: '' ) end it 'disabling issue transitions' do - create(:jira_service, project: project, jira_issue_transition_automatic: true, jira_issue_transition_id: '1, 2, 3') + create(:jira_integration, project: project, jira_issue_transition_automatic: true, jira_issue_transition_id: '1, 2, 3') visit_project_integration('Jira') expect(page).to have_field('Enable Jira transitions', checked: true) @@ -140,7 +140,7 @@ RSpec.describe 'User activates Jira', :js do click_save_integration expect(page).to have_content('Jira settings saved and active.') - expect(project.reload.jira_service.data_fields).to have_attributes( + expect(project.reload.jira_integration.data_fields).to have_attributes( jira_issue_transition_automatic: false, jira_issue_transition_id: '' ) diff --git a/spec/features/projects/services/user_activates_slack_notifications_spec.rb b/spec/features/projects/services/user_activates_slack_notifications_spec.rb index dec83ff1489..d5fe8b083ba 100644 --- a/spec/features/projects/services/user_activates_slack_notifications_spec.rb +++ b/spec/features/projects/services/user_activates_slack_notifications_spec.rb @@ -20,12 +20,12 @@ RSpec.describe 'User activates Slack notifications', :js do end context 'when service is already configured' do - let(:service) { Integrations::Slack.new } - let(:project) { create(:project, slack_service: service) } + let(:integration) { Integrations::Slack.new } + let(:project) { create(:project, slack_integration: integration) } before do - service.fields - service.update!( + integration.fields + integration.update!( push_channel: 1, issue_channel: 2, merge_request_channel: 3, @@ -34,7 +34,7 @@ RSpec.describe 'User activates Slack notifications', :js do pipeline_channel: 6, wiki_page_channel: 7) - visit(edit_project_service_path(project, service)) + visit(edit_project_service_path(project, integration)) end it 'filters events by channel' do diff --git a/spec/frontend/issuable_bulk_update_sidebar/components/status_select_spec.js b/spec/frontend/issuable_bulk_update_sidebar/components/status_select_spec.js new file mode 100644 index 00000000000..09dcb963154 --- /dev/null +++ b/spec/frontend/issuable_bulk_update_sidebar/components/status_select_spec.js @@ -0,0 +1,77 @@ +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import StatusSelect from '~/issuable_bulk_update_sidebar/components/status_select.vue'; +import { ISSUE_STATUS_SELECT_OPTIONS } from '~/issuable_bulk_update_sidebar/constants'; + +describe('StatusSelect', () => { + let wrapper; + + const findDropdown = () => wrapper.findComponent(GlDropdown); + const findAllDropdownItems = () => wrapper.findAllComponents(GlDropdownItem); + const findHiddenInput = () => wrapper.find('input'); + + function createComponent() { + wrapper = shallowMount(StatusSelect); + } + + afterEach(() => { + wrapper.destroy(); + }); + + describe('with no value selected', () => { + beforeEach(() => { + createComponent(); + }); + + it('renders default text', () => { + expect(findDropdown().props('text')).toBe('Select status'); + }); + + it('renders dropdown items with `is-checked` prop set to `false`', () => { + const dropdownItems = findAllDropdownItems(); + + expect(dropdownItems.at(0).props('isChecked')).toBe(false); + expect(dropdownItems.at(1).props('isChecked')).toBe(false); + }); + }); + + describe('when selecting a value', () => { + const selectItemAtIndex = 0; + + beforeEach(async () => { + createComponent(); + await findAllDropdownItems().at(selectItemAtIndex).vm.$emit('click'); + }); + + it('updates value of the hidden input', () => { + expect(findHiddenInput().attributes('value')).toBe( + ISSUE_STATUS_SELECT_OPTIONS[selectItemAtIndex].value, + ); + }); + + it('updates the dropdown text prop', () => { + expect(findDropdown().props('text')).toBe( + ISSUE_STATUS_SELECT_OPTIONS[selectItemAtIndex].text, + ); + }); + + it('sets dropdown item `is-checked` prop to `true`', () => { + const dropdownItems = findAllDropdownItems(); + + expect(dropdownItems.at(0).props('isChecked')).toBe(true); + expect(dropdownItems.at(1).props('isChecked')).toBe(false); + }); + + describe('when selecting the value that is already selected', () => { + it('clears dropdown selection', async () => { + await findAllDropdownItems().at(selectItemAtIndex).vm.$emit('click'); + + const dropdownItems = findAllDropdownItems(); + + expect(dropdownItems.at(0).props('isChecked')).toBe(false); + expect(dropdownItems.at(1).props('isChecked')).toBe(false); + expect(findDropdown().props('text')).toBe('Select status'); + }); + }); + }); +}); diff --git a/spec/frontend/issuable_spec.js b/spec/frontend/issuable_spec.js index 9c8f1e04609..e0bd7b802c9 100644 --- a/spec/frontend/issuable_spec.js +++ b/spec/frontend/issuable_spec.js @@ -1,5 +1,5 @@ +import issuableInitBulkUpdateSidebar from '~/issuable_bulk_update_sidebar/issuable_init_bulk_update_sidebar'; import IssuableIndex from '~/issuable_index'; -import issuableInitBulkUpdateSidebar from '~/issuable_init_bulk_update_sidebar'; describe('Issuable', () => { describe('initBulkUpdate', () => { diff --git a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js index d58c87d66cb..395c74dcba6 100644 --- a/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js +++ b/spec/frontend/vue_shared/components/security_reports/artifact_downloads/merge_request_artifact_download_spec.js @@ -3,7 +3,7 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; import { - expectedDownloadDropdownProps, + expectedDownloadDropdownPropsWithTitle, securityReportMergeRequestDownloadPathsQueryResponse, } from 'jest/vue_shared/security_reports/mock_data'; import createFlash from '~/flash'; @@ -80,7 +80,7 @@ describe('Merge request artifact Download', () => { }); it('renders the download dropdown', () => { - expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps); + expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownPropsWithTitle); }); }); diff --git a/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js b/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js index 9138d2d3f4c..4b75da0b126 100644 --- a/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js +++ b/spec/frontend/vue_shared/security_reports/components/security_report_download_dropdown_spec.js @@ -40,14 +40,13 @@ describe('SecurityReportDownloadDropdown component', () => { expect(findDropdown().props('loading')).toBe(false); }); - it('renders a dropdown items for each artifact', () => { + it('renders a dropdown item for each artifact', () => { artifacts.forEach((artifact, i) => { const item = findDropdownItems().at(i); expect(item.text()).toContain(artifact.name); - expect(item.attributes()).toMatchObject({ - href: artifact.path, - download: expect.any(String), - }); + + expect(item.element.getAttribute('href')).toBe(artifact.path); + expect(item.element.getAttribute('download')).toBeDefined(); }); }); }); @@ -61,4 +60,32 @@ describe('SecurityReportDownloadDropdown component', () => { expect(findDropdown().props('loading')).toBe(true); }); }); + + describe('given title props', () => { + beforeEach(() => { + createComponent({ artifacts: [], loading: true, title: 'test title' }); + }); + + it('should render title', () => { + expect(findDropdown().attributes('title')).toBe('test title'); + }); + + it('should not render text', () => { + expect(findDropdown().text().trim()).toBe(''); + }); + }); + + describe('given text props', () => { + beforeEach(() => { + createComponent({ artifacts: [], loading: true, text: 'test text' }); + }); + + it('should not render title', () => { + expect(findDropdown().props().title).not.toBeDefined(); + }); + + it('should render text', () => { + expect(findDropdown().props().text).toContain('test text'); + }); + }); }); diff --git a/spec/frontend/vue_shared/security_reports/mock_data.js b/spec/frontend/vue_shared/security_reports/mock_data.js index bd9ce3b7314..06631710509 100644 --- a/spec/frontend/vue_shared/security_reports/mock_data.js +++ b/spec/frontend/vue_shared/security_reports/mock_data.js @@ -581,9 +581,18 @@ export const secretDetectionArtifacts = [ }, ]; -export const expectedDownloadDropdownProps = { +export const expectedDownloadDropdownPropsWithTitle = { loading: false, artifacts: [...secretDetectionArtifacts, ...sastArtifacts], + text: '', + title: 'Download results', +}; + +export const expectedDownloadDropdownPropsWithText = { + loading: false, + artifacts: [...secretDetectionArtifacts, ...sastArtifacts], + title: '', + text: 'Download results', }; /** diff --git a/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js b/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js index 038d7754776..bef538e1ff1 100644 --- a/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js +++ b/spec/frontend/vue_shared/security_reports/security_reports_app_spec.js @@ -8,7 +8,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import { trimText } from 'helpers/text_helper'; import waitForPromises from 'helpers/wait_for_promises'; import { - expectedDownloadDropdownProps, + expectedDownloadDropdownPropsWithText, securityReportMergeRequestDownloadPathsQueryNoArtifactsResponse, securityReportMergeRequestDownloadPathsQueryResponse, sastDiffSuccessMock, @@ -99,7 +99,7 @@ describe('Security reports app', () => { }); it('renders the download dropdown', () => { - expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps); + expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownPropsWithText); }); it('renders the expected message', () => { @@ -203,7 +203,7 @@ describe('Security reports app', () => { }); it('renders the download dropdown', () => { - expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps); + expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownPropsWithText); }); }); @@ -225,7 +225,7 @@ describe('Security reports app', () => { }); it('renders the download dropdown', () => { - expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps); + expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownPropsWithText); }); }); @@ -247,7 +247,7 @@ describe('Security reports app', () => { }); it('renders the download dropdown', () => { - expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownProps); + expect(findDownloadDropdown().props()).toEqual(expectedDownloadDropdownPropsWithText); }); }); diff --git a/spec/graphql/mutations/alert_management/prometheus_integration/create_spec.rb b/spec/graphql/mutations/alert_management/prometheus_integration/create_spec.rb index 7ab0f43d674..888b56d6a23 100644 --- a/spec/graphql/mutations/alert_management/prometheus_integration/create_spec.rb +++ b/spec/graphql/mutations/alert_management/prometheus_integration/create_spec.rb @@ -32,7 +32,7 @@ RSpec.describe Mutations::AlertManagement::PrometheusIntegration::Create do context 'when UpdateService responds with success' do it 'returns the integration with no errors' do expect(resolve).to eq( - integration: ::PrometheusService.last!, + integration: ::Integrations::Prometheus.last!, errors: [] ) end diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb index c375345250d..8c36153d485 100644 --- a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb @@ -22,7 +22,7 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end context 'when project has no Jira service' do - let_it_be(:jira_service) { nil } + let_it_be(:jira_integration) { nil } context 'when user is a maintainer' do before do @@ -34,7 +34,7 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end context 'when project has Jira service' do - let(:jira_service) { create(:jira_service, project: project) } + let(:jira_integration) { create(:jira_integration, project: project) } context 'when user is a developer' do before do @@ -98,6 +98,6 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do end def resolve_jira_projects(args = {}, context = { current_user: user }) - resolve(described_class, obj: jira_service, args: args, ctx: context) + resolve(described_class, obj: jira_integration, args: args, ctx: context) end end diff --git a/spec/graphql/resolvers/projects/services_resolver_spec.rb b/spec/graphql/resolvers/projects/services_resolver_spec.rb index a1b631113b2..6da99c8448e 100644 --- a/spec/graphql/resolvers/projects/services_resolver_spec.rb +++ b/spec/graphql/resolvers/projects/services_resolver_spec.rb @@ -40,7 +40,7 @@ RSpec.describe Resolvers::Projects::ServicesResolver do context 'when project has services' do let_it_be(:project) { create(:project, :private) } - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } context 'when user cannot access services' do context 'when anonymous user' do diff --git a/spec/graphql/types/projects/service_type_spec.rb b/spec/graphql/types/projects/service_type_spec.rb index 567bdfaec24..cb09f1ca6cc 100644 --- a/spec/graphql/types/projects/service_type_spec.rb +++ b/spec/graphql/types/projects/service_type_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Types::Projects::ServiceType do describe ".resolve_type" do it 'resolves the corresponding type for objects' do - expect(described_class.resolve_type(build(:jira_service), {})).to eq(Types::Projects::Services::JiraServiceType) + expect(described_class.resolve_type(build(:jira_integration), {})).to eq(Types::Projects::Services::JiraServiceType) expect(described_class.resolve_type(build(:service), {})).to eq(Types::Projects::Services::BaseServiceType) expect(described_class.resolve_type(build(:drone_ci_integration), {})).to eq(Types::Projects::Services::BaseServiceType) expect(described_class.resolve_type(build(:custom_issue_tracker_integration), {})).to eq(Types::Projects::Services::BaseServiceType) diff --git a/spec/helpers/operations_helper_spec.rb b/spec/helpers/operations_helper_spec.rb index e1bd477bc75..61c6bb1ccf7 100644 --- a/spec/helpers/operations_helper_spec.rb +++ b/spec/helpers/operations_helper_spec.rb @@ -21,7 +21,7 @@ RSpec.describe OperationsHelper do end context 'initial service configuration' do - let_it_be(:prometheus_service) { PrometheusService.new(project: project) } + let_it_be(:prometheus_service) { ::Integrations::Prometheus.new(project: project) } before do allow(project).to receive(:find_or_initialize_service).and_call_original diff --git a/spec/helpers/services_helper_spec.rb b/spec/helpers/services_helper_spec.rb index 6dd872225ba..af1873509f0 100644 --- a/spec/helpers/services_helper_spec.rb +++ b/spec/helpers/services_helper_spec.rb @@ -36,8 +36,8 @@ RSpec.describe ServicesHelper do subject { helper.integration_form_data(integration) } - context 'Slack service' do - let(:integration) { build(:slack_service) } + context 'with Slack integration' do + let(:integration) { build(:integrations_slack) } it { is_expected.to include(*fields) } it { is_expected.not_to include(*jira_fields) } @@ -48,14 +48,14 @@ RSpec.describe ServicesHelper do end context 'Jira service' do - let(:integration) { build(:jira_service) } + let(:integration) { build(:jira_integration) } it { is_expected.to include(*fields, *jira_fields) } end end describe '#scoped_reset_integration_path' do - let(:integration) { build_stubbed(:jira_service) } + let(:integration) { build_stubbed(:jira_integration) } let(:group) { nil } subject { helper.scoped_reset_integration_path(integration, group: group) } @@ -75,7 +75,7 @@ RSpec.describe ServicesHelper do end context 'when a new integration is not persisted' do - let_it_be(:integration) { build(:jira_service) } + let_it_be(:integration) { build(:jira_integration) } it 'returns an empty string' do is_expected.to eq('') diff --git a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb index 7557b9a118d..503477b2115 100644 --- a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb +++ b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb @@ -118,7 +118,7 @@ RSpec.describe Banzai::Filter::References::ExternalIssueReferenceFilter do end context "redmine project" do - let_it_be(:service) { create(:redmine_service, project: project) } + let_it_be(:integration) { create(:redmine_integration, project: project) } before do project.update!(issues_enabled: false) @@ -183,7 +183,7 @@ RSpec.describe Banzai::Filter::References::ExternalIssueReferenceFilter do end context "jira project" do - let_it_be(:service) { create(:jira_service, project: project) } + let_it_be(:service) { create(:jira_integration, project: project) } let(:reference) { issue.to_reference } diff --git a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb index 7fe82420364..58864aac084 100644 --- a/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb +++ b/spec/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2_spec.rb @@ -3,18 +3,18 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::BackfillJiraTrackerDeploymentType2, :migration, schema: 20201028182809 do - let_it_be(:jira_service_temp) { described_class::JiraServiceTemp } + let_it_be(:jira_integration_temp) { described_class::JiraServiceTemp } let_it_be(:jira_tracker_data_temp) { described_class::JiraTrackerDataTemp } let_it_be(:atlassian_host) { 'https://api.atlassian.net' } let_it_be(:mixedcase_host) { 'https://api.AtlassiaN.nEt' } let_it_be(:server_host) { 'https://my.server.net' } - let(:jira_service) { jira_service_temp.create!(type: 'JiraService', active: true, category: 'issue_tracker') } + let(:jira_integration) { jira_integration_temp.create!(type: 'JiraService', active: true, category: 'issue_tracker') } subject { described_class.new } def create_tracker_data(options = {}) - jira_tracker_data_temp.create!({ service_id: jira_service.id }.merge(options)) + jira_tracker_data_temp.create!({ service_id: jira_integration.id }.merge(options)) end describe '#perform' do diff --git a/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb b/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb index 80879c8c6d9..f2cd2acd4f3 100644 --- a/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb @@ -283,11 +283,11 @@ RSpec.describe Gitlab::BackgroundMigration::MigrateIssueTrackersSensitiveData, s end context 'with Jira service with invalid properties, valid Jira service and valid bugzilla service' do - let!(:jira_service_invalid) do + let!(:jira_integration_invalid) do services.create!(id: 19, title: 'invalid - title', description: 'invalid - description', type: 'JiraService', properties: 'invalid data', category: 'issue_tracker') end - let!(:jira_service_valid) do + let!(:jira_integration_valid) do services.create!(id: 20, type: 'JiraService', properties: jira_properties.to_json, category: 'issue_tracker') end @@ -298,21 +298,21 @@ RSpec.describe Gitlab::BackgroundMigration::MigrateIssueTrackersSensitiveData, s it 'migrates data for the valid service' do subject - jira_service_invalid.reload - expect(JiraTrackerData.find_by(service_id: jira_service_invalid.id)).to be_nil - expect(jira_service_invalid.title).to eq('invalid - title') - expect(jira_service_invalid.description).to eq('invalid - description') - expect(jira_service_invalid.properties).to eq('invalid data') + jira_integration_invalid.reload + expect(JiraTrackerData.find_by(service_id: jira_integration_invalid.id)).to be_nil + expect(jira_integration_invalid.title).to eq('invalid - title') + expect(jira_integration_invalid.description).to eq('invalid - description') + expect(jira_integration_invalid.properties).to eq('invalid data') - jira_service_valid.reload - data = JiraTrackerData.find_by(service_id: jira_service_valid.id) + jira_integration_valid.reload + data = JiraTrackerData.find_by(service_id: jira_integration_valid.id) expect(data.url).to eq(url) expect(data.api_url).to eq(api_url) expect(data.username).to eq(username) expect(data.password).to eq(password) - expect(jira_service_valid.title).to eq(title) - expect(jira_service_valid.description).to eq(description) + expect(jira_integration_valid.title).to eq(title) + expect(jira_integration_valid.description).to eq(description) bugzilla_integration_valid.reload data = IssueTrackerData.find_by(service_id: bugzilla_integration_valid.id) diff --git a/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb index 28291508ac0..fe08cdb1213 100644 --- a/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb +++ b/spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb @@ -140,7 +140,7 @@ RSpec.describe Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService integrations = result[:project].reload.integrations expect(integrations.count).to eq(1) - # Ensures PrometheusService#self_monitoring_project? is true + # Ensures Integrations::Prometheus#self_monitoring_project? is true expect(integrations.first.allow_local_api_url?).to be_truthy end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 98da5bbcb1d..92f694bd6d4 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -369,7 +369,7 @@ project: - emails_on_push_integration - pipelines_email_integration - mattermost_slash_commands_integration -- slack_slash_commands_service +- slack_slash_commands_integration - irker_integration - packagist_integration - pivotaltracker_integration @@ -377,17 +377,17 @@ project: - flowdock_integration - assembla_integration - asana_integration -- slack_service +- slack_integration - microsoft_teams_integration - mattermost_integration - hangouts_chat_integration - unify_circuit_service - buildkite_integration - bamboo_integration -- teamcity_service +- teamcity_integration - pushover_integration -- jira_service -- redmine_service +- jira_integration +- redmine_integration - youtrack_service - custom_issue_tracker_integration - bugzilla_integration @@ -485,7 +485,7 @@ project: - protected_environments - mirror_user - push_rule -- jenkins_service +- jenkins_integration - index_status - feature_usage - approval_rules diff --git a/spec/lib/gitlab/jira_import/base_importer_spec.rb b/spec/lib/gitlab/jira_import/base_importer_spec.rb index 9d8143775f9..479551095de 100644 --- a/spec/lib/gitlab/jira_import/base_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/base_importer_spec.rb @@ -9,10 +9,10 @@ RSpec.describe Gitlab::JiraImport::BaseImporter do describe 'with any inheriting class' do context 'when project validation is ok' do - let!(:jira_service) { create(:jira_service, project: project) } + let!(:jira_integration) { create(:jira_integration, project: project) } before do - stub_jira_service_test + stub_jira_integration_test allow(Gitlab::JiraImport).to receive(:validate_project_settings!) end diff --git a/spec/lib/gitlab/jira_import/issues_importer_spec.rb b/spec/lib/gitlab/jira_import/issues_importer_spec.rb index 4a32f0fd3a9..aead5405bd1 100644 --- a/spec/lib/gitlab/jira_import/issues_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/issues_importer_spec.rb @@ -9,12 +9,12 @@ RSpec.describe Gitlab::JiraImport::IssuesImporter do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:jira_import) { create(:jira_import_state, project: project, user: current_user) } - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } subject { described_class.new(project) } before do - stub_jira_service_test + stub_jira_integration_test end describe '#imported_items_cache_key' do diff --git a/spec/lib/gitlab/jira_import/labels_importer_spec.rb b/spec/lib/gitlab/jira_import/labels_importer_spec.rb index db98a83cb3c..71440590815 100644 --- a/spec/lib/gitlab/jira_import/labels_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/labels_importer_spec.rb @@ -8,7 +8,7 @@ RSpec.describe Gitlab::JiraImport::LabelsImporter do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } let(:importer) { described_class.new(project) } @@ -20,7 +20,7 @@ RSpec.describe Gitlab::JiraImport::LabelsImporter do describe '#execute', :clean_gitlab_redis_cache do before do - stub_jira_service_test + stub_jira_integration_test end context 'when label is missing from jira import' do diff --git a/spec/lib/gitlab/jira_import_spec.rb b/spec/lib/gitlab/jira_import_spec.rb index 94fdff984d5..a7c73e79641 100644 --- a/spec/lib/gitlab/jira_import_spec.rb +++ b/spec/lib/gitlab/jira_import_spec.rb @@ -31,12 +31,12 @@ RSpec.describe Gitlab::JiraImport do end end - context 'when Jira service was not setup' do + context 'when Jira integration was not setup' do it_behaves_like 'raise Jira import error', 'Jira integration not configured.' end - context 'when Jira service exists' do - let!(:jira_service) { create(:jira_service, project: project, active: true) } + context 'when Jira integration exists' do + let!(:jira_integration) { create(:jira_integration, project: project, active: true) } context 'when Jira connection is not valid' do before do @@ -50,14 +50,14 @@ RSpec.describe Gitlab::JiraImport do end before do - stub_jira_service_test + stub_jira_integration_test end context 'without user param' do it_behaves_like 'jira configuration base checks' context 'when jira connection is valid' do - let!(:jira_service) { create(:jira_service, project: project, active: true) } + let!(:jira_integration) { create(:jira_integration, project: project, active: true) } it 'does not return any error' do expect { subject }.not_to raise_error @@ -77,8 +77,8 @@ RSpec.describe Gitlab::JiraImport do it_behaves_like 'jira configuration base checks' - context 'when jira service is configured' do - let!(:jira_service) { create(:jira_service, project: project, active: true) } + context 'when jira integration is configured' do + let!(:jira_integration) { create(:jira_integration, project: project, active: true) } context 'when issues feature is disabled' do let_it_be(:project, reload: true) { create(:project, :issues_disabled) } @@ -96,7 +96,7 @@ RSpec.describe Gitlab::JiraImport do context 'when user does not have permissions to run the import' do before do - create(:jira_service, project: project, active: true) + create(:jira_integration, project: project, active: true) project.add_developer(user) end diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb index 229d49868d4..e040ddb1be4 100644 --- a/spec/lib/gitlab/reference_extractor_spec.rb +++ b/spec/lib/gitlab/reference_extractor_spec.rb @@ -227,7 +227,7 @@ RSpec.describe Gitlab::ReferenceExtractor do context 'with an inactive external issue tracker' do let(:project) { create(:project) } - let!(:jira_service) { create(:jira_service, project: project, active: false) } + let!(:jira_integration) { create(:jira_integration, project: project, active: false) } let(:issue) { create(:issue, project: project) } context 'when GitLab issues are enabled' do diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index ea82de186f5..8652f9c4a58 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -435,8 +435,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do create(:issue, project: project, author: User.support_bot) create(:note, project: project, noteable: issue, author: user) create(:todo, project: project, target: issue, author: user) - create(:jira_service, :jira_cloud_service, active: true, project: create(:project, :jira_dvcs_cloud, creator: user)) - create(:jira_service, active: true, project: create(:project, :jira_dvcs_server, creator: user)) + create(:jira_integration, :jira_cloud_service, active: true, project: create(:project, :jira_dvcs_cloud, creator: user)) + create(:jira_integration, active: true, project: create(:project, :jira_dvcs_server, creator: user)) end expect(described_class.usage_activity_by_stage_plan({})).to include( diff --git a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb index 2999332509a..ea5192375f3 100644 --- a/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb +++ b/spec/migrations/20190924152703_migrate_issue_trackers_data_spec.rb @@ -14,11 +14,11 @@ RSpec.describe MigrateIssueTrackersData do } end - let!(:jira_service) do + let!(:jira_integration) do services.create!(type: 'JiraService', properties: properties, category: 'issue_tracker') end - let!(:jira_service_nil) do + let!(:jira_integration_nil) do services.create!(type: 'JiraService', properties: nil, category: 'issue_tracker') end @@ -55,7 +55,7 @@ RSpec.describe MigrateIssueTrackersData do freeze_time do migrate! - expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_service.id, bugzilla_integration.id) + expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_integration.id, bugzilla_integration.id) expect(migration_name).to be_scheduled_delayed_migration(6.minutes, youtrack_service.id, gitlab_service.id) expect(BackgroundMigrationWorker.jobs.size).to eq(2) end diff --git a/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb b/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb index 5516e2af3f1..90bbdca4d9c 100644 --- a/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb +++ b/spec/migrations/20200130145430_reschedule_migrate_issue_trackers_data_spec.rb @@ -14,11 +14,11 @@ RSpec.describe RescheduleMigrateIssueTrackersData do } end - let!(:jira_service) do + let!(:jira_integration) do services.create!(id: 10, type: 'JiraService', properties: properties, category: 'issue_tracker') end - let!(:jira_service_nil) do + let!(:jira_integration_nil) do services.create!(id: 11, type: 'JiraService', properties: nil, category: 'issue_tracker') end @@ -56,7 +56,7 @@ RSpec.describe RescheduleMigrateIssueTrackersData do freeze_time do migrate! - expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_service.id, bugzilla_integration.id) + expect(migration_name).to be_scheduled_delayed_migration(3.minutes, jira_integration.id, bugzilla_integration.id) expect(migration_name).to be_scheduled_delayed_migration(6.minutes, youtrack_service.id, gitlab_service.id) expect(BackgroundMigrationWorker.jobs.size).to eq(2) end diff --git a/spec/migrations/delete_template_services_duplicated_by_type_spec.rb b/spec/migrations/delete_template_services_duplicated_by_type_spec.rb index b5a29436159..577fea984da 100644 --- a/spec/migrations/delete_template_services_duplicated_by_type_spec.rb +++ b/spec/migrations/delete_template_services_duplicated_by_type_spec.rb @@ -14,11 +14,11 @@ RSpec.describe DeleteTemplateServicesDuplicatedByType do end it 'deletes service templates duplicated by type except the one with the lowest ID' do - jenkins_service_id = services.where(type: 'JenkinsService').order(:id).pluck(:id).first - jira_service_id = services.where(type: 'JiraService').pluck(:id).first + jenkins_integration_id = services.where(type: 'JenkinsService').order(:id).pluck(:id).first + jira_integration_id = services.where(type: 'JiraService').pluck(:id).first migrate! - expect(services.pluck(:id)).to contain_exactly(jenkins_service_id, jira_service_id) + expect(services.pluck(:id)).to contain_exactly(jenkins_integration_id, jira_integration_id) end end diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb index cf73460bf1e..8de3ebb18b9 100644 --- a/spec/models/ci/pipeline_schedule_spec.rb +++ b/spec/models/ci/pipeline_schedule_spec.rb @@ -123,8 +123,15 @@ RSpec.describe Ci::PipelineSchedule do '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 0) '*/5 * * * *' | '0 * * * *' | (1.day.in_minutes / 2.hours.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 11, 0) | Time.zone.local(2021, 5, 27, 12, 5) '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) - '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) + '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 10).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) + '*/5 * * * *' | '0 1 * * *' | (1.day.in_minutes / 8).to_i | true | Time.zone.local(2021, 5, 27, 1, 0) | Time.zone.local(2021, 5, 28, 1, 0) '*/5 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 0) | Time.zone.local(2021, 6, 1, 1, 0) + '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 0) + '*/9 * * * *' | '0 1 1 * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 1, 9) | Time.zone.local(2021, 6, 1, 1, 9) + '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | true | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0) + '*/5 * * * *' | '59 14 * * *' | (1.day.in_minutes / 1.hour.in_minutes).to_i | false | Time.zone.local(2021, 5, 1, 15, 0) | Time.zone.local(2021, 5, 2, 15, 0) + '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | true | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 45) + '*/5 * * * *' | '45 21 1 2 *' | (1.day.in_minutes / 5).to_i | false | Time.zone.local(2021, 2, 1, 21, 45) | Time.zone.local(2022, 2, 1, 21, 50) end with_them do diff --git a/spec/models/concerns/has_integrations_spec.rb b/spec/models/concerns/has_integrations_spec.rb index 6e55a1c8b01..6b3f75bfcfd 100644 --- a/spec/models/concerns/has_integrations_spec.rb +++ b/spec/models/concerns/has_integrations_spec.rb @@ -7,14 +7,14 @@ RSpec.describe HasIntegrations do let_it_be(:project_2) { create(:project) } let_it_be(:project_3) { create(:project) } let_it_be(:project_4) { create(:project) } - let_it_be(:instance_integration) { create(:jira_service, :instance) } + let_it_be(:instance_integration) { create(:jira_integration, :instance) } before do - create(:jira_service, project: project_1, inherit_from_id: instance_integration.id) - create(:jira_service, project: project_2, inherit_from_id: nil) - create(:jira_service, group: create(:group), project: nil, inherit_from_id: nil) - create(:jira_service, project: project_3, inherit_from_id: nil) - create(:slack_service, project: project_4, inherit_from_id: nil) + create(:jira_integration, project: project_1, inherit_from_id: instance_integration.id) + create(:jira_integration, project: project_2, inherit_from_id: nil) + create(:jira_integration, group: create(:group), project: nil, inherit_from_id: nil) + create(:jira_integration, project: project_3, inherit_from_id: nil) + create(:integrations_slack, project: project_4, inherit_from_id: nil) end describe '.with_custom_integration_for' do diff --git a/spec/models/concerns/integrations/has_data_fields_spec.rb b/spec/models/concerns/integrations/has_data_fields_spec.rb index 54e0ac9c5a5..b28fef571c6 100644 --- a/spec/models/concerns/integrations/has_data_fields_spec.rb +++ b/spec/models/concerns/integrations/has_data_fields_spec.rb @@ -84,7 +84,7 @@ RSpec.describe Integrations::HasDataFields do context 'when data are stored in data_fields' do let(:service) do - create(:jira_service, url: url, username: username) + create(:jira_integration, url: url, username: username) end it_behaves_like 'data fields' @@ -111,45 +111,52 @@ RSpec.describe Integrations::HasDataFields do end context 'when data are stored in properties' do - let(:service) { create(:jira_service, :without_properties_callback, properties: properties) } + let(:integration) { create(:jira_integration, :without_properties_callback, properties: properties) } - it_behaves_like 'data fields' + it_behaves_like 'data fields' do + let(:service) { integration } + end describe '{arg}_was?' do it 'returns nil when the property has not been assigned a new value' do - service.username = 'new_username' - service.validate - expect(service.url_was).to be_nil + integration.username = 'new_username' + integration.validate + + expect(integration.url_was).to be_nil end it 'returns initial value when the property has been assigned a different value' do - service.url = 'http://example.com' - service.validate - expect(service.url_was).to eq('http://url.com') + integration.url = 'http://example.com' + integration.validate + + expect(integration.url_was).to eq('http://url.com') end it 'returns initial value when the property has been re-assigned the same value' do - service.url = 'http://url.com' - service.validate - expect(service.url_was).to eq('http://url.com') + integration.url = 'http://url.com' + integration.validate + + expect(integration.url_was).to eq('http://url.com') end end end context 'when data are stored in both properties and data_fields' do - let(:service) do - create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |integration| + let(:integration) do + create(:jira_integration, :without_properties_callback, active: false, properties: properties).tap do |integration| create(:jira_tracker_data, properties.merge(integration: integration)) end end - it_behaves_like 'data fields' + it_behaves_like 'data fields' do + let(:service) { integration } + end describe '{arg}_was?' do it 'returns nil' do - service.url = 'http://example.com' - service.validate - expect(service.url_was).to be_nil + integration.url = 'http://example.com' + integration.validate + expect(integration.url_was).to be_nil end end end diff --git a/spec/models/deployment_metrics_spec.rb b/spec/models/deployment_metrics_spec.rb index fadfc1b63ac..a7a58cc9f85 100644 --- a/spec/models/deployment_metrics_spec.rb +++ b/spec/models/deployment_metrics_spec.rb @@ -20,7 +20,7 @@ RSpec.describe DeploymentMetrics do end context 'with a Prometheus Service' do - let(:prometheus_service) { instance_double(PrometheusService, can_query?: true, configured?: true) } + let(:prometheus_service) { instance_double(::Integrations::Prometheus, can_query?: true, configured?: true) } before do allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service @@ -30,7 +30,7 @@ RSpec.describe DeploymentMetrics do end context 'with a Prometheus Service that cannot query' do - let(:prometheus_service) { instance_double(PrometheusService, configured?: true, can_query?: false) } + let(:prometheus_service) { instance_double(::Integrations::Prometheus, configured?: true, can_query?: false) } before do allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service @@ -40,7 +40,7 @@ RSpec.describe DeploymentMetrics do end context 'with a Prometheus Service that is not configured' do - let(:prometheus_service) { instance_double(PrometheusService, configured?: false, can_query?: false) } + let(:prometheus_service) { instance_double(::Integrations::Prometheus, configured?: false, can_query?: false) } before do allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service @@ -64,7 +64,7 @@ RSpec.describe DeploymentMetrics do describe '#metrics' do let(:deployment) { create(:deployment, :success) } - let(:prometheus_adapter) { instance_double(PrometheusService, can_query?: true, configured?: true) } + let(:prometheus_adapter) { instance_double(::Integrations::Prometheus, can_query?: true, configured?: true) } let(:deployment_metrics) { described_class.new(deployment.project, deployment) } subject { deployment_metrics.metrics } diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 8f4bc43c38a..0a08b15a1eb 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -565,11 +565,11 @@ RSpec.describe Group do describe '.without_integration' do let(:another_group) { create(:group) } - let(:instance_integration) { build(:jira_service, :instance) } + let(:instance_integration) { build(:jira_integration, :instance) } before do - create(:jira_service, group: group, project: nil) - create(:slack_service, group: another_group, project: nil) + create(:jira_integration, group: group, project: nil) + create(:integrations_slack, group: another_group, project: nil) end it 'returns groups without integration' do diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb index d4ea3e5d08a..e7661bf3eed 100644 --- a/spec/models/integration_spec.rb +++ b/spec/models/integration_spec.rb @@ -68,9 +68,9 @@ RSpec.describe Integration do describe 'Scopes' do describe '.by_type' do - let!(:service1) { create(:jira_service) } - let!(:service2) { create(:jira_service) } - let!(:service3) { create(:redmine_service) } + let!(:service1) { create(:jira_integration) } + let!(:service2) { create(:jira_integration) } + let!(:service3) { create(:redmine_integration) } subject { described_class.by_type(type) } @@ -88,8 +88,8 @@ RSpec.describe Integration do end describe '.for_group' do - let!(:service1) { create(:jira_service, project_id: nil, group_id: group.id) } - let!(:service2) { create(:jira_service) } + let!(:service1) { create(:jira_integration, project_id: nil, group_id: group.id) } + let!(:service2) { create(:jira_integration) } it 'returns the right group service' do expect(described_class.for_group(group)).to match_array([service1]) @@ -234,15 +234,17 @@ RSpec.describe Integration do end describe '.find_or_initialize_non_project_specific_integration' do - let!(:service1) { create(:jira_service, project_id: nil, group_id: group.id) } - let!(:service2) { create(:jira_service) } + let!(:integration_1) { create(:jira_integration, project_id: nil, group_id: group.id) } + let!(:integration_2) { create(:jira_integration) } - it 'returns the right service' do - expect(Integration.find_or_initialize_non_project_specific_integration('jira', group_id: group)).to eq(service1) + it 'returns the right integration' do + expect(Integration.find_or_initialize_non_project_specific_integration('jira', group_id: group)) + .to eq(integration_1) end - it 'does not create a new service' do - expect { Integration.find_or_initialize_non_project_specific_integration('redmine', group_id: group) }.not_to change { Integration.count } + it 'does not create a new integration' do + expect { Integration.find_or_initialize_non_project_specific_integration('redmine', group_id: group) } + .not_to change(Integration, :count) end end @@ -280,7 +282,7 @@ RSpec.describe Integration do context 'with a few existing instances' do before do - create(:jira_service, :instance) + create(:jira_integration, :instance) end it_behaves_like 'service instances' @@ -326,7 +328,7 @@ RSpec.describe Integration do context 'with a few existing templates' do before do - create(:jira_service, :template) + create(:jira_integration, :template) end it 'creates the rest of the service templates' do @@ -353,7 +355,7 @@ RSpec.describe Integration do end context 'when integration is an instance-level integration' do - let(:integration) { create(:jira_service, :instance) } + let(:integration) { create(:jira_integration, :instance) } it 'sets inherit_from_id from integration' do service = described_class.build_from_integration(integration, project_id: project.id) @@ -363,7 +365,7 @@ RSpec.describe Integration do end context 'when integration is a group-level integration' do - let(:integration) { create(:jira_service, group: group, project: nil) } + let(:integration) { create(:jira_integration, group: group, project: nil) } it 'sets inherit_from_id from integration' do service = described_class.build_from_integration(integration, project_id: project.id) @@ -418,7 +420,7 @@ RSpec.describe Integration do context 'when data are stored in properties' do let(:properties) { data_params } let!(:integration) do - create(:jira_service, :without_properties_callback, template: true, properties: properties.merge(additional: 'something')) + create(:jira_integration, :without_properties_callback, template: true, properties: properties.merge(additional: 'something')) end it_behaves_like 'service creation from an integration' @@ -426,7 +428,7 @@ RSpec.describe Integration do context 'when data are stored in separated fields' do let(:integration) do - create(:jira_service, :template, data_params.merge(properties: {})) + create(:jira_integration, :template, data_params.merge(properties: {})) end it_behaves_like 'service creation from an integration' @@ -435,7 +437,7 @@ RSpec.describe Integration do context 'when data are stored in both properties and separated fields' do let(:properties) { data_params } let(:integration) do - create(:jira_service, :without_properties_callback, active: true, template: true, properties: properties).tap do |integration| + create(:jira_integration, :without_properties_callback, active: true, template: true, properties: properties).tap do |integration| create(:jira_tracker_data, data_params.merge(integration: integration)) end end @@ -472,26 +474,26 @@ RSpec.describe Integration do end describe '.default_integration' do - context 'with an instance-level service' do - let_it_be(:instance_service) { create(:jira_service, :instance) } + context 'with an instance-level integration' do + let_it_be(:instance_integration) { create(:jira_integration, :instance) } - it 'returns the instance service' do - expect(described_class.default_integration('JiraService', project)).to eq(instance_service) + it 'returns the instance integration' do + expect(described_class.default_integration('JiraService', project)).to eq(instance_integration) end - it 'returns nil for nonexistent service type' do + it 'returns nil for nonexistent integration type' do expect(described_class.default_integration('HipchatService', project)).to eq(nil) end - context 'with a group service' do - let_it_be(:group_service) { create(:jira_service, group_id: group.id, project_id: nil) } + context 'with a group integration' do + let_it_be(:group_integration) { create(:jira_integration, group_id: group.id, project_id: nil) } - it 'returns the group service for a project' do - expect(described_class.default_integration('JiraService', project)).to eq(group_service) + it 'returns the group integration for a project' do + expect(described_class.default_integration('JiraService', project)).to eq(group_integration) end - it 'returns the instance service for a group' do - expect(described_class.default_integration('JiraService', group)).to eq(instance_service) + it 'returns the instance integration for a group' do + expect(described_class.default_integration('JiraService', group)).to eq(instance_integration) end context 'with a subgroup' do @@ -499,27 +501,27 @@ RSpec.describe Integration do let!(:project) { create(:project, group: subgroup) } - it 'returns the closest group service for a project' do - expect(described_class.default_integration('JiraService', project)).to eq(group_service) + it 'returns the closest group integration for a project' do + expect(described_class.default_integration('JiraService', project)).to eq(group_integration) end - it 'returns the closest group service for a subgroup' do - expect(described_class.default_integration('JiraService', subgroup)).to eq(group_service) + it 'returns the closest group integration for a subgroup' do + expect(described_class.default_integration('JiraService', subgroup)).to eq(group_integration) end - context 'having a service with custom settings' do - let!(:subgroup_service) { create(:jira_service, group_id: subgroup.id, project_id: nil) } + context 'having a integration with custom settings' do + let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil) } - it 'returns the closest group service for a project' do - expect(described_class.default_integration('JiraService', project)).to eq(subgroup_service) + it 'returns the closest group integration for a project' do + expect(described_class.default_integration('JiraService', project)).to eq(subgroup_integration) end end - context 'having a service inheriting settings' do - let!(:subgroup_service) { create(:jira_service, group_id: subgroup.id, project_id: nil, inherit_from_id: group_service.id) } + context 'having a integration inheriting settings' do + let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil, inherit_from_id: group_integration.id) } - it 'returns the closest group service which does not inherit from its parent for a project' do - expect(described_class.default_integration('JiraService', project)).to eq(group_service) + it 'returns the closest group integration which does not inherit from its parent for a project' do + expect(described_class.default_integration('JiraService', project)).to eq(group_integration) end end end @@ -528,7 +530,7 @@ RSpec.describe Integration do end describe '.create_from_active_default_integrations' do - context 'with an active service template' do + context 'with an active integration template' do let_it_be(:template_integration) { create(:prometheus_service, :template, api_url: 'https://prometheus.template.com/') } it 'creates a service from the template' do @@ -669,11 +671,8 @@ RSpec.describe Integration do end describe '.integration_name_to_model' do - it 'returns the model for the given service name', :aggregate_failures do + it 'returns the model for the given service name' do expect(described_class.integration_name_to_model('asana')).to eq(Integrations::Asana) - # TODO We can remove this test when all models have been namespaced: - # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60968#note_570994955 - expect(described_class.integration_name_to_model('prometheus')).to eq(PrometheusService) end it 'raises an error if service name is invalid' do diff --git a/spec/models/integrations/jenkins_spec.rb b/spec/models/integrations/jenkins_spec.rb index 2374dfe4480..792ff3e8763 100644 --- a/spec/models/integrations/jenkins_spec.rb +++ b/spec/models/integrations/jenkins_spec.rb @@ -30,8 +30,8 @@ RSpec.describe Integrations::Jenkins do end describe 'username validation' do - before do - @jenkins_service = described_class.create!( + let(:jenkins_integration) do + described_class.create!( active: active, project: project, properties: { @@ -43,7 +43,7 @@ RSpec.describe Integrations::Jenkins do ) end - subject { @jenkins_service } + subject { jenkins_integration } context 'when the service is active' do let(:active) { true } @@ -84,7 +84,7 @@ RSpec.describe Integrations::Jenkins do describe '#hook_url' do let(:username) { nil } let(:password) { nil } - let(:jenkins_service) do + let(:jenkins_integration) do described_class.new( project: project, properties: { @@ -96,7 +96,7 @@ RSpec.describe Integrations::Jenkins do ) end - subject { jenkins_service.hook_url } + subject { jenkins_integration.hook_url } context 'when the jenkins_url has no relative path' do let(:jenkins_url) { 'http://jenkins.example.com/' } @@ -138,10 +138,10 @@ RSpec.describe Integrations::Jenkins do user = create(:user, username: 'username') project = create(:project, name: 'project') push_sample_data = Gitlab::DataBuilder::Push.build_sample(project, user) - jenkins_service = described_class.create!(jenkins_params) + jenkins_integration = described_class.create!(jenkins_params) stub_request(:post, jenkins_hook_url).with(headers: { 'Authorization' => jenkins_authorization }) - result = jenkins_service.test(push_sample_data) + result = jenkins_integration.test(push_sample_data) expect(result).to eq({ success: true, result: '' }) end @@ -152,20 +152,20 @@ RSpec.describe Integrations::Jenkins do let(:namespace) { create(:group, :private) } let(:project) { create(:project, :private, name: 'project', namespace: namespace) } let(:push_sample_data) { Gitlab::DataBuilder::Push.build_sample(project, user) } - let(:jenkins_service) { described_class.create!(jenkins_params) } + let(:jenkins_integration) { described_class.create!(jenkins_params) } before do stub_request(:post, jenkins_hook_url) end it 'invokes the Jenkins API' do - jenkins_service.execute(push_sample_data) + jenkins_integration.execute(push_sample_data) expect(a_request(:post, jenkins_hook_url)).to have_been_made.once end it 'adds default web hook headers to the request' do - jenkins_service.execute(push_sample_data) + jenkins_integration.execute(push_sample_data) expect( a_request(:post, jenkins_hook_url) @@ -174,7 +174,7 @@ RSpec.describe Integrations::Jenkins do end it 'request url contains properly serialized username and password' do - jenkins_service.execute(push_sample_data) + jenkins_integration.execute(push_sample_data) expect( a_request(:post, 'http://jenkins.example.com/project/my_project') @@ -187,8 +187,8 @@ RSpec.describe Integrations::Jenkins do let(:project) { create(:project) } context 'when a password was previously set' do - before do - @jenkins_service = described_class.create!( + let(:jenkins_integration) do + described_class.create!( project: project, properties: { jenkins_url: 'http://jenkins.example.com/', @@ -199,42 +199,47 @@ RSpec.describe Integrations::Jenkins do end it 'resets password if url changed' do - @jenkins_service.jenkins_url = 'http://jenkins-edited.example.com/' - @jenkins_service.save! - expect(@jenkins_service.password).to be_nil + jenkins_integration.jenkins_url = 'http://jenkins-edited.example.com/' + jenkins_integration.save! + + expect(jenkins_integration.password).to be_nil end it 'resets password if username is blank' do - @jenkins_service.username = '' - @jenkins_service.save! - expect(@jenkins_service.password).to be_nil + jenkins_integration.username = '' + jenkins_integration.save! + + expect(jenkins_integration.password).to be_nil end it 'does not reset password if username changed' do - @jenkins_service.username = 'some_name' - @jenkins_service.save! - expect(@jenkins_service.password).to eq('password') + jenkins_integration.username = 'some_name' + jenkins_integration.save! + + expect(jenkins_integration.password).to eq('password') end it 'does not reset password if new url is set together with password, even if it\'s the same password' do - @jenkins_service.jenkins_url = 'http://jenkins_edited.example.com/' - @jenkins_service.password = 'password' - @jenkins_service.save! - expect(@jenkins_service.password).to eq('password') - expect(@jenkins_service.jenkins_url).to eq('http://jenkins_edited.example.com/') + jenkins_integration.jenkins_url = 'http://jenkins_edited.example.com/' + jenkins_integration.password = 'password' + jenkins_integration.save! + + expect(jenkins_integration.password).to eq('password') + expect(jenkins_integration.jenkins_url).to eq('http://jenkins_edited.example.com/') end it 'resets password if url changed, even if setter called multiple times' do - @jenkins_service.jenkins_url = 'http://jenkins1.example.com/' - @jenkins_service.jenkins_url = 'http://jenkins1.example.com/' - @jenkins_service.save! - expect(@jenkins_service.password).to be_nil + jenkins_integration.jenkins_url = 'http://jenkins1.example.com/' + jenkins_integration.jenkins_url = 'http://jenkins1.example.com/' + jenkins_integration.save! + + expect(jenkins_integration.password).to be_nil end end context 'when no password was previously set' do - before do - @jenkins_service = described_class.create!( + let(:jenkins_integration) do + described_class.create!( project: create(:project), properties: { jenkins_url: 'http://jenkins.example.com/', @@ -244,11 +249,12 @@ RSpec.describe Integrations::Jenkins do end it 'saves password if new url is set together with password' do - @jenkins_service.jenkins_url = 'http://jenkins_edited.example.com/' - @jenkins_service.password = 'password' - @jenkins_service.save! - expect(@jenkins_service.password).to eq('password') - expect(@jenkins_service.jenkins_url).to eq('http://jenkins_edited.example.com/') + jenkins_integration.jenkins_url = 'http://jenkins_edited.example.com/' + jenkins_integration.password = 'password' + jenkins_integration.save! + + expect(jenkins_integration.password).to eq('password') + expect(jenkins_integration.jenkins_url).to eq('http://jenkins_edited.example.com/') end end end diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb index f6310866773..d63f5261915 100644 --- a/spec/models/integrations/jira_spec.rb +++ b/spec/models/integrations/jira_spec.rb @@ -14,7 +14,7 @@ RSpec.describe Integrations::Jira do let(:password) { 'jira-password' } let(:transition_id) { 'test27' } let(:server_info_results) { { 'deploymentType' => 'Cloud' } } - let(:jira_service) do + let(:jira_integration) do described_class.new( project: project, url: url, @@ -100,7 +100,7 @@ RSpec.describe Integrations::Jira do end describe '#fields' do - let(:service) { create(:jira_service) } + let(:service) { create(:jira_integration) } subject(:fields) { service.fields } @@ -164,13 +164,13 @@ RSpec.describe Integrations::Jira do end context 'when loading serverInfo' do - let(:jira_service) { subject } + let(:jira_integration) { subject } context 'from a Cloud instance' do let(:server_info_results) { { 'deploymentType' => 'Cloud' } } it 'is detected' do - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy end end @@ -178,7 +178,7 @@ RSpec.describe Integrations::Jira do let(:server_info_results) { { 'deploymentType' => 'Server' } } it 'is detected' do - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy end end @@ -189,7 +189,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://example-api.atlassian.net' } it 'deployment_type is set to cloud' do - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy end end @@ -197,7 +197,7 @@ RSpec.describe Integrations::Jira do let(:api_url) { 'http://my-jira-api.someserver.com' } it 'deployment_type is set to server' do - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy end end end @@ -210,7 +210,7 @@ RSpec.describe Integrations::Jira do it 'deployment_type is set to cloud' do expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url) - expect(jira_service.jira_tracker_data.deployment_cloud?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_cloud?).to be_truthy end end @@ -219,7 +219,7 @@ RSpec.describe Integrations::Jira do it 'deployment_type is set to server' do expect(Gitlab::AppLogger).to receive(:warn).with(message: "Jira API returned no ServerInfo, setting deployment_type from URL", server_info: server_info_results, url: api_url) - expect(jira_service.jira_tracker_data.deployment_server?).to be_truthy + expect(jira_integration.jira_tracker_data.deployment_server?).to be_truthy end end end @@ -487,7 +487,7 @@ RSpec.describe Integrations::Jira do context 'when data are stored in properties' do let(:properties) { data_params } let!(:service) do - create(:jira_service, :without_properties_callback, properties: properties.merge(additional: 'something')) + create(:jira_integration, :without_properties_callback, properties: properties.merge(additional: 'something')) end it_behaves_like 'handles jira fields' @@ -495,7 +495,7 @@ RSpec.describe Integrations::Jira do context 'when data are stored in separated fields' do let(:service) do - create(:jira_service, data_params.merge(properties: {})) + create(:jira_integration, data_params.merge(properties: {})) end it_behaves_like 'handles jira fields' @@ -504,7 +504,7 @@ RSpec.describe Integrations::Jira do context 'when data are stored in both properties and separated fields' do let(:properties) { data_params } let(:service) do - create(:jira_service, :without_properties_callback, active: false, properties: properties).tap do |integration| + create(:jira_integration, :without_properties_callback, active: false, properties: properties).tap do |integration| create(:jira_tracker_data, data_params.merge(integration: integration)) end end @@ -522,7 +522,7 @@ RSpec.describe Integrations::Jira do end it 'call the Jira API to get the issue' do - jira_service.find_issue(issue_key) + jira_integration.find_issue(issue_key) expect(WebMock).to have_requested(:get, issue_url) end @@ -531,7 +531,7 @@ RSpec.describe Integrations::Jira do let(:issue_url) { "#{url}/rest/api/2/issue/#{issue_key}?expand=renderedFields,transitions" } it 'calls the Jira API with the options to get the issue' do - jira_service.find_issue(issue_key, rendered_fields: true, transitions: true) + jira_integration.find_issue(issue_key, rendered_fields: true, transitions: true) expect(WebMock).to have_requested(:get, issue_url) end @@ -558,16 +558,16 @@ RSpec.describe Integrations::Jira do end subject(:close_issue) do - jira_service.close_issue(resource, ExternalIssue.new(issue_key, project)) + jira_integration.close_issue(resource, ExternalIssue.new(issue_key, project)) end before do - jira_service.jira_issue_transition_id = '999' + jira_integration.jira_issue_transition_id = '999' # These stubs are needed to test Integrations::Jira#close_issue. # We close the issue then do another request to API to check if it got closed. # Here is stubbed the API return with a closed and an opened issues. - open_issue = JIRA::Resource::Issue.new(jira_service.client, attrs: issue_fields.deep_stringify_keys) + open_issue = JIRA::Resource::Issue.new(jira_integration.client, attrs: issue_fields.deep_stringify_keys) closed_issue = open_issue.dup allow(open_issue).to receive(:resolution).and_return(false) allow(closed_issue).to receive(:resolution).and_return(true) @@ -585,7 +585,7 @@ RSpec.describe Integrations::Jira do let(:external_issue) { ExternalIssue.new('JIRA-123', project) } def close_issue - jira_service.close_issue(resource, external_issue, current_user) + jira_integration.close_issue(resource, external_issue, current_user) end it 'calls Jira API' do @@ -636,7 +636,7 @@ RSpec.describe Integrations::Jira do context 'when "comment_on_event_enabled" is set to false' do it 'creates Remote Link reference but does not create comment' do - allow(jira_service).to receive_messages(comment_on_event_enabled: false) + allow(jira_integration).to receive_messages(comment_on_event_enabled: false) close_issue expect(WebMock).not_to have_requested(:post, comment_url) @@ -709,12 +709,12 @@ RSpec.describe Integrations::Jira do end it 'logs exception when transition id is not valid' do - allow(jira_service).to receive(:log_error) + allow(jira_integration).to receive(:log_error) WebMock.stub_request(:post, transitions_url).with(basic_auth: %w(jira-username jira-password)).and_raise("Bad Request") close_issue - expect(jira_service).to have_received(:log_error).with( + expect(jira_integration).to have_received(:log_error).with( "Issue transition failed", error: hash_including( exception_class: 'StandardError', @@ -734,7 +734,7 @@ RSpec.describe Integrations::Jira do context 'when custom transition IDs are blank' do before do - jira_service.jira_issue_transition_id = '' + jira_integration.jira_issue_transition_id = '' end it 'does not transition the issue' do @@ -755,7 +755,7 @@ RSpec.describe Integrations::Jira do end before do - jira_service.jira_issue_transition_automatic = true + jira_integration.jira_issue_transition_automatic = true close_issue end @@ -789,7 +789,7 @@ RSpec.describe Integrations::Jira do context 'when using multiple transition ids' do before do - allow(jira_service).to receive_messages(jira_issue_transition_id: '1,2,3') + allow(jira_integration).to receive_messages(jira_issue_transition_id: '1,2,3') end it 'calls the api with transition ids separated by comma' do @@ -805,7 +805,7 @@ RSpec.describe Integrations::Jira do end it 'calls the api with transition ids separated by semicolon' do - allow(jira_service).to receive_messages(jira_issue_transition_id: '1;2;3') + allow(jira_integration).to receive_messages(jira_issue_transition_id: '1;2;3') close_issue @@ -864,7 +864,7 @@ RSpec.describe Integrations::Jira do let(:jira_issue) { ExternalIssue.new('JIRA-123', project) } - subject { jira_service.create_cross_reference_note(jira_issue, resource, user) } + subject { jira_integration.create_cross_reference_note(jira_issue, resource, user) } shared_examples 'creates a comment on Jira' do let(:issue_url) { "#{url}/rest/api/2/issue/JIRA-123" } @@ -936,7 +936,7 @@ RSpec.describe Integrations::Jira do let(:server_info_results) { { 'url' => 'http://url', 'deploymentType' => 'Cloud' } } def server_info - jira_service.test(nil) + jira_integration.test(nil) end context 'when the test succeeds' do @@ -946,7 +946,7 @@ RSpec.describe Integrations::Jira do end it 'gets Jira project with API URL if set' do - jira_service.update!(api_url: 'http://jira.api.com') + jira_integration.update!(api_url: 'http://jira.api.com') expect(server_info).to eq(success: true, result: server_info_results) expect(WebMock).to have_requested(:get, /jira.api.com/) @@ -961,13 +961,13 @@ RSpec.describe Integrations::Jira do WebMock.stub_request(:get, test_url).with(basic_auth: [username, password]) .to_raise(JIRA::HTTPError.new(double(message: error_message))) - expect(jira_service).to receive(:log_error).with( + expect(jira_integration).to receive(:log_error).with( 'Error sending message', client_url: 'http://jira.example.com', error: error_message ) - expect(jira_service.test(nil)).to eq(success: false, result: error_message) + expect(jira_integration.test(nil)).to eq(success: false, result: error_message) end end end @@ -983,17 +983,17 @@ RSpec.describe Integrations::Jira do } allow(Gitlab.config).to receive(:issues_tracker).and_return(settings) - service = project.create_jira_service(active: true) + integration = project.create_jira_integration(active: true) - expect(service.url).to eq('http://jira.sample/projects/project_a') - expect(service.api_url).to eq('http://jira.sample/api') + expect(integration.url).to eq('http://jira.sample/projects/project_a') + expect(integration.api_url).to eq('http://jira.sample/api') end end it 'removes trailing slashes from url' do - service = described_class.new(url: 'http://jira.test.com/path/') + integration = described_class.new(url: 'http://jira.test.com/path/') - expect(service.url).to eq('http://jira.test.com/path') + expect(integration.url).to eq('http://jira.test.com/path') end end @@ -1063,19 +1063,65 @@ RSpec.describe Integrations::Jira do describe '#issue_transition_enabled?' do it 'returns true if automatic transitions are enabled' do - jira_service.jira_issue_transition_automatic = true + jira_integration.jira_issue_transition_automatic = true - expect(jira_service.issue_transition_enabled?).to be(true) + expect(jira_integration.issue_transition_enabled?).to be(true) end it 'returns true if custom transitions are set' do - jira_service.jira_issue_transition_id = '1, 2, 3' + jira_integration.jira_issue_transition_id = '1, 2, 3' - expect(jira_service.issue_transition_enabled?).to be(true) + expect(jira_integration.issue_transition_enabled?).to be(true) end it 'returns false if automatic and custom transitions are disabled' do - expect(jira_service.issue_transition_enabled?).to be(false) + expect(jira_integration.issue_transition_enabled?).to be(false) + end + end + + describe 'valid_connection? and configured?' do + before do + allow(jira_integration).to receive(:test).with(nil).and_return(test_result) + end + + context 'when the test fails' do + let(:test_result) { { success: false } } + + it 'is falsey' do + expect(jira_integration).not_to be_valid_connection + end + + it 'implies that configured? is also falsey' do + expect(jira_integration).not_to be_configured + end + end + + context 'when the test succeeds' do + let(:test_result) { { success: true } } + + it 'is truthy' do + expect(jira_integration).to be_valid_connection + end + + context 'when the integration is active' do + before do + jira_integration.active = true + end + + it 'implies that configured? is also truthy' do + expect(jira_integration).to be_configured + end + end + + context 'when the integration is inactive' do + before do + jira_integration.active = false + end + + it 'implies that configured? is falsey' do + expect(jira_integration).not_to be_configured + end + end end end end diff --git a/spec/models/integrations/prometheus_spec.rb b/spec/models/integrations/prometheus_spec.rb new file mode 100644 index 00000000000..e3e17738cfb --- /dev/null +++ b/spec/models/integrations/prometheus_spec.rb @@ -0,0 +1,542 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require 'googleauth' + +RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching, :snowplow do + include PrometheusHelpers + include ReactiveCachingHelpers + + let_it_be_with_reload(:project) { create(:prometheus_project) } + + let(:service) { project.prometheus_service } + + describe "Associations" do + it { is_expected.to belong_to :project } + end + + context 'redirects' do + it 'does not follow redirects' do + redirect_to = 'https://redirected.example.com' + redirect_req_stub = stub_prometheus_request(prometheus_query_url('1'), status: 302, headers: { location: redirect_to }) + redirected_req_stub = stub_prometheus_request(redirect_to, body: { 'status': 'success' }) + + result = service.test + + # result = { success: false, result: error } + expect(result[:success]).to be_falsy + expect(result[:result]).to be_instance_of(Gitlab::PrometheusClient::UnexpectedResponseError) + + expect(redirect_req_stub).to have_been_requested + expect(redirected_req_stub).not_to have_been_requested + end + end + + describe 'Validations' do + context 'when manual_configuration is enabled' do + before do + service.manual_configuration = true + end + + it 'validates presence of api_url' do + expect(service).to validate_presence_of(:api_url) + end + end + + context 'when manual configuration is disabled' do + before do + service.manual_configuration = false + end + + it 'does not validate presence of api_url' do + expect(service).not_to validate_presence_of(:api_url) + expect(service.valid?).to eq(true) + end + + context 'local connections allowed' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + end + + it 'does not validate presence of api_url' do + expect(service).not_to validate_presence_of(:api_url) + expect(service.valid?).to eq(true) + end + end + end + + context 'when the api_url domain points to localhost or local network' do + let(:domain) { Addressable::URI.parse(service.api_url).hostname } + + it 'cannot query' do + expect(service.can_query?).to be true + + aggregate_failures do + ['127.0.0.1', '192.168.2.3'].each do |url| + allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) + + expect(service.can_query?).to be false + end + end + end + + it 'can query when local requests are allowed' do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + + aggregate_failures do + ['127.0.0.1', '192.168.2.3'].each do |url| + allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) + + expect(service.can_query?).to be true + end + end + end + + context 'with self-monitoring project and internal Prometheus' do + before do + service.api_url = 'http://localhost:9090' + + stub_application_setting(self_monitoring_project_id: project.id) + stub_config(prometheus: { enable: true, server_address: 'localhost:9090' }) + end + + it 'allows self-monitoring project to connect to internal Prometheus' do + aggregate_failures do + ['127.0.0.1', '192.168.2.3'].each do |url| + allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) + + expect(service.can_query?).to be true + end + end + end + + it 'does not allow self-monitoring project to connect to other local URLs' do + service.api_url = 'http://localhost:8000' + + aggregate_failures do + ['127.0.0.1', '192.168.2.3'].each do |url| + allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) + + expect(service.can_query?).to be false + end + end + end + end + end + end + + describe 'callbacks' do + context 'after_create' do + let(:project) { create(:project) } + let(:service) { build(:prometheus_service, project: project) } + + subject(:create_service) { service.save! } + + it 'creates default alerts' do + expect(Prometheus::CreateDefaultAlertsWorker) + .to receive(:perform_async) + .with(project.id) + + create_service + end + + context 'no project exists' do + let(:service) { build(:prometheus_service, :instance) } + + it 'does not create default alerts' do + expect(Prometheus::CreateDefaultAlertsWorker) + .not_to receive(:perform_async) + + create_service + end + end + end + end + + describe '#test' do + before do + service.manual_configuration = true + end + + let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), body: prometheus_value_body('vector')) } + + context 'success' do + it 'reads the discovery endpoint' do + expect(service.test[:result]).to eq('Checked API endpoint') + expect(service.test[:success]).to be_truthy + expect(req_stub).to have_been_requested.twice + end + end + + context 'failure' do + let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), status: 404) } + + it 'fails to read the discovery endpoint' do + expect(service.test[:success]).to be_falsy + expect(req_stub).to have_been_requested + end + end + end + + describe '#prometheus_client' do + let(:api_url) { 'http://some_url' } + + before do + service.active = true + service.api_url = api_url + service.manual_configuration = manual_configuration + end + + context 'manual configuration is enabled' do + let(:manual_configuration) { true } + + it 'calls valid?' do + allow(service).to receive(:valid?).and_call_original + + expect(service.prometheus_client).not_to be_nil + + expect(service).to have_received(:valid?) + end + end + + context 'manual configuration is disabled' do + let(:manual_configuration) { false } + + it 'no client provided' do + expect(service.prometheus_client).to be_nil + end + end + + context 'when local requests are allowed' do + let(:manual_configuration) { true } + let(:api_url) { 'http://192.168.1.1:9090' } + + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) + + stub_prometheus_request("#{api_url}/api/v1/query?query=1") + end + + it 'allows local requests' do + expect(service.prometheus_client).not_to be_nil + expect { service.prometheus_client.ping }.not_to raise_error + end + end + + context 'when local requests are blocked' do + let(:manual_configuration) { true } + let(:api_url) { 'http://192.168.1.1:9090' } + + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) + + stub_prometheus_request("#{api_url}/api/v1/query?query=1") + end + + it 'blocks local requests' do + expect(service.prometheus_client).to be_nil + end + + context 'with self monitoring project and internal Prometheus URL' do + before do + stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) + stub_application_setting(self_monitoring_project_id: project.id) + + stub_config(prometheus: { + enable: true, + server_address: api_url + }) + end + + it 'allows local requests' do + expect(service.prometheus_client).not_to be_nil + expect { service.prometheus_client.ping }.not_to raise_error + end + end + end + + context 'behind IAP' do + let(:manual_configuration) { true } + + let(:google_iap_service_account) do + { + type: "service_account", + # dummy private key generated only for this test to pass openssl validation + private_key: <<~KEY + -----BEGIN RSA PRIVATE KEY----- + MIIBOAIBAAJAU85LgUY5o6j6j/07GMLCNUcWJOBA1buZnNgKELayA6mSsHrIv31J + Y8kS+9WzGPQninea7DcM4hHA7smMgQD1BwIDAQABAkAqKxMy6PL3tn7dFL43p0ex + JyOtSmlVIiAZG1t1LXhE/uoLpYi5DnbYqGgu0oih+7nzLY/dXpNpXUmiRMOUEKmB + AiEAoTi2rBXbrLSi2C+H7M/nTOjMQQDuZ8Wr4uWpKcjYJTMCIQCFEskL565oFl/7 + RRQVH+cARrAsAAoJSbrOBAvYZ0PI3QIgIEFwis10vgEF86rOzxppdIG/G+JL0IdD + 9IluZuXAGPECIGUo7qSaLr75o2VEEgwtAFH5aptIPFjrL5LFCKwtdB4RAiAYZgFV + HCMmaooAw/eELuMoMWNYmujZ7VaAnOewGDW0uw== + -----END RSA PRIVATE KEY----- + KEY + } + end + + def stub_iap_request + service.google_iap_service_account_json = Gitlab::Json.generate(google_iap_service_account) + service.google_iap_audience_client_id = 'IAP_CLIENT_ID.apps.googleusercontent.com' + + stub_request(:post, 'https://oauth2.googleapis.com/token') + .to_return( + status: 200, + body: '{"id_token": "FOO"}', + headers: { 'Content-Type': 'application/json; charset=UTF-8' } + ) + end + + it 'includes the authorization header' do + stub_iap_request + + expect(service.prometheus_client).not_to be_nil + expect(service.prometheus_client.send(:options)).to have_key(:headers) + expect(service.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO") + end + + context 'when passed with token_credential_uri', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284819' do + let(:malicious_host) { 'http://example.com' } + + where(:param_name) do + [ + :token_credential_uri, + :tokencredentialuri, + :Token_credential_uri, + :tokenCredentialUri + ] + end + + with_them do + it 'does not make any unexpected HTTP requests' do + google_iap_service_account[param_name] = malicious_host + stub_iap_request + stub_request(:any, malicious_host).to_raise('Making additional HTTP requests is forbidden!') + + expect(service.prometheus_client).not_to be_nil + end + end + end + end + end + + describe '#prometheus_available?' do + context 'clusters with enabled prometheus' do + before do + create(:clusters_integrations_prometheus, cluster: cluster) + end + + context 'cluster belongs to project' do + let(:cluster) { create(:cluster, projects: [project]) } + + it 'returns true' do + expect(service.prometheus_available?).to be(true) + end + end + + context 'cluster belongs to projects group' do + let_it_be(:group) { create(:group) } + + let(:project) { create(:prometheus_project, group: group) } + let(:cluster) { create(:cluster_for_group, groups: [group]) } + + it 'returns true' do + expect(service.prometheus_available?).to be(true) + end + + it 'avoids N+1 queries' do + service + 5.times do |i| + other_cluster = create(:cluster_for_group, groups: [group], environment_scope: i) + create(:clusters_integrations_prometheus, cluster: other_cluster) + end + expect { service.prometheus_available? }.not_to exceed_query_limit(1) + end + end + + context 'cluster belongs to gitlab instance' do + let(:cluster) { create(:cluster, :instance) } + + it 'returns true' do + expect(service.prometheus_available?).to be(true) + end + end + end + + context 'clusters with prometheus disabled' do + let(:cluster) { create(:cluster, projects: [project]) } + let!(:prometheus) { create(:clusters_integrations_prometheus, :disabled, cluster: cluster) } + + it 'returns false' do + expect(service.prometheus_available?).to be(false) + end + end + + context 'clusters without prometheus' do + let(:cluster) { create(:cluster, projects: [project]) } + + it 'returns false' do + expect(service.prometheus_available?).to be(false) + end + end + + context 'no clusters' do + it 'returns false' do + expect(service.prometheus_available?).to be(false) + end + end + end + + describe '#synchronize_service_state before_save callback' do + context 'no clusters with prometheus are installed' do + context 'when service is inactive' do + before do + service.active = false + end + + it 'activates service when manual_configuration is enabled' do + expect { service.update!(manual_configuration: true) }.to change { service.active }.from(false).to(true) + end + + it 'keeps service inactive when manual_configuration is disabled' do + expect { service.update!(manual_configuration: false) }.not_to change { service.active }.from(false) + end + end + + context 'when service is active' do + before do + service.active = true + end + + it 'keeps the service active when manual_configuration is enabled' do + expect { service.update!(manual_configuration: true) }.not_to change { service.active }.from(true) + end + + it 'inactivates the service when manual_configuration is disabled' do + expect { service.update!(manual_configuration: false) }.to change { service.active }.from(true).to(false) + end + end + end + + context 'with prometheus installed in the cluster' do + before do + allow(service).to receive(:prometheus_available?).and_return(true) + end + + context 'when service is inactive' do + before do + service.active = false + end + + it 'activates service when manual_configuration is enabled' do + expect { service.update!(manual_configuration: true) }.to change { service.active }.from(false).to(true) + end + + it 'activates service when manual_configuration is disabled' do + expect { service.update!(manual_configuration: false) }.to change { service.active }.from(false).to(true) + end + end + + context 'when service is active' do + before do + service.active = true + end + + it 'keeps service active when manual_configuration is enabled' do + expect { service.update!(manual_configuration: true) }.not_to change { service.active }.from(true) + end + + it 'keeps service active when manual_configuration is disabled' do + expect { service.update!(manual_configuration: false) }.not_to change { service.active }.from(true) + end + end + end + end + + describe '#track_events after_commit callback' do + before do + allow(service).to receive(:prometheus_available?).and_return(true) + end + + context "enabling manual_configuration" do + it "tracks enable event" do + service.update!(manual_configuration: false) + service.update!(manual_configuration: true) + + expect_snowplow_event(category: 'cluster:services:prometheus', action: 'enabled_manual_prometheus') + end + + it "tracks disable event" do + service.update!(manual_configuration: true) + service.update!(manual_configuration: false) + + expect_snowplow_event(category: 'cluster:services:prometheus', action: 'disabled_manual_prometheus') + end + end + end + + describe '#editable?' do + it 'is editable' do + expect(service.editable?).to be(true) + end + + context 'when cluster exists with prometheus enabled' do + let(:cluster) { create(:cluster, projects: [project]) } + + before do + service.update!(manual_configuration: false) + + create(:clusters_integrations_prometheus, cluster: cluster) + end + + it 'remains editable' do + expect(service.editable?).to be(true) + end + end + end + + describe '#fields' do + let(:expected_fields) do + [ + { + type: 'checkbox', + name: 'manual_configuration', + title: s_('PrometheusService|Active'), + help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'), + required: true + }, + { + type: 'text', + name: 'api_url', + title: 'API URL', + placeholder: s_('PrometheusService|https://prometheus.example.com/'), + help: s_('PrometheusService|The Prometheus API base URL.'), + required: true + }, + { + type: 'text', + name: 'google_iap_audience_client_id', + title: 'Google IAP Audience Client ID', + placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'), + help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'), + autocomplete: 'off', + required: false + }, + { + type: 'textarea', + name: 'google_iap_service_account_json', + title: 'Google IAP Service Account JSON', + placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'), + help: s_('PrometheusService|The contents of the credentials.json file of your service account.'), + required: false + } + ] + end + + it 'returns fields' do + expect(service.fields).to eq(expected_fields) + end + end +end diff --git a/spec/models/integrations/slack_slash_commands_spec.rb b/spec/models/integrations/slack_slash_commands_spec.rb index a9d3c820a3c..b9d26312d64 100644 --- a/spec/models/integrations/slack_slash_commands_spec.rb +++ b/spec/models/integrations/slack_slash_commands_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Integrations::SlackSlashCommands do end let(:service) do - project.create_slack_slash_commands_service( + project.create_slack_slash_commands_integration( properties: { token: 'token' }, active: true ) diff --git a/spec/models/integrations/slack_spec.rb b/spec/models/integrations/slack_spec.rb index e598c528967..4661d9c8291 100644 --- a/spec/models/integrations/slack_spec.rb +++ b/spec/models/integrations/slack_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Integrations::Slack do stub_request(:post, "https://slack.service.url/") end - let_it_be(:slack_service) { create(:slack_service, branches_to_be_notified: 'all') } + let_it_be(:slack_integration) { create(:integrations_slack, branches_to_be_notified: 'all') } it 'uses only known events', :aggregate_failures do described_class::SUPPORTED_EVENTS_FOR_USAGE_LOG.each do |action| @@ -26,7 +26,7 @@ RSpec.describe Integrations::Slack do it 'increases the usage data counter' do expect(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event).with(event_name, values: user.id).and_call_original - slack_service.execute(data) + slack_integration.execute(data) end end @@ -38,7 +38,7 @@ RSpec.describe Integrations::Slack do it 'does not increase the usage data counter' do expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event).with('i_ecosystem_slack_service_pipeline_notification', values: user.id) - slack_service.execute(data) + slack_integration.execute(data) end end @@ -126,7 +126,7 @@ RSpec.describe Integrations::Slack do it 'does not increase the usage data counter' do expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event) - slack_service.execute(data) + slack_integration.execute(data) end end end diff --git a/spec/models/integrations/teamcity_spec.rb b/spec/models/integrations/teamcity_spec.rb index b88a4722ad4..5ed65bf7f46 100644 --- a/spec/models/integrations/teamcity_spec.rb +++ b/spec/models/integrations/teamcity_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do let(:teamcity_full_url) { 'http://gitlab.com/teamcity/httpAuth/app/rest/builds/branch:unspecified:any,revision:123' } let(:project) { create(:project) } - subject(:service) do + subject(:integration) do described_class.create!( project: project, properties: { @@ -28,14 +28,14 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do end describe 'Validations' do - context 'when service is active' do + context 'when integration is active' do before do subject.active = true end it { is_expected.to validate_presence_of(:build_type) } it { is_expected.to validate_presence_of(:teamcity_url) } - it_behaves_like 'issue tracker service URL attribute', :teamcity_url + it_behaves_like 'issue tracker integration URL attribute', :teamcity_url describe '#username' do it 'does not validate the presence of username if password is nil' do @@ -66,7 +66,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do end end - context 'when service is inactive' do + context 'when integration is inactive' do before do subject.active = false end @@ -79,71 +79,66 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do end describe 'Callbacks' do + let(:teamcity_integration) { integration } + describe 'before_update :reset_password' do context 'when a password was previously set' do it 'resets password if url changed' do - teamcity_service = service - - teamcity_service.teamcity_url = 'http://gitlab1.com' - teamcity_service.save! + teamcity_integration.teamcity_url = 'http://gitlab1.com' + teamcity_integration.save! - expect(teamcity_service.password).to be_nil + expect(teamcity_integration.password).to be_nil end it 'does not reset password if username changed' do - teamcity_service = service + teamcity_integration.username = 'some_name' + teamcity_integration.save! - teamcity_service.username = 'some_name' - teamcity_service.save! - - expect(teamcity_service.password).to eq('password') + expect(teamcity_integration.password).to eq('password') end it "does not reset password if new url is set together with password, even if it's the same password" do - teamcity_service = service - - teamcity_service.teamcity_url = 'http://gitlab_edited.com' - teamcity_service.password = 'password' - teamcity_service.save! + teamcity_integration.teamcity_url = 'http://gitlab_edited.com' + teamcity_integration.password = 'password' + teamcity_integration.save! - expect(teamcity_service.password).to eq('password') - expect(teamcity_service.teamcity_url).to eq('http://gitlab_edited.com') + expect(teamcity_integration.password).to eq('password') + expect(teamcity_integration.teamcity_url).to eq('http://gitlab_edited.com') end end it 'saves password if new url is set together with password when no password was previously set' do - teamcity_service = service - teamcity_service.password = nil + teamcity_integration.password = nil - teamcity_service.teamcity_url = 'http://gitlab_edited.com' - teamcity_service.password = 'password' - teamcity_service.save! + teamcity_integration.teamcity_url = 'http://gitlab_edited.com' + teamcity_integration.password = 'password' + teamcity_integration.save! - expect(teamcity_service.password).to eq('password') - expect(teamcity_service.teamcity_url).to eq('http://gitlab_edited.com') + expect(teamcity_integration.password).to eq('password') + expect(teamcity_integration.teamcity_url).to eq('http://gitlab_edited.com') end end end describe '#build_page' do it 'returns the contents of the reactive cache' do - stub_reactive_cache(service, { build_page: 'foo' }, 'sha', 'ref') + stub_reactive_cache(integration, { build_page: 'foo' }, 'sha', 'ref') - expect(service.build_page('sha', 'ref')).to eq('foo') + expect(integration.build_page('sha', 'ref')).to eq('foo') end end describe '#commit_status' do it 'returns the contents of the reactive cache' do - stub_reactive_cache(service, { commit_status: 'foo' }, 'sha', 'ref') + stub_reactive_cache(integration, { commit_status: 'foo' }, 'sha', 'ref') - expect(service.commit_status('sha', 'ref')).to eq('foo') + expect(integration.commit_status('sha', 'ref')).to eq('foo') end end describe '#calculate_reactive_cache' do context 'build_page' do - subject { service.calculate_reactive_cache('123', 'unused')[:build_page] } + subject { integration.calculate_reactive_cache('123', 'unused')[:build_page] } it 'returns a specific URL when status is 500' do stub_request(status: 500) @@ -179,7 +174,7 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do end context 'commit_status' do - subject { service.calculate_reactive_cache('123', 'unused')[:commit_status] } + subject { integration.calculate_reactive_cache('123', 'unused')[:commit_status] } it 'sets commit status to :error when status is 500' do stub_request(status: 500) @@ -243,25 +238,25 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do it 'handles push request correctly' do stub_post_to_build_queue(branch: 'dev-123_branch') - expect(service.execute(data)).to include('Ok') + expect(integration.execute(data)).to include('Ok') end it 'returns nil when ref is blank' do data[:after] = Gitlab::Git::BLANK_SHA - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end it 'returns nil when there is no content' do data[:total_commits_count] = 0 - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end it 'returns nil when a merge request is opened for the same ref' do create(:merge_request, source_project: project, source_branch: 'dev-123_branch') - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end end @@ -283,26 +278,26 @@ RSpec.describe Integrations::Teamcity, :use_clean_rails_memory_store_caching do it 'handles merge request correctly' do stub_post_to_build_queue(branch: 'dev-123_branch') - expect(service.execute(data)).to include('Ok') + expect(integration.execute(data)).to include('Ok') end it 'returns nil when merge request is not opened' do data[:object_attributes][:state] = 'closed' - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end it 'returns nil unless merge request is marked as unchecked' do data[:object_attributes][:merge_status] = 'can_be_merged' - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end end it 'returns nil when event is not supported' do data = { object_kind: 'foo' } - expect(service.execute(data)).to be_nil + expect(integration.execute(data)).to be_nil end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 73b1cb13f19..11637de6c37 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -779,7 +779,7 @@ RSpec.describe MergeRequest, factory_default: :keep do context 'when both internal and external issue trackers are enabled' do before do - create(:jira_service, project: subject.project) + create(:jira_integration, project: subject.project) subject.project.reload end @@ -1310,7 +1310,7 @@ RSpec.describe MergeRequest, factory_default: :keep do subject.project.add_developer(subject.author) commit = double(:commit, safe_message: 'Fixes TEST-3') - create(:jira_service, project: subject.project) + create(:jira_integration, project: subject.project) subject.project.reload allow(subject).to receive(:commits).and_return([commit]) diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb deleted file mode 100644 index a2025388fab..00000000000 --- a/spec/models/project_services/prometheus_service_spec.rb +++ /dev/null @@ -1,542 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -require 'googleauth' - -RSpec.describe PrometheusService, :use_clean_rails_memory_store_caching, :snowplow do - include PrometheusHelpers - include ReactiveCachingHelpers - - let_it_be_with_reload(:project) { create(:prometheus_project) } - - let(:service) { project.prometheus_service } - - describe "Associations" do - it { is_expected.to belong_to :project } - end - - context 'redirects' do - it 'does not follow redirects' do - redirect_to = 'https://redirected.example.com' - redirect_req_stub = stub_prometheus_request(prometheus_query_url('1'), status: 302, headers: { location: redirect_to }) - redirected_req_stub = stub_prometheus_request(redirect_to, body: { 'status': 'success' }) - - result = service.test - - # result = { success: false, result: error } - expect(result[:success]).to be_falsy - expect(result[:result]).to be_instance_of(Gitlab::PrometheusClient::UnexpectedResponseError) - - expect(redirect_req_stub).to have_been_requested - expect(redirected_req_stub).not_to have_been_requested - end - end - - describe 'Validations' do - context 'when manual_configuration is enabled' do - before do - service.manual_configuration = true - end - - it 'validates presence of api_url' do - expect(service).to validate_presence_of(:api_url) - end - end - - context 'when manual configuration is disabled' do - before do - service.manual_configuration = false - end - - it 'does not validate presence of api_url' do - expect(service).not_to validate_presence_of(:api_url) - expect(service.valid?).to eq(true) - end - - context 'local connections allowed' do - before do - stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) - end - - it 'does not validate presence of api_url' do - expect(service).not_to validate_presence_of(:api_url) - expect(service.valid?).to eq(true) - end - end - end - - context 'when the api_url domain points to localhost or local network' do - let(:domain) { Addressable::URI.parse(service.api_url).hostname } - - it 'cannot query' do - expect(service.can_query?).to be true - - aggregate_failures do - ['127.0.0.1', '192.168.2.3'].each do |url| - allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) - - expect(service.can_query?).to be false - end - end - end - - it 'can query when local requests are allowed' do - stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) - - aggregate_failures do - ['127.0.0.1', '192.168.2.3'].each do |url| - allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) - - expect(service.can_query?).to be true - end - end - end - - context 'with self-monitoring project and internal Prometheus' do - before do - service.api_url = 'http://localhost:9090' - - stub_application_setting(self_monitoring_project_id: project.id) - stub_config(prometheus: { enable: true, server_address: 'localhost:9090' }) - end - - it 'allows self-monitoring project to connect to internal Prometheus' do - aggregate_failures do - ['127.0.0.1', '192.168.2.3'].each do |url| - allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) - - expect(service.can_query?).to be true - end - end - end - - it 'does not allow self-monitoring project to connect to other local URLs' do - service.api_url = 'http://localhost:8000' - - aggregate_failures do - ['127.0.0.1', '192.168.2.3'].each do |url| - allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([Addrinfo.tcp(url, 80)]) - - expect(service.can_query?).to be false - end - end - end - end - end - end - - describe 'callbacks' do - context 'after_create' do - let(:project) { create(:project) } - let(:service) { build(:prometheus_service, project: project) } - - subject(:create_service) { service.save! } - - it 'creates default alerts' do - expect(Prometheus::CreateDefaultAlertsWorker) - .to receive(:perform_async) - .with(project.id) - - create_service - end - - context 'no project exists' do - let(:service) { build(:prometheus_service, :instance) } - - it 'does not create default alerts' do - expect(Prometheus::CreateDefaultAlertsWorker) - .not_to receive(:perform_async) - - create_service - end - end - end - end - - describe '#test' do - before do - service.manual_configuration = true - end - - let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), body: prometheus_value_body('vector')) } - - context 'success' do - it 'reads the discovery endpoint' do - expect(service.test[:result]).to eq('Checked API endpoint') - expect(service.test[:success]).to be_truthy - expect(req_stub).to have_been_requested.twice - end - end - - context 'failure' do - let!(:req_stub) { stub_prometheus_request(prometheus_query_url('1'), status: 404) } - - it 'fails to read the discovery endpoint' do - expect(service.test[:success]).to be_falsy - expect(req_stub).to have_been_requested - end - end - end - - describe '#prometheus_client' do - let(:api_url) { 'http://some_url' } - - before do - service.active = true - service.api_url = api_url - service.manual_configuration = manual_configuration - end - - context 'manual configuration is enabled' do - let(:manual_configuration) { true } - - it 'calls valid?' do - allow(service).to receive(:valid?).and_call_original - - expect(service.prometheus_client).not_to be_nil - - expect(service).to have_received(:valid?) - end - end - - context 'manual configuration is disabled' do - let(:manual_configuration) { false } - - it 'no client provided' do - expect(service.prometheus_client).to be_nil - end - end - - context 'when local requests are allowed' do - let(:manual_configuration) { true } - let(:api_url) { 'http://192.168.1.1:9090' } - - before do - stub_application_setting(allow_local_requests_from_web_hooks_and_services: true) - - stub_prometheus_request("#{api_url}/api/v1/query?query=1") - end - - it 'allows local requests' do - expect(service.prometheus_client).not_to be_nil - expect { service.prometheus_client.ping }.not_to raise_error - end - end - - context 'when local requests are blocked' do - let(:manual_configuration) { true } - let(:api_url) { 'http://192.168.1.1:9090' } - - before do - stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) - - stub_prometheus_request("#{api_url}/api/v1/query?query=1") - end - - it 'blocks local requests' do - expect(service.prometheus_client).to be_nil - end - - context 'with self monitoring project and internal Prometheus URL' do - before do - stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) - stub_application_setting(self_monitoring_project_id: project.id) - - stub_config(prometheus: { - enable: true, - server_address: api_url - }) - end - - it 'allows local requests' do - expect(service.prometheus_client).not_to be_nil - expect { service.prometheus_client.ping }.not_to raise_error - end - end - end - - context 'behind IAP' do - let(:manual_configuration) { true } - - let(:google_iap_service_account) do - { - type: "service_account", - # dummy private key generated only for this test to pass openssl validation - private_key: <<~KEY - -----BEGIN RSA PRIVATE KEY----- - MIIBOAIBAAJAU85LgUY5o6j6j/07GMLCNUcWJOBA1buZnNgKELayA6mSsHrIv31J - Y8kS+9WzGPQninea7DcM4hHA7smMgQD1BwIDAQABAkAqKxMy6PL3tn7dFL43p0ex - JyOtSmlVIiAZG1t1LXhE/uoLpYi5DnbYqGgu0oih+7nzLY/dXpNpXUmiRMOUEKmB - AiEAoTi2rBXbrLSi2C+H7M/nTOjMQQDuZ8Wr4uWpKcjYJTMCIQCFEskL565oFl/7 - RRQVH+cARrAsAAoJSbrOBAvYZ0PI3QIgIEFwis10vgEF86rOzxppdIG/G+JL0IdD - 9IluZuXAGPECIGUo7qSaLr75o2VEEgwtAFH5aptIPFjrL5LFCKwtdB4RAiAYZgFV - HCMmaooAw/eELuMoMWNYmujZ7VaAnOewGDW0uw== - -----END RSA PRIVATE KEY----- - KEY - } - end - - def stub_iap_request - service.google_iap_service_account_json = Gitlab::Json.generate(google_iap_service_account) - service.google_iap_audience_client_id = 'IAP_CLIENT_ID.apps.googleusercontent.com' - - stub_request(:post, 'https://oauth2.googleapis.com/token') - .to_return( - status: 200, - body: '{"id_token": "FOO"}', - headers: { 'Content-Type': 'application/json; charset=UTF-8' } - ) - end - - it 'includes the authorization header' do - stub_iap_request - - expect(service.prometheus_client).not_to be_nil - expect(service.prometheus_client.send(:options)).to have_key(:headers) - expect(service.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO") - end - - context 'when passed with token_credential_uri', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284819' do - let(:malicious_host) { 'http://example.com' } - - where(:param_name) do - [ - :token_credential_uri, - :tokencredentialuri, - :Token_credential_uri, - :tokenCredentialUri - ] - end - - with_them do - it 'does not make any unexpected HTTP requests' do - google_iap_service_account[param_name] = malicious_host - stub_iap_request - stub_request(:any, malicious_host).to_raise('Making additional HTTP requests is forbidden!') - - expect(service.prometheus_client).not_to be_nil - end - end - end - end - end - - describe '#prometheus_available?' do - context 'clusters with enabled prometheus' do - before do - create(:clusters_integrations_prometheus, cluster: cluster) - end - - context 'cluster belongs to project' do - let(:cluster) { create(:cluster, projects: [project]) } - - it 'returns true' do - expect(service.prometheus_available?).to be(true) - end - end - - context 'cluster belongs to projects group' do - let_it_be(:group) { create(:group) } - - let(:project) { create(:prometheus_project, group: group) } - let(:cluster) { create(:cluster_for_group, groups: [group]) } - - it 'returns true' do - expect(service.prometheus_available?).to be(true) - end - - it 'avoids N+1 queries' do - service - 5.times do |i| - other_cluster = create(:cluster_for_group, groups: [group], environment_scope: i) - create(:clusters_integrations_prometheus, cluster: other_cluster) - end - expect { service.prometheus_available? }.not_to exceed_query_limit(1) - end - end - - context 'cluster belongs to gitlab instance' do - let(:cluster) { create(:cluster, :instance) } - - it 'returns true' do - expect(service.prometheus_available?).to be(true) - end - end - end - - context 'clusters with prometheus disabled' do - let(:cluster) { create(:cluster, projects: [project]) } - let!(:prometheus) { create(:clusters_integrations_prometheus, :disabled, cluster: cluster) } - - it 'returns false' do - expect(service.prometheus_available?).to be(false) - end - end - - context 'clusters without prometheus' do - let(:cluster) { create(:cluster, projects: [project]) } - - it 'returns false' do - expect(service.prometheus_available?).to be(false) - end - end - - context 'no clusters' do - it 'returns false' do - expect(service.prometheus_available?).to be(false) - end - end - end - - describe '#synchronize_service_state before_save callback' do - context 'no clusters with prometheus are installed' do - context 'when service is inactive' do - before do - service.active = false - end - - it 'activates service when manual_configuration is enabled' do - expect { service.update!(manual_configuration: true) }.to change { service.active }.from(false).to(true) - end - - it 'keeps service inactive when manual_configuration is disabled' do - expect { service.update!(manual_configuration: false) }.not_to change { service.active }.from(false) - end - end - - context 'when service is active' do - before do - service.active = true - end - - it 'keeps the service active when manual_configuration is enabled' do - expect { service.update!(manual_configuration: true) }.not_to change { service.active }.from(true) - end - - it 'inactivates the service when manual_configuration is disabled' do - expect { service.update!(manual_configuration: false) }.to change { service.active }.from(true).to(false) - end - end - end - - context 'with prometheus installed in the cluster' do - before do - allow(service).to receive(:prometheus_available?).and_return(true) - end - - context 'when service is inactive' do - before do - service.active = false - end - - it 'activates service when manual_configuration is enabled' do - expect { service.update!(manual_configuration: true) }.to change { service.active }.from(false).to(true) - end - - it 'activates service when manual_configuration is disabled' do - expect { service.update!(manual_configuration: false) }.to change { service.active }.from(false).to(true) - end - end - - context 'when service is active' do - before do - service.active = true - end - - it 'keeps service active when manual_configuration is enabled' do - expect { service.update!(manual_configuration: true) }.not_to change { service.active }.from(true) - end - - it 'keeps service active when manual_configuration is disabled' do - expect { service.update!(manual_configuration: false) }.not_to change { service.active }.from(true) - end - end - end - end - - describe '#track_events after_commit callback' do - before do - allow(service).to receive(:prometheus_available?).and_return(true) - end - - context "enabling manual_configuration" do - it "tracks enable event" do - service.update!(manual_configuration: false) - service.update!(manual_configuration: true) - - expect_snowplow_event(category: 'cluster:services:prometheus', action: 'enabled_manual_prometheus') - end - - it "tracks disable event" do - service.update!(manual_configuration: true) - service.update!(manual_configuration: false) - - expect_snowplow_event(category: 'cluster:services:prometheus', action: 'disabled_manual_prometheus') - end - end - end - - describe '#editable?' do - it 'is editable' do - expect(service.editable?).to be(true) - end - - context 'when cluster exists with prometheus enabled' do - let(:cluster) { create(:cluster, projects: [project]) } - - before do - service.update!(manual_configuration: false) - - create(:clusters_integrations_prometheus, cluster: cluster) - end - - it 'remains editable' do - expect(service.editable?).to be(true) - end - end - end - - describe '#fields' do - let(:expected_fields) do - [ - { - type: 'checkbox', - name: 'manual_configuration', - title: s_('PrometheusService|Active'), - help: s_('PrometheusService|Select this checkbox to override the auto configuration settings with your own settings.'), - required: true - }, - { - type: 'text', - name: 'api_url', - title: 'API URL', - placeholder: s_('PrometheusService|https://prometheus.example.com/'), - help: s_('PrometheusService|The Prometheus API base URL.'), - required: true - }, - { - type: 'text', - name: 'google_iap_audience_client_id', - title: 'Google IAP Audience Client ID', - placeholder: s_('PrometheusService|IAP_CLIENT_ID.apps.googleusercontent.com'), - help: s_('PrometheusService|PrometheusService|The ID of the IAP-secured resource.'), - autocomplete: 'off', - required: false - }, - { - type: 'textarea', - name: 'google_iap_service_account_json', - title: 'Google IAP Service Account JSON', - placeholder: s_('PrometheusService|{ "type": "service_account", "project_id": ... }'), - help: s_('PrometheusService|The contents of the credentials.json file of your service account.'), - required: false - } - ] - end - - it 'returns fields' do - expect(service.fields).to eq(expected_fields) - end - end -end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 84fcb24e4c5..287f0a1b540 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -35,7 +35,7 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_many(:hooks) } it { is_expected.to have_many(:protected_branches) } it { is_expected.to have_many(:exported_protected_branches) } - it { is_expected.to have_one(:slack_service) } + it { is_expected.to have_one(:slack_integration) } it { is_expected.to have_one(:microsoft_teams_integration) } it { is_expected.to have_one(:mattermost_integration) } it { is_expected.to have_one(:hangouts_chat_integration) } @@ -55,13 +55,13 @@ RSpec.describe Project, factory_default: :keep do it { is_expected.to have_one(:pivotaltracker_integration) } it { is_expected.to have_one(:flowdock_integration) } it { is_expected.to have_one(:assembla_integration) } - it { is_expected.to have_one(:slack_slash_commands_service) } + it { is_expected.to have_one(:slack_slash_commands_integration) } it { is_expected.to have_one(:mattermost_slash_commands_integration) } it { is_expected.to have_one(:buildkite_integration) } it { is_expected.to have_one(:bamboo_integration) } - it { is_expected.to have_one(:teamcity_service) } - it { is_expected.to have_one(:jira_service) } - it { is_expected.to have_one(:redmine_service) } + it { is_expected.to have_one(:teamcity_integration) } + it { is_expected.to have_one(:jira_integration) } + it { is_expected.to have_one(:redmine_integration) } it { is_expected.to have_one(:youtrack_service) } it { is_expected.to have_one(:custom_issue_tracker_integration) } it { is_expected.to have_one(:bugzilla_integration) } @@ -1446,13 +1446,13 @@ RSpec.describe Project, factory_default: :keep do end end - describe '.with_active_jira_services' do - it 'returns the correct project' do - active_jira_service = create(:jira_service) + describe '.with_active_jira_integrations' do + it 'returns the correct integrations' do + active_jira_integration = create(:jira_integration) active_service = create(:service, active: true) - expect(described_class.with_active_jira_services).to include(active_jira_service.project) - expect(described_class.with_active_jira_services).not_to include(active_service.project) + expect(described_class.with_active_jira_integrations).to include(active_jira_integration.project) + expect(described_class.with_active_jira_integrations).not_to include(active_service.project) end end @@ -5369,26 +5369,26 @@ RSpec.describe Project, factory_default: :keep do end describe '#execute_services' do - let(:service) { create(:slack_service, push_events: true, merge_requests_events: false, active: true) } + let(:integration) { create(:integrations_slack, push_events: true, merge_requests_events: false, active: true) } - it 'executes services with the specified scope' do + it 'executes integrations with the specified scope' do data = 'any data' expect_next_found_instance_of(Integrations::Slack) do |instance| expect(instance).to receive(:async_execute).with(data).once end - service.project.execute_services(data, :push_hooks) + integration.project.execute_services(data, :push_hooks) end - it 'does not execute services that don\'t match the specified scope' do + it 'does not execute integration that don\'t match the specified scope' do expect(Integrations::Slack).not_to receive(:allocate).and_wrap_original do |method| method.call.tap do |instance| expect(instance).not_to receive(:async_execute) end end - service.project.execute_services(anything, :merge_request_hooks) + integration.project.execute_services(anything, :merge_request_hooks) end end @@ -5942,7 +5942,7 @@ RSpec.describe Project, factory_default: :keep do context 'without an exisiting integration, nor instance-level or template' do it 'builds the service if instance or template does not exists' do - expect(subject.find_or_initialize_service('prometheus')).to be_a(PrometheusService) + expect(subject.find_or_initialize_service('prometheus')).to be_a(::Integrations::Prometheus) expect(subject.find_or_initialize_service('prometheus').api_url).to be_nil end end diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb index d0fe0cca8a1..27df461af1c 100644 --- a/spec/policies/project_policy_spec.rb +++ b/spec/policies/project_policy_spec.rb @@ -70,7 +70,7 @@ RSpec.describe ProjectPolicy do context 'when external tracker configured' do it 'does not include the issues permissions' do - create(:jira_service, project: project) + create(:jira_integration, project: project) expect_disallowed :read_issue, :read_issue_iid, :create_issue, :update_issue, :admin_issue, :create_incident end diff --git a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb index 0ef61ae0d5b..dd7806bdbe0 100644 --- a/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb +++ b/spec/requests/api/graphql/mutations/alert_management/prometheus_integration/create_spec.rb @@ -42,7 +42,7 @@ RSpec.describe 'Creating a new Prometheus Integration' do it 'creates a new integration' do post_graphql_mutation(mutation, current_user: current_user) - new_integration = ::PrometheusService.last! + new_integration = ::Integrations::Prometheus.last! integration_response = mutation_response['integration'] expect(response).to have_gitlab_http_status(:success) diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb index e7124512ef1..75668c9e6ae 100644 --- a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb +++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb @@ -80,17 +80,17 @@ RSpec.describe 'Starting a Jira Import' do end end - context 'when project has no Jira service' do + context 'when project has no Jira integration' do it_behaves_like 'a mutation that returns errors in the response', errors: ['Jira integration not configured.'] end - context 'when when project has Jira service' do - let!(:service) { create(:jira_service, project: project) } + context 'when when project has Jira integration' do + let!(:service) { create(:jira_integration, project: project) } before do project.reload - stub_jira_service_test + stub_jira_integration_test end context 'when issues feature are disabled' do diff --git a/spec/requests/api/graphql/project/base_service_spec.rb b/spec/requests/api/graphql/project/base_service_spec.rb index af462c4a639..5dc0f55db88 100644 --- a/spec/requests/api/graphql/project/base_service_spec.rb +++ b/spec/requests/api/graphql/project/base_service_spec.rb @@ -7,9 +7,9 @@ RSpec.describe 'query Jira service' do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } let_it_be(:bugzilla_integration) { create(:bugzilla_integration, project: project) } - let_it_be(:redmine_service) { create(:redmine_service, project: project) } + let_it_be(:redmine_integration) { create(:redmine_integration, project: project) } let(:query) do %( diff --git a/spec/requests/api/graphql/project/jira_service_spec.rb b/spec/requests/api/graphql/project/jira_service_spec.rb index 905a669bf0d..64e9e04ae44 100644 --- a/spec/requests/api/graphql/project/jira_service_spec.rb +++ b/spec/requests/api/graphql/project/jira_service_spec.rb @@ -7,7 +7,7 @@ RSpec.describe 'query Jira service' do let_it_be(:current_user) { create(:user) } let_it_be(:project) { create(:project) } - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } let(:query) do %( diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index e7e26c34a83..ce7f56fe81d 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -386,7 +386,7 @@ RSpec.describe API::Projects do end context 'when external issue tracker is enabled' do - let!(:jira_service) { create(:jira_service, project: project) } + let!(:jira_integration) { create(:jira_integration, project: project) } it 'includes open_issues_count' do get api('/projects', user) diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb index 740a583ab74..9e9c1e02529 100644 --- a/spec/requests/api/services_spec.rb +++ b/spec/requests/api/services_spec.rb @@ -121,9 +121,9 @@ RSpec.describe API::Services do end def deactive_service! - return initialized_service.update!(active: false) unless initialized_service.is_a?(PrometheusService) + return initialized_service.update!(active: false) unless initialized_service.is_a?(::Integrations::Prometheus) - # PrometheusService sets `#active` itself within a `before_save`: + # Integrations::Prometheus sets `#active` itself within a `before_save`: initialized_service.manual_configuration = false initialized_service.save! end @@ -239,7 +239,7 @@ RSpec.describe API::Services do let(:service_name) { 'slack_slash_commands' } before do - project.create_slack_slash_commands_service( + project.create_slack_slash_commands_integration( active: true, properties: { token: 'token' } ) diff --git a/spec/serializers/merge_request_diff_entity_spec.rb b/spec/serializers/merge_request_diff_entity_spec.rb index 9bf95e68874..fae0cd7a0f9 100644 --- a/spec/serializers/merge_request_diff_entity_spec.rb +++ b/spec/serializers/merge_request_diff_entity_spec.rb @@ -29,7 +29,7 @@ RSpec.describe MergeRequestDiffEntity do expect(subject).to include( :version_index, :created_at, :commits_count, :latest, :short_commit_sha, :version_path, - :compare_path + :compare_path, :state ) end end diff --git a/spec/serializers/service_event_entity_spec.rb b/spec/serializers/service_event_entity_spec.rb index 91254c7dd27..f610c8f1488 100644 --- a/spec/serializers/service_event_entity_spec.rb +++ b/spec/serializers/service_event_entity_spec.rb @@ -12,7 +12,7 @@ RSpec.describe ServiceEventEntity do end describe '#as_json' do - context 'service without fields' do + context 'integration without fields' do let(:integration) { create(:emails_on_push_integration, push_events: true) } let(:event) { 'push' } @@ -24,8 +24,8 @@ RSpec.describe ServiceEventEntity do end end - context 'service with fields' do - let(:integration) { create(:slack_service, note_events: false, note_channel: 'note-channel') } + context 'integration with fields' do + let(:integration) { create(:integrations_slack, note_events: false, note_channel: 'note-channel') } let(:event) { 'note' } it 'exposes correct attributes' do diff --git a/spec/serializers/service_field_entity_spec.rb b/spec/serializers/service_field_entity_spec.rb index 20ca98416f8..6e9ebfb66d9 100644 --- a/spec/serializers/service_field_entity_spec.rb +++ b/spec/serializers/service_field_entity_spec.rb @@ -5,18 +5,18 @@ require 'spec_helper' RSpec.describe ServiceFieldEntity do let(:request) { double('request') } - subject { described_class.new(field, request: request, service: service).as_json } + subject { described_class.new(field, request: request, service: integration).as_json } before do - allow(request).to receive(:service).and_return(service) + allow(request).to receive(:service).and_return(integration) end describe '#as_json' do context 'Jira Service' do - let(:service) { create(:jira_service) } + let(:integration) { create(:jira_integration) } context 'field with type text' do - let(:field) { service.global_fields.find { |field| field[:name] == 'username' } } + let(:field) { integration_field('username') } it 'exposes correct attributes' do expected_hash = { @@ -35,7 +35,7 @@ RSpec.describe ServiceFieldEntity do end context 'field with type password' do - let(:field) { service.global_fields.find { |field| field[:name] == 'password' } } + let(:field) { integration_field('password') } it 'exposes correct attributes but hides password' do expected_hash = { @@ -56,10 +56,9 @@ RSpec.describe ServiceFieldEntity do context 'EmailsOnPush Service' do let(:integration) { create(:emails_on_push_integration, send_from_committer_email: '1') } - let(:service) { integration } # TODO: remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 is complete context 'field with type checkbox' do - let(:field) { integration.global_fields.find { |field| field[:name] == 'send_from_committer_email' } } + let(:field) { integration_field('send_from_committer_email') } it 'exposes correct attributes and casts value to Boolean' do expected_hash = { @@ -78,7 +77,7 @@ RSpec.describe ServiceFieldEntity do end context 'field with type select' do - let(:field) { integration.global_fields.find { |field| field[:name] == 'branches_to_be_notified' } } + let(:field) { integration_field('branches_to_be_notified') } it 'exposes correct attributes' do expected_hash = { @@ -97,4 +96,8 @@ RSpec.describe ServiceFieldEntity do end end end + + def integration_field(name) + integration.global_fields.find { |f| f[:name] == name } + end end diff --git a/spec/services/admin/propagate_integration_service_spec.rb b/spec/services/admin/propagate_integration_service_spec.rb index 13320528e4f..151658fe429 100644 --- a/spec/services/admin/propagate_integration_service_spec.rb +++ b/spec/services/admin/propagate_integration_service_spec.rb @@ -7,20 +7,20 @@ RSpec.describe Admin::PropagateIntegrationService do include JiraServiceHelper before do - stub_jira_service_test + stub_jira_integration_test end let(:group) { create(:group) } let_it_be(:project) { create(:project) } - let_it_be(:instance_integration) { create(:jira_service, :instance) } - let_it_be(:not_inherited_integration) { create(:jira_service, project: project) } + let_it_be(:instance_integration) { create(:jira_integration, :instance) } + let_it_be(:not_inherited_integration) { create(:jira_integration, project: project) } let_it_be(:inherited_integration) do - create(:jira_service, project: create(:project), inherit_from_id: instance_integration.id) + create(:jira_integration, project: create(:project), inherit_from_id: instance_integration.id) end let_it_be(:different_type_inherited_integration) do - create(:redmine_service, project: project, inherit_from_id: instance_integration.id) + create(:redmine_integration, project: project, inherit_from_id: instance_integration.id) end context 'with inherited integration' do @@ -55,7 +55,7 @@ RSpec.describe Admin::PropagateIntegrationService do end context 'for a group-level integration' do - let(:group_integration) { create(:jira_service, group: group, project: nil) } + let(:group_integration) { create(:jira_integration, group: group, project: nil) } context 'with a project without integration' do let(:another_project) { create(:project, group: group) } @@ -81,7 +81,7 @@ RSpec.describe Admin::PropagateIntegrationService do context 'with a subgroup with integration' do let(:subgroup) { create(:group, parent: group) } - let(:subgroup_integration) { create(:jira_service, group: subgroup, project: nil, inherit_from_id: group_integration.id) } + let(:subgroup_integration) { create(:jira_integration, group: subgroup, project: nil, inherit_from_id: group_integration.id) } it 'calls to PropagateIntegrationInheritDescendantWorker' do expect(PropagateIntegrationInheritDescendantWorker).to receive(:perform_async) diff --git a/spec/services/bulk_create_integration_service_spec.rb b/spec/services/bulk_create_integration_service_spec.rb index 8369eb48088..ebfd988f26e 100644 --- a/spec/services/bulk_create_integration_service_spec.rb +++ b/spec/services/bulk_create_integration_service_spec.rb @@ -6,13 +6,13 @@ RSpec.describe BulkCreateIntegrationService do include JiraServiceHelper before_all do - stub_jira_service_test + stub_jira_integration_test end let_it_be(:excluded_group) { create(:group) } let_it_be(:excluded_project) { create(:project, group: excluded_group) } - let(:instance_integration) { create(:jira_service, :instance) } - let(:template_integration) { create(:jira_service, :template) } + let(:instance_integration) { create(:jira_integration, :instance) } + let(:template_integration) { create(:jira_integration, :template) } let(:excluded_attributes) { %w[id project_id group_id inherit_from_id instance template created_at updated_at] } shared_examples 'creates integration from batch ids' do @@ -49,7 +49,7 @@ RSpec.describe BulkCreateIntegrationService do context 'with a project association' do let!(:project) { create(:project) } - let(:created_integration) { project.jira_service } + let(:created_integration) { project.jira_integration } let(:batch) { Project.where(id: project.id) } let(:association) { 'project' } @@ -73,8 +73,8 @@ RSpec.describe BulkCreateIntegrationService do context 'with a project association' do let!(:project) { create(:project, group: group) } - let(:integration) { create(:jira_service, group: group, project: nil) } - let(:created_integration) { project.jira_service } + let(:integration) { create(:jira_integration, group: group, project: nil) } + let(:created_integration) { project.jira_integration } let(:batch) { Project.where(id: Project.minimum(:id)..Project.maximum(:id)).without_integration(integration).in_namespace(integration.group.self_and_descendants) } let(:association) { 'project' } let(:inherit_from_id) { integration.id } @@ -85,7 +85,7 @@ RSpec.describe BulkCreateIntegrationService do context 'with a group association' do let!(:subgroup) { create(:group, parent: group) } - let(:integration) { create(:jira_service, group: group, project: nil, inherit_from_id: instance_integration.id) } + let(:integration) { create(:jira_integration, group: group, project: nil, inherit_from_id: instance_integration.id) } let(:created_integration) { Integration.find_by(group: subgroup) } let(:batch) { Group.where(id: subgroup.id) } let(:association) { 'group' } @@ -101,7 +101,7 @@ RSpec.describe BulkCreateIntegrationService do context 'with a project association' do let!(:project) { create(:project) } - let(:created_integration) { project.jira_service } + let(:created_integration) { project.jira_integration } let(:batch) { Project.where(id: project.id) } let(:association) { 'project' } let(:inherit_from_id) { integration.id } diff --git a/spec/services/bulk_update_integration_service_spec.rb b/spec/services/bulk_update_integration_service_spec.rb index a866e0852bc..b6b7d1936a2 100644 --- a/spec/services/bulk_update_integration_service_spec.rb +++ b/spec/services/bulk_update_integration_service_spec.rb @@ -6,7 +6,7 @@ RSpec.describe BulkUpdateIntegrationService do include JiraServiceHelper before_all do - stub_jira_service_test + stub_jira_integration_test end let(:excluded_attributes) { %w[id project_id group_id inherit_from_id instance template created_at updated_at] } diff --git a/spec/services/git/branch_push_service_spec.rb b/spec/services/git/branch_push_service_spec.rb index cc3ba21f002..d52e3a0b6fa 100644 --- a/spec/services/git/branch_push_service_spec.rb +++ b/spec/services/git/branch_push_service_spec.rb @@ -411,13 +411,13 @@ RSpec.describe Git::BranchPushService, services: true do context "for jira issue tracker" do include JiraServiceHelper - let(:jira_tracker) { project.create_jira_service if project.jira_service.nil? } + let(:jira_tracker) { project.create_jira_integration if project.jira_integration.nil? } before do - # project.create_jira_service doesn't seem to invalidate the cache here + # project.create_jira_integration doesn't seem to invalidate the cache here project.has_external_issue_tracker = true - stub_jira_service_test - jira_service_settings + stub_jira_integration_test + jira_integration_settings stub_jira_urls("JIRA-1") allow(closing_commit).to receive_messages({ diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb index 2fbd5eeef5f..889b5551746 100644 --- a/spec/services/groups/transfer_service_spec.rb +++ b/spec/services/groups/transfer_service_spec.rb @@ -241,7 +241,7 @@ RSpec.describe Groups::TransferService do context 'when the group is allowed to be transferred' do let_it_be(:new_parent_group, reload: true) { create(:group, :public) } - let_it_be(:new_parent_group_integration) { create(:slack_service, group: new_parent_group, project: nil, webhook: 'http://new-group.slack.com') } + let_it_be(:new_parent_group_integration) { create(:integrations_slack, group: new_parent_group, project: nil, webhook: 'http://new-group.slack.com') } before do allow(PropagateIntegrationWorker).to receive(:perform_async) @@ -277,8 +277,8 @@ RSpec.describe Groups::TransferService do let(:new_created_integration) { Integration.find_by(group: group) } context 'with an inherited integration' do - let_it_be(:instance_integration) { create(:slack_service, :instance, webhook: 'http://project.slack.com') } - let_it_be(:group_integration) { create(:slack_service, group: group, project: nil, webhook: 'http://group.slack.com', inherit_from_id: instance_integration.id) } + let_it_be(:instance_integration) { create(:integrations_slack, :instance, webhook: 'http://project.slack.com') } + let_it_be(:group_integration) { create(:integrations_slack, group: group, project: nil, webhook: 'http://group.slack.com', inherit_from_id: instance_integration.id) } it 'replaces inherited integrations', :aggregate_failures do expect(new_created_integration.webhook).to eq(new_parent_group_integration.webhook) @@ -288,7 +288,7 @@ RSpec.describe Groups::TransferService do end context 'with a custom integration' do - let_it_be(:group_integration) { create(:slack_service, group: group, project: nil, webhook: 'http://group.slack.com') } + let_it_be(:group_integration) { create(:integrations_slack, group: group, project: nil, webhook: 'http://group.slack.com') } it 'does not updates the integrations', :aggregate_failures do expect { transfer_service.execute(new_parent_group) }.not_to change { group_integration.webhook } diff --git a/spec/services/integrations/test/project_service_spec.rb b/spec/services/integrations/test/project_service_spec.rb index 8417f8c4c8a..2e09dea11f1 100644 --- a/spec/services/integrations/test/project_service_spec.rb +++ b/spec/services/integrations/test/project_service_spec.rb @@ -7,7 +7,8 @@ RSpec.describe Integrations::Test::ProjectService do describe '#execute' do let_it_be(:project) { create(:project) } - let(:integration) { create(:slack_service, project: project) } + + let(:integration) { create(:integrations_slack, project: project) } let(:user) { project.owner } let(:event) { nil } let(:sample_data) { { data: 'sample' } } @@ -32,7 +33,7 @@ RSpec.describe Integrations::Test::ProjectService do context 'with event specified' do context 'event not supported by integration' do - let(:integration) { create(:jira_service, project: project) } + let(:integration) { create(:jira_integration, project: project) } let(:event) { 'push' } it 'returns error message' do diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index 0b315422be8..4a285600d42 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -81,7 +81,7 @@ RSpec.describe Issues::CloseService do describe '#close_issue' do context 'with external issue' do context 'with an active external issue tracker supporting close_issue' do - let!(:external_issue_tracker) { create(:jira_service, project: project) } + let!(:external_issue_tracker) { create(:jira_integration, project: project) } it 'closes the issue on the external issue tracker' do project.reload @@ -92,7 +92,7 @@ RSpec.describe Issues::CloseService do end context 'with inactive external issue tracker supporting close_issue' do - let!(:external_issue_tracker) { create(:jira_service, project: project, active: false) } + let!(:external_issue_tracker) { create(:jira_integration, project: project, active: false) } it 'does not close the issue on the external issue tracker' do project.reload diff --git a/spec/services/jira/requests/projects/list_service_spec.rb b/spec/services/jira/requests/projects/list_service_spec.rb index 0fff51b1226..1230ac250d0 100644 --- a/spec/services/jira/requests/projects/list_service_spec.rb +++ b/spec/services/jira/requests/projects/list_service_spec.rb @@ -5,17 +5,17 @@ require 'spec_helper' RSpec.describe Jira::Requests::Projects::ListService do include AfterNextHelpers - let(:jira_service) { create(:jira_service) } + let(:jira_integration) { create(:jira_integration) } let(:params) { {} } describe '#execute' do - let(:service) { described_class.new(jira_service, params) } + let(:service) { described_class.new(jira_integration, params) } subject { service.execute } - context 'without jira_service' do + context 'without jira_integration' do before do - jira_service.update!(active: false) + jira_integration.update!(active: false) end it 'returns an error response' do @@ -24,8 +24,8 @@ RSpec.describe Jira::Requests::Projects::ListService do end end - context 'when jira_service is nil' do - let(:jira_service) { nil } + context 'when jira_integration is nil' do + let(:jira_integration) { nil } it 'returns an error response' do expect(subject.error?).to be_truthy @@ -33,7 +33,7 @@ RSpec.describe Jira::Requests::Projects::ListService do end end - context 'with jira_service' do + context 'with jira_integration' do context 'when validations and params are ok' do let(:response_headers) { { 'content-type' => 'application/json' } } let(:response_body) { [].to_json } @@ -59,7 +59,7 @@ RSpec.describe Jira::Requests::Projects::ListService do end context 'when jira runs on a subpath' do - let(:jira_service) { create(:jira_service, url: 'http://jira.example.com/jira') } + let(:jira_integration) { create(:jira_integration, url: 'http://jira.example.com/jira') } let(:expected_url_pattern) { /.*jira.example.com\/jira\/rest\/api\/2\/project/ } it 'takes the subpath into account' do diff --git a/spec/services/jira_import/start_import_service_spec.rb b/spec/services/jira_import/start_import_service_spec.rb index a10928355ef..36d639cd724 100644 --- a/spec/services/jira_import/start_import_service_spec.rb +++ b/spec/services/jira_import/start_import_service_spec.rb @@ -28,10 +28,10 @@ RSpec.describe JiraImport::StartImportService do end context 'when project validation is ok' do - let!(:jira_service) { create(:jira_service, project: project, active: true) } + let!(:jira_integration) { create(:jira_integration, project: project, active: true) } before do - stub_jira_service_test + stub_jira_integration_test allow(Gitlab::JiraImport).to receive(:validate_project_settings!) end diff --git a/spec/services/jira_import/users_importer_spec.rb b/spec/services/jira_import/users_importer_spec.rb index 2e8c556d62c..af408847260 100644 --- a/spec/services/jira_import/users_importer_spec.rb +++ b/spec/services/jira_import/users_importer_spec.rb @@ -33,7 +33,7 @@ RSpec.describe JiraImport::UsersImporter do end before do - stub_jira_service_test + stub_jira_integration_test project.add_maintainer(user) end @@ -45,7 +45,7 @@ RSpec.describe JiraImport::UsersImporter do RSpec.shared_examples 'maps Jira users to GitLab users' do |users_mapper_service:| context 'when Jira import is configured correctly' do - let_it_be(:jira_service) { create(:jira_service, project: project, active: true, url: "http://jira.example.net") } + let_it_be(:jira_integration) { create(:jira_integration, project: project, active: true, url: "http://jira.example.net") } context 'when users mapper service raises an error' do let(:error) { Timeout::Error.new } @@ -98,9 +98,9 @@ RSpec.describe JiraImport::UsersImporter do context 'when Jira instance is of Server deployment type' do before do - allow(project).to receive(:jira_service).and_return(jira_service) + allow(project).to receive(:jira_integration).and_return(jira_integration) - jira_service.data_fields.deployment_server! + jira_integration.data_fields.deployment_server! end it_behaves_like 'maps Jira users to GitLab users', users_mapper_service: JiraImport::ServerUsersMapperService @@ -108,9 +108,9 @@ RSpec.describe JiraImport::UsersImporter do context 'when Jira instance is of Cloud deployment type' do before do - allow(project).to receive(:jira_service).and_return(jira_service) + allow(project).to receive(:jira_integration).and_return(jira_integration) - jira_service.data_fields.deployment_cloud! + jira_integration.data_fields.deployment_cloud! end it_behaves_like 'maps Jira users to GitLab users', users_mapper_service: JiraImport::CloudUsersMapperService diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index d10f82289bd..0f282384661 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -252,8 +252,8 @@ RSpec.describe MergeRequests::BuildService do context 'when the source branch matches an issue' do where(:factory, :source_branch, :closing_message) do - :jira_service | 'FOO-123-fix-issue' | 'Closes FOO-123' - :jira_service | 'fix-issue' | nil + :jira_integration | 'FOO-123-fix-issue' | 'Closes FOO-123' + :jira_integration | 'fix-issue' | nil :custom_issue_tracker_integration | '123-fix-issue' | 'Closes #123' :custom_issue_tracker_integration | 'fix-issue' | nil nil | '123-fix-issue' | 'Closes #123' @@ -351,8 +351,8 @@ RSpec.describe MergeRequests::BuildService do context 'when the source branch matches an issue' do where(:factory, :source_branch, :title, :closing_message) do - :jira_service | 'FOO-123-fix-issue' | 'Resolve FOO-123 "Fix issue"' | 'Closes FOO-123' - :jira_service | 'fix-issue' | 'Fix issue' | nil + :jira_integration | 'FOO-123-fix-issue' | 'Resolve FOO-123 "Fix issue"' | 'Closes FOO-123' + :jira_integration | 'fix-issue' | 'Fix issue' | nil :custom_issue_tracker_integration | '123-fix-issue' | 'Resolve #123 "Fix issue"' | 'Closes #123' :custom_issue_tracker_integration | 'fix-issue' | 'Fix issue' | nil nil | '123-fix-issue' | 'Resolve "A bug"' | 'Closes #123' @@ -400,8 +400,8 @@ RSpec.describe MergeRequests::BuildService do context 'when the source branch matches an issue' do where(:factory, :source_branch, :title, :closing_message) do - :jira_service | 'FOO-123-fix-issue' | 'Resolve FOO-123 "Fix issue"' | 'Closes FOO-123' - :jira_service | 'fix-issue' | 'Fix issue' | nil + :jira_integration | 'FOO-123-fix-issue' | 'Resolve FOO-123 "Fix issue"' | 'Closes FOO-123' + :jira_integration | 'fix-issue' | 'Fix issue' | nil :custom_issue_tracker_integration | '123-fix-issue' | 'Resolve #123 "Fix issue"' | 'Closes #123' :custom_issue_tracker_integration | 'fix-issue' | 'Fix issue' | nil nil | '123-fix-issue' | 'Resolve "A bug"' | 'Closes #123' diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index 503c0282bd6..b3af4d67896 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -163,14 +163,14 @@ RSpec.describe MergeRequests::MergeService do context 'with Jira integration' do include JiraServiceHelper - let(:jira_tracker) { project.create_jira_service } + let(:jira_tracker) { project.create_jira_integration } let(:jira_issue) { ExternalIssue.new('JIRA-123', project) } let(:commit) { double('commit', safe_message: "Fixes #{jira_issue.to_reference}") } before do - stub_jira_service_test + stub_jira_integration_test project.update!(has_external_issue_tracker: true) - jira_service_settings + jira_integration_settings stub_jira_urls(jira_issue.id) allow(merge_request).to receive(:commits).and_return([commit]) end diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index ac0b6cc8ef1..b8e48cef171 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -703,7 +703,7 @@ RSpec.describe Projects::CreateService, '#execute' do create(:clusters_integrations_prometheus, cluster: cluster) end - it 'creates PrometheusService record', :aggregate_failures do + it 'creates Integrations::Prometheus record', :aggregate_failures do project = create_project(user, opts.merge!(namespace_id: group.id)) service = project.prometheus_service @@ -720,7 +720,7 @@ RSpec.describe Projects::CreateService, '#execute' do create(:clusters_integrations_prometheus, cluster: cluster) end - it 'creates PrometheusService record', :aggregate_failures do + it 'creates Integrations::Prometheus record', :aggregate_failures do project = create_project(user, opts) service = project.prometheus_service @@ -731,7 +731,7 @@ RSpec.describe Projects::CreateService, '#execute' do it 'cleans invalid record and logs warning', :aggregate_failures do invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json) - allow(PrometheusService).to receive(:new).and_return(invalid_service_record) + allow(::Integrations::Prometheus).to receive(:new).and_return(invalid_service_record) expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) })) project = create_project(user, opts) @@ -741,7 +741,7 @@ RSpec.describe Projects::CreateService, '#execute' do end context 'shared Prometheus integration is not available' do - it 'does not persist PrometheusService record', :aggregate_failures do + it 'does not persist Integrations::Prometheus record' do project = create_project(user, opts) expect(project.prometheus_service).to be_nil diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index 3171abfb36f..2856d2ee2da 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -7,7 +7,7 @@ RSpec.describe Projects::TransferService do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } - let_it_be(:group_integration) { create(:slack_service, group: group, project: nil, webhook: 'http://group.slack.com') } + let_it_be(:group_integration) { create(:integrations_slack, group: group, project: nil, webhook: 'http://group.slack.com') } let(:project) { create(:project, :repository, :legacy_storage, namespace: user.namespace) } subject(:execute_transfer) { described_class.new(project, user).execute(group).tap { project.reload } } @@ -121,24 +121,24 @@ RSpec.describe Projects::TransferService do context 'with a project integration' do let_it_be_with_reload(:project) { create(:project, namespace: user.namespace) } - let_it_be(:instance_integration) { create(:slack_service, :instance, webhook: 'http://project.slack.com') } + let_it_be(:instance_integration) { create(:integrations_slack, :instance, webhook: 'http://project.slack.com') } context 'with an inherited integration' do - let_it_be(:project_integration) { create(:slack_service, project: project, webhook: 'http://project.slack.com', inherit_from_id: instance_integration.id) } + let_it_be(:project_integration) { create(:integrations_slack, project: project, webhook: 'http://project.slack.com', inherit_from_id: instance_integration.id) } it 'replaces inherited integrations', :aggregate_failures do execute_transfer - expect(project.slack_service.webhook).to eq(group_integration.webhook) + expect(project.slack_integration.webhook).to eq(group_integration.webhook) expect(Integration.count).to eq(3) end end context 'with a custom integration' do - let_it_be(:project_integration) { create(:slack_service, project: project, webhook: 'http://project.slack.com') } + let_it_be(:project_integration) { create(:integrations_slack, project: project, webhook: 'http://project.slack.com') } it 'does not updates the integrations' do - expect { execute_transfer }.not_to change { project.slack_service.webhook } + expect { execute_transfer }.not_to change { project.slack_integration.webhook } end end end diff --git a/spec/services/projects/update_service_spec.rb b/spec/services/projects/update_service_spec.rb index e1b22da2e61..315329263b5 100644 --- a/spec/services/projects/update_service_spec.rb +++ b/spec/services/projects/update_service_spec.rb @@ -503,7 +503,7 @@ RSpec.describe Projects::UpdateService do it 'creates new record' do expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) } - .to change { ::PrometheusService.where(project: project).count } + .to change { ::Integrations::Prometheus.where(project: project).count } .from(0) .to(1) end @@ -519,7 +519,7 @@ RSpec.describe Projects::UpdateService do it 'does not create new record' do expect { update_project(project, user, prometheus_service_attributes: prometheus_service_attributes) } - .not_to change { ::PrometheusService.where(project: project).count } + .not_to change { ::Integrations::Prometheus.where(project: project).count } end end end diff --git a/spec/services/prometheus/proxy_service_spec.rb b/spec/services/prometheus/proxy_service_spec.rb index f22ea361fde..b78683cace7 100644 --- a/spec/services/prometheus/proxy_service_spec.rb +++ b/spec/services/prometheus/proxy_service_spec.rb @@ -65,7 +65,7 @@ RSpec.describe Prometheus::ProxyService do end describe '#execute' do - let(:prometheus_adapter) { instance_double(PrometheusService) } + let(:prometheus_adapter) { instance_double(::Integrations::Prometheus) } let(:params) { ActionController::Parameters.new(query: '1').permit! } subject { described_class.new(environment, 'GET', 'query', params) } diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 54cef164f1c..395fada574e 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -355,15 +355,15 @@ RSpec.describe SystemNoteService do let(:issue) { create(:issue, project: project) } let(:merge_request) { create(:merge_request, :simple, target_project: project, source_project: project) } let(:jira_issue) { ExternalIssue.new("JIRA-1", project)} - let(:jira_tracker) { project.jira_service } + let(:jira_tracker) { project.jira_integration } let(:commit) { project.commit } let(:comment_url) { jira_api_comment_url(jira_issue.id) } let(:success_message) { "SUCCESS: Successfully posted to http://jira.example.net." } before do - stub_jira_service_test + stub_jira_integration_test stub_jira_urls(jira_issue.id) - jira_service_settings + jira_integration_settings end def cross_reference(type, link_exists = false) diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb index 0eb327ea7f1..d2d9eba2bc6 100644 --- a/spec/services/system_notes/issuables_service_spec.rb +++ b/spec/services/system_notes/issuables_service_spec.rb @@ -728,7 +728,7 @@ RSpec.describe ::SystemNotes::IssuablesService do let(:noteable) { ExternalIssue.new('EXT-1234', project) } it 'is false with issue tracker supporting referencing' do - create(:jira_service, project: project) + create(:jira_integration, project: project) project.reload expect(service.cross_reference_disallowed?(noteable)).to be_falsey diff --git a/spec/support/helpers/jira_service_helper.rb b/spec/support/helpers/jira_service_helper.rb index ce908d53f88..3cfd0de06e8 100644 --- a/spec/support/helpers/jira_service_helper.rb +++ b/spec/support/helpers/jira_service_helper.rb @@ -4,7 +4,7 @@ module JiraServiceHelper JIRA_URL = "http://jira.example.net" JIRA_API = JIRA_URL + "/rest/api/2" - def jira_service_settings + def jira_integration_settings url = JIRA_URL username = 'jira-user' password = 'my-secret-password' @@ -77,7 +77,7 @@ module JiraServiceHelper JIRA_API + "/issue/#{issue_id}" end - def stub_jira_service_test + def stub_jira_integration_test WebMock.stub_request(:get, /serverInfo/).to_return(body: { url: 'http://url' }.to_json) end diff --git a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb index e532b42fd1c..588e73394b7 100644 --- a/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb +++ b/spec/support/shared_contexts/features/integrations/integrations_shared_context.rb @@ -46,7 +46,7 @@ Integration.available_services_names.each do |service| before do enable_license_for_service(service) - stub_jira_service_test if service == 'jira' + stub_jira_integration_test if service == 'jira' end def initialize_service(service, attrs = {}) diff --git a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb index de40b926a1c..6d34675e8e5 100644 --- a/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb +++ b/spec/support/shared_contexts/requests/api/graphql/jira_import/jira_projects_context.rb @@ -4,8 +4,8 @@ RSpec.shared_context 'Jira projects request context' do let(:url) { 'https://jira.example.com' } let(:username) { 'jira-username' } let(:password) { 'jira-password' } - let!(:jira_service) do - create(:jira_service, + let!(:jira_integration) do + create(:jira_integration, project: project, url: url, username: username, diff --git a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb index 66448aca2c5..1bba398f59e 100644 --- a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb +++ b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb @@ -8,7 +8,7 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |service_name| def execute_with_options(options) receive(:new).with(webhook_url, options.merge(http_client: Integrations::SlackMattermostNotifier::HTTPClient)) - .and_return(double(:slack_service).as_null_object) + .and_return(double(:slack_integration).as_null_object) end describe "Associations" do diff --git a/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb b/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb index b275d594792..9d1a55b5f73 100644 --- a/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb +++ b/spec/support/shared_examples/models/issue_tracker_service_shared_examples.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.shared_examples 'issue tracker service URL attribute' do |url_attr| +RSpec.shared_examples 'issue tracker integration URL attribute' do |url_attr| it { is_expected.to allow_value('https://example.com').for(url_attr) } it { is_expected.not_to allow_value('example.com').for(url_attr) } @@ -8,6 +8,12 @@ RSpec.shared_examples 'issue tracker service URL attribute' do |url_attr| it { is_expected.not_to allow_value('herp-and-derp').for(url_attr) } end +# TODO: clean up: +# remove when https://gitlab.com/gitlab-org/gitlab/-/issues/330300 has been completed +RSpec.shared_examples 'issue tracker service URL attribute' do |url_attr| + it_behaves_like 'issue tracker integration URL attribute', url_attr +end + RSpec.shared_examples 'allows project key on reference pattern' do |url_attr| it 'allows underscores in the project name' do expect(described_class.reference_pattern.match('EXT_EXT-1234')[0]).to eq 'EXT_EXT-1234' diff --git a/spec/support/shared_examples/services/jira_import/user_mapper_services_shared_examples.rb b/spec/support/shared_examples/services/jira_import/user_mapper_services_shared_examples.rb index cbe5c7d89db..0151723793e 100644 --- a/spec/support/shared_examples/services/jira_import/user_mapper_services_shared_examples.rb +++ b/spec/support/shared_examples/services/jira_import/user_mapper_services_shared_examples.rb @@ -3,7 +3,7 @@ RSpec.shared_examples 'mapping jira users' do let(:client) { double } - let_it_be(:jira_service) { create(:jira_service, project: project, active: true) } + let_it_be(:jira_integration) { create(:jira_integration, project: project, active: true) } before do allow(subject).to receive(:client).and_return(client) diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index a1aa7c04b67..172fe249eb6 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -313,7 +313,7 @@ RSpec.describe 'layouts/nav/sidebar/_project' do end context 'with Jira issue tracker' do - let_it_be(:jira) { create(:jira_service, project: project, issues_enabled: false) } + let_it_be(:jira) { create(:jira_integration, project: project, issues_enabled: false) } it 'has a link to the Jira issue tracker' do render diff --git a/spec/views/projects/services/_form.haml_spec.rb b/spec/views/projects/services/_form.haml_spec.rb index f063e73dae4..177f703ba6c 100644 --- a/spec/views/projects/services/_form.haml_spec.rb +++ b/spec/views/projects/services/_form.haml_spec.rb @@ -15,7 +15,7 @@ RSpec.describe 'projects/services/_form' do current_user: user, can?: true, current_application_settings: Gitlab::CurrentSettings.current_application_settings, - integration: project.redmine_service, + integration: project.redmine_integration, request: double(referer: '/services') ) end diff --git a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb index f82f6ccd9d6..10702c17cb5 100644 --- a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb @@ -16,7 +16,7 @@ RSpec.describe Gitlab::JiraImport::Stage::ImportIssuesWorker do let_it_be(:jira_import, reload: true) { create(:jira_import_state, :scheduled, project: project) } before do - stub_jira_service_test + stub_jira_integration_test end context 'when import did not start' do @@ -25,7 +25,7 @@ RSpec.describe Gitlab::JiraImport::Stage::ImportIssuesWorker do end context 'when import started', :clean_gitlab_redis_cache do - let_it_be(:jira_service) { create(:jira_service, project: project) } + let_it_be(:jira_integration) { create(:jira_integration, project: project) } before do jira_import.start! diff --git a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb index 0b7a35a92e2..52c516b9ff9 100644 --- a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb @@ -21,10 +21,10 @@ RSpec.describe Gitlab::JiraImport::Stage::ImportLabelsWorker do end context 'when import started' do - let!(:jira_service) { create(:jira_service, project: project) } + let!(:jira_integration) { create(:jira_integration, project: project) } before do - stub_jira_service_test + stub_jira_integration_test jira_import.start! diff --git a/spec/workers/projects/post_creation_worker_spec.rb b/spec/workers/projects/post_creation_worker_spec.rb index 50c21575878..d1600daa3bd 100644 --- a/spec/workers/projects/post_creation_worker_spec.rb +++ b/spec/workers/projects/post_creation_worker_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Projects::PostCreationWorker do create(:clusters_integrations_prometheus, cluster: cluster) end - it 'creates PrometheusService record', :aggregate_failures do + it 'creates an Integrations::Prometheus record', :aggregate_failures do subject service = project.prometheus_service @@ -53,7 +53,7 @@ RSpec.describe Projects::PostCreationWorker do create(:clusters_integrations_prometheus, cluster: cluster) end - it 'creates PrometheusService record', :aggregate_failures do + it 'creates an Integrations::Prometheus record', :aggregate_failures do subject service = project.prometheus_service @@ -64,7 +64,7 @@ RSpec.describe Projects::PostCreationWorker do it 'cleans invalid record and logs warning', :aggregate_failures do invalid_service_record = build(:prometheus_service, properties: { api_url: nil, manual_configuration: true }.to_json) - allow(PrometheusService).to receive(:new).and_return(invalid_service_record) + allow(::Integrations::Prometheus).to receive(:new).and_return(invalid_service_record) expect(Gitlab::ErrorTracking).to receive(:track_exception).with(an_instance_of(ActiveRecord::RecordInvalid), include(extra: { project_id: a_kind_of(Integer) })).twice subject @@ -74,7 +74,7 @@ RSpec.describe Projects::PostCreationWorker do end context 'shared Prometheus application is not available' do - it 'does not persist PrometheusService record', :aggregate_failures do + it 'does not persist an Integrations::Prometheus record' do subject expect(project.prometheus_service).to be_nil diff --git a/spec/workers/propagate_integration_group_worker_spec.rb b/spec/workers/propagate_integration_group_worker_spec.rb index 1c72bed323a..9d46534df4f 100644 --- a/spec/workers/propagate_integration_group_worker_spec.rb +++ b/spec/workers/propagate_integration_group_worker_spec.rb @@ -8,7 +8,7 @@ RSpec.describe PropagateIntegrationGroupWorker do let_it_be(:another_group) { create(:group) } let_it_be(:subgroup1) { create(:group, parent: group) } let_it_be(:subgroup2) { create(:group, parent: group) } - let_it_be(:integration) { create(:redmine_service, :instance) } + let_it_be(:integration) { create(:redmine_integration, :instance) } let(:job_args) { [integration.id, group.id, subgroup2.id] } @@ -22,7 +22,7 @@ RSpec.describe PropagateIntegrationGroupWorker do end context 'with a group integration' do - let_it_be(:integration) { create(:redmine_service, group: group, project: nil) } + let_it_be(:integration) { create(:redmine_integration, group: group, project: nil) } it 'calls to BulkCreateIntegrationService' do expect(BulkCreateIntegrationService).to receive(:new) diff --git a/spec/workers/propagate_integration_inherit_descendant_worker_spec.rb b/spec/workers/propagate_integration_inherit_descendant_worker_spec.rb index b5eb0f69017..8a231d4104c 100644 --- a/spec/workers/propagate_integration_inherit_descendant_worker_spec.rb +++ b/spec/workers/propagate_integration_inherit_descendant_worker_spec.rb @@ -5,8 +5,8 @@ require 'spec_helper' RSpec.describe PropagateIntegrationInheritDescendantWorker do let_it_be(:group) { create(:group) } let_it_be(:subgroup) { create(:group, parent: group) } - let_it_be(:group_integration) { create(:redmine_service, group: group, project: nil) } - let_it_be(:subgroup_integration) { create(:redmine_service, group: subgroup, project: nil, inherit_from_id: group_integration.id) } + let_it_be(:group_integration) { create(:redmine_integration, group: group, project: nil) } + let_it_be(:subgroup_integration) { create(:redmine_integration, group: subgroup, project: nil, inherit_from_id: group_integration.id) } it_behaves_like 'an idempotent worker' do let(:job_args) { [group_integration.id, subgroup_integration.id, subgroup_integration.id] } diff --git a/spec/workers/propagate_integration_inherit_worker_spec.rb b/spec/workers/propagate_integration_inherit_worker_spec.rb index 2b4f241f755..dd5d246d7f9 100644 --- a/spec/workers/propagate_integration_inherit_worker_spec.rb +++ b/spec/workers/propagate_integration_inherit_worker_spec.rb @@ -4,10 +4,10 @@ require 'spec_helper' RSpec.describe PropagateIntegrationInheritWorker do describe '#perform' do - let_it_be(:integration) { create(:redmine_service, :instance) } - let_it_be(:integration1) { create(:redmine_service, inherit_from_id: integration.id) } + let_it_be(:integration) { create(:redmine_integration, :instance) } + let_it_be(:integration1) { create(:redmine_integration, inherit_from_id: integration.id) } let_it_be(:integration2) { create(:bugzilla_integration, inherit_from_id: integration.id) } - let_it_be(:integration3) { create(:redmine_service) } + let_it_be(:integration3) { create(:redmine_integration) } it_behaves_like 'an idempotent worker' do let(:job_args) { [integration.id, integration1.id, integration3.id] } diff --git a/spec/workers/propagate_integration_project_worker_spec.rb b/spec/workers/propagate_integration_project_worker_spec.rb index c8293744bec..312631252cc 100644 --- a/spec/workers/propagate_integration_project_worker_spec.rb +++ b/spec/workers/propagate_integration_project_worker_spec.rb @@ -8,7 +8,7 @@ RSpec.describe PropagateIntegrationProjectWorker do let_it_be(:project1) { create(:project) } let_it_be(:project2) { create(:project, group: group) } let_it_be(:project3) { create(:project, group: group) } - let_it_be(:integration) { create(:redmine_service, :instance) } + let_it_be(:integration) { create(:redmine_integration, :instance) } let(:job_args) { [integration.id, project1.id, project3.id] } @@ -22,7 +22,7 @@ RSpec.describe PropagateIntegrationProjectWorker do end context 'with a group integration' do - let_it_be(:integration) { create(:redmine_service, group: group, project: nil) } + let_it_be(:integration) { create(:redmine_integration, group: group, project: nil) } it 'calls to BulkCreateIntegrationService' do expect(BulkCreateIntegrationService).to receive(:new) -- cgit v1.2.3