mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-08 21:06:24 +08:00
New implementation for attachments creation
This commit is contained in:
parent
1fd0ca6795
commit
9cb4454537
18 changed files with 190 additions and 61 deletions
|
@ -18,8 +18,8 @@ var ExternalProtocols = (function() {
|
||||||
var msg;
|
var msg;
|
||||||
msg = key.charAt(0).toUpperCase() + key.slice(1) + ': ' + errors.protocol[key].join(', ');
|
msg = key.charAt(0).toUpperCase() + key.slice(1) + ': ' + errors.protocol[key].join(', ');
|
||||||
if ((input.length > 0) && (errors.protocol[key].length > 0)) {
|
if ((input.length > 0) && (errors.protocol[key].length > 0)) {
|
||||||
input.next('span.help-block').html(msg);
|
input.parent().next('span.help-block').html(msg);
|
||||||
input.parent().addClass('has-error');
|
input.parent().parent().addClass('has-error');
|
||||||
} else if (errors.protocol[key].length > 0) {
|
} else if (errors.protocol[key].length > 0) {
|
||||||
modal.find('.general-error > span').append(msg + '<br/>');
|
modal.find('.general-error > span').append(msg + '<br/>');
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ var ExternalProtocols = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function initLoadProtocolModalPreview() {
|
function initLoadProtocolModalPreview() {
|
||||||
var externalProtocols = $('.exteral-proocol-result');
|
var externalProtocols = $('.external-protocol-result');
|
||||||
externalProtocols.on('click', 'a[data-action="external-import"]', function(e) {
|
externalProtocols.on('click', 'a[data-action="external-import"]', function(e) {
|
||||||
var link = $(this);
|
var link = $(this);
|
||||||
animateSpinner(null, true);
|
animateSpinner(null, true);
|
||||||
|
@ -120,7 +120,6 @@ var ExternalProtocols = (function() {
|
||||||
function initFormSubmits() {
|
function initFormSubmits() {
|
||||||
var modal = $('#protocol-preview-modal');
|
var modal = $('#protocol-preview-modal');
|
||||||
modal.on('click', 'button[data-action=import_protocol]', function() {
|
modal.on('click', 'button[data-action=import_protocol]', function() {
|
||||||
// console.log('click');
|
|
||||||
var form = modal.find('form');
|
var form = modal.find('form');
|
||||||
var hiddenField = form.find('#protocol_protocol_type');
|
var hiddenField = form.find('#protocol_protocol_type');
|
||||||
hiddenField.attr('value', $(this).data('import_type'));
|
hiddenField.attr('value', $(this).data('import_type'));
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.general-eror {
|
.general-error {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,23 +47,26 @@ class ExternalProtocolsController < ApplicationController
|
||||||
protocol_source: new_params[:protocol_source],
|
protocol_source: new_params[:protocol_source],
|
||||||
protocol_client_id: new_params[:protocol_client_id],
|
protocol_client_id: new_params[:protocol_client_id],
|
||||||
user_id: current_user.id,
|
user_id: current_user.id,
|
||||||
team_id: @team.id
|
team_id: @team.id,
|
||||||
|
build_with_assets: false
|
||||||
)
|
)
|
||||||
p = service_call.built_protocol
|
|
||||||
p.valid? # Get validations errors here
|
|
||||||
|
|
||||||
@protocol = p
|
|
||||||
if service_call.succeed?
|
if service_call.succeed?
|
||||||
|
@protocol = service_call.built_protocol
|
||||||
|
@protocol&.valid? # Get validations errors here
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
html: render_to_string(
|
html: render_to_string(
|
||||||
partial: 'protocol_importers/import_form.html.erb',
|
partial: 'protocol_importers/import_form.html.erb',
|
||||||
locals: { protocol: p, steps_json: service_call.serialized_steps }
|
locals: { protocol: @protocol,
|
||||||
|
steps_json: service_call.serialized_steps,
|
||||||
|
steps_assets: service_call.steps_assets }
|
||||||
),
|
),
|
||||||
title: "Import protocol - #{p.name}",
|
title: t('protocol_importers.new.modal_title', protocol_name: @protocol.name),
|
||||||
footer: render_to_string(
|
footer: render_to_string(
|
||||||
partial: 'protocol_importers/preview_modal_footer.html.erb'
|
partial: 'protocol_importers/preview_modal_footer.html.erb'
|
||||||
),
|
),
|
||||||
validation_errors: { protocol: p.errors.messages }
|
validation_errors: { protocol: @protocol.errors.messages }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
render json: { errors: service_call.errors }, status: 400
|
render json: { errors: service_call.errors }, status: 400
|
||||||
|
@ -74,7 +77,7 @@ class ExternalProtocolsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
service_call = ProtocolImporters::ImportProtocolService.call(
|
service_call = ProtocolImporters::ImportProtocolService.call(
|
||||||
protocol_params: create_protocol_params,
|
protocol_params: create_protocol_params,
|
||||||
steps_params: JSON.parse(create_steps_params[:steps]),
|
steps_params_json: create_steps_params[:steps],
|
||||||
user_id: current_user.id,
|
user_id: current_user.id,
|
||||||
team_id: @team.id
|
team_id: @team.id
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,13 +5,15 @@ module ProtocolImporters
|
||||||
extend Service
|
extend Service
|
||||||
require 'protocol_importers/protocols_io/v3/errors'
|
require 'protocol_importers/protocols_io/v3/errors'
|
||||||
|
|
||||||
attr_reader :errors, :built_protocol
|
attr_reader :errors, :built_protocol, :steps_assets
|
||||||
|
|
||||||
def initialize(protocol_client_id:, protocol_source:, user_id:, team_id:)
|
def initialize(protocol_client_id:, protocol_source:, user_id:, team_id:, build_with_assets: true)
|
||||||
@id = protocol_client_id
|
@id = protocol_client_id
|
||||||
@protocol_source = protocol_source
|
@protocol_source = protocol_source
|
||||||
@user = User.find user_id
|
@user = User.find_by_id user_id
|
||||||
@team = Team.find team_id
|
@team = Team.find_by_id team_id
|
||||||
|
@build_with_assets = build_with_assets
|
||||||
|
@steps_assets = {}
|
||||||
@errors = {}
|
@errors = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,11 +28,12 @@ module ProtocolImporters
|
||||||
|
|
||||||
pio = ProtocolImporters::ProtocolIntermediateObject.new(normalized_json: normalized_hash,
|
pio = ProtocolImporters::ProtocolIntermediateObject.new(normalized_json: normalized_hash,
|
||||||
user: @user,
|
user: @user,
|
||||||
team: @team)
|
team: @team,
|
||||||
|
build_with_assets: @build_with_assets)
|
||||||
|
|
||||||
@built_protocol = pio.build
|
@built_protocol = pio.build
|
||||||
# Protocol with AR errors should not handled here as someting whats wrong.
|
@steps_assets = pio.steps_assets unless @build_with_assets
|
||||||
# @errors[:protocol] = pio.protocol.errors unless @built_protocol.valid?
|
|
||||||
self
|
self
|
||||||
rescue api_errors => e
|
rescue api_errors => e
|
||||||
@errors[e.error_type] = e.message
|
@errors[e.error_type] = e.message
|
||||||
|
@ -48,14 +51,18 @@ module ProtocolImporters
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialized_steps
|
def serialized_steps
|
||||||
|
# Serialize steps with nested attributes for Tables and NOT nasted attributes for Assets
|
||||||
|
# We want to avoid creating (downloading) Assets instances on building first time and again on importing/creating,
|
||||||
|
# when both actions are not in a row.
|
||||||
|
# Also serialization does not work properly with paperclip attrs
|
||||||
return nil unless built_protocol
|
return nil unless built_protocol
|
||||||
|
|
||||||
built_protocol.steps.map do |step|
|
built_protocol.steps.map do |step|
|
||||||
step_hash = step.attributes.symbolize_keys.slice(:name, :description, :position)
|
step_hash = step.attributes.symbolize_keys.slice(:name, :description, :position)
|
||||||
|
|
||||||
# if step.assets.any?
|
if !@build_with_assets && @steps_assets[step.position].any?
|
||||||
# step_hash[:assets_attributes] = step.assets.map { |a| a.attributes.symbolize_keys.except(:id) }
|
step_hash[:attachments] = @steps_assets[step.position]
|
||||||
# end
|
end
|
||||||
|
|
||||||
if step.tables.any?
|
if step.tables.any?
|
||||||
step_hash[:tables_attributes] = step.tables.map { |t| t.attributes.symbolize_keys.slice(:contents) }
|
step_hash[:tables_attributes] = step.tables.map { |t| t.attributes.symbolize_keys.slice(:contents) }
|
||||||
|
|
|
@ -6,11 +6,11 @@ module ProtocolImporters
|
||||||
|
|
||||||
attr_reader :errors, :protocol
|
attr_reader :errors, :protocol
|
||||||
|
|
||||||
def initialize(protocol_params:, steps_params:, team_id:, user_id:)
|
def initialize(protocol_params:, steps_params_json:, team_id:, user_id:)
|
||||||
@user = User.find user_id
|
@user = User.find_by_id user_id
|
||||||
@team = Team.find team_id
|
@team = Team.find_by_id team_id
|
||||||
@protocol_params = protocol_params
|
@protocol_params = protocol_params
|
||||||
@steps_params = steps_params
|
@steps_params = JSON.parse(steps_params_json) # catch error here
|
||||||
@errors = {}
|
@errors = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -18,10 +18,17 @@ module ProtocolImporters
|
||||||
return self unless valid?
|
return self unless valid?
|
||||||
|
|
||||||
@protocol = Protocol.new(@protocol_params.merge!(added_by: @user, team: @team))
|
@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))
|
|
||||||
|
|
||||||
# TODO: Manually create file here. "Accept nasted attributes won't work here"
|
@protocol.steps << @steps_params.map do |step_params|
|
||||||
|
# Create step with nested attributes for tables
|
||||||
|
s = Step.new(step_params
|
||||||
|
.symbolize_keys
|
||||||
|
.slice(:name, :position, :description, :tables_attributes)
|
||||||
|
.merge(user: @user, completed: false))
|
||||||
|
|
||||||
|
# 'Manually' create assets here. "Accept nasted attributes won't work assets"
|
||||||
|
s.assets << AttachmentsBuilder.generate(step_params.deep_symbolize_keys, user: @user, team: @team)
|
||||||
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
@errors[:protocol] = @protocol.errors.messages unless @protocol.save
|
@errors[:protocol] = @protocol.errors.messages unless @protocol.save
|
||||||
|
|
|
@ -2,16 +2,27 @@
|
||||||
|
|
||||||
module ProtocolImporters
|
module ProtocolImporters
|
||||||
module AttachmentsBuilder
|
module AttachmentsBuilder
|
||||||
def self.generate(step_json)
|
def self.generate(step_json, user: nil, team: nil)
|
||||||
return [] unless step_json[:attachments]&.any?
|
return [] unless step_json[:attachments]&.any?
|
||||||
|
|
||||||
step_json[:attachments].map do |f|
|
step_json[:attachments].map do |f|
|
||||||
Asset.new(file: URI.parse(f[:url]),
|
Asset.new(file: URI.parse(f[:url]),
|
||||||
created_by: @user,
|
created_by: user,
|
||||||
last_modified_by: @user,
|
last_modified_by: user,
|
||||||
team: @team,
|
team: team,
|
||||||
file_file_name: f[:name])
|
file_file_name: f[:name])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.generate_json(step_json)
|
||||||
|
return [] unless step_json[:attachments]&.any?
|
||||||
|
|
||||||
|
step_json[:attachments].map do |f|
|
||||||
|
{
|
||||||
|
name: f[:name],
|
||||||
|
url: f[:url]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
module ProtocolImporters
|
module ProtocolImporters
|
||||||
class ProtocolIntermediateObject
|
class ProtocolIntermediateObject
|
||||||
attr_accessor :normalized_protocol_data, :user, :team, :protocol
|
attr_reader :normalized_protocol_data, :user, :team, :protocol, :steps_assets, :build_with_assets
|
||||||
|
|
||||||
def initialize(normalized_json: {}, user:, team:)
|
def initialize(normalized_json: {}, user:, team:, build_with_assets: true)
|
||||||
@normalized_protocol_data = normalized_json.with_indifferent_access[:protocol] if normalized_json
|
@normalized_protocol_data = normalized_json.with_indifferent_access[:protocol] if normalized_json
|
||||||
@user = user
|
@user = user
|
||||||
@team = team
|
@team = team
|
||||||
|
@steps_assets = {}
|
||||||
|
@build_with_assets = build_with_assets
|
||||||
end
|
end
|
||||||
|
|
||||||
def import
|
def import
|
||||||
|
@ -28,7 +30,11 @@ module ProtocolImporters
|
||||||
def build_steps
|
def build_steps
|
||||||
@normalized_protocol_data[:steps].map do |s|
|
@normalized_protocol_data[:steps].map do |s|
|
||||||
step = Step.new(step_attributes(s))
|
step = Step.new(step_attributes(s))
|
||||||
step.assets << AttachmentsBuilder.generate(s)
|
if @build_with_assets
|
||||||
|
step.assets << AttachmentsBuilder.generate(s, user: user, team: team)
|
||||||
|
else
|
||||||
|
@steps_assets[step.position] = AttachmentsBuilder.generate_json(s)
|
||||||
|
end
|
||||||
step.tables << TablesBuilder.extract_tables_from_html_string(s[:description][:body], true)
|
step.tables << TablesBuilder.extract_tables_from_html_string(s[:description][:body], true)
|
||||||
step.description = StepDescriptionBuilder.generate(s)
|
step.description = StepDescriptionBuilder.generate(s)
|
||||||
step
|
step
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="steps">
|
<div id="steps">
|
||||||
<% protocol.steps.sort_by{ |s| s.position }.each do |step| %>
|
<% protocol.steps.sort_by{ |s| s.position }.each do |step| %>
|
||||||
<%= render partial: "steps/step.html.erb", locals: { step: step, preview: true } %>
|
<%= render partial: "steps/step.html.erb", locals: { step: step, steps_assets: steps_assets, preview: true, import: true } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
<div class='row empty-text'>
|
<div class='row empty-text'>
|
||||||
<%= t('protocols.index.external_protocols.list_panel.empty_text') %>
|
<%= t('protocols.index.external_protocols.list_panel.empty_text') %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="external-protocol-result">
|
||||||
|
<a href="#" data-source="protocolsio/v3" data-id="11176" data-action="external-import" data-url="<%= team_build_external_protocol_path(current_team.id,) %>">Protocols IO, 11176</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class='protocol-card'
|
<div class='protocol-card'
|
||||||
data-protocol-source='protocolsio/v3'
|
data-protocol-source='protocolsio/v3'
|
||||||
|
@ -72,11 +75,6 @@
|
||||||
data-show-protocol-id='errorr'>
|
data-show-protocol-id='errorr'>
|
||||||
Error protocol (click me, should default to default screen)
|
Error protocol (click me, should default to default screen)
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="exteral-proocol-result">
|
|
||||||
<a href="#" data-source="protocolsio/v3" data-id="11176" data-action="external-import" data-url="<%= team_build_external_protocol_path(current_team.id,) %>">Protocols IO, 11176</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class='col-md-7 protocol-preview-panel'>
|
<div class='col-md-7 protocol-preview-panel'>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<% preview = (defined?(preview) ? preview : false) %>
|
<% preview = (defined?(preview) ? preview : false) %>
|
||||||
|
<% import = (defined?(import) ? import : false) %>
|
||||||
<div class ="step <%= step.completed? ? "completed" : "not-completed" %>">
|
<div class ="step <%= step.completed? ? "completed" : "not-completed" %>">
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
@ -113,7 +114,12 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% if import %>
|
||||||
|
<%= render partial: 'steps/attachments/preview_list.html.erb',
|
||||||
|
locals: { attachments: steps_assets[step.position]} %>
|
||||||
|
<% else %>
|
||||||
<%= render partial: 'steps/attachments/list.html.erb', locals: { step: step, preview: preview } %>
|
<%= render partial: 'steps/attachments/list.html.erb', locals: { step: step, preview: preview } %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% unless step.checklists.blank? then %>
|
<% unless step.checklists.blank? then %>
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
|
@ -147,10 +153,12 @@
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
<% unless import %>
|
||||||
<hr>
|
<hr>
|
||||||
<%= render partial: 'steps/comments.html.erb', locals: { comments: step.last_comments,
|
<%= render partial: 'steps/comments.html.erb', locals: { comments: step.last_comments,
|
||||||
comments_count: step.step_comments.count,
|
comments_count: step.step_comments.count,
|
||||||
step: step } %>
|
step: step } %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
9
app/views/steps/attachments/_new_attachment.html.erb
Normal file
9
app/views/steps/attachments/_new_attachment.html.erb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<div class="attachment-placeholder pull-left new">
|
||||||
|
<div class="attachment-thumbnail no-shadow">
|
||||||
|
<i class="fas fa-image"></i>
|
||||||
|
</div>
|
||||||
|
<div class="attachment-label"><%= truncate(file_name || file_url, length: Constants::FILENAME_TRUNCATION_LENGTH) %>
|
||||||
|
</div>
|
||||||
|
<div class="spencer-bonnet-modif">
|
||||||
|
</div>
|
||||||
|
</div>
|
23
app/views/steps/attachments/_preview_list.html.erb
Normal file
23
app/views/steps/attachments/_preview_list.html.erb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 attachments-actions">
|
||||||
|
|
||||||
|
<div class="title">
|
||||||
|
<h4>
|
||||||
|
<%= t('protocols.steps.files', count: attachments.size) %>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="attachemnts-header pull-right">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-xs-12 attachments">
|
||||||
|
<% attachments.each do |a| %>
|
||||||
|
<%= render partial: 'steps/attachments/new_attachment.html.erb',
|
||||||
|
locals: { file_url: a[:url], file_name: a[:name] } %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<hr>
|
|
@ -1,5 +1,7 @@
|
||||||
en:
|
en:
|
||||||
protocol_importers:
|
protocol_importers:
|
||||||
|
new:
|
||||||
|
modal_title: 'Import protocol - %{protocol_name}'
|
||||||
templates:
|
templates:
|
||||||
amount:
|
amount:
|
||||||
title: 'Amount'
|
title: 'Amount'
|
||||||
|
|
|
@ -110,6 +110,8 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
service = double('success_service')
|
service = double('success_service')
|
||||||
allow(service).to(receive(:succeed?)).and_return(true)
|
allow(service).to(receive(:succeed?)).and_return(true)
|
||||||
allow(service).to(receive(:built_protocol)).and_return(protocol)
|
allow(service).to(receive(:built_protocol)).and_return(protocol)
|
||||||
|
allow(service).to(receive(:serialized_steps)).and_return({}.to_s)
|
||||||
|
allow(service).to(receive(:steps_assets)).and_return([])
|
||||||
|
|
||||||
allow_any_instance_of(ProtocolImporters::BuildProtocolFromClientService)
|
allow_any_instance_of(ProtocolImporters::BuildProtocolFromClientService)
|
||||||
.to(receive(:call)).and_return(service)
|
.to(receive(:call)).and_return(service)
|
||||||
|
@ -148,8 +150,10 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
team_id: team.id,
|
team_id: team.id,
|
||||||
protocol_params: {},
|
protocol: {
|
||||||
steps_params: {}
|
name: 'name',
|
||||||
|
steps: {}.to_s
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -159,7 +163,7 @@ describe ExternalProtocolsController, type: :controller do
|
||||||
# Setup double
|
# Setup double
|
||||||
service = double('success_service')
|
service = double('success_service')
|
||||||
allow(service).to(receive(:succeed?)).and_return(true)
|
allow(service).to(receive(:succeed?)).and_return(true)
|
||||||
allow(service).to(receive(:protocol)).and_return({})
|
allow(service).to(receive(:protocol)).and_return(create(:protocol))
|
||||||
|
|
||||||
allow_any_instance_of(ProtocolImporters::ImportProtocolService).to(receive(:call)).and_return(service)
|
allow_any_instance_of(ProtocolImporters::ImportProtocolService).to(receive(:call)).and_return(service)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,14 @@ describe ProtocolImporters::BuildProtocolFromClientService do
|
||||||
ProtocolImporters::BuildProtocolFromClientService
|
ProtocolImporters::BuildProtocolFromClientService
|
||||||
.call(protocol_client_id: 'id', protocol_source: 'protocolsio/v3', user_id: user.id, team_id: team.id)
|
.call(protocol_client_id: 'id', protocol_source: 'protocolsio/v3', user_id: user.id, team_id: team.id)
|
||||||
end
|
end
|
||||||
|
let(:service_call_without_assets) do
|
||||||
|
ProtocolImporters::BuildProtocolFromClientService
|
||||||
|
.call(protocol_client_id: 'id',
|
||||||
|
protocol_source: 'protocolsio/v3',
|
||||||
|
user_id: user.id,
|
||||||
|
team_id: team.id,
|
||||||
|
build_with_assets: false)
|
||||||
|
end
|
||||||
let(:normalized_response) do
|
let(:normalized_response) do
|
||||||
JSON.parse(file_fixture('protocol_importers/normalized_single_protocol.json').read)
|
JSON.parse(file_fixture('protocol_importers/normalized_single_protocol.json').read)
|
||||||
.to_h.with_indifferent_access
|
.to_h.with_indifferent_access
|
||||||
|
@ -16,7 +24,7 @@ describe ProtocolImporters::BuildProtocolFromClientService do
|
||||||
|
|
||||||
context 'when have invalid arguments' do
|
context 'when have invalid arguments' do
|
||||||
it 'returns an error when can\'t find user' do
|
it 'returns an error when can\'t find user' do
|
||||||
allow(User).to receive(:find).and_return(nil)
|
allow(User).to receive(:find_by_id).and_return(nil)
|
||||||
|
|
||||||
expect(service_call.errors).to have_key(:invalid_arguments)
|
expect(service_call.errors).to have_key(:invalid_arguments)
|
||||||
end
|
end
|
||||||
|
@ -69,5 +77,13 @@ describe ProtocolImporters::BuildProtocolFromClientService do
|
||||||
expect(service_call.built_protocol).to be_instance_of(Protocol)
|
expect(service_call.built_protocol).to be_instance_of(Protocol)
|
||||||
end
|
end
|
||||||
# more tests will be implemented when add error handling to service
|
# more tests will be implemented when add error handling to service
|
||||||
|
|
||||||
|
describe 'serialized_steps' do
|
||||||
|
context 'when build without assets' do
|
||||||
|
it 'returns JSON with attachments' do
|
||||||
|
expect(JSON.parse(service_call_without_assets.serialized_steps).first).to have_key('attachments')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,19 +8,19 @@ describe ProtocolImporters::ImportProtocolService do
|
||||||
let(:protocol_params) { attributes_for :protocol, :in_public_repository }
|
let(:protocol_params) { attributes_for :protocol, :in_public_repository }
|
||||||
let(:steps_params) do
|
let(:steps_params) do
|
||||||
[
|
[
|
||||||
attributes_for(:step).merge!(assets_attributes: [attributes_for(:asset)]),
|
attributes_for(:step).merge!(attachments: [{ name: 'random.jpg', url: 'http://www.example.com/random.jpg' }]),
|
||||||
attributes_for(:step).merge!(tables_attributes: [attributes_for(:table), attributes_for(:table)])
|
attributes_for(:step).merge!(tables_attributes: [attributes_for(:table), attributes_for(:table)])
|
||||||
]
|
].to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:service_call) do
|
let(:service_call) do
|
||||||
ProtocolImporters::ImportProtocolService
|
ProtocolImporters::ImportProtocolService
|
||||||
.call(protocol_params: protocol_params, steps_params: steps_params, user_id: user.id, team_id: team.id)
|
.call(protocol_params: protocol_params, steps_params_json: steps_params, user_id: user.id, team_id: team.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when have invalid arguments' do
|
context 'when have invalid arguments' do
|
||||||
it 'returns an error when can\'t find user' do
|
it 'returns an error when can\'t find user' do
|
||||||
allow(User).to receive(:find).and_return(nil)
|
allow(User).to receive(:find_by_id).and_return(nil)
|
||||||
|
|
||||||
expect(service_call.errors).to have_key(:invalid_arguments)
|
expect(service_call.errors).to have_key(:invalid_arguments)
|
||||||
end
|
end
|
||||||
|
@ -28,19 +28,20 @@ describe ProtocolImporters::ImportProtocolService do
|
||||||
it 'returns invalid protocol when can\'t save it' do
|
it 'returns invalid protocol when can\'t save it' do
|
||||||
# step with file without name
|
# step with file without name
|
||||||
steps_invalid_params = [
|
steps_invalid_params = [
|
||||||
attributes_for(:step).merge!(assets_attributes: [attributes_for(:asset).except(:file_file_name)])
|
attributes_for(:step).except(:name).merge!(tables_attributes: [attributes_for(:table)])
|
||||||
]
|
].to_json
|
||||||
|
|
||||||
s = ProtocolImporters::ImportProtocolService.call(protocol_params: protocol_params,
|
s = ProtocolImporters::ImportProtocolService.call(protocol_params: protocol_params,
|
||||||
steps_params: steps_invalid_params,
|
steps_params_json: steps_invalid_params,
|
||||||
user_id: user.id, team_id: team.id)
|
user_id: user.id, team_id: team.id)
|
||||||
|
|
||||||
expect(s.protocol).to be_invalid
|
expect(s.protocol).to be_invalid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when have valid arguments' do
|
context 'when have valid arguments' do
|
||||||
before do
|
before do
|
||||||
|
stub_request(:get, 'http://www.example.com/random.jpg').to_return(status: 200, body: '', headers: {})
|
||||||
|
|
||||||
@protocol = Protocol.new
|
@protocol = Protocol.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ RSpec.describe ProtocolImporters::AttachmentsBuilder do
|
||||||
end
|
end
|
||||||
let(:generate_files_from_step) { described_class.generate(step) }
|
let(:generate_files_from_step) { described_class.generate(step) }
|
||||||
let(:first_file_in_result) { generate_files_from_step.first }
|
let(:first_file_in_result) { generate_files_from_step.first }
|
||||||
|
let(:generate_json_files_from_step) { described_class.generate_json(step) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_request(:get, 'https://pbs.twimg.com/media/Cwu3zrZWQAA7axs.jpg').to_return(status: 200, body: '', headers: {})
|
stub_request(:get, 'https://pbs.twimg.com/media/Cwu3zrZWQAA7axs.jpg').to_return(status: 200, body: '', headers: {})
|
||||||
|
@ -15,7 +16,7 @@ RSpec.describe ProtocolImporters::AttachmentsBuilder do
|
||||||
.to_return(status: 200, body: '', headers: {})
|
.to_return(status: 200, body: '', headers: {})
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'self.build_assets_for_step' do
|
describe 'self.generate' do
|
||||||
it 'returns array of Asset instances' do
|
it 'returns array of Asset instances' do
|
||||||
expect(first_file_in_result).to be_instance_of(Asset)
|
expect(first_file_in_result).to be_instance_of(Asset)
|
||||||
end
|
end
|
||||||
|
@ -24,4 +25,14 @@ RSpec.describe ProtocolImporters::AttachmentsBuilder do
|
||||||
expect(first_file_in_result).to be_valid
|
expect(first_file_in_result).to be_valid
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'self.generate_json' do
|
||||||
|
it 'returns JSON with 2 items (files)' do
|
||||||
|
expect(generate_json_files_from_step.size).to be == 2
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns JSON item with name and url' do
|
||||||
|
expect(generate_json_files_from_step.first.keys).to contain_exactly(:name, :url)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,9 @@ require 'rails_helper'
|
||||||
describe ProtocolImporters::ProtocolIntermediateObject do
|
describe ProtocolImporters::ProtocolIntermediateObject do
|
||||||
subject(:pio) { described_class.new(normalized_json: normalized_result, user: user, team: team) }
|
subject(:pio) { described_class.new(normalized_json: normalized_result, user: user, team: team) }
|
||||||
let(:invalid_pio) { described_class.new(normalized_json: normalized_result, user: nil, team: team) }
|
let(:invalid_pio) { described_class.new(normalized_json: normalized_result, user: nil, team: team) }
|
||||||
|
let(:pio_without_assets) do
|
||||||
|
described_class.new(normalized_json: normalized_result, user: user, team: team, build_with_assets: false)
|
||||||
|
end
|
||||||
let(:user) { create :user }
|
let(:user) { create :user }
|
||||||
let(:team) { create :team }
|
let(:team) { create :team }
|
||||||
let(:normalized_result) do
|
let(:normalized_result) do
|
||||||
|
@ -34,5 +37,26 @@ describe ProtocolImporters::ProtocolIntermediateObject do
|
||||||
it { expect(invalid_pio.import).to be_invalid }
|
it { expect(invalid_pio.import).to be_invalid }
|
||||||
it { expect { invalid_pio.import }.not_to(change { Protocol.all.count }) }
|
it { expect { invalid_pio.import }.not_to(change { Protocol.all.count }) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when build wihout assets' do
|
||||||
|
it { expect { pio_without_assets.import }.to change { Protocol.all.count }.by(1) }
|
||||||
|
it { expect { invalid_pio.import }.not_to(change { Asset.all.count }) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.steps_assets' do
|
||||||
|
context 'when have default pio' do
|
||||||
|
it 'retuns empty hash for steps_assets' do
|
||||||
|
pio.build
|
||||||
|
expect(pio.steps_assets).to be == {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when have pio built without assets' do
|
||||||
|
it 'returns hash with two assets on steps by position' do
|
||||||
|
pio_without_assets.build
|
||||||
|
expect(pio_without_assets.steps_assets.size).to be == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Reference in a new issue