add new API endpoints and fix/update ExperimentMember and MyModuleMember modules

This commit is contained in:
zmagoD 2021-05-22 18:36:30 +02:00
parent be94cb09c2
commit 300c1521fd
14 changed files with 495 additions and 44 deletions

View file

@ -21,7 +21,7 @@ module AccessPermissions
def update
@experiment_member = ExperimentMember.new(current_user, @experiment, @project)
@experiment_member.update(permitted_update_params)
@experiment_member.handle_change(permitted_update_params)
respond_to do |format|
format.json do

View file

@ -22,7 +22,7 @@ module AccessPermissions
def update
@my_module_member = MyModuleMember.new(current_user, @my_module, @experiment, @project)
@my_module_member.update(permitted_update_params)
@my_module_member.handle_change(permitted_update_params)
respond_to do |format|
format.json do

View file

@ -0,0 +1,87 @@
# frozen_string_literal: true
module Api
module V1
class ExperimentUserAssignmentsController < BaseController
before_action :load_team
before_action :load_project
before_action :load_experiment
before_action :load_user_assignment, only: :show
before_action :load_user_assignment_for_managing, only: %i(update destroy)
def index
user_assignments = @experiment.user_assignments
.page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: user_assignments,
each_serializer: ExperimentUserAssignmentSerializer,
include: :user
end
def show
render jsonapi: @user_assignment,
serializer: ExperimentUserAssignmentSerializer,
include: :user
end
def create
raise PermissionError.new(Experiment, :manage) unless can_manage_experiment?(@experiment)
user_role = UserRole.find_by_name user_assignment_params[:role]
experiment_member = ExperimentMember.new(current_user, @experiment, @project)
experiment_member.create(
user_role_id: user_role.id,
user_id: user_assignment_params[:user_id]
)
render jsonapi: experiment_member.user_project, serializer: ExperimentUserAssignmentSerializer, status: :created
end
def update
user_role = UserRole.find_by_name user_assignment_params[:role]
user = @user_assignment.user
experiment_member = ExperimentMember.new(
current_user,
@experiment,
@project,
user,
@user_assignment
)
return render body: nil, status: :no_content if @user_assignment.user_role == user_role
experiment_member.update(user_role_id: user_role.id, user_id: user.id)
render jsonapi: experiment_member.user_project, serializer: ExperimentUserAssignmentSerializer, status: :ok
end
def destroy
experiment_member = ExperimentMember.new(
current_user,
@experiment,
@project,
@user_assignment.user,
@user_assignment
)
experiment_member.destroy
render body: nil
end
private
def load_user_assignment
@user_assignment = @experiment.user_assignments.find(params.require(:id))
end
def load_user_assignment_for_managing
@user_assignment = @experiment.user_assignments.find(params.require(:id))
raise PermissionError.new(Experiment, :manage) unless can_manage_experiment?(@experiment)
end
def user_assignment_params
raise TypeError unless params.require(:data).require(:type) == 'experiment_user_assignments'
params.require(:data).require(:attributes).permit(:user_id, :role)
end
end
end
end

View file

@ -0,0 +1,90 @@
# frozen_string_literal: true
module Api
module V1
class TaskUserAssignmentsController < BaseController
before_action :load_team
before_action :load_project
before_action :load_experiment
before_action :load_task
before_action :load_user_assignment, only: :show
before_action :load_user_assignment_for_managing, only: %i(update destroy)
def index
user_assignments = @task.user_assignments
.page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: user_assignments,
each_serializer: TaskUserAssignmentSerializer,
include: :user
end
def show
render jsonapi: @user_assignment,
serializer: TaskUserAssignmentSerializer,
include: :user
end
def create
raise PermissionError.new(MyModule, :read) unless can_manage_module?(@task)
user_role = UserRole.find_by_name user_assignment_params[:role]
my_module_member = MyModuleMember.new(current_user, @task, @experiment, @project)
my_module_member.create(
user_role_id: user_role.id,
user_id: user_assignment_params[:user_id]
)
render jsonapi: my_module_member.user_project, serializer: TaskUserAssignmentSerializer, status: :created
end
def update
user_role = UserRole.find_by_name user_assignment_params[:role]
user = @user_assignment.user
my_module_member = MyModuleMember.new(
current_user,
@task,
@experiment,
@project,
user,
@user_assignment
)
return render body: nil, status: :no_content if @user_assignment.user_role == user_role
my_module_member.update(user_role_id: user_role.id, user_id: user.id)
render jsonapi: my_module_member.user_project, serializer: TaskUserAssignmentSerializer, status: :ok
end
def destroy
my_module_member = MyModuleMember.new(
current_user,
@task,
@experiment,
@project,
@user_assignment.user,
@user_assignment
)
my_module_member.destroy
render body: nil
end
private
def load_user_assignment
@user_assignment = @task.user_assignments.find(params.require(:id))
end
def load_user_assignment_for_managing
@user_assignment = @task.user_assignments.find(params.require(:id))
raise PermissionError.new(MyModule, :manage) unless can_manage_module?(@task)
end
def user_assignment_params
raise TypeError unless params.require(:data).require(:type) == 'task_user_assignments'
params.require(:data).require(:attributes).permit(:user_id, :role)
end
end
end
end

View file

@ -27,22 +27,34 @@ module Api
def create
raise PermissionError.new(Project, :manage) unless can_manage_project?(@project)
user_project = @project.user_projects.create!(user_project_params.merge!(assigned_by: current_user))
# internally we reuse the same logic as for user project assignment
user_role = UserRole.find_by_name user_project_params[:role]
user = @team.users.find(user_project_params[:user_id])
render jsonapi: user_project, serializer: UserProjectSerializer, status: :created
project_member = ProjectMember.new(user, @project, current_user)
project_member.assign = true
project_member.user_role_id = user_role.id
project_member.create
render jsonapi: project_member.user_project, serializer: UserProjectSerializer, status: :created
end
def update
@user_project.role = user_project_params[:role]
return render body: nil, status: :no_content unless @user_project.changed?
user_role = UserRole.find_by_name user_project_params[:role]
project_member = ProjectMember.new(@user_project.user, @project, current_user)
@user_project.assigned_by = current_user
@user_project.save!
if project_member.user_assignment&.user_role == user_role
return render body: nil, status: :no_content
end
project_member.user_role_id = user_role.id
project_member.update
render jsonapi: @user_project, serializer: UserProjectSerializer, status: :ok
end
def destroy
@user_project.destroy!
project_member = ProjectMember.new(@user_project.user, @project, current_user)
project_member.destroy
render body: nil
end

View file

@ -8,10 +8,11 @@ class ExperimentMember
:user, :project, :user_role,
:user_assignment
def initialize(current_user, experiment, project, user = nil)
def initialize(current_user, experiment, project, user = nil, user_assignment = nil)
@experiment = experiment
@current_user = current_user
@project = project
@user_assignment = user_assignment
if user
@user = user
@ -19,15 +20,9 @@ class ExperimentMember
end
end
def update(params)
self.user_role_id = params[:user_role_id]
self.user_id = params[:user_id]
def handle_change(params)
prepare_data(params)
ActiveRecord::Base.transaction do
@user = @project.users.find(user_id)
@user_role = UserRole.find_by(id: user_role_id)
@user_assignment = UserAssignment.find_by(assignable: experiment, user: user)
if destroy_role?
user_assignment.destroy
elsif user_assignment.present?
@ -44,8 +39,47 @@ class ExperimentMember
end
end
def update(params)
prepare_data(params)
ActiveRecord::Base.transaction do
user_assignment.update!(user_role: user_role)
log_change_activity
end
end
def create(params)
prepare_data(params)
ActiveRecord::Base.transaction do
@user_assignment = UserAssignment.create!(
assignable: experiment,
user: user,
user_role: user_role,
assigned_by: current_user
)
log_change_activity
end
end
def destroy
ActiveRecord::Base.transaction do
user_assignment.destroy
log_change_activity
end
end
private
def prepare_data(params)
self.user_role_id = params[:user_role_id]
self.user_id = params[:user_id]
@user = @project.users.find(user_id)
@user_role = UserRole.find_by(id: user_role_id)
@user_assignment ||= UserAssignment.find_by(assignable: experiment, user: user)
end
def log_change_activity
Activities::CreateActivityService.call(
activity_type: :change_user_role_on_experiment,

View file

@ -8,11 +8,12 @@ class MyModuleMember
:experiment, :user, :project,
:user_role, :user_assignment
def initialize(current_user, my_module, experiment, project, user = nil)
def initialize(current_user, my_module, experiment, project, user = nil , user_assignment = nil)
@experiment = experiment
@current_user = current_user
@project = project
@my_module = my_module
@user_assignment = user_assignment
if user
@user = user
@ -20,15 +21,9 @@ class MyModuleMember
end
end
def update(params)
self.user_role_id = params[:user_role_id]
self.user_id = params[:user_id]
def handle_change(params)
prepare_data(params)
ActiveRecord::Base.transaction do
@user = @project.users.find(user_id)
@user_role = UserRole.find_by(id: user_role_id)
@user_assignment = UserAssignment.find_by(assignable: my_module, user: user)
if destroy_role?
user_assignment.destroy
elsif user_assignment.present?
@ -45,8 +40,47 @@ class MyModuleMember
end
end
def update(params)
prepare_data(params)
ActiveRecord::Base.transaction do
user_assignment.update!(user_role: user_role)
log_change_activity
end
end
def create(params)
prepare_data(params)
ActiveRecord::Base.transaction do
@user_assignment = UserAssignment.create!(
assignable: my_module,
user: user,
user_role: user_role,
assigned_by: current_user
)
log_change_activity
end
end
def destroy
ActiveRecord::Base.transaction do
user_assignment.destroy
log_change_activity
end
end
private
def prepare_data(params)
self.user_role_id = params[:user_role_id]
self.user_id = params[:user_id]
@user = @project.users.find(user_id)
@user_role = UserRole.find_by(id: user_role_id)
@user_assignment ||= UserAssignment.find_by(assignable: my_module, user: user)
end
def log_change_activity
Activities::CreateActivityService.call(
activity_type: :change_user_role_on_my_module,

View file

@ -4,7 +4,7 @@ class ProjectMember
include ActiveModel::Model
attr_accessor :user, :project, :assign, :user_role_id, :user_id
attr_reader :current_user, :user_assignment, :user_role
attr_reader :current_user, :user_assignment, :user_role, :user_project
delegate :user_role, to: :user_assignment, allow_nil: true
@ -25,7 +25,7 @@ class ProjectMember
return unless assign
ActiveRecord::Base.transaction do
UserProject.create!(project: @project, user: @user)
@user_project = UserProject.create!(project: @project, user: @user)
@user_assignment = UserAssignment.create!(
assignable: @project,
user: @user,

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Api
module V1
class ExperimentUserAssignmentSerializer < ActiveModel::Serializer
type :experiment_user_assignments
attributes :id, :role
belongs_to :user, serializer: UserSerializer
belongs_to :experiment, serializer: ExperimentSerializer
end
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
module Api
module V1
class TaskUserAssignmentSerializer < ActiveModel::Serializer
type :task_user_assignments
attributes :id, :role
belongs_to :user, serializer: UserSerializer
belongs_to :task, serializer: TaskSerializer
end
end
end

View file

@ -697,9 +697,11 @@ Rails.application.routes.draw do
get 'activities', to: 'projects#activities'
resources :reports, only: %i(index show), path: 'reports', as: :reports
resources :experiments, only: %i(index show create update) do
resources :experiment_user_assignments, only: %i(index show create update)
resources :task_groups, only: %i(index show)
resources :connections, only: %i(index show)
resources :tasks, only: %i(index show create update) do
resources :tasks_user_assignments, only: %i(index show create update)
resources :task_inventory_items, only: %i(index show),
path: 'items',
as: :items

View file

@ -19,7 +19,7 @@ describe ExperimentMember, type: :model do
let(:subject) { described_class.new(user, experiment, project) }
describe 'update' do
describe '#handle_change' do
let!(:valid_params) {
{
user_id: user.id,
@ -29,7 +29,7 @@ describe ExperimentMember, type: :model do
it 'creates a new user assigment when no assigment present' do
expect {
subject.update(valid_params)
subject.handle_change(valid_params)
}.to change(UserAssignment, :count).by(1)
end
@ -38,21 +38,101 @@ describe ExperimentMember, type: :model do
create :user_assignment, assignable: project, user: user, user_role: normal_user_role, assigned_by: user
expect {
subject.update(valid_params)
subject.handle_change(valid_params)
}.to change(UserAssignment, :count).by(-1)
end
it 'updates the assigment user role' do
assigment = create :user_assignment, assignable: experiment, user: user, user_role: owner_role, assigned_by: user
subject.update(valid_params)
subject.handle_change(valid_params)
expect(assigment.reload.user_role).to eq normal_user_role
end
it 'logs a change_user_role_on_experiment activity' do
expect {
subject.handle_change(valid_params)
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_experiment'
end
end
describe '#update' do
let!(:experiment_user_assignment) {
create :user_assignment,
assignable: experiment,
user: user,
user_role: owner_role,
assigned_by: user
}
let!(:valid_params) {
{
user_id: user.id,
user_role_id: normal_user_role.id
}
}
let!(:subject) { described_class.new(user, experiment, project, user, experiment_user_assignment) }
it 'updates the assigment user role' do
subject.update(valid_params)
expect(experiment_user_assignment.reload.user_role).to eq normal_user_role
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.update(valid_params)
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_experiment'
end
end
describe '#destroy' do
let!(:experiment_user_assignment) {
create :user_assignment,
assignable: experiment,
user: user,
user_role: owner_role,
assigned_by: user
}
let!(:subject) { described_class.new(user, experiment, project, user, experiment_user_assignment) }
it 'destroys the assigment user role' do
expect {
subject.destroy
}.to change(UserAssignment, :count).by(-1)
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.destroy
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_experiment'
end
end
describe '#create' do
let!(:valid_params) {
{
user_id: user.id,
user_role_id: normal_user_role.id
}
}
let(:subject) { described_class.new(user, experiment, project) }
it 'creates a new user assigment when no assigment present' do
expect {
subject.create(valid_params)
}.to change(UserAssignment, :count).by(1)
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.create(valid_params)
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_experiment'
end
end
end

View file

@ -7,14 +7,18 @@ describe MyModuleMember, type: :model do
let!(:user) { create :user }
let!(:project) { create :project }
let!(:user_project) { create :user_project, user: user, project: project }
let!(:user_assignment) { create :user_assignment, assignable: project, user: user, user_role: owner_role, assigned_by: user }
let!(:user_assignment) {
create :user_assignment,
assignable: project,
user: user,
user_role: owner_role,
assigned_by: user
}
let!(:experiment) { create :experiment, project: project }
let!(:my_module) { create :my_module, experiment: experiment }
let(:normal_user_role) { create :normal_user_role }
let(:subject) { described_class.new(user, my_module, experiment, project) }
describe 'update' do
describe '#handle_change' do
let!(:valid_params) {
{
user_id: user.id,
@ -22,9 +26,11 @@ describe MyModuleMember, type: :model do
}
}
let(:subject) { described_class.new(user, my_module, experiment, project) }
it 'creates a new user assigment when no assigment present' do
expect {
subject.update(valid_params)
subject.handle_change(valid_params)
}.to change(UserAssignment, :count).by(1)
end
@ -33,7 +39,7 @@ describe MyModuleMember, type: :model do
create :user_assignment, assignable: experiment, user: user, user_role: normal_user_role, assigned_by: user
expect {
subject.update(valid_params)
subject.handle_change(valid_params)
}.to change(UserAssignment, :count).by(-1)
end
@ -42,16 +48,47 @@ describe MyModuleMember, type: :model do
create :user_assignment, assignable: project, user: user, user_role: normal_user_role, assigned_by: user
expect {
subject.update(valid_params)
subject.handle_change(valid_params)
}.to change(UserAssignment, :count).by(-1)
end
it 'updates the assigment user role' do
assigment = create :user_assignment, assignable: my_module, user: user, user_role: owner_role, assigned_by: user
subject.update(valid_params)
subject.handle_change(valid_params)
expect(assigment.reload.user_role).to eq normal_user_role
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.handle_change(valid_params)
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_my_module'
end
end
describe '#update' do
let!(:my_module_user_assignment) {
create :user_assignment,
assignable: my_module,
user: user,
user_role: owner_role,
assigned_by: user
}
let!(:valid_params) {
{
user_id: user.id,
user_role_id: normal_user_role.id
}
}
let!(:subject) { described_class.new(user, my_module, experiment, project, user, my_module_user_assignment) }
it 'updates the assigment user role' do
subject.update(valid_params)
expect(my_module_user_assignment.reload.user_role).to eq normal_user_role
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.update(valid_params)
@ -59,4 +96,53 @@ describe MyModuleMember, type: :model do
expect(Activity.last.type_of).to eq 'change_user_role_on_my_module'
end
end
describe '#destroy' do
let!(:user_assignment) {
create :user_assignment,
assignable: my_module,
user: user,
user_role: owner_role,
assigned_by: user
}
let!(:subject) { described_class.new(user, my_module, experiment, project, user, user_assignment) }
it 'destroys the assigment user role' do
expect {
subject.destroy
}.to change(UserAssignment, :count).by(-1)
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.destroy
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_my_module'
end
end
describe '#create' do
let!(:valid_params) {
{
user_id: user.id,
user_role_id: normal_user_role.id
}
}
let(:subject) { described_class.new(user, my_module, experiment, project) }
it 'creates a new user assigment when no assigment present' do
expect {
subject.create(valid_params)
}.to change(UserAssignment, :count).by(1)
end
it 'logs a change_user_role_on_my_module activity' do
expect {
subject.create(valid_params)
}.to change(Activity, :count).by(1)
expect(Activity.last.type_of).to eq 'change_user_role_on_my_module'
end
end
end

View file

@ -10,7 +10,7 @@ describe ProjectMember, type: :model do
let(:subject) { described_class.new(user, project, user) }
describe 'create' do
describe '#create' do
it 'create a user_assignment and user_project records' do
subject.assign = true
subject.user_role_id = owner_role.id
@ -30,7 +30,7 @@ describe ProjectMember, type: :model do
end
end
describe 'update' do
describe '#update' do
let!(:user_project) { create :user_project, user: user, project: project }
let!(:user_assignment) {
create :user_assignment,
@ -55,7 +55,7 @@ describe ProjectMember, type: :model do
end
end
describe 'destroy' do
describe '#destroy' do
let!(:user_two) { create :user }
let!(:user_project_two) { create :user_project, user: user_two, project: project }
let!(:user_assignment_two) {