# frozen_string_literal: true require 'spec_helper' RSpec.describe Gitlab::AlertManagement::Payload::ManagedPrometheus do let_it_be(:project) { create(:project) } let(:raw_payload) { {} } let(:parsed_payload) { described_class.new(project: project, payload: raw_payload) } it_behaves_like 'subclass has expected api' shared_context 'with gitlab alert' do let_it_be(:gitlab_alert) { create(:prometheus_alert, project: project) } let(:metric_id) { gitlab_alert.prometheus_metric_id.to_s } let(:alert_id) { gitlab_alert.id.to_s } end describe '#metric_id' do subject { parsed_payload.metric_id } it { is_expected.to be_nil } context 'with gitlab_alert_id' do let(:raw_payload) { { 'labels' => { 'gitlab_alert_id' => '12' } } } it { is_expected.to eq(12) } end end describe '#gitlab_prometheus_alert_id' do subject { parsed_payload.gitlab_prometheus_alert_id } it { is_expected.to be_nil } context 'with gitlab_alert_id' do let(:raw_payload) { { 'labels' => { 'gitlab_prometheus_alert_id' => '12' } } } it { is_expected.to eq(12) } end end describe '#gitlab_alert' do subject { parsed_payload.gitlab_alert } context 'without alert info in payload' do it { is_expected.to be_nil } end context 'with metric id in payload' do let(:raw_payload) { { 'labels' => { 'gitlab_alert_id' => metric_id } } } let(:metric_id) { '-1' } context 'without matching alert' do it { is_expected.to be_nil } end context 'with matching alert' do include_context 'with gitlab alert' it { is_expected.to eq(gitlab_alert) } context 'when unclear which alert applies' do # With multiple alerts for different environments, # we can't be sure which prometheus alert the payload # belongs to let_it_be(:another_alert) do create(:prometheus_alert, prometheus_metric: gitlab_alert.prometheus_metric, project: project) end it { is_expected.to be_nil } end end end context 'with alert id' do # gitlab_prometheus_alert_id is a stronger identifier, # but was added after gitlab_alert_id; we won't # see it without gitlab_alert_id also present let(:raw_payload) do { 'labels' => { 'gitlab_alert_id' => metric_id, 'gitlab_prometheus_alert_id' => alert_id } } end context 'without matching alert' do let(:alert_id) { '-1' } let(:metric_id) { '-1' } it { is_expected.to be_nil } end context 'with matching alerts' do include_context 'with gitlab alert' it { is_expected.to eq(gitlab_alert) } end end end describe '#full_query' do subject { parsed_payload.full_query } it { is_expected.to be_nil } context 'with gitlab alert' do include_context 'with gitlab alert' let(:raw_payload) { { 'labels' => { 'gitlab_alert_id' => metric_id } } } it { is_expected.to eq(gitlab_alert.full_query) } end context 'with sufficient fallback info' do let(:raw_payload) { { 'generatorURL' => 'http://localhost:9090/graph?g0.expr=vector%281%29' } } it { is_expected.to eq('vector(1)') } end end describe '#environment' do subject { parsed_payload.environment } context 'with gitlab alert' do include_context 'with gitlab alert' let(:raw_payload) { { 'labels' => { 'gitlab_alert_id' => metric_id } } } it { is_expected.to eq(gitlab_alert.environment) } end context 'with sufficient fallback info' do let_it_be(:environment) { create(:environment, project: project, name: 'production') } let(:raw_payload) do { 'labels' => { 'gitlab_alert_id' => '-1', 'gitlab_environment_name' => 'production' } } end it { is_expected.to eq(environment) } end end describe '#metrics_dashboard_url' do subject { parsed_payload.metrics_dashboard_url } context 'without alert' do it { is_expected.to be_nil } end context 'with gitlab alert' do include_context 'gitlab-managed prometheus alert attributes' do let(:raw_payload) { payload } end it { is_expected.to eq(dashboard_url_for_alert) } end end end