summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/projects/error_tracking_controller.rb40
-rw-r--r--app/controllers/projects/settings/operations_controller.rb40
-rw-r--r--app/models/error_tracking/project_error_tracking_setting.rb20
-rw-r--r--app/serializers/error_tracking/project_serializer.rb2
-rw-r--r--app/services/error_tracking/list_projects_service.rb15
-rw-r--r--app/services/error_tracking/list_sentry_projects_service.rb45
-rw-r--r--app/services/projects/operations/update_service.rb23
-rw-r--r--config/routes/project.rb6
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb128
-rw-r--r--spec/controllers/projects/settings/operations_controller_spec.rb70
-rw-r--r--spec/models/error_tracking/project_error_tracking_setting_spec.rb70
-rw-r--r--spec/services/error_tracking/list_projects_service_spec.rb49
-rw-r--r--spec/services/error_tracking/list_sentry_projects_service_spec.rb149
-rw-r--r--spec/services/projects/operations/update_service_spec.rb58
14 files changed, 643 insertions, 72 deletions
diff --git a/app/controllers/projects/error_tracking_controller.rb b/app/controllers/projects/error_tracking_controller.rb
index 9e403e1d25b..2cd3dad12a2 100644
--- a/app/controllers/projects/error_tracking_controller.rb
+++ b/app/controllers/projects/error_tracking_controller.rb
@@ -15,6 +15,14 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
end
end
+ def list_projects
+ respond_to do |format|
+ format.json do
+ render_project_list_json
+ end
+ end
+ end
+
private
def render_index_json
@@ -32,6 +40,32 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
}
end
+ def render_project_list_json
+ service = ErrorTracking::ListProjectsService.new(
+ project,
+ current_user,
+ list_projects_params
+ )
+ result = service.execute
+
+ unless result[:status] == :success
+ return render(
+ status: result[:http_status] || :bad_request,
+ json: {
+ message: result[:message]
+ }
+ )
+ end
+
+ render json: {
+ projects: serialize_projects(result[:projects])
+ }
+ end
+
+ def list_projects_params
+ params.require(:error_tracking_setting).permit([:api_host, :token])
+ end
+
def set_polling_interval
Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
end
@@ -41,4 +75,10 @@ class Projects::ErrorTrackingController < Projects::ApplicationController
.new(project: project, user: current_user)
.represent(errors)
end
+
+ def serialize_projects(projects)
+ ErrorTracking::ProjectSerializer
+ .new(project: project, user: current_user)
+ .represent(projects)
+ end
end
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index 521ec2acebb..1ba0ff8be7b 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -14,16 +14,37 @@ module Projects
def update
result = ::Projects::Operations::UpdateService.new(project, current_user, update_params).execute
+ render_update_response(result)
+ end
+
+ private
+
+ # overridden in EE
+ def render_update_response(result)
+ respond_to do |format|
+ format.json do
+ render_update_json_response(result)
+ end
+ end
+ end
+
+ def render_update_json_response(result)
if result[:status] == :success
- flash[:notice] = _('Your changes have been saved')
- redirect_to project_settings_operations_path(@project)
+ render json: {
+ status: result[:status],
+ message: _('Your changes have been saved')
+ }
else
- render 'show'
+ render(
+ status: result[:http_status] || :bad_request,
+ json: {
+ status: result[:status],
+ message: result[:message]
+ }
+ )
end
end
- private
-
def error_tracking_setting
@error_tracking_setting ||= project.error_tracking_setting ||
project.build_error_tracking_setting
@@ -35,7 +56,14 @@ module Projects
# overridden in EE
def permitted_project_params
- { error_tracking_setting_attributes: [:enabled, :api_url, :token] }
+ {
+ error_tracking_setting_attributes: [
+ :enabled,
+ :api_host,
+ :token,
+ project: [:slug, :name, :organization_slug, :organization_name]
+ ]
+ }
end
def check_license
diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb
index 31084c54bdc..892eef8eb99 100644
--- a/app/models/error_tracking/project_error_tracking_setting.rb
+++ b/app/models/error_tracking/project_error_tracking_setting.rb
@@ -40,6 +40,8 @@ module ErrorTracking
end
def self.build_api_url_from(api_host:, project_slug:, organization_slug:)
+ return if api_host.blank?
+
uri = Addressable::URI.parse("#{api_host}/api/0/projects/#{organization_slug}/#{project_slug}/")
uri.path = uri.path.squeeze('/')
@@ -63,13 +65,29 @@ module ErrorTracking
end
def list_sentry_projects
- { projects: sentry_client.list_projects }
+ with_reactive_cache('list_projects', {}) do |result|
+ result
+ end
end
def calculate_reactive_cache(request, opts)
case request
when 'list_issues'
sentry_client.list_issues(**opts.symbolize_keys)
+ when 'list_projects'
+ begin
+ { projects: sentry_client.list_projects }
+ rescue Sentry::Client::SentryError => e
+ {
+ error: e.message,
+ http_status: :unprocessable_entity
+ }
+ rescue Sentry::Client::Error => e
+ {
+ error: e.message,
+ http_status: :bad_request
+ }
+ end
end
end
diff --git a/app/serializers/error_tracking/project_serializer.rb b/app/serializers/error_tracking/project_serializer.rb
index b2406f4d631..68724088fff 100644
--- a/app/serializers/error_tracking/project_serializer.rb
+++ b/app/serializers/error_tracking/project_serializer.rb
@@ -2,6 +2,6 @@
module ErrorTracking
class ProjectSerializer < BaseSerializer
- entity ProjectEntity
+ entity ErrorTracking::ProjectEntity
end
end
diff --git a/app/services/error_tracking/list_projects_service.rb b/app/services/error_tracking/list_projects_service.rb
index c6e8be0f2be..f2d0904a41f 100644
--- a/app/services/error_tracking/list_projects_service.rb
+++ b/app/services/error_tracking/list_projects_service.rb
@@ -11,12 +11,15 @@ module ErrorTracking
return error(setting.errors.full_messages.join(', '), :bad_request)
end
- begin
- result = setting.list_sentry_projects
- rescue Sentry::Client::Error => e
- return error(e.message, :bad_request)
- rescue Sentry::Client::SentryError => e
- return error(e.message, :unprocessable_entity)
+ result = setting.list_sentry_projects
+
+ # our results are not yet ready
+ if result.nil?
+ return error('not ready', :no_content)
+ end
+
+ if result[:error].present?
+ return error(result[:error], result[:http_status] || :bad_request)
end
success(projects: result[:projects])
diff --git a/app/services/error_tracking/list_sentry_projects_service.rb b/app/services/error_tracking/list_sentry_projects_service.rb
new file mode 100644
index 00000000000..c07ab0e84a2
--- /dev/null
+++ b/app/services/error_tracking/list_sentry_projects_service.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module ErrorTracking
+ class ListSentryProjectsService < ::BaseService
+ def execute
+ return error('access denied') unless can_read?
+
+ e = project_error_tracking_setting
+
+ unless e.valid?
+ return error(e.errors.full_messages.join(', '), :bad_request)
+ end
+
+ begin
+ result = e.list_sentry_projects
+ rescue Sentry::Client::Error => e
+ return error(e.message, :bad_request)
+ rescue Sentry::Client::SentryError => e
+ return error(e.message, :unprocessable_entity)
+ end
+
+ success(projects: result[:projects])
+ end
+
+ private
+
+ def project_error_tracking_setting
+ e = project.error_tracking_setting || project.build_error_tracking_setting
+
+ e.api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
+ api_host: params[:api_host],
+ organization_slug: nil,
+ project_slug: nil
+ )
+ e.token = params[:token]
+ e.enabled = true
+
+ e
+ end
+
+ def can_read?
+ can?(current_user, :read_sentry_issue, project)
+ end
+ end
+end
diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb
index abd6d8de750..aedf79c86d7 100644
--- a/app/services/projects/operations/update_service.rb
+++ b/app/services/projects/operations/update_service.rb
@@ -12,7 +12,28 @@ module Projects
private
def project_update_params
- params.slice(:error_tracking_setting_attributes)
+ error_tracking_params
+ end
+
+ def error_tracking_params
+ settings = params[:error_tracking_setting_attributes]
+ return {} if settings.blank?
+
+ api_url = ErrorTracking::ProjectErrorTrackingSetting.build_api_url_from(
+ api_host: settings[:api_host],
+ project_slug: settings.dig(:project, :slug),
+ organization_slug: settings.dig(:project, :organization_slug)
+ )
+
+ {
+ error_tracking_setting_attributes: {
+ api_url: api_url,
+ token: settings[:token],
+ enabled: settings[:enabled],
+ project_name: settings.dig(:project, :name),
+ organization_name: settings.dig(:project, :organization_name)
+ }
+ }
end
end
end
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 21793e7756a..59b4a119a08 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -443,7 +443,11 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
- resources :error_tracking, only: [:index], controller: :error_tracking
+ resources :error_tracking, only: [:index], controller: :error_tracking do
+ collection do
+ post :list_projects
+ end
+ end
# Since both wiki and repository routing contains wildcard characters
# its preferable to keep it below all other project routes
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 6464398cea1..f65b00aabfd 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -107,8 +107,11 @@ describe Projects::ErrorTrackingController do
let(:http_status) { :no_content }
before do
- expect(list_issues_service).to receive(:execute)
- .and_return(status: :error, message: error_message, http_status: http_status)
+ expect(list_issues_service).to receive(:execute).and_return(
+ status: :error,
+ message: error_message,
+ http_status: http_status
+ )
end
it 'returns http_status with message' do
@@ -122,9 +125,130 @@ describe Projects::ErrorTrackingController do
end
end
+ describe 'POST #list_projects' do
+ context 'with insufficient permissions' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'returns 404' do
+ post :list_projects, params: list_projects_params
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'with an anonymous user' do
+ before do
+ sign_out(user)
+ end
+
+ it 'redirects to sign-in page' do
+ post :list_projects, params: list_projects_params
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context 'with authorized user' do
+ let(:list_projects_service) { spy(:list_projects_service) }
+ let(:sentry_project) { build(:error_tracking_project) }
+
+ before do
+ expect(ErrorTracking::ListProjectsService)
+ .to receive(:new).with(
+ project,
+ user,
+ ActionController::Parameters.new(
+ list_projects_params[:error_tracking_setting]
+ ).permit!
+ )
+ .and_return(list_projects_service)
+ end
+
+ context 'service result is successful' do
+ before do
+ expect(list_projects_service).to receive(:execute)
+ .and_return(status: :success, projects: [sentry_project])
+ end
+
+ it 'returns a list of projects' do
+ post :list_projects, params: list_projects_params
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('error_tracking/list_projects')
+ expect(json_response['projects']).to eq([sentry_project].as_json)
+ end
+ end
+
+ context 'service result is erroneous' do
+ let(:error_message) { 'error message' }
+
+ context 'without http_status' do
+ before do
+ expect(list_projects_service).to receive(:execute)
+ .and_return(status: :error, message: error_message)
+ end
+
+ it 'returns 400 with message' do
+ get :list_projects, params: list_projects_params
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']).to eq(error_message)
+ end
+ end
+
+ context 'with explicit http_status' do
+ let(:http_status) { :no_content }
+
+ before do
+ expect(list_projects_service).to receive(:execute).and_return(
+ status: :error,
+ message: error_message,
+ http_status: http_status
+ )
+ end
+
+ it 'returns http_status with message' do
+ get :list_projects, params: list_projects_params
+
+ expect(response).to have_gitlab_http_status(http_status)
+ expect(json_response['message']).to eq(error_message)
+ end
+ end
+ end
+ end
+
+ private
+
+ def list_projects_params(opts = {})
+ opts.reverse_merge(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json,
+ error_tracking_setting: {
+ api_host: 'gitlab.com',
+ token: 'token'
+ }
+ )
+ end
+ end
+
private
def project_params(opts = {})
opts.reverse_merge(namespace_id: project.namespace, project_id: project)
end
+
+ def list_projects_params(opts = {})
+ opts.reverse_merge(
+ namespace_id: project.namespace,
+ project_id: project,
+ format: :json,
+ error_tracking_setting: {
+ api_host: 'gitlab.com',
+ token: 'token'
+ }
+ )
+ end
end
diff --git a/spec/controllers/projects/settings/operations_controller_spec.rb b/spec/controllers/projects/settings/operations_controller_spec.rb
index d989ec22481..825aa2c7db2 100644
--- a/spec/controllers/projects/settings/operations_controller_spec.rb
+++ b/spec/controllers/projects/settings/operations_controller_spec.rb
@@ -74,38 +74,56 @@ describe Projects::Settings::OperationsController do
{
error_tracking_setting_attributes: {
enabled: '1',
- api_url: 'http://url',
- token: 'token'
+ api_host: 'http://url',
+ token: 'token',
+ project: {
+ slug: 'sentry-project',
+ name: 'Sentry Project',
+ organization_slug: 'sentry-org',
+ organization_name: 'Sentry Org'
+ }
}
}
end
+
let(:error_tracking_permitted) do
ActionController::Parameters.new(error_tracking_params).permit!
end
- context 'when update succeeds' do
- before do
- stub_operations_update_service_returning(status: :success)
- end
-
- it 'shows a notice' do
- patch :update, params: project_params(project, error_tracking_params)
-
- expect(response).to redirect_to(operations_url)
- expect(flash[:notice]).to eq _('Your changes have been saved')
- end
- end
-
- context 'when update fails' do
- before do
- stub_operations_update_service_returning(status: :error)
+ context 'format json' do
+ context 'when update succeeds' do
+ before do
+ stub_operations_update_service_returning(status: :success)
+ end
+
+ it 'returns success status' do
+ patch :update,
+ params: project_params(project, error_tracking_params),
+ format: :json
+
+ expect(json_response).to eq(
+ 'status' => 'success',
+ 'message' => _('Your changes have been saved')
+ )
+ end
end
- it 'renders show page' do
- patch :update, params: project_params(project, error_tracking_params)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response).to render_template(:show)
+ context 'when update fails' do
+ before do
+ stub_operations_update_service_returning(
+ status: :error,
+ message: 'error message'
+ )
+ end
+
+ it 'returns error' do
+ patch :update,
+ params: project_params(project, error_tracking_params),
+ format: :json
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']).not_to be_nil
+ end
end
end
@@ -147,11 +165,11 @@ describe Projects::Settings::OperationsController do
private
- def project_params(project, params = {})
+ def project_params(project, project_params = {}, other_params = {})
{
namespace_id: project.namespace,
project_id: project,
- project: params
- }
+ project: project_params
+ }.merge(other_params)
end
end
diff --git a/spec/models/error_tracking/project_error_tracking_setting_spec.rb b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
index d30228b863c..eed2ccc8ea0 100644
--- a/spec/models/error_tracking/project_error_tracking_setting_spec.rb
+++ b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
@@ -149,15 +149,63 @@ describe ErrorTracking::ProjectErrorTrackingSetting do
describe '#list_sentry_projects' do
let(:projects) { [:list, :of, :projects] }
- let(:sentry_client) { spy(:sentry_client) }
- it 'calls sentry client' do
- expect(subject).to receive(:sentry_client).and_return(sentry_client)
- expect(sentry_client).to receive(:list_projects).and_return(projects)
+ let(:result) do
+ subject.list_sentry_projects
+ end
+
+ context 'when cached' do
+ let(:sentry_client) { spy(:sentry_client) }
+
+ before do
+ stub_reactive_cache(subject, projects, {})
+ synchronous_reactive_cache(subject)
+
+ expect(subject).to receive(:sentry_client).and_return(sentry_client)
+ expect(sentry_client).to receive(:list_projects)
+ .and_return(projects)
+ end
+
+ it 'returns cached projects' do
+ expect(result).to eq(projects: projects)
+ end
+ end
+
+ context 'when not cached' do
+ it 'returns nil' do
+ expect(subject).not_to receive(:sentry_client)
+ expect(result).to be_nil
+ end
+ end
+
+ context 'when sentry client raises exception' do
+ let(:sentry_client) { spy(:sentry_client) }
+
+ before do
+ synchronous_reactive_cache(subject)
+
+ expect(subject).to receive(:sentry_client).and_return(sentry_client)
+ end
+
+ it 'returns error for Sentry::Client::Error exception' do
+ expect(sentry_client).to receive(:list_projects)
+ .and_raise(Sentry::Client::Error, 'error message')
- result = subject.list_sentry_projects
+ expect(result).to eq(
+ error: 'error message',
+ http_status: :bad_request
+ )
+ end
+
+ it 'returns error for Sentry::Client::SentryError exception' do
+ expect(sentry_client).to receive(:list_projects)
+ .and_raise(Sentry::Client::SentryError, 'error message')
- expect(result).to eq(projects: projects)
+ expect(result).to eq(
+ error: 'error message',
+ http_status: :unprocessable_entity
+ )
+ end
end
end
@@ -257,6 +305,16 @@ describe ErrorTracking::ProjectErrorTrackingSetting do
expect(api_url).to eq(':::')
end
+
+ it 'returns nil when api_host is blank' do
+ api_url = described_class.build_api_url_from(
+ api_host: '',
+ organization_slug: 'org-slug',
+ project_slug: 'proj-slug'
+ )
+
+ expect(api_url).to be_nil
+ end
end
describe '#api_host' do
diff --git a/spec/services/error_tracking/list_projects_service_spec.rb b/spec/services/error_tracking/list_projects_service_spec.rb
index ee9c59e3f65..6204ca87576 100644
--- a/spec/services/error_tracking/list_projects_service_spec.rb
+++ b/spec/services/error_tracking/list_projects_service_spec.rb
@@ -50,18 +50,6 @@ describe ErrorTracking::ListProjectsService do
end
end
- context 'sentry client raises exception' do
- before do
- expect(error_tracking_setting).to receive(:list_sentry_projects)
- .and_raise(Sentry::Client::Error, 'Sentry response error: 500')
- end
-
- it 'returns error response' do
- expect(result[:message]).to eq('Sentry response error: 500')
- expect(result[:http_status]).to eq(:bad_request)
- end
- end
-
context 'with invalid url' do
let(:params) do
ActionController::Parameters.new(
@@ -92,6 +80,39 @@ describe ErrorTracking::ListProjectsService do
expect(result).to eq(status: :success, projects: projects)
end
end
+
+ context 'when list_sentry_projects returns nil' do
+ before do
+ expect(error_tracking_setting)
+ .to receive(:list_sentry_projects).and_return(nil)
+ end
+
+ it 'result is not ready' do
+ result = subject.execute
+
+ expect(result).to eq(
+ status: :error,
+ http_status: :no_content,
+ message: 'not ready'
+ )
+ end
+ end
+
+ context 'when list_sentry_projects returns empty array' do
+ before do
+ expect(error_tracking_setting)
+ .to receive(:list_sentry_projects).and_return({ projects: [] })
+ end
+
+ it 'returns the empty array' do
+ result = subject.execute
+
+ expect(result).to eq(
+ status: :success,
+ projects: []
+ )
+ end
+ end
end
context 'with unauthorized user' do
@@ -112,10 +133,14 @@ describe ErrorTracking::ListProjectsService do
.to receive(:list_sentry_projects).and_return(projects: [])
error_tracking_setting.enabled = false
+ error_tracking_setting.save!
end
it 'ignores enabled flag' do
expect(result).to include(status: :success, projects: [])
+
+ error_tracking_setting.reload
+ expect(error_tracking_setting.enabled).to be false
end
end
diff --git a/spec/services/error_tracking/list_sentry_projects_service_spec.rb b/spec/services/error_tracking/list_sentry_projects_service_spec.rb
new file mode 100644
index 00000000000..ad9ea56f279
--- /dev/null
+++ b/spec/services/error_tracking/list_sentry_projects_service_spec.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ErrorTracking::ListSentryProjectsService do
+ set(:user) { create(:user) }
+ set(:project) { create(:project) }
+
+ let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' }
+ let(:token) { 'test-token' }
+ let(:new_api_host) { 'https://gitlab.com/' }
+ let(:new_token) { 'new-token' }
+ let(:params) { ActionController::Parameters.new(api_host: new_api_host, token: new_token) }
+
+ let(:error_tracking_setting) do
+ create(:project_error_tracking_setting, api_url: sentry_url, token: token, project: project)
+ end
+
+ subject { described_class.new(project, user, params) }
+
+ before do
+ project.add_reporter(user)
+ end
+
+ describe '#execute' do
+ context 'with authorized user' do
+ before do
+ expect(project).to receive(:error_tracking_setting).at_least(:once)
+ .and_return(error_tracking_setting)
+ end
+
+ it 'uses new api_url and token' do
+ sentry_client = spy(:sentry_client)
+
+ expect(Sentry::Client).to receive(:new)
+ .with(new_api_host + 'api/0/projects/', new_token).and_return(sentry_client)
+ expect(sentry_client).to receive(:list_projects).and_return([])
+
+ subject.execute
+ end
+
+ context 'sentry client raises exception' do
+ it 'returns error response' do
+ expect(error_tracking_setting).to receive(:list_sentry_projects)
+ .and_raise(Sentry::Client::Error, 'Sentry response error: 500')
+
+ subject = described_class.new(project, user, params)
+ result = subject.execute
+
+ expect(result[:message]).to eq('Sentry response error: 500')
+ expect(result[:http_status]).to eq(:bad_request)
+ end
+ end
+
+ context 'with invalid url' do
+ let(:params) do
+ ActionController::Parameters.new(
+ api_host: 'https://localhost',
+ token: new_token
+ )
+ end
+
+ subject { described_class.new(project, user, params) }
+
+ before do
+ error_tracking_setting.enabled = false
+ end
+
+ it 'returns error' do
+ result = subject.execute
+
+ expect(error_tracking_setting).not_to be_valid
+ expect(result[:message]).to start_with('Api url is blocked')
+ end
+ end
+
+ context 'when list_sentry_projects returns projects' do
+ let(:projects) { [:list, :of, :projects] }
+
+ before do
+ expect(error_tracking_setting)
+ .to receive(:list_sentry_projects).and_return(projects: projects)
+ end
+
+ it 'returns the projects' do
+ result = subject.execute
+
+ expect(result).to eq(status: :success, projects: projects)
+ end
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:unauthorized_user) { create(:user) }
+
+ subject { described_class.new(project, unauthorized_user) }
+
+ it 'returns error' do
+ result = subject.execute
+
+ expect(result).to include(status: :error, message: 'access denied')
+ end
+ end
+
+ context 'with error tracking disabled' do
+ before do
+ expect(project).to receive(:error_tracking_setting).at_least(:once)
+ .and_return(error_tracking_setting)
+ expect(error_tracking_setting)
+ .to receive(:list_sentry_projects).and_return(projects: [])
+
+ error_tracking_setting.enabled = false
+ end
+
+ it 'ignores enabled flag' do
+ result = subject.execute
+
+ expect(result).to include(status: :success, projects: [])
+ end
+ end
+
+ context 'error_tracking_setting is nil' do
+ let(:new_api_host) { 'https://gitlab.com/' }
+ let(:new_token) { 'new-token' }
+ let(:params) { ActionController::Parameters.new(api_host: new_api_host, token: new_token) }
+
+ before do
+ expect(project).to receive(:error_tracking_setting).at_least(:once)
+ .and_return(nil)
+ end
+
+ it 'builds a new error_tracking_setting' do
+ sentry_client = spy(:sentry_client)
+
+ expect(Sentry::Client).to receive(:new)
+ .with(new_api_host + 'api/0/projects/', new_token)
+ .and_return(sentry_client)
+
+ expect(sentry_client).to receive(:list_projects)
+ .and_return([:project1, :project2])
+
+ result = subject.execute
+
+ expect(result[:projects]).to eq([:project1, :project2])
+ expect(project.error_tracking_setting).to be_nil
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb
index 6afae3da80c..cf90230732c 100644
--- a/spec/services/projects/operations/update_service_spec.rb
+++ b/spec/services/projects/operations/update_service_spec.rb
@@ -14,13 +14,19 @@ describe Projects::Operations::UpdateService do
context 'error tracking' do
context 'with existing error tracking setting' do
let(:params) do
- {
+ ActionController::Parameters.new({
error_tracking_setting_attributes: {
enabled: false,
- api_url: 'http://gitlab.com/api/0/projects/org/project',
- token: 'token'
+ api_host: 'http://gitlab.com/',
+ token: 'token',
+ project: {
+ slug: 'project',
+ name: 'Project',
+ organization_slug: 'org',
+ organization_name: 'Org'
+ }
}
- }
+ }).permit!
end
before do
@@ -32,28 +38,60 @@ describe Projects::Operations::UpdateService do
project.reload
expect(project.error_tracking_setting).not_to be_enabled
- expect(project.error_tracking_setting.api_url).to eq('http://gitlab.com/api/0/projects/org/project')
+ expect(project.error_tracking_setting.api_url).to eq(
+ 'http://gitlab.com/api/0/projects/org/project/'
+ )
expect(project.error_tracking_setting.token).to eq('token')
+ expect(project.error_tracking_setting[:project_name]).to eq('Project')
+ expect(project.error_tracking_setting[:organization_name]).to eq('Org')
+ end
+
+ context 'disable error tracking' do
+ before do
+ params[:error_tracking_setting_attributes][:api_host] = ''
+ params[:error_tracking_setting_attributes][:enabled] = false
+ end
+
+ it 'can set api_url to nil' do
+ expect(result[:status]).to eq(:success)
+
+ project.reload
+ expect(project.error_tracking_setting).not_to be_enabled
+ expect(project.error_tracking_setting.api_url).to be_nil
+ expect(project.error_tracking_setting.token).to eq('token')
+ expect(project.error_tracking_setting[:project_name]).to eq('Project')
+ expect(project.error_tracking_setting[:organization_name]).to eq('Org')
+ end
end
end
context 'without an existing error tracking setting' do
let(:params) do
- {
+ ActionController::Parameters.new({
error_tracking_setting_attributes: {
enabled: true,
- api_url: 'http://gitlab.com/api/0/projects/org/project',
- token: 'token'
+ api_host: 'http://gitlab.com/',
+ token: 'token',
+ project: {
+ slug: 'project',
+ name: 'Project',
+ organization_slug: 'org',
+ organization_name: 'Org'
+ }
}
- }
+ }).permit!
end
it 'creates a setting' do
expect(result[:status]).to eq(:success)
expect(project.error_tracking_setting).to be_enabled
- expect(project.error_tracking_setting.api_url).to eq('http://gitlab.com/api/0/projects/org/project')
+ expect(project.error_tracking_setting.api_url).to eq(
+ 'http://gitlab.com/api/0/projects/org/project/'
+ )
expect(project.error_tracking_setting.token).to eq('token')
+ expect(project.error_tracking_setting[:project_name]).to eq('Project')
+ expect(project.error_tracking_setting[:organization_name]).to eq('Org')
end
end