diff --git a/app/controllers/api/v1/task_inventory_items_controller.rb b/app/controllers/api/v1/task_inventory_items_controller.rb index d09a47cc6..c93ced8e5 100644 --- a/app/controllers/api/v1/task_inventory_items_controller.rb +++ b/app/controllers/api/v1/task_inventory_items_controller.rb @@ -9,6 +9,7 @@ module Api before_action :load_task before_action :load_my_module_repository_row, only: :update before_action :check_stock_consumption_update_permissions, only: :update + before_action :check_task_assign_permissions, only: %i(create destroy) def index items = @@ -31,6 +32,20 @@ module Api include: %i(inventory_cells inventory) end + def create + @inventory_item = RepositoryRow.find_by(id: repository_row_params[:attributes][:item_id]) + + raise PermissionError.new(Repository, :read) unless @inventory_item && can_read_repository?(@inventory_item.repository) + + @task.my_module_repository_rows.create!(repository_row: @inventory_item, assigned_by: current_user) + + render jsonapi: @task.repository_rows, + each_serializer: TaskInventoryItemSerializer, + show_repository: true, + my_module: @task, + include: include_params + end + def update @my_module_repository_row.consume_stock( current_user, @@ -45,6 +60,16 @@ module Api include: %i(inventory_cells inventory) end + def destroy + @inventory_item = @task.repository_rows.find(params.require(:id)) + + raise PermissionError.new(Repository, :read) unless @inventory_item && can_read_repository?(@inventory_item.repository) + + @task.my_module_repository_rows.find_by(repository_row: @inventory_item).destroy! + + render body: nil + end + private def load_my_module_repository_row @@ -61,11 +86,15 @@ module Api end end + def check_task_assign_permissions + raise PermissionError.new(MyModule, :assing_repository_item_to_task) unless can_assign_my_module_repository_rows?(@task) + end + def repository_row_params raise TypeError unless params.require(:data).require(:type) == 'inventory_items' params.require(:data).require(:attributes) - params.permit(data: { attributes: %i(stock_consumption stock_consumption_comment) })[:data] + params.permit(data: { attributes: %i(stock_consumption stock_consumption_comment item_id) })[:data] end def permitted_includes diff --git a/config/locales/en.yml b/config/locales/en.yml index 5ef83b473..56d310fd3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -4547,6 +4547,9 @@ en: update_stock_consumption_permission: title: "Permission denied" detail: "You don't have permisson to update stock consumption on this task item." + assing_repository_item_to_task_permission: + title: "Permission denied" + detail: "You don't have permisson to assign/unassign inventory item on this task item." record_not_found: title: "Not found" detail: "%{model} record with id %{id} not found in the specified scope" diff --git a/config/routes.rb b/config/routes.rb index 4e7957e51..6447fec60 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1011,7 +1011,7 @@ Rails.application.routes.draw do resources :user_assignments, only: %i(index show update), controller: :task_user_assignments - resources :task_inventory_items, only: %i(index show update), + resources :task_inventory_items, only: %i(index show update create destroy), path: 'items', as: :items resources :task_users, only: %i(index show), diff --git a/spec/requests/api/v1/task_inventory_items_controller_spec.rb b/spec/requests/api/v1/task_inventory_items_controller_spec.rb index 425b5d009..14249c6ff 100644 --- a/spec/requests/api/v1/task_inventory_items_controller_spec.rb +++ b/spec/requests/api/v1/task_inventory_items_controller_spec.rb @@ -26,6 +26,7 @@ RSpec.describe 'Api::V1::TasksController', type: :request do @repository = create(:repository, created_by: @user, team: @team) @repository_stock_column = create(:repository_column, :stock_type, repository: @repository) @repository_row = create(:repository_row, name: 'Test row', repository: @repository) + @repository_row_second = create(:repository_row, name: 'Test row assing', repository: @repository) @repository_stock_unit_item = create(:repository_stock_unit_item, created_by: @user, last_modified_by: @user, repository_column: @repository_stock_column) @@ -88,6 +89,119 @@ RSpec.describe 'Api::V1::TasksController', type: :request do end end + describe 'CREATE assign invnetory item to task, #create' do + before :all do + @valid_headers['Content-Type'] = 'application/json' + end + + let(:request_body_valid) do + { + data: { + type: 'inventory_items', + attributes: { + item_id: @repository_row_second.id + } + } + } + end + + let(:request_body_existing) do + { + data: { + type: 'task_assignments', + attributes: { + item_id: @repository_row.id + } + } + } + end + + let(:request_body_without_type) do + { + data: { + attributes: { + item_id: @repository_row_second.id + } + } + } + end + + context 'when has valid params' do + let(:action) do + post(api_v1_team_project_experiment_task_items_path( + team_id: @team.id, + project_id: @project.id, + experiment_id: @experiment.id, + task_id: @my_module.id + ), + params: request_body_valid.to_json, + headers: @valid_headers) + end + + it 'Count assigned items' do + action + expect(@my_module.repository_rows.count).to eq(2) + end + + it 'returns well formated response' do + action + expect(json[:data]).to match( + JSON.parse( + ActiveModelSerializers::SerializableResource + .new(@my_module.repository_rows, + show_repository: true, + my_module: @my_module, + each_serializer: Api::V1::TaskInventoryItemSerializer) + .to_json + )['data'] + ) + end + end + + context 'when has not valid params' do + let(:action) do + post(api_v1_team_project_experiment_task_items_path( + team_id: @team.id, + project_id: @project.id, + experiment_id: @experiment.id, + task_id: @my_module.id + ), + params: request_body_existing.to_json, + headers: @valid_headers) + end + + let(:action_without_type) do + post(api_v1_team_project_experiment_task_items_path( + team_id: @team.id, + project_id: @project.id, + experiment_id: @experiment.id, + task_id: @my_module.id + ), + params: request_body_without_type.to_json, + headers: @valid_headers) + end + + it 'Item already assigned to task' do + action + expect(response).to have_http_status 400 + expect(@my_module.repository_rows.count).to eq(1) + end + + it 'Action without type' do + action_without_type + expect(response).to have_http_status 400 + expect(@my_module.repository_rows.count).to eq(1) + end + + it 'renders 403 when task is locked' do + @my_module.update(archived: true) + action + + expect(response).to have_http_status(403) + end + end + end + describe 'PATCH task inventory items, #update' do before :all do @valid_headers['Content-Type'] = 'application/json' @@ -157,4 +271,42 @@ RSpec.describe 'Api::V1::TasksController', type: :request do end end end + + describe 'DELETE assigned item to task, #destroy' do + let(:action) { + delete(api_v1_team_project_experiment_task_item_path( + id: @repository_row.id, + team_id: @team.id, + project_id: @project.id, + experiment_id: @experiment.id, + task_id: @my_module.id + ), + headers: @valid_headers) + } + it 'Delete assigned item' do + action + expect(response).to have_http_status(200) + expect(@my_module.repository_rows.count).to eq(0) + end + + it 'Delete not assigned item' do + delete(api_v1_team_project_experiment_task_item_path( + id: @repository_row_second.id, + team_id: @team.id, + project_id: @project.id, + experiment_id: @experiment.id, + task_id: @my_module.id + ), + headers: @valid_headers) + expect(response).to have_http_status(404) + expect(@my_module.repository_rows.count).to eq(1) + end + + it 'renders 403 when task is locked' do + @my_module.update_column(:archived, true) + action + + expect(response).to have_http_status(403) + end + end end