diff options
Diffstat (limited to 'spec/models/project_services/datadog_service_spec.rb')
-rw-r--r-- | spec/models/project_services/datadog_service_spec.rb | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/spec/models/project_services/datadog_service_spec.rb b/spec/models/project_services/datadog_service_spec.rb new file mode 100644 index 00000000000..1d9f49e4824 --- /dev/null +++ b/spec/models/project_services/datadog_service_spec.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true +require 'securerandom' + +require 'spec_helper' + +RSpec.describe DatadogService, :model do + let_it_be(:project) { create(:project) } + let_it_be(:pipeline) { create(:ci_pipeline, project: project) } + let_it_be(:build) { create(:ci_build, project: project) } + + let(:active) { true } + let(:dd_site) { 'datadoghq.com' } + let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/v1/input/' } + let(:api_url) { nil } + let(:api_key) { SecureRandom.hex(32) } + let(:dd_env) { 'ci' } + let(:dd_service) { 'awesome-gitlab' } + + let(:expected_hook_url) { default_url + api_key + "?env=#{dd_env}&service=#{dd_service}" } + + let(:instance) do + described_class.new( + active: active, + project: project, + properties: { + datadog_site: dd_site, + api_url: api_url, + api_key: api_key, + datadog_env: dd_env, + datadog_service: dd_service + } + ) + end + + let(:saved_instance) do + instance.save! + instance + end + + let(:pipeline_data) { Gitlab::DataBuilder::Pipeline.build(pipeline) } + let(:build_data) { Gitlab::DataBuilder::Build.build(build) } + + describe 'associations' do + it { is_expected.to belong_to(:project) } + it { is_expected.to have_one(:service_hook) } + end + + describe 'validations' do + subject { instance } + + context 'when service is active' do + let(:active) { true } + + it { is_expected.to validate_presence_of(:api_key) } + it { is_expected.to allow_value(api_key).for(:api_key) } + it { is_expected.not_to allow_value('87dab2403c9d462 87aec4d9214edb1e').for(:api_key) } + it { is_expected.not_to allow_value('................................').for(:api_key) } + + context 'when selecting site' do + let(:dd_site) { 'datadoghq.com' } + let(:api_url) { nil } + + it { is_expected.to validate_presence_of(:datadog_site) } + it { is_expected.not_to validate_presence_of(:api_url) } + it { is_expected.not_to allow_value('datadog hq.com').for(:datadog_site) } + end + + context 'with custom api_url' do + let(:dd_site) { nil } + let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' } + + it { is_expected.not_to validate_presence_of(:datadog_site) } + it { is_expected.to validate_presence_of(:api_url) } + it { is_expected.to allow_value(api_url).for(:api_url) } + it { is_expected.not_to allow_value('example.com').for(:api_url) } + end + + context 'when missing site and api_url' do + let(:dd_site) { nil } + let(:api_url) { nil } + + it { is_expected.not_to be_valid } + it { is_expected.to validate_presence_of(:datadog_site) } + it { is_expected.to validate_presence_of(:api_url) } + end + end + + context 'when service is not active' do + let(:active) { false } + + it { is_expected.to be_valid } + it { is_expected.not_to validate_presence_of(:api_key) } + end + end + + describe '#hook_url' do + subject { instance.hook_url } + + context 'with standard site URL' do + it { is_expected.to eq(expected_hook_url) } + end + + context 'with custom URL' do + let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' } + + it { is_expected.to eq(api_url + api_key + "?env=#{dd_env}&service=#{dd_service}") } + + context 'blank' do + let(:api_url) { '' } + + it { is_expected.to eq(expected_hook_url) } + end + end + + context 'without optional params' do + let(:dd_service) { nil } + let(:dd_env) { nil } + + it { is_expected.to eq(default_url + api_key) } + end + end + + describe '#api_keys_url' do + subject { instance.api_keys_url } + + it { is_expected.to eq("https://app.#{dd_site}/account/settings#api") } + + context 'with unset datadog_site' do + let(:dd_site) { nil } + + it { is_expected.to eq("https://docs.datadoghq.com/account_management/api-app-keys/") } + end + end + + describe '#test' do + context 'when request is succesful' do + subject { saved_instance.test(pipeline_data) } + + before do + stub_request(:post, expected_hook_url).to_return(body: 'OK') + end + it { is_expected.to eq({ success: true, result: 'OK' }) } + end + + context 'when request fails' do + subject { saved_instance.test(pipeline_data) } + + before do + stub_request(:post, expected_hook_url).to_return(body: 'CRASH!!!', status: 500) + end + it { is_expected.to eq({ success: false, result: 'CRASH!!!' }) } + end + end + + describe '#execute' do + before do + stub_request(:post, expected_hook_url) + saved_instance.execute(data) + end + + context 'with pipeline data' do + let(:data) { pipeline_data } + let(:expected_headers) do + { WebHookService::GITLAB_EVENT_HEADER => 'Pipeline Hook' } + end + + it { expect(a_request(:post, expected_hook_url).with(headers: expected_headers)).to have_been_made } + end + + context 'with job data' do + let(:data) { build_data } + let(:expected_headers) do + { WebHookService::GITLAB_EVENT_HEADER => 'Job Hook' } + end + + it { expect(a_request(:post, expected_hook_url).with(headers: expected_headers)).to have_been_made } + end + end +end |