Better settings coupling with spec coverage

This commit is contained in:
2015-02-20 11:51:35 +01:00
parent adeedb2f1b
commit cde551dc7f
6 changed files with 102 additions and 19 deletions
@@ -21,6 +21,7 @@ module Suppliers
find_current_supplier! find_current_supplier!
return unless current_supplier.present? return unless current_supplier.present?
current_employee.enrich_with_settings current_supplier.settings_for(current_employee) current_employee.enrich_with_settings current_supplier.settings_for(current_employee)
raise CanCan::AccessDenied unless current_employee.active?
@current_ability = ::Ability.new( current_employee ) @current_ability = ::Ability.new( current_employee )
end end
+15 -6
View File
@@ -1,13 +1,19 @@
class Employee class Employee
include SimplyStored::Couch include SimplyStored::Couch
include ActiveModel::SerializerSupport include ActiveModel::SerializerSupport
attr_reader :settings
DEFAULT_SETTINGS = { DEFAULT_SETTINGS = {
'manager' => false, 'manager' => false,
'active' => true, 'active' => true,
'color' => '#3a87ad' 'color' => '#3a87ad'
} }
attr_accessor *DEFAULT_SETTINGS.keys DEFAULT_SETTINGS.each do |attribute, default_value|
attr_reader :settings define_method(attribute) { settings.public_send attribute }
define_method("#{attribute}=") { |value| settings.set attribute, value }
if default_value == true or default_value == false # boolean
define_method(:"#{attribute}?"){ public_send attribute }
end
end
view :by_confirmation_token, key: :confirmation_token # devise confirmable view :by_confirmation_token, key: :confirmation_token # devise confirmable
devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable, :confirmable devise :database_authenticatable, :recoverable, :rememberable, :trackable, :registerable, :confirmable
@@ -35,10 +41,13 @@ class Employee
def enrich_with_settings(settings) def enrich_with_settings(settings)
@settings = settings @settings = settings
settings.settings.each do |attribute, value| end
public_send "#{attribute}=", value alias_method :settings=, :enrich_with_settings
end
settings alias_method :orig_save, :save
def save(*args)
settings.persist!
orig_save(*args)
end end
def settings def settings
+9 -1
View File
@@ -45,7 +45,7 @@ class Supplier
alias_method :non_enriced_employees, :employees alias_method :non_enriced_employees, :employees
def employees def employees
non_enriced_employees.tap { |es| es.each{ |e| e.enrich_with_settings(settings_for(e) ) }} @cached_enriched_employees ||= non_enriced_employees.tap { |es| es.each{ |e| e.enrich_with_settings(settings_for(e) ) }}
end end
after_create :add_section_on_create after_create :add_section_on_create
@@ -94,6 +94,14 @@ class Supplier
@active_lists @active_lists
end end
before_method :reload do
@employees = nil
@cached_enriched_employees = nil
@employee_settings = nil
@active_lists = nil
@active_orders = nil
end
# Return the currently active tables for the supplier # Return the currently active tables for the supplier
def active_tables(options = {}) def active_tables(options = {})
+9 -12
View File
@@ -6,13 +6,13 @@ class SupplierEmployeesSettings
@employee_ids = supplier.employee_ids || [] @employee_ids = supplier.employee_ids || []
end end
def for_employee(employee_id) def for_employee(employee)
employee_id = employee_id.id if employee_id.is_a?(Employee) if employee_ids.include? employee.id
if employee_ids.include? employee_id settings = SupplierEmployeeSettings.new(self, employee, dictionary[employee.id])
SupplierEmployeeSettings.new(self, employee_id, dictionary[employee_id])
else else
SupplierEmployeeSettings::NullObject.new settings = SupplierEmployeeSettings::NullObject.new
end end
employee.settings = settings
end end
def [](val) def [](val)
@@ -48,7 +48,7 @@ class SupplierEmployeesSettings
class SupplierEmployeeSettings class SupplierEmployeeSettings
delegate :as_json, :to_json, to: :settings delegate :as_json, :to_json, to: :settings
attr_reader :id, :settings, :all_employees_settings attr_reader :employee, :settings, :all_employees_settings
class NullObject < ::NullObject class NullObject < ::NullObject
::Employee::DEFAULT_SETTINGS.each do |attribute, value| ::Employee::DEFAULT_SETTINGS.each do |attribute, value|
if value == true or value == false if value == true or value == false
@@ -58,9 +58,9 @@ class SupplierEmployeesSettings
end end
end end
def initialize(all_employees_settings, employee_id, settings = {}) def initialize(all_employees_settings, employee, settings = {})
@all_employees_settings = all_employees_settings @all_employees_settings = all_employees_settings
@id = employee_id @employee = employee
@settings = Employee.default_settings.merge(settings || {}) @settings = Employee.default_settings.merge(settings || {})
end end
@@ -70,10 +70,7 @@ class SupplierEmployeesSettings
def set(attribute, value, persist: false) def set(attribute, value, persist: false)
settings[attribute] = value settings[attribute] = value
all_employees_settings[id][attribute] = value all_employees_settings[employee.id][attribute] = value
if employee = all_employees_settings.supplier.employees.find{|e| e.id == id}
employee.public_send("#{attribute}=", value)
end
persist! if persist persist! if persist
self self
end end
+19
View File
@@ -3,3 +3,22 @@ class NilClass
false false
end end
end end
module MethodPrependAndAppend
def before_method(m, &blk)
alias_method :"#{m}_before_extending", m
define_method m do
instance_eval(&blk)
send :"#{m}_before_extending"
end
end
def after_method(m, &blk)
alias_method :"#{m}_before_extending", m
define_method m do
result = send :"#{m}_before_extending"
instance_eval(result, &blk)
end
end
end
Class.send :include, MethodPrependAndAppend
+49
View File
@@ -13,4 +13,53 @@ describe Employee do
end end
end end
end end
describe 'settings' do
let(:supplier){ build :supplier }
let(:employee){ create :employee}
before do
supplier.add_employee employee
employee.enrich_with_settings supplier.settings_for(employee)
end
it 'responds to defaults' do
employee.manager?.should be false
employee.active?.should be true
employee.color.should == '#3a87ad'
end
it 'Sets the values non persisted on the supplier' do
employee.manager = true
supplier.employee_settings_storage[employee.id]['manager'].should be true
supplier.reload
supplier.employee_settings_storage.should_not be_present
end
it 'persists settings of the supplier on save' do
employee.manager = true
employee.save
supplier.reload
supplier.employee_settings_storage[employee.id]['manager'].should be true
end
it 'does not non existant suppliers on save' do
employee.manager = true
->{ employee.save }.should_not change{ Supplier.count }
end
it 'sets attributes on the employee if fetched through the supplier' do
settings = supplier.settings_for employee
settings.is_manager!
employee.manager?.should be true
end
it 'Implements settings on employees' do
supplier.update employee_settings_storage: {employee.id => { 'manager' => true }}
supplier.reload
# Without the acessor employees on the supplier, the employee and therefore its settings are not linked to the supplier
linked_employee = supplier.employees.find{|e| e.id == employee.id }
linked_employee.should be_manager
end
end
end end