Upgrade Rails to 6.0 [SCI-3745]

This commit is contained in:
Oleksii Kriuchykhin 2019-09-12 17:21:48 +02:00
parent 9512b448e6
commit c068901b00
70 changed files with 467 additions and 381 deletions

View file

@ -1,4 +1,4 @@
FROM ruby:2.6.3-buster
FROM ruby:2.6.4-buster
MAINTAINER BioSistemika <info@biosistemika.com>
# additional dependecies
@ -13,11 +13,14 @@ RUN apt-get update -qq && \
postgresql-client \
default-jre-headless \
poppler-utils \
librsvg2-2 \
libvips42 \
sudo graphviz --no-install-recommends \
libreoffice \
libfile-mimeinfo-perl \
chromium-driver && \
npm install -g yarn && \
ln -s /usr/lib/x86_64-linux-gnu/libvips.so.42 /usr/lib/x86_64-linux-gnu/libvips.so && \
rm -rf /var/lib/apt/lists/*
# heroku tools

View file

@ -1,4 +1,4 @@
FROM ruby:2.6.3-buster
FROM ruby:2.6.4-buster
MAINTAINER BioSistemika <info@biosistemika.com>
# additional dependecies
@ -16,10 +16,13 @@ RUN apt-get update -qq && \
netcat \
default-jre-headless \
poppler-utils \
librsvg2-2 \
libvips42 \
sudo graphviz --no-install-recommends \
libreoffice \
libfile-mimeinfo-perl && \
npm install -g yarn && \
ln -s /usr/lib/x86_64-linux-gnu/libvips.so.42 /usr/lib/x86_64-linux-gnu/libvips.so && \
rm -rf /var/lib/apt/lists/*
ENV RAILS_ENV production

16
Gemfile
View file

@ -2,21 +2,21 @@
source 'http://rubygems.org'
ruby '2.6.3'
ruby '2.6.4'
gem 'bootsnap', require: false
gem 'bootstrap-sass', '~> 3.3.7'
gem 'bootstrap_form', '~> 2.7.0'
gem 'devise', '~> 4.6.2'
gem 'devise', '~> 4.7.1'
gem 'devise_invitable'
gem 'figaro'
gem 'pg', '~> 1.1'
gem 'pg_search' # PostgreSQL full text search
gem 'rails', '~> 5.2.3'
gem 'rails', '~> 6.0.0'
gem 'recaptcha', require: 'recaptcha/rails'
gem 'sanitize', '~> 5.0'
gem 'sassc-rails'
gem 'simple_token_authentication', '~> 1.15.1' # Token authentication for Devise
gem 'simple_token_authentication', '~> 1.16.0' # Token authentication for Devise
gem 'webpacker', '~> 4.0.0'
gem 'yomu'
@ -32,7 +32,7 @@ gem 'omniauth-rails_csrf_protection', '~> 0.1'
# Gems for API implementation
gem 'active_model_serializers', '~> 0.10.7'
gem 'json-jwt'
gem 'jsonapi-renderer', '= 0.2.0'
gem 'jsonapi-renderer', '~> 0.2.2'
gem 'jwt', '~> 1.5'
gem 'kaminari'
gem 'rack-attack'
@ -92,7 +92,7 @@ gem 'delayed_job_active_record'
gem 'devise-async',
git: 'https://github.com/mhfs/devise-async.git',
branch: 'devise-4.x'
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
gem 'paperclip', '~> 6.1' # File attachment, image attachment library
gem 'rufus-scheduler', '~> 3.5'
@ -108,7 +108,7 @@ gem 'base62' # Used for smart annotations
gem 'newrelic_rpm'
# Permission helper Gem
gem 'canaid', git: 'https://github.com/biosistemika/canaid', branch: 'master'
gem 'canaid', git: 'https://github.com/biosistemika/canaid', branch: 'rails_6'
group :development, :test do
gem 'awesome_print'
@ -123,7 +123,7 @@ group :development, :test do
gem 'pry-byebug'
gem 'pry-rails'
gem 'rails-controller-testing'
gem 'rspec-rails'
gem 'rspec-rails', '>= 4.0.0.beta2'
gem 'rubocop', '>= 0.59.0', require: false
gem 'rubocop-performance'
gem 'timecop'

View file

@ -1,19 +1,19 @@
GIT
remote: https://github.com/biosistemika/canaid
revision: c65ea0a2fae1edb368aa561e35a153c2cd3bccdd
branch: master
revision: 8c87ae49648f4ca2c37313b0d9b9c561a10a71a2
branch: rails_6
specs:
canaid (1.0.4)
devise (~> 4.6.2)
canaid (1.0.3)
devise (>= 3.4.1)
docile (>= 1.1.0)
rails (~> 5.2.3)
rails (>= 4)
GIT
remote: https://github.com/biosistemika/jquery-scrollto-rails
revision: d1d40d5334e0bccfc64208ba81b9a7792f6cb591
revision: 7b09a7bd9dbf0bbee420c92be32d7ce2f75d0766
specs:
jquery-scrollto-rails (1.4.3)
railties (> 3.1, < 6.0)
railties (> 3.1, < 7.0)
GIT
remote: https://github.com/einzige/sneaky-save
@ -42,72 +42,85 @@ GIT
GEM
remote: http://rubygems.org/
specs:
actioncable (5.2.3)
actionpack (= 5.2.3)
actioncable (6.0.0)
actionpack (= 6.0.0)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
actionmailbox (6.0.0)
actionpack (= 6.0.0)
activejob (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
mail (>= 2.7.1)
actionmailer (6.0.0)
actionpack (= 6.0.0)
actionview (= 6.0.0)
activejob (= 6.0.0)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.3)
actionview (= 5.2.3)
activesupport (= 5.2.3)
actionpack (6.0.0)
actionview (= 6.0.0)
activesupport (= 6.0.0)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.3)
activesupport (= 5.2.3)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.0)
actionpack (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
nokogiri (>= 1.8.5)
actionview (6.0.0)
activesupport (= 6.0.0)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_model_serializers (0.10.10)
actionpack (>= 4.1, < 6.1)
activemodel (>= 4.1, < 6.1)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
activejob (5.2.3)
activesupport (= 5.2.3)
activejob (6.0.0)
activesupport (= 6.0.0)
globalid (>= 0.3.6)
activemodel (5.2.3)
activesupport (= 5.2.3)
activerecord (5.2.3)
activemodel (= 5.2.3)
activesupport (= 5.2.3)
arel (>= 9.0)
activemodel (6.0.0)
activesupport (= 6.0.0)
activerecord (6.0.0)
activemodel (= 6.0.0)
activesupport (= 6.0.0)
activerecord-import (1.0.2)
activerecord (>= 3.2)
activestorage (5.2.3)
actionpack (= 5.2.3)
activerecord (= 5.2.3)
activestorage (6.0.0)
actionpack (= 6.0.0)
activejob (= 6.0.0)
activerecord (= 6.0.0)
marcel (~> 0.3.1)
activesupport (5.2.3)
activesupport (6.0.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
zeitwerk (~> 2.1, >= 2.1.8)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
aes_key_wrap (1.0.1)
ajax-datatables-rails (0.3.1)
railties (>= 3.1)
arel (9.0.0)
aspector (0.14.0)
ast (2.4.0)
auto_strip_attributes (2.5.0)
activerecord (>= 4.0)
autoprefixer-rails (9.6.1)
autoprefixer-rails (9.6.1.1)
execjs
autosize-rails (1.18.17)
rails (>= 3.1)
awesome_print (1.8.0)
aws-eventstream (1.0.3)
aws-partitions (1.197.0)
aws-sdk-core (3.62.0)
aws-partitions (1.211.0)
aws-sdk-core (3.67.0)
aws-eventstream (~> 1.0, >= 1.0.2)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.1)
@ -118,7 +131,7 @@ GEM
aws-sdk-rails (2.1.0)
aws-sdk-ses (~> 1)
railties (>= 3)
aws-sdk-s3 (1.46.0)
aws-sdk-s3 (1.48.0)
aws-sdk-core (~> 3, >= 3.61.1)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
@ -137,7 +150,7 @@ GEM
bindata (2.4.4)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
bootsnap (1.4.4)
bootsnap (1.4.5)
msgpack (~> 1.0)
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
@ -147,11 +160,11 @@ GEM
momentjs-rails (>= 2.8.1)
bootstrap_form (2.7.0)
builder (3.2.3)
bullet (6.0.1)
bullet (6.0.2)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
byebug (11.0.1)
capybara (3.28.0)
capybara (3.29.0)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
@ -201,30 +214,30 @@ GEM
cucumber-tag_expressions (~> 1.1.0)
gherkin (~> 5.0)
cucumber-expressions (6.0.1)
cucumber-rails (1.7.0)
capybara (>= 2.3.0, < 4)
cucumber-rails (1.8.0)
capybara (>= 2.12, < 4)
cucumber (>= 3.0.2, < 4)
mime-types (>= 1.17, < 4)
mime-types (>= 2.0, < 4)
nokogiri (~> 1.8)
railties (>= 4.2, < 7)
cucumber-tag_expressions (1.1.1)
cucumber-wire (0.0.1)
database_cleaner (1.7.0)
debug_inspector (0.0.3)
deface (1.5.0)
deface (1.5.1)
nokogiri (>= 1.6)
polyglot
rails (>= 4.1)
rainbow (>= 2.1.0)
delayed_job (4.1.7)
activesupport (>= 3.0, < 5.3)
delayed_job_active_record (4.1.3)
activerecord (>= 3.0, < 5.3)
delayed_job (4.1.8)
activesupport (>= 3.0, < 6.1)
delayed_job_active_record (4.1.4)
activerecord (>= 3.0, < 6.1)
delayed_job (>= 3.0, < 5)
devise (4.6.2)
devise (4.7.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 6.0)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise_invitable (2.0.1)
@ -237,7 +250,7 @@ GEM
doorkeeper (5.1.0)
railties (>= 5)
erubi (1.8.0)
et-orbi (1.2.1)
et-orbi (1.2.2)
tzinfo
execjs (2.7.0)
factory_bot (5.0.2)
@ -245,15 +258,15 @@ GEM
factory_bot_rails (5.0.2)
factory_bot (~> 5.0.2)
railties (>= 4.2.0)
faker (1.9.3)
i18n (>= 0.7)
faker (2.2.2)
i18n (~> 1.6.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
fastimage (2.1.5)
fastimage (2.1.7)
ffi (1.11.1)
figaro (1.1.1)
thor (~> 0.14)
fugit (1.3.1)
fugit (1.3.3)
et-orbi (~> 1.1, >= 1.1.8)
raabro (~> 1.1)
gherkin (5.1.0)
@ -269,6 +282,9 @@ GEM
concurrent-ruby (~> 1.0)
i18n-js (3.3.0)
i18n (>= 0.6.6)
image_processing (1.9.3)
mini_magick (>= 4.9.5, < 5)
ruby-vips (>= 2.0.13, < 3)
iniparse (1.4.4)
jaro_winkler (1.5.3)
jbuilder (2.9.1)
@ -290,7 +306,7 @@ GEM
json_matchers (0.11.1)
json_schema
json_schema (0.20.7)
jsonapi-renderer (0.2.0)
jsonapi-renderer (0.2.2)
jwt (1.5.6)
kaminari (1.1.1)
activesupport (>= 4.1.0)
@ -321,7 +337,9 @@ GEM
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mime-types (1.25.1)
mime-types (3.3)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0904)
mimemagic (0.3.3)
mini_magick (4.9.5)
mini_mime (1.0.2)
@ -338,8 +356,8 @@ GEM
coffee-rails (>= 3.2.1)
jquery-rails
rails (>= 3.2.0)
newrelic_rpm (6.5.0.357)
nio4r (2.4.0)
newrelic_rpm (6.6.0.358)
nio4r (2.5.1)
nokogiri (1.10.4)
mini_portile2 (~> 2.4.0)
nokogumbo (2.0.1)
@ -362,7 +380,7 @@ GEM
actionpack (>= 4.2)
omniauth (>= 1.3.1)
orm_adapter (0.5.0)
overcommit (0.49.0)
overcommit (0.49.1)
childprocess (>= 0.6.3, < 2.0)
iniparse (~> 1.4)
paperclip (6.1.0)
@ -372,7 +390,7 @@ GEM
mimemagic (~> 0.3.0)
terrapin (~> 0.6.0)
parallel (1.17.0)
parser (2.6.3.0)
parser (2.6.4.0)
ast (~> 2.4.0)
pg (1.1.4)
pg_search (2.3.0)
@ -387,8 +405,8 @@ GEM
pry (~> 0.10)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (3.1.1)
puma (4.0.1)
public_suffix (4.0.1)
puma (4.1.1)
nio4r (~> 2.0)
raabro (1.1.6)
rack (2.0.7)
@ -398,18 +416,20 @@ GEM
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.3)
actioncable (= 5.2.3)
actionmailer (= 5.2.3)
actionpack (= 5.2.3)
actionview (= 5.2.3)
activejob (= 5.2.3)
activemodel (= 5.2.3)
activerecord (= 5.2.3)
activestorage (= 5.2.3)
activesupport (= 5.2.3)
rails (6.0.0)
actioncable (= 6.0.0)
actionmailbox (= 6.0.0)
actionmailer (= 6.0.0)
actionpack (= 6.0.0)
actiontext (= 6.0.0)
actionview (= 6.0.0)
activejob (= 6.0.0)
activemodel (= 6.0.0)
activerecord (= 6.0.0)
activestorage (= 6.0.0)
activesupport (= 6.0.0)
bundler (>= 1.3.0)
railties (= 5.2.3)
railties (= 6.0.0)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.4)
actionpack (>= 5.0.1.x)
@ -427,25 +447,25 @@ GEM
rails (> 3.1)
rails_serve_static_assets (0.0.5)
rails_stdout_logging (0.0.5)
railties (5.2.3)
actionpack (= 5.2.3)
activesupport (= 5.2.3)
railties (6.0.0)
actionpack (= 6.0.0)
activesupport (= 6.0.0)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
thor (>= 0.20.3, < 2.0)
rainbow (3.0.0)
rake (12.3.3)
rb-fsevent (0.10.3)
rb-inotify (0.10.0)
ffi (~> 1.0)
rdoc (6.1.1)
rdoc (6.2.0)
recaptcha (5.1.0)
json
regexp_parser (1.6.0)
responders (3.0.0)
actionpack (>= 5.0)
railties (>= 5.0)
rgl (0.5.4)
rgl (0.5.6)
lazy_priority_queue (~> 0.1.0)
stream (~> 0.5.2)
roo (2.8.2)
@ -459,14 +479,14 @@ GEM
rspec-mocks (3.8.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-rails (3.8.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-rails (4.0.0.beta2)
actionpack (>= 4.2)
activesupport (>= 4.2)
railties (>= 4.2)
rspec-core (~> 3.8)
rspec-expectations (~> 3.8)
rspec-mocks (~> 3.8)
rspec-support (~> 3.8)
rspec-support (3.8.2)
rubocop (0.74.0)
jaro_winkler (~> 1.5.1)
@ -479,12 +499,14 @@ GEM
rubocop (>= 0.71.0)
ruby-graphviz (1.2.4)
ruby-progressbar (1.10.1)
ruby-vips (2.0.15)
ffi (~> 1.9)
ruby_dep (1.5.0)
rubyzip (1.2.3)
rubyzip (1.2.4)
rufus-scheduler (3.6.0)
fugit (~> 1.1, >= 1.1.6)
safe_yaml (1.0.5)
sanitize (5.0.0)
sanitize (5.1.0)
crass (~> 1.0.2)
nokogiri (>= 1.8.0)
nokogumbo (~> 2.0)
@ -493,9 +515,8 @@ GEM
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sassc (2.0.1)
sassc (2.2.0)
ffi (~> 1.9)
rake
sassc-rails (2.1.2)
railties (>= 4.0.0)
sassc (>= 2.0)
@ -513,9 +534,9 @@ GEM
shoulda-matchers (4.1.2)
activesupport (>= 4.2.0)
silencer (1.0.1)
simple_token_authentication (1.15.1)
actionmailer (>= 3.2.6, < 6)
actionpack (>= 3.2.6, < 6)
simple_token_authentication (1.16.0)
actionmailer (>= 3.2.6, < 7)
actionpack (>= 3.2.6, < 7)
devise (>= 3.2, < 6)
simplecov (0.17.0)
docile (~> 1.1)
@ -552,7 +573,7 @@ GEM
uniform_notifier (1.12.1)
warden (1.2.8)
rack (>= 2.0.6)
webmock (3.6.2)
webmock (3.7.2)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@ -568,9 +589,8 @@ GEM
wkhtmltopdf-heroku (2.12.4.0)
xpath (3.2.0)
nokogiri (~> 1.8)
yomu (0.2.4)
json (~> 1.8)
mime-types (~> 1.23)
yomu (0.1.5)
zeitwerk (2.1.10)
PLATFORMS
ruby
@ -606,7 +626,7 @@ DEPENDENCIES
deface (~> 1.0)
delayed_job_active_record
delayed_paperclip!
devise (~> 4.6.2)
devise (~> 4.7.1)
devise-async!
devise_invitable
discard (~> 1.0)
@ -618,6 +638,7 @@ DEPENDENCIES
hammerjs-rails
httparty (~> 0.13.1)
i18n-js (~> 3.0)
image_processing (~> 1.2)
jbuilder
jquery-rails
jquery-scrollto-rails!
@ -625,12 +646,11 @@ DEPENDENCIES
js_cookie_rails
json-jwt
json_matchers
jsonapi-renderer (= 0.2.0)
jsonapi-renderer (~> 0.2.2)
jwt (~> 1.5)
kaminari
listen (~> 3.0)
logging (~> 2.0.0)
mini_magick
momentjs-rails (~> 2.17.1)
nested_form_fields
newrelic_rpm
@ -647,14 +667,14 @@ DEPENDENCIES
pry-rails
puma
rack-attack
rails (~> 5.2.3)
rails (~> 6.0.0)
rails-controller-testing
rails_12factor
rails_autolink (~> 1.1, >= 1.1.6)
recaptcha
rgl
roo (~> 2.8.2)
rspec-rails
rspec-rails (>= 4.0.0.beta2)
rubocop (>= 0.59.0)
rubocop-performance
ruby-graphviz (~> 1.2)
@ -667,7 +687,7 @@ DEPENDENCIES
selenium-webdriver
shoulda-matchers
silencer
simple_token_authentication (~> 1.15.1)
simple_token_authentication (~> 1.16.0)
simplecov
sneaky-save!
spinjs-rails
@ -685,7 +705,7 @@ DEPENDENCIES
yomu
RUBY VERSION
ruby 2.6.3p62
ruby 2.6.4p104
BUNDLED WITH
1.17.3

View file

@ -3,6 +3,8 @@
# The base controller for all ActiveStorage controllers.
module ActiveStorage
class BaseController < ApplicationController
include ActiveStorage::SetCurrent
before_action do
ActiveStorage::Current.host = request.base_url
end

View file

@ -6,7 +6,7 @@ module ActiveStorage
include ActiveStorage::CheckBlobPermissions
def show
expires_in ActiveStorage::Blob.service.url_expires_in
expires_in ActiveStorage.service_urls_expire_in
redirect_to @blob.service_url(disposition: params[:disposition])
end
end

View file

@ -6,7 +6,7 @@ module ActiveStorage
include ActiveStorage::CheckBlobPermissions
def show
expires_in ActiveStorage::Blob.service.url_expires_in
expires_in ActiveStorage.service_urls_expire_in
redirect_to @blob.representation(params[:variation_key]).processed.service_url(disposition: params[:disposition])
end
end

View file

@ -91,7 +91,7 @@ class ExperimentsController < ApplicationController
end
old_text = @experiment.description
@experiment.update_attributes(experiment_params)
@experiment.update(experiment_params)
@experiment.last_modified_by = current_user
if @experiment.save

View file

@ -97,7 +97,7 @@ class RepositoriesController < ApplicationController
def update
old_name = @repository.name
@repository.update_attributes(repository_params)
@repository.update(repository_params)
respond_to do |format|
format.json do

View file

@ -87,7 +87,7 @@ class RepositoryColumnsController < ApplicationController
def update
respond_to do |format|
format.json do
@repository_column.update_attributes(repository_column_params)
@repository_column.update(repository_column_params)
if @repository_column.save
log_activity(:edit_column_inventory)

View file

@ -492,7 +492,7 @@ class StepsController < ApplicationController
update_params = {}
delete_step_tables(params)
extract_destroy_params(params, update_params)
@step.update_attributes(update_params) unless update_params.empty?
@step.update(update_params) unless update_params.empty?
end
# Delete the step table

View file

@ -73,7 +73,7 @@ class TagsController < ApplicationController
def update
@tag.last_modified_by = current_user
if @tag.update_attributes(tag_params)
if @tag.update(tag_params)
log_activity(:edit_tag, @tag.project, tag: @tag.id, project: @tag.project.id)
respond_to do |format|
format.html

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true
class Asset < ApplicationRecord
include ActiveStorage::Downloading
include SearchableModel
include DatabaseHelper
include Encryptor
@ -199,15 +198,15 @@ class Asset < ApplicationRecord
end
def medium_preview
return file.variant(resize: Constants::MEDIUM_PIC_FORMAT) if previewable_image?
return file.variant(resize_to_limit: Constants::MEDIUM_PIC_FORMAT) if previewable_image?
file.preview(resize: Constants::MEDIUM_PIC_FORMAT)
file.preview(resize_to_limit: Constants::MEDIUM_PIC_FORMAT)
end
def large_preview
return file.variant(resize: Constants::LARGE_PIC_FORMAT) if previewable_image?
return file.variant(resize_to_limit: Constants::LARGE_PIC_FORMAT) if previewable_image?
file.preview(resize: Constants::LARGE_PIC_FORMAT)
file.preview(resize_to_limit: Constants::LARGE_PIC_FORMAT)
end
def file_name

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
class SystemNotification < ApplicationRecord
include PgSearch
include PgSearch::Model
scope :modals, -> { select(:modal_title, :modal_body, :id) }
# Full text postgreSQL search configuration

View file

@ -1,11 +1,10 @@
# frozen_string_literal: true
class TinyMceAsset < ApplicationRecord
include ActiveStorage::Downloading
extend ProtocolsExporter
extend MarvinJsActions
attr_accessor :reference
before_create :set_reference, optional: true
before_create :set_reference
after_create :calculate_estimated_size, :self_destruct
after_destroy :release_team_space
@ -98,7 +97,7 @@ class TinyMceAsset < ApplicationRecord
end
def preview
image.variant(resize: Constants::LARGE_PIC_FORMAT)
image.variant(resize_to_limit: Constants::LARGE_PIC_FORMAT)
end
def self.delete_unsaved_image(id)

View file

@ -8,7 +8,6 @@ class User < ApplicationRecord
include User::ProjectRoles
include TeamBySubjectModel
include InputSanitizeHelper
include ActiveStorage::Downloading
include ImageVariantProcessing
acts_as_token_authenticatable
@ -264,7 +263,7 @@ class User < ApplicationRecord
else
Constants::ICON_SMALL_PIC_FORMAT
end
avatar.variant(resize: format)
avatar.variant(resize_to_limit: format)
end
def avatar_url(style)

View file

@ -2,9 +2,11 @@
# archived (for restore permissions) or active (for all other permissions) -
# now we mostly do the check only for the permission level for which the
# permission was made
Canaid::Permissions.register_generic do
# organization: create team
can :create_teams do |_|
true
module Organization
Canaid::Permissions.register_generic do
# organization: create team
can :create_teams do |_|
true
end
end
end

View file

@ -28,8 +28,7 @@ module ActiveStorage
# Wraps the Amazon Simple Storage Service (S3) as an Active Storage service.
# See ActiveStorage::Service for the generic API documentation that applies to all services.
class Service::CustomS3Service < Service
attr_reader :client, :bucket
attr_reader :multipart_upload_threshold, :upload_options
attr_reader :client, :bucket, :upload_options
attr_reader :subfolder
def initialize(bucket:, upload: {}, **options)
@ -38,17 +37,14 @@ module ActiveStorage
@client = Aws::S3::Resource.new(**options)
@bucket = @client.bucket(bucket)
@multipart_upload_threshold = upload.fetch(:multipart_threshold, 100.megabytes)
@upload_options = upload
end
def upload(key, io, checksum: nil, content_type: nil, **)
instrument :upload, key: key, checksum: checksum do
if io.size < multipart_upload_threshold
upload_with_single_part key, io, checksum: checksum, content_type: content_type
else
upload_with_multipart key, io, content_type: content_type
end
object_for(key).put(upload_options.merge(body: io, content_md5: checksum, content_type: content_type))
rescue Aws::S3::Errors::BadDigest
raise ActiveStorage::IntegrityError
end
end
@ -60,6 +56,8 @@ module ActiveStorage
else
instrument :download, key: key do
object_for(key).get.body.string.force_encoding(Encoding::BINARY)
rescue Aws::S3::Errors::NoSuchKey
raise ActiveStorage::FileNotFoundError
end
end
end
@ -68,8 +66,10 @@ module ActiveStorage
instrument :download_chunk, key: key, range: range do
object_for(key).get(range: "bytes=#{range.begin}-#{range.exclude_end? ? range.end - 1 : range.end}")
.body
.string
.read
.force_encoding(Encoding::BINARY)
rescue Aws::S3::Errors::NoSuchKey
raise ActiveStorage::FileNotFoundError
end
end
@ -81,7 +81,6 @@ module ActiveStorage
def delete_prefixed(prefix)
instrument :delete_prefixed, prefix: prefix do
prefix = subfolder.present? ? File.join(subfolder, prefix) : prefix
bucket.objects(prefix: prefix).batch_delete!
end
end
@ -107,11 +106,10 @@ module ActiveStorage
end
def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:)
raise ActiveStorage::IntegrityError if content_length > Rails.configuration.x.file_max_size_mb.megabytes
instrument :url, key: key do |payload|
generated_url = object_for(key).presigned_url :put, expires_in: expires_in.to_i,
content_type: content_type, content_length: content_length, content_md5: checksum
content_type: content_type, content_length: content_length, content_md5: checksum,
whitelist_headers: ['content-length']
payload[:url] = generated_url
@ -119,7 +117,7 @@ module ActiveStorage
end
end
def headers_for_direct_upload(_key, content_type:, checksum:, **)
def headers_for_direct_upload(_, content_type:, checksum:, **)
{ 'Content-Type' => content_type, 'Content-MD5' => checksum }
end
@ -129,23 +127,6 @@ module ActiveStorage
private
MAXIMUM_UPLOAD_PARTS_COUNT = 10000
MINIMUM_UPLOAD_PART_SIZE = 5.megabytes
def upload_with_single_part(key, io, checksum: nil, content_type: nil)
object_for(key).put(body: io, content_md5: checksum, content_type: content_type, **upload_options)
rescue Aws::S3::Errors::BadDigest
raise ActiveStorage::IntegrityError
end
def upload_with_multipart(key, io, content_type: nil)
part_size = [io.size.fdiv(MAXIMUM_UPLOAD_PARTS_COUNT).ceil, MINIMUM_UPLOAD_PART_SIZE].max
object_for(key).upload_stream(content_type: content_type, part_size: part_size, **upload_options) do |out|
IO.copy_stream(io, out)
end
end
def object_for(key)
key = subfolder.present? ? File.join(subfolder, key) : key
bucket.object(key)
@ -158,25 +139,12 @@ module ActiveStorage
chunk_size = 5.megabytes
offset = 0
raise ActiveStorage::FileNotFoundError unless object.exists?
while offset < object.content_length
yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}")
.body
.string
.force_encoding(Encoding::BINARY)
yield object.get(range: "bytes=#{offset}-#{offset + chunk_size - 1}").body.read.force_encoding(Encoding::BINARY)
offset += chunk_size
end
end
end
module S3SignerModifier
def build_signer(cfg)
signer = super(cfg)
signer.unsigned_headers.delete('content-length')
signer
end
end
Aws::S3::Presigner.class_eval do
prepend S3SignerModifier
end
end

View file

@ -26,7 +26,7 @@ module ClientApi
def update_team!
raise ClientApi::CustomTeamError unless @params
return if @team.update_attributes(@params)
return if @team.update(@params)
raise ClientApi::CustomTeamError, @team.errors.full_messages
end

View file

@ -91,7 +91,7 @@ module Notifications
if n.new_record?
save_notification n
elsif n.last_time_changed_at < attrs[:last_time_changed_at]
n.update_attributes!(attrs)
n.update!(attrs)
end
end
end

View file

@ -2,7 +2,6 @@
module ProtocolImporters
class BuildProtocolFromClientService
require 'protocol_importers/protocols_io/v3/errors'
extend Service
attr_reader :errors, :built_protocol, :steps_assets

View file

@ -3,7 +3,6 @@
module ProtocolImporters
class SearchProtocolsService
extend Service
require 'protocol_importers/protocols_io/v3/errors'
attr_reader :errors, :protocols_list

View file

@ -3,13 +3,8 @@
class SpreadsheetParser
# Based on file's extension opens file (used for importing)
def self.open_spreadsheet(file)
if file.class == ActionDispatch::Http::UploadedFile
filename = file.original_filename
file_path = file.path
else
filename = file.filename.to_s
file_path = file.service_url
end
filename = file.original_filename
file_path = file.path
case File.extname(filename)
when '.csv'

View file

@ -335,33 +335,32 @@ class TeamImporter
tiny_mce_asset = TinyMceAsset.new(tiny_mce_asset_json['tiny_mce_asset'])
tiny_mce_asset_blob = tiny_mce_asset_json['tiny_mce_asset_blob']
# Try to find and load file
File.open(
File.join(@import_dir, 'tiny_mce_assets', tiny_mce_asset.id.to_s,
tiny_mce_asset_blob['filename'])
) do |tiny_mce_file|
orig_tmce_id = tiny_mce_asset.id
tiny_mce_asset.id = nil
if tiny_mce_asset.object_id.present?
mappings = instance_variable_get("@#{tiny_mce_asset.object_type.underscore}_mappings")
tiny_mce_asset.object_id = mappings[tiny_mce_asset.object_id]
end
tiny_mce_asset.team = team
tiny_mce_asset.save!
tiny_mce_asset.image.attach(io: tiny_mce_file, filename: File.basename(tiny_mce_file))
@mce_asset_counter += 1
if tiny_mce_asset.object_id.present?
object = tiny_mce_asset.object
object_field = Extends::RICH_TEXT_FIELD_MAPPINGS[object.class.name]
encoded_id = Base62.encode(tiny_mce_asset.id)
object.public_send(object_field).sub!("data-mce-token=\"#{Base62.encode(orig_tmce_id)}\"",
"data-mce-token=\"#{encoded_id}\"")
# Check for old fields
new_asset_format = "<img src=\"\" class=\"img-responsive\" data-mce-token=\"#{encoded_id}\"/>"
object.public_send(object_field).sub!("[~tiny_mce_id:#{orig_tmce_id}]",
new_asset_format)
object.save!
end
tiny_mce_file = File.open(File.join(@import_dir,
'tiny_mce_assets',
tiny_mce_asset.id.to_s,
tiny_mce_asset_blob['filename']))
orig_tmce_id = tiny_mce_asset.id
tiny_mce_asset.id = nil
if tiny_mce_asset.object_id.present?
mappings = instance_variable_get("@#{tiny_mce_asset.object_type.underscore}_mappings")
tiny_mce_asset.object_id = mappings[tiny_mce_asset.object_id]
end
tiny_mce_asset.team = team
tiny_mce_asset.save!
tiny_mce_asset.image.attach(io: tiny_mce_file, filename: File.basename(tiny_mce_file))
@mce_asset_counter += 1
next unless tiny_mce_asset.object_id.present?
object = tiny_mce_asset.object
object_field = Extends::RICH_TEXT_FIELD_MAPPINGS[object.class.name]
encoded_id = Base62.encode(tiny_mce_asset.id)
object.public_send(object_field).sub!("data-mce-token=\"#{Base62.encode(orig_tmce_id)}\"",
"data-mce-token=\"#{encoded_id}\"")
# Check for old fields
new_asset_format = "<img src=\"\" class=\"img-responsive\" data-mce-token=\"#{encoded_id}\"/>"
object.public_send(object_field).sub!("[~tiny_mce_id:#{orig_tmce_id}]",
new_asset_format)
object.save!
end
end
@ -806,22 +805,19 @@ class TeamImporter
else
asset_json['file_file_name']
end
File.open(
"#{@import_dir}/assets/#{asset.id}/#{asset_file_name}"
) do |file|
orig_asset_id = asset.id
asset.id = nil
asset.created_by_id = user_id || find_user(asset.created_by_id)
asset.last_modified_by_id =
user_id || find_user(asset.last_modified_by_id)
asset.team = team
asset.in_template = true if @is_template
asset.save!
asset.file.attach(io: file, filename: File.basename(file))
asset.post_process_file(team)
@asset_mappings[orig_asset_id] = asset.id
@asset_counter += 1
end
file = File.open("#{@import_dir}/assets/#{asset.id}/#{asset_file_name}")
orig_asset_id = asset.id
asset.id = nil
asset.created_by_id = user_id || find_user(asset.created_by_id)
asset.last_modified_by_id =
user_id || find_user(asset.last_modified_by_id)
asset.team = team
asset.in_template = true if @is_template
asset.save!
asset.file.attach(io: file, filename: File.basename(file))
asset.post_process_file(team)
@asset_mappings[orig_asset_id] = asset.id
@asset_counter += 1
asset
end

View file

@ -43,7 +43,7 @@ class UserDataDeletion
my_module.user_my_modules.destroy_all
my_module.report_elements.destroy_all
my_module.sample_my_modules.destroy_all
my_module.protocols.each { |p| p.update_attributes(parent_id: nil) }
my_module.protocols.each { |p| p.update(parent_id: nil) }
my_module.protocols.each do |protocol|
destroy_protocol(protocol)
end
@ -65,7 +65,7 @@ class UserDataDeletion
project.delete
end
team.protocols.each { |p| p.update_attributes(parent_id: nil) }
team.protocols.each { |p| p.update(parent_id: nil) }
team.protocols.where(my_module: nil).each do |protocol|
destroy_protocol(protocol)
end

View file

@ -6,11 +6,9 @@ module ProtocolImporters
return [] unless step_json[:attachments]&.any?
step_json[:attachments].map do |f|
Asset.new(file: URI.parse(f[:url]),
created_by: user,
last_modified_by: user,
team: team,
file_file_name: f[:name])
asset = Asset.new(created_by: user, last_modified_by: user, team: team)
asset.file.attach(io: URI.open(f[:url]), filename: f[:name])
asset
end
end

View file

@ -1,11 +1,10 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIO
module ProtocolsIo
module V3
class ApiClient
include HTTParty
require 'protocol_importers/protocols_io/v3/errors'
CONSTANTS = Constants::PROTOCOLS_IO_V3_API
@ -89,7 +88,7 @@ module ProtocolImporters
rescue StandardError => e
Rails.logger.error "Error: #{e.class}, message: #{e.message}"
raise ProtocolImporters::ProtocolsIO::V3::NetworkError.new(e.class),
raise ProtocolImporters::ProtocolsIo::V3::NetworkError.new(e.class),
I18n.t('protocol_importers.errors.cannot_import_protocol')
end
@ -100,13 +99,13 @@ module ProtocolImporters
when 0
return response
when 1
raise ProtocolImporters::ProtocolsIO::V3::ArgumentError.new(:missing_or_empty_parameters), error_message
raise ProtocolImporters::ProtocolsIo::V3::ArgumentError.new(:missing_or_empty_parameters), error_message
when 1218
raise ProtocolImporters::ProtocolsIO::V3::UnauthorizedError.new(:invalid_token), error_message
raise ProtocolImporters::ProtocolsIo::V3::UnauthorizedError.new(:invalid_token), error_message
when 1219
raise ProtocolImporters::ProtocolsIO::V3::UnauthorizedError.new(:token_expires), error_message
raise ProtocolImporters::ProtocolsIo::V3::UnauthorizedError.new(:token_expires), error_message
else
raise ProtocolImporters::ProtocolsIO::V3::Error.new(:api_response_error), response.parsed_response
raise ProtocolImporters::ProtocolsIo::V3::Error.new(:api_response_error), response.parsed_response
end
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIo
module V3
# MissingOrEmptyParameters
class ArgumentError < Error; end
end
end
end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIO
module ProtocolsIo
module V3
class Error < StandardError
attr_reader :error_type

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIo
module V3
# SocketError, HTTPParty::Error
class NetworkError < Error; end
end
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIo
module V3
# General NormalizerError
class NormalizerError < Error; end
end
end
end

View file

@ -1,11 +1,9 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIO
module ProtocolsIo
module V3
class ProtocolNormalizer < ProtocolImporters::ProtocolNormalizer
require 'protocol_importers/protocols_io/v3/errors'
def normalize_protocol(client_data)
# client_data is HttpParty ApiReponse object
protocol_hash = client_data.parsed_response.with_indifferent_access[:protocol]
@ -67,7 +65,7 @@ module ProtocolImporters
{ protocol: normalized_data }
rescue StandardError => e
raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
raise ProtocolImporters::ProtocolsIo::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
end
def normalize_list(client_data)
@ -108,7 +106,7 @@ module ProtocolImporters
normalized_data
rescue StandardError => e
raise ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
raise ProtocolImporters::ProtocolsIo::V3::NormalizerError.new(e.class.to_s.downcase.to_sym), e.message
end
end
end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIO
module ProtocolsIo
module V3
class StepComponents
AVAILABLE_COMPONENTS = {

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
module ProtocolImporters
module ProtocolsIo
module V3
# InvalidToken, ExpiredToken
class UnauthorizedError < Error; end
end
end
end

View file

@ -0,0 +1,10 @@
class UserSubdomain
def self.matches?(request)
if ENV['USER_SUBDOMAIN']
return (request.subdomain.present? &&
request.subdomain == ENV['USER_SUBDOMAIN'])
else
return true
end
end
end

View file

@ -1,14 +1,3 @@
class UserSubdomain
def self.matches?(request)
if ENV['USER_SUBDOMAIN']
return (request.subdomain.present? &&
request.subdomain == ENV['USER_SUBDOMAIN'])
else
return true
end
end
end
class WopiSubdomain
def self.matches?(request)
if ENV['WOPI_ENABLED'] == 'true'

View file

@ -1,6 +1,5 @@
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)
@ -9,24 +8,25 @@ def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a starting point to setup your application.
FileUtils.chdir APP_ROOT do
# This script is a way to setup or update your development environment automatically.
# This script is idempotent, so that you can run it at anytime and get an expectable outcome.
# Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# Install JavaScript dependencies if using Yarn
# Install JavaScript dependencies
# system('bin/yarn')
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
# FileUtils.cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
system! 'bin/rails db:setup'
system! 'bin/rails db:prepare'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'

View file

@ -9,7 +9,7 @@ Bundler.require(*Rails.groups)
module Scinote
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.load_defaults '6.0'
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers

View file

@ -2,7 +2,7 @@ development:
adapter: async
test:
adapter: async
adapter: test
production:
adapter: redis

View file

@ -2,3 +2,7 @@
Rails.application.config.active_storage.previewers = [ActiveStorage::Previewer::PopplerPDFPreviewer,
ActiveStorage::Previewer::LibreofficePreviewer]
Rails.application.config.active_storage.variable_content_types << 'image/svg+xml'
Rails.application.config.active_storage.variant_processor = :vips

View file

@ -91,11 +91,11 @@ class Constants
#=============================================================================
# Picture size formats
LARGE_PIC_FORMAT = '800x600>'.freeze
MEDIUM_PIC_FORMAT = '300x300>'.freeze
THUMB_PIC_FORMAT = '100x100'.freeze
ICON_PIC_FORMAT = '40x40'.freeze
ICON_SMALL_PIC_FORMAT = '30x30'.freeze
LARGE_PIC_FORMAT = [800, 600].freeze
MEDIUM_PIC_FORMAT = [300, 300].freeze
THUMB_PIC_FORMAT = [100, 100].freeze
ICON_PIC_FORMAT = [40, 40].freeze
ICON_SMALL_PIC_FORMAT = [30, 30].freeze
# Hands-on-table number of starting columns and rows
HANDSONTABLE_INIT_COLS_CNT = 5
@ -217,7 +217,7 @@ class Constants
PROTOCOLS_ENDPOINTS = {
protocolsio: {
v3: 'ProtocolsIO::V3'
v3: 'ProtocolsIo::V3'
}
}.freeze

View file

@ -11,6 +11,8 @@
# policy.object_src :none
# policy.script_src :self, :https
# policy.style_src :self, :https
# # If you are using webpack-dev-server then specify webpack-dev-server host
# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
# # Specify URI for violation reports
# # policy.report_uri "/csp-violation-report-endpoint"
@ -19,6 +21,9 @@
# If you are using UJS then enable automatic nonce generation
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Set the nonce only to specific directives
# Rails.application.config.content_security_policy_nonce_directives = %w(script-src)
# Report CSP violations to a specified URI
# For further information see the following documentation:
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only

View file

@ -0,0 +1,16 @@
# Be sure to restart your server when you modify this file.
# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.
# Read more: https://github.com/cyu/rack-cors
# Rails.application.config.middleware.insert_before 0, Rack::Cors do
# allow do
# origins 'example.com'
#
# resource '*',
# headers: :any,
# methods: [:get, :post, :put, :patch, :delete, :options, :head]
# end
# end

View file

@ -0,0 +1,45 @@
# Be sure to restart your server when you modify this file.
#
# This file contains migration options to ease your Rails 6.0 upgrade.
#
# Once upgraded flip defaults one by one to migrate to the new default.
#
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
# Don't force requests from old versions of IE to be UTF-8 encoded.
# Rails.application.config.action_view.default_enforce_utf8 = false
# Embed purpose and expiry metadata inside signed and encrypted
# cookies for increased security.
#
# This option is not backwards compatible with earlier Rails versions.
# It's best enabled when your entire app is migrated and stable on 6.0.
# Rails.application.config.action_dispatch.use_cookies_with_metadata = true
# Change the return value of `ActionDispatch::Response#content_type` to Content-Type header without modification.
# Rails.application.config.action_dispatch.return_only_media_type_on_content_type = false
# Return false instead of self when enqueuing is aborted from a callback.
# Rails.application.config.active_job.return_false_on_aborted_enqueue = true
# Send Active Storage analysis and purge jobs to dedicated queues.
# Rails.application.config.active_storage.queues.analysis = :active_storage_analysis
# Rails.application.config.active_storage.queues.purge = :active_storage_purge
# When assigning to a collection of attachments declared via `has_many_attached`, replace existing
# attachments instead of appending. Use #attach to add new attachments without replacing existing ones.
# Rails.application.config.active_storage.replace_on_assign_to_many = true
# Use ActionMailer::MailDeliveryJob for sending parameterized and normal mail.
#
# The default delivery jobs (ActionMailer::Parameterized::DeliveryJob, ActionMailer::DeliveryJob),
# will be removed in Rails 6.1. This setting is not backwards compatible with earlier Rails versions.
# If you send mail in the background, job workers need to have a copy of
# MailDeliveryJob to ensure all delivery jobs are processed properly.
# Make sure your entire app is migrated and stable on 6.0 before using this setting.
# Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"
# Enable the same cache key to be reused when the object being cached of type
# `ActiveRecord::Relation` changes by moving the volatile information (max updated at and count)
# of the relation's cache key into the cache version to support recycling cache key.
# Rails.application.config.active_record.collection_cache_versioning = true

View file

@ -2188,4 +2188,4 @@ en:
new_button: "Create Chemical Drawing"
structure_placeholder: "Click here to enter Chemical Drawing name"
modal_name_title: "Chemical Drawing name:"
checmical_drawing: "Chemical drawings"
checmical_drawing: "Chemical drawings"

View file

@ -2,29 +2,19 @@ Rails.application.routes.draw do
use_doorkeeper do
skip_controllers :applications, :authorized_applications, :token_info
end
require 'subdomain'
def draw(routes_name)
instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
end
constraints UserSubdomain do
devise_for :users,
controllers: { registrations: 'users/registrations',
sessions: 'users/sessions',
invitations: 'users/invitations',
confirmations: 'users/confirmations',
omniauth_callbacks: 'users/omniauth_callbacks' }
devise_for :users, controllers: { registrations: 'users/registrations',
sessions: 'users/sessions',
invitations: 'users/invitations',
confirmations: 'users/confirmations',
omniauth_callbacks: 'users/omniauth_callbacks' }
devise_scope :user do
authenticated :user do
root 'projects#index'
end
unauthenticated do
root 'users/sessions#new'
end
end
root 'projects#index'
# # Client APP endpoints
# get '/settings', to: 'client_api/settings#index'

View file

@ -0,0 +1,10 @@
# This migration comes from active_storage (originally 20180723000244)
class AddForeignKeyConstraintToActiveStorageAttachmentsForBlobId < ActiveRecord::Migration[6.0]
def up
return if foreign_key_exists?(:active_storage_attachments, column: :blob_id)
if table_exists?(:active_storage_blobs)
add_foreign_key :active_storage_attachments, :active_storage_blobs, column: :blob_id
end
end
end

View file

@ -2,15 +2,15 @@
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
# This file is the source Rails uses to define your schema when running `rails
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2019_06_13_134100) do
ActiveRecord::Schema.define(version: 2019_09_10_125740) do
# These are extensions that must be enabled in order to support this database
enable_extension "btree_gist"

View file

@ -108,7 +108,7 @@ namespace :samples_to_repository_migration do
# Update report elements
team.reports.each do |r|
r.report_elements.where(type_of: 7).each do |e|
e.update_attributes(type_of: 17, repository_id: repository.id)
e.update(type_of: 17, repository_id: repository.id)
end
end

View file

@ -7,7 +7,6 @@ describe Api::ApiController, type: :controller do
end
it 'Returns HTTP success' do
expect(response).to be_success
expect(response).to have_http_status(200)
end
@ -36,7 +35,6 @@ describe Api::ApiController, type: :controller do
end
it 'Returns HTTP success' do
expect(response).to be_success
expect(response).to have_http_status(200)
end

View file

@ -34,7 +34,7 @@ describe ClientApi::Users::InvitationsController, type: :controller, broken: tru
format: :json
expect(response).to_not be_success
expect(response).to have_http_status(:unprocessable_entity)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end

View file

@ -46,7 +46,7 @@ describe ExternalProtocolsController, type: :controller do
it 'returns JSON, 200 response when protocol parsing was valid' do
action
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
it 'contains html key in the response' do
@ -79,17 +79,17 @@ describe ExternalProtocolsController, type: :controller do
end
it 'returns JSON, 200 response when preview was successfully returned' do
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_html_preview)).and_return(html_preview)
# Call action
action
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
it 'should return html preview in the JSON' do
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_html_preview)).and_return(html_preview)
# Call action
@ -98,7 +98,7 @@ describe ExternalProtocolsController, type: :controller do
end
it 'returns error JSON and 400 response when something went wrong' do
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_html_preview)).and_raise(StandardError)
# Call action
@ -139,7 +139,7 @@ describe ExternalProtocolsController, type: :controller do
it 'returns JSON, 200 response when protocol parsing was valid' do
action
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
it 'should return html form in the JSON' do
@ -160,7 +160,7 @@ describe ExternalProtocolsController, type: :controller do
# Call action
action
expect(response).to have_http_status(:bad_request)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
@ -189,7 +189,7 @@ describe ExternalProtocolsController, type: :controller do
# Call action
action
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
it 'returns JSON, 400 response when protocol parsing was invalid' do
@ -203,7 +203,7 @@ describe ExternalProtocolsController, type: :controller do
# Call action
action
expect(response).to have_http_status(:bad_request)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end

View file

@ -71,7 +71,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :index, params: params, format: :json
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end
@ -85,7 +85,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :index_dt, params: params, format: :json
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end
@ -97,7 +97,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :archive, params: params, format: :json
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end
@ -113,10 +113,10 @@ describe ProjectsController, type: :controller do
it 'returns success response, then unprocessable_entity on second run' do
get :create, params: params, format: :json
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
get :create, params: params, format: :json
expect(response).to have_http_status(:unprocessable_entity)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
it 'calls create activity for creating project' do
@ -141,7 +141,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :edit, params: params, format: :json
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end
@ -158,7 +158,7 @@ describe ProjectsController, type: :controller do
it 'returns redirect response' do
action
expect(response).to have_http_status(:redirect)
expect(response.content_type).to eq 'text/html'
expect(response.media_type).to eq 'text/html'
end
it 'calls create activity service (change_project_visibility)' do
@ -209,7 +209,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :show, params: params
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'text/html'
expect(response.media_type).to eq 'text/html'
end
end
end
@ -225,7 +225,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :notifications, format: :json, params: params
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'application/json'
expect(response.media_type).to eq 'application/json'
end
end
end
@ -241,7 +241,7 @@ describe ProjectsController, type: :controller do
it 'returns success response' do
get :experiment_archive, params: params
expect(response).to have_http_status(:success)
expect(response.content_type).to eq 'text/html'
expect(response.media_type).to eq 'text/html'
end
end
end

View file

@ -3,7 +3,7 @@
FactoryBot.define do
factory :activity do
type_of { :create_project }
message { Faker::Lorem.sentence(10) }
message { Faker::Lorem.sentence(word_count: 10) }
subject { create :project }
owner { create :user }
team

View file

@ -2,7 +2,7 @@
FactoryBot.define do
factory :checklist_item do
text { Faker::Lorem.sentence(10) }
text { Faker::Lorem.sentence(word_count: 10) }
checklist
checked { false }
end

View file

@ -3,8 +3,8 @@
FactoryBot.define do
factory :my_module do
sequence(:name) { |n| "Task-#{n}" }
x { Faker::Number.between(1, 100) }
y { Faker::Number.between(1, 100) }
x { Faker::Number.between(from: 1, to: 100) }
y { Faker::Number.between(from: 1, to: 100) }
workflow_order { MyModule.where(experiment_id: experiment.id).count + 1 }
experiment
my_module_group { create :my_module_group, experiment: experiment }
@ -12,7 +12,7 @@ FactoryBot.define do
tags { create_list :tag, 3, project: experiment.project }
end
trait :with_due_date do
due_date { Faker::Time.between(Date.today, Date.today + 10.days) }
due_date { Faker::Time.between(from: Date.today, to: Date.today + 10.days) }
end
end
end

View file

@ -3,7 +3,7 @@
FactoryBot.define do
factory :step do
name { Faker::Name.unique.name }
position { Faker::Number.between(1, 10) }
position { Faker::Number.between(from: 1, to: 10) }
completed { true }
user
protocol

View file

@ -5,8 +5,8 @@ FactoryBot.define do
sequence(:title) { |n| "System notification #{n}" }
description { Faker::ChuckNorris.fact[0..255] }
modal_title { Faker::Name.first_name }
modal_body { Faker::Lorem.paragraphs(4).map { |pr| "<p>#{pr}</p>" }.join }
source_created_at { Faker::Time.between(3.days.ago, Date.today) }
modal_body { Faker::Lorem.paragraphs(number: 4).map { |pr| "<p>#{pr}</p>" }.join }
source_created_at { Faker::Time.between(from: 3.days.ago, to: Date.today) }
source_id { SystemNotification.order(source_id: :desc).first&.source_id.to_i + 1 }
last_time_changed_at { Time.now }
trait :show_on_login do

View file

@ -2,6 +2,6 @@
FactoryBot.define do
factory :temp_file do
session_id { Faker::Lorem.characters(20) }
session_id { Faker::Lorem.characters(number: 20) }
end
end

View file

@ -2,7 +2,7 @@
FactoryBot.define do
factory :token do
token { Faker::Lorem.characters(100) }
token { Faker::Lorem.characters(number: 100) }
ttl { 60 }
user
end

View file

@ -5,14 +5,14 @@ FactoryBot.define do
user
system_notification
trait :seen do
seen_at { Faker::Time.between(3.days.ago, Date.today) }
seen_at { Faker::Time.between(from: 3.days.ago, to: Date.today) }
end
trait :read do
read_at { Faker::Time.between(3.days.ago, Date.today) }
read_at { Faker::Time.between(from: 3.days.ago, to: Date.today) }
end
trait :seen_and_read do
seen_at { Faker::Time.between(3.days.ago, Date.today) }
read_at { Faker::Time.between(seen_at, Date.today) }
seen_at { Faker::Time.between(from: 3.days.ago, to: Date.today) }
read_at { Faker::Time.between(from: seen_at, to: Date.today) }
end
end
end

View file

@ -2,10 +2,10 @@
FactoryBot.define do
factory :wopi_discovery do
proof_key_mod { Faker::Lorem.characters(20) }
proof_key_exp { Faker::Lorem.characters(20) }
proof_key_old_mod { Faker::Lorem.characters(20) }
proof_key_old_exp { Faker::Lorem.characters(20) }
proof_key_mod { Faker::Lorem.characters(number: 20) }
proof_key_exp { Faker::Lorem.characters(number: 20) }
proof_key_old_mod { Faker::Lorem.characters(number: 20) }
proof_key_old_exp { Faker::Lorem.characters(number: 20) }
expires { 60 }
end
end

View file

@ -201,7 +201,7 @@ RSpec.describe 'Api::V1::InventoriesController', type: :request do
updated_inventory[:data][:attributes][:name] =
Faker::Name.unique.name
patch api_v1_team_inventory_path(
id: @teams.first.repositories.first.id,
id: updated_inventory[:data][:id],
team_id: @teams.first.id
), params: updated_inventory.to_json,
headers: @valid_headers

View file

@ -50,7 +50,7 @@ RSpec.describe 'Api::V1::ResultsController', type: :request do
included: [
{ type: 'result_texts',
attributes: {
text: Faker::Lorem.sentence(25)
text: Faker::Lorem.sentence(word_count: 25)
} }
] }

View file

@ -32,9 +32,9 @@ describe ProtocolImporters::BuildProtocolFromClientService do
context 'when raise api client error' do
it 'return api errors' do
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:single_protocol)
.and_raise(ProtocolImporters::ProtocolsIO::V3::ArgumentError
.and_raise(ProtocolImporters::ProtocolsIo::V3::ArgumentError
.new(:missing_or_empty_parameters), 'Missing Or Empty Parameters Error'))
expect(service_call.errors).to have_key(:missing_or_empty_parameters)
@ -45,13 +45,13 @@ describe ProtocolImporters::BuildProtocolFromClientService do
it 'return normalizer errors' do
client_data = double('api_response')
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:single_protocol)
.and_return(client_data))
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ProtocolNormalizer)
.to(receive(:normalize_protocol).with(client_data)
.and_raise(ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(:nil_protocol), 'Nil Protocol'))
.and_raise(ProtocolImporters::ProtocolsIo::V3::NormalizerError.new(:nil_protocol), 'Nil Protocol'))
expect(service_call.errors).to have_key(:nil_protocol)
end
@ -61,11 +61,11 @@ describe ProtocolImporters::BuildProtocolFromClientService do
before do
client_data = double('api_response')
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:single_protocol)
.and_return(client_data))
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ProtocolNormalizer)
.to(receive(:normalize_protocol).with(client_data)
.and_return(normalized_response))

View file

@ -34,9 +34,9 @@ describe ProtocolImporters::SearchProtocolsService do
context 'when raise api client error' do
it 'return api errors' do
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_list)
.and_raise(ProtocolImporters::ProtocolsIO::V3::ArgumentError
.and_raise(ProtocolImporters::ProtocolsIo::V3::ArgumentError
.new(:missing_or_empty_parameters), 'Missing Or Empty Parameters Error'))
expect(service_call.errors).to have_key(:missing_or_empty_parameters)
@ -47,13 +47,13 @@ describe ProtocolImporters::SearchProtocolsService do
it 'return normalizer errors' do
client_data = double('api_response')
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_list)
.and_return(client_data))
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ProtocolNormalizer)
.to(receive(:normalize_list).with(client_data)
.and_raise(ProtocolImporters::ProtocolsIO::V3::NormalizerError.new(:nil_protocol), 'Nil Protocol'))
.and_raise(ProtocolImporters::ProtocolsIo::V3::NormalizerError.new(:nil_protocol), 'Nil Protocol'))
expect(service_call.errors).to have_key(:nil_protocol)
end
@ -63,11 +63,11 @@ describe ProtocolImporters::SearchProtocolsService do
before do
client_data = double('api_response')
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ApiClient)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ApiClient)
.to(receive(:protocol_list)
.and_return(client_data))
allow_any_instance_of(ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer)
allow_any_instance_of(ProtocolImporters::ProtocolsIo::V3::ProtocolNormalizer)
.to(receive(:normalize_list).with(client_data)
.and_return(normalized_list))
end

View file

@ -113,7 +113,7 @@ describe Tasks::SamplesToRepositoryMigrationService do
end
it 'generates valid list_items' do
generated_list_items = subject.second.repository_list_items
generated_list_items = subject.second.repository_list_items.order(:id)
expect(generated_list_items.count).to eq 10
generated_list_items.each_with_index do |item, index|
expect(item.data).to eq "Sample Type Item (#{index})"
@ -168,7 +168,7 @@ describe Tasks::SamplesToRepositoryMigrationService do
end
it 'generates valid list_items' do
generated_list_items = subject.first.repository_list_items
generated_list_items = subject.first.repository_list_items.order(:id)
expect(generated_list_items.count).to eq 10
generated_list_items.each_with_index do |item, index|
expect(item.data).to eq "Sample Group Item (#{index})"

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
describe ProtocolImporters::ProtocolsIo::V3::ApiClient do
CONSTANTS = Constants::PROTOCOLS_IO_V3_API
TOKEN = 'test_token'
@ -60,7 +60,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
it 'raises NetworkError on timeout' do
stub_protocols.to_timeout
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIO::V3::NetworkError)
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIo::V3::NetworkError)
end
it 'raises ArgumentError when status_code = 1' do
@ -68,7 +68,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
body: JSON.generate(status_code: 1, error_message: 'Argument error'),
headers: { 'Content-Type': 'application/json' })
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIO::V3::ArgumentError)
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIo::V3::ArgumentError)
end
it 'raises UnauthorizedError when status_code = 1218' do
@ -76,7 +76,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
body: JSON.generate(status_code: 1218, error_message: 'Argument error'),
headers: { 'Content-Type': 'application/json' })
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIO::V3::UnauthorizedError)
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIo::V3::UnauthorizedError)
end
it 'raises UnauthorizedError when status_code = 1219' do
@ -84,7 +84,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
body: JSON.generate(status_code: 1219, error_message: 'Argument error'),
headers: { 'Content-Type': 'application/json' })
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIO::V3::UnauthorizedError)
expect { protocol_list_call }.to raise_error(ProtocolImporters::ProtocolsIo::V3::UnauthorizedError)
end
it 'requests server with default query parameters if none are given' do
@ -122,7 +122,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
body: JSON.generate(status_code: 0),
headers: { 'Content-Type': 'application/json' })
ProtocolImporters::ProtocolsIO::V3::ApiClient.new(TOKEN).protocol_list(key_query)
ProtocolImporters::ProtocolsIo::V3::ApiClient.new(TOKEN).protocol_list(key_query)
expect(WebMock).to have_requested(:get, URL).with(headers: headers, query: default_query_params_with_key)
end
end
@ -150,14 +150,14 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
it 'raises NetworkError on timeout' do
stub_request(:get, SINGLE_PROTOCOL_URL).to_timeout
expect { subject.single_protocol(PROTOCOL_ID) }.to raise_error(ProtocolImporters::ProtocolsIO::V3::NetworkError)
expect { subject.single_protocol(PROTOCOL_ID) }.to raise_error(ProtocolImporters::ProtocolsIo::V3::NetworkError)
end
it 'should send authorization token if provided on initialization' do
headers = { 'Authorization': "Bearer #{TOKEN}" }
stub_single_protocol.with(headers: headers)
ProtocolImporters::ProtocolsIO::V3::ApiClient.new(TOKEN).single_protocol(PROTOCOL_ID)
ProtocolImporters::ProtocolsIo::V3::ApiClient.new(TOKEN).single_protocol(PROTOCOL_ID)
expect(WebMock).to have_requested(:get, SINGLE_PROTOCOL_URL).with(headers: headers)
end
end
@ -180,7 +180,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ApiClient do
stub_html_preview.to_timeout
expect { subject.protocol_html_preview(PROTOCOL_URI) }
.to raise_error(ProtocolImporters::ProtocolsIO::V3::NetworkError)
.to raise_error(ProtocolImporters::ProtocolsIo::V3::NetworkError)
end
end
end

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer do
describe ProtocolImporters::ProtocolsIo::V3::ProtocolNormalizer do
let(:client_data) { double('api_response') }
let(:protocols_io_single_protocol) do
@ -48,7 +48,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer do
.and_return({})
expect { subject.normalize_protocol(client_data) }
.to raise_error(ProtocolImporters::ProtocolsIO::V3::NormalizerError)
.to raise_error(ProtocolImporters::ProtocolsIo::V3::NormalizerError)
end
context 'when do not have name' do
@ -73,7 +73,7 @@ describe ProtocolImporters::ProtocolsIO::V3::ProtocolNormalizer do
.and_return({})
expect { subject.normalize_list(client_data) }
.to raise_error(ProtocolImporters::ProtocolsIO::V3::NormalizerError)
.to raise_error(ProtocolImporters::ProtocolsIo::V3::NormalizerError)
end
end
end

View file

@ -2,7 +2,7 @@
require 'rails_helper'
describe ProtocolImporters::ProtocolsIO::V3::StepComponents do
describe ProtocolImporters::ProtocolsIo::V3::StepComponents do
let(:components) do
[
{ type_id: 1, source: { description: 'Description' } },