mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-27 02:04:33 +08:00
Extend asset API upload to support base64
This commit is contained in:
parent
8b24a0f704
commit
4958139699
4 changed files with 192 additions and 100 deletions
|
@ -5,6 +5,7 @@ module Api
|
|||
class AssetsController < BaseController
|
||||
before_action :load_team, :load_project, :load_experiment, :load_task, :load_protocol, :load_step
|
||||
before_action :load_asset, only: :show
|
||||
before_action :check_upload_type, only: :create
|
||||
|
||||
def index
|
||||
attachments = @step.assets
|
||||
|
@ -21,9 +22,18 @@ module Api
|
|||
def create
|
||||
raise PermissionError.new(Asset, :create) unless can_manage_protocol_in_module?(@protocol)
|
||||
|
||||
asset = @step.assets.new(asset_params)
|
||||
asset.save!(context: :on_api_upload)
|
||||
if @form_multipart_upload
|
||||
asset = @step.assets.new(asset_params)
|
||||
else
|
||||
blob = ActiveStorage::Blob.create_after_upload!(
|
||||
io: StringIO.new(Base64.decode64(asset_params[:file_data])),
|
||||
filename: asset_params[:file_name],
|
||||
content_type: asset_params[:content_type]
|
||||
)
|
||||
asset = @step.assets.new(file: blob)
|
||||
end
|
||||
|
||||
asset.save!(context: :on_api_upload)
|
||||
asset.post_process_file
|
||||
|
||||
render jsonapi: asset,
|
||||
|
@ -36,7 +46,9 @@ module Api
|
|||
def asset_params
|
||||
raise TypeError unless params.require(:data).require(:type) == 'attachments'
|
||||
|
||||
attr_list = %i(file)
|
||||
return params.require(:data).require(:attributes).permit(:file) if @form_multipart_upload
|
||||
|
||||
attr_list = %i(file_data content_type file_name)
|
||||
params.require(:data).require(:attributes).require(attr_list)
|
||||
params.require(:data).require(:attributes).permit(attr_list)
|
||||
end
|
||||
|
@ -45,6 +57,10 @@ module Api
|
|||
@asset = @step.assets.find(params.require(:id))
|
||||
raise PermissionError.new(Asset, :read) unless can_read_protocol_in_module?(@asset.step.protocol)
|
||||
end
|
||||
|
||||
def check_upload_type
|
||||
@form_multipart_upload = true if params.dig(:data, :attributes)[:file]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -103,7 +103,22 @@ module Api
|
|||
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)
|
||||
|
||||
if !result_file_params[:file]
|
||||
filedata = Base64.decode64(result_file_params[:file_data])
|
||||
content_type = result_file_params[:content_type]
|
||||
filename = result_file_params[:file_name]
|
||||
|
||||
blob = ActiveStorage::Blob.create_after_upload!(
|
||||
io: StringIO.new(filedata),
|
||||
filename: filename,
|
||||
content_type: content_type
|
||||
)
|
||||
asset = Asset.create!(file: blob)
|
||||
else # multipart form
|
||||
asset = Asset.create!(result_file_params)
|
||||
end
|
||||
|
||||
ResultAsset.create!(asset: asset, result: @result)
|
||||
end
|
||||
end
|
||||
|
@ -139,8 +154,11 @@ module Api
|
|||
prms = params[:included]&.select { |el| el[:type] == 'result_files' }&.first
|
||||
return nil unless prms
|
||||
|
||||
prms.require(:attributes).require(:file)
|
||||
prms.dig(:attributes).permit(:file)
|
||||
return prms.dig(:attributes).permit(:file) if prms.require(:attributes)[:file]
|
||||
|
||||
prms.require(:attributes).require(:file_data)
|
||||
prms.require(:attributes).require(:file_name)
|
||||
prms.dig(:attributes).permit(:file_data, :file_name)
|
||||
end
|
||||
|
||||
def tiny_mce_asset_params
|
||||
|
|
|
@ -27,13 +27,13 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
create(:step_asset, step: @step, asset: asset)
|
||||
|
||||
get(api_v1_team_project_experiment_task_protocol_step_assets_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id
|
||||
), headers: @valid_headers)
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id
|
||||
), headers: @valid_headers)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
@ -42,13 +42,13 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
context 'when protocol is not found' do
|
||||
it 'renders 404' do
|
||||
get(api_v1_team_project_experiment_task_protocol_step_assets_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: -1,
|
||||
step_id: @step.id
|
||||
), headers: @valid_headers)
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: -1,
|
||||
step_id: @step.id
|
||||
), headers: @valid_headers)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@ -61,14 +61,14 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
create(:step_asset, step: @step, asset: asset)
|
||||
|
||||
get(api_v1_team_project_experiment_task_protocol_step_asset_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: asset.id
|
||||
), headers: @valid_headers)
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: asset.id
|
||||
), headers: @valid_headers)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
@ -77,14 +77,14 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
context 'when experiment is not found' do
|
||||
it 'renders 404' do
|
||||
get(api_v1_team_project_experiment_task_protocol_step_asset_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: -1,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: asset.id
|
||||
), headers: @valid_headers)
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: -1,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: asset.id
|
||||
), headers: @valid_headers)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@ -93,14 +93,14 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
context 'when asset is not found' do
|
||||
it 'renders 404' do
|
||||
get(api_v1_team_project_experiment_task_protocol_step_asset_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: -1
|
||||
), headers: @valid_headers)
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id,
|
||||
id: -1
|
||||
), headers: @valid_headers)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
@ -113,49 +113,82 @@ RSpec.describe 'Api::V1::AssetsController', type: :request do
|
|||
end
|
||||
|
||||
before :each do
|
||||
@file = fixture_file_upload('files/test.jpg', 'image/jpg')
|
||||
allow_any_instance_of(Asset).to receive(:post_process_file)
|
||||
end
|
||||
|
||||
let(:action) do
|
||||
post(api_v1_team_project_experiment_task_protocol_step_assets_path(
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id
|
||||
),
|
||||
team_id: @team.id,
|
||||
project_id: @project.id,
|
||||
experiment_id: @experiment.id,
|
||||
task_id: @task.id,
|
||||
protocol_id: @protocol.id,
|
||||
step_id: @step.id
|
||||
),
|
||||
params: request_body,
|
||||
headers: @valid_headers)
|
||||
end
|
||||
let(:request_body) do
|
||||
{
|
||||
data: {
|
||||
type: 'attachments',
|
||||
attributes: attributes
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
context 'when has valid params' do
|
||||
let(:request_body) do
|
||||
{
|
||||
data: {
|
||||
type: 'attachments',
|
||||
attributes: {
|
||||
file: @file
|
||||
}
|
||||
context 'when multipart form' do
|
||||
let(:file) { fixture_file_upload('files/test.jpg', 'image/jpg') }
|
||||
let(:attributes) { { file: file } }
|
||||
|
||||
it 'creates new asset' do
|
||||
expect { action }.to change { Asset.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns status 201' do
|
||||
action
|
||||
|
||||
expect(response).to have_http_status 201
|
||||
end
|
||||
|
||||
it 'calls post_process_file function for text extraction' do
|
||||
expect_any_instance_of(Asset).to receive(:post_process_file)
|
||||
|
||||
action
|
||||
end
|
||||
end
|
||||
|
||||
context 'when base64 with json' do
|
||||
let(:filedata_base64) do
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAIAA'\
|
||||
'AACCAIAAAD91JpzAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAE0lE'\
|
||||
'QVQIHWP8//8/AwMDExADAQAkBgMBOOSShwAAAABJRU5ErkJggg=='
|
||||
end
|
||||
let(:attributes) do
|
||||
{
|
||||
file_data: filedata_base64,
|
||||
file_name: 'file.png',
|
||||
content_type: 'image/png'
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
let(:request_body) { super().to_json }
|
||||
|
||||
it 'creates new asset' do
|
||||
expect { action }.to change { Asset.count }.by(1)
|
||||
end
|
||||
it 'creates new asset' do
|
||||
expect { action }.to change { Asset.count }.by(1)
|
||||
end
|
||||
|
||||
it 'returns status 201' do
|
||||
action
|
||||
it 'returns status 201' do
|
||||
action
|
||||
|
||||
expect(response).to have_http_status 201
|
||||
end
|
||||
expect(response).to have_http_status 201
|
||||
end
|
||||
|
||||
it 'calls post_process_file function for text extraction' do
|
||||
expect_any_instance_of(Asset).to receive(:post_process_file)
|
||||
it 'calls post_process_file function for text extraction' do
|
||||
expect_any_instance_of(Asset).to receive(:post_process_file)
|
||||
|
||||
action
|
||||
action
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -268,7 +268,6 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
|
|||
end
|
||||
|
||||
context 'when resultType is File' do
|
||||
let(:file) { fixture_file_upload('files/test.jpg', 'image/jpg') }
|
||||
let(:request_body) do
|
||||
{
|
||||
data: {
|
||||
|
@ -277,31 +276,57 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
|
|||
name: 'my result'
|
||||
}
|
||||
},
|
||||
included: [
|
||||
{ type: 'result_files',
|
||||
attributes: {
|
||||
file: file
|
||||
} }
|
||||
]
|
||||
included: [{ type: 'result_files', attributes: attributes }]
|
||||
}
|
||||
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)
|
||||
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)
|
||||
context 'when file is base64' do
|
||||
let(:filedata_base64) do
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAIAA'\
|
||||
'AACCAIAAAD91JpzAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAE0lE'\
|
||||
'QVQIHWP8//8/AwMDExADAQAkBgMBOOSShwAAAABJRU5ErkJggg=='
|
||||
end
|
||||
let(:attributes) do
|
||||
{
|
||||
file_data: filedata_base64,
|
||||
file_name: 'file.png',
|
||||
content_type: 'image/png'
|
||||
}
|
||||
end
|
||||
let(:request_body) { super().to_json }
|
||||
|
||||
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
|
||||
|
||||
it 'returns status 201' do
|
||||
action
|
||||
context 'when file is multipart form' do
|
||||
let(:attributes) { { file: fixture_file_upload('files/test.jpg', 'image/jpg') } }
|
||||
|
||||
expect(response).to have_http_status 201
|
||||
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
|
||||
end
|
||||
|
@ -390,12 +415,12 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
|
|||
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)
|
||||
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
|
||||
|
@ -459,12 +484,12 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
|
|||
|
||||
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)
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue