Skip to content

Commit

Permalink
Merge 20f57c4 into d5b4695
Browse files Browse the repository at this point in the history
  • Loading branch information
DmitryTsepelev committed Nov 14, 2018
2 parents d5b4695 + 20f57c4 commit 089ac9b
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 47 deletions.
14 changes: 1 addition & 13 deletions lib/logux/action_caller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'logux/model/insecure_update_subscriber'

module Logux
class ActionCaller
attr_reader :action, :meta
Expand All @@ -14,7 +12,7 @@ def initialize(action:, meta:)
end

def call!
detect_insecure_updates do
Logux::Model::UpdatesDeprecator.watch(level: :error) do
logger.info(
"Searching action for Logux action: #{action}, meta: #{meta}"
)
Expand All @@ -40,15 +38,5 @@ def class_finder
def action_controller
class_finder.find_action_class.new(action: action, meta: meta)
end

def detect_insecure_updates
ActiveSupport::Notifications.subscribe(
'logux.insecure_update',
Logux::Model::InsecureUpdateSubscriber.new
)
yield
ensure
ActiveSupport::Notifications.unsubscribe('logux.insecure_update')
end
end
end
7 changes: 2 additions & 5 deletions lib/logux/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative 'model/updater'
require_relative 'model/proxy'
require_relative 'model/dsl'
require_relative 'model/updates_deprecator'

module Logux
module Model
Expand All @@ -29,12 +30,8 @@ def touch_logux_id_for_changes
updater = Updater.new(model: self, attributes: attributes)
self.logux_fields_updated_at = updater.updated_attributes

trigger_insecure_update_notification
end

def trigger_insecure_update_notification
ActiveSupport::Notifications.instrument(
'logux.insecure_update',
Logux::Model::UpdatesDeprecator::EVENT,
model_class: self.class,
changed: changed
)
Expand Down
29 changes: 0 additions & 29 deletions lib/logux/model/insecure_update_subscriber.rb

This file was deleted.

52 changes: 52 additions & 0 deletions lib/logux/model/updates_deprecator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# frozen_string_literal: true

module Logux
module Model
class UpdatesDeprecator
EVENT = 'logux.insecure_update'

class << self
def watch(args = {}, &block)
new(args).watch(&block)
end
end

def initialize(level: :warn)
@level = level
end

def watch(&block)
callback = lambda(&method(:handle_insecure_update))
ActiveSupport::Notifications.subscribed(callback, EVENT, &block)
end

private

# rubocop:disable Naming/UncommunicativeMethodParamName
def handle_insecure_update(_, _, _, _, args)
attributes = args[:changed].map(&:to_sym) - [:logux_fields_updated_at]
insecure_attributes =
attributes & args[:model_class].logux_crdt_mapped_attributes
return if insecure_attributes.empty?

notify_about_insecure_update(insecure_attributes)
end
# rubocop:enable Naming/UncommunicativeMethodParamName

def notify_about_insecure_update(insecure_attributes)
pluralized_attributes = 'attribute'.pluralize(insecure_attributes.count)

message = <<~TEXT
Logux tracked #{pluralized_attributes} (#{insecure_attributes.join(', ')}) should be updated using model.logux.update(...)
TEXT

case @level
when :warn
ActiveSupport::Deprecation.warn(message)
when :error
raise InsecureUpdateError, message
end
end
end
end
end
43 changes: 43 additions & 0 deletions spec/logux/model/updates_deprecator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require 'spec_helper'

describe Logux::Model::UpdatesDeprecator do
let(:post) { create(:post) }

context 'with error level' do
it 'raises error when insecure update is detected' do
expect do
described_class.watch(level: :error) do
post.update_attributes(title: 'new title')
end
end.to raise_error(Logux::Model::InsecureUpdateError)
end

it 'does not raise error when update is secure' do
expect do
described_class.watch(level: :error) do
post.update_attributes(updated_at: Time.now)
end
end.not_to raise_error(Logux::Model::InsecureUpdateError)
end
end

context 'with warn level' do
it 'outputs deprecation warning when update is detected' do
expect do
described_class.watch(level: :warn) do
post.update_attributes(title: 'new title')
end
end.to output(/DEPRECATION WARNING/).to_stderr
end

it 'uses warn level by default' do
expect do
described_class.watch do
post.update_attributes(title: 'new title')
end
end.to output(/DEPRECATION WARNING/).to_stderr
end
end
end

0 comments on commit 089ac9b

Please sign in to comment.