Add step result link [SCI-11879]

This commit is contained in:
Andrej 2025-05-13 11:59:49 +02:00
parent 5a2f039278
commit e63fb45b9e
13 changed files with 187 additions and 2 deletions

View file

@ -0,0 +1,53 @@
# frozen_string_literal: true
class StepResultsController < ApplicationController
before_action :load_step, only: :create
before_action :load_result, only: :create
before_action :load_step_result, only: :destroy
before_action :check_manage_permissions, only: %i(create destroy)
def create
ActiveRecord::Base.transaction do
@step_result = StepResult.create!(step: @step, result: @result, created_by: current_user)
render json: { step_result: { id: @step_result.id } }
rescue ActiveRecord::RecordInvalid => e
Rails.logger.error e.message
render json: { errors: @step_result.errors.full_messages }, status: :unprocessable_entity
end
end
def destroy
ActiveRecord::Base.transaction do
if @step_result.destroy
render json: {}, status: :ok
else
render json: { errors: @step_result.errors.full_messages }, status: :unprocessable_entity
end
end
@step_result.destroy!
end
private
def load_step
@step = Step.find_by(id: params[:step_id])
render_404 unless @step
end
def load_result
@result = Result.find_by(id: params[:result_id])
render_404 unless @result
end
def load_step_result
@step_result = StepResult.find_by(id: params[:id])
render_404 unless @step_result
@step = @step_result.step
@result = @step_result.result
end
def check_manage_permissions
render_403 unless @step.my_module == @result.my_module && can_manage_my_module?(@step.my_module)
end
end

View file

@ -31,6 +31,8 @@ class Result < ApplicationRecord
has_many :result_texts, inverse_of: :result, dependent: :destroy
has_many :result_comments, inverse_of: :result, foreign_key: :associated_id, dependent: :destroy
has_many :report_elements, inverse_of: :result, dependent: :destroy
has_many :step_results, inverse_of: :result, dependent: :destroy
has_many :steps, through: :step_results
accepts_nested_attributes_for :result_texts
accepts_nested_attributes_for :assets

View file

@ -44,6 +44,8 @@ class Step < ApplicationRecord
has_many :tables, through: :step_tables, dependent: :destroy
has_many :report_elements, inverse_of: :step, dependent: :destroy
has_many :form_responses, as: :parent, inverse_of: :parent, dependent: :destroy
has_many :step_results, inverse_of: :step, dependent: :destroy
has_many :results, through: :step_results
accepts_nested_attributes_for :checklists,
reject_if: :all_blank,

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class StepResult < ApplicationRecord
belongs_to :result
belongs_to :step
belongs_to :created_by, class_name: 'User'
end

View file

@ -10,13 +10,19 @@ class ResultSerializer < ActiveModel::Serializer
attributes :name, :id, :urls, :updated_at, :created_at_formatted, :updated_at_formatted, :user,
:my_module_id, :attachments_manageble, :marvinjs_enabled, :marvinjs_context, :type,
:wopi_enabled, :wopi_context, :created_at, :created_by, :archived, :assets_order,
:open_vector_editor_context, :comments_count, :assets_view_mode, :storage_limit, :collapsed
:open_vector_editor_context, :comments_count, :assets_view_mode, :storage_limit, :collapsed, :steps
def collapsed
result_states = current_user.settings.fetch('result_states', {})
result_states[object.id.to_s] == true
end
def steps
object.steps.map do |step|
{ id: step.id, name: step.name }
end
end
def marvinjs_enabled
MarvinJsService.enabled?
end

View file

@ -10,7 +10,7 @@ class StepSerializer < ActiveModel::Serializer
attributes :name, :position, :completed, :attachments_manageble, :urls, :assets_view_mode,
:marvinjs_enabled, :marvinjs_context, :created_by, :created_at, :assets_order,
:wopi_enabled, :wopi_context, :comments_count, :unseen_comments, :storage_limit,
:type, :open_vector_editor_context, :collapsed
:type, :open_vector_editor_context, :collapsed, :results
def collapsed
step_states = @instance_options[:user].settings.fetch('task_step_states', {})
@ -21,6 +21,12 @@ class StepSerializer < ActiveModel::Serializer
MarvinJsService.enabled?
end
def results
object.results.map do |result|
{ id: result.id, name: result.name }
end
end
def type
'Step'
end

View file

@ -459,6 +459,13 @@ Rails.application.routes.draw do
# as well as 'module info' page for single module (HTML)
get 'experiments/:experiment_id/table', to: 'my_modules#index'
get 'experiments/:experiment_id/modules', to: 'my_modules#index', as: :my_modules
resources :step_results, only: %i(destroy) do
collection do
post :create
end
end
resources :my_modules, path: '/modules', only: [:show, :update] do
post 'save_table_state', on: :collection, defaults: { format: 'json' }

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
class CreateStepResults < ActiveRecord::Migration[7.0]
def change
create_table :step_results do |t|
t.references :step, null: false, foreign_key: true
t.references :result, null: false, foreign_key: true
t.references :created_by, null: false, foreign_key: { to_table: :users }
t.timestamps
end
end
end

View file

@ -0,0 +1,51 @@
# frozen_string_literal: true
require 'rails_helper'
describe StepResultsController, type: :controller do
login_user
include_context 'reference_project_structure', {
my_modules: 1,
step: true,
result_text: true
}
let(:step_second) { create :step, protocol: my_modules.first.protocol, user: user }
let(:result_second) { create :result, my_module: my_modules.first, user: user }
let(:step_result) { create :step_result, step: step_second, result: result_second }
describe 'POST create link step result succesfully' do
let(:action) { post :create, params: params }
let(:params) do
{
step_id: step.id,
result_id: result_text.result.id
}
end
it 'calls create activity service' do
action
expect(response).to have_http_status(:success)
end
it 'calls create activity service' do
params[:step_id] = step_second.id
action
expect(response).to have_http_status(:forbidden)
end
end
describe 'DELETE destroy' do
let(:action) { delete :destroy, params: params, format: :json }
context 'when in protocol repository' do
let(:params) { { id: step_result.id } }
it 'calls create activity for deleting step in protocol repository' do
action
expect(response).to have_http_status(:success)
end
end
end
end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
FactoryBot.define do
factory :step_result do
association :step, factory: :step
association :result, factory: :result
association :created_by, factory: :user
end
end

View file

@ -40,6 +40,8 @@ describe Result, type: :model do
it { should have_many :result_texts }
it { should have_many :result_comments }
it { should have_many :report_elements }
it { should have_many :step_results }
it { should have_many :steps }
end
describe 'Validations' do

View file

@ -0,0 +1,26 @@
# frozen_string_literal: true
require 'rails_helper'
describe StepResult, type: :model do
let(:step_result) { build :step_result }
it 'is valid' do
expect(step_result).to be_valid
end
it 'should be of class form field value' do
expect(subject.class).to eq StepResult
end
describe 'Database table' do
it { should have_db_column :created_at }
it { should have_db_column :updated_at }
end
describe 'Relations' do
it { should belong_to(:step) }
it { should belong_to(:result) }
it { should belong_to(:created_by).class_name('User') }
end
end

View file

@ -38,6 +38,8 @@ describe Step, type: :model do
it { should have_many :tables }
it { should have_many :report_elements }
it { should have_many :tiny_mce_assets }
it { should have_many :step_results }
it { should have_many :results }
end
describe 'Validations' do