Merge branch 'develop' of git.znuny.com:zammad/zammad into develop
This commit is contained in:
commit
97eca99501
9 changed files with 423 additions and 252 deletions
|
@ -61,6 +61,9 @@ module HasGroups
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def group_access?(group_id, access)
|
def group_access?(group_id, access)
|
||||||
|
return false if !active?
|
||||||
|
return false if !groups_access_permission?
|
||||||
|
|
||||||
group_id = self.class.ensure_group_id_parameter(group_id)
|
group_id = self.class.ensure_group_id_parameter(group_id)
|
||||||
access = self.class.ensure_group_access_list_parameter(access)
|
access = self.class.ensure_group_access_list_parameter(access)
|
||||||
|
|
||||||
|
@ -92,8 +95,10 @@ module HasGroups
|
||||||
#
|
#
|
||||||
# @return [Array<Integer>] Group IDs the instance has the given access(es) to.
|
# @return [Array<Integer>] Group IDs the instance has the given access(es) to.
|
||||||
def group_ids_access(access)
|
def group_ids_access(access)
|
||||||
access = self.class.ensure_group_access_list_parameter(access)
|
return [] if !active?
|
||||||
|
return [] if !groups_access_permission?
|
||||||
|
|
||||||
|
access = self.class.ensure_group_access_list_parameter(access)
|
||||||
foreign_key = group_through.foreign_key
|
foreign_key = group_through.foreign_key
|
||||||
klass = group_through.klass
|
klass = group_through.klass
|
||||||
|
|
||||||
|
@ -124,6 +129,8 @@ module HasGroups
|
||||||
#
|
#
|
||||||
# @return [Array<Group>] Groups the instance has the given access(es) to.
|
# @return [Array<Group>] Groups the instance has the given access(es) to.
|
||||||
def groups_access(access)
|
def groups_access(access)
|
||||||
|
return [] if !active?
|
||||||
|
return [] if !groups_access_permission?
|
||||||
group_ids = group_ids_access(access)
|
group_ids = group_ids_access(access)
|
||||||
Group.where(id: group_ids)
|
Group.where(id: group_ids)
|
||||||
end
|
end
|
||||||
|
@ -179,9 +186,24 @@ module HasGroups
|
||||||
@group_through ||= self.class.group_through
|
@group_through ||= self.class.group_through
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Checks if the instance has general permission to Group access.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
# customer_user.groups_access_permission?
|
||||||
|
# #=> false
|
||||||
|
#
|
||||||
|
# @return [Boolean]
|
||||||
|
def groups_access_permission?
|
||||||
|
return true if !respond_to?(:permissions?)
|
||||||
|
permissions?('ticket.agent')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def groups_access_map(key)
|
def groups_access_map(key)
|
||||||
|
return {} if !active?
|
||||||
|
return {} if !groups_access_permission?
|
||||||
|
|
||||||
{}.tap do |hash|
|
{}.tap do |hash|
|
||||||
groups.access.where(active: true).pluck(key, :access).each do |entry|
|
groups.access.where(active: true).pluck(key, :access).each do |entry|
|
||||||
hash[ entry[0] ] ||= []
|
hash[ entry[0] ] ||= []
|
||||||
|
@ -257,20 +279,7 @@ module HasGroups
|
||||||
#
|
#
|
||||||
# @return [Array<Integer>]
|
# @return [Array<Integer>]
|
||||||
def group_access_ids(group_id, access)
|
def group_access_ids(group_id, access)
|
||||||
group_id = ensure_group_id_parameter(group_id)
|
group_access(group_id, access).collect(&:id)
|
||||||
access = ensure_group_access_list_parameter(access)
|
|
||||||
|
|
||||||
# check direct access
|
|
||||||
ids = group_through.klass.includes(name.downcase).where(group_id: group_id, access: access, table_name => { active: true }).pluck(group_through.foreign_key)
|
|
||||||
ids ||= []
|
|
||||||
|
|
||||||
# check indirect access through roles if possible
|
|
||||||
return ids if !respond_to?(:role_access_ids)
|
|
||||||
role_instance_ids = role_access_ids(group_id, access)
|
|
||||||
|
|
||||||
# combines and removes duplicates
|
|
||||||
# and returns them in one statement
|
|
||||||
ids | role_instance_ids
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Lists instances having the given access(es) to the given Group.
|
# Lists instances having the given access(es) to the given Group.
|
||||||
|
@ -289,8 +298,22 @@ module HasGroups
|
||||||
#
|
#
|
||||||
# @return [Array<Class>]
|
# @return [Array<Class>]
|
||||||
def group_access(group_id, access)
|
def group_access(group_id, access)
|
||||||
instance_ids = group_access_ids(group_id, access)
|
group_id = ensure_group_id_parameter(group_id)
|
||||||
where(id: instance_ids)
|
access = ensure_group_access_list_parameter(access)
|
||||||
|
|
||||||
|
# check direct access
|
||||||
|
ids = group_through.klass.includes(name.downcase).where(group_id: group_id, access: access, table_name => { active: true }).pluck(group_through.foreign_key)
|
||||||
|
ids ||= []
|
||||||
|
|
||||||
|
# get instances and check for required permission
|
||||||
|
instances = where(id: ids).select(&:groups_access_permission?)
|
||||||
|
|
||||||
|
# check indirect access through roles if possible
|
||||||
|
return instances if !respond_to?(:role_access)
|
||||||
|
|
||||||
|
# combines and removes duplicates
|
||||||
|
# and returns them in one statement
|
||||||
|
instances | role_access(group_id, access)
|
||||||
end
|
end
|
||||||
|
|
||||||
# The reflection instance containing the association data
|
# The reflection instance containing the association data
|
||||||
|
|
|
@ -18,6 +18,8 @@ module HasRoles
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def role_access?(group_id, access)
|
def role_access?(group_id, access)
|
||||||
|
return false if !groups_access_permission?
|
||||||
|
|
||||||
group_id = self.class.ensure_group_id_parameter(group_id)
|
group_id = self.class.ensure_group_id_parameter(group_id)
|
||||||
access = self.class.ensure_group_access_list_parameter(access)
|
access = self.class.ensure_group_access_list_parameter(access)
|
||||||
|
|
||||||
|
@ -37,6 +39,30 @@ module HasRoles
|
||||||
# methods defined here are going to extend the class, not the instance of it
|
# methods defined here are going to extend the class, not the instance of it
|
||||||
class_methods do
|
class_methods do
|
||||||
|
|
||||||
|
# Lists instances having the given access(es) to the given Group through Roles.
|
||||||
|
#
|
||||||
|
# @example Group ID param
|
||||||
|
# User.role_access(1, 'read')
|
||||||
|
# #=> [1, 3, ...]
|
||||||
|
#
|
||||||
|
# @example Group param
|
||||||
|
# User.role_access(group, 'read')
|
||||||
|
# #=> [1, 3, ...]
|
||||||
|
#
|
||||||
|
# @example Access list
|
||||||
|
# User.role_access(group, ['read', 'create'])
|
||||||
|
# #=> [1, 3, ...]
|
||||||
|
#
|
||||||
|
# @return [Array<Integer>]
|
||||||
|
def role_access(group_id, access)
|
||||||
|
group_id = ensure_group_id_parameter(group_id)
|
||||||
|
access = ensure_group_access_list_parameter(access)
|
||||||
|
|
||||||
|
role_ids = RoleGroup.includes(:role).where(group_id: group_id, access: access, roles: { active: true }).pluck(:role_id)
|
||||||
|
join_table = reflect_on_association(:roles).join_table
|
||||||
|
joins(:roles).where(active: true, join_table => { role_id: role_ids }).distinct.select(&:groups_access_permission?)
|
||||||
|
end
|
||||||
|
|
||||||
# Lists IDs of instances having the given access(es) to the given Group through Roles.
|
# Lists IDs of instances having the given access(es) to the given Group through Roles.
|
||||||
#
|
#
|
||||||
# @example Group ID param
|
# @example Group ID param
|
||||||
|
@ -53,12 +79,7 @@ module HasRoles
|
||||||
#
|
#
|
||||||
# @return [Array<Integer>]
|
# @return [Array<Integer>]
|
||||||
def role_access_ids(group_id, access)
|
def role_access_ids(group_id, access)
|
||||||
group_id = ensure_group_id_parameter(group_id)
|
role_access(group_id, access).collect(&:id)
|
||||||
access = ensure_group_access_list_parameter(access)
|
|
||||||
|
|
||||||
role_ids = RoleGroup.includes(:role).where(group_id: group_id, access: access, roles: { active: true }).pluck(:role_id)
|
|
||||||
join_table = reflect_on_association(:roles).join_table
|
|
||||||
includes(:roles).where(active: true, join_table => { role_id: role_ids }).distinct.pluck(:id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def ensure_group_id_parameter(group_or_id)
|
def ensure_group_id_parameter(group_or_id)
|
||||||
|
|
|
@ -768,7 +768,7 @@ perform changes on ticket
|
||||||
email = User.lookup(id: owner_id).email
|
email = User.lookup(id: owner_id).email
|
||||||
recipients_raw.push(email)
|
recipients_raw.push(email)
|
||||||
elsif recipient == 'ticket_agents'
|
elsif recipient == 'ticket_agents'
|
||||||
User.group_access(group_id, 'full').order(:login).each do |user|
|
User.group_access(group_id, 'full').sort_by(&:login).each do |user|
|
||||||
recipients_raw.push(user.email)
|
recipients_raw.push(user.email)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -47,10 +47,11 @@ class Transaction::Notification
|
||||||
recipients_and_channels = []
|
recipients_and_channels = []
|
||||||
|
|
||||||
# loop through all users
|
# loop through all users
|
||||||
possible_recipients = User.group_access(ticket.group_id, 'full').order(:login)
|
possible_recipients = User.group_access(ticket.group_id, 'full').sort_by(&:login)
|
||||||
if ticket.owner_id == 1
|
if ticket.owner_id == 1
|
||||||
possible_recipients.push ticket.owner
|
possible_recipients.push ticket.owner
|
||||||
end
|
end
|
||||||
|
|
||||||
already_checked_recipient_ids = {}
|
already_checked_recipient_ids = {}
|
||||||
possible_recipients.each { |user|
|
possible_recipients.each { |user|
|
||||||
result = NotificationFactory::Mailer.notification_settings(user, ticket, @item[:type])
|
result = NotificationFactory::Mailer.notification_settings(user, ticket, @item[:type])
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
|
# Requires: let(:group_access_instance) { ... }
|
||||||
|
# Requires: let(:new_group_access_instance) { ... }
|
||||||
RSpec.shared_examples 'HasGroups' do
|
RSpec.shared_examples 'HasGroups' do
|
||||||
|
|
||||||
context 'group' do
|
context 'group' do
|
||||||
|
let(:group_access_instance_inactive) {
|
||||||
let(:factory_name) { described_class.name.downcase.to_sym }
|
group_access_instance.update_attribute(:active, false)
|
||||||
let(:instance) { create(factory_name) }
|
group_access_instance
|
||||||
let(:instance_inactive) { create(factory_name, active: false) }
|
}
|
||||||
let(:group_full) { create(:group) }
|
let(:group_full) { create(:group) }
|
||||||
let(:group_read) { create(:group) }
|
let(:group_read) { create(:group) }
|
||||||
let(:group_inactive) { create(:group, active: false) }
|
let(:group_inactive) { create(:group, active: false) }
|
||||||
|
@ -20,7 +22,7 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'instance responds to group_through_identifier method' do
|
it 'instance responds to group_through_identifier method' do
|
||||||
expect(instance).to respond_to(described_class.group_through_identifier)
|
expect(group_access_instance).to respond_to(described_class.group_through_identifier)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -38,19 +40,19 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
context '#groups' do
|
context '#groups' do
|
||||||
|
|
||||||
it 'responds to groups' do
|
it 'responds to groups' do
|
||||||
expect(instance).to respond_to(:groups)
|
expect(group_access_instance).to respond_to(:groups)
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#groups.access' do
|
context '#groups.access' do
|
||||||
|
|
||||||
it 'responds to groups.access' do
|
it 'responds to groups.access' do
|
||||||
expect(instance.groups).to respond_to(:access)
|
expect(group_access_instance.groups).to respond_to(:access)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'result' do
|
context 'result' do
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
group_inactive.name => 'write',
|
group_inactive.name => 'write',
|
||||||
|
@ -58,23 +60,23 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns all related Groups' do
|
it 'returns all related Groups' do
|
||||||
expect(instance.groups.access.size).to eq(3)
|
expect(group_access_instance.groups.access.size).to eq(3)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds join table attribute(s like) access' do
|
it 'adds join table attribute(s like) access' do
|
||||||
expect(instance.groups.access.first).to respond_to(:access)
|
expect(group_access_instance.groups.access.first).to respond_to(:access)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters for given access parameter' do
|
it 'filters for given access parameter' do
|
||||||
expect(instance.groups.access('read')).to include(group_read)
|
expect(group_access_instance.groups.access('read')).to include(group_read)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'filters for given access list parameter' do
|
it 'filters for given access list parameter' do
|
||||||
expect(instance.groups.access('read', 'write')).to include(group_read, group_inactive)
|
expect(group_access_instance.groups.access('read', 'write')).to include(group_read, group_inactive)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'always includes full access groups' do
|
it 'always includes full access groups' do
|
||||||
expect(instance.groups.access('read')).to include(group_full)
|
expect(group_access_instance.groups.access('read')).to include(group_full)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -82,14 +84,14 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
|
|
||||||
context '#group_access?' do
|
context '#group_access?' do
|
||||||
|
|
||||||
before(:each) do
|
it 'responds to group_access?' do
|
||||||
instance.group_names_access_map = {
|
expect(group_access_instance).to respond_to(:group_access?)
|
||||||
group_read.name => 'read',
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'responds to group_access?' do
|
before(:each) do
|
||||||
expect(instance).to respond_to(:group_access?)
|
group_access_instance.group_names_access_map = {
|
||||||
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Group ID parameter' do
|
context 'Group ID parameter' do
|
||||||
|
@ -105,45 +107,61 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'prevents inactive Group' do
|
it 'prevents inactive Group' do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_inactive.name => 'read',
|
group_inactive.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(instance.group_access?(group_inactive.id, 'read')).to be false
|
expect(group_access_instance.group_access?(group_inactive.id, 'read')).to be false
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'prevents inactive instances' do
|
||||||
|
group_access_instance_inactive.group_names_access_map = {
|
||||||
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(group_access_instance_inactive.group_access?(group_read.id, 'read')).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#group_ids_access' do
|
context '#group_ids_access' do
|
||||||
|
|
||||||
|
it 'responds to group_ids_access' do
|
||||||
|
expect(group_access_instance).to respond_to(:group_ids_access)
|
||||||
|
end
|
||||||
|
|
||||||
before(:each) do
|
before(:each) do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'responds to group_ids_access' do
|
|
||||||
expect(instance).to respond_to(:group_ids_access)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'lists only active Group IDs' do
|
it 'lists only active Group IDs' do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
group_inactive.name => 'read',
|
group_inactive.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = instance.group_ids_access('read')
|
result = group_access_instance.group_ids_access('read')
|
||||||
expect(result).not_to include(group_inactive.id)
|
expect(result).not_to include(group_inactive.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "doesn't list for inactive instances" do
|
||||||
|
group_access_instance_inactive.group_names_access_map = {
|
||||||
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(group_access_instance_inactive.group_ids_access('read')).to be_empty
|
||||||
|
end
|
||||||
|
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'lists access Group IDs' do
|
it 'lists access Group IDs' do
|
||||||
result = instance.group_ids_access('read')
|
result = group_access_instance.group_ids_access('read')
|
||||||
expect(result).to include(group_read.id)
|
expect(result).to include(group_read.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't list for no access" do
|
it "doesn't list for no access" do
|
||||||
result = instance.group_ids_access('write')
|
result = group_access_instance.group_ids_access('write')
|
||||||
expect(result).not_to include(group_read.id)
|
expect(result).not_to include(group_read.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -151,12 +169,12 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'lists access Group IDs' do
|
it 'lists access Group IDs' do
|
||||||
result = instance.group_ids_access(%w(read write))
|
result = group_access_instance.group_ids_access(%w(read write))
|
||||||
expect(result).to include(group_read.id)
|
expect(result).to include(group_read.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't list for no access" do
|
it "doesn't list for no access" do
|
||||||
result = instance.group_ids_access(%w(write create))
|
result = group_access_instance.group_ids_access(%w(write create))
|
||||||
expect(result).not_to include(group_read.id)
|
expect(result).not_to include(group_read.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -165,19 +183,19 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
context '#groups_access' do
|
context '#groups_access' do
|
||||||
|
|
||||||
it 'responds to groups_access' do
|
it 'responds to groups_access' do
|
||||||
expect(instance).to respond_to(:groups_access)
|
expect(group_access_instance).to respond_to(:groups_access)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'wraps #group_ids_access' do
|
it 'wraps #group_ids_access' do
|
||||||
expect(instance).to receive(:group_ids_access)
|
expect(group_access_instance).to receive(:group_ids_access)
|
||||||
instance.groups_access('read')
|
group_access_instance.groups_access('read')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns Groups' do
|
it 'returns Groups' do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
result = instance.groups_access('read')
|
result = group_access_instance.groups_access('read')
|
||||||
expect(result).to include(group_read)
|
expect(result).to include(group_read)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -185,14 +203,14 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
context '#group_names_access_map=' do
|
context '#group_names_access_map=' do
|
||||||
|
|
||||||
it 'responds to group_names_access_map=' do
|
it 'responds to group_names_access_map=' do
|
||||||
expect(instance).to respond_to(:group_names_access_map=)
|
expect(group_access_instance).to respond_to(:group_names_access_map=)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Group name => access relation storage' do
|
context 'existing instance' do
|
||||||
|
|
||||||
it 'stores Hash with String values' do
|
it 'stores Hash with String values' do
|
||||||
expect do
|
expect do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
|
@ -201,9 +219,9 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
}.by(2)
|
}.by(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'stores Hash with String values' do
|
it 'stores Hash with Array<String> values' do
|
||||||
expect do
|
expect do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => %w(read write),
|
group_read.name => %w(read write),
|
||||||
}
|
}
|
||||||
|
@ -211,13 +229,13 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
described_class.group_through.klass.count
|
described_class.group_through.klass.count
|
||||||
}.by(3)
|
}.by(3)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'new instance' do
|
context 'new instance' do
|
||||||
let(:new_instance) { build(factory_name) }
|
|
||||||
|
|
||||||
it "doesn't store directly" do
|
it "doesn't store directly" do
|
||||||
expect do
|
expect do
|
||||||
new_instance.group_names_access_map = {
|
new_group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
|
@ -228,24 +246,23 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
|
|
||||||
it 'stores after save' do
|
it 'stores after save' do
|
||||||
expect do
|
expect do
|
||||||
new_instance.group_names_access_map = {
|
new_group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
new_instance.save
|
new_group_access_instance.save
|
||||||
end.to change {
|
end.to change {
|
||||||
described_class.group_through.klass.count
|
described_class.group_through.klass.count
|
||||||
}.by(2)
|
}.by(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context '#group_names_access_map' do
|
context '#group_names_access_map' do
|
||||||
|
|
||||||
it 'responds to group_names_access_map' do
|
it 'responds to group_names_access_map' do
|
||||||
expect(instance).to respond_to(:group_names_access_map)
|
expect(group_access_instance).to respond_to(:group_names_access_map)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns instance Group name => access relations as Hash' do
|
it 'returns instance Group name => access relations as Hash' do
|
||||||
|
@ -254,23 +271,32 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.name => ['read'],
|
group_read.name => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.group_names_access_map = expected
|
group_access_instance.group_names_access_map = expected
|
||||||
|
|
||||||
expect(instance.group_names_access_map).to eq(expected)
|
expect(group_access_instance.group_names_access_map).to eq(expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't map for inactive instances" do
|
||||||
|
group_access_instance_inactive.group_names_access_map = {
|
||||||
|
group_full.name => ['full'],
|
||||||
|
group_read.name => ['read'],
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(group_access_instance_inactive.group_names_access_map).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '#group_ids_access_map=' do
|
context '#group_ids_access_map=' do
|
||||||
|
|
||||||
it 'responds to group_ids_access_map=' do
|
it 'responds to group_ids_access_map=' do
|
||||||
expect(instance).to respond_to(:group_ids_access_map=)
|
expect(group_access_instance).to respond_to(:group_ids_access_map=)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Group ID => access relation storage' do
|
context 'existing instance' do
|
||||||
|
|
||||||
it 'stores Hash with String values' do
|
it 'stores Hash with String values' do
|
||||||
expect do
|
expect do
|
||||||
instance.group_ids_access_map = {
|
group_access_instance.group_ids_access_map = {
|
||||||
group_full.id => 'full',
|
group_full.id => 'full',
|
||||||
group_read.id => 'read',
|
group_read.id => 'read',
|
||||||
}
|
}
|
||||||
|
@ -281,7 +307,7 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
|
|
||||||
it 'stores Hash with String values' do
|
it 'stores Hash with String values' do
|
||||||
expect do
|
expect do
|
||||||
instance.group_ids_access_map = {
|
group_access_instance.group_ids_access_map = {
|
||||||
group_full.id => 'full',
|
group_full.id => 'full',
|
||||||
group_read.id => %w(read write),
|
group_read.id => %w(read write),
|
||||||
}
|
}
|
||||||
|
@ -289,13 +315,13 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
described_class.group_through.klass.count
|
described_class.group_through.klass.count
|
||||||
}.by(3)
|
}.by(3)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'new instance' do
|
context 'new instance' do
|
||||||
let(:new_instance) { build(factory_name) }
|
|
||||||
|
|
||||||
it "doesn't store directly" do
|
it "doesn't store directly" do
|
||||||
expect do
|
expect do
|
||||||
new_instance.group_ids_access_map = {
|
new_group_access_instance.group_ids_access_map = {
|
||||||
group_full.id => 'full',
|
group_full.id => 'full',
|
||||||
group_read.id => 'read',
|
group_read.id => 'read',
|
||||||
}
|
}
|
||||||
|
@ -306,24 +332,23 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
|
|
||||||
it 'stores after save' do
|
it 'stores after save' do
|
||||||
expect do
|
expect do
|
||||||
new_instance.group_ids_access_map = {
|
new_group_access_instance.group_ids_access_map = {
|
||||||
group_full.id => 'full',
|
group_full.id => 'full',
|
||||||
group_read.id => 'read',
|
group_read.id => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
new_instance.save
|
new_group_access_instance.save
|
||||||
end.to change {
|
end.to change {
|
||||||
described_class.group_through.klass.count
|
described_class.group_through.klass.count
|
||||||
}.by(2)
|
}.by(2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
context '#group_ids_access_map' do
|
context '#group_ids_access_map' do
|
||||||
|
|
||||||
it 'responds to group_ids_access_map' do
|
it 'responds to group_ids_access_map' do
|
||||||
expect(instance).to respond_to(:group_ids_access_map)
|
expect(group_access_instance).to respond_to(:group_ids_access_map)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns instance Group ID => access relations as Hash' do
|
it 'returns instance Group ID => access relations as Hash' do
|
||||||
|
@ -332,9 +357,18 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.id => ['read'],
|
group_read.id => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.group_ids_access_map = expected
|
group_access_instance.group_ids_access_map = expected
|
||||||
|
|
||||||
expect(instance.group_ids_access_map).to eq(expected)
|
expect(group_access_instance.group_ids_access_map).to eq(expected)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't map for inactive instances" do
|
||||||
|
group_access_instance_inactive.group_ids_access_map = {
|
||||||
|
group_full.id => ['full'],
|
||||||
|
group_read.id => ['read'],
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(group_access_instance_inactive.group_ids_access_map).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -346,8 +380,8 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.id => ['read'],
|
group_read.id => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.associations_from_param(group_ids: expected)
|
group_access_instance.associations_from_param(group_ids: expected)
|
||||||
expect(instance.group_ids_access_map).to eq(expected)
|
expect(group_access_instance.group_ids_access_map).to eq(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'handles groups parameter as group_names_access_map' do
|
it 'handles groups parameter as group_names_access_map' do
|
||||||
|
@ -356,8 +390,8 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.name => ['read'],
|
group_read.name => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.associations_from_param(groups: expected)
|
group_access_instance.associations_from_param(groups: expected)
|
||||||
expect(instance.group_names_access_map).to eq(expected)
|
expect(group_access_instance.group_names_access_map).to eq(expected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -369,9 +403,9 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.id => ['read'],
|
group_read.id => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.group_ids_access_map = expected
|
group_access_instance.group_ids_access_map = expected
|
||||||
|
|
||||||
result = instance.attributes_with_association_ids
|
result = group_access_instance.attributes_with_association_ids
|
||||||
expect(result['group_ids']).to eq(expected)
|
expect(result['group_ids']).to eq(expected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -384,9 +418,9 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.id => ['read'],
|
group_read.id => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.group_ids_access_map = expected
|
group_access_instance.group_ids_access_map = expected
|
||||||
|
|
||||||
result = instance.attributes_with_association_names
|
result = group_access_instance.attributes_with_association_names
|
||||||
expect(result['group_ids']).to eq(expected)
|
expect(result['group_ids']).to eq(expected)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -396,77 +430,77 @@ RSpec.shared_examples 'HasGroups' do
|
||||||
group_read.name => ['read'],
|
group_read.name => ['read'],
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.group_names_access_map = expected
|
group_access_instance.group_names_access_map = expected
|
||||||
|
|
||||||
result = instance.attributes_with_association_names
|
result = group_access_instance.attributes_with_association_names
|
||||||
expect(result['groups']).to eq(expected)
|
expect(result['groups']).to eq(expected)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context '.group_access_ids' do
|
|
||||||
|
|
||||||
before(:each) do
|
|
||||||
instance.group_names_access_map = {
|
|
||||||
group_read.name => 'read',
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'responds to group_access_ids' do
|
|
||||||
expect(described_class).to respond_to(:group_access_ids)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'lists only active instance IDs' do
|
|
||||||
instance_inactive.group_names_access_map = {
|
|
||||||
group_read.name => 'read',
|
|
||||||
}
|
|
||||||
|
|
||||||
result = described_class.group_access_ids(group_read.id, 'read')
|
|
||||||
expect(result).not_to include(instance_inactive.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'Group ID parameter' do
|
|
||||||
include_examples '.group_access_ids call' do
|
|
||||||
let(:group_parameter) { group_read.id }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'Group parameter' do
|
|
||||||
include_examples '.group_access_ids call' do
|
|
||||||
let(:group_parameter) { group_read.id }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context '.group_access' do
|
context '.group_access' do
|
||||||
|
|
||||||
it 'responds to group_access' do
|
it 'responds to group_access' do
|
||||||
expect(described_class).to respond_to(:group_access)
|
expect(described_class).to respond_to(:group_access)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'wraps .group_access_ids' do
|
before(:each) do
|
||||||
expect(described_class).to receive(:group_access_ids)
|
group_access_instance.group_names_access_map = {
|
||||||
described_class.group_access(group_read, 'read')
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns class instances' do
|
it 'lists only active instances' do
|
||||||
instance.group_names_access_map = {
|
group_access_instance_inactive.group_names_access_map = {
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = described_class.group_access(group_read, 'read')
|
result = described_class.group_access(group_read.id, 'read')
|
||||||
expect(result).to include(instance)
|
expect(result).not_to include(group_access_instance_inactive)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Group ID parameter' do
|
||||||
|
include_examples '.group_access call' do
|
||||||
|
let(:group_parameter) { group_read.id }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Group parameter' do
|
||||||
|
include_examples '.group_access call' do
|
||||||
|
let(:group_parameter) { group_read }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '.group_access_ids' do
|
||||||
|
|
||||||
|
it 'responds to group_access_ids' do
|
||||||
|
expect(described_class).to respond_to(:group_access_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'wraps .group_access' do
|
||||||
|
expect(described_class).to receive(:group_access).and_call_original
|
||||||
|
described_class.group_access_ids(group_read, 'read')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns class instances' do
|
||||||
|
group_access_instance.group_names_access_map = {
|
||||||
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
|
|
||||||
|
result = described_class.group_access_ids(group_read, 'read')
|
||||||
|
expect(result).to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'destroys relations before instance gets destroyed' do
|
it 'destroys relations before instance gets destroyed' do
|
||||||
|
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_full.name => 'full',
|
group_full.name => 'full',
|
||||||
group_read.name => 'read',
|
group_read.name => 'read',
|
||||||
group_inactive.name => 'write',
|
group_inactive.name => 'write',
|
||||||
}
|
}
|
||||||
expect do
|
expect do
|
||||||
instance.destroy
|
group_access_instance.destroy
|
||||||
end.to change {
|
end.to change {
|
||||||
described_class.group_through.klass.count
|
described_class.group_through.klass.count
|
||||||
}.by(-3)
|
}.by(-3)
|
||||||
|
@ -478,46 +512,46 @@ RSpec.shared_examples '#group_access? call' do
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'checks positive' do
|
it 'checks positive' do
|
||||||
expect(instance.group_access?(group_parameter, 'read')).to be true
|
expect(group_access_instance.group_access?(group_parameter, 'read')).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks negative' do
|
it 'checks negative' do
|
||||||
expect(instance.group_access?(group_parameter, 'write')).to be false
|
expect(group_access_instance.group_access?(group_parameter, 'write')).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'checks positive' do
|
it 'checks positive' do
|
||||||
expect(instance.group_access?(group_parameter, %w(read write))).to be true
|
expect(group_access_instance.group_access?(group_parameter, %w(read write))).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks negative' do
|
it 'checks negative' do
|
||||||
expect(instance.group_access?(group_parameter, %w(write create))).to be false
|
expect(group_access_instance.group_access?(group_parameter, %w(write create))).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RSpec.shared_examples '.group_access_ids call' do
|
RSpec.shared_examples '.group_access call' do
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'lists access IDs' do
|
it 'lists access IDs' do
|
||||||
expect(described_class.group_access_ids(group_parameter, 'read')).to include(instance.id)
|
expect(described_class.group_access(group_parameter, 'read')).to include(group_access_instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes non access IDs' do
|
it 'excludes non access IDs' do
|
||||||
expect(described_class.group_access_ids(group_parameter, 'write')).not_to include(instance.id)
|
expect(described_class.group_access(group_parameter, 'write')).not_to include(group_access_instance)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'lists access IDs' do
|
it 'lists access IDs' do
|
||||||
expect(described_class.group_access_ids(group_parameter, %w(read write))).to include(instance.id)
|
expect(described_class.group_access(group_parameter, %w(read write))).to include(group_access_instance)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes non access IDs' do
|
it 'excludes non access IDs' do
|
||||||
expect(described_class.group_access_ids(group_parameter, %w(write create))).not_to include(instance.id)
|
expect(described_class.group_access(group_parameter, %w(write create))).not_to include(group_access_instance)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
79
spec/models/concerns/has_groups_permissions_examples.rb
Normal file
79
spec/models/concerns/has_groups_permissions_examples.rb
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# Requires: let(:group_access_no_permission_instance) { ... }
|
||||||
|
RSpec.shared_examples 'HasGroups and Permissions' do
|
||||||
|
|
||||||
|
context 'group' do
|
||||||
|
|
||||||
|
let(:group_read) { create(:group) }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
group_access_no_permission_instance.group_names_access_map = {
|
||||||
|
group_read.name => 'read',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#group_access?' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.group_access?(group_read, 'read')).to be false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#group_ids_access' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.group_ids_access('read')).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#groups_access' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.groups_access('read')).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#group_names_access_map' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.group_names_access_map).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#group_ids_access_map' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.group_ids_access_map).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#attributes_with_association_ids' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.attributes_with_association_ids['group_ids']).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '#attributes_with_association_names' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
expect(group_access_no_permission_instance.attributes_with_association_names['group_ids']).to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '.group_access' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
result = described_class.group_access(group_read.id, 'read')
|
||||||
|
expect(result).not_to include(group_access_no_permission_instance)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context '.group_access_ids' do
|
||||||
|
|
||||||
|
it 'prevents instances without permissions' do
|
||||||
|
result = described_class.group_access(group_read.id, 'read')
|
||||||
|
expect(result).not_to include(group_access_no_permission_instance.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,10 +1,13 @@
|
||||||
|
# Requires: let(:group_access_instance) { ... }
|
||||||
|
# Requires: let(:new_group_access_instance) { ... }
|
||||||
RSpec.shared_examples 'HasRoles' do
|
RSpec.shared_examples 'HasRoles' do
|
||||||
|
|
||||||
context 'role' do
|
context 'role' do
|
||||||
|
|
||||||
let(:factory_name) { described_class.name.downcase.to_sym }
|
let(:group_access_instance_inactive) {
|
||||||
let(:instance) { create(factory_name) }
|
group_access_instance.update_attribute(:active, false)
|
||||||
let(:instance_inactive) { create(factory_name, active: false) }
|
group_access_instance
|
||||||
|
}
|
||||||
let(:role) { create(:role) }
|
let(:role) { create(:role) }
|
||||||
let(:group_instance) { create(:group) }
|
let(:group_instance) { create(:group) }
|
||||||
let(:group_role) { create(:group) }
|
let(:group_role) { create(:group) }
|
||||||
|
@ -12,16 +15,18 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
|
|
||||||
context '#role_access?' do
|
context '#role_access?' do
|
||||||
|
|
||||||
|
it 'responds to role_access?' do
|
||||||
|
expect(group_access_instance).to respond_to(:role_access?)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'active Role' do
|
||||||
before(:each) do
|
before(:each) do
|
||||||
role.group_names_access_map = {
|
role.group_names_access_map = {
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.roles = [role]
|
group_access_instance.roles.push(role)
|
||||||
end
|
group_access_instance.save
|
||||||
|
|
||||||
it 'responds to role_access?' do
|
|
||||||
expect(instance).to respond_to(:role_access?)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Group ID parameter' do
|
context 'Group ID parameter' do
|
||||||
|
@ -41,7 +46,8 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_inactive.name => 'read',
|
group_inactive.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(instance.group_access?(group_inactive.id, 'read')).to be false
|
expect(group_access_instance.group_access?(group_inactive.id, 'read')).to be false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'prevents inactive Role' do
|
it 'prevents inactive Role' do
|
||||||
|
@ -50,9 +56,10 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.roles = [role_inactive]
|
group_access_instance.roles.push(role_inactive)
|
||||||
|
group_access_instance.save
|
||||||
|
|
||||||
expect(instance.group_access?(group_role.id, 'read')).to be false
|
expect(group_access_instance.group_access?(group_role.id, 'read')).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -63,7 +70,8 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.roles = [role]
|
group_access_instance.roles.push(role)
|
||||||
|
group_access_instance.save
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'responds to role_access_ids' do
|
it 'responds to role_access_ids' do
|
||||||
|
@ -75,19 +83,12 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = described_class.group_access_ids(group_role.id, 'read')
|
group_access_instance_inactive.roles.push(role)
|
||||||
expect(result).not_to include(instance_inactive.id)
|
group_access_instance_inactive.save
|
||||||
end
|
group_access_instance_inactive.save
|
||||||
|
|
||||||
it 'lists only active instance IDs' do
|
|
||||||
role.group_names_access_map = {
|
|
||||||
group_role.name => 'read',
|
|
||||||
}
|
|
||||||
|
|
||||||
instance_inactive.roles = [role]
|
|
||||||
|
|
||||||
result = described_class.role_access_ids(group_role.id, 'read')
|
result = described_class.role_access_ids(group_role.id, 'read')
|
||||||
expect(result).not_to include(instance_inactive.id)
|
expect(result).not_to include(group_access_instance_inactive.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'Group ID parameter' do
|
context 'Group ID parameter' do
|
||||||
|
@ -98,7 +99,7 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
|
|
||||||
context 'Group parameter' do
|
context 'Group parameter' do
|
||||||
include_examples '.role_access_ids call' do
|
include_examples '.role_access_ids call' do
|
||||||
let(:group_parameter) { group_role.id }
|
let(:group_parameter) { group_role }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -110,9 +111,10 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.roles = [role]
|
group_access_instance.roles.push(role)
|
||||||
|
group_access_instance.save
|
||||||
|
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_instance.name => 'read',
|
group_instance.name => 'read',
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -120,13 +122,13 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
context '#group_access?' do
|
context '#group_access?' do
|
||||||
|
|
||||||
it 'falls back to #role_access?' do
|
it 'falls back to #role_access?' do
|
||||||
expect(instance).to receive(:role_access?)
|
expect(group_access_instance).to receive(:role_access?)
|
||||||
instance.group_access?(group_role, 'read')
|
group_access_instance.group_access?(group_role, 'read')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't fall back to #role_access? if not needed" do
|
it "doesn't fall back to #role_access? if not needed" do
|
||||||
expect(instance).not_to receive(:role_access?)
|
expect(group_access_instance).not_to receive(:role_access?)
|
||||||
instance.group_access?(group_instance, 'read')
|
group_access_instance.group_access?(group_instance, 'read')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,9 +139,10 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.roles = [role]
|
group_access_instance.roles.push(role)
|
||||||
|
group_access_instance.save
|
||||||
|
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_instance.name => 'read',
|
group_instance.name => 'read',
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -150,28 +153,28 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
group_inactive.name => 'read',
|
group_inactive.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = instance.group_ids_access('read')
|
result = group_access_instance.group_ids_access('read')
|
||||||
expect(result).not_to include(group_inactive.id)
|
expect(result).not_to include(group_inactive.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'lists access Group IDs' do
|
it 'lists access Group IDs' do
|
||||||
result = instance.group_ids_access('read')
|
result = group_access_instance.group_ids_access('read')
|
||||||
expect(result).to include(group_role.id)
|
expect(result).to include(group_role.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't list for no access" do
|
it "doesn't list for no access" do
|
||||||
result = instance.group_ids_access('write')
|
result = group_access_instance.group_ids_access('write')
|
||||||
expect(result).not_to include(group_role.id)
|
expect(result).not_to include(group_role.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't contain duplicate IDs" do
|
it "doesn't contain duplicate IDs" do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = instance.group_ids_access('read')
|
result = group_access_instance.group_ids_access('read')
|
||||||
expect(result.uniq).to eq(result)
|
expect(result.uniq).to eq(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -179,21 +182,21 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'lists access Group IDs' do
|
it 'lists access Group IDs' do
|
||||||
result = instance.group_ids_access(%w(read write))
|
result = group_access_instance.group_ids_access(%w(read write))
|
||||||
expect(result).to include(group_role.id)
|
expect(result).to include(group_role.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't list for no access" do
|
it "doesn't list for no access" do
|
||||||
result = instance.group_ids_access(%w(write create))
|
result = group_access_instance.group_ids_access(%w(write create))
|
||||||
expect(result).not_to include(group_role.id)
|
expect(result).not_to include(group_role.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't contain duplicate IDs" do
|
it "doesn't contain duplicate IDs" do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
result = instance.group_ids_access(%w(read create))
|
result = group_access_instance.group_ids_access(%w(read create))
|
||||||
expect(result.uniq).to eq(result)
|
expect(result.uniq).to eq(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -203,11 +206,11 @@ RSpec.shared_examples 'HasRoles' do
|
||||||
|
|
||||||
it 'includes the result of .role_access_ids' do
|
it 'includes the result of .role_access_ids' do
|
||||||
result = described_class.group_access_ids(group_role, 'read')
|
result = described_class.group_access_ids(group_role, 'read')
|
||||||
expect(result).to include(instance.id)
|
expect(result).to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't contain duplicate IDs" do
|
it "doesn't contain duplicate IDs" do
|
||||||
instance.group_names_access_map = {
|
group_access_instance.group_names_access_map = {
|
||||||
group_role.name => 'read',
|
group_role.name => 'read',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,22 +226,22 @@ RSpec.shared_examples '#role_access? call' do
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'checks positive' do
|
it 'checks positive' do
|
||||||
expect(instance.role_access?(group_parameter, 'read')).to be true
|
expect(group_access_instance.role_access?(group_parameter, 'read')).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks negative' do
|
it 'checks negative' do
|
||||||
expect(instance.role_access?(group_parameter, 'write')).to be false
|
expect(group_access_instance.role_access?(group_parameter, 'write')).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'checks positive' do
|
it 'checks positive' do
|
||||||
expect(instance.role_access?(group_parameter, %w(read write))).to be true
|
expect(group_access_instance.role_access?(group_parameter, %w(read write))).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'checks negative' do
|
it 'checks negative' do
|
||||||
expect(instance.role_access?(group_parameter, %w(write create))).to be false
|
expect(group_access_instance.role_access?(group_parameter, %w(write create))).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -247,22 +250,22 @@ RSpec.shared_examples '.role_access_ids call' do
|
||||||
context 'single access' do
|
context 'single access' do
|
||||||
|
|
||||||
it 'lists access IDs' do
|
it 'lists access IDs' do
|
||||||
expect(described_class.role_access_ids(group_parameter, 'read')).to include(instance.id)
|
expect(described_class.role_access_ids(group_parameter, 'read')).to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes non access IDs' do
|
it 'excludes non access IDs' do
|
||||||
expect(described_class.role_access_ids(group_parameter, 'write')).not_to include(instance.id)
|
expect(described_class.role_access_ids(group_parameter, 'write')).not_to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'access list' do
|
context 'access list' do
|
||||||
|
|
||||||
it 'lists access IDs' do
|
it 'lists access IDs' do
|
||||||
expect(described_class.role_access_ids(group_parameter, %w(read write))).to include(instance.id)
|
expect(described_class.role_access_ids(group_parameter, %w(read write))).to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'excludes non access IDs' do
|
it 'excludes non access IDs' do
|
||||||
expect(described_class.role_access_ids(group_parameter, %w(write create))).not_to include(instance.id)
|
expect(described_class.role_access_ids(group_parameter, %w(write create))).not_to include(group_access_instance.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,5 +2,8 @@ require 'rails_helper'
|
||||||
require 'models/concerns/has_groups_examples'
|
require 'models/concerns/has_groups_examples'
|
||||||
|
|
||||||
RSpec.describe Role do
|
RSpec.describe Role do
|
||||||
|
let(:group_access_instance) { create(:role) }
|
||||||
|
let(:new_group_access_instance) { build(:role) }
|
||||||
|
|
||||||
include_examples 'HasGroups'
|
include_examples 'HasGroups'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
require 'models/concerns/has_groups_examples'
|
require 'models/concerns/has_groups_examples'
|
||||||
require 'models/concerns/has_roles_examples'
|
require 'models/concerns/has_roles_examples'
|
||||||
|
require 'models/concerns/has_groups_permissions_examples'
|
||||||
|
|
||||||
RSpec.describe User do
|
RSpec.describe User do
|
||||||
|
|
||||||
|
let(:group_access_instance) { create(:user, roles: [Role.find_by(name: 'Agent')]) }
|
||||||
|
let(:new_group_access_instance) { build(:user, roles: [Role.find_by(name: 'Agent')]) }
|
||||||
|
let(:group_access_no_permission_instance) { build(:user) }
|
||||||
|
|
||||||
include_examples 'HasGroups'
|
include_examples 'HasGroups'
|
||||||
include_examples 'HasRoles'
|
include_examples 'HasRoles'
|
||||||
|
include_examples 'HasGroups and Permissions'
|
||||||
|
|
||||||
let(:new_password) { 'N3W54V3PW!' }
|
let(:new_password) { 'N3W54V3PW!' }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue