Commit 0010c6b0 authored by Sean McGivern's avatar Sean McGivern

Merge branch...

Merge branch '342835-move-web-hooks-logic-from-featureflag-model-to-a-new-hookservice' into 'master'

Move web hooks logic from FeatureFlag model to a new HookService

See merge request gitlab-org/gitlab!72143
parents 60f706df 865236d4
...@@ -98,13 +98,6 @@ module Operations ...@@ -98,13 +98,6 @@ module Operations
Ability.issues_readable_by_user(issues, current_user) Ability.issues_readable_by_user(issues, current_user)
end end
def execute_hooks(current_user)
run_after_commit do
feature_flag_data = Gitlab::DataBuilder::FeatureFlag.build(self, current_user)
project.execute_hooks(feature_flag_data, :feature_flag_hooks)
end
end
def hook_attrs def hook_attrs
{ {
id: id, id: id,
......
...@@ -7,6 +7,8 @@ module FeatureFlags ...@@ -7,6 +7,8 @@ module FeatureFlags
AUDITABLE_ATTRIBUTES = %w(name description active).freeze AUDITABLE_ATTRIBUTES = %w(name description active).freeze
def success(**args) def success(**args)
audit_event = args.fetch(:audit_event) { audit_event(args[:feature_flag]) }
save_audit_event(audit_event)
sync_to_jira(args[:feature_flag]) sync_to_jira(args[:feature_flag])
super super
end end
...@@ -66,5 +68,11 @@ module FeatureFlags ...@@ -66,5 +68,11 @@ module FeatureFlags
feature_flag_by_name.scopes.find_by_environment_scope(params[:environment_scope]) feature_flag_by_name.scopes.find_by_environment_scope(params[:environment_scope])
end end
end end
private
def audit_message(feature_flag)
raise NotImplementedError, "This method should be overriden by subclasses"
end
end end
end end
...@@ -10,8 +10,6 @@ module FeatureFlags ...@@ -10,8 +10,6 @@ module FeatureFlags
feature_flag = project.operations_feature_flags.new(params) feature_flag = project.operations_feature_flags.new(params)
if feature_flag.save if feature_flag.save
save_audit_event(audit_event(feature_flag))
success(feature_flag: feature_flag) success(feature_flag: feature_flag)
else else
error(feature_flag.errors.full_messages, 400) error(feature_flag.errors.full_messages, 400)
......
...@@ -13,8 +13,6 @@ module FeatureFlags ...@@ -13,8 +13,6 @@ module FeatureFlags
ApplicationRecord.transaction do ApplicationRecord.transaction do
if feature_flag.destroy if feature_flag.destroy
save_audit_event(audit_event(feature_flag))
success(feature_flag: feature_flag) success(feature_flag: feature_flag)
else else
error(feature_flag.errors.full_messages) error(feature_flag.errors.full_messages)
......
# frozen_string_literal: true
module FeatureFlags
class HookService
HOOK_NAME = :feature_flag_hooks
def initialize(feature_flag, current_user)
@feature_flag = feature_flag
@current_user = current_user
end
def execute
project.execute_hooks(hook_data, HOOK_NAME)
end
private
attr_reader :feature_flag, :current_user
def project
@project ||= feature_flag.project
end
def hook_data
Gitlab::DataBuilder::FeatureFlag.build(feature_flag, current_user)
end
end
end
...@@ -7,6 +7,11 @@ module FeatureFlags ...@@ -7,6 +7,11 @@ module FeatureFlags
'parameters' => 'parameters' 'parameters' => 'parameters'
}.freeze }.freeze
def success(**args)
execute_hooks_after_commit(args[:feature_flag])
super
end
def execute(feature_flag) def execute(feature_flag)
return error('Access Denied', 403) unless can_update?(feature_flag) return error('Access Denied', 403) unless can_update?(feature_flag)
return error('Not Found', 404) unless valid_user_list_ids?(feature_flag, user_list_ids(params)) return error('Not Found', 404) unless valid_user_list_ids?(feature_flag, user_list_ids(params))
...@@ -20,16 +25,11 @@ module FeatureFlags ...@@ -20,16 +25,11 @@ module FeatureFlags
end end
end end
# We generate the audit event before the feature flag is saved as #changed_strategies_messages depends on the strategies' states before save
audit_event = audit_event(feature_flag) audit_event = audit_event(feature_flag)
if feature_flag.active_changed?
feature_flag.execute_hooks(current_user)
end
if feature_flag.save if feature_flag.save
save_audit_event(audit_event) success(feature_flag: feature_flag, audit_event: audit_event)
success(feature_flag: feature_flag)
else else
error(feature_flag.errors.full_messages, :bad_request) error(feature_flag.errors.full_messages, :bad_request)
end end
...@@ -38,6 +38,16 @@ module FeatureFlags ...@@ -38,6 +38,16 @@ module FeatureFlags
private private
def execute_hooks_after_commit(feature_flag)
return unless feature_flag.active_previously_changed?
# The `current_user` method (defined in `BaseService`) is not available within the `run_after_commit` block
user = current_user
feature_flag.run_after_commit do
HookService.new(feature_flag, user).execute
end
end
def audit_message(feature_flag) def audit_message(feature_flag)
changes = changed_attributes_messages(feature_flag) changes = changed_attributes_messages(feature_flag)
changes += changed_strategies_messages(feature_flag) changes += changed_strategies_messages(feature_flag)
......
...@@ -164,26 +164,4 @@ RSpec.describe Operations::FeatureFlag do ...@@ -164,26 +164,4 @@ RSpec.describe Operations::FeatureFlag do
expect(subject.hook_attrs).to eq(hook_attrs) expect(subject.hook_attrs).to eq(hook_attrs)
end end
end end
describe "#execute_hooks" do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:feature_flag) { create(:operations_feature_flag, project: project) }
it 'does not execute the hook when feature_flag event is disabled' do
create(:project_hook, project: project, feature_flag_events: false)
expect(WebHookWorker).not_to receive(:perform_async)
feature_flag.execute_hooks(user)
feature_flag.touch
end
it 'executes hook when feature_flag event is enabled' do
hook = create(:project_hook, project: project, feature_flag_events: true)
expect(WebHookWorker).to receive(:perform_async).with(hook.id, an_instance_of(Hash), 'feature_flag_hooks')
feature_flag.execute_hooks(user)
feature_flag.touch
end
end
end end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe FeatureFlags::HookService do
describe '#execute_hooks' do
let_it_be(:namespace) { create(:namespace) }
let_it_be(:project) { create(:project, :repository, namespace: namespace) }
let_it_be(:feature_flag) { create(:operations_feature_flag, project: project) }
let_it_be(:user) { namespace.owner }
let!(:hook) { create(:project_hook, project: project) }
let(:hook_data) { double }
subject(:service) { described_class.new(feature_flag, user) }
describe 'HOOK_NAME' do
specify { expect(described_class::HOOK_NAME).to eq(:feature_flag_hooks) }
end
before do
allow(Gitlab::DataBuilder::FeatureFlag).to receive(:build).with(feature_flag, user).once.and_return(hook_data)
end
it 'calls feature_flag.project.execute_hooks' do
expect(feature_flag.project).to receive(:execute_hooks).with(hook_data, described_class::HOOK_NAME)
service.execute
end
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