From c3fceb90dfbd6e31597bdb76ee68b56c6e9b5927 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Tue, 29 Aug 2017 18:49:07 +0200 Subject: [PATCH 001/189] Backport API to Rails-4 [SCI-1579] --- .rspec | 2 + Gemfile | 22 ++- Gemfile.lock | 125 ++++++++++++-- app/assets/stylesheets/themes/scinote.scss | 22 +++ app/controllers/api/api_controller.rb | 85 ++++++++++ .../api/v20170715/core_api_controller.rb | 53 ++++++ .../users/omniauth_callbacks_controller.rb | 46 +++--- app/models/user.rb | 15 +- app/models/user_identity.rb | 4 + app/services/api.rb | 25 +++ app/services/api/core_jwt.rb | 34 ++++ app/views/user_notifications/_list.html.erb | 23 +-- .../_recent_notifications.html.erb | 24 +-- .../icons/_assignment.html.erb | 3 + .../icons/_deliver.html.erb | 3 + .../icons/_recent_changes.html.erb | 3 + .../icons/_system_message.html.erb | 5 + .../settings/account/_navigation.html.erb | 4 +- app/views/users/shared/_links.html.erb | 7 +- config/initializers/core_api.rb | 11 ++ config/initializers/extends.rb | 8 + config/locales/en.yml | 7 + config/routes.rb | 19 ++- .../20170803153030_add_user_identity_table.rb | 13 ++ spec/controllers/api/api_controller_spec.rb | 65 ++++++++ .../api/v20170715/core_api_controller_spec.rb | 129 +++++++++++++++ spec/factories/asset_text_datums.rb | 5 + spec/factories/assets.rb | 12 ++ spec/factories/custom_fields.rb | 5 + spec/factories/experiments.rb | 26 +++ spec/factories/my_module_groups.rb | 6 + spec/factories/my_module_repository_rows.rb | 6 + spec/factories/my_modules.rb | 10 ++ spec/factories/projects.rb | 24 +++ spec/factories/reports.rb | 7 + spec/factories/repository.rb | 7 + spec/factories/repository_cell.rb | 9 ++ spec/factories/repository_columns.rb | 8 + spec/factories/repository_rows.rb | 7 + spec/factories/sample_groups.rb | 7 + spec/factories/sample_my_modules.rb | 6 + spec/factories/sample_types.rb | 5 + spec/factories/samples.rb | 7 + spec/factories/samples_tables.rb | 4 + spec/factories/teams.rb | 8 + spec/factories/users.rb | 12 ++ spec/models/activity_spec.rb | 30 ++++ spec/models/asset_spec.rb | 48 ++++++ spec/models/asset_text_datum_spec.rb | 33 ++++ spec/models/checklist_item_spec.rb | 32 ++++ spec/models/checklist_spec.rb | 31 ++++ spec/models/comment_spec.rb | 29 ++++ spec/models/connection_step | 18 +++ spec/models/custom_field_spec.rb | 61 +++++++ spec/models/experiment_spec.rb | 68 ++++++++ spec/models/my_module_group_spec.rb | 28 ++++ spec/models/my_module_repository_row_spec.rb | 27 ++++ spec/models/my_module_spec.rb | 73 +++++++++ spec/models/my_module_tag_spec.rb | 24 +++ spec/models/notification_spec.rb | 23 +++ spec/models/project_comment_spec.rb | 26 +++ spec/models/project_spec.rb | 65 ++++++++ spec/models/protocol_keyword_spec.rb | 30 ++++ spec/models/protocol_protocol_keyword_spec.rb | 22 +++ spec/models/protocol_spec.rb | 52 ++++++ spec/models/report_element_spec.rb | 47 ++++++ spec/models/report_spec.rb | 44 +++++ spec/models/repository_cell_spec.rb | 21 +++ spec/models/repository_column_spec.rb | 39 +++++ spec/models/repository_date_value_spec.rb | 26 +++ spec/models/repository_row_spec.rb | 34 ++++ spec/models/repository_spec.rb | 43 +++++ spec/models/repository_table_state_spec.rb | 25 +++ spec/models/repository_text_value_spec.rb | 29 ++++ spec/models/result_asset_spec.rb | 22 +++ spec/models/result_comment_spec.rb | 25 +++ spec/models/result_spec.rb | 43 +++++ spec/models/result_table_spec.rb | 22 +++ spec/models/result_text_spec.rb | 26 +++ spec/models/sample_custom_field_spec.rb | 29 ++++ spec/models/sample_group_spec.rb | 42 +++++ spec/models/sample_my_module_spec.rb | 33 ++++ spec/models/sample_spec.rb | 40 +++++ spec/models/sample_type_spec.rb | 45 ++++++ spec/models/samples_table_spec.rb | 25 +++ spec/models/settings_spec.rb | 12 ++ spec/models/step_asset_spec.rb | 22 +++ spec/models/step_comment_spec.rb | 25 +++ spec/models/step_spec.rb | 49 ++++++ spec/models/step_table_spec.rb | 21 +++ spec/models/table_spec.rb | 40 +++++ spec/models/tag_spec.rb | 37 +++++ spec/models/task_comment_spec.rb | 25 +++ spec/models/team_spec.rb | 47 ++++++ spec/models/temp_file_spec.rb | 21 +++ spec/models/tiny_mce_asset_spec.rb | 30 ++++ spec/models/token_spec.rb | 22 +++ spec/models/user_my_module_spec.rb | 26 +++ spec/models/user_notification_spec.rb | 20 +++ spec/models/user_project_spec.rb | 28 ++++ spec/models/user_spec.rb | 152 ++++++++++++++++++ spec/models/user_team_spec.rb | 28 ++++ spec/models/wopi_action_spec.rb | 25 +++ spec/models/wopi_app_spec.rb | 24 +++ spec/models/wopi_discovery_spec.rb | 27 ++++ spec/models/zip_export_spec.rb | 21 +++ spec/rails_helper.rb | 93 +++++++++++ spec/spec_helper.rb | 100 ++++++++++++ spec/support/api_helper.rb | 17 ++ 109 files changed, 3141 insertions(+), 89 deletions(-) create mode 100644 .rspec create mode 100644 app/controllers/api/api_controller.rb create mode 100644 app/controllers/api/v20170715/core_api_controller.rb create mode 100644 app/models/user_identity.rb create mode 100644 app/services/api.rb create mode 100644 app/services/api/core_jwt.rb create mode 100644 app/views/user_notifications/icons/_assignment.html.erb create mode 100644 app/views/user_notifications/icons/_deliver.html.erb create mode 100644 app/views/user_notifications/icons/_recent_changes.html.erb create mode 100644 app/views/user_notifications/icons/_system_message.html.erb create mode 100644 config/initializers/core_api.rb create mode 100644 db/migrate/20170803153030_add_user_identity_table.rb create mode 100644 spec/controllers/api/api_controller_spec.rb create mode 100644 spec/controllers/api/v20170715/core_api_controller_spec.rb create mode 100644 spec/factories/asset_text_datums.rb create mode 100644 spec/factories/assets.rb create mode 100644 spec/factories/custom_fields.rb create mode 100644 spec/factories/experiments.rb create mode 100644 spec/factories/my_module_groups.rb create mode 100644 spec/factories/my_module_repository_rows.rb create mode 100644 spec/factories/my_modules.rb create mode 100644 spec/factories/projects.rb create mode 100644 spec/factories/reports.rb create mode 100644 spec/factories/repository.rb create mode 100644 spec/factories/repository_cell.rb create mode 100644 spec/factories/repository_columns.rb create mode 100644 spec/factories/repository_rows.rb create mode 100644 spec/factories/sample_groups.rb create mode 100644 spec/factories/sample_my_modules.rb create mode 100644 spec/factories/sample_types.rb create mode 100644 spec/factories/samples.rb create mode 100644 spec/factories/samples_tables.rb create mode 100644 spec/factories/teams.rb create mode 100644 spec/factories/users.rb create mode 100644 spec/models/activity_spec.rb create mode 100644 spec/models/asset_spec.rb create mode 100644 spec/models/asset_text_datum_spec.rb create mode 100644 spec/models/checklist_item_spec.rb create mode 100644 spec/models/checklist_spec.rb create mode 100644 spec/models/comment_spec.rb create mode 100644 spec/models/connection_step create mode 100644 spec/models/custom_field_spec.rb create mode 100644 spec/models/experiment_spec.rb create mode 100644 spec/models/my_module_group_spec.rb create mode 100644 spec/models/my_module_repository_row_spec.rb create mode 100644 spec/models/my_module_spec.rb create mode 100644 spec/models/my_module_tag_spec.rb create mode 100644 spec/models/notification_spec.rb create mode 100644 spec/models/project_comment_spec.rb create mode 100644 spec/models/project_spec.rb create mode 100644 spec/models/protocol_keyword_spec.rb create mode 100644 spec/models/protocol_protocol_keyword_spec.rb create mode 100644 spec/models/protocol_spec.rb create mode 100644 spec/models/report_element_spec.rb create mode 100644 spec/models/report_spec.rb create mode 100644 spec/models/repository_cell_spec.rb create mode 100644 spec/models/repository_column_spec.rb create mode 100644 spec/models/repository_date_value_spec.rb create mode 100644 spec/models/repository_row_spec.rb create mode 100644 spec/models/repository_spec.rb create mode 100644 spec/models/repository_table_state_spec.rb create mode 100644 spec/models/repository_text_value_spec.rb create mode 100644 spec/models/result_asset_spec.rb create mode 100644 spec/models/result_comment_spec.rb create mode 100644 spec/models/result_spec.rb create mode 100644 spec/models/result_table_spec.rb create mode 100644 spec/models/result_text_spec.rb create mode 100644 spec/models/sample_custom_field_spec.rb create mode 100644 spec/models/sample_group_spec.rb create mode 100644 spec/models/sample_my_module_spec.rb create mode 100644 spec/models/sample_spec.rb create mode 100644 spec/models/sample_type_spec.rb create mode 100644 spec/models/samples_table_spec.rb create mode 100644 spec/models/settings_spec.rb create mode 100644 spec/models/step_asset_spec.rb create mode 100644 spec/models/step_comment_spec.rb create mode 100644 spec/models/step_spec.rb create mode 100644 spec/models/step_table_spec.rb create mode 100644 spec/models/table_spec.rb create mode 100644 spec/models/tag_spec.rb create mode 100644 spec/models/task_comment_spec.rb create mode 100644 spec/models/team_spec.rb create mode 100644 spec/models/temp_file_spec.rb create mode 100644 spec/models/tiny_mce_asset_spec.rb create mode 100644 spec/models/token_spec.rb create mode 100644 spec/models/user_my_module_spec.rb create mode 100644 spec/models/user_notification_spec.rb create mode 100644 spec/models/user_project_spec.rb create mode 100644 spec/models/user_spec.rb create mode 100644 spec/models/user_team_spec.rb create mode 100644 spec/models/wopi_action_spec.rb create mode 100644 spec/models/wopi_app_spec.rb create mode 100644 spec/models/wopi_discovery_spec.rb create mode 100644 spec/models/zip_export_spec.rb create mode 100644 spec/rails_helper.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/support/api_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..5be63fcb0 --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--require spec_helper +--format documentation diff --git a/Gemfile b/Gemfile index 6754fde93..4dcf92164 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,10 @@ gem 'yomu' gem 'font-awesome-rails', '~> 4.6' gem 'recaptcha', require: 'recaptcha/rails' gem 'sanitize', '~> 4.4' +gem 'omniauth' + +# Gems for API implementation +gem 'jwt' # JS datetime library, requirement of datetime picker gem 'momentjs-rails', '>= 2.9.0' @@ -51,7 +55,7 @@ gem 'wicked_pdf' gem 'silencer' # Silence certain Rails logs gem 'wkhtmltopdf-heroku' gem 'remotipart', '~> 1.2' # Async file uploads -gem 'faker' # Generate fake data +gem 'faker', '~> 1.7.3' # Generate fake data gem 'auto_strip_attributes', '~> 2.1' # Removes unnecessary whitespaces from ActiveRecord or ActiveModel attributes gem 'deface', '~> 1.0' gem 'nokogiri' # HTML/XML parser @@ -75,7 +79,13 @@ gem 'base62' # Used for smart annotations gem 'newrelic_rpm' group :development, :test do + gem 'listen', '~> 3.0' gem 'byebug' + gem 'pry' + gem 'pry-byebug' + gem 'pry-rails' + gem 'factory_girl_rails' + gem 'rspec-rails' gem 'better_errors' gem 'binding_of_caller' gem 'awesome_print' @@ -90,9 +100,13 @@ group :production do end group :test do - gem 'minitest-reporters', '~> 1.1' - gem "shoulda-context" - gem "shoulda-matchers", ">= 3.0.1" + gem 'shoulda-matchers' + gem 'cucumber-rails', require: false + gem 'database_cleaner' + gem 'capybara' + gem 'poltergeist' + gem 'phantomjs', :require => 'phantomjs/poltergeist' + gem 'simplecov', require: false end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/Gemfile.lock b/Gemfile.lock index aed66990c..c65d99fc0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,10 +54,11 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) + addressable (2.5.2) + public_suffix (>= 2.0.2, < 4.0) ajax-datatables-rails (0.3.1) railties (>= 3.1) algorithms (0.6.1) - ansi (1.5.0) arel (6.0.3) aspector (0.14.0) ast (2.3.0) @@ -99,8 +100,16 @@ GEM bootstrap_form (2.3.0) builder (3.2.2) byebug (8.2.1) + capybara (2.15.1) + addressable + mini_mime (>= 0.1.3) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) climate_control (0.0.3) activesupport (>= 3.0) + cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) coderay (1.1.1) @@ -115,6 +124,24 @@ GEM commit_param_routing (0.0.1) concurrent-ruby (1.0.0) crass (1.0.2) + cucumber (2.4.0) + builder (>= 2.1.2) + cucumber-core (~> 1.5.0) + cucumber-wire (~> 0.0.1) + diff-lcs (>= 1.1.3) + gherkin (~> 4.0) + multi_json (>= 1.7.5, < 2.0) + multi_test (>= 0.1.2) + cucumber-core (1.5.0) + gherkin (~> 4.0) + cucumber-rails (1.5.0) + capybara (>= 1.1.2, < 3) + cucumber (>= 1.3.8, < 4) + mime-types (>= 1.17, < 4) + nokogiri (~> 1.5) + railties (>= 4, < 5.2) + cucumber-wire (0.0.1) + database_cleaner (1.6.1) debug_inspector (0.0.2) deface (1.0.2) colorize (>= 0.5.8) @@ -138,17 +165,27 @@ GEM devise_invitable (1.5.5) actionmailer (>= 3.2.6, < 5) devise (>= 3.2.0) + diff-lcs (1.3) + docile (1.1.5) erubis (2.7.0) execjs (2.6.0) - faker (1.6.1) + factory_girl (4.8.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) + railties (>= 3.0.0) + faker (1.7.3) i18n (~> 0.5) + ffi (1.9.18) figaro (1.1.1) thor (~> 0.14) font-awesome-rails (4.6.3.1) railties (>= 3.2, < 5.1) + gherkin (4.1.3) globalid (0.3.6) activesupport (>= 4.1.0) hammerjs-rails (2.0.4) + hashie (3.5.6) i18n (0.7.0) i18n-js (3.0.0.rc11) i18n (~> 0.6) @@ -170,9 +207,14 @@ GEM js_cookie_rails (1.0.1) railties (>= 3.1) json (1.8.3) + jwt (1.5.6) kaminari (0.16.3) actionpack (>= 3.0.0) activesupport (>= 3.0.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) little-plugger (1.1.4) logging (2.0.0) little-plugger (~> 1.1) @@ -181,18 +223,16 @@ GEM nokogiri (>= 1.5.9) mail (2.6.3) mime-types (>= 1.16, < 3) + method_source (0.8.2) mime-types (1.25.1) mimemagic (0.3.0) + mini_mime (0.1.4) mini_portile2 (2.1.0) minitest (5.9.0) - minitest-reporters (1.1.10) - ansi - builder - minitest (>= 5.0) - ruby-progressbar momentjs-rails (2.10.6) railties (>= 3.1) multi_json (1.11.2) + multi_test (0.1.2) nested_form_fields (0.7.4) coffee-rails (>= 3.2.1) jquery-rails @@ -203,6 +243,9 @@ GEM nokogumbo (1.4.10) nokogiri oj (2.17.4) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) orm_adapter (0.5.0) paperclip (4.3.2) activemodel (>= 3.2.0) @@ -213,8 +256,23 @@ GEM parser (2.4.0.0) ast (~> 2.2) pg (0.18.4) + phantomjs (2.1.1.0) + poltergeist (1.16.0) + capybara (~> 2.1) + cliver (~> 0.3.1) + websocket-driver (>= 0.2.0) polyglot (0.3.5) powerpack (0.1.1) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-byebug (3.3.0) + byebug (~> 8.0) + pry (~> 0.10) + pry-rails (0.3.6) + pry (>= 0.10.4) + public_suffix (3.0.0) puma (2.15.3) rack (1.6.4) rack-test (0.6.3) @@ -253,6 +311,9 @@ GEM rainbow (2.2.2) rake rake (12.0.0) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) rdoc (4.2.0) recaptcha (4.0.0) json @@ -266,6 +327,23 @@ GEM roo (2.7.1) nokogiri (~> 1) rubyzip (~> 1.1, < 2.0.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.6.0) + rspec-rails (3.6.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) rubocop (0.48.1) parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) @@ -274,6 +352,7 @@ GEM unicode-display_width (~> 1.0, >= 1.0.1) ruby-graphviz (1.2.2) ruby-progressbar (1.8.1) + ruby_dep (1.5.0) rubyzip (1.2.1) sanitize (4.4.0) crass (~> 1.0.2) @@ -292,7 +371,6 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - shoulda-context (1.2.1) shoulda-matchers (3.1.1) activesupport (>= 4.0.0) silencer (1.0.1) @@ -300,6 +378,12 @@ GEM actionmailer (>= 3.2.6, < 6) actionpack (>= 3.2.6, < 6) devise (>= 3.2, < 6) + simplecov (0.15.0) + docile (~> 1.1.0) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + slop (3.6.0) sourcemap (0.1.1) spinjs-rails (1.4) rails (>= 3.1) @@ -334,8 +418,13 @@ GEM unicode-display_width (1.2.1) warden (1.2.6) rack (>= 1.0) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) wicked_pdf (1.0.3) wkhtmltopdf-heroku (2.12.3.0) + xpath (2.1.0) + nokogiri (~> 1.3) yomu (0.2.4) json (~> 1.8) mime-types (~> 1.23) @@ -361,14 +450,18 @@ DEPENDENCIES bootstrap3-datetimepicker-rails (~> 4.15.35) bootstrap_form byebug + capybara commit_param_routing + cucumber-rails + database_cleaner deface (~> 1.0) delayed_job_active_record delayed_paperclip! devise (= 3.5.6) devise-async devise_invitable - faker + factory_girl_rails + faker (~> 1.7.3) figaro font-awesome-rails (~> 4.6) hammerjs-rails @@ -379,15 +472,22 @@ DEPENDENCIES jquery-turbolinks jquery-ui-rails js_cookie_rails + jwt kaminari + listen (~> 3.0) logging (~> 2.0.0) - minitest-reporters (~> 1.1) momentjs-rails (>= 2.9.0) nested_form_fields newrelic_rpm nokogiri + omniauth paperclip (~> 4.3) pg + phantomjs + poltergeist + pry + pry-byebug + pry-rails puma rails (= 4.2.5) rails_12factor @@ -396,6 +496,7 @@ DEPENDENCIES remotipart (~> 1.2) rgl roo (~> 2.7.1) + rspec-rails rubocop ruby-graphviz (~> 1.2) rubyzip @@ -403,10 +504,10 @@ DEPENDENCIES sass-rails (~> 5.0) scss_lint sdoc (~> 0.4.0) - shoulda-context - shoulda-matchers (>= 3.0.1) + shoulda-matchers silencer simple_token_authentication (~> 1.0) + simplecov sneaky-save! spinjs-rails starscope diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index e5a41a988..c03d96374 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -338,6 +338,28 @@ a { } } +.btn-omniauth-login { + background-color: $color-theme-primary; + color: $color-white; + + &:active, + &:focus, + &:active:focus { + background-color: darken($color-theme-primary, 5%); + color: $color-white; + + &:hover { + background-color: darken($color-theme-primary, 10%); + color: $color-white; + } + } + + &:hover { + background-color: darken($color-theme-primary, 5%); + color: $color-white; + } +} + .btn-open-file { position: relative; overflow: hidden; diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb new file mode 100644 index 000000000..737defe82 --- /dev/null +++ b/app/controllers/api/api_controller.rb @@ -0,0 +1,85 @@ +module Api + class ApiController < ActionController::Base + attr_reader :iss + attr_reader :token + attr_reader :current_user + + before_action :load_token, except: %i(authenticate status) + before_action :load_iss, except: %i(authenticate status) + before_action :authenticate_request!, except: %i(authenticate status) + + rescue_from StandardError do + render json: {}, status: :bad_request + end + + rescue_from JWT::InvalidPayload, JWT::DecodeError do + render json: { message: I18n.t('api.core.invalid_token') }, + status: :unauthorized + end + + def initialize + super + @iss = nil + end + + def status + response = {} + response[:message] = I18n.t('api.core.status_ok') + response[:versions] = [] + Extends::API_VERSIONS.each do |ver| + response[:versions] << { version: ver, baseUrl: "/api/#{ver}/" } + end + render json: response, status: :ok + end + + def authenticate + if auth_params[:grant_type] == 'password' + user = User.find_by_email(auth_params[:email]) + raise StandardError unless user && + user.valid_password?(auth_params[:password]) + payload = { user_id: user.id } + token = CoreJwt.encode(payload) + render json: { token_type: 'bearer', access_token: token } + else + raise StandardError + end + end + + private + + def load_token + @token = + request.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last + raise StandardError unless @token + end + + def authenticate_request! + Extends::API_PLUGABLE_AUTH_METHODS.each do |auth_method| + method(auth_method).call + return true if current_user + end + # Check request header for proper auth token + payload = CoreJwt.decode(token) + @current_user = User.find_by_id(payload['user_id']) + # Implement sliding sessions, i.e send new token in case of successful + # authorization and when tokens TTL reached specific value (to avoid token + # generation on each request) + if CoreJwt.refresh_needed?(payload) + new_token = CoreJwt.encode(user_id: @current_user.id) + response.headers['X-Access-Token'] = new_token + end + rescue JWT::ExpiredSignature + render json: { message: I18n.t('api.core.expired_token') }, + status: :unauthorized + end + + def load_iss + @iss = CoreJwt.read_iss(token) + raise JWT::InvalidPayload unless @iss + end + + def auth_params + params.permit(:grant_type, :email, :password) + end + end +end diff --git a/app/controllers/api/v20170715/core_api_controller.rb b/app/controllers/api/v20170715/core_api_controller.rb new file mode 100644 index 000000000..e06705d9e --- /dev/null +++ b/app/controllers/api/v20170715/core_api_controller.rb @@ -0,0 +1,53 @@ +module Api + module V20170715 + class CoreApiController < ApiController + include PermissionHelper + + def tasks_tree + teams_json = [] + current_user.teams.find_each do |tm| + team = tm.as_json(only: %i(name description)) + team['team_id'] = tm.id.to_s + projects = [] + tm.projects.find_each do |pr| + project = pr.as_json(only: %i(name visibility archived)) + project['project_id'] = pr.id.to_s + experiments = [] + pr.experiments.find_each do |exp| + experiment = exp.as_json(only: %i(name description archived)) + experiment['experiment_id'] = exp.id.to_s + tasks = [] + exp.my_modules.find_each do |tk| + task = tk.as_json(only: %i(name description archived)) + task['task_id'] = tk.id.to_s + tasks << task + end + experiment['tasks'] = tasks + experiments << experiment + end + project['experiments'] = experiments + projects << project + end + team['projects'] = projects + teams_json << team + end + render json: teams_json, status: :ok + end + + def task_samples + task = MyModule.find_by_id(params[:task_id]) + return render json: {}, status: :not_found unless task + return render json: {}, status: :forbidden unless can_view_module(task) + samples = task.samples + samples_json = [] + samples.find_each do |s| + sample = {} + sample['sample_id'] = s.id.to_s + sample['name'] = s.name + samples_json << sample + end + render json: samples_json, status: :ok + end + end + end +end diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 1907e5b1b..27b884710 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -1,28 +1,32 @@ -class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController - # You should configure your model like this: - # devise :omniauthable, omniauth_providers: [:twitter] +module Users + class OmniauthCallbacksController < Devise::OmniauthCallbacksController + skip_before_action :verify_authenticity_token - # You should also create an action method in this controller like this: - # def twitter - # end + # You should configure your model like this: + # devise :omniauthable, omniauth_providers: [:twitter] - # More info at: - # https://github.com/plataformatec/devise#omniauth + # You should also create an action method in this controller like this: + # def twitter + # end - # GET|POST /resource/auth/twitter - # def passthru - # super - # end + # More info at: + # https://github.com/plataformatec/devise#omniauth - # GET|POST /users/auth/twitter/callback - # def failure - # super - # end + # GET|POST /resource/auth/twitter + # def passthru + # super + # end - # protected + # GET|POST /users/auth/twitter/callback + # def failure + # super + # end - # The path used when OmniAuth fails - # def after_omniauth_failure_path_for(scope) - # super(scope) - # end + # protected + + # The path used when OmniAuth fails + # def after_omniauth_failure_path_for(scope) + # super(scope) + # end + end end diff --git a/app/models/user.rb b/app/models/user.rb index 1440462bf..12c0cc2c3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,6 +4,7 @@ class User < ActiveRecord::Base acts_as_token_authenticatable devise :invitable, :confirmable, :database_authenticatable, :registerable, :async, :recoverable, :rememberable, :trackable, :validatable, + :omniauthable, omniauth_providers: Extends::OMNIAUTH_PROVIDERS, stretches: Constants::PASSWORD_STRETCH_FACTOR has_attached_file :avatar, styles: { @@ -37,6 +38,7 @@ class User < ActiveRecord::Base validate :time_zone_check # Relations + has_many :user_identities, inverse_of: :user has_many :user_teams, inverse_of: :user has_many :teams, through: :user_teams has_many :user_projects, inverse_of: :user @@ -197,7 +199,18 @@ class User < ActiveRecord::Base end def name=(name) - full_name = name + self.full_name = name + end + + def self.from_omniauth(auth) + includes(:user_identities) + .where( + 'user_identities.provider=? AND user_identities.uid=?', + auth.provider, + auth.uid + ) + .references(:user_identities) + .take end # Search all active users for username & email. Can diff --git a/app/models/user_identity.rb b/app/models/user_identity.rb new file mode 100644 index 000000000..c5a7c08f6 --- /dev/null +++ b/app/models/user_identity.rb @@ -0,0 +1,4 @@ +class UserIdentity < ActiveRecord::Base + belongs_to :user + validates :provider, uniqueness: { scope: :user_id } +end diff --git a/app/services/api.rb b/app/services/api.rb new file mode 100644 index 000000000..da7998464 --- /dev/null +++ b/app/services/api.rb @@ -0,0 +1,25 @@ +module Api + class << self + attr_accessor :configuration + end + + def self.configuration + @configuration ||= Configuration.new + end + + def self.configure + yield(configuration) + end + + class Configuration + attr_accessor :core_api_sign_alg + attr_accessor :core_api_token_ttl + attr_accessor :core_api_token_iss + + def initialize + @core_api_sign_alg = 'HS256' + @core_api_token_ttl = 30.minutes + @core_api_token_iss = 'SciNote' + end + end +end diff --git a/app/services/api/core_jwt.rb b/app/services/api/core_jwt.rb new file mode 100644 index 000000000..b4f7e9f60 --- /dev/null +++ b/app/services/api/core_jwt.rb @@ -0,0 +1,34 @@ +module Api + class CoreJwt + require 'jwt' + KEY_SECRET = Rails.application.secrets.secret_key_base + + def self.encode(payload, expires_at = nil) + if expires_at + payload[:exp] = expires_at + else + payload[:exp] = Api.configuration.core_api_token_ttl.from_now.to_i + end + payload[:iss] = Api.configuration.core_api_token_iss + JWT.encode(payload, KEY_SECRET, Api.configuration.core_api_sign_alg) + end + + def self.decode(token) + HashWithIndifferentAccess.new( + JWT.decode(token, KEY_SECRET, Api.configuration.core_api_sign_alg)[0] + ) + end + + def self.read_iss(token) + HashWithIndifferentAccess.new( + JWT.decode(token, nil, false)[0] + )[:iss].to_s + end + + def self.refresh_needed?(payload) + time_left = payload[:exp].to_i - Time.now.to_i + return true if time_left < (Api.configuration.core_api_token_ttl.to_i / 2) + false + end + end +end diff --git a/app/views/user_notifications/_list.html.erb b/app/views/user_notifications/_list.html.erb index 7a995fb0d..b178eb735 100644 --- a/app/views/user_notifications/_list.html.erb +++ b/app/views/user_notifications/_list.html.erb @@ -3,26 +3,9 @@
- <% if notification.type_of == 'recent_changes' %> -
- <%= image_tag avatar_path(notification.generator_user, :icon_small), class: 'avatar img-circle' %> -
- <% end %> - <% if notification.type_of == 'assignment' %> -
- <%= fa_icon 'newspaper-o' %> -
- <% end %> - <% if notification.type_of == 'system_message' %> -
- -
- <% end %> - <% if notification.type_of == 'deliver' %> -
- <%= fa_icon 'truck' %> -
- <% end %> + <%= render partial: "user_notifications/icons/#{notification.type_of}", + locals: {notification: notification}, + formats: [:html] %>
<%= sanitize_input(notification.title) %>
diff --git a/app/views/user_notifications/_recent_notifications.html.erb b/app/views/user_notifications/_recent_notifications.html.erb index 65a5c9592..f93b736db 100644 --- a/app/views/user_notifications/_recent_notifications.html.erb +++ b/app/views/user_notifications/_recent_notifications.html.erb @@ -2,27 +2,9 @@
  • - - <% if notification.type_of == 'recent_changes' %> -
    - <%= image_tag avatar_path(notification.generator_user, :icon_small), class: 'avatar' %> -
    - <% end %> - <% if notification.type_of == 'assignment' %> -
    - <%= fa_icon 'newspaper-o' %> -
    - <% end %> - <% if notification.type_of == 'system_message' %> -
    - -
    - <% end %> - <% if notification.type_of == 'deliver' %> -
    - <%= fa_icon 'truck' %> -
    - <% end %> + <%= render partial: "user_notifications/icons/#{notification.type_of}", + locals: {notification: notification}, + formats: [:html] %>
    diff --git a/app/views/user_notifications/icons/_assignment.html.erb b/app/views/user_notifications/icons/_assignment.html.erb new file mode 100644 index 000000000..de1b33852 --- /dev/null +++ b/app/views/user_notifications/icons/_assignment.html.erb @@ -0,0 +1,3 @@ +
    + <%= fa_icon 'newspaper-o' %> +
    diff --git a/app/views/user_notifications/icons/_deliver.html.erb b/app/views/user_notifications/icons/_deliver.html.erb new file mode 100644 index 000000000..b42f2c2d7 --- /dev/null +++ b/app/views/user_notifications/icons/_deliver.html.erb @@ -0,0 +1,3 @@ +
    + <%= fa_icon 'truck' %> +
    diff --git a/app/views/user_notifications/icons/_recent_changes.html.erb b/app/views/user_notifications/icons/_recent_changes.html.erb new file mode 100644 index 000000000..631aa0349 --- /dev/null +++ b/app/views/user_notifications/icons/_recent_changes.html.erb @@ -0,0 +1,3 @@ +
    + <%= image_tag avatar_path(notification.generator_user, :icon_small), class: 'avatar img-circle' %> +
    diff --git a/app/views/user_notifications/icons/_system_message.html.erb b/app/views/user_notifications/icons/_system_message.html.erb new file mode 100644 index 000000000..2b8a769f9 --- /dev/null +++ b/app/views/user_notifications/icons/_system_message.html.erb @@ -0,0 +1,5 @@ +
    + + + +
    diff --git a/app/views/users/settings/account/_navigation.html.erb b/app/views/users/settings/account/_navigation.html.erb index f890b5a5f..15c11270c 100644 --- a/app/views/users/settings/account/_navigation.html.erb +++ b/app/views/users/settings/account/_navigation.html.erb @@ -1,8 +1,8 @@ - diff --git a/app/views/users/shared/_links.html.erb b/app/views/users/shared/_links.html.erb index fd266bbbd..25ccbae38 100644 --- a/app/views/users/shared/_links.html.erb +++ b/app/views/users/shared/_links.html.erb @@ -18,8 +18,7 @@ <%= link_to t("devise.links.not_receive_unlock"), new_unlock_path(resource_name) %>
    <% end -%> -<%- if devise_mapping.omniauthable? %> - <%- resource_class.omniauth_providers.each do |provider| %> - <%= link_to t("devise.links.sign_in_provider", provider: "#{provider.to_s.titleize}"), omniauth_authorize_path(resource_name, provider) %>
    - <% end -%> +<%- if devise_mapping.omniauthable? && resource_class.omniauth_providers.any? %> +

    <%= t("devise.links.more_sign_in_options") %>

    +
    <% end -%> diff --git a/config/initializers/core_api.rb b/config/initializers/core_api.rb new file mode 100644 index 000000000..c76ddf54d --- /dev/null +++ b/config/initializers/core_api.rb @@ -0,0 +1,11 @@ +Api.configure do |config| + if ENV['CORE_API_SIGN_ALG'] + config.core_api_sign_alg = ENV['CORE_API_SIGN_ALG'] + end + if ENV['CORE_API_TOKEN_TTL'] + config.core_api_token_ttl = ENV['CORE_API_TOKEN_TTL'] + end + if ENV['CORE_API_TOKEN_ISS'] + config.core_api_token_iss = ENV['CORE_API_TOKEN_ISS'] + end +end diff --git a/config/initializers/extends.rb b/config/initializers/extends.rb index b5a9d2b05..27495f574 100644 --- a/config/initializers/extends.rb +++ b/config/initializers/extends.rb @@ -42,4 +42,12 @@ class Extends # Data type name should match corresponding model's name REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0, RepositoryDateValue: 1 } + + # List of implemented core API versions + API_VERSIONS = ['20170715'] + + # Array used for injecting names of additional authentication methods for API + API_PLUGABLE_AUTH_METHODS = [] + + OMNIAUTH_PROVIDERS = [] end diff --git a/config/locales/en.yml b/config/locales/en.yml index 24498ed3c..acd1eb534 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -44,6 +44,7 @@ en: forgot: "Forgot your password?" not_receive_confirmation: "Didn't receive confirmation instructions?" not_receive_unlock: "Didn't receive unlock instructions?" + more_sign_in_options: "You can also:" sign_in_provider: "Sign in with %{provider}" helpers: @@ -1786,6 +1787,12 @@ en: busy: "The server is still processing your request. If you leave this page, the changes will be lost! Are you sure you want to continue?" no_name: "(no name)" + api: + core: + status_ok: "Ok" + expired_token: "Token is expired" + invalid_token: "Token is invalid" + Add: "Add" Asset: "File" Assets: "Files" diff --git a/config/routes.rb b/config/routes.rb index 7aed6b3f9..09eae4ef9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,12 @@ Rails.application.routes.draw do require 'subdomain' constraints UserSubdomain do - devise_for :users, controllers: { registrations: 'users/registrations', - sessions: 'users/sessions', - invitations: 'users/invitations', - confirmations: 'users/confirmations' } + devise_for :users, + controllers: { registrations: 'users/registrations', + sessions: 'users/sessions', + invitations: 'users/invitations', + confirmations: 'users/confirmations', + omniauth_callbacks: 'users/omniauth_callbacks' } root 'projects#index' @@ -472,6 +474,15 @@ Rails.application.routes.draw do post 'avatar_signature' => 'users/registrations#signature' get 'users/auth_token_sign_in' => 'users/sessions#auth_token_create' end + + namespace :api, defaults: { format: 'json' } do + get 'status', to: 'api#status' + post 'auth/token', to: 'api#authenticate' + scope '20170715', module: 'v20170715' do + get 'tasks/tree', to: 'core_api#tasks_tree' + get 'tasks/:task_id/samples', to: 'core_api#task_samples' + end + end end constraints WopiSubdomain do diff --git a/db/migrate/20170803153030_add_user_identity_table.rb b/db/migrate/20170803153030_add_user_identity_table.rb new file mode 100644 index 000000000..8a1661c1a --- /dev/null +++ b/db/migrate/20170803153030_add_user_identity_table.rb @@ -0,0 +1,13 @@ +class AddUserIdentityTable < ActiveRecord::Migration[5.1] + def change + create_table :user_identities do |t| + t.belongs_to :user, index: true + t.string :provider, null: false + t.string :uid, null: false + t.timestamps null: true + end + + add_index :user_identities, %i(provider uid), unique: true + add_index :user_identities, %i(user_id provider), unique: true + end +end diff --git a/spec/controllers/api/api_controller_spec.rb b/spec/controllers/api/api_controller_spec.rb new file mode 100644 index 000000000..637fa7310 --- /dev/null +++ b/spec/controllers/api/api_controller_spec.rb @@ -0,0 +1,65 @@ +require 'rails_helper' + +describe Api::ApiController, type: :controller do + describe 'GET #status' do + before do + get :status + end + + it 'Returns HTTP success' do + expect(response).to be_success + expect(response).to have_http_status(200) + end + + it 'Response with correct JSON status structure' do + hash_body = nil + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match( + 'message' => I18n.t('api.core.status_ok'), + 'versions' => [{ 'version' => '20170715', + 'baseUrl' => '/api/20170715/' }] + ) + end + end + + describe 'Post #authenticate' do + let(:user) { create(:user) } + + context 'When valid request' do + before do + post :authenticate, email: user.email, + password: user.password, + grant_type: 'password' + end + + it 'Returns HTTP success' do + expect(response).to have_http_status(200) + end + + it 'Returns valid JWT token' do + token = nil + expect { token = json['access_token'] }.not_to raise_exception + user_id = nil + expect { user_id = decode_token(token) }.not_to raise_exception + expect(user_id).to eq(user.id) + end + end + + context 'When invalid password in request' do + it 'Returns HTTP error' do + post :authenticate, email: user.email, + password: 'wrong_password', + grant_type: 'password' + expect(response).to have_http_status(400) + end + end + + context 'When no grant_type in request' do + it 'Returns HTTP error' do + post :authenticate, email: user.email, + password: user.password + expect(response).to have_http_status(400) + end + end + end +end diff --git a/spec/controllers/api/v20170715/core_api_controller_spec.rb b/spec/controllers/api/v20170715/core_api_controller_spec.rb new file mode 100644 index 000000000..bb4aaa6e5 --- /dev/null +++ b/spec/controllers/api/v20170715/core_api_controller_spec.rb @@ -0,0 +1,129 @@ +require 'rails_helper' + +describe Api::V20170715::CoreApiController, type: :controller do + let(:user) { create(:user) } + let(:task) { create(:my_module) } + let(:sample1) { create(:sample) } + let(:sample2) { create(:sample) } + let(:sample3) { create(:sample) } + before do + task.samples << [sample1, sample2, sample3] + UserProject.create!(user: user, project: task.experiment.project, role: 0) + end + + describe 'GET #task_samples' do + context 'When valid request' do + before do + request.headers['HTTP_ACCEPT'] = 'application/json' + request.headers['Authorization'] = 'Bearer ' + generate_token(user.id) + get :task_samples, task_id: task.id + end + + it 'Returns HTTP success' do + expect(response).to have_http_status(200) + end + + it 'Returns JSON body containing expected Samples' do + hash_body = nil + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match( + [{ 'sample_id' => sample1.id.to_s, 'name' => sample1.name }, + { 'sample_id' => sample2.id.to_s, 'name' => sample2.name }, + { 'sample_id' => sample3.id.to_s, 'name' => sample3.name }] + ) + end + end + + context 'When invalid request' do + context 'When invalid token' do + before do + request.headers['HTTP_ACCEPT'] = 'application/json' + request.headers['Authorization'] = 'Bearer WroNgToken' + get :task_samples, task_id: task.id + end + + it 'Returns HTTP unauthorized' do + expect(response).to have_http_status(401) + end + end + + context 'When valid token, but invalid request' do + before do + request.headers['HTTP_ACCEPT'] = 'application/json' + request.headers['Authorization'] = 'Bearer ' + generate_token(user.id) + end + + it 'Returns HTTP not found' do + get :task_samples, task_id: 1000 + expect(response).to have_http_status(404) + expect(json).to match({}) + end + + it 'Returns HTTP access denied' do + UserProject.where(user: user, project: task.experiment.project) + .first + .destroy! + get :task_samples, task_id: task.id + expect(response).to have_http_status(403) + expect(json).to match({}) + end + end + end + end + + describe 'GET #tasks_tree' do + context 'When valid request' do + before do + request.headers['HTTP_ACCEPT'] = 'application/json' + request.headers['Authorization'] = 'Bearer ' + generate_token(user.id) + get :tasks_tree + end + + it 'Returns HTTP success' do + expect(response).to have_http_status(200) + end + + it 'Returns JSON body containing expected Task tree' do + team = user.teams.first + experiment = task.experiment + project = experiment.project + hash_body = nil + expect { hash_body = json }.not_to raise_exception + expect(hash_body).to match( + ['team_id' => team.id.to_s, 'name' => team.name, + 'description' => team.description, + 'projects' => [{ + 'project_id' => project.id.to_s, 'name' => project.name, + 'visibility' => project.visibility, + 'archived' => project.archived, + 'experiments' => [{ + 'experiment_id' => experiment.id.to_s, + 'name' => experiment.name, + 'description' => experiment.description, + 'archived' => experiment.archived, + 'tasks' => [{ + 'task_id' => task.id.to_s, 'name' => task.name, + 'description' => task.description, + 'archived' => task.archived + }] + }] + }]] + ) + end + end + + context 'When invalid request' do + context 'When invalid token' do + before do + request.headers['HTTP_ACCEPT'] = 'application/json' + request.headers['Authorization'] = 'Bearer WroNgToken' + get :tasks_tree + end + + it 'Returns HTTP unauthorized' do + expect(response).to have_http_status(401) + end + end + end + end +end diff --git a/spec/factories/asset_text_datums.rb b/spec/factories/asset_text_datums.rb new file mode 100644 index 000000000..b272b26ee --- /dev/null +++ b/spec/factories/asset_text_datums.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :asset_text_datum do + data "Sample name\tSample type\n" + "sample6\tsample\n" + "\n" + end +end diff --git a/spec/factories/assets.rb b/spec/factories/assets.rb new file mode 100644 index 000000000..456ea1f29 --- /dev/null +++ b/spec/factories/assets.rb @@ -0,0 +1,12 @@ +FactoryGirl.define do + factory :asset do + association :created_by, factory: :project_user + association :team, factory: :team + file_file_name 'sample_file.txt' + file_content_type 'text/plain' + file_file_size 69 + version 1 + estimated_size 232 + file_processing false + end +end diff --git a/spec/factories/custom_fields.rb b/spec/factories/custom_fields.rb new file mode 100644 index 000000000..6d1ced03e --- /dev/null +++ b/spec/factories/custom_fields.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :custom_field do + name 'My custom field' + end +end diff --git a/spec/factories/experiments.rb b/spec/factories/experiments.rb new file mode 100644 index 000000000..d15997fad --- /dev/null +++ b/spec/factories/experiments.rb @@ -0,0 +1,26 @@ +FactoryGirl.define do + factory :experiment do + name 'My Experiment' + description 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' + end + + factory :experiment_one, class: Experiment do + name 'My Experiment One' + description 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' + association :project, factory: :project + association :created_by, factory: :user, email: Faker::Internet.email + association :last_modified_by, + factory: :user, + email: Faker::Internet.email + end + + factory :experiment_two, class: Experiment do + name Faker::Name.name + description 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.' + association :project, factory: :project + association :created_by, factory: :user, email: Faker::Internet.email + association :last_modified_by, + factory: :user, + email: Faker::Internet.email + end +end diff --git a/spec/factories/my_module_groups.rb b/spec/factories/my_module_groups.rb new file mode 100644 index 000000000..3688ad772 --- /dev/null +++ b/spec/factories/my_module_groups.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :my_module_group do + name Faker::Name.unique.name + experiment { Experiment.first || create(:experiment_two) } + end +end diff --git a/spec/factories/my_module_repository_rows.rb b/spec/factories/my_module_repository_rows.rb new file mode 100644 index 000000000..af444818c --- /dev/null +++ b/spec/factories/my_module_repository_rows.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :mm_repository_row, class: MyModuleRepositoryRow do + association :repository_row, factory: :repository_row + association :my_module, factory: :my_module + end +end diff --git a/spec/factories/my_modules.rb b/spec/factories/my_modules.rb new file mode 100644 index 000000000..ff2a92d50 --- /dev/null +++ b/spec/factories/my_modules.rb @@ -0,0 +1,10 @@ +FactoryGirl.define do + factory :my_module do + name 'My first module' + x 0 + y 0 + workflow_order 0 + experiment { Experiment.first || create(:experiment_one) } + my_module_group { MyModuleGroup.first || create(:my_module_group) } + end +end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb new file mode 100644 index 000000000..1db48538a --- /dev/null +++ b/spec/factories/projects.rb @@ -0,0 +1,24 @@ +FactoryGirl.define do + factory :project do + created_by { User.first || association(:project_user) } + team { Team.first || association(:project_team) } + archived false + name 'My project' + visibility 'hidden' + end + + factory :project_user, class: User do + full_name Faker::Name.name + initials 'AD' + email Faker::Internet.email + password 'asdf1243' + password_confirmation 'asdf1243' + end + + factory :project_team, class: Team do + created_by { User.first || association(:project_user) } + name 'My team' + description 'Lorem ipsum dolor sit amet, consectetuer adipiscing eli.' + space_taken 1048576 + end +end diff --git a/spec/factories/reports.rb b/spec/factories/reports.rb new file mode 100644 index 000000000..e36b8d5b6 --- /dev/null +++ b/spec/factories/reports.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :report do + user { User.first || association(:user) } + project { Project.first || association(:project) } + name Faker::Name.unique.name + end +end diff --git a/spec/factories/repository.rb b/spec/factories/repository.rb new file mode 100644 index 000000000..caffd62cd --- /dev/null +++ b/spec/factories/repository.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :repository do + name 'My Repository' + created_by { User.first || create(:user) } + team { Team.first || create(:team) } + end +end diff --git a/spec/factories/repository_cell.rb b/spec/factories/repository_cell.rb new file mode 100644 index 000000000..1c8f39886 --- /dev/null +++ b/spec/factories/repository_cell.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + factory :repository_cell do + repository_row { RepositoryRow.first || create(:repository_row) } + repository_column do + RepositoryColumn.first || create(:repository_column) + end + value 'RepositoryTextValue' + end +end diff --git a/spec/factories/repository_columns.rb b/spec/factories/repository_columns.rb new file mode 100644 index 000000000..9417db115 --- /dev/null +++ b/spec/factories/repository_columns.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :repository_column do + name 'My Column' + created_by { User.first || create(:user) } + repository { Repository.first || create(:repository) } + data_type :RepositoryTextValue + end +end diff --git a/spec/factories/repository_rows.rb b/spec/factories/repository_rows.rb new file mode 100644 index 000000000..524db45f5 --- /dev/null +++ b/spec/factories/repository_rows.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :repository_row do + name 'Custom row' + created_by { User.first || association(:user) } + last_modified_by { User.first || association(:user) } + end +end diff --git a/spec/factories/sample_groups.rb b/spec/factories/sample_groups.rb new file mode 100644 index 000000000..5943a1557 --- /dev/null +++ b/spec/factories/sample_groups.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :sample_group do + name 'Sample' + color '#ff00ff' + team { Team.first || create(:team) } + end +end diff --git a/spec/factories/sample_my_modules.rb b/spec/factories/sample_my_modules.rb new file mode 100644 index 000000000..fbe1fcbc8 --- /dev/null +++ b/spec/factories/sample_my_modules.rb @@ -0,0 +1,6 @@ +FactoryGirl.define do + factory :sample_my_module do + sample { Sample.frist || create(:sample) } + my_module { MyModule.frist || create(:my_module) } + end +end diff --git a/spec/factories/sample_types.rb b/spec/factories/sample_types.rb new file mode 100644 index 000000000..90d0e4a67 --- /dev/null +++ b/spec/factories/sample_types.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :sample_type do + name 'Sample type' + end +end diff --git a/spec/factories/samples.rb b/spec/factories/samples.rb new file mode 100644 index 000000000..8b7b515e9 --- /dev/null +++ b/spec/factories/samples.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :sample do + name 'Sample' + user { User.first || create(:user) } + team { Team.first || create(:team) } + end +end diff --git a/spec/factories/samples_tables.rb b/spec/factories/samples_tables.rb new file mode 100644 index 000000000..5f14031c6 --- /dev/null +++ b/spec/factories/samples_tables.rb @@ -0,0 +1,4 @@ +FactoryGirl.define do + factory :samples_table do + end +end diff --git a/spec/factories/teams.rb b/spec/factories/teams.rb new file mode 100644 index 000000000..9d196212f --- /dev/null +++ b/spec/factories/teams.rb @@ -0,0 +1,8 @@ +FactoryGirl.define do + factory :team do + created_by { User.first || create(:user) } + name 'My team' + description 'Lorem ipsum dolor sit amet, consectetuer adipiscing eli.' + space_taken 1048576 + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb new file mode 100644 index 000000000..b60595471 --- /dev/null +++ b/spec/factories/users.rb @@ -0,0 +1,12 @@ +FactoryGirl.define do + factory :user do + full_name 'admin' + initials 'AD' + email 'admin_test@scinote.net' + password 'asdf1243' + password_confirmation 'asdf1243' + after(:create) do |user| + user.teams << (Team.first || FactoryGirl.create(:team)) + end + end +end diff --git a/spec/models/activity_spec.rb b/spec/models/activity_spec.rb new file mode 100644 index 000000000..fa4829942 --- /dev/null +++ b/spec/models/activity_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +describe Activity, type: :model do + it 'should be of class Activity' do + expect(subject.class).to eq Activity + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :my_module_id } + it { should have_db_column :user_id } + it { should have_db_column :type_of } + it { should have_db_column :message } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :project_id } + it { should have_db_column :experiment_id } + end + + describe 'Relations' do + it { should belong_to :project } + it { should belong_to :experiment } + it { should belong_to :my_module } + it { should belong_to :user } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :type_of } + end +end diff --git a/spec/models/asset_spec.rb b/spec/models/asset_spec.rb new file mode 100644 index 000000000..36b7d7365 --- /dev/null +++ b/spec/models/asset_spec.rb @@ -0,0 +1,48 @@ +require 'rails_helper' + +describe Asset, type: :model do + it 'should be of class Asset' do + expect(subject.class).to eq Asset + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :file_file_name } + it { should have_db_column :file_content_type } + it { should have_db_column :file_file_size } + it { should have_db_column :file_updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :estimated_size } + it { should have_db_column :file_present } + it { should have_db_column :lock } + it { should have_db_column :lock_ttl } + it { should have_db_column :version } + it { should have_db_column :file_processing } + it { should have_db_column :team_id } + end + + describe 'Relations' do + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should belong_to :team } + it { should have_many :report_elements } + it { should have_one :step_asset } + it { should have_one :step } + it { should have_one :result_asset } + it { should have_one :result } + it { should have_one :asset_text_datum } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :file } + it 'should validate the presence of estimated size' do + asset = build :asset, estimated_size: nil + expect(asset).to_not be_valid + end + # should validate_presence_of :estimated_size } + it { should validate_inclusion_of(:file_present).in_array([true, false]) } + end +end diff --git a/spec/models/asset_text_datum_spec.rb b/spec/models/asset_text_datum_spec.rb new file mode 100644 index 000000000..e959296df --- /dev/null +++ b/spec/models/asset_text_datum_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +describe AssetTextDatum, type: :model do + it 'should be of class Activity' do + expect(subject.class).to eq AssetTextDatum + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :data } + it { should have_db_column :asset_id } + it { should have_db_column :created_at } + it { should have_db_column :data_vector } + end + + describe 'Relations' do + it { should belong_to :asset } + end + + describe 'Should be a valid object' do + let(:asset) { create :asset } + + it { should validate_presence_of :data } + it { should validate_presence_of :asset } + + it 'should have uniq asset' do + create :asset_text_datum, asset: asset + new_atd = build :asset_text_datum, asset: asset + # binding.pry + expect(new_atd).to_not be_valid + end + end +end diff --git a/spec/models/checklist_item_spec.rb b/spec/models/checklist_item_spec.rb new file mode 100644 index 000000000..62dd392e6 --- /dev/null +++ b/spec/models/checklist_item_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +describe ChecklistItem, type: :model do + it 'should be of class ChecklistItem' do + expect(subject.class).to eq ChecklistItem + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :text } + it { should have_db_column :checked } + it { should have_db_column :checklist_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :position } + end + + describe 'Relations' do + it { should belong_to :checklist } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :text } + it { should validate_length_of(:text).is_at_most(Constants::TEXT_MAX_LENGTH) } + it { should validate_presence_of :checklist } + it { should validate_inclusion_of(:checked).in_array([true, false]) } + end +end diff --git a/spec/models/checklist_spec.rb b/spec/models/checklist_spec.rb new file mode 100644 index 000000000..61e765e29 --- /dev/null +++ b/spec/models/checklist_spec.rb @@ -0,0 +1,31 @@ +require 'rails_helper' + +describe Checklist, type: :model do + it 'should be of class Checklist' do + expect(subject.class).to eq Checklist + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :step_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to :step } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :report_elements } + it { should have_many :checklist_items } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_length_of(:name).is_at_most(Constants::TEXT_MAX_LENGTH) } + it { should validate_presence_of :step } + end +end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb new file mode 100644 index 000000000..215fad153 --- /dev/null +++ b/spec/models/comment_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +describe Comment, type: :model do + it 'should be of class Comment' do + expect(subject.class).to eq Comment + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :message } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :type } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :associated_id } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to(:last_modified_by).class_name('User') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :message } + it { should validate_length_of(:message).is_at_most(Constants::TEXT_MAX_LENGTH) } + it { should validate_presence_of :user } + end +end diff --git a/spec/models/connection_step b/spec/models/connection_step new file mode 100644 index 000000000..78eda9935 --- /dev/null +++ b/spec/models/connection_step @@ -0,0 +1,18 @@ +require 'rails_helper' + +describe Connection, type: :model do + it 'should be of class Connection' do + expect(subject.class).to eq Connection + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :input_id } + it { should have_db_column :output_id } + end + + describe 'Relations' do + it { should belong_to(:to).class_name('MyModule') } + it { should belong_to(:from).class_name('MyModule') } + end +end diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb new file mode 100644 index 000000000..292e96148 --- /dev/null +++ b/spec/models/custom_field_spec.rb @@ -0,0 +1,61 @@ +require 'rails_helper' + +describe CustomField, type: :model do + it 'should be of class CustomField' do + expect(subject.class).to eq CustomField + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :user_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :team } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :sample_custom_fields } + end + + describe 'Should be a valid object' do + before do + @user = create :user, email: 'example_one@adsf.com' + @team = create :team + @samples_table = create :samples_table, user: @user, team: @team + end + + it { should validate_presence_of :name } + it { should validate_presence_of :user } + + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + + it do + should validate_exclusion_of(:name).in_array( + ['Assigned', 'Sample name', 'Sample type', + 'Sample group', 'Added on', 'Added by'] + ) + end + + it 'should have uniq name scoped on team' do + create :custom_field, user: @user, team: @team + custom_field_two = build :custom_field, user: @user, team: @team + + expect(custom_field_two).to_not be_valid + end + + it 'should have uniq case sensitive name' do + build_stubbed :custom_field, name: 'custom one', user: @user, team: @team + cf = build :custom_field, name: 'CUSTOM ONE', user: @user, team: @team + + expect(cf).to be_valid + end + end +end diff --git a/spec/models/experiment_spec.rb b/spec/models/experiment_spec.rb new file mode 100644 index 000000000..d30877fa4 --- /dev/null +++ b/spec/models/experiment_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +describe Experiment, type: :model do + it 'should be of class Experiment' do + expect(subject.class).to eq Experiment + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :description } + it { should have_db_column :project_id } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :archived } + it { should have_db_column :archived_by_id } + it { should have_db_column :archived_on } + it { should have_db_column :restored_by_id } + it { should have_db_column :restored_on } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :workflowimg_file_name } + it { should have_db_column :workflowimg_content_type } + it { should have_db_column :workflowimg_file_size } + it { should have_db_column :workflowimg_updated_at } + end + + describe 'Relations' do + it { should belong_to :project } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should belong_to(:archived_by).class_name('User') } + it { should belong_to(:restored_by).class_name('User') } + it { should have_many :my_modules } + it { should have_many :my_module_groups } + it { should have_many :report_elements } + it { should have_many :activities } + end + + describe 'Should be a valid object' do + let(:project) { create :project } + it { should validate_presence_of :project } + it { should validate_presence_of :created_by } + it { should validate_presence_of :last_modified_by } + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + + it do + should validate_length_of(:description) + .is_at_most(Constants::TEXT_MAX_LENGTH) + end + + it 'should have uniq name scoped on project' do + create :experiment, name: 'experiment', + project: project, + created_by: project.created_by, + last_modified_by: project.created_by + new_exp = build_stubbed :experiment, name: 'experiment', + project: project, + created_by: project.created_by, + last_modified_by: project.created_by + expect(new_exp).to_not be_valid + end + end +end diff --git a/spec/models/my_module_group_spec.rb b/spec/models/my_module_group_spec.rb new file mode 100644 index 000000000..507d74d8e --- /dev/null +++ b/spec/models/my_module_group_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +describe MyModuleGroup, type: :model do + it 'should be of class MyModuleGroup' do + expect(subject.class).to eq MyModuleGroup + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :experiment_id } + end + + describe 'Relations' do + it { should belong_to :experiment } + it { should belong_to(:created_by).class_name('User') } + it { should have_many(:my_modules)} + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :experiment } + it { should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) } + end +end diff --git a/spec/models/my_module_repository_row_spec.rb b/spec/models/my_module_repository_row_spec.rb new file mode 100644 index 000000000..677692314 --- /dev/null +++ b/spec/models/my_module_repository_row_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +describe MyModuleRepositoryRow, type: :model do + it 'should be of class MyModuleRepositoryRow' do + expect(subject.class).to eq MyModuleRepositoryRow + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :repository_row_id } + it { should have_db_column :my_module_id } + it { should have_db_column :assigned_by_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :my_module } + it { should belong_to(:assigned_by).class_name('User') } + it { should belong_to :repository_row } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :repository_row } + it { should validate_presence_of :my_module } + end +end diff --git a/spec/models/my_module_spec.rb b/spec/models/my_module_spec.rb new file mode 100644 index 000000000..f926b4b34 --- /dev/null +++ b/spec/models/my_module_spec.rb @@ -0,0 +1,73 @@ +require 'rails_helper' + +describe MyModule, type: :model do + it 'should be of class MyModule' do + expect(subject.class).to eq MyModule + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :due_date } + it { should have_db_column :description } + it { should have_db_column :x } + it { should have_db_column :y } + it { should have_db_column :my_module_group_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :archived } + it { should have_db_column :archived_on } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :archived_by_id } + it { should have_db_column :restored_by_id } + it { should have_db_column :restored_on } + it { should have_db_column :nr_of_assigned_samples } + it { should have_db_column :workflow_order } + it { should have_db_column :experiment_id } + it { should have_db_column :state } + it { should have_db_column :completed_on } + end + + describe 'Relations' do + it { should belong_to :experiment } + it { should belong_to :my_module_group } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should belong_to(:archived_by).class_name('User') } + it { should belong_to(:restored_by).class_name('User') } + it { should have_many :results } + it { should have_many :my_module_tags } + it { should have_many :tags } + it { should have_many :task_comments } + it { should have_many :my_modules } + it { should have_many :sample_my_modules } + it { should have_many :samples } + it { should have_many :my_module_repository_rows } + it { should have_many :repository_rows } + it { should have_many :user_my_modules } + it { should have_many :users } + it { should have_many :activities } + it { should have_many :report_elements } + it { should have_many :protocols } + it { should have_many(:inputs).class_name('Connection') } + it { should have_many(:outputs).class_name('Connection') } + it { should have_many(:my_module_antecessors).class_name('MyModule') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :x } + it { should validate_presence_of :y } + it { should validate_presence_of :workflow_order } + it { should validate_presence_of :experiment } + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:description) + .is_at_most(Constants::TEXT_MAX_LENGTH) + end + end +end diff --git a/spec/models/my_module_tag_spec.rb b/spec/models/my_module_tag_spec.rb new file mode 100644 index 000000000..0045e8d57 --- /dev/null +++ b/spec/models/my_module_tag_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +describe MyModuleTag, type: :model do + it 'should be of class MyModuleTag' do + expect(subject.class).to eq MyModuleTag + end + + describe 'Database table' do + it { should have_db_column :my_module_id } + it { should have_db_column :tag_id } + it { should have_db_column :created_by_id } + end + + describe 'Relations' do + it { should belong_to :my_module } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to :tag } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :my_module } + it { should validate_presence_of :tag } + end +end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb new file mode 100644 index 000000000..e54539b00 --- /dev/null +++ b/spec/models/notification_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +describe Notification, type: :model do + it 'should be of class Notification' do + expect(subject.class).to eq Notification + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :title } + it { should have_db_column :message } + it { should have_db_column :type_of } + it { should have_db_column :generator_user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to(:generator_user).class_name('User') } + it { should have_many :users } + it { should have_many :user_notifications } + end +end diff --git a/spec/models/project_comment_spec.rb b/spec/models/project_comment_spec.rb new file mode 100644 index 000000000..cdefd4449 --- /dev/null +++ b/spec/models/project_comment_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe Comment::ProjectComment, type: :model do + it 'should be of class MyModuleTag' do + expect(subject.class).to eq Comment::ProjectComment + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :message } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :type } + it { should have_db_column :associated_id } + end + + describe 'Relations' do + it { should belong_to(:project).with_foreign_key('associated_id') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :project } + end +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb new file mode 100644 index 000000000..c0f9fe1e4 --- /dev/null +++ b/spec/models/project_spec.rb @@ -0,0 +1,65 @@ +require 'rails_helper' + +describe Project, type: :model do + it 'should be of class Project' do + expect(subject.class).to eq Project + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :name } + it { should have_db_column :visibility } + it { should have_db_column :due_date } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :archived } + it { should have_db_column :archived_on } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :archived_by_id } + it { should have_db_column :restored_by_id } + it { should have_db_column :restored_on } + it { should have_db_column :experiments_order } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should belong_to(:archived_by).class_name('User') } + it { should belong_to(:restored_by).class_name('User') } + it { should have_many :user_projects } + it { should have_many :users } + it { should have_many :experiments } + it { should have_many :project_comments } + it { should have_many :activities } + it { should have_many :tags } + it { should have_many :reports } + it { should have_many :report_elements } + end + + describe 'Should be a valid object' do + let(:user) { create :user } + let(:team) { create :team, created_by: user } + it { should validate_presence_of :visibility } + it { should validate_presence_of :team } + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + + it 'should have a unique name scoped to team' do + FactoryGirl.create :project, + created_by: user, + last_modified_by: user, + team: team + project_two = FactoryGirl.build :project, + created_by: user, + last_modified_by: user, + team: team + expect(project_two).to_not be_valid + end + end +end diff --git a/spec/models/protocol_keyword_spec.rb b/spec/models/protocol_keyword_spec.rb new file mode 100644 index 000000000..459580f5b --- /dev/null +++ b/spec/models/protocol_keyword_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +describe ProtocolKeyword, type: :model do + it 'should be of class ProtocolKeyword' do + expect(subject.class).to eq ProtocolKeyword + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :nr_of_protocols } + it { should have_db_column :team_id } + end + + describe 'Relations' do + it { should belong_to :team } + it { should have_many :protocol_protocol_keywords } + it { should have_many :protocols } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :team } + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + end +end diff --git a/spec/models/protocol_protocol_keyword_spec.rb b/spec/models/protocol_protocol_keyword_spec.rb new file mode 100644 index 000000000..afad606cc --- /dev/null +++ b/spec/models/protocol_protocol_keyword_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe ProtocolProtocolKeyword, type: :model do + it 'should be of class ProtocolProtocolKeyword' do + expect(subject.class).to eq ProtocolProtocolKeyword + end + + describe 'Database table' do + it { should have_db_column :protocol_id } + it { should have_db_column :protocol_keyword_id } + end + + describe 'Relations' do + it { should belong_to :protocol } + it { should belong_to :protocol_keyword } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :protocol } + it { should validate_presence_of :protocol_keyword } + end +end diff --git a/spec/models/protocol_spec.rb b/spec/models/protocol_spec.rb new file mode 100644 index 000000000..32b84db71 --- /dev/null +++ b/spec/models/protocol_spec.rb @@ -0,0 +1,52 @@ +require 'rails_helper' + +describe Protocol, type: :model do + it 'should be of class Protocol' do + expect(subject.class).to eq Protocol + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :authors } + it { should have_db_column :description } + it { should have_db_column :added_by_id } + it { should have_db_column :my_module_id } + it { should have_db_column :team_id } + it { should have_db_column :protocol_type } + it { should have_db_column :parent_id } + it { should have_db_column :parent_updated_at } + it { should have_db_column :archived_by_id } + it { should have_db_column :archived_on } + it { should have_db_column :restored_by_id } + it { should have_db_column :restored_on } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :published_on } + it { should have_db_column :nr_of_linked_children } + end + + describe 'Relations' do + it { should belong_to :my_module } + it { should belong_to :team } + it { should belong_to(:added_by).class_name('User') } + it { should belong_to(:parent).class_name('Protocol') } + it { should belong_to(:archived_by).class_name('User') } + it { should belong_to(:restored_by).class_name('User') } + it { should have_many(:linked_children).class_name('Protocol') } + it { should have_many :protocol_protocol_keywords } + it { should have_many :protocol_keywords } + it { should have_many :steps } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :team } + it { should validate_presence_of :protocol_type } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:description) + .is_at_most(Constants::TEXT_MAX_LENGTH) + end + end +end diff --git a/spec/models/report_element_spec.rb b/spec/models/report_element_spec.rb new file mode 100644 index 000000000..965aa5296 --- /dev/null +++ b/spec/models/report_element_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +describe ReportElement, type: :model do + it 'should be of class ReportElement' do + expect(subject.class).to eq ReportElement + end + + describe 'Database table' do + it { should have_db_column :position } + it { should have_db_column :type_of } + it { should have_db_column :sort_order } + it { should have_db_column :report_id } + it { should have_db_column :parent_id } + it { should have_db_column :project_id } + it { should have_db_column :my_module_id } + it { should have_db_column :step_id } + it { should have_db_column :result_id } + it { should have_db_column :checklist_id } + it { should have_db_column :asset_id } + it { should have_db_column :table_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :experiment_id } + it { should have_db_column :repository_id } + end + + describe 'Relations' do + it { should belong_to :report } + it { should belong_to :project } + it { should belong_to :experiment } + it { should belong_to :my_module } + it { should belong_to :step } + it { should belong_to :result } + it { should belong_to :checklist } + it { should belong_to :asset } + it { should belong_to :table } + it { should belong_to :repository } + it { should belong_to(:report) } + it { should have_many(:children).class_name('ReportElement') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :position } + it { should validate_presence_of :report } + it { should validate_presence_of :type_of } + end +end diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb new file mode 100644 index 000000000..1dd288081 --- /dev/null +++ b/spec/models/report_spec.rb @@ -0,0 +1,44 @@ +require 'rails_helper' + +describe Report, type: :model do + it 'should be of class Report' do + expect(subject.class).to eq Report + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :description } + it { should have_db_column :project_id } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to :project } + it { should belong_to :user } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :report_elements } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :project } + it { should validate_presence_of :user } + it do + should validate_length_of(:description) + .is_at_most(Constants::TEXT_MAX_LENGTH) + end + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + + it 'should have uniq name scoped to user, project' do + create :report, name: 'Same Name' + new_rep = build :report, name: 'Same Name' + expect(new_rep).to_not be_valid + end + end +end diff --git a/spec/models/repository_cell_spec.rb b/spec/models/repository_cell_spec.rb new file mode 100644 index 000000000..44f66259f --- /dev/null +++ b/spec/models/repository_cell_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe RepositoryCell, type: :model do + it 'should be of class RepositoryCell' do + expect(subject.class).to eq RepositoryCell + end + + describe 'Database table' do + it { should have_db_column :repository_row_id } + it { should have_db_column :repository_column_id } + it { should have_db_column :value_id } + it { should have_db_column :value_type } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :repository_row } + it { should belong_to :repository_column } + end +end diff --git a/spec/models/repository_column_spec.rb b/spec/models/repository_column_spec.rb new file mode 100644 index 000000000..0ba1b8807 --- /dev/null +++ b/spec/models/repository_column_spec.rb @@ -0,0 +1,39 @@ +require 'rails_helper' + +describe RepositoryColumn, type: :model do + it 'should be of class RepositoryColumn' do + expect(subject.class).to eq RepositoryColumn + end + + describe 'Database table' do + it { should have_db_column :repository_id } + it { should have_db_column :created_by_id } + it { should have_db_column :name } + it { should have_db_column :data_type } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :repository } + it { should belong_to(:created_by).class_name('User') } + it { should have_many :repository_cells } + it { should have_many :repository_rows } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :created_by } + it { should validate_presence_of :repository } + it { should validate_presence_of :data_type } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it 'have uniq name scoped to repository' do + create :repository_column, name: 'Repo One' + column_two = build :repository_column, name: 'Repo One' + + expect(column_two).to_not be_valid + end + end +end diff --git a/spec/models/repository_date_value_spec.rb b/spec/models/repository_date_value_spec.rb new file mode 100644 index 000000000..2cdcaa347 --- /dev/null +++ b/spec/models/repository_date_value_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe RepositoryDateValue, type: :model do + it 'should be of class RepositoryDateValue' do + expect(subject.class).to eq RepositoryDateValue + end + + describe 'Database table' do + it { should have_db_column :data } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_one :repository_cell } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :repository_cell } + it { should validate_presence_of :data } + end +end diff --git a/spec/models/repository_row_spec.rb b/spec/models/repository_row_spec.rb new file mode 100644 index 000000000..40830d4b2 --- /dev/null +++ b/spec/models/repository_row_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +describe RepositoryRow, type: :model do + it 'should be of class RepositoryRow' do + expect(subject.class).to eq RepositoryRow + end + + describe 'Database table' do + it { should have_db_column :repository_id } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :repository } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :repository_cells } + it { should have_many :repository_columns } + it { should have_many :my_module_repository_rows } + it { should have_many :my_modules } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :created_by } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + end +end diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb new file mode 100644 index 000000000..6a927f715 --- /dev/null +++ b/spec/models/repository_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe Repository, type: :model do + it 'should be of class Repository' do + expect(subject.class).to eq Repository + end + + describe 'Database table' do + it { should have_db_column :team_id } + it { should have_db_column :created_by_id } + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to(:created_by).class_name('User') } + it { should have_many :repository_rows } + it { should have_many :repository_table_states } + it { should have_many :report_elements } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :team } + it { should validate_presence_of :created_by } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + + it 'should have uniq name scoped to team' do + create :repository, name: 'Repository One' + repo = build :repository, name: 'Repository One' + expect(repo).to_not be_valid + end + + it 'should have uniq name scoped to team calse insensitive' do + create :repository, name: 'Repository One' + repo = build :repository, name: 'REPOSITORY ONE' + expect(repo).to_not be_valid + end + end +end diff --git a/spec/models/repository_table_state_spec.rb b/spec/models/repository_table_state_spec.rb new file mode 100644 index 000000000..95490f00d --- /dev/null +++ b/spec/models/repository_table_state_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe RepositoryTableState, type: :model do + it 'should be of class RepositoryTableState' do + expect(subject.class).to eq RepositoryTableState + end + + describe 'Database table' do + it { should have_db_column :state } + it { should have_db_column :user_id } + it { should have_db_column :repository_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :repository } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :user } + it { should validate_presence_of :repository } + end +end diff --git a/spec/models/repository_text_value_spec.rb b/spec/models/repository_text_value_spec.rb new file mode 100644 index 000000000..151a6c5e8 --- /dev/null +++ b/spec/models/repository_text_value_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +describe RepositoryTextValue, type: :model do + it 'should be of class RepositoryTextValue' do + expect(subject.class).to eq RepositoryTextValue + end + + describe 'Database table' do + it { should have_db_column :data } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_one :repository_cell } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :repository_cell } + it { should validate_presence_of :data } + it do + should validate_length_of(:data).is_at_most(Constants::TEXT_MAX_LENGTH) + end + end +end diff --git a/spec/models/result_asset_spec.rb b/spec/models/result_asset_spec.rb new file mode 100644 index 000000000..7729e222c --- /dev/null +++ b/spec/models/result_asset_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe ResultAsset, type: :model do + it 'should be of class ResultAsset' do + expect(subject.class).to eq ResultAsset + end + + describe 'Database table' do + it { should have_db_column :result_id } + it { should have_db_column :asset_id } + end + + describe 'Relations' do + it { should belong_to :result } + it { should belong_to :asset } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :result } + it { should validate_presence_of :asset } + end +end diff --git a/spec/models/result_comment_spec.rb b/spec/models/result_comment_spec.rb new file mode 100644 index 000000000..e47b00f2d --- /dev/null +++ b/spec/models/result_comment_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe ResultComment, type: :model do + it 'should be of class ResultComment' do + expect(subject.class).to eq ResultComment + end + + describe 'Database table' do + it { should have_db_column :message } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :type } + it { should have_db_column :associated_id } + end + + describe 'Relations' do + it { should belong_to :result } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :result } + end +end diff --git a/spec/models/result_spec.rb b/spec/models/result_spec.rb new file mode 100644 index 000000000..35cfbcef8 --- /dev/null +++ b/spec/models/result_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe Result, type: :model do + it 'should be of class Result' do + expect(subject.class).to eq Result + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :my_module_id } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :archived } + it { should have_db_column :archived_on } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :archived_by_id } + it { should have_db_column :restored_by_id } + it { should have_db_column :restored_on } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :my_module } + it { should belong_to(:archived_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should belong_to(:restored_by).class_name('User') } + it { should have_one :result_asset } + it { should have_one :asset } + it { should have_one :result_table } + it { should have_one :table } + it { should have_one :result_text } + it { should have_many :result_comments } + it { should have_many :report_elements } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :user } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + end +end diff --git a/spec/models/result_table_spec.rb b/spec/models/result_table_spec.rb new file mode 100644 index 000000000..8bda00fa2 --- /dev/null +++ b/spec/models/result_table_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe ResultTable, type: :model do + it 'should be of class ResultTable' do + expect(subject.class).to eq ResultTable + end + + describe 'Database table' do + it { should have_db_column :result_id } + it { should have_db_column :table_id } + end + + describe 'Relations' do + it { should belong_to :result } + it { should belong_to :table } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :result } + it { should validate_presence_of :table } + end +end diff --git a/spec/models/result_text_spec.rb b/spec/models/result_text_spec.rb new file mode 100644 index 000000000..83e05e2b7 --- /dev/null +++ b/spec/models/result_text_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe ResultText, type: :model do + it 'should be of class ResultText' do + expect(subject.class).to eq ResultText + end + + describe 'Database table' do + it { should have_db_column :result_id } + it { should have_db_column :text } + end + + describe 'Relations' do + it { should belong_to :result } + it { should have_many :tiny_mce_assets } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :text } + it { should validate_presence_of :result } + it do + should validate_length_of(:text) + .is_at_most(Constants::RICH_TEXT_MAX_LENGTH) + end + end +end diff --git a/spec/models/sample_custom_field_spec.rb b/spec/models/sample_custom_field_spec.rb new file mode 100644 index 000000000..f04023cd7 --- /dev/null +++ b/spec/models/sample_custom_field_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +describe SampleCustomField, type: :model do + it 'should be of class SampleCustomField' do + expect(subject.class).to eq SampleCustomField + end + + describe 'Database table' do + it { should have_db_column :value } + it { should have_db_column :custom_field_id } + it { should have_db_column :sample_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :custom_field } + it { should belong_to :sample } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :value } + it { should validate_presence_of :custom_field } + it { should validate_presence_of :sample } + it do + should validate_length_of(:value).is_at_most(Constants::NAME_MAX_LENGTH) + end + end +end diff --git a/spec/models/sample_group_spec.rb b/spec/models/sample_group_spec.rb new file mode 100644 index 000000000..45fe8e100 --- /dev/null +++ b/spec/models/sample_group_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +describe SampleGroup, type: :model do + it 'should be of class SampleGroup' do + expect(subject.class).to eq SampleGroup + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :color } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :samples } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :color } + it { should validate_presence_of :team } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:color).is_at_most(Constants::COLOR_MAX_LENGTH) + end + it 'should have uniq name scoped to team' do + create :sample_group, name: 'My Group' + new_group = build :sample_group, name: 'My Group' + + expect(new_group).to_not be_valid + end + end +end diff --git a/spec/models/sample_my_module_spec.rb b/spec/models/sample_my_module_spec.rb new file mode 100644 index 000000000..ead544cf3 --- /dev/null +++ b/spec/models/sample_my_module_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +describe SampleMyModule, type: :model do + it 'should be of class SampleMyModule' do + expect(subject.class).to eq SampleMyModule + end + + describe 'Database table' do + it { should have_db_column :sample_id } + it { should have_db_column :my_module_id } + it { should have_db_column :assigned_by_id } + it { should have_db_column :assigned_on } + end + + describe 'Relations' do + it { should belong_to(:assigned_by).class_name('User') } + it { should belong_to :sample } + it { should belong_to :my_module } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :sample } + it { should validate_presence_of :my_module } + + it 'should have one sample assigned per model' do + sample = create :sample + my_module = create :my_module, name: 'Module one' + create :sample_my_module, sample: sample, my_module: my_module + new_smm = build :sample_my_module, sample: sample, my_module: my_module + expect(new_smm).to_not be_valid + end + end +end diff --git a/spec/models/sample_spec.rb b/spec/models/sample_spec.rb new file mode 100644 index 000000000..94afa6196 --- /dev/null +++ b/spec/models/sample_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +describe Sample, type: :model do + it 'should be of class Sample' do + expect(subject.class).to eq Sample + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :user_id } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :sample_group_id } + it { should have_db_column :sample_type_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :nr_of_modules_assigned_to } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :team } + it { should belong_to :sample_group } + it { should belong_to :sample_type } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :sample_my_modules } + it { should have_many :my_modules } + it { should have_many :sample_custom_fields } + it { should have_many :custom_fields } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :user } + it { should validate_presence_of :team } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + end +end diff --git a/spec/models/sample_type_spec.rb b/spec/models/sample_type_spec.rb new file mode 100644 index 000000000..e2b240802 --- /dev/null +++ b/spec/models/sample_type_spec.rb @@ -0,0 +1,45 @@ +require 'rails_helper' + +describe SampleType, type: :model do + it 'should be of class SampleType' do + expect(subject.class).to eq SampleType + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :samples } + end + + describe 'Should be a valid object' do + let(:team) { create :team } + + it { should validate_presence_of :name } + it { should validate_presence_of :team } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + + it 'should have uniq name scoped to team' do + create :sample_type, name: 'Sample one', team: team + new_type = build :sample_type, name: 'Sample one', team: team + expect(new_type).to_not be_valid + end + + it 'should not be case sensitive' do + create :sample_type, name: 'Sample T', team: team + new_type = build :sample_type, name: 'SAMPLE T', team: team + expect(new_type).to_not be_valid + end + end +end diff --git a/spec/models/samples_table_spec.rb b/spec/models/samples_table_spec.rb new file mode 100644 index 000000000..f7773bca6 --- /dev/null +++ b/spec/models/samples_table_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe SamplesTable, type: :model do + it 'should be of class SamplesTable' do + expect(subject.class).to eq SamplesTable + end + + describe 'Database table' do + it { should have_db_column :status } + it { should have_db_column :user_id } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :team } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :team } + it { should validate_presence_of :user } + end +end diff --git a/spec/models/settings_spec.rb b/spec/models/settings_spec.rb new file mode 100644 index 000000000..f37097dcb --- /dev/null +++ b/spec/models/settings_spec.rb @@ -0,0 +1,12 @@ +require 'rails_helper' + +describe Settings, type: :model do + it 'should be of class Settings' do + expect(subject.class).to eq Settings + end + + describe 'Database table' do + it { should have_db_column :type } + it { should have_db_column :values } + end +end diff --git a/spec/models/step_asset_spec.rb b/spec/models/step_asset_spec.rb new file mode 100644 index 000000000..7ff4fb76f --- /dev/null +++ b/spec/models/step_asset_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe StepAsset, type: :model do + it 'should be of class StepAsset' do + expect(subject.class).to eq StepAsset + end + + describe 'Database table' do + it { should have_db_column :step_id } + it { should have_db_column :asset_id } + end + + describe 'Relations' do + it { should belong_to :step } + it { should belong_to :asset } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :step } + it { should validate_presence_of :asset } + end +end diff --git a/spec/models/step_comment_spec.rb b/spec/models/step_comment_spec.rb new file mode 100644 index 000000000..24f77fc7a --- /dev/null +++ b/spec/models/step_comment_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe StepComment, type: :model do + it 'should be of class StepComment' do + expect(subject.class).to eq StepComment + end + + describe 'Database table' do + it { should have_db_column :message } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :type } + it { should have_db_column :associated_id } + end + + describe 'Relations' do + it { should belong_to :step } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :step } + end +end diff --git a/spec/models/step_spec.rb b/spec/models/step_spec.rb new file mode 100644 index 000000000..e9ab4db52 --- /dev/null +++ b/spec/models/step_spec.rb @@ -0,0 +1,49 @@ +require 'rails_helper' + +describe Step, type: :model do + it 'should be of class Step' do + expect(subject.class).to eq Step + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :description } + it { should have_db_column :position } + it { should have_db_column :completed } + it { should have_db_column :completed_on } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :protocol_id } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :protocol } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :checklists } + it { should have_many :step_comments } + it { should have_many :step_assets } + it { should have_many :assets } + it { should have_many :step_tables } + it { should have_many :tables } + it { should have_many :report_elements } + it { should have_many :tiny_mce_assets } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :position } + it { should validate_presence_of :user } + it { should validate_presence_of :protocol } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:description) + .is_at_most(Constants::RICH_TEXT_MAX_LENGTH) + end + it { should validate_inclusion_of(:completed).in_array([true, false]) } + end +end diff --git a/spec/models/step_table_spec.rb b/spec/models/step_table_spec.rb new file mode 100644 index 000000000..eb46ef53a --- /dev/null +++ b/spec/models/step_table_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe StepTable, type: :model do + it 'should be of class StepTable' do + expect(subject.class).to eq StepTable + end + + describe 'Database table' do + it { should have_db_column :step_id } + it { should have_db_column :table_id } + end + + describe 'Relations' do + it { should belong_to :step } + it { should belong_to :table } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :step } + end +end diff --git a/spec/models/table_spec.rb b/spec/models/table_spec.rb new file mode 100644 index 000000000..0865458ba --- /dev/null +++ b/spec/models/table_spec.rb @@ -0,0 +1,40 @@ +require 'rails_helper' + +describe Table, type: :model do + it 'should be of class Table' do + expect(subject.class).to eq Table + end + + describe 'Database table' do + it { should have_db_column :contents } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :data_vector } + it { should have_db_column :name } + it { should have_db_column :team_id } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_one :step_table } + it { should have_one :step } + it { should have_one :result_table } + it { should have_one :result } + it { should have_many :report_elements } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :contents } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:contents) + .is_at_most(Constants::TABLE_JSON_MAX_SIZE_MB.megabytes) + end + end +end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb new file mode 100644 index 000000000..e95c7abef --- /dev/null +++ b/spec/models/tag_spec.rb @@ -0,0 +1,37 @@ +require 'rails_helper' + +describe Tag, type: :model do + it 'should be of class Tag' do + expect(subject.class).to eq Tag + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :color } + it { should have_db_column :project_id } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + end + + describe 'Relations' do + it { should belong_to :project } + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :my_module_tags } + it { should have_many :my_modules } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :color } + it { should validate_presence_of :project } + it do + should validate_length_of(:name).is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:color).is_at_most(Constants::COLOR_MAX_LENGTH) + end + end +end diff --git a/spec/models/task_comment_spec.rb b/spec/models/task_comment_spec.rb new file mode 100644 index 000000000..fa832b144 --- /dev/null +++ b/spec/models/task_comment_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe TaskComment, type: :model do + it 'should be of class TaskComment' do + expect(subject.class).to eq TaskComment + end + + describe 'Database table' do + it { should have_db_column :message } + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :type } + it { should have_db_column :associated_id } + end + + describe 'Relations' do + it { should belong_to :my_module } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :my_module } + end +end diff --git a/spec/models/team_spec.rb b/spec/models/team_spec.rb new file mode 100644 index 000000000..cfdf642bf --- /dev/null +++ b/spec/models/team_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' + +describe Team, type: :model do + it 'should be of class Team' do + expect(subject.class).to eq Team + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :created_by_id } + it { should have_db_column :last_modified_by_id } + it { should have_db_column :description } + it { should have_db_column :space_taken } + end + + describe 'Relations' do + it { should belong_to(:created_by).class_name('User') } + it { should belong_to(:last_modified_by).class_name('User') } + it { should have_many :user_teams } + it { should have_many :users } + it { should have_many :samples } + it { should have_many :samples_tables } + it { should have_many :sample_groups } + it { should have_many :sample_types } + it { should have_many :projects } + it { should have_many :custom_fields } + it { should have_many :protocols } + it { should have_many :protocol_keywords } + it { should have_many :tiny_mce_assets } + it { should have_many :repositories } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :space_taken } + it do + should validate_length_of(:name) + .is_at_least(Constants::NAME_MIN_LENGTH) + .is_at_most(Constants::NAME_MAX_LENGTH) + end + it do + should validate_length_of(:description) + .is_at_most(Constants::TEXT_MAX_LENGTH) + end + end +end diff --git a/spec/models/temp_file_spec.rb b/spec/models/temp_file_spec.rb new file mode 100644 index 000000000..1f5113f86 --- /dev/null +++ b/spec/models/temp_file_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe TempFile, type: :model do + it 'should be of class TempFile' do + expect(subject.class).to eq TempFile + end + + describe 'Database table' do + it { should have_db_column :session_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :file_file_name } + it { should have_db_column :file_content_type } + it { should have_db_column :file_file_size } + it { should have_db_column :file_updated_at } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :session_id } + end +end diff --git a/spec/models/tiny_mce_asset_spec.rb b/spec/models/tiny_mce_asset_spec.rb new file mode 100644 index 000000000..c97b1f8cd --- /dev/null +++ b/spec/models/tiny_mce_asset_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +describe TinyMceAsset, type: :model do + it 'should be of class TinyMceAsset' do + expect(subject.class).to eq TinyMceAsset + end + + describe 'Database table' do + it { should have_db_column :image_file_name } + it { should have_db_column :image_content_type } + it { should have_db_column :image_file_size } + it { should have_db_column :image_updated_at } + it { should have_db_column :estimated_size } + it { should have_db_column :step_id } + it { should have_db_column :team_id } + it { should have_db_column :result_text_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :team } + it { should belong_to :step } + it { should belong_to :result_text } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :estimated_size } + end +end diff --git a/spec/models/token_spec.rb b/spec/models/token_spec.rb new file mode 100644 index 000000000..a87877310 --- /dev/null +++ b/spec/models/token_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +describe Token, type: :model do + it 'should be of class Token' do + expect(subject.class).to eq Token + end + + describe 'Database table' do + it { should have_db_column :token } + it { should have_db_column :ttl } + it { should have_db_column :user_id } + end + + describe 'Relations' do + it { should belong_to :user } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :token } + it { should validate_presence_of :ttl } + end +end diff --git a/spec/models/user_my_module_spec.rb b/spec/models/user_my_module_spec.rb new file mode 100644 index 000000000..5ba89fdef --- /dev/null +++ b/spec/models/user_my_module_spec.rb @@ -0,0 +1,26 @@ +require 'rails_helper' + +describe UserMyModule, type: :model do + it 'should be of class UserMyModule' do + expect(subject.class).to eq UserMyModule + end + + describe 'Database table' do + it { should have_db_column :user_id } + it { should have_db_column :my_module_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :assigned_by_id } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :my_module } + it { should belong_to(:assigned_by).class_name('User') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :user } + it { should validate_presence_of :my_module } + end +end diff --git a/spec/models/user_notification_spec.rb b/spec/models/user_notification_spec.rb new file mode 100644 index 000000000..70eb9445f --- /dev/null +++ b/spec/models/user_notification_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe UserNotification, type: :model do + it 'should be of class UserNotification' do + expect(subject.class).to eq UserNotification + end + + describe 'Database table' do + it { should have_db_column :user_id } + it { should have_db_column :notification_id } + it { should have_db_column :checked } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :notification } + end +end diff --git a/spec/models/user_project_spec.rb b/spec/models/user_project_spec.rb new file mode 100644 index 000000000..18883e775 --- /dev/null +++ b/spec/models/user_project_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +describe UserProject, type: :model do + it 'should be of class UserProject' do + expect(subject.class).to eq UserProject + end + + describe 'Database table' do + it { should have_db_column :role } + it { should have_db_column :user_id } + it { should have_db_column :project_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :assigned_by_id } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :project } + it { should belong_to(:assigned_by).class_name('User') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :role } + it { should validate_presence_of :user } + it { should validate_presence_of :project } + end +end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 000000000..aa55b0a06 --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,152 @@ +require 'rails_helper' + +describe User, type: :model do + it 'should be of class User' do + expect(subject.class).to eq User + end + + describe 'Database table' do + it { should have_db_column :id } + it { should have_db_column :full_name } + it { should have_db_column :initials } + it { should have_db_column :email } + it { should have_db_column :encrypted_password } + it { should have_db_column :reset_password_token } + it { should have_db_column :reset_password_sent_at } + it { should have_db_column :sign_in_count } + it { should have_db_column :current_sign_in_at } + it { should have_db_column :last_sign_in_at } + it { should have_db_column :current_sign_in_ip } + it { should have_db_column :last_sign_in_ip } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :avatar_file_name } + it { should have_db_column :avatar_content_type } + it { should have_db_column :avatar_file_size } + it { should have_db_column :avatar_updated_at } + it { should have_db_column :confirmation_token } + it { should have_db_column :confirmed_at } + it { should have_db_column :confirmation_sent_at } + it { should have_db_column :unconfirmed_email } + it { should have_db_column :time_zone } + it { should have_db_column :invitation_token } + it { should have_db_column :invitation_created_at } + it { should have_db_column :invitation_sent_at } + it { should have_db_column :invitation_accepted_at } + it { should have_db_column :invitation_limit } + it { should have_db_column :invited_by_id } + it { should have_db_column :invited_by_type } + it { should have_db_column :invitations_count } + it { should have_db_column :tutorial_status } + it { should have_db_column :assignments_notification } + it { should have_db_column :recent_notification } + it { should have_db_column :assignments_notification_email } + it { should have_db_column :recent_notification_email } + it { should have_db_column :current_team_id } + it { should have_db_column :system_message_notification_email } + it { should have_db_column :authentication_token } + end + + describe 'Relations' do + it { should have_many :user_teams } + it { should have_many :teams } + it { should have_many :user_projects } + it { should have_many :projects } + it { should have_many :user_my_modules } + it { should have_many :comments } + it { should have_many :activities } + it { should have_many :results } + it { should have_many :samples } + it { should have_many :samples_tables } + it { should have_many :repositories } + it { should have_many :repository_table_states } + it { should have_many :steps } + it { should have_many :custom_fields } + it { should have_many :reports } + it { should have_many :created_assets } + it { should have_many :modified_assets } + it { should have_many :created_checklists } + it { should have_many :modified_checklists } + it { should have_many :created_checklist_items } + it { should have_many :modified_checklist_items } + it { should have_many :modified_comments } + it { should have_many :modified_custom_fields } + it { should have_many :created_my_module_groups } + it { should have_many :created_my_module_tags } + it { should have_many :created_my_modules } + it { should have_many :modified_my_modules } + it { should have_many :archived_my_modules } + it { should have_many :restored_my_modules } + it { should have_many :created_teams } + it { should have_many :modified_teams } + it { should have_many :created_projects } + it { should have_many :modified_projects } + it { should have_many :archived_projects } + it { should have_many :restored_projects } + it { should have_many :modified_reports } + it { should have_many :modified_results } + it { should have_many :archived_results } + it { should have_many :restored_results } + it { should have_many :created_sample_groups } + it { should have_many :modified_sample_groups } + it { should have_many :assigned_sample_my_modules } + it { should have_many :created_sample_types } + it { should have_many :modified_sample_types } + it { should have_many :modified_samples } + it { should have_many :modified_steps } + it { should have_many :created_tables } + it { should have_many :modified_tables } + it { should have_many :created_tags } + it { should have_many :tokens } + it { should have_many :modified_tags } + it { should have_many :assigned_user_my_modules } + it { should have_many :assigned_user_teams } + it { should have_many :assigned_user_projects } + it { should have_many :added_protocols } + it { should have_many :archived_protocols } + it { should have_many :restored_protocols } + it { should have_many :assigned_my_module_repository_rows } + it { should have_many :user_notifications } + it { should have_many :notifications } + it { should have_many :zip_exports } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :full_name } + it { should validate_presence_of :initials } + it { should validate_presence_of :email } + it { should validate_presence_of :time_zone } + + it do + should validate_length_of(:full_name).is_at_most( + Constants::NAME_MAX_LENGTH + ) + end + + it do + should validate_length_of(:initials).is_at_most( + Constants::USER_INITIALS_MAX_LENGTH + ) + end + + it do + should validate_length_of(:email).is_at_most( + Constants::EMAIL_MAX_LENGTH + ) + end + end + + describe 'Should return a user name' do + let(:user) { build :user, full_name: 'Tinker' } + + it 'should return a user full name' do + expect(user.name).to eq 'Tinker' + end + + it 'should to be able to change full name' do + user.name = 'Axe' + expect(user.name).to_not eq 'Tinker' + expect(user.name).to eq 'Axe' + end + end +end diff --git a/spec/models/user_team_spec.rb b/spec/models/user_team_spec.rb new file mode 100644 index 000000000..8ca01063f --- /dev/null +++ b/spec/models/user_team_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +describe UserTeam, type: :model do + it 'should be of class UserTeam' do + expect(subject.class).to eq UserTeam + end + + describe 'Database table' do + it { should have_db_column :role } + it { should have_db_column :user_id } + it { should have_db_column :team_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :assigned_by_id } + end + + describe 'Relations' do + it { should belong_to :user } + it { should belong_to :team } + it { should belong_to(:assigned_by).class_name('User') } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :role } + it { should validate_presence_of :user } + it { should validate_presence_of :team } + end +end diff --git a/spec/models/wopi_action_spec.rb b/spec/models/wopi_action_spec.rb new file mode 100644 index 000000000..cc9c1353f --- /dev/null +++ b/spec/models/wopi_action_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe WopiAction, type: :model do + it 'should be of class WopiAction' do + expect(subject.class).to eq WopiAction + end + + describe 'Database table' do + it { should have_db_column :action } + it { should have_db_column :extension } + it { should have_db_column :urlsrc } + it { should have_db_column :wopi_app_id } + end + + describe 'Relations' do + it { should belong_to(:wopi_app) } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :action } + it { should validate_presence_of :extension } + it { should validate_presence_of :urlsrc } + it { should validate_presence_of :wopi_app } + end +end diff --git a/spec/models/wopi_app_spec.rb b/spec/models/wopi_app_spec.rb new file mode 100644 index 000000000..fd38579cc --- /dev/null +++ b/spec/models/wopi_app_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +describe WopiApp, type: :model do + it 'should be of class WopiApp' do + expect(subject.class).to eq WopiApp + end + + describe 'Database table' do + it { should have_db_column :name } + it { should have_db_column :icon } + it { should have_db_column :wopi_discovery_id } + end + + describe 'Relations' do + it { should belong_to :wopi_discovery } + it { should have_many :wopi_actions } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :name } + it { should validate_presence_of :icon } + it { should validate_presence_of :wopi_discovery } + end +end diff --git a/spec/models/wopi_discovery_spec.rb b/spec/models/wopi_discovery_spec.rb new file mode 100644 index 000000000..009c0caa5 --- /dev/null +++ b/spec/models/wopi_discovery_spec.rb @@ -0,0 +1,27 @@ +require 'rails_helper' + +describe WopiDiscovery, type: :model do + it 'should be of class WopiDiscovery' do + expect(subject.class).to eq WopiDiscovery + end + + describe 'Database table' do + it { should have_db_column :expires } + it { should have_db_column :proof_key_mod } + it { should have_db_column :proof_key_exp } + it { should have_db_column :proof_key_old_mod } + it { should have_db_column :proof_key_old_exp } + end + + describe 'Relations' do + it { should have_many :wopi_apps } + end + + describe 'Should be a valid object' do + it { should validate_presence_of :expires } + it { should validate_presence_of :proof_key_mod } + it { should validate_presence_of :proof_key_exp } + it { should validate_presence_of :proof_key_old_mod } + it { should validate_presence_of :proof_key_old_exp } + end +end diff --git a/spec/models/zip_export_spec.rb b/spec/models/zip_export_spec.rb new file mode 100644 index 000000000..f77a0f451 --- /dev/null +++ b/spec/models/zip_export_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +describe ZipExport, type: :model do + it 'should be of class ZipExport' do + expect(subject.class).to eq ZipExport + end + + describe 'Database table' do + it { should have_db_column :user_id } + it { should have_db_column :created_at } + it { should have_db_column :updated_at } + it { should have_db_column :zip_file_file_name } + it { should have_db_column :zip_file_content_type } + it { should have_db_column :zip_file_file_size } + it { should have_db_column :zip_file_updated_at } + end + + describe 'Relations' do + it { should belong_to :user } + end +end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 000000000..84cdc722f --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,93 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +require 'spec_helper' +require 'shoulda-matchers' +require 'database_cleaner' +ENV['RAILS_ENV'] = 'test' +require File.expand_path('../../config/environment', __FILE__) +# Prevent database truncation if the environment is production +abort('The Rails environment is running in production mode!') if Rails.env.production? +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! + +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +# Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + +# Checks for pending migration and applies them before tests are run. +# If you are not using ActiveRecord, you can remove this line. +ActiveRecord::Migration.maintain_test_schema! + +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + # http://www.virtuouscode.com/2012/08/31/configuring-database_cleaner-with-rails-rspec-capybara-and-selenium/ + config.use_transactional_fixtures = false + config.before(:suite) do + DatabaseCleaner.clean_with(:truncation) + end + + config.before(:each) do + DatabaseCleaner.strategy = :transaction + end + + config.before(:each, js: true) do + DatabaseCleaner.strategy = :truncation + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.after(:each) do + DatabaseCleaner.clean + end + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") + + # includes FactoryGirl in rspec + config.include FactoryGirl::Syntax::Methods + config.include Devise::TestHelpers, type: :controller + config.include ApiHelper, type: :controller +end + +# config shoulda matchers to work with rspec +Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 000000000..2b2309f8c --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,100 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +require 'capybara/rspec' +require 'simplecov' +require 'faker' + +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/spec/support/api_helper.rb b/spec/support/api_helper.rb new file mode 100644 index 000000000..fbbd15928 --- /dev/null +++ b/spec/support/api_helper.rb @@ -0,0 +1,17 @@ +module ApiHelper + def generate_token(user_id) + Api::CoreJwt.encode(user_id: user_id) + end + + def generate_expired_token(user_id) + Api::CoreJwt.encode({ user_id: user_id }, (Time.now.to_i - 300)) + end + + def decode_token(token) + Api::CoreJwt.decode(token)['user_id'].to_i + end + + def json + JSON.parse(response.body) + end +end From e5bfb3c42d0853e3126d61a6f1c320f04f8764f3 Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Fri, 1 Sep 2017 09:06:25 +0200 Subject: [PATCH 002/189] Rollback migration version --- db/migrate/20170803153030_add_user_identity_table.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrate/20170803153030_add_user_identity_table.rb b/db/migrate/20170803153030_add_user_identity_table.rb index 8a1661c1a..29d439d0d 100644 --- a/db/migrate/20170803153030_add_user_identity_table.rb +++ b/db/migrate/20170803153030_add_user_identity_table.rb @@ -1,4 +1,4 @@ -class AddUserIdentityTable < ActiveRecord::Migration[5.1] +class AddUserIdentityTable < ActiveRecord::Migration def change create_table :user_identities do |t| t.belongs_to :user, index: true From 8463c893864f673b912b27afc92c0d36199e2f4d Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Fri, 1 Sep 2017 09:36:40 +0200 Subject: [PATCH 003/189] Update Gemfile --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 4dcf92164..627127154 100644 --- a/Gemfile +++ b/Gemfile @@ -30,7 +30,7 @@ gem 'uglifier', '>= 1.3.0' # jQuery & plugins gem 'jquery-turbolinks' gem 'jquery-rails' -gem 'jquery-ui-rails' +gem 'jquery-ui-rails', '~> 5.0' gem 'jquery-scrollto-rails' gem 'hammerjs-rails' gem 'introjs-rails' # Create quick tutorials From a927c2832ddab3232e948b0406e097b43cda5f11 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Fri, 1 Sep 2017 16:36:45 +0200 Subject: [PATCH 004/189] Improve error logging [GIOT-31] --- app/controllers/api/api_controller.rb | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/app/controllers/api/api_controller.rb b/app/controllers/api/api_controller.rb index 737defe82..246cc25f1 100644 --- a/app/controllers/api/api_controller.rb +++ b/app/controllers/api/api_controller.rb @@ -8,11 +8,13 @@ module Api before_action :load_iss, except: %i(authenticate status) before_action :authenticate_request!, except: %i(authenticate status) - rescue_from StandardError do + rescue_from StandardError do |e| + logger.error e.message render json: {}, status: :bad_request end - rescue_from JWT::InvalidPayload, JWT::DecodeError do + rescue_from JWT::InvalidPayload, JWT::DecodeError do |e| + logger.error e.message render json: { message: I18n.t('api.core.invalid_token') }, status: :unauthorized end @@ -35,22 +37,25 @@ module Api def authenticate if auth_params[:grant_type] == 'password' user = User.find_by_email(auth_params[:email]) - raise StandardError unless user && - user.valid_password?(auth_params[:password]) + unless user && user.valid_password?(auth_params[:password]) + raise StandardError, 'Wrong user password' + end payload = { user_id: user.id } token = CoreJwt.encode(payload) render json: { token_type: 'bearer', access_token: token } else - raise StandardError + raise StandardError, 'Wrong grant type in request' end end private def load_token - @token = - request.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last - raise StandardError unless @token + if request.headers['Authorization'] + @token = + request.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last + end + raise StandardError, 'No token in the header' unless @token end def authenticate_request! @@ -75,7 +80,7 @@ module Api def load_iss @iss = CoreJwt.read_iss(token) - raise JWT::InvalidPayload unless @iss + raise JWT::InvalidPayload, 'Wrong ISS in the token' unless @iss end def auth_params From fc0e2d217203072d67c9d78c2b783f1d83082dd2 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Fri, 1 Sep 2017 17:00:13 +0200 Subject: [PATCH 005/189] Add validation for uid uniqness [GIOT-29] --- app/models/user_identity.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user_identity.rb b/app/models/user_identity.rb index c5a7c08f6..e0ae551e4 100644 --- a/app/models/user_identity.rb +++ b/app/models/user_identity.rb @@ -1,4 +1,5 @@ class UserIdentity < ActiveRecord::Base belongs_to :user validates :provider, uniqueness: { scope: :user_id } + validates :uid, uniqueness: { scope: :provider } end From b4a13dffe313c6d4cb17a9aa19e633fffdc5fd17 Mon Sep 17 00:00:00 2001 From: Jure Grabnar Date: Mon, 11 Sep 2017 13:07:22 +0200 Subject: [PATCH 006/189] init commit, dodav na protocols index gumb z dropdown --- app/assets/javascripts/application.js.erb | 6 +++--- .../import_json_protocols_io/import_records.rb | 0 app/views/protocols/index.html.erb | 10 +++++++++- bin/aws-rb | 17 +++++++++++++++++ bin/aws.rb | 17 +++++++++++++++++ bin/bundler | 17 +++++++++++++++++ bin/byebug | 17 +++++++++++++++++ bin/coderay | 17 +++++++++++++++++ bin/convert_to_should_syntax | 17 +++++++++++++++++ bin/dot2ruby | 17 +++++++++++++++++ bin/erubis | 17 +++++++++++++++++ bin/figaro | 17 +++++++++++++++++ bin/gem2gv | 17 +++++++++++++++++ bin/git2gv | 17 +++++++++++++++++ bin/mongrel_rpm | 17 +++++++++++++++++ bin/newrelic | 17 +++++++++++++++++ bin/newrelic_cmd | 17 +++++++++++++++++ bin/nokogiri | 17 +++++++++++++++++ bin/nrdebug | 17 +++++++++++++++++ bin/puma | 17 +++++++++++++++++ bin/pumactl | 17 +++++++++++++++++ bin/rackup | 17 +++++++++++++++++ bin/rdoc | 17 +++++++++++++++++ bin/ri | 17 +++++++++++++++++ bin/rubocop | 17 +++++++++++++++++ bin/ruby-parse | 17 +++++++++++++++++ bin/ruby-rewrite | 17 +++++++++++++++++ bin/ruby2gv | 17 +++++++++++++++++ bin/sass | 17 +++++++++++++++++ bin/sass-convert | 17 +++++++++++++++++ bin/scss | 17 +++++++++++++++++ bin/scss-lint | 17 +++++++++++++++++ bin/sdoc | 17 +++++++++++++++++ bin/sdoc-merge | 17 +++++++++++++++++ bin/sprockets | 17 +++++++++++++++++ bin/starscope | 17 +++++++++++++++++ bin/thor | 17 +++++++++++++++++ bin/tilt | 17 +++++++++++++++++ bin/wkhtmltopdf-linux-amd64 | 17 +++++++++++++++++ bin/xml2gv | 17 +++++++++++++++++ 40 files changed, 641 insertions(+), 4 deletions(-) create mode 100644 app/services/import_json_protocols_io/import_records.rb create mode 100755 bin/aws-rb create mode 100755 bin/aws.rb create mode 100755 bin/bundler create mode 100755 bin/byebug create mode 100755 bin/coderay create mode 100755 bin/convert_to_should_syntax create mode 100755 bin/dot2ruby create mode 100755 bin/erubis create mode 100755 bin/figaro create mode 100755 bin/gem2gv create mode 100755 bin/git2gv create mode 100755 bin/mongrel_rpm create mode 100755 bin/newrelic create mode 100755 bin/newrelic_cmd create mode 100755 bin/nokogiri create mode 100755 bin/nrdebug create mode 100755 bin/puma create mode 100755 bin/pumactl create mode 100755 bin/rackup create mode 100755 bin/rdoc create mode 100755 bin/ri create mode 100755 bin/rubocop create mode 100755 bin/ruby-parse create mode 100755 bin/ruby-rewrite create mode 100755 bin/ruby2gv create mode 100755 bin/sass create mode 100755 bin/sass-convert create mode 100755 bin/scss create mode 100755 bin/scss-lint create mode 100755 bin/sdoc create mode 100755 bin/sdoc-merge create mode 100755 bin/sprockets create mode 100755 bin/starscope create mode 100755 bin/thor create mode 100755 bin/tilt create mode 100755 bin/wkhtmltopdf-linux-amd64 create mode 100755 bin/xml2gv diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 0a3b2f08b..240899728 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -8,9 +8,9 @@ //= require jquery.scrollTo //= require jquery.autosize //= require jquery-ui/widget -//= require jquery-ui/mouse -//= require jquery-ui/draggable -//= require jquery-ui/droppable +//= require jquery-ui/widgets/mouse +//= require jquery-ui/widgets/draggable +//= require jquery-ui/widgets/droppable //= require jquery.ui.touch-punch.min //= require jquery.caret.min //= require jquery.atwho.min diff --git a/app/services/import_json_protocols_io/import_records.rb b/app/services/import_json_protocols_io/import_records.rb new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index d9a48073d..f14303461 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -63,7 +63,15 @@
    - +
    diff --git a/bin/aws-rb b/bin/aws-rb new file mode 100755 index 000000000..ba93f3013 --- /dev/null +++ b/bin/aws-rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'aws-rb' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("aws-sdk-v1", "aws-rb") diff --git a/bin/aws.rb b/bin/aws.rb new file mode 100755 index 000000000..35700654f --- /dev/null +++ b/bin/aws.rb @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'aws.rb' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("aws-sdk-core", "aws.rb") diff --git a/bin/bundler b/bin/bundler new file mode 100755 index 000000000..d6107f047 --- /dev/null +++ b/bin/bundler @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'bundler' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("bundler", "bundler") diff --git a/bin/byebug b/bin/byebug new file mode 100755 index 000000000..d9bf0f4eb --- /dev/null +++ b/bin/byebug @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'byebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("byebug", "byebug") diff --git a/bin/coderay b/bin/coderay new file mode 100755 index 000000000..e248d2436 --- /dev/null +++ b/bin/coderay @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'coderay' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("coderay", "coderay") diff --git a/bin/convert_to_should_syntax b/bin/convert_to_should_syntax new file mode 100755 index 000000000..c083c4683 --- /dev/null +++ b/bin/convert_to_should_syntax @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'convert_to_should_syntax' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("shoulda-context", "convert_to_should_syntax") diff --git a/bin/dot2ruby b/bin/dot2ruby new file mode 100755 index 000000000..585531cf7 --- /dev/null +++ b/bin/dot2ruby @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'dot2ruby' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "dot2ruby") diff --git a/bin/erubis b/bin/erubis new file mode 100755 index 000000000..9d0f9cb06 --- /dev/null +++ b/bin/erubis @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'erubis' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("erubis", "erubis") diff --git a/bin/figaro b/bin/figaro new file mode 100755 index 000000000..1b9c61dc9 --- /dev/null +++ b/bin/figaro @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'figaro' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("figaro", "figaro") diff --git a/bin/gem2gv b/bin/gem2gv new file mode 100755 index 000000000..31f38af7c --- /dev/null +++ b/bin/gem2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'gem2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "gem2gv") diff --git a/bin/git2gv b/bin/git2gv new file mode 100755 index 000000000..6e5d0dac4 --- /dev/null +++ b/bin/git2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'git2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "git2gv") diff --git a/bin/mongrel_rpm b/bin/mongrel_rpm new file mode 100755 index 000000000..20cb86dc8 --- /dev/null +++ b/bin/mongrel_rpm @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'mongrel_rpm' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("newrelic_rpm", "mongrel_rpm") diff --git a/bin/newrelic b/bin/newrelic new file mode 100755 index 000000000..7a2008dda --- /dev/null +++ b/bin/newrelic @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'newrelic' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("newrelic_rpm", "newrelic") diff --git a/bin/newrelic_cmd b/bin/newrelic_cmd new file mode 100755 index 000000000..02d32467c --- /dev/null +++ b/bin/newrelic_cmd @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'newrelic_cmd' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("newrelic_rpm", "newrelic_cmd") diff --git a/bin/nokogiri b/bin/nokogiri new file mode 100755 index 000000000..c1f0ca44f --- /dev/null +++ b/bin/nokogiri @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'nokogiri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("nokogiri", "nokogiri") diff --git a/bin/nrdebug b/bin/nrdebug new file mode 100755 index 000000000..3878e8590 --- /dev/null +++ b/bin/nrdebug @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'nrdebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("newrelic_rpm", "nrdebug") diff --git a/bin/puma b/bin/puma new file mode 100755 index 000000000..13d14022f --- /dev/null +++ b/bin/puma @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'puma' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("puma", "puma") diff --git a/bin/pumactl b/bin/pumactl new file mode 100755 index 000000000..41681ff7f --- /dev/null +++ b/bin/pumactl @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'pumactl' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("puma", "pumactl") diff --git a/bin/rackup b/bin/rackup new file mode 100755 index 000000000..0f074e64e --- /dev/null +++ b/bin/rackup @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rackup' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rack", "rackup") diff --git a/bin/rdoc b/bin/rdoc new file mode 100755 index 000000000..c051912da --- /dev/null +++ b/bin/rdoc @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rdoc", "rdoc") diff --git a/bin/ri b/bin/ri new file mode 100755 index 000000000..56db0fc44 --- /dev/null +++ b/bin/ri @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ri' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rdoc", "ri") diff --git a/bin/rubocop b/bin/rubocop new file mode 100755 index 000000000..ccb4d5630 --- /dev/null +++ b/bin/rubocop @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'rubocop' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rubocop", "rubocop") diff --git a/bin/ruby-parse b/bin/ruby-parse new file mode 100755 index 000000000..20557e7b3 --- /dev/null +++ b/bin/ruby-parse @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ruby-parse' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("parser", "ruby-parse") diff --git a/bin/ruby-rewrite b/bin/ruby-rewrite new file mode 100755 index 000000000..60032ed17 --- /dev/null +++ b/bin/ruby-rewrite @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ruby-rewrite' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("parser", "ruby-rewrite") diff --git a/bin/ruby2gv b/bin/ruby2gv new file mode 100755 index 000000000..3b82be141 --- /dev/null +++ b/bin/ruby2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'ruby2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "ruby2gv") diff --git a/bin/sass b/bin/sass new file mode 100755 index 000000000..ef9f699d8 --- /dev/null +++ b/bin/sass @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "sass") diff --git a/bin/sass-convert b/bin/sass-convert new file mode 100755 index 000000000..13936f1df --- /dev/null +++ b/bin/sass-convert @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sass-convert' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "sass-convert") diff --git a/bin/scss b/bin/scss new file mode 100755 index 000000000..76c0dce5f --- /dev/null +++ b/bin/scss @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'scss' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sass", "scss") diff --git a/bin/scss-lint b/bin/scss-lint new file mode 100755 index 000000000..b300f8e46 --- /dev/null +++ b/bin/scss-lint @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'scss-lint' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("scss_lint", "scss-lint") diff --git a/bin/sdoc b/bin/sdoc new file mode 100755 index 000000000..6d3dbba68 --- /dev/null +++ b/bin/sdoc @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sdoc", "sdoc") diff --git a/bin/sdoc-merge b/bin/sdoc-merge new file mode 100755 index 000000000..7e997760e --- /dev/null +++ b/bin/sdoc-merge @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sdoc-merge' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sdoc", "sdoc-merge") diff --git a/bin/sprockets b/bin/sprockets new file mode 100755 index 000000000..e8ffa4dd9 --- /dev/null +++ b/bin/sprockets @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'sprockets' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("sprockets", "sprockets") diff --git a/bin/starscope b/bin/starscope new file mode 100755 index 000000000..bbaaa6afd --- /dev/null +++ b/bin/starscope @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'starscope' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("starscope", "starscope") diff --git a/bin/thor b/bin/thor new file mode 100755 index 000000000..63f10e55d --- /dev/null +++ b/bin/thor @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'thor' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("thor", "thor") diff --git a/bin/tilt b/bin/tilt new file mode 100755 index 000000000..a606a2ee5 --- /dev/null +++ b/bin/tilt @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'tilt' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("tilt", "tilt") diff --git a/bin/wkhtmltopdf-linux-amd64 b/bin/wkhtmltopdf-linux-amd64 new file mode 100755 index 000000000..55847d918 --- /dev/null +++ b/bin/wkhtmltopdf-linux-amd64 @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'wkhtmltopdf-linux-amd64' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("wkhtmltopdf-heroku", "wkhtmltopdf-linux-amd64") diff --git a/bin/xml2gv b/bin/xml2gv new file mode 100755 index 000000000..33b47ef4a --- /dev/null +++ b/bin/xml2gv @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true +# +# This file was generated by Bundler. +# +# The application 'xml2gv' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("ruby-graphviz", "xml2gv") From 31e8c107fdbc9f9a21f698bc3b31e6bdd56d663b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Mon, 11 Sep 2017 14:35:00 +0200 Subject: [PATCH 007/189] dodav na pravi branch te file --- app/views/protocols/index.html.erb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index f14303461..df069595f 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -62,16 +62,25 @@ -
    -
    - + + + +
    +
    From 2c0a458aafa49cf478ec120b451f9fab0c82b012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Mon, 11 Sep 2017 15:21:35 +0200 Subject: [PATCH 008/189] dodav moj alternativni text za importanje (text na gumbu), za rails translate (t) --- config/locales/en.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 24498ed3c..4b975782b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1443,6 +1443,7 @@ en: edit: "Edit" clone_btn: "Copy" import: "Import" + import_alt: "from SciNote protocol file(.eln)" export: "Export" make_private: "Make private" publish: "Publish" From f668f60237115687c106db974dc7ef0f4ed6013e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Mon, 11 Sep 2017 15:22:22 +0200 Subject: [PATCH 009/189] dodav moj stil gumba, ki ga opredeli kot link (padding 0, border 0), za dropdown meni --- app/assets/stylesheets/themes/scinote.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index e5a41a988..026833e74 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -1795,6 +1795,14 @@ textarea.textarea-sm { -webkit-padding-before: 0; -webkit-padding-after: 0; } + .btn.btn-default-link { + border:none; + padding:0; + height: 100%; + min-height: 34px; + -webkit-padding-before: 0; + -webkit-padding-after: 0; + } } } From 0f4dadefa99a2d076fa71489ecd28e7d37998645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Mon, 11 Sep 2017 15:23:09 +0200 Subject: [PATCH 010/189] prvi (star gumb) v dropdownu sedaj deluje --- app/views/protocols/index.html.erb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index df069595f..8e850e405 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -68,10 +68,18 @@
    - > - - - > - + + + @@ -65,28 +80,7 @@ - -
    From 62350d0d420821c27c5b546fa93640ddd92d8e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Mon, 11 Sep 2017 16:03:33 +0200 Subject: [PATCH 012/189] Changed the styling so first option isnt outlined like button, but now mouse cursor wont change to hand when hovering over; will leave this small bug for fixing later --- app/assets/stylesheets/themes/scinote.scss | 6 ++++++ app/views/protocols/index.html.erb | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 026833e74..3850029ce 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -2008,6 +2008,12 @@ th.custom-field .modal-tooltiptext { margin-right: 5px; padding: 3px; } + .btn-link { + border-radius: 4px; + margin-right: 5px; + padding: 3px; + cursor:pointer; + } .btn:last-child { margin-right: 20px; diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index af0cdbadf..44adefe47 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -55,9 +55,9 @@ diff --git a/config/locales/en.yml b/config/locales/en.yml index 4b975782b..65936cca5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1444,6 +1444,7 @@ en: clone_btn: "Copy" import: "Import" import_alt: "from SciNote protocol file(.eln)" + import_json: "from protocols.io file(.json)" export: "Export" make_private: "Make private" publish: "Publish" From fdbae19156d31bf1babf8cef3f76524b4f55ffa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Tue, 12 Sep 2017 09:33:18 +0200 Subject: [PATCH 014/189] changed .json to .txt for clarity --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 65936cca5..7ecb93269 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1444,7 +1444,7 @@ en: clone_btn: "Copy" import: "Import" import_alt: "from SciNote protocol file(.eln)" - import_json: "from protocols.io file(.json)" + import_json: "from protocols.io file(.txt)" export: "Export" make_private: "Make private" publish: "Publish" From 706031dacb3ffc8e83ec512ba53bbb541bbdc517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDan=20=C5=BDagar?= Date: Tue, 12 Sep 2017 15:25:22 +0200 Subject: [PATCH 015/189] added model and controler, model should go to services while the controller should go to protocols controller --- app/controllers/temp_jsons_controller.rb | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100755 app/controllers/temp_jsons_controller.rb diff --git a/app/controllers/temp_jsons_controller.rb b/app/controllers/temp_jsons_controller.rb new file mode 100755 index 000000000..2839fdd85 --- /dev/null +++ b/app/controllers/temp_jsons_controller.rb @@ -0,0 +1,16 @@ +class TempJsonsController < ApplicationController + + def new + @temp_json=JsonTemp.new + end + def create + @temp_json=JsonTemp.new(temp_params) + json_file_contents=@temp_json.json_file.read + json_object=JSON.parse(json_file_contents) + + end + + def temp_params + params.require(:json_file) + end +end From b7432b336a1b7470f39a74c28e0ac3fbcebaf221 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Wed, 13 Sep 2017 15:15:08 +0200 Subject: [PATCH 016/189] added file upload popup modal, rails routes and controller functions, deleted old standalone model and controller --- app/assets/javascripts/temp_jsons.js | 2 ++ app/assets/stylesheets/temp_jsons.scss | 3 +++ app/assets/stylesheets/themes/scinote.scss | 21 ++++++++++----- app/controllers/protocols_controller.rb | 16 +++++++++++ app/helpers/temp_jsons_helper.rb | 2 ++ .../_import_json_protocol_modal.html.erb | 23 ++++++++++++++++ app/views/protocols/index.html.erb | 27 ++++++++----------- config/locales/en.yml | 3 +++ config/routes.rb | 10 +++++++ db/schema.rb | 13 +++++---- .../controllers/temp_jsons_controller_test.rb | 7 +++++ 11 files changed, 97 insertions(+), 30 deletions(-) create mode 100644 app/assets/javascripts/temp_jsons.js create mode 100644 app/assets/stylesheets/temp_jsons.scss create mode 100644 app/helpers/temp_jsons_helper.rb create mode 100644 app/views/protocols/import_export/_import_json_protocol_modal.html.erb create mode 100644 test/controllers/temp_jsons_controller_test.rb diff --git a/app/assets/javascripts/temp_jsons.js b/app/assets/javascripts/temp_jsons.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/temp_jsons.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/temp_jsons.scss b/app/assets/stylesheets/temp_jsons.scss new file mode 100644 index 000000000..b12deb7f5 --- /dev/null +++ b/app/assets/stylesheets/temp_jsons.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the temp_jsons controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 3850029ce..73fd098fa 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -337,7 +337,18 @@ a { border-color: darken($color-theme-secondary, 10%); } } - +.btn-link-alt { + border-radius: 4px; + margin-right: 5px; + padding: 3px; + cursor:pointer; +} +.btn-invis-file{ + opacity: 0; + position: absolute; + z-index: -1; + display: none; +} .btn-open-file { position: relative; overflow: hidden; @@ -1803,6 +1814,7 @@ textarea.textarea-sm { -webkit-padding-before: 0; -webkit-padding-after: 0; } + } } @@ -2008,12 +2020,7 @@ th.custom-field .modal-tooltiptext { margin-right: 5px; padding: 3px; } - .btn-link { - border-radius: 4px; - margin-right: 5px; - padding: 3px; - cursor:pointer; - } + .btn:last-child { margin-right: 20px; diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 1cab571da..6a69e9433 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -599,7 +599,23 @@ class ProtocolsController < ApplicationController end end end +# +#tule +def protocolsio_import_new + #@temp_json=JsonTemp.new +end +def protocolsio_import_create + + json_file_contents=File.read(params[:json_file].path) + json_object=JSON.parse(json_file_contents) + byebug +end + +def protocolsio_temp_params + params.require(:json_file) +end +# def export # Make a zip output stream and send it to the client respond_to do |format| diff --git a/app/helpers/temp_jsons_helper.rb b/app/helpers/temp_jsons_helper.rb new file mode 100644 index 000000000..554afcb2d --- /dev/null +++ b/app/helpers/temp_jsons_helper.rb @@ -0,0 +1,2 @@ +module TempJsonsHelper +end diff --git a/app/views/protocols/import_export/_import_json_protocol_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_modal.html.erb new file mode 100644 index 000000000..a9bfc0a61 --- /dev/null +++ b/app/views/protocols/import_export/_import_json_protocol_modal.html.erb @@ -0,0 +1,23 @@ + diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index 0281d0955..8448b64cd 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -1,3 +1,4 @@ +<%= render partial: "protocols/import_export/import_json_protocol_modal" %> <% provide(:head_title, t("protocols.index.head_title")) %> <% if current_team %> @@ -48,9 +49,8 @@ <% end %>
    - -
    - +
    + @@ -84,11 +83,7 @@ - - - - -
    +
    diff --git a/config/locales/en.yml b/config/locales/en.yml index 7ecb93269..b2d1e1c2d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1445,6 +1445,9 @@ en: import: "Import" import_alt: "from SciNote protocol file(.eln)" import_json: "from protocols.io file(.txt)" + modal_import_json_title: "Import protocols.io file" + modal_import_json_notice: "Upload your protocols.io .txt json protocol file" + modal_import_json_submit: "Upload file" export: "Export" make_private: "Make private" publish: "Publish" diff --git a/config/routes.rb b/config/routes.rb index 7aed6b3f9..085c7036c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -398,6 +398,10 @@ Rails.application.routes.draw do to: 'protocols#load_from_repository_modal' post 'load_from_repository', to: 'protocols#load_from_repository' post 'load_from_file', to: 'protocols#load_from_file' + ## + ##-tule gre tvoje json_import match 'admin_login' => 'user#admin_login', + post 'protocolsio_import_create', to: 'protocols#protocolsio_import_create' + ## get 'copy_to_repository_modal', to: 'protocols#copy_to_repository_modal' post 'copy_to_repository', to: 'protocols#copy_to_repository' get 'protocol_status_bar', to: 'protocols#protocol_status_bar' @@ -406,6 +410,7 @@ Rails.application.routes.draw do get 'edit_keywords_modal', to: 'protocols#edit_keywords_modal' get 'edit_authors_modal', to: 'protocols#edit_authors_modal' get 'edit_description_modal', to: 'protocols#edit_description_modal' + end collection do get 'create_new_modal', to: 'protocols#create_new_modal' @@ -415,6 +420,10 @@ Rails.application.routes.draw do post 'archive', to: 'protocols#archive' post 'restore', to: 'protocols#restore' post 'import', to: 'protocols#import' + ## + ##-tule gre tvoje json_import match 'admin_login' => 'user#admin_login', + post 'protocolsio_import_create', to: 'protocols#protocolsio_import_create' + ## get 'export', to: 'protocols#export' end end @@ -481,4 +490,5 @@ Rails.application.routes.draw do get 'wopi/files/:id', to: 'wopi#file_get_endpoint', as: 'wopi_rest_endpoint' post 'wopi/files/:id', to: 'wopi#post_file_endpoint' end + end diff --git a/db/schema.rb b/db/schema.rb index 6046e0877..c34571109 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170515141252) do +ActiveRecord::Schema.define(version: 20170619125051) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -413,7 +413,6 @@ ActiveRecord::Schema.define(version: 20170515141252) do t.datetime "updated_at" end - add_index "repository_rows", ["name"], name: "index_repository_rows_on_name", using: :btree add_index "repository_rows", ["repository_id"], name: "index_repository_rows_on_repository_id", using: :btree create_table "repository_table_states", force: :cascade do |t| @@ -544,11 +543,11 @@ ActiveRecord::Schema.define(version: 20170515141252) do add_index "samples", ["user_id"], name: "index_samples_on_user_id", using: :btree create_table "samples_tables", force: :cascade do |t| - t.jsonb "status", default: {"time"=>0, "order"=>[[2, "desc"]], "start"=>0, "length"=>10, "search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "columns"=>[{"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}], "ColReorder"=>[0, 1, 2, 3, 4, 5, 6]}, null: false - t.integer "user_id", null: false - t.integer "team_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.jsonb "status", default: {"time"=>0, "order"=>[[2, "desc"]], "start"=>0, "length"=>10, "search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "columns"=>[{"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}], "assigned"=>"all", "ColReorder"=>[0, 1, 2, 3, 4, 5, 6]}, null: false + t.integer "user_id", null: false + t.integer "team_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "samples_tables", ["team_id"], name: "index_samples_tables_on_team_id", using: :btree diff --git a/test/controllers/temp_jsons_controller_test.rb b/test/controllers/temp_jsons_controller_test.rb new file mode 100644 index 000000000..4fe936641 --- /dev/null +++ b/test/controllers/temp_jsons_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class TempJsonsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end From 9fc91aac3272f0a537e6e1660eb230bbf5eaa773 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Wed, 13 Sep 2017 16:04:16 +0200 Subject: [PATCH 017/189] added protocols io upload preview modal --- app/controllers/protocols_controller.rb | 4 +- ...mport_json_protocol_preview_modal.html.erb | 84 +++++++++++++++++++ app/views/protocols/index.html.erb | 2 + 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 6a69e9433..005f609dd 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -608,8 +608,8 @@ def protocolsio_import_create json_file_contents=File.read(params[:json_file].path) - json_object=JSON.parse(json_file_contents) - byebug + @json_object=JSON.parse(json_file_contents) + render :partial => "/protocols/import_json_protocol_preview_modal" end def protocolsio_temp_params diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb new file mode 100644 index 000000000..07510de19 --- /dev/null +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -0,0 +1,84 @@ + diff --git a/app/views/protocols/index.html.erb b/app/views/protocols/index.html.erb index 8448b64cd..8f50b9c33 100644 --- a/app/views/protocols/index.html.erb +++ b/app/views/protocols/index.html.erb @@ -1,4 +1,6 @@ <%= render partial: "protocols/import_export/import_json_protocol_modal" %> +<%= render partial: "protocols/import_export/import_json_protocol_preview_modal" %> + <% provide(:head_title, t("protocols.index.head_title")) %> <% if current_team %> From 29b9d503632a656f68289eb7203ec731f174b02b Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Thu, 14 Sep 2017 11:30:53 +0200 Subject: [PATCH 018/189] Modals now popup correctly trough ajax, added js file for this functionality, and two partials which are reused from existing importer --- app/controllers/protocols_controller.rb | 7 ++++++- .../import_export/_import_json_protocol_modal.html.erb | 1 + .../_import_json_protocol_preview_modal.html.erb | 4 +++- app/views/protocols/index.html.erb | 5 ++--- app/views/protocols/protocolsio_import_create.js.erb | 3 +++ 5 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 app/views/protocols/protocolsio_import_create.js.erb diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 005f609dd..760a96a9f 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -609,7 +609,12 @@ def protocolsio_import_create json_file_contents=File.read(params[:json_file].path) @json_object=JSON.parse(json_file_contents) - render :partial => "/protocols/import_json_protocol_preview_modal" + + respond_to do |format| + format.html + format.js + end + end def protocolsio_temp_params diff --git a/app/views/protocols/import_export/_import_json_protocol_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_modal.html.erb index a9bfc0a61..5d35ba8c7 100644 --- a/app/views/protocols/import_export/_import_json_protocol_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_modal.html.erb @@ -18,6 +18,7 @@ <%= submit_tag t("protocols.index.modal_import_json_submit"), class: "btn btn-default" %>
    <% end %> +
  • diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb index 07510de19..771b74ea3 100644 --- a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -1,4 +1,4 @@ - - <% #puts json_object %> @@ -25,12 +24,12 @@ - <%= f.text_field :authors, :value => json_object['username'], class: "form-control" %> + <%= f.text_field :authors, :value => json_object['full_name'], class: "form-control" %>
    - --> + <%= f.text_area :description, :value => json_object['description'], class: "form-control" %>
    @@ -39,12 +38,14 @@
    - <%= f.text_field :doesnt_exist, :value => json_object['created_on']+" (Protocols.io value)", class: "form-control" %> + <% display_created_at=Time.at(json_object['created_on'].to_i) %> + <%= f.text_field :doesnt_exist, :value => display_created_at.to_s+" (Protocols.io value)", class: "form-control" %>
    - <%= f.text_field :doesnt_exist, :value => json_object['last_modified']+" (Protocols.io value)", class: "form-control" %> + <% display_last_modified=Time.at(json_object['last_modified'].to_i) %> + <%= f.text_field :doesnt_exist, :value => display_last_modified.to_s+" (Protocols.io value)", class: "form-control" %>
    @@ -57,21 +58,55 @@
    -
    +
    + -
    + <% if json_object["before_start"]&&json_object["before_start"]!="" %> + + + + + <% end %> + <% if json_object["warning"]&&json_object["warning"]!="" %> + + + + + + + <% end %> + + + <% if json_object["guidelines"]&&json_object["guidelines"]!="" %> + + + + + + <% end %> <% counter=0 whitelist_simple=["1","6","17"] whitelist_complex=["8","9","15","18","19","20"]%> - <% #byebug %> <% json_object["steps"].each do |step| %> - - - + <% end #posamezni koraki%> + + <% if json_object["manuscript_citation"]&&json_object["manuscript_citation"]!="" %> + + + + + + <% end %> + + <% if json_object["publish_date"]&&json_object["publish_date"]!="" %> + + + + + + <% end %> + + <% if json_object["vendor_name"]&&json_object["vendor_name"]!="" %> + + + + + + <% end %> + <% if json_object["vendor_link"]&&json_object["vendor_link"]!="" %> + + + + + + <% end %> + <% if json_object["keywords"]&&json_object["keywords"]!="" %> + + + + + + <% end %> + <% if json_object["tags"]&&json_object["tags"]!="" %> + + + + + + <% end %>
    +

    Before starting protocol information

    + <%= strip_tags(json_object["before_start"].remove("\"")) %> + +
    +

    Protocol warning

    + <%= strip_tags(json_object["warning"].remove("\"")) %> + +
    +

    Guidelines

    + <%= strip_tags(json_object["guidelines"].remove("\"")) %> + +
    Step <%= (counter+=1).to_s %> Step guid (Protocols.io) :<%= step["guid"] %> +

    Step <%= (counter+=1).to_s %>


    + Step guid (Protocols.io) :<%= step["guid"] %> <% #byebug %> <% if counter>1 %>
    Guid of previous step (Protocols.io) :<%= step["previous_guid"] %> @@ -79,59 +114,66 @@ <% step["components"].each do |key,value| %> <% #byebug %> - <% if counter>1 #nevem zaka ampak v vseh njihovih izvoženih jsonih ima prvi korak čudno strukturo - #elementov, v kateri so shranjeni kot hash, katerega ključ je "0", vrednost pa komponenta, to zruši iteriranje v enem stavku - #trenutno sem porabil {5} ur da bi našel rešitev, tako da bi ena zanka naredila oboje. - # to je samo v prvem koraku, naprej so vsi shranjeni brez tega arraya, in se po njih da normalno iterirat + <% if counter>1 #here i made an if to distinguish the first step from the others, because the first step + #sometimes has weird nesting that makes the below outputs not work %> - <% #byebug %> + <% #if false %> + <% if whitelist_simple.include?(key["component_type_id"]) && key["data"]!="" && key["name"] && key["data"]%>
    - <%= key["name"]+" : "+key["data"] %> + <%= strip_tags(key["name"].remove("\""))+" : "+ strip_tags(key["data"].remove("\"")) %> <% #byebug #debug #comp[counter];counter;@json.file_contents["steps"][3]["components"][0]["name"] #@json.file_contents["steps"][0]["components"] %> + <% #end %> <% elsif key && whitelist_complex.include?(key["component_type_id"]) %> <% case key["component_type_id"]%> <% when "8"%>
    - <%= "-"+key["name"]+" : "+key["source_data"]["name"] %> + <%= "-"+strip_tags(key["name"].remove("\""))+" : "+strip_tags(key["source_data"]["name"].remove("\"")) %>
    - Developer : <%= key["source_data"]["developer"] %> + Developer : <%= strip_tags(key["source_data"]["developer"].remove("\"")) %>
    - Version : <%= key["source_data"]["version"] %> + Version : <%= strip_tags(key["source_data"]["version"].remove("\"")) %>
    - Link : <%= key["source_data"]["link"] %> + Link : <%= strip_tags(key["source_data"]["link"].remove("\"")) %>
    - Repository : <%= key["source_data"]["repository"] %> + Repository : <%= strip_tags(key["source_data"]["repository"].remove("\"")) %>
    - OS name , OS version : <%= key["source_data"]["os_name"]+" , "+key["source_data"]["os_version"] %> + OS name , OS version : <%= strip_tags(key["source_data"]["os_name"].remove("\""))+" , "+strip_tags(key["source_data"]["os_version"].remove("\"")) %> <% when "9"%>
    - <%= "-"+key["name"]+" : "+key["source_data"]["name"] %> + <%= "-"+strip_tags(key["name"].remove("\""))+" : "+strip_tags(key["source_data"]["name"].remove("\"")) %>
    - Link : <%= key["source_data"]["link"] %> + Link : <%= strip_tags(key["source_data"]["link"].remove("\"")) %> <% when "15"%>
    - <%= "-"+key["name"]+" : "+key["source_data"]["name"] %> + <%= "-"+strip_tags(key["name"].remove("\""))+" : "+strip_tags(key["source_data"]["name"].remove("\"")) %>
    - Description : <%= key["source_data"]["description"] %> + Description : <%= strip_tags(key["source_data"]["description"].remove("\"")) %>
    - OS name , OS version : <%= key["source_data"]["os_name"]+" , "+key["source_data"]["os_version"] %> + OS name , OS version : <%= strip_tags(key["source_data"]["os_name"].remove("\""))+" , "+strip_tags(key["source_data"]["os_version"].remove("\"")) %> <% when "18"%> - +
    + -This protocol also contains an attached sub-protocol: <%= strip_tags(key["source_data"]["protocol_name"].remove("\"")) %> +
    + Author: <%= strip_tags(key["source_data"]["full_name"].remove("\"")) %> +
    + <% if key["source_data"]["link"]&&key["source_data"]["link"]!="" %> + Link: <%= strip_tags(key["source_data"]["link"].remove("\"")) %> + <% end %> <% when "19"%>
    - <%= "-"+key["name"]+" : "+key["source_data"]["body"] %> + <%= "-"+strip_tags(key["name"].remove("\""))+" : "+strip_tags(key["source_data"]["body"].remove("\"")) %>
    - Link : <%= key["source_data"]["link"] %> + Link : <%= strip_tags(key["source_data"]["link"].remove("\"")) %> <% when "20"%> @@ -141,6 +183,7 @@ <% end %> + <% end #notranji if št 1%> @@ -149,11 +192,11 @@ <% unless value %> <% value=key #json format ima random arraye namest hashov, ta problem je opisan pri if counter > 1 stavku %> <% end %> - <% #byebug %> + <% if whitelist_simple.include?(value["component_type_id"])&& value["data"]!="" && value["name"] && value["data"] %>
    - <%= value["name"]+" : "+value["data"] %> - <% #byebug + <%= strip_tags(value["name"].remove("\""))+" : "+strip_tags(value["data"].remove("\"")) %> + <% #debug #comp[counter];counter;@json.file_contents["steps"][3]["components"][0]["name"] #@json.file_contents["steps"][0]["components"] @@ -163,40 +206,48 @@ <% case value["component_type_id"]%> <% when "8"%>
    - <%= "-"+value["name"]+" : "+value["source_data"]["name"] %> + <%= "-"+strip_tags(value["name"].remove("\""))+" : "+strip_tags(value["source_data"]["name"].remove("\"")) %>
    - Developer : <%= value["source_data"]["developer"] %> + Developer : <%= strip_tags(value["source_data"]["developer"].remove("\"")) %>
    - Version : <%= value["source_data"]["version"] %> + Version : <%= strip_tags(value["source_data"]["version"].remove("\"")) %>
    - Link : <%= value["source_data"]["link"] %> + Link : <%= strip_tags(value["source_data"]["link"].remove("\"")) %>
    - Repository : <%= value["source_data"]["repository"] %> + Repository : <%= strip_tags(value["source_data"]["repository"].remove("\"")) %>
    - OS name , OS version : <%= value["source_data"]["os_name"]+" , "+value["source_data"]["os_version"] %> + OS name , OS version : <%= strip_tags(value["source_data"]["os_name"].remove("\""))+" , "+strip_tags(value["source_data"]["os_version"].remove("\"")) %> <% when "9"%>
    - <%= "-"+value["name"]+" : "+value["source_data"]["name"] %> + <%= "-"+strip_tags(value["name"].remove("\""))+" : "+strip_tags(value["source_data"]["name"].remove("\"")) %>
    - Link : <%= value["source_data"]["link"] %> + Link : <%= strip_tags(value["source_data"]["link"].remove("\"")) %> <% when "15"%>
    - <%= "-"+value["name"]+" : "+value["source_data"]["name"] %> + <%= "-"+strip_tags(value["name"].remove("\""))+" : "+strip_tags(value["source_data"]["name"].remove("\"")) %>
    - Description : <%= value["source_data"]["description"] %> + Description : <%= strip_tags(value["source_data"]["description"].remove("\"")) %>
    - OS name , OS version : <%= value["source_data"]["os_name"]+" , "+value["source_data"]["os_version"] %> + OS name , OS version : <%= strip_tags(value["source_data"]["os_name"].remove("\""))+" , "+strip_tags(value["source_data"]["os_version"].remove("\"")) %> <% when "18"%> +
    + -This protocol also contains an attached sub-protocol: <%= strip_tags(value["source_data"]["protocol_name"].remove("\"")) %> +
    + Author: <%= strip_tags(value["source_data"]["full_name"].remove("\"")) %> + <% if value["source_data"]["link"]&&value["source_data"]["link"]!="" %> +
    + Link: <%= strip_tags(value["source_data"]["link"].remove("\"")) %> + <% end %> <% when "19"%>
    - <%= "-"+value["name"]+" : "+value["source_data"]["body"] %> + <%= "-"+strip_tags(value["name"])+" : "+strip_tags(value["source_data"]["body"].remove("\"")) %>
    - Link : <%= value["source_data"]["link"] %> + Link : <%= strip_tags(value["source_data"]["link"].remove("\"")) %> <% when "20"%> @@ -211,12 +262,83 @@ <% end #komponente koraka %> +
    WIP
    +

    Manuscript citation

    + <%= strip_tags(json_object["manuscript_citation"].remove("\"")) %> + +
    +

    Publish date

    + <%= strip_tags(json_object["publish_date"].remove("\"")) %> + +
    +

    Vendor name

    + <%= strip_tags(json_object["vendor_name"].remove("\"")) %> + +
    +

    Vendor link

    + <%= strip_tags(json_object["vendor_link"].remove("\"")) %> + +
    +

    Keywords

    + <%= strip_tags(json_object["keywords"].remove("\"")) %> + +
    +

    Tags

    + <% json_object["tags"].each do |tag| %> + <%= strip_tags(tag["tag_name"].remove("\""))+" , " %> + <% end %> +
    From f861b1fc52ae7bac926019fc8d851698f90b59d9 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 15 Sep 2017 15:52:55 +0200 Subject: [PATCH 023/189] Configured the controller,the main task ahead is to figure out how to import all of the data i have available --- app/controllers/protocols_controller.rb | 16 ++++++---- ...mport_json_protocol_preview_modal.html.erb | 30 +++++++++++-------- config/routes.rb | 8 ++--- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 0a3d85203..ff989cf00 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -601,23 +601,29 @@ class ProtocolsController < ApplicationController end # #tule -def protocolsio_import_new - #@temp_json=JsonTemp.new -end def protocolsio_import_create - + json_file_contents=File.read(params[:json_file].path) @json_object=JSON.parse(json_file_contents) @protocol=Protocol.new respond_to do |format| - format.html + format.html {} format.js {} end end +def protocolsio_import_save + #@temp_json=JsonTemp.new + respond_to do |format| + format.html {render protocols} + format.js {render nothing} + + end +end + def protocolsio_temp_params params.require(:json_file) end diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb index 21acd0b8d..66f6ebfc3 100644 --- a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -1,3 +1,4 @@ +<%= form_for(protocol, :url => "protocols/protocolsio_import_save",method: :post) do |f| %> @@ -65,26 +65,26 @@
    - +
    <% if @json_object["before_start"]&&@json_object["before_start"]!="" %> -
    Before starting protocol information:
    - <%= (@json_object["before_start"]) %> + Before starting protocol information:
    + <%= (@json_object["before_start"]) %>
    <% end %> <% if @json_object["warning"]&&@json_object["warning"]!="" %> -
    Protocol warning:
    - <%= (@json_object["warning"]) %> + Protocol warning:
    + <%= (@json_object["warning"]) %>
    <% end %> <% if @json_object["guidelines"]&&@json_object["guidelines"]!="" %> -
    Guidelines:
    - <%= (@json_object["guidelines"]) %> + Guidelines:
    + <%= (@json_object["guidelines"]) %>
    <% end %> @@ -150,7 +150,6 @@ <% if counter>1 #here i made an if to distinguish the first step from the others, because the first step #sometimes has weird nesting that makes the below outputs not work %> - <% #byebug %> <% if whitelist_simple.include?(key["component_type_id"]) && key["data"]!="" && key["data"] %>
    <% case key["component_type_id"]%> @@ -169,15 +168,15 @@
    <%= key["name"]+": " %> <%= (key["source_data"]["name"]) %>
    - Developer : <%= (key["source_data"]["developer"]) %> + Developer: <%= (key["source_data"]["developer"]) %>
    - Version : <%= (key["source_data"]["version"]) %> + Version: <%= (key["source_data"]["version"]) %>
    - Link : <%= (key["source_data"]["link"]) %> + Link: <%= (key["source_data"]["link"]) %>
    - Repository : <%= (key["source_data"]["repository"]) %> + Repository: <%= (key["source_data"]["repository"]) %>
    - OS name , OS version : <%= (key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) %> + OS name , OS version: <%= (key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) %> <% when "9"%>
    @@ -190,9 +189,9 @@
    <%= key["name"]+": " %> <%= key["source_data"]["name"] %>
    - Description : <%= (key["source_data"]["description"]) %> + Description: <%= (key["source_data"]["description"]) %>
    - OS name , OS version : <%= (key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) %> + OS name , OS version: <%= (key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) %> <% when "18"%>
    @@ -207,7 +206,7 @@
    <%= key["name"]+": " %> <%= key["source_data"]["body"] %>
    - Link : <%= (key["source_data"]["link"]) %> + Link: <%= (key["source_data"]["link"]) %> <% when "20"%> @@ -354,7 +353,7 @@ <% end %> <% end %> - +
    From deef790951309b50ebcc77f0e8f6a810e9c6cc5a Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 11:56:50 +0200 Subject: [PATCH 035/189] added validations to controllers (file too big, names too big), some javascript error messagges, and fixed some nil exceptions in controllers appending nil strings to descriptions --- app/controllers/protocols_controller.rb | 101 ++++++++++++------ ...mport_json_protocol_preview_modal.html.erb | 19 ++-- .../protocolsio_import_create.js.erb | 19 ++-- .../protocols/protocolsio_import_save.js.erb | 5 + config/locales/en.yml | 1 + 5 files changed, 102 insertions(+), 43 deletions(-) diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index e9169db40..442cd23fc 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -606,9 +606,20 @@ class ProtocolsController < ApplicationController # #tule def protocolsio_import_create - + @protocolsio_too_big=false + file_size=(File.size(params[:json_file].path)) + + if(file_size/1000>Constants::FILE_MAX_SIZE_MB) + @protocolsio_too_big=true + respond_to do |format| + format.js {} + end + else + @protocolsio_too_big=false + end json_file_contents=File.read(params[:json_file].path) + json_file_contents.gsub! '\"', "'" @@ -632,7 +643,7 @@ def protocolsio_import_save # will have to fit various things in here (guidelines, manuscript citations etc etc) #"before_start","warning","guidelines","manuscript_citation","publish_date","created_on" #"vendor_name","vendor_link","keywords","tags" - description_array = [ "before_start","warning","guidelines","manuscript_citation","publish_date","created_on","vendor_name","vendor_link","keywords","tags" ] + description_array = [ "before_start","warning","guidelines","manuscript_citation","publish_date","created_on","vendor_name","vendor_link","keywords","tags","link" ] description_string=params["protocol"]["description"] #@import_object["description"]=params["protocol"]["description"] description_array.each do |element| @@ -640,16 +651,16 @@ def protocolsio_import_save if(@json_object[element]&&@json_object[element]!="") new_element = element.slice(0,1).capitalize + element.slice(1..-1) new_element= new_element.gsub("_"," ") - description_string=description_string+new_element.to_s+": "+params["protocol"]["created_at"].to_s+"\n" + description_string=description_string+new_element.to_s+": "+Sanitize.clean(params["protocol"]["created_at"].to_s)+"\n" end else if(element=="tags") - if(@json_object[element]&&@json_object[element]!="") + if(@json_object[element].any?&&@json_object[element]!="") new_element = element.slice(0,1).capitalize + element.slice(1..-1) new_element= new_element.gsub("_"," ") description_string=description_string+new_element.to_s+": " @json_object[element].each do |tag| - description_string=description_string+tag["tag_name"]+" , " + description_string=description_string+Sanitize.clean(tag["tag_name"])+" , " end description_string=description_string+"\n" end @@ -658,7 +669,7 @@ def protocolsio_import_save if(@json_object[element]&&@json_object[element]!="") new_element = element.slice(0,1).capitalize + element.slice(1..-1) new_element= new_element.gsub("_"," ") - description_string=description_string+new_element.to_s+": "+@json_object[element].to_s+"\n" + description_string=description_string+new_element.to_s+": "+Sanitize.clean(@json_object[element].to_s)+"\n" end end end @@ -696,7 +707,7 @@ def protocolsio_import_save when "1" if !key["data"].nil? && key["data"]!="" - element_string="
    "+key["data"]+"
    " + element_string="
    "+(key["data"])+"
    " if(@import_object["steps"][step_pos.to_s]["description"]) @import_object["steps"][step_pos.to_s]["description"]<" + element_string="
    Expected result: "+(key["data"])+"
    " @import_object["steps"][step_pos.to_s]["description"]<Developer: "+key["source_data"]["developer"]+"
    Version: "+key["source_data"]["version"]+"
    Link: "+key["source_data"]["link"]+"
    Repository: "+key["source_data"]["repository"]+"
    OS name , OS version: "+key["source_data"]["os_name"]+" , "+key["source_data"]["os_version"] + if(key["source_data"]["name"]&&key["source_data"]["developer"]&&key["source_data"]["version"]&&key["source_data"]["link"]&&key["source_data"]["repository"]&&key["source_data"]["os_name"]&&key["source_data"]["os_version"]) + element_string="
    Software package: "+(key["source_data"]["name"])+"
    Developer: "+(key["source_data"]["developer"])+"
    Version: "+(key["source_data"]["version"])+"
    Link: "+(key["source_data"]["link"])+"
    Repository: "+(key["source_data"]["repository"])+"
    OS name , OS version: "+(key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) @import_object["steps"][step_pos.to_s]["description"]<Link: "+key["source_data"]["link"] + if(key["source_data"]["name"]&&key["source_data"]["link"]) + element_string="
    Dataset: "+(key["source_data"]["name"])+"
    Link: "+(key["source_data"]["link"]) @import_object["steps"][step_pos.to_s]["description"]<Description: "+key["source_data"]["description"]+"
    OS name , OS version: "+key["source_data"]["os_name"]+" , "+key["source_data"]["os_version"] + if(key["source_data"]["name"]&&key["source_data"]["description"]&&key["source_data"]["os_name"]&&key["source_data"]["os_version"]) + element_string="
    Command: "+(key["source_data"]["name"])+"
    Description: "+(key["source_data"]["description"])+"
    OS name , OS version: "+(key["source_data"]["os_name"])+" , "+(key["source_data"]["os_version"]) @import_object["steps"][step_pos.to_s]["description"]<Author: "+key["source_data"]["full_name"]+"
    Link: "+key["source_data"]["link"] + if(key["source_data"]["protocol_name"]&&key["source_data"]["full_name"]&&key["source_data"]["link"]) + element_string="
    This protocol also contains an attached sub-protocol: "+(key["source_data"]["protocol_name"])+"
    Author: "+(key["source_data"]["full_name"])+"
    Link: "+(key["source_data"]["link"]) + @import_object["steps"][step_pos.to_s]["description"]<Link: "+key["source_data"]["link"] + if(key["source_data"]["body"]&&key["source_data"]["link"]) + element_string="
    Safety information: "+(key["source_data"]["body"])+"
    Link: "+(key["source_data"]["link"]) @import_object["steps"][step_pos.to_s]["description"]<" + element_string="
    "+(value["data"].to_s)+"
    " if(@import_object["steps"][step_pos.to_s]["description"]) @import_object["steps"][step_pos.to_s]["description"]<" + element_string="
    Expected result: "+(value["data"])+"
    " @import_object["steps"][step_pos.to_s]["description"]<Developer: "+value["source_data"]["developer"]+"
    Version: "+value["source_data"]["version"]+"
    Link: "+value["source_data"]["link"]+"
    Repository: "+value["source_data"]["repository"]+"
    OS name , OS version: "+value["source_data"]["os_name"]+" , "+value["source_data"]["os_version"] - @import_object["steps"][step_pos.to_s]["description"]<Link: "+value["source_data"]["link"] - @import_object["steps"][step_pos.to_s]["description"]<Description: "+value["source_data"]["description"]+"
    OS name , OS version: "+value["source_data"]["os_name"]+" , "+value["source_data"]["os_version"] - @import_object["steps"][step_pos.to_s]["description"]<Author: "+value["source_data"]["full_name"]+"
    Link: "+value["source_data"]["link"] + if(value["source_data"]["name"]&&value["source_data"]["developer"]&&value["source_data"]["version"]&&value["source_data"]["link"]&&value["source_data"]["repository"]&&value["source_data"]["os_name"]&&value["source_data"]["os_version"]) + element_string="
    Software package: "+(value["source_data"]["name"])+"
    Developer: "+(value["source_data"]["developer"])+"
    Version: "+(value["source_data"]["version"])+"
    Link: "+(value["source_data"]["link"])+"
    Repository: "+(value["source_data"]["repository"])+"
    OS name , OS version: "+(value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) + @import_object["steps"][step_pos.to_s]["description"]<Link: "+(value["source_data"]["link"]) + @import_object["steps"][step_pos.to_s]["description"]<Description: "+(value["source_data"]["description"])+"
    OS name , OS version: "+(value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) + @import_object["steps"][step_pos.to_s]["description"]<Author: "+(value["source_data"]["full_name"])+"
    Link: "+(value["source_data"]["link"]) + @import_object["steps"][step_pos.to_s]["description"]<Link: "+value["source_data"]["link"] + if(value["source_data"]["body"]&&value["source_data"]["link"]) + + element_string="
    Safety information: "+(value["source_data"]["body"])+"
    Link: "+(value["source_data"]["link"]) @import_object["steps"][step_pos.to_s]["description"]< root_url # protocolsDatatable.ajax.reload(); # $('#modal-import-json-protocol-preview').modal('hide'); else + @protocolsio_general_error=false format.json { render json: { name: p_name, new_name: protocol.name, status: :ok diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb index 0bdca490e..703b8eb64 100644 --- a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -86,6 +86,13 @@ Guidelines:
    <%= (@json_object["guidelines"]) %>
    + <% end %> + + <% if @json_object["link"]&&@json_object["link"]!="" %> + +
    Supplied link:
    + <%= (@json_object["link"]) %> + <% end %> <% counter=0 %> @@ -317,37 +324,37 @@ <% if @json_object["manuscript_citation"]&&@json_object["manuscript_citation"]!="" %> -
    Manuscript citation
    +
    Manuscript citation:
    <%= (@json_object["manuscript_citation"]) %> <% end %> <% if @json_object["publish_date"]&&@json_object["publish_date"]!="" %> -
    Publish date
    +
    Publish date:
    <%= (@json_object["publish_date"]) %> <% end %> <% if @json_object["vendor_name"]&&@json_object["vendor_name"]!="" %> -
    Vendor name
    +
    Vendor name:
    <%= (@json_object["vendor_name"]) %> <% end %> <% if @json_object["vendor_link"]&&@json_object["vendor_link"]!="" %> -
    Vendor link
    +
    Vendor link:
    <%= (@json_object["vendor_link"]) %> <% end %> <% if @json_object["keywords"]&&@json_object["keywords"]!="" %> -
    Keywords
    +
    Keywords:
    <%= (@json_object["keywords"]) %> <% end %> <% if @json_object["tags"]&&@json_object["tags"]!="" %> -
    Tags
    +
    Tags:
    <% @json_object["tags"].each do |tag| %> <%= (tag["tag_name"])+" , " %> <% end %> diff --git a/app/views/protocols/protocolsio_import_create.js.erb b/app/views/protocols/protocolsio_import_create.js.erb index 8d8b03acf..f37528b00 100644 --- a/app/views/protocols/protocolsio_import_create.js.erb +++ b/app/views/protocols/protocolsio_import_create.js.erb @@ -1,9 +1,16 @@ -$('#modal-import-json-protocol').modal('hide'); -<% if remotipart_submitted? %> - $('#protocolsio-preview-modal-target').html("<%= j "#{render(:partial => 'protocols/import_export/import_json_protocol_preview_modal')}" %>"); +<% if @protocolsio_too_big %> +alert('<%= I18n.t('my_modules.protocols.load_from_file_size_error', + size: Constants::FILE_MAX_SIZE_MB ) %>'); + + <% else %> - $('#protocolsio-preview-modal-target').html("<%= j render(:partial => 'protocols/import_export/import_json_protocol_preview_modal') %>"); -<% end %> -$('#modal-import-json-protocol-preview').modal('show'); + $('#modal-import-json-protocol').modal('hide'); + <% if remotipart_submitted? %> + $('#protocolsio-preview-modal-target').html("<%= j "#{render(:partial => 'protocols/import_export/import_json_protocol_preview_modal')}" %>"); + <% else %> + $('#protocolsio-preview-modal-target').html("<%= j render(:partial => 'protocols/import_export/import_json_protocol_preview_modal') %>"); + <% end %> + $('#modal-import-json-protocol-preview').modal('show'); +<% end %> diff --git a/app/views/protocols/protocolsio_import_save.js.erb b/app/views/protocols/protocolsio_import_save.js.erb index e3e10e8fc..3741c0eb3 100644 --- a/app/views/protocols/protocolsio_import_save.js.erb +++ b/app/views/protocols/protocolsio_import_save.js.erb @@ -1,2 +1,7 @@ +<% if @protocolsio_general_error %> +alert('<%= I18n.t('my_modules.protocols.load_from_file_protocol_general_error', max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>'); +<% else %> + $('#modal-import-json-protocol-preview').modal('hide'); protocolsDatatable.ajax.reload(); +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index c0f362732..b17d01075 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -603,6 +603,7 @@ en: load_from_file_error: "Failed to load the protocol from file." load_from_file_error_locked: "Failed to load the protocol from file. One or more files are currently being edited." load_from_file_size_error: "Failed to load the protocol from file. Limit is %{size}Mb." + load_from_file_protocol_general_error: "Failed to load the protocol from file. It is likely that certain fields (protocol and individual step titles and names) contain too many or too few characters.(max is %{max} and min is %{min})" results: head_title: "%{project} | %{module} | Results" add_label: "Add new result:" From 6a07aa28e4338ae7bcd341aaca1f6192ff30ca83 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 13:11:49 +0200 Subject: [PATCH 036/189] Accidentally removed this line after reviewing git changes, adding it back --- app/assets/javascripts/protocols/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/protocols/index.js b/app/assets/javascripts/protocols/index.js index 031731988..b53a00c23 100644 --- a/app/assets/javascripts/protocols/index.js +++ b/app/assets/javascripts/protocols/index.js @@ -335,7 +335,7 @@ function initModals() { modal.find(".modal-body").html(""); // Simply re-render table - + protocolsDatatable.ajax.reload(); } From 4051c0b06baf6ca8bb67763232f8dea8273492d4 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 13:28:38 +0200 Subject: [PATCH 037/189] Deleted old unused files i spotted on github --- app/assets/javascripts/temp_jsons.js | 2 -- app/assets/stylesheets/temp_jsons.scss | 3 --- app/controllers/temp_jsons_controller.rb | 16 ---------------- app/helpers/temp_jsons_helper.rb | 2 -- test/controllers/temp_jsons_controller_test.rb | 7 ------- 5 files changed, 30 deletions(-) delete mode 100644 app/assets/javascripts/temp_jsons.js delete mode 100644 app/assets/stylesheets/temp_jsons.scss delete mode 100755 app/controllers/temp_jsons_controller.rb delete mode 100644 app/helpers/temp_jsons_helper.rb delete mode 100644 test/controllers/temp_jsons_controller_test.rb diff --git a/app/assets/javascripts/temp_jsons.js b/app/assets/javascripts/temp_jsons.js deleted file mode 100644 index dee720fac..000000000 --- a/app/assets/javascripts/temp_jsons.js +++ /dev/null @@ -1,2 +0,0 @@ -// Place all the behaviors and hooks related to the matching controller here. -// All this logic will automatically be available in application.js. diff --git a/app/assets/stylesheets/temp_jsons.scss b/app/assets/stylesheets/temp_jsons.scss deleted file mode 100644 index b12deb7f5..000000000 --- a/app/assets/stylesheets/temp_jsons.scss +++ /dev/null @@ -1,3 +0,0 @@ -// Place all the styles related to the temp_jsons controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/temp_jsons_controller.rb b/app/controllers/temp_jsons_controller.rb deleted file mode 100755 index 2839fdd85..000000000 --- a/app/controllers/temp_jsons_controller.rb +++ /dev/null @@ -1,16 +0,0 @@ -class TempJsonsController < ApplicationController - - def new - @temp_json=JsonTemp.new - end - def create - @temp_json=JsonTemp.new(temp_params) - json_file_contents=@temp_json.json_file.read - json_object=JSON.parse(json_file_contents) - - end - - def temp_params - params.require(:json_file) - end -end diff --git a/app/helpers/temp_jsons_helper.rb b/app/helpers/temp_jsons_helper.rb deleted file mode 100644 index 554afcb2d..000000000 --- a/app/helpers/temp_jsons_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module TempJsonsHelper -end diff --git a/test/controllers/temp_jsons_controller_test.rb b/test/controllers/temp_jsons_controller_test.rb deleted file mode 100644 index 4fe936641..000000000 --- a/test/controllers/temp_jsons_controller_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'test_helper' - -class TempJsonsControllerTest < ActionController::TestCase - # test "the truth" do - # assert true - # end -end From 6ebdea5dcef569f23a83ad95f31e5cac5cf54b60 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 15:12:29 +0200 Subject: [PATCH 038/189] Fixed old workaround with inconsistent protocols.io json formatting and made the workaround nicer (now its only one if statement, instead of one whole block of duplicated code) --- app/controllers/protocols_controller.rb | 88 ++------------ ...mport_json_protocol_preview_modal.html.erb | 111 +++--------------- 2 files changed, 25 insertions(+), 174 deletions(-) diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 442cd23fc..d4452e5cc 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -608,7 +608,7 @@ class ProtocolsController < ApplicationController def protocolsio_import_create @protocolsio_too_big=false file_size=(File.size(params[:json_file].path)) - + if(file_size/1000>Constants::FILE_MAX_SIZE_MB) @protocolsio_too_big=true respond_to do |format| @@ -699,8 +699,12 @@ def protocolsio_import_save step["components"].each do |key,value| element_string=nil - if counter>1 #here i made an if to distinguish the first step from the others, because the first step - #sometimes has weird nesting that requires different handling + if counter<=1 #here i made an if to distinguish the first step from the others, because the first step + #sometimes has index values as keys instead of hashes + if value.class==Hash + key=value + end + end if whitelist_simple.include?(key["component_type_id"]) case key["component_type_id"] @@ -770,85 +774,7 @@ def protocolsio_import_save end end #finished step component iteration - else #it is first step - unless value - value=key #some json files have random empty arrays in beggining of step components - end - if whitelist_simple.include?(value["component_type_id"]) - - case value["component_type_id"] - when "1" - if !value["data"].nil? && value["data"]!="" - - element_string="
    "+(value["data"].to_s)+"
    " - if(@import_object["steps"][step_pos.to_s]["description"]) - @import_object["steps"][step_pos.to_s]["description"]<" - @import_object["steps"][step_pos.to_s]["description"]<Developer: "+(value["source_data"]["developer"])+"
    Version: "+(value["source_data"]["version"])+"
    Link: "+(value["source_data"]["link"])+"
    Repository: "+(value["source_data"]["repository"])+"
    OS name , OS version: "+(value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) - @import_object["steps"][step_pos.to_s]["description"]<Link: "+(value["source_data"]["link"]) - @import_object["steps"][step_pos.to_s]["description"]<Description: "+(value["source_data"]["description"])+"
    OS name , OS version: "+(value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) - @import_object["steps"][step_pos.to_s]["description"]<Author: "+(value["source_data"]["full_name"])+"
    Link: "+(value["source_data"]["link"]) - @import_object["steps"][step_pos.to_s]["description"]<Link: "+(value["source_data"]["link"]) - @import_object["steps"][step_pos.to_s]["description"]< <% step["components"].each do |key1,value1| #finding section (title of step) %> - <% if counter >1 %> + <% if counter <=1 %> + <% if value1.class==Hash %> + <% key1=value1 %> + <% end %> + <% end %> <% if(key1["component_type_id"]=="6") %> <% if(!key1["data"].nil? && key1["data"]!="") %> <%# byebug %> <% title ||=key1["data"] %> <% end %> <% end %> - <% else %> - <% unless value1 %> - <% value1=key1 %> - <% end %> - <% if(value1["component_type_id"]=="6") %> - <% if(!value1["data"].nil? && value1["data"]!="") %> - <% #byebug %> - <% title ||=value1["data"] %> + <% end %> - <% end %> - <% end %> - <% end %> <% if title.nil? %> <%# byebug %> <% title ="Protocols.io" %> @@ -153,16 +147,19 @@ <% step["components"].each do |key,value| %> - - <% if counter>1 #here i made an if to distinguish the first step from the others, because the first step - #sometimes has weird nesting that makes the below outputs not work + <% if counter<=1 #here i made an if to distinguish the first step from the others, because the first step + #sometimes has index values as keys instead of hashes %> + <% if value.class==Hash %> + <% key=value %> + <% end %> + <% end %> + + <% if whitelist_simple.include?(key["component_type_id"]) && key["data"]!="" && key["data"] %>
    <% case key["component_type_id"]%> - <% when "6" %> - - <% when "1" %> + <% when "1" %>
    Description: <%=key["data"]%>
    <% when "17" %>
    Expected result: <%=key["data"]%>
    @@ -220,83 +217,11 @@ <% else %> - <% end %> + <% end #case if%> - <% end #notranji if št 1%> - - <% else #if first step %> - - <% unless value %> - <% value=key #protocols io first step json formating is sometimes broken, this is a workaround%> - <% end %> - <% #byebug %> - <% if whitelist_simple.include?(value["component_type_id"]) && value["data"] && value["data"]!="" %> -
    - <% case value["component_type_id"]%> - <% when "6" %> - - <% when "1" %> -
    Description: <%=value["data"]%>
    - <% when "17" %> -
    Expected result: <%=value["data"]%>
    - <% else %> - <% end %> - - <% elsif value && whitelist_complex.include?(value["component_type_id"]) %> - <% case value["component_type_id"]%> - <% when "8"%> -
    - <%= value["name"]+": " %> <%= (value["source_data"]["name"]) %> -
    - Developer : <%= (value["source_data"]["developer"]) %> -
    - Version : <%= (value["source_data"]["version"]) %> -
    - Link : <%= (value["source_data"]["link"]) %> -
    - Repository : <%= (value["source_data"]["repository"]) %> -
    - OS name , OS version : <%= (value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) %> - - <% when "9"%> -
    - <%= value["name"]+": " %> <%= value["source_data"]["name"] %> -
    - Link : <%= (value["source_data"]["link"]) %> + <% end #inner if%> - <% when "15"%> -
    - <%= value["name"]+": " %> <%= value["source_data"]["name"] %> -
    - Description : <%= (value["source_data"]["description"]) %> -
    - OS name , OS version : <%= (value["source_data"]["os_name"])+" , "+(value["source_data"]["os_version"]) %> - - <% when "18"%> -
    - This protocol also contains an attached sub-protocol: <%= (value["source_data"]["protocol_name"]) %> -
    - Author: <%= (value["source_data"]["full_name"]) %> -
    - <% if value["source_data"]["link"]&&value["source_data"]["link"]!="" %> - Link: <%= (value["source_data"]["link"]) %> - <% end %> - <% when "19"%> -
    - <%= value["name"]+": " %> <%= value["source_data"]["body"] %> -
    - Link : <%= (value["source_data"]["link"]) %> - - - <% when "20"%> - - <% else %> - - <% end %> - - <% end #inner whitelist if%> - <% end #first step if %> <% end #step component loop %>
    @@ -317,7 +242,7 @@
    - <%# div od blocka %> + <%# block div%> <% end #step loop%> From dd4d4072e875c72be3945fc6d2d5d2ff69f9ab67 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 16:02:56 +0200 Subject: [PATCH 039/189] Made code more aesthetic --- app/assets/javascripts/protocols/index.js | 2 - app/controllers/protocols_controller.rb | 50 ++++++------------- ...mport_json_protocol_preview_modal.html.erb | 2 +- .../protocolsio_import_create.js.erb | 2 +- 4 files changed, 17 insertions(+), 39 deletions(-) diff --git a/app/assets/javascripts/protocols/index.js b/app/assets/javascripts/protocols/index.js index b53a00c23..13960bbec 100644 --- a/app/assets/javascripts/protocols/index.js +++ b/app/assets/javascripts/protocols/index.js @@ -338,8 +338,6 @@ function initModals() { protocolsDatatable.ajax.reload(); } - - // Make private modal hidden action $("#make-private-results-modal").on("hidden.bs.modal", function(e) { refresh($(this)); diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index d4452e5cc..62ec530e0 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -66,7 +66,6 @@ class ProtocolsController < ApplicationController before_action :check_import_permissions, only: [ :import ] before_action :check_export_permissions, only: [ :export ] - def index end @@ -469,7 +468,6 @@ class ProtocolsController < ApplicationController end def load_from_repository - respond_to do |format| if @protocol.can_destroy? transaction_error = false @@ -520,7 +518,6 @@ class ProtocolsController < ApplicationController def load_from_file # This is actually very similar to import - respond_to do |format| if @protocol.can_destroy? transaction_error = false @@ -569,8 +566,7 @@ class ProtocolsController < ApplicationController end end - def import #tega uporabi .eln import - + def import protocol = nil respond_to do |format| transaction_error = false @@ -603,8 +599,7 @@ class ProtocolsController < ApplicationController end end end -# -#tule + def protocolsio_import_create @protocolsio_too_big=false file_size=(File.size(params[:json_file].path)) @@ -612,40 +607,30 @@ def protocolsio_import_create if(file_size/1000>Constants::FILE_MAX_SIZE_MB) @protocolsio_too_big=true respond_to do |format| - format.js {} + format.js {} #if file is too big, default to the js.erb file named the same as this controller + # where a javascript alert is called end - else - @protocolsio_too_big=false end - json_file_contents=File.read(params[:json_file].path) - - json_file_contents.gsub! '\"', "'" - - + json_file_contents.gsub! '\"', "'" #escaped double quotes too stressfull, html works with single quotes too + #json double quotes dont get escaped since they dont match \", they are just " @json_object=JSON.parse(json_file_contents) @protocol=Protocol.new - respond_to do |format| - #format.html {} - format.js {} + format.js {} # go to the js.erb file named the same as this controller, where a preview modal is rendered, and + # some modals get closed and opened end - end def protocolsio_import_save - #@temp_json=JsonTemp.new @json_object=JSON.parse(params["json_object"]) @import_object=Hash.new @import_object["name"]=params["protocol"]["name"] - - # will have to fit various things in here (guidelines, manuscript citations etc etc) - #"before_start","warning","guidelines","manuscript_citation","publish_date","created_on" - #"vendor_name","vendor_link","keywords","tags" + # since scinote only has description field, while protocols.io has many many others, here i am basically + #putting everything important from protocols.io into description description_array = [ "before_start","warning","guidelines","manuscript_citation","publish_date","created_on","vendor_name","vendor_link","keywords","tags","link" ] description_string=params["protocol"]["description"] - #@import_object["description"]=params["protocol"]["description"] description_array.each do |element| if(element=="created_on") if(@json_object[element]&&@json_object[element]!="") @@ -664,7 +649,8 @@ def protocolsio_import_save end description_string=description_string+"\n" end - + #Since protocols description field doesnt show html, i just remove it here because its even messier Otherwise + #what this does is basically appends "FIELD NAME: "+" FIELD VALUE" to description for various fields else if(@json_object[element]&&@json_object[element]!="") new_element = element.slice(0,1).capitalize + element.slice(1..-1) @@ -674,33 +660,27 @@ def protocolsio_import_save end end end - @import_object["authors"]=params["protocol"]["authors"] @import_object["created_at"]=params["protocol"]["created_at"] @import_object["updated_at"]=params["protocol"]["last_modified"] @import_object["description"]=description_string - #@import_object["steps"] - - @import_object["steps"]=Hash.new counter=0 step_pos=-1 - #these whitelists are there to not let some useless step components true, that always have data set to null (data doesnt get imported over to json) + #these whitelists are there to not let some useless step components trough, that always have data set to null (data doesnt get imported over to json) whitelist_simple=["1","6","17"] #(simple to map) id 1= step description, id 6= section (title), id 17= expected result whitelist_complex=["8","9","15","18","19","20"] #(complex mapping with nested hashes) id 8 = software package, id 9 = dataset, id 15 = command, id 18 = attached sub protocol # id 19= safety information ,id 20= regents (materials, like scinote samples kind of) @json_object["steps"].each do |step| - #@import_object["steps"][step_pos.to_s]=step step_pos+=1 counter+=1 - @import_object["steps"][step_pos.to_s]=Hash.new @import_object["steps"][step_pos.to_s]["position"]=step_pos step["components"].each do |key,value| element_string=nil if counter<=1 #here i made an if to distinguish the first step from the others, because the first step - #sometimes has index values as keys instead of hashes + #sometimes has index values as keys instead of hashes, for no good reason if value.class==Hash key=value end @@ -724,7 +704,7 @@ def protocolsio_import_save if !key["data"].nil? && key["data"]!="" @import_object["steps"][step_pos.to_s]["name"]=key["data"] else - @import_object["steps"][step_pos.to_s]["name"]="Protocols.io" + @import_object["steps"][step_pos.to_s]["name"]="Step" end when "17" if !key["data"].nil? && key["data"]!="" diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb index 50417e9e7..5f1bd5842 100644 --- a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -134,7 +134,7 @@ <% end %> <% if title.nil? %> <%# byebug %> - <% title ="Protocols.io" %> + <% title ="Step" %> <% end %> <%= title %> diff --git a/app/views/protocols/protocolsio_import_create.js.erb b/app/views/protocols/protocolsio_import_create.js.erb index f37528b00..50d95301f 100644 --- a/app/views/protocols/protocolsio_import_create.js.erb +++ b/app/views/protocols/protocolsio_import_create.js.erb @@ -7,7 +7,7 @@ alert('<%= I18n.t('my_modules.protocols.load_from_file_size_error', <% else %> $('#modal-import-json-protocol').modal('hide'); - <% if remotipart_submitted? %> + <% if remotipart_submitted? %> <%# a workaround to a bug with remotipart, that caused alot of headache, courtesy of github.com/dhampik %> $('#protocolsio-preview-modal-target').html("<%= j "#{render(:partial => 'protocols/import_export/import_json_protocol_preview_modal')}" %>"); <% else %> $('#protocolsio-preview-modal-target').html("<%= j render(:partial => 'protocols/import_export/import_json_protocol_preview_modal') %>"); From 549346bb0a8ec35190d270bd4d431556db748516 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 22 Sep 2017 16:13:06 +0200 Subject: [PATCH 040/189] Deleted a warning that was out of place --- .../_import_json_protocol_preview_modal.html.erb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb index 5f1bd5842..6bf7ffa68 100644 --- a/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_preview_modal.html.erb @@ -11,11 +11,7 @@ From ac26b17ddf29a1115b59007480a4145155b03c12 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 3 Nov 2017 16:45:15 +0100 Subject: [PATCH 096/189] Rubocop refactor --- app/assets/stylesheets/themes/scinote.scss | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index e0da5c7ba..89e7781b0 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -339,16 +339,18 @@ a { } .btn-link-alt { border-radius: 4px; + cursor: pointer; margin-right: 5px; padding: 3px; - cursor:pointer; } -.btn-invis-file{ + +.btn-invis-file { + display: none; opacity: 0; position: absolute; z-index: -1; - display: none; } + .btn-open-file { position: relative; overflow: hidden; @@ -1272,20 +1274,20 @@ ul.content-module-activities { } } -/* Import json protocols.io protocol modal */ +// Import json protocols.io protocol modal #modal-import-json-protocol-preview .modal-dialog { width: 70%; } .import-protocols-modal-preview-container-json { height: 300px; - overflow-y: scroll; overflow-x: scroll; + overflow-y: scroll; width: 100%; .eln-table { - text-align: center; height: 21px; + text-align: center; } .badge-preview { @@ -1834,8 +1836,8 @@ textarea.textarea-sm { -webkit-padding-after: 0; } .btn.btn-default-link { - border:none; - padding:0; + border: 0; + padding: 0; height: 100%; min-height: 34px; -webkit-padding-before: 0; From 4354363215c27b101161d22d16e373a8799e093f Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 3 Nov 2017 16:46:03 +0100 Subject: [PATCH 097/189] rubocop refactor css --- app/assets/stylesheets/themes/scinote.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 89e7781b0..96be2928b 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -1837,11 +1837,11 @@ textarea.textarea-sm { } .btn.btn-default-link { border: 0; - padding: 0; height: 100%; min-height: 34px; - -webkit-padding-before: 0; + padding: 0; -webkit-padding-after: 0; + -webkit-padding-before: 0; } } From 0dc0109d91d1f9cfcd56acac6defced00b4936be Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 3 Nov 2017 21:47:52 +0100 Subject: [PATCH 098/189] reverted schema --- db/schema.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index e0fcd75d2..337d4ca50 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -544,12 +544,12 @@ ActiveRecord::Schema.define(version: 20170619125051) do add_index "samples", ["user_id"], name: "index_samples_on_user_id", using: :btree create_table "samples_tables", force: :cascade do |t| - t.jsonb "status", default: {"time"=>0, "order"=>[[2, "desc"]], "start"=>0, "length"=>10, "search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "columns"=>[{"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}], "assigned"=>"all", "ColReorder"=>[0, 1, 2, 3, 4, 5, 6]}, null: false - t.integer "user_id", null: false - t.integer "team_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end + t.jsonb "status", default: {"time"=>0, "order"=>[[2, "desc"]], "start"=>0, "length"=>10, "search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "columns"=>[{"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}, {"search"=>{"regex"=>false, "smart"=>true, "search"=>"", "caseInsensitive"=>true}, "visible"=>true}], "ColReorder"=>[0, 1, 2, 3, 4, 5, 6]}, null: false + t.integer "user_id", null: false + t.integer "team_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false +end add_index "samples_tables", ["team_id"], name: "index_samples_tables_on_team_id", using: :btree add_index "samples_tables", ["user_id"], name: "index_samples_tables_on_user_id", using: :btree From 04c6f0c20df1227c9695b6a3822a495536858a23 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 3 Nov 2017 21:50:06 +0100 Subject: [PATCH 099/189] schema missing space --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 337d4ca50..26902db7c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -549,7 +549,7 @@ ActiveRecord::Schema.define(version: 20170619125051) do t.integer "team_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false -end + end add_index "samples_tables", ["team_id"], name: "index_samples_tables_on_team_id", using: :btree add_index "samples_tables", ["user_id"], name: "index_samples_tables_on_user_id", using: :btree From 09ac0febbbf73f371fd6309cbff54f3f720ef988 Mon Sep 17 00:00:00 2001 From: Luka Murn Date: Tue, 7 Nov 2017 12:48:53 +0100 Subject: [PATCH 100/189] Bump version to 1.12.6 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index e0a6b34fb..456e5c4ad 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.12.5 +1.12.6 From f43492adff46c640e929fb7c87da0b9252bd3da1 Mon Sep 17 00:00:00 2001 From: zmagod Date: Tue, 7 Nov 2017 15:08:26 +0100 Subject: [PATCH 101/189] trigger an alert to on canvas save if page reload [fixes SCI-1610] --- app/assets/javascripts/projects/canvas.js.erb | 37 +++++++++++++++++++ config/locales/en.yml | 1 + 2 files changed, 38 insertions(+) diff --git a/app/assets/javascripts/projects/canvas.js.erb b/app/assets/javascripts/projects/canvas.js.erb index bd070ad7a..1e5087844 100644 --- a/app/assets/javascripts/projects/canvas.js.erb +++ b/app/assets/javascripts/projects/canvas.js.erb @@ -240,6 +240,7 @@ function initializeEdit() { // Restore draggable position restoreDraggablePosition($("#diagram"), $("#canvas-container")); + preventCanvasReloadOnSave(); $("#canvas-container").submit(function (){ animateSpinner( this, @@ -3108,3 +3109,39 @@ function tutorialAfterCb() { .css({'pointer-events': 'auto'}); }); } + +/** prevent reload page */ +var preventCanvasReloadOnSave = (function() { + 'use strict'; + + function confirmReload() { + if( confirm(I18n.t('experiments.canvas.reload_on_submit')) ) { + return true; + } else { + return false + } + } + + function preventCanvasReload() { + document.onkeydown = function(){ + switch (event.keyCode){ + case 116: + event.returnValue = false; + return confirmReload(); + case 82: + if (event.ctrlKey){ + event.returnValue = false; + return confirmReload(); + } + } + } + } + + function bindToCanvasSave(fun) { + $('#canvas-save').on('click', function() { + fun(); + }) + } + + return function() { bindToCanvasSave(preventCanvasReload) }; +})(); diff --git a/config/locales/en.yml b/config/locales/en.yml index 827016a01..2183553f9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -682,6 +682,7 @@ en: head_title: "%{project} | Overview" canvas_edit: "Edit experiment" zoom: "Zoom: " + reload_on_submit: "Save action is running. Reloading this page may cause unexpected behavior." modal_manage_tags: head_title: "Manage tags for" subtitle: "Showing tags of task %{module}" From 9086cd8b6b79a53ec474bb26ec8e917ef0bb023b Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Wed, 25 Oct 2017 22:08:33 +0200 Subject: [PATCH 102/189] Jira branch code --- .../import_export/_import_json_protocol_p_desc.html.erb | 8 ++++---- config/locales/en.yml | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb b/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb index b1a62200f..365fc8dd2 100644 --- a/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb @@ -28,10 +28,6 @@ <%= t('protocols.protocols_io_import.preview.guideln') %> <%= sanitize_input(json_object['guidelines'].html_safe) %>
    <% end %> - <% if json_object['link'].present? %> - <%= t('protocols.protocols_io_import.preview.p_link') %> - <%= sanitize_input(json_object['link'].html_safe) %>
    - <% end %> <% if json_object['manuscript_citation'].present? %> <%= t('protocols.protocols_io_import.preview.manu_cit') %> <%= sanitize_input(json_object['manuscript_citation'].html_safe) %>
    @@ -58,6 +54,10 @@ <%= sanitize_input(tag['tag_name'])+' , ' %>
    <% end %> <% end %> + <% if json_object['link'].present? %> + <%= t('protocols.protocols_io_import.preview.p_link') %> + <%= sanitize_input(json_object['link'].html_safe) %>
    + <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d77f7546c..3331e45cd 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1385,7 +1385,7 @@ en: b_s_p: "Before starting protocol information:" warn: "Protocol warning:" guideln: "Guidelines:" - p_link: "Supplied link:" + p_link: "Link:" s_nobr_link: "Link:" s_link: "Link:" s_desc: "Description:" @@ -1555,6 +1555,7 @@ en: title: "Import results" message_failed: "Failed to import %{nr} protocol/s." message_ok: "Successfully imported %{nr} protocol/s." + message_ok_pio: "Successfully imported protocol from protocols.io file." row_success: "Imported" row_renamed: "Imported & renamed" row_failed: "Failed" From 8b247770efa065870bb7b4285957512f9ac56e05 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Wed, 25 Oct 2017 23:04:19 +0200 Subject: [PATCH 103/189] Added the success flash alert --- app/views/protocols/protocolsio_import_save.js.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/protocols/protocolsio_import_save.js.erb b/app/views/protocols/protocolsio_import_save.js.erb index 16ad30454..830ebafbf 100644 --- a/app/views/protocols/protocolsio_import_save.js.erb +++ b/app/views/protocols/protocolsio_import_save.js.erb @@ -1,8 +1,9 @@ <% if @protocolsio_general_error %> - alert('<%= I18n.t('my_modules.protocols.load_from_file_protocol_general_error', + alert('<%= t('my_modules.protocols.load_from_file_protocol_general_error', max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>'); <% else %> $('#modal-import-json-protocol-preview').modal('hide'); $('#protocols_io_form').trigger("reset"); protocolsDatatable.ajax.reload(); + HelperModule.flashAlertMsg('<%= t('protocols.index.import_results.message_ok_pio')%>', 'success'); <% end %> From feb686b4ac604583d50326f63d392e3babc01d23 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Wed, 25 Oct 2017 23:17:20 +0200 Subject: [PATCH 104/189] Fixed alignement --- app/views/protocols/protocolsio_import_save.js.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/protocols/protocolsio_import_save.js.erb b/app/views/protocols/protocolsio_import_save.js.erb index 830ebafbf..6fa532567 100644 --- a/app/views/protocols/protocolsio_import_save.js.erb +++ b/app/views/protocols/protocolsio_import_save.js.erb @@ -5,5 +5,5 @@ $('#modal-import-json-protocol-preview').modal('hide'); $('#protocols_io_form').trigger("reset"); protocolsDatatable.ajax.reload(); - HelperModule.flashAlertMsg('<%= t('protocols.index.import_results.message_ok_pio')%>', 'success'); + HelperModule.flashAlertMsg(' <%= t('protocols.index.import_results.message_ok_pio')%>', 'success'); <% end %> From 4b837dbe9dbc6ea8da60ef59738a31702e7bf2e2 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Fri, 27 Oct 2017 00:17:42 +0200 Subject: [PATCH 105/189] Forgot flash fail messagges, now added them for file too big and general error --- app/views/protocols/protocolsio_import_create.js.erb | 5 +++-- app/views/protocols/protocolsio_import_save.js.erb | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/protocols/protocolsio_import_create.js.erb b/app/views/protocols/protocolsio_import_create.js.erb index ba20d05c3..b9dbd0cd5 100644 --- a/app/views/protocols/protocolsio_import_create.js.erb +++ b/app/views/protocols/protocolsio_import_create.js.erb @@ -1,7 +1,8 @@ <% if @protocolsio_too_big %> -alert('<%= I18n.t('my_modules.protocols.load_from_file_size_error', - size: Constants::FILE_MAX_SIZE_MB ) %>'); +$('#modal-import-json-protocol').modal('hide'); +HelperModule.flashAlertMsg(' <%= t('my_modules.protocols.load_from_file_size_error', + size: Constants::FILE_MAX_SIZE_MB ) %>','danger'); <% else %> $('#modal-import-json-protocol').modal('hide'); <% if remotipart_submitted? %> <%# a workaround to a bug with remotipart, that caused alot of headache, courtesy of github.com/dhampik %> diff --git a/app/views/protocols/protocolsio_import_save.js.erb b/app/views/protocols/protocolsio_import_save.js.erb index 6fa532567..5566d0f54 100644 --- a/app/views/protocols/protocolsio_import_save.js.erb +++ b/app/views/protocols/protocolsio_import_save.js.erb @@ -1,6 +1,7 @@ <% if @protocolsio_general_error %> - alert('<%= t('my_modules.protocols.load_from_file_protocol_general_error', - max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>'); +$('#modal-import-json-protocol-preview').modal('hide'); + HelperModule.flashAlertMsg(' <%= t('my_modules.protocols.load_from_file_protocol_general_error', + max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>', 'danger'); <% else %> $('#modal-import-json-protocol-preview').modal('hide'); $('#protocols_io_form').trigger("reset"); From 518eb09110767903cb907f0dd6de6d6588fe84b8 Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Thu, 2 Nov 2017 16:48:09 +0100 Subject: [PATCH 106/189] Deleted un needed error flash --- app/views/protocols/protocolsio_import_save.js.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/protocols/protocolsio_import_save.js.erb b/app/views/protocols/protocolsio_import_save.js.erb index 5566d0f54..1250b7816 100644 --- a/app/views/protocols/protocolsio_import_save.js.erb +++ b/app/views/protocols/protocolsio_import_save.js.erb @@ -1,7 +1,7 @@ <% if @protocolsio_general_error %> $('#modal-import-json-protocol-preview').modal('hide'); - HelperModule.flashAlertMsg(' <%= t('my_modules.protocols.load_from_file_protocol_general_error', - max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>', 'danger'); + alert(' <%= t('my_modules.protocols.load_from_file_protocol_general_error', + max: Constants::NAME_MAX_LENGTH, min: Constants::NAME_MIN_LENGTH) %>'); <% else %> $('#modal-import-json-protocol-preview').modal('hide'); $('#protocols_io_form').trigger("reset"); From a40a63ae50a33174275f856186d808194fe4c7ae Mon Sep 17 00:00:00 2001 From: Zanz2 Date: Thu, 9 Nov 2017 15:38:06 +0100 Subject: [PATCH 107/189] Made code more aesthetic --- .../_import_json_protocol_p_desc.html.erb | 139 +++++++++--------- .../_import_json_protocol_s_desc.html.erb | 23 ++- 2 files changed, 76 insertions(+), 86 deletions(-) diff --git a/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb b/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb index ee294c054..266a9ed07 100644 --- a/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb +++ b/app/views/protocols/import_export/_import_json_protocol_p_desc.html.erb @@ -12,78 +12,73 @@
    -
    -
    -
    -
    - <% prot_info_string = '' %> - <% protocol_table_elements_array = [] %> - <% if json_object['before_start'].present? %> - <% prot_info_string += (json_object['before_start']) %> - <%= t('protocols.protocols_io_import.preview.b_s_p') %> - <%= sanitize_input(string_html_table_remove(json_object['before_start']).html_safe) %>
    - <% end %> - <% if json_object['warning'].present? %> - <% prot_info_string += (json_object['warning']) %> - <%= t('protocols.protocols_io_import.preview.warn') %> - <%= sanitize_input(string_html_table_remove(json_object['warning']).html_safe) %>
    - <% end %> - <% if json_object['guidelines'].present? %> - <% prot_info_string += (json_object['guidelines']) %> - <%= t('protocols.protocols_io_import.preview.guideln') %> - <%= sanitize_input(string_html_table_remove(json_object['guidelines']).html_safe) %>
    - <% end %> - <% if json_object['manuscript_citation'].present? %> - <% prot_info_string += (json_object['manuscript_citation']) %> - <%= t('protocols.protocols_io_import.preview.manu_cit') %> - <%= sanitize_input(string_html_table_remove(json_object['manuscript_citation']).html_safe) %>
    - <% end %> - <% if json_object['publish_date'].present? %> - <%= t('protocols.protocols_io_import.preview.pbl_date') %> - <%= sanitize_input(json_object['publish_date']) %>
    - <% end %> - <% if json_object['vendor_name'].present? %> - <%= t('protocols.protocols_io_import.preview.vnd_name') %> - <%= sanitize_input(json_object['vendor_name']) %>
    - <% end %> - <% if json_object['vendor_link'].present? %> - <%= t('protocols.protocols_io_import.preview.vnd_link') %> - <%= sanitize_input(json_object['vendor_link'].html_safe) %>
    - <% end %> - <% if json_object['keywords'].present? %> - <%= t('protocols.protocols_io_import.preview.key_wrd') %> - <%= sanitize_input(json_object['keywords']) %>
    - <% end %> - <% if json_object['tags'].present? %> - <%= t('protocols.protocols_io_import.preview.tags') %> - <% json_object['tags'].each do |tag| %> - <%= sanitize_input(tag['tag_name'])+' , ' %>
    - <% end %> - <% end %> - <% if json_object['link'].present? %> - <%= t('protocols.protocols_io_import.preview.p_link') %> - <%= sanitize_input(json_object['link'].html_safe) %>
    - <% end %> - <% tables, garbage = protocolsio_string_to_table_element(prot_info_string) %> - <% if tables.present? %> -


    - <% end %> - <% table_count = 0 %> - <% tables.each do |index, table| %> - <% table_hash = JSON.parse((Base64.decode64(table['contents']))) %> - <% pio_table_id = "pio_table_prot_info_"+table_count.to_s %> - <% protocol_table_elements_array.push([pio_table_id,table_hash['data']]) %> - - -
    - - - <% table_count += 1 %> - <% end %> - -
    -
    -
    +
    +
    +
    +
    + <% prot_info_string = '' %> + <% protocol_table_elements_array = [] %> + <% if json_object['before_start'].present? %> + <% prot_info_string += (json_object['before_start']) %> + <%= t('protocols.protocols_io_import.preview.b_s_p') %> + <%= sanitize_input(string_html_table_remove(json_object['before_start']).html_safe) %>
    + <% end %> + <% if json_object['warning'].present? %> + <% prot_info_string += (json_object['warning']) %> + <%= t('protocols.protocols_io_import.preview.warn') %> + <%= sanitize_input(string_html_table_remove(json_object['warning']).html_safe) %>
    + <% end %> + <% if json_object['guidelines'].present? %> + <% prot_info_string += (json_object['guidelines']) %> + <%= t('protocols.protocols_io_import.preview.guideln') %> + <%= sanitize_input(string_html_table_remove(json_object['guidelines']).html_safe) %>
    + <% end %> + <% if json_object['manuscript_citation'].present? %> + <% prot_info_string += (json_object['manuscript_citation']) %> + <%= t('protocols.protocols_io_import.preview.manu_cit') %> + <%= sanitize_input(string_html_table_remove(json_object['manuscript_citation']).html_safe) %>
    + <% end %> + <% if json_object['publish_date'].present? %> + <%= t('protocols.protocols_io_import.preview.pbl_date') %> + <%= sanitize_input(json_object['publish_date']) %>
    + <% end %> + <% if json_object['vendor_name'].present? %> + <%= t('protocols.protocols_io_import.preview.vnd_name') %> + <%= sanitize_input(json_object['vendor_name']) %>
    + <% end %> + <% if json_object['vendor_link'].present? %> + <%= t('protocols.protocols_io_import.preview.vnd_link') %> + <%= sanitize_input(json_object['vendor_link'].html_safe) %>
    + <% end %> + <% if json_object['keywords'].present? %> + <%= t('protocols.protocols_io_import.preview.key_wrd') %> + <%= sanitize_input(json_object['keywords']) %>
    + <% end %> + <% if json_object['tags'].present? %> + <%= t('protocols.protocols_io_import.preview.tags') %> + <% json_object['tags'].each do |tag| %> + <%= sanitize_input(tag['tag_name'])+' , ' %>
    + <% end %> + <% end %> + <% if json_object['link'].present? %> + <%= t('protocols.protocols_io_import.preview.p_link') %> + <%= sanitize_input(json_object['link'].html_safe) %>
    + <% end %> + <% tables, garbage = protocolsio_string_to_table_element(prot_info_string) %> + <% if tables.present? %> +


    + <% end %> + <% table_count = 0 %> + <% tables.each do |index, table| %> + <% table_hash = JSON.parse((Base64.decode64(table['contents']))) %> + <% pio_table_id = "pio_table_prot_info_"+table_count.to_s %> + <% protocol_table_elements_array.push([pio_table_id,table_hash['data']]) %> +
    + <% table_count += 1 %> + <% end %> +
    +
    +