mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-06 03:46:39 +08:00
Add API endpoint for Attachments resource
This commit is contained in:
parent
e7083e188c
commit
1be88baab1
5 changed files with 233 additions and 1 deletions
48
app/controllers/api/v1/assets_controller.rb
Normal file
48
app/controllers/api/v1/assets_controller.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class AssetsController < BaseController
|
||||
before_action :load_team, :load_project, :load_experiment, :load_task, :load_protocol, :load_step
|
||||
before_action :load_asset, only: :show
|
||||
|
||||
def index
|
||||
attachments = @step.assets
|
||||
.page(params.dig(:page, :number))
|
||||
.per(params.dig(:page, :size))
|
||||
|
||||
render jsonapi: attachments, each_serializer: AssetSerializer
|
||||
end
|
||||
|
||||
def show
|
||||
render jsonapi: @asset, serializer: AssetSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
raise PermissionError.new(Asset, :create) unless can_manage_protocol_in_module?(@protocol)
|
||||
|
||||
asset = @step.assets.create!(asset_params)
|
||||
|
||||
asset.reload
|
||||
|
||||
render jsonapi: asset,
|
||||
serializer: AssetSerializer,
|
||||
status: :created
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def asset_params
|
||||
raise TypeError unless params.require(:data).require(:type) == 'attachments'
|
||||
|
||||
attr_list = %i(file)
|
||||
params.require(:data).require(:attributes).require(attr_list)
|
||||
params.require(:data).require(:attributes).permit(attr_list)
|
||||
end
|
||||
|
||||
def load_asset
|
||||
@asset = @step.assets.find(params.require(:id))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
24
app/serializers/api/v1/asset_serializer.rb
Normal file
24
app/serializers/api/v1/asset_serializer.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class AssetSerializer < ActiveModel::Serializer
|
||||
include Rails.application.routes.url_helpers
|
||||
|
||||
type :attachments
|
||||
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
|
||||
|
||||
def file_url
|
||||
rails_blob_url(object.file, disposition: 'attachment') if object.file.attached?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,7 @@ module Api
|
|||
attributes :id, :name, :description, :position, :completed
|
||||
attribute :completed_on, if: :completed?
|
||||
belongs_to :protocol, serializer: ProtocolSerializer
|
||||
has_many :assets, serializer: AssetSerializer
|
||||
|
||||
def completed?
|
||||
object.completed
|
||||
|
|
|
@ -666,7 +666,9 @@ Rails.application.routes.draw do
|
|||
path: 'tags',
|
||||
as: :tags
|
||||
resources :protocols, only: %i(index) do
|
||||
resources :steps, only: %i(index show create)
|
||||
resources :steps, only: %i(index show create) do
|
||||
resources :assets, only: %i(index show create), path: 'attachments'
|
||||
end
|
||||
end
|
||||
resources :results, only: %i(index create show)
|
||||
get 'activities', to: 'tasks#activities'
|
||||
|
|
157
spec/requests/api/v1/assets_controller_spec.rb
Normal file
157
spec/requests/api/v1/assets_controller_spec.rb
Normal file
|
@ -0,0 +1,157 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Api::V1::AssetsController', type: :request do
|
||||
before :all do
|
||||
@user = create(:user)
|
||||
@team = create(:team, created_by: @user)
|
||||
@project = create(:project, team: @team)
|
||||
@experiment = create(:experiment, :with_tasks, project: @project)
|
||||
@task = @experiment.my_modules.first
|
||||
@protocol = create(:protocol, my_module: @task)
|
||||
@step = create(:step, protocol: @protocol)
|
||||
|
||||
create(:user_team, user: @user, team: @team)
|
||||
create(:user_project, :normal_user, user: @user, project: @project)
|
||||
|
||||
@valid_headers =
|
||||
{ 'Authorization': 'Bearer ' + generate_token(@user.id) }
|
||||
end
|
||||
|
||||
let(:asset) { create :asset, step: @step }
|
||||
|
||||
describe 'GET steps, #index' do
|
||||
context 'when has valid params' do
|
||||
it 'renders 200' 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)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET step, #show' do
|
||||
context 'when has valid params' do
|
||||
it 'renders 200' 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)
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST step, #create' do
|
||||
before :all do
|
||||
@valid_headers['Content-Type'] = 'application/json'
|
||||
end
|
||||
|
||||
before :each do
|
||||
@file = fixture_file_upload('files/test.jpg', 'image/jpg')
|
||||
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
|
||||
),
|
||||
params: request_body.to_json,
|
||||
headers: @valid_headers)
|
||||
end
|
||||
|
||||
context 'when has valid params' do
|
||||
let(:request_body) do
|
||||
{
|
||||
data: {
|
||||
type: 'attachments',
|
||||
attributes: {
|
||||
file: @file
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
context 'when has missing param' do
|
||||
let(:request_body) do
|
||||
{
|
||||
data: {
|
||||
type: 'attachments',
|
||||
attributes: {
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
it 'renders 400' do
|
||||
action
|
||||
|
||||
expect(response).to have_http_status(400)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue