Commit b0843ed9 authored by Peter Leitzen's avatar Peter Leitzen

Instantiate collaborators in publishing services

We can still inject them when we have the need to have a different
serializer and storage client.
parent 52a32a0f
......@@ -2,26 +2,44 @@
module StatusPage
class PublishBaseService
def initialize(project:, storage_client:, serializer:)
include Gitlab::Utils::StrongMemoize
def initialize(project:)
@project = project
@storage_client = storage_client
@serializer = serializer
end
def execute(*args)
return error_feature_not_available unless feature_available?
return error_no_storage_client unless storage_client
publish(*args)
end
private
attr_reader :project, :storage_client, :serializer
attr_reader :project
def publish(*args)
raise NotImplementedError
end
def storage_client
strong_memoize(:strong_memoize) do
project.status_page_setting&.storage_client
end
end
def serializer
strong_memoize(:serializer) do
# According to development/reusing_abstractions.html#abstractions
# serializers can only be used from controllers.
# For the Status Page however, we generate JSON in background jobs.
# rubocop: disable CodeReuse/Serializer
StatusPage::IncidentSerializer.new
# rubocop: enable CodeReuse/Serializer
end
end
def feature_available?
project.status_page_setting&.enabled?
end
......@@ -55,6 +73,10 @@ module StatusPage
error('Feature not available')
end
def error_no_storage_client
error('No storage client available. Is the status page setting activated?')
end
def success(payload = {})
ServiceResponse.success(payload: payload)
end
......
......@@ -4,39 +4,30 @@ require 'spec_helper'
describe StatusPage::PublishDetailsService do
let_it_be(:project, refind: true) { create(:project) }
let(:storage_client) { instance_double(StatusPage::Storage::S3Client) }
let(:serializer) { instance_double(StatusPage::IncidentSerializer) }
let(:issue) { instance_double(Issue) }
let(:user_notes) { double(:user_notes) }
let(:incident_id) { 1 }
let(:key) { StatusPage::Storage.details_path(incident_id) }
let(:content) { { id: incident_id } }
let(:content_json) { content.to_json }
let(:service) do
described_class.new(
project: project, storage_client: storage_client, serializer: serializer
)
end
let(:service) { described_class.new(project: project) }
subject(:result) { service.execute(issue, user_notes) }
describe '#execute' do
context 'when license is available' do
before do
allow(serializer).to receive(:represent_details).with(issue, user_notes)
.and_return(content)
end
before do
allow(serializer).to receive(:represent_details).with(issue, user_notes)
.and_return(content)
end
include_examples 'publish incidents'
include_examples 'publish incidents'
context 'when serialized content is missing id' do
let(:content) { { other_id: incident_id } }
context 'when serialized content is missing id' do
let(:content) { { other_id: incident_id } }
it 'returns an error' do
expect(result).to be_error
expect(result.message).to eq('Missing object key')
end
it 'returns an error' do
expect(result).to be_error
expect(result.message).to eq('Missing object key')
end
end
end
......
......@@ -4,29 +4,20 @@ require 'spec_helper'
describe StatusPage::PublishListService do
let_it_be(:project, refind: true) { create(:project) }
let(:storage_client) { instance_double(StatusPage::Storage::S3Client) }
let(:serializer) { instance_double(StatusPage::IncidentSerializer) }
let(:issues) { [instance_double(Issue)] }
let(:key) { StatusPage::Storage.list_path }
let(:content) { [{ some: :content }] }
let(:content_json) { content.to_json }
let(:service) do
described_class.new(
project: project, storage_client: storage_client, serializer: serializer
)
end
let(:service) { described_class.new(project: project) }
subject(:result) { service.execute(issues) }
describe '#execute' do
context 'when license is available' do
before do
allow(serializer).to receive(:represent_list).with(issues)
.and_return(content)
end
include_examples 'publish incidents'
before do
allow(serializer).to receive(:represent_list).with(issues)
.and_return(content)
end
include_examples 'publish incidents'
end
end
# frozen_string_literal: true
RSpec.shared_examples 'publish incidents' do
let_it_be(:status_page_setting) do
create(:status_page_setting, :enabled, project: project)
let(:status_page_setting_enabled) { true }
let(:storage_client) { instance_double(StatusPage::Storage::S3Client) }
let(:serializer) { instance_double(StatusPage::IncidentSerializer) }
let(:content_json) { content.to_json }
let(:status_page_setting) do
instance_double(StatusPageSetting, enabled?: status_page_setting_enabled,
storage_client: storage_client)
end
before do
stub_licensed_features(status_page: true)
allow(project).to receive(:status_page_setting)
.and_return(status_page_setting)
allow(StatusPage::IncidentSerializer).to receive(:new)
.and_return(serializer)
end
shared_examples 'feature is not available' do
it 'returns feature not available error' do
expect(result).to be_error
expect(result.message).to eq('Feature not available')
end
end
context 'when upload succeeds' do
......@@ -66,27 +73,12 @@ RSpec.shared_examples 'publish incidents' do
end
end
context 'when feature is not available' do
before do
stub_licensed_features(status_page: false)
end
context 'when status page setting is not enabled' do
let(:status_page_setting_enabled) { false }
it_behaves_like 'feature is not available'
end
context 'when status page setting is disabled' do
before do
status_page_setting.update!(enabled: false)
end
it_behaves_like 'feature is not available'
end
context 'when feature flag is disabled' do
before do
stub_feature_flags(status_page: false)
it 'returns feature not available error' do
expect(result).to be_error
expect(result.message).to eq('Feature not available')
end
it_behaves_like 'feature is not available'
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment