Add update result(file) and create result(file) API endpoint

This commit is contained in:
Urban Rotnik 2019-09-24 12:41:45 +02:00
parent 060125a1c4
commit cc9d987321
5 changed files with 188 additions and 23 deletions

View file

@ -1,15 +1,11 @@
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
module Api
module V1
class ResultsController < BaseController
before_action :load_team
before_action :load_project
before_action :load_experiment
before_action :load_task
before_action :load_result, only: %i(show)
before_action :check_manage_permissions, only: %i(create)
before_action :load_team, :load_project, :load_experiment, :load_task
before_action :load_result, only: %i(show update)
before_action :check_manage_permissions, only: %i(create update)
def index
results = @task.results
@ -21,12 +17,31 @@ module Api
def create
create_text_result if result_text_params.present?
create_file_result if !@result && result_file_params.present?
render jsonapi: @result,
serializer: ResultSerializer,
include: %i(text table file),
status: :created
end
def update
@result.attributes = result_params
update_file_result if result_file_params.present? && @result.is_asset
update_text_result if result_text_params.present? && @result.is_text
if (@result.changed? && @result.save!) || @asset_result_updated
render jsonapi: @result,
serializer: ResultSerializer,
include: %i(text table file),
status: :ok
else
render body: nil, status: :no_content
end
end
def show
render jsonapi: @result, serializer: ResultSerializer,
include: %i(text table file)
@ -39,12 +54,11 @@ module Api
end
def check_manage_permissions
unless can_manage_module?(@task)
raise PermissionError.new(MyModule, :manage)
end
raise PermissionError.new(MyModule, :manage) unless can_manage_module?(@task)
end
def create_text_result
# rubocop:disable Metrics/BlockLength:
Result.transaction do
@result = Result.create!(
user: current_user,
@ -80,6 +94,30 @@ module Api
result_text.save!
end
end
# rubocop:enable Metrics/BlockLength:
end
def update_text_result
raise NotImplementedError, 'update_text_result should be implemented!'
end
def create_file_result
Result.transaction do
@result = @task.results.create!(result_params.merge(user_id: current_user.id))
asset = Asset.create!(result_file_params)
ResultAsset.create!(asset: asset, result: @result)
end
end
def update_file_result
old_checksum, new_checksum = nil
Result.transaction do
old_checksum = @result.asset.file.blob.checksum
@result.asset.file.purge
@result.asset.file.attach(result_file_params[:file])
new_checksum = @result.asset.file.blob.checksum
end
@asset_result_updated = old_checksum != new_checksum
end
def result_params
@ -92,10 +130,15 @@ module Api
# Partially implement sideposting draft
# https://github.com/json-api/json-api/pull/1197
def result_text_params
prms =
params[:included]&.select { |el| el[:type] == 'result_texts' }&.first
prms.require(:attributes).require(:text)
prms[:attributes]
prms = params[:included]&.select { |el| el[:type] == 'result_texts' }&.first
prms&.require(:attributes)&.require(:text)
prms&.dig(:attributes)&.permit(:text)
end
def result_file_params
prms = params[:included]&.select { |el| el[:type] == 'result_files' }&.first
prms&.require(:attributes)&.require(:file)
prms&.dig(:attributes)&.permit(:file)
end
def tiny_mce_asset_params
@ -126,4 +169,3 @@ module Api
end
end
end
# rubocop:enable Metrics/LineLength

View file

@ -9,9 +9,6 @@ module Api
attributes :id, :file_name, :file_size, :file_type, :file_url
belongs_to :step, serializer: StepSerializer
delegate :file_name, to: :object
delegate :file_size, to: :object
def file_type
object.content_type
end

View file

@ -670,7 +670,7 @@ Rails.application.routes.draw do
resources :assets, only: %i(index show create), path: 'attachments'
end
end
resources :results, only: %i(index create show)
resources :results, only: %i(index create show update)
get 'activities', to: 'tasks#activities'
end
end

View file

@ -126,7 +126,7 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
protocol_id: @protocol.id,
step_id: @step.id
),
params: request_body.to_json,
params: request_body,
headers: @valid_headers)
end

View file

@ -1,6 +1,5 @@
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
require 'rails_helper'
RSpec.describe 'Api::V1::ResultsController', type: :request do
@ -47,7 +46,7 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
attributes: {
name: Faker::Name.unique.name
} },
included: [
included: [
{ type: 'result_texts',
attributes: {
text: Faker::Lorem.sentence(word_count: 25)
@ -267,6 +266,44 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
expect { hash_body = json }.not_to raise_exception
expect(hash_body['errors'][0]).to include('status': 404)
end
context 'when resultType is File' do
let(:file) { fixture_file_upload('files/test.jpg', 'image/jpg') }
let(:request_body) do
{
data: {
type: 'results',
attributes: {
name: 'my result'
}
},
included: [
{ type: 'result_files',
attributes: {
file: file
} }
]
}
end
let(:action) do
post(api_v1_team_project_experiment_task_results_path(
team_id: @teams.first.id,
project_id: @valid_project,
experiment_id: @valid_experiment,
task_id: @valid_task
), params: request_body, headers: @valid_headers)
end
it 'creates new asset' do
expect { action }.to change { ResultAsset.count }.by(1)
end
it 'returns status 201' do
action
expect(response).to have_http_status 201
end
end
end
describe 'GET result, #show' do
@ -329,5 +366,94 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
expect(hash_body['errors'][0]).to include('status': 404)
end
end
describe 'PUT result, #update' do
context 'when resultType is file' do
let(:result_file) { @valid_task.results.last }
let(:file) { fixture_file_upload('files/test.jpg', 'image/jpg') }
let(:request_body) do
{
data: {
type: 'results',
attributes: {
name: 'my result'
}
},
included: [
{ type: 'result_files',
attributes: {
file: file
} }
]
}
end
let(:action) do
put(api_v1_team_project_experiment_task_result_path(
team_id: @teams.first.id,
project_id: @valid_project,
experiment_id: @valid_experiment,
task_id: @valid_task,
id: result_file.id
), params: request_body, headers: @valid_headers)
end
context 'when has attributes for update' do
it 'updates tasks name' do
action
expect(result_file.reload.name).to eq('my result')
end
it 'returns status 200' do
action
expect(response).to have_http_status 200
end
end
context 'when there is nothing to update' do
let(:request_body_with_same_name) do
{
data: {
type: 'results',
attributes: {
name: result_file.reload.name
}
}
}
end
it 'returns 204' do
put(api_v1_team_project_experiment_task_result_path(
team_id: @teams.first.id,
project_id: @valid_project,
experiment_id: @valid_experiment,
task_id: @valid_task,
id: result_file.id
), params: request_body_with_same_name.to_json, headers: @valid_headers)
expect(response).to have_http_status 204
end
end
end
context 'when resultType is text' do
let(:result_text) { @valid_task.results.first }
let(:action) do
put(api_v1_team_project_experiment_task_result_path(
team_id: @teams.first.id,
project_id: @valid_project,
experiment_id: @valid_experiment,
task_id: @valid_task,
id: result_text.id
), params: @valid_text_hash_body.to_json, headers: @valid_headers)
end
it 'returns status 500' do
action
expect(response).to have_http_status 500
end
end
end
end
# rubocop:enable Metrics/LineLength