Add step form responses API V2 controller, add API serializers for form response values [SCI-11692] (#8393)

This commit is contained in:
Alex Kriuchykhin 2025-04-07 09:57:05 +02:00 committed by GitHub
parent e586b666cc
commit 62f3be4d9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 311 additions and 4 deletions

View file

@ -92,7 +92,7 @@ module Api
end
def permitted_includes
%w(tables assets checklists checklists.checklist_items comments user form_responses)
%w(tables assets checklists checklists.checklist_items comments user)
end
def check_manage_permissions

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
module Api
module V2
module StepElements
class FormResponsesController < BaseController
before_action :load_team, :load_project, :load_experiment, :load_task, :load_protocol, :load_step
before_action :load_form_response, only: %i(show)
def index
form_responses = timestamps_filter(@step.form_responses).page(params.dig(:page, :number))
.per(params.dig(:page, :size))
render jsonapi: form_responses, each_serializer: Api::V2::FormResponseSerializer, include: include_params
end
def show
render jsonapi: @form_response, serializer: Api::V2::FormResponseSerializer, include: include_params
end
private
def load_form_response
@form_response = @step.form_responses.find(params.require(:id))
end
def permitted_includes
%w(form_field_values)
end
end
end
end
end

View file

@ -61,6 +61,10 @@ module Api
params.require(:data).require(:attributes).permit(:name, :completed)
end
def permitted_includes
%w(tables assets checklists checklists.checklist_items comments user form_responses)
end
end
end
end

View file

@ -4,7 +4,7 @@ module Api
module V1
class FormResponseSerializer < ActiveModel::Serializer
type :form_responses
attributes :id, :form_id, :position
attributes :id, :position
include TimestampableModel

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormActionFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.formatted
end
def value_type
'action'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormDatetimeFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.value
end
def value_type
object.range? ? 'date_time_range' : 'date_time'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormMultipleChoiceFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.value
end
def value_type
'multiple_choice'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormNumberFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.value
end
def value_type
'number'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormRepositoryRowsFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.data&.map { |repository_row| { id: repository_row['id'], inventory_id: repository_row['repository_id'] } }
end
def value_type
'inventory_items'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,21 @@
# frozen_string_literal: true
module Api
module V2
class FormResponseSerializer < ActiveModel::Serializer
type :form_responses
attributes :id, :position, :status
belongs_to :form, serializer: Api::V2::FormSerializer
belongs_to :created_by, serializer: Api::V1::UserSerializer
belongs_to :submitted_by, serializer: Api::V1::UserSerializer
has_many :form_field_values, namespace: Api::V2
include TimestampableModel
def position
object&.step_orderable_element&.position
end
end
end
end

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
module Api
module V2
class FormSerializer < ActiveModel::Serializer
type :forms
attributes :id, :name, :description
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormSingleChoiceFieldValueSerializer < ActiveModel::Serializer
type :form_action_field_values
attributes :id, :value, :value_type
def value
object.value
end
def value_type
'single_choice'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
module Api
module V2
class FormTextFieldValueSerializer < ActiveModel::Serializer
type :form_field_values
attributes :id, :value, :value_type
def value
object.value
end
def value_type
'text'
end
include TimestampableModel
end
end
end

View file

@ -0,0 +1,22 @@
# frozen_string_literal: true
module Api
module V2
class StepOrderableElementSerializer < ActiveModel::Serializer
attributes :position, :element
def element
case object.orderable_type
when 'Checklist'
Api::V1::ChecklistSerializer.new(object.orderable).as_json
when 'StepTable'
Api::V1::TableSerializer.new(object.orderable.table).as_json
when 'StepText'
Api::V1::StepTextSerializer.new(object.orderable).as_json
when 'FromResponse'
Api::V2::FormResponseSerializer.new(object.orderable).as_json
end
end
end
end
end

View file

@ -17,8 +17,8 @@ module Api
has_many :tables, serializer: Api::V1::TableSerializer
has_many :step_texts, serializer: Api::V1::StepTextSerializer
has_many :step_comments, key: :comments, serializer: Api::V1::CommentSerializer
has_many :form_responses, serializer: Api::V1::FormResponseSerializer
has_many :step_orderable_elements, key: :step_elements, serializer: Api::V1::StepOrderableElementSerializer
has_many :form_responses, serializer: Api::V2::FormResponseSerializer
has_many :step_orderable_elements, key: :step_elements, serializer: Api::V2::StepOrderableElementSerializer
include TimestampableModel
end

View file

@ -24,6 +24,7 @@ namespace :v2 do
end
resources :tables, except: %i(new edit)
resources :texts, except: %i(new edit)
resources :form_responses, only: %i(index show)
end
end
end

View file

@ -0,0 +1,74 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Api::V2::StepElements::FormResponsesController', type: :request do
before :all do
@user = create(:user)
@team = create(:team, created_by: @user)
@project = create(:project, team: @team, created_by: @user)
@experiment = create(:experiment, :with_tasks, project: @project, created_by: @user)
@task = @experiment.my_modules.first
@protocol = create(:protocol, my_module: @task)
@step = create(:step, protocol: @protocol)
@form = create(:form, team: @team, created_by: @user)
@form_field = create(:form_field, form: @form, created_by: @user, data: { type: 'TextField' })
@form_response = create(:form_response, form: @form, parent: @step, created_by: @user)
@form_field_value = create(:form_field_value, type: 'FormTextFieldValue', form_field: @form_field, form_response: @form_response, created_by: @user)
@valid_headers = {
'Authorization': 'Bearer ' + generate_token(@user.id),
'Content-Type': 'application/json'
}
end
describe 'GET form_responses, #index' do
context 'when has valid params' do
it 'renders 200' do
get api_v2_team_project_experiment_task_protocol_step_form_responses_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 step is not found' do
it 'renders 404' do
get api_v2_team_project_experiment_task_protocol_step_form_responses_path(
team_id: @team.id,
project_id: @project.id,
experiment_id: @experiment.id,
task_id: @task.id,
protocol_id: @protocol.id,
step_id: -1
), headers: @valid_headers
expect(response).to have_http_status(404)
end
end
end
describe 'GET form_response, #show' do
context 'when has valid params' do
it 'renders 200' do
get api_v2_team_project_experiment_task_protocol_step_form_response_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: @form_response.id
), headers: @valid_headers
expect(response).to have_http_status(200)
end
end
end
end