gitlab-org--gitlab-foss/spec/models/alert_management/http_integration_spec.rb

235 lines
6.3 KiB
Ruby

# frozen_string_literal: true
require 'spec_helper'
RSpec.describe AlertManagement::HttpIntegration do
include ::Gitlab::Routing.url_helpers
let_it_be(:project) { create(:project) }
subject(:integration) { build(:alert_management_http_integration) }
describe 'associations' do
it { is_expected.to belong_to(:project) }
end
describe 'default values' do
it { expect(described_class.new.endpoint_identifier).to be_present }
it { expect(described_class.new(endpoint_identifier: 'test').endpoint_identifier).to eq('test') }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
context 'when active' do
# Using `create` instead of `build` the integration so `token` is set.
# Uniqueness spec saves integration with `validate: false` otherwise.
subject { create(:alert_management_http_integration, :legacy) }
it { is_expected.to validate_uniqueness_of(:endpoint_identifier).scoped_to(:project_id, :active) }
end
context 'when inactive' do
subject { create(:alert_management_http_integration, :legacy, :inactive) }
it { is_expected.not_to validate_uniqueness_of(:endpoint_identifier).scoped_to(:project_id, :active) }
end
context 'payload_attribute_mapping' do
subject { build(:alert_management_http_integration, payload_attribute_mapping: attribute_mapping) }
context 'with valid JSON schema' do
let(:attribute_mapping) do
{
title: { path: %w(a b c), type: 'string', label: 'Title' },
description: { path: %w(a), type: 'string' }
}
end
it { is_expected.to be_valid }
end
context 'with invalid JSON schema' do
shared_examples 'is invalid record' do
it do
expect(subject).to be_invalid
expect(subject.errors.messages[:payload_attribute_mapping]).to eq(['must be a valid json schema'])
end
end
context 'when property is not an object' do
let(:attribute_mapping) do
{ title: 'That is not a valid schema' }
end
it_behaves_like 'is invalid record'
end
context 'when property missing required attributes' do
let(:attribute_mapping) do
{ title: { type: 'string' } }
end
it_behaves_like 'is invalid record'
end
context 'when property has extra attributes' do
let(:attribute_mapping) do
{ title: { path: %w(a b c), type: 'string', extra: 'property' } }
end
it_behaves_like 'is invalid record'
end
end
end
end
describe 'before validation' do
describe '#ensure_payload_example_not_nil' do
subject(:integration) { build(:alert_management_http_integration, payload_example: payload_example) }
context 'when the payload_example is nil' do
let(:payload_example) { nil }
it 'sets the payload_example to empty JSON' do
integration.valid?
expect(integration.payload_example).to eq({})
end
end
context 'when the payload_example is not nil' do
let(:payload_example) { { 'key' => 'value' } }
it 'sets the payload_example to specified value' do
integration.valid?
expect(integration.payload_example).to eq(payload_example)
end
end
end
end
describe '#token' do
subject { integration.token }
shared_context 'assign token' do |token|
let!(:previous_token) { integration.token }
before do
integration.token = token
integration.valid?
end
end
shared_examples 'valid token' do
it { is_expected.to match(/\A\h{32}\z/) }
end
context 'when unsaved' do
context 'when assigned' do
include_context 'assign token', 'random_token'
it_behaves_like 'valid token'
it { is_expected.not_to eq('random_token') }
end
end
context 'when persisted' do
before do
integration.save!
integration.reload
end
it_behaves_like 'valid token'
context 'when resetting' do
include_context 'assign token', ''
it_behaves_like 'valid token'
it { is_expected.not_to eq(previous_token) }
end
context 'when reassigning' do
include_context 'assign token', 'random_token'
it_behaves_like 'valid token'
it { is_expected.to eq(previous_token) }
end
end
end
describe '#endpoint_identifier' do
subject { integration.endpoint_identifier }
context 'when defined on initialize' do
let(:integration) { described_class.new }
it { is_expected.to match(/\A\h{16}\z/) }
end
context 'when included in initialization args' do
let(:integration) { described_class.new(endpoint_identifier: 'legacy') }
it { is_expected.to eq('legacy') }
end
context 'when reassigning' do
let(:integration) { create(:alert_management_http_integration) }
let!(:starting_identifier) { subject }
it 'does not allow reassignment' do
integration.endpoint_identifier = 'newValidId'
integration.save!
expect(integration.reload.endpoint_identifier).to eq(starting_identifier)
end
end
end
describe '#url' do
subject { integration.url }
it do
is_expected.to eq(
project_alert_http_integration_url(
integration.project,
'datadog',
integration.endpoint_identifier,
format: :json
)
)
end
context 'when name is not defined' do
let(:integration) { described_class.new(project: project) }
it do
is_expected.to eq(
project_alert_http_integration_url(
integration.project,
'http-endpoint',
integration.endpoint_identifier,
format: :json
)
)
end
end
context 'for a legacy integration' do
let(:integration) { build(:alert_management_http_integration, :legacy) }
it do
is_expected.to eq(
project_alerts_notify_url(
integration.project,
format: :json
)
)
end
end
end
end