mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-27 02:04:33 +08:00
Add update result(file) and create result(file) API endpoint
This commit is contained in:
parent
060125a1c4
commit
cc9d987321
5 changed files with 188 additions and 23 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue