Import protocol service after object is built

This commit is contained in:
Urban Rotnik 2019-06-11 15:32:23 +02:00
parent eb275c4d12
commit 0d43ecdfab
3 changed files with 109 additions and 1 deletions

View file

@ -0,0 +1,49 @@
# frozen_string_literal: true
module ProtocolImporters
class ImportProtocolService
extend Service
attr_reader :errors, :protocol
def initialize(protocol_params:, steps_params:, team_id:, user_id:)
@user = User.find user_id
@team = Team.find team_id
@protocol_params = protocol_params
@steps_params = steps_params
@errors = {}
end
def call
return self unless valid?
@protocol = Protocol.new(@protocol_params.merge!(added_by: @user, team: @team))
@protocol.steps << @steps_params.collect do |step_params|
Step.new(step_params.merge(user: @user, completed: false))
end
@errors[:protocol] = @protocol.errors.messages unless @protocol.save
self
end
def succeed?
@errors.none?
end
private
def valid?
unless [@protocol_params, @user, @team].all?
@errors[:invalid_arguments] = {
'user': @user,
'team': @team,
'@protocol_params': @protocol_params
}.map { |key, value| "Can't find #{key.capitalize}" if value.nil? }.compact
return false
end
true
end
end
end

View file

@ -3,6 +3,6 @@
FactoryBot.define do
factory :table do
name { Faker::Name.unique.name }
contents { { some_data: 'needs to be here' } }
contents { { data: [%w(A B C), %w(D E F), %w(G H I)] } }
end
end

View file

@ -0,0 +1,59 @@
# frozen_string_literal: true
require 'rails_helper'
describe ProtocolImporters::ImportProtocolService do
let(:user) { create :user }
let(:team) { create :team }
let(:protocol_params) { attributes_for :protocol, :in_public_repository }
let(:steps_params) do
[
attributes_for(:step).merge!(assets_attributes: [attributes_for(:asset)]),
attributes_for(:step).merge!(tables_attributes: [attributes_for(:table), attributes_for(:table)])
]
end
let(:service_call) do
ProtocolImporters::ImportProtocolService
.call(protocol_params: protocol_params, steps_params: steps_params, user_id: user.id, team_id: team.id)
end
context 'when have invalid arguments' do
it 'returns an error when can\'t find user' do
allow(User).to receive(:find).and_return(nil)
expect(service_call.errors).to have_key(:invalid_arguments)
end
it 'returns invalid protocol when can\'t save it' do
# step with file without name
steps_invalid_params = [
attributes_for(:step).merge!(assets_attributes: [attributes_for(:asset).except(:file_file_name)])
]
s = ProtocolImporters::ImportProtocolService.call(protocol_params: protocol_params,
steps_params: steps_invalid_params,
user_id: user.id, team_id: team.id)
expect(s.protocol).to be_invalid
end
end
context 'when have valid arguments' do
before do
@protocol = Protocol.new
end
# rubocop:disable MultilineMethodCallIndentation
it do
expect do
service_result = service_call
@protocol = service_result.protocol
end.to change { Protocol.all.count }.by(1)
.and change { @protocol.steps.count }.by(2)
.and change { Table.joins(:step_table).where('step_tables.step_id': @protocol.steps.pluck(:id)).count }.by(2)
.and change { Asset.joins(:step_asset).where('step_assets.step_id': @protocol.steps.pluck(:id)).count }.by(1)
end
# rubocop:enable MultilineMethodCallIndentation
end
end