Commit 544dddab by John Doe

added specs for create_permission

parent ab1c0ca6
# frozen_string_literal: true
class PermissionsController < ApplicationController
before_action :set_permission, only: [:show, :update, :destroy]
before_action :authenticate_user!
before_action :set_nilm
before_action :authorize_admin
# GET /permissions
# GET /permissions.json
def index
@permissions = Permission.all
end
# GET /permissions/1
# GET /permissions/1.json
def show
# return permissions for nilm specified by nilm_id
@permissions = Permission.find_by_nilm(@nilm)
end
# POST /permissions
# POST /permissions.json
def create
@permission = Permission.new(permission_params)
if @permission.save
render :show, status: :created, location: @permission
else
render json: @permission.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /permissions/1
# PATCH/PUT /permissions/1.json
def update
if @permission.update(permission_params)
render :show, status: :ok, location: @permission
else
render json: @permission.errors, status: :unprocessable_entity
end
# create permission for nilm specified by nilm_id
@service = PermissionService.new
@service.run(@nilm, params[:role], params[:type], params[:target_id])
@permission = @service.permission
render status: @service.success? ? :ok : :unprocessable_entity
end
# DELETE /permissions/1
# DELETE /permissions/1.json
def destroy
@permission.destroy
# remove permission from nilm specified by nilm_id
@service = ServiceStub.new
@service.add_notice("Removed permission")
@nilm.permissions.find(params[:id]).destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_permission
@permission = Permission.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def permission_params
params.fetch(:permission, {})
end
def set_nilm
@nilm = Nilm.find(params[:nilm_id])
end
# authorization based on nilms
def authorize_owner
head :unauthorized unless current_user.owns_nilm?(@nilm)
end
end
......@@ -4,14 +4,14 @@
class Nilm < ApplicationRecord
#---Associations-----
has_one :db
has_one :db, dependent: :destroy
has_many :permissions, dependent: :destroy #viewer, owner, admin
has_many :users, through: :permissions
has_many :user_groups, through: :permissions
#---Validations-----
validates :name, presence: true
# def as_json(_options = {})
# nilm = super(except: [:created_at, :updated_at])
# nilm[:available] = db.available
......
......@@ -3,4 +3,30 @@ class Permission < ApplicationRecord
belongs_to :user
belongs_to :user_group
belongs_to :nilm
#---Validations---
ROLES = %w(admin owner viewer)
validates :role, :inclusion => {:in => ROLES}
validate :user_xor_group
def user_xor_group
unless user.blank? ^ user_group.blank?
errors.add(:base, "specify a user or group not both")
end
end
def target_name
if self.user_id?
return self.user.name
elsif self.user_group_id?
return self.user_group.name
else
return "[no target set]"
end
end
def self.json_keys
[:id, :nilm_id, :role]
end
end
......@@ -73,6 +73,10 @@ class User < ActiveRecord::Base
return self.has_permission(["admin","owner","viewer"],nilm)
end
def name
"#{self.first_name} #{self.last_name}"
end
protected
......
......@@ -16,9 +16,7 @@ class EditFolder
# result is valid (eg folder's can't have the same name)
db_folder.assign_attributes(attribs)
unless db_folder.valid?
db_folder.errors
.full_messages
.each { |e| add_error(e) }
add_errors(db_folder.errors.full_messages)
return self
end
# local model checks out, update the remote NilmDB
......
# frozen_string_literal: true
# Handles changing DbStream attributes
class CreatePermission
include ServiceStatus
attr_reader :permission
def run(nilm, role, type, target_id)
# create [role] perimssion on [nilm] for
# the user or group specified
# [type]: user|group
# [target_id]: user_id or user_group_id value
#
@permission = Permission.create(nilm: nilm, role: role)
begin
case type
when "user"
if(nilm.permissions.find_by_user_id(target_id))
add_error("user already has permissions on this nilm")
return self
end
@permission.user = User.find(target_id)
when "group"
@permission.user_group = UserGroup.find(target_id)
if(nilm.permissions.find_by_user_group_id(target_id))
add_error("group already has permissions on this nilm")
return self
end
else
add_error("invalid type")
return self
end
rescue ActiveRecord::RecordNotFound
add_error("target does not exist")
return self
end
unless @permission.save
add_errors(@permission.errors.full_messages)
return self
end
set_notice("Created permission")
self
end
end
......@@ -42,6 +42,10 @@ module ServiceStatus
@errors << String(message)
end
def add_errors(messages)
messages.each{|m| self.add_error(m)}
end
def errors?
!@errors.empty?
end
......
json.extract! permission, :id, :created_at, :updated_at
json.url permission_url(permission, format: :json)
\ No newline at end of file
json.extract! permission, *Permission.json_keys
json.name permission.target_name
......@@ -13,7 +13,7 @@ module ControlPanel
# -- all .rb files in that directory are automatically loaded.
config.api_only = true
# Add folders under the services and adapters directory
%w(nilm db db_folder db_stream).each do |service|
%w(nilm db db_folder db_stream permission).each do |service|
config.autoload_paths << Rails.root.join("app/services/#{service}")
end
config.autoload_paths << Rails.root.join("app/adapters")
......
......@@ -7,5 +7,5 @@ Rails.application.routes.draw do
mount_devise_token_auth_for 'User', at: 'auth'
resources :user_groups
resources :permissions
resources :permissions, only: [:index, :create, :destroy]
end
FactoryGirl.define do
factory :permission do
user
nilm
role "admin"
after(:build) do |permission|
# if no user or group specified, create a user
if(permission.user.blank? &&
permission.user_group.blank?)
permission.user = create(:user)
end
end
end
end
......@@ -6,7 +6,7 @@ FactoryGirl.define do
sequence :name do |n| "group#{n}" end
description { Faker::Lorem.sentence }
owner { users.first }
users { members.empty? ? [User.first] : members }
owner { users.empty? ? create(:user): users.first }
users { members.empty? ? [create(:user)] : members }
end
end
......@@ -9,4 +9,23 @@ RSpec.describe 'Nilm' do
specify { expect(nilm).to respond_to(:url) }
specify { expect(nilm).to respond_to(:db) }
end
it 'removes associated db when destroyed' do
db = Db.create
nilm = Nilm.create(db: db)
nilm.destroy
expect(Db.find_by_id(db.id)).to be nil
end
it 'removes associated permissions when destroyed' do
nilm = create(:nilm)
u = create(:user)
g = create(:user_group)
puser = create(:permission, nilm: nilm, user: u)
pgrp = create(:permission, nilm: nilm, user_group: g)
nilm.destroy
[puser.id, pgrp.id].each do |id|
expect(Permission.find_by_id(id)).to be nil
end
end
end
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Permission, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
describe 'object' do
let(:permission) { Permission.new }
specify { expect(permission).to respond_to(:role) }
specify { expect(permission).to respond_to(:nilm) }
specify { expect(permission).to respond_to(:user_group) }
specify { expect(permission).to respond_to(:user) }
end
it 'requires either a user or a group, not both' do
u = create(:user)
g = create(:user_group)
n = create(:nilm)
# valid with a user
p = build(:permission, nilm: n, user: u)
expect(p.valid?).to be true
# valid with a group
p.user = nil
p.user_group = g
expect(p.valid?).to be true
# invalid with neither
p.user_group = nil
expect(p.valid?).to be false
# invalid with both
p.user_group = g
p.user = u
expect(p.valid?).to be false
expect(p.errors.full_messages.first)
.to match(/not both/)
end
it 'requires role to be viewer|owner|admin' do
p = build(:permission)
%w(owner viewer admin).each do |role|
p.role=role
expect(p.valid?).to be true
end
['',nil,'other'].each do |invalid_role|
p.role = invalid_role
expect(p.valid?).to be false
end
end
it 'responds to target_name' do
u = create(:user, first_name: "John", last_name: "Donnal")
p = build(:permission, user: u)
expect(p.target_name).to match('John Donnal')
g = create(:user_group, name: 'a group')
p.user = nil; p.user_group = g
expect(p.target_name).to match('a group')
end
end
......@@ -9,6 +9,12 @@ RSpec.describe User, type: :model do
specify { expect(user).to respond_to(:email) }
end
it 'responds to name' do
u = build(:user, first_name: 'Bill', last_name: 'Test')
expect(u.name).to match('Bill Test')
end
describe
describe "permission management" do
context "Given the Donnal's House and the Lab" do
before(:each) do
......
# frozen_string_literal: true
require 'rails_helper'
describe 'CreatePermission service' do
let(:nilm){ create(:nilm)}
let(:user){ create(:user)}
let(:group){ create(:user_group)}
it 'creates [role] permission for specified user' do
service = CreatePermission.new
service.run(nilm,'admin','user',user.id)
p = service.permission
expect(service.success?).to be true
expect(p.valid?).to be true
expect(p).to have_attributes(nilm: nilm,
user: user,
role: 'admin')
end
it 'creates [role] permission for specified group' do
service = CreatePermission.new
service.run(nilm,'admin','group',group.id)
p = service.permission
expect(service.success?).to be true
expect(p.valid?).to be true
expect(p).to have_attributes(nilm: nilm,
user_group: group,
role: 'admin')
end
it 'does not allow users multiple permissions on a nilm' do
create(:permission, user: user, nilm: nilm, role: 'viewer')
service = CreatePermission.new
service.run(nilm,'admin','user',user.id)
expect(service.success?).to be false
end
it 'does not allow groups multiple permissions on a nilm' do
create(:permission, user_group: group, nilm: nilm, role: 'viewer')
service = CreatePermission.new
service.run(nilm,'admin','group',group.id)
expect(service.success?).to be false
end
it 'verifies type in user|group' do
service = CreatePermission.new
service.run(nilm,'admin','bogus_type',0)
expect(service.success?).to be false
expect(service.errors[0]).to match(/type/)
end
it 'checks if user or group exists' do
['user','group'].each do |target_type|
service = CreatePermission.new
service.run(nilm,'admin',target_type,99)
expect(service.success?).to be false
expect(service.errors[0]).to match(/target/)
end
end
it 'forwards permission errors' do
service = CreatePermission.new
service.run(nilm,'bad_role','user',user.id)
p = service.permission
expect(service.success?).to be false
expect(service.errors).to eq(p.errors.full_messages)
end
end
......@@ -15,8 +15,9 @@ describe 'ServiceStatus' do
it 'tracks errors' do
x = ModuleTester.new
x.add_error('message')
x.add_errors(['multiple','messages'])
expect(x.errors?).to be true
expect(x.errors.length).to eq(1)
expect(x.errors.length).to eq(3)
end
it 'tracks warnings' do
......
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 sign in to comment