258 lines
7.6 KiB
Ruby
258 lines
7.6 KiB
Ruby
# frozen_string_literal: true
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe 'sentry errors requests' do
|
|
include GraphqlHelpers
|
|
let_it_be(:project) { create(:project, :repository) }
|
|
let_it_be(:project_setting) { create(:project_error_tracking_setting, project: project) }
|
|
let_it_be(:current_user) { project.owner }
|
|
|
|
let(:query) do
|
|
graphql_query_for(
|
|
'project',
|
|
{ 'fullPath' => project.full_path },
|
|
query_graphql_field('sentryErrors', {}, fields)
|
|
)
|
|
end
|
|
|
|
describe 'getting a detailed sentry error' do
|
|
let_it_be(:sentry_detailed_error) { build(:detailed_error_tracking_error) }
|
|
let(:sentry_gid) { sentry_detailed_error.to_global_id.to_s }
|
|
|
|
let(:detailed_fields) do
|
|
all_graphql_fields_for('SentryDetailedError'.classify)
|
|
end
|
|
|
|
let(:fields) do
|
|
query_graphql_field('detailedError', { id: sentry_gid }, detailed_fields)
|
|
end
|
|
|
|
let(:error_data) { graphql_data.dig('project', 'sentryErrors', 'detailedError') }
|
|
|
|
it 'returns a successful response', :aggregate_failures, :quarantine do
|
|
post_graphql(query, current_user: current_user)
|
|
|
|
expect(response).to have_gitlab_http_status(:success)
|
|
expect(graphql_errors).to be_nil
|
|
expect(json_response.keys).to include('data')
|
|
end
|
|
|
|
context 'when data is loading via reactive cache' do
|
|
before do
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to return an empty error' do
|
|
expect(error_data).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'reactive cache returns data' do
|
|
before do
|
|
allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:issue_details)
|
|
.and_return(issue: sentry_detailed_error)
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
let(:sentry_error) { sentry_detailed_error }
|
|
let(:error) { error_data }
|
|
|
|
it_behaves_like 'setting sentry error data'
|
|
|
|
it 'is expected to return the frequency correctly' do
|
|
aggregate_failures 'it returns the frequency correctly' do
|
|
expect(error_data['frequency'].count).to eql sentry_detailed_error.frequency.count
|
|
|
|
first_frequency = error_data['frequency'].first
|
|
expect(Time.parse(first_frequency['time'])).to eql Time.at(sentry_detailed_error.frequency[0][0], in: 0)
|
|
expect(first_frequency['count']).to eql sentry_detailed_error.frequency[0][1]
|
|
end
|
|
end
|
|
|
|
context 'user does not have permission' do
|
|
let(:current_user) { create(:user) }
|
|
|
|
it 'is expected to return an empty error' do
|
|
expect(error_data).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'sentry api returns an error' do
|
|
before do
|
|
expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:issue_details)
|
|
.and_return(error: 'error message')
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to handle the error and return nil' do
|
|
expect(error_data).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'getting an errors list' do
|
|
let_it_be(:sentry_error) { build(:error_tracking_error) }
|
|
let_it_be(:pagination) do
|
|
{
|
|
'next' => { 'cursor' => '2222' },
|
|
'previous' => { 'cursor' => '1111' }
|
|
}
|
|
end
|
|
|
|
let(:fields) do
|
|
<<~QUERY
|
|
errors {
|
|
nodes {
|
|
#{all_graphql_fields_for('SentryError'.classify)}
|
|
}
|
|
pageInfo {
|
|
hasNextPage
|
|
hasPreviousPage
|
|
startCursor
|
|
endCursor
|
|
}
|
|
}
|
|
QUERY
|
|
end
|
|
|
|
let(:error_data) { graphql_data.dig('project', 'sentryErrors', 'errors', 'nodes') }
|
|
let(:pagination_data) { graphql_data.dig('project', 'sentryErrors', 'errors', 'pageInfo') }
|
|
|
|
it_behaves_like 'a working graphql query' do
|
|
before do
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
end
|
|
|
|
context 'when data is loading via reactive cache' do
|
|
before do
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to return nil' do
|
|
expect(error_data).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'reactive cache returns data' do
|
|
before do
|
|
expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:list_sentry_issues)
|
|
.and_return(issues: [sentry_error], pagination: pagination)
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
let(:error) { error_data.first }
|
|
|
|
it 'is expected to return an array of data' do
|
|
expect(error_data).to be_a Array
|
|
expect(error_data.count).to eq 1
|
|
end
|
|
|
|
it_behaves_like 'setting sentry error data'
|
|
|
|
it 'sets the pagination correctly' do
|
|
expect(pagination_data['startCursor']).to eq(pagination['previous']['cursor'])
|
|
expect(pagination_data['endCursor']).to eq(pagination['next']['cursor'])
|
|
end
|
|
|
|
it 'is expected to return the frequency correctly' do
|
|
aggregate_failures 'it returns the frequency correctly' do
|
|
error = error_data.first
|
|
|
|
expect(error['frequency'].count).to eql sentry_error.frequency.count
|
|
|
|
first_frequency = error['frequency'].first
|
|
|
|
expect(Time.parse(first_frequency['time'])).to eql Time.at(sentry_error.frequency[0][0], in: 0)
|
|
expect(first_frequency['count']).to eql sentry_error.frequency[0][1]
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'sentry api itself errors out' do
|
|
before do
|
|
expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:list_sentry_issues)
|
|
.and_return(error: 'error message')
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to handle the error and return nil' do
|
|
expect(error_data).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'getting a stack trace' do
|
|
let_it_be(:sentry_stack_trace) { build(:error_tracking_error_event) }
|
|
let(:sentry_gid) { global_id_of(Gitlab::ErrorTracking::DetailedError.new(id: 1)) }
|
|
|
|
let(:stack_trace_fields) do
|
|
all_graphql_fields_for('SentryErrorStackTrace'.classify)
|
|
end
|
|
|
|
let(:fields) do
|
|
query_graphql_field('errorStackTrace', { id: sentry_gid }, stack_trace_fields)
|
|
end
|
|
|
|
let(:stack_trace_data) { graphql_data.dig('project', 'sentryErrors', 'errorStackTrace') }
|
|
|
|
it_behaves_like 'a working graphql query' do
|
|
before do
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
end
|
|
|
|
context 'when data is loading via reactive cache' do
|
|
before do
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to return an empty error' do
|
|
expect(stack_trace_data).to be_nil
|
|
end
|
|
end
|
|
|
|
context 'reactive cache returns data' do
|
|
before do
|
|
allow_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:issue_latest_event)
|
|
.and_return(latest_event: sentry_stack_trace)
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it_behaves_like 'setting stack trace error'
|
|
|
|
context 'user does not have permission' do
|
|
let(:current_user) { create(:user) }
|
|
|
|
it 'is expected to return an empty error' do
|
|
expect(stack_trace_data).to be_nil
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'sentry api returns an error' do
|
|
before do
|
|
expect_any_instance_of(ErrorTracking::ProjectErrorTrackingSetting)
|
|
.to receive(:issue_latest_event)
|
|
.and_return(error: 'error message')
|
|
|
|
post_graphql(query, current_user: current_user)
|
|
end
|
|
|
|
it 'is expected to handle the error and return nil' do
|
|
expect(stack_trace_data).to be_nil
|
|
end
|
|
end
|
|
end
|
|
end
|