diff --git a/.annotaterb.yml b/.annotaterb.yml new file mode 100644 index 0000000000..0f4129c32e --- /dev/null +++ b/.annotaterb.yml @@ -0,0 +1,71 @@ +--- +:position: before +:position_in_additional_file_patterns: before +:position_in_class: before +:position_in_factory: before +:position_in_fixture: before +:position_in_routes: before +:position_in_serializer: before +:position_in_test: before +:classified_sort: true +:exclude_controllers: true +:exclude_factories: false +:exclude_fixtures: true +:exclude_helpers: true +:exclude_scaffolds: true +:exclude_serializers: true +:exclude_sti_subclasses: false +:exclude_tests: true +:force: false +:format_markdown: false +:format_rdoc: false +:format_yard: false +:frozen: false +:grouped_polymorphic: false +:ignore_database_name: false +:ignore_model_sub_dir: false +:ignore_unknown_models: false +:include_version: false +:show_check_constraints: false +:show_unique_constraints: false +:show_exclusion_constraints: false +:show_enums: false +:show_complete_foreign_keys: false +:show_foreign_keys: true +:show_indexes: true +:show_indexes_comments: false +:show_indexes_include: false +:simple_indexes: false +:sort: false +:timestamp: false +:trace: false +:with_comment: true +:with_column_comments: true +:with_table_comments: true +:position_of_column_comment: :with_name +:active_admin: false +:command: +:debug: false +:hide_default_column_types: json,jsonb,hstore +:hide_limit_column_types: integer,boolean +:timestamp_columns: +- created_at +- updated_at +:ignore_columns: +:ignore_routes: +:ignore_multi_database_name: false +:models: true +:routes: false +:skip_on_db_migrate: false +:auto_annotate_routes_after_migrate: false +:target_action: :do_annotations +:wrapper: +:wrapper_close: +:wrapper_open: +:classes_default_to_s: [] +:additional_file_patterns: [] +:model_dir: +- app/models +:require: [] +:root_dir: +- '' diff --git a/.github/workflows/brakeman.yml b/.github/workflows/brakeman.yml index 52ecd71cf1..1ba5268110 100644 --- a/.github/workflows/brakeman.yml +++ b/.github/workflows/brakeman.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 # Will run Brakeman checks on dependencies # https://github.com/marketplace/actions/brakeman-action diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index 650ac6720e..8b64400fe5 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - name: 'Determine Ruby and Bundler Versions from Gemfile.lock' run: | @@ -27,4 +27,4 @@ jobs: - name: 'Run Danger' env: DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: bundle exec danger \ No newline at end of file + run: bundle exec danger diff --git a/.github/workflows/eslint.yml b/.github/workflows/eslint.yml index a3aa258eae..e29efe6a6f 100644 --- a/.github/workflows/eslint.yml +++ b/.github/workflows/eslint.yml @@ -9,17 +9,23 @@ jobs: steps: # Checkout the repo - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 # Install Node - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v5 with: cache: 'yarn' - node-version: 18 + node-version: 24 # Run yarn install for JS dependencies - name: 'Yarn Install' - run: yarn install + run: yarn install --frozen-lockfile - name: 'Run ESLint' - run: yarn run eslint app/javascript/**/*.js --ext .js + run: yarn lint + + - name: 'Run JavaScript tests' + run: yarn test --reporters dots + + - name: 'Build CSS' + run: yarn build:css diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml index 7c25271528..7df099a8ef 100644 --- a/.github/workflows/mysql.yml +++ b/.github/workflows/mysql.yml @@ -14,7 +14,7 @@ jobs: steps: # Checkout the repo - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 # Install Ruby and run bundler - uses: ruby/setup-ruby@v1 @@ -22,9 +22,9 @@ jobs: bundler-cache: true # Install Node - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v5 with: - node-version: 18 + node-version: 24 cache: 'yarn' # Copy all of the example configs over @@ -45,7 +45,7 @@ jobs: # Run yarn install for JS dependencies - name: 'Yarn Install' - run: yarn install + run: yarn install --frozen-lockfile # Start the DB server and initialize the DB - name: 'Start MySQL' @@ -53,8 +53,8 @@ jobs: - name: 'Build out the test database' run: | - DISABLE_SPRING=1 bundle exec rails db:create RAILS_ENV=test - DISABLE_SPRING=1 bundle exec rails db:schema:load RAILS_ENV=test + bundle exec rails db:create RAILS_ENV=test + bundle exec rails db:schema:load RAILS_ENV=test - name: 'Run any pending database migrations' run: bin/rails db:migrate RAILS_ENV=test diff --git a/.github/workflows/postgres.yml b/.github/workflows/postgres.yml index dbc9d73ba1..1a731f12d9 100644 --- a/.github/workflows/postgres.yml +++ b/.github/workflows/postgres.yml @@ -9,7 +9,7 @@ jobs: services: # Postgres installation db: - image: postgres + image: postgres:16 env: # Latest version of Postgres has increased security. We can use the default # user/password in this testing scenario though so use the following env @@ -27,11 +27,10 @@ jobs: env: RAILS_ENV: test DATABASE_URL: postgres://postgres:@localhost:5432/roadmap_test - DISABLE_SPRING: 1 steps: # Checkout the repo - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 # Install Ruby and run bundler - uses: ruby/setup-ruby@v1 @@ -42,9 +41,9 @@ jobs: ## /home/runner/runners/2.301.1/externals/node12/bin/node: --openssl-legacy-provider is not allowed in NODE_OPTIONS # Install Node - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v5 with: - node-version: 18 + node-version: 24 cache: "yarn" # Install the Postgres developer packages @@ -79,15 +78,16 @@ jobs: # Run yarn install for JS dependencies - name: "Yarn Install" run: | - yarn install + yarn install --frozen-lockfile # TEMPORARY WORKAROUND FOR THE FOLLOWING ISSUE: https://github.com/DMPRoadmap/roadmap/issues/3485 # Remove this once our tests are compatible with the new version of Chrome # Source: https://github.com/teamcapybara/capybara/issues/2800#issuecomment-2731100953 - name: Remove image-bundled Chrome run: sudo apt-get purge google-chrome-stable - - name: Setup stable Chrome - uses: browser-actions/setup-chrome@v1 + - name: Setup Chrome 128 + id: setup-chrome + uses: browser-actions/setup-chrome@v2 with: chrome-version: 128 install-chromedriver: true @@ -99,6 +99,12 @@ jobs: bundle exec rails db:setup bundle exec rails db:migrate + # PostgreSQL is the canonical source of the shared schema.rb. + - name: "Check schema drift" + run: | + bundle exec rails db:schema:dump + git diff --exit-code -- db/schema.rb + # Prebuild the CSS, JS and image assets - name: "Compile Assets" run: bundle exec rails assets:precompile @@ -112,4 +118,9 @@ jobs: # Run the time consuming integration tests (using Chrome headless browser) - name: "Run Integration Tests" - run: bundle exec rspec spec/features/ + env: + CHROME_BIN: ${{ steps.setup-chrome.outputs.chrome-path }} + run: | + "$CHROME_BIN" --version + chromedriver --version + bundle exec rspec spec/features/ diff --git a/.github/workflows/rubocop.yml b/.github/workflows/rubocop.yml index 15c3fd9028..1570e50ebc 100644 --- a/.github/workflows/rubocop.yml +++ b/.github/workflows/rubocop.yml @@ -8,7 +8,7 @@ jobs: steps: # Checkout the repo - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 # Install Ruby and run bundler - uses: ruby/setup-ruby@v1 diff --git a/.gitignore b/.gitignore index b32c4f2b28..61355c0a3a 100644 --- a/.gitignore +++ b/.gitignore @@ -116,3 +116,6 @@ yarn-debug.log* # Ignore briley AWS cloud9 script to start the application cloud9-start.sh + +# Ignore key files for decrypting credentials and more. +/config/*.key diff --git a/.node-version b/.node-version new file mode 100644 index 0000000000..ca5c350055 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +24.18.0 diff --git a/.rubocop.yml b/.rubocop.yml index 40f584cdac..6828ce92ce 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,6 +29,7 @@ plugins: - rubocop-performance AllCops: + TargetRubyVersion: 3.4 # Show the name of the cops being voilated in the feedback DisplayCopNames: true DisplayStyleGuide: true diff --git a/.ruby-version b/.ruby-version index 0aec50e6ed..0ce07b72f8 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.4 +3.4.11 diff --git a/CHANGELOG.md b/CHANGELOG.md index a344d9bbec..e83731be73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## v6.0.0 + +- Upgrade the required runtime from Ruby 3.1/Rails 7.1 to Ruby 3.4/Rails 8.1 + and update compatible gems. This release adds no product features or API + versions. +- Adapt existing authentication, enums, routes, exports, and schema dumping + for the new framework versions. Continue to support PostgreSQL and MySQL. +- Update CI for Node 24, asset builds, and PostgreSQL schema drift checks; + add regression coverage for API headers, DOCX exports, and permission flags. +- Replace the Ruby 3.4-incompatible model annotation tool and remove Spring. + ## v5.0.3 - Patch API token auth to check user's status [#3606](https://github.com/DMPRoadmap/roadmap/pull/3606) - fix(policy): harden authorization for plan resources [#3613](https://github.com/DMPRoadmap/roadmap/pull/3613) diff --git a/Gemfile b/Gemfile index 2a9aa8721d..5929beab5c 100644 --- a/Gemfile +++ b/Gemfile @@ -2,20 +2,17 @@ source 'https://rubygems.org' -ruby '3.1.4' +ruby '~> 3.4.0' + +# Ruby 3.4 ships CSV separately; exports and statistics require it directly. +gem 'csv' # ===========# # CORE RAILS # # ===========# # Full-stack web application framework. (http://rubyonrails.org) -gem 'rails', '~> 7.1' - -# TODO: Remove this once Rails addresses the issue with its dependency on mimemagic. Mimemagic had -# an MIT license but was using some incompatible GPL license code. -# Versions of mimemagic that were yanked: https://rubygems.org/gems/mimemagic/versions -# Analysis of the issue: https://www.theregister.com/2021/03/25/ruby_rails_code/ -gem 'mimemagic' +gem 'rails', '~> 8.1.0' # Use Puma as the app server gem 'puma', group: :puma, require: false @@ -31,10 +28,10 @@ gem 'cssbundling-rails' # Turbo gives you the speed of a single-page web application without having to write any JavaScript.. # Read more: https://github.com/hotwired/turbo-rails # https://github.com/hotwired/turbo-rails/blob/main/UPGRADING.md -gem 'turbo-rails' +gem 'turbo-rails', '~> 2.0' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder' +gem 'jbuilder', '~> 2.15' # Use Redis adapter to run Action Cable in production # gem "redis", "~> 4.0" @@ -47,10 +44,6 @@ gem 'jbuilder' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', require: false -# The ultimate text progress bar library for Ruby! -# (https://github.com/jfelchner/ruby-progressbar) -gem 'ruby-progressbar' - # Provides Sprockets implementation for Rails 4.x (and beyond) Asset Pipeline. # https://github.com/rails/sprockets-rails gem 'sprockets-rails' @@ -85,7 +78,7 @@ gem 'flag_shih_tzu' # , "~> 0.3.23" # Flexible authentication solution for Rails with Warden # (https://github.com/plataformatec/devise) -gem 'devise' +gem 'devise', '~> 5.0' # An invitation strategy for Devise (https://github.com/scambra/devise_invitable) gem 'devise_invitable' @@ -205,14 +198,15 @@ gem 'dotenv-rails' gem 'activerecord_json_validator' -# We need to freeze the mail gem version as the recently released 2.8.0 triggers an exception -# We will need to check if it's fixed when we migrate to Ruby 3.0/3.1 -# See : https://github.com/DMPRoadmap/roadmap/issues/3254 -gem 'mail', '2.7.1' +gem 'logger', '~> 1.7' +gem 'mail' # This library provides functionality to send internet mail via SMTP, the Simple Mail Transfer Protocol. # https://github.com/ruby/net-smtp -gem 'net-smtp' +gem 'net-imap', '~> 0.5' +gem 'net-pop', '~> 0.1' +gem 'net-smtp', '~> 0.5' +gem 'rake', '~> 13.4' # ================================= # # ENVIRONMENT SPECIFIC DEPENDENCIES # @@ -220,12 +214,12 @@ gem 'net-smtp' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console - gem 'byebug', platforms: %i[mri mingw x64_mingw] + gem 'byebug', platforms: %i[mri windows] end group :test do # RSpec for Rails (https://github.com/rspec/rspec-rails) - gem 'rspec-rails' + gem 'rspec-rails', '~> 8.0' # factory_bot_rails provides integration between factory_bot and rails 3 # or newer (http://github.com/thoughtbot/factory_bot_rails) @@ -260,7 +254,7 @@ group :test do gem 'capybara' # Easy installation and use of web drivers to run system tests with browsers - gem 'selenium-webdriver' + gem 'selenium-webdriver', '~> 4.25' # RSpec::CollectionMatchers lets you express expected outcomes on # collections of an object in an example. @@ -288,25 +282,21 @@ group :ci, :development do # RuboCop is a Ruby code style checking and code formatting tool. It aims to enforce # the community-driven Ruby Style Guide. - gem 'rubocop' + # Keep Roadmap's established lint rules during the runtime upgrade. + gem 'rubocop', '~> 1.81.0' # RuboCop rules for detecting and autocorrecting undecorated strings for i18n # (gettext and rails-i18n) gem 'rubocop-i18n' # Performance checks by Rubocop - gem 'rubocop-performance', require: false + gem 'rubocop-performance', '~> 1.26.0', require: false end group :development do # Access an interactive console on exception pages or by calling 'console' anywhere in the code. gem 'listen' gem 'web-console' - # Spring speeds up development by keeping your application running in the background. - # Read more: https://github.com/rails/spring - gem 'spring' - gem 'spring-watcher-listen' - # Simple Progress Bar for output to a terminal # (http://github.com/paul/progress_bar) gem 'progress_bar', require: false @@ -322,16 +312,11 @@ group :development do # even further up the stack. (http://github.com/banister/binding_of_caller) gem 'binding_of_caller' - # rspec command for spring - # (https://github.com/jonleighton/spring-commands-rspec) - gem 'spring-commands-rspec' - # Profiles loading speed for rack applications. (http://miniprofiler.com) gem 'rack-mini-profiler' - # Annotates Rails Models, routes, fixtures, and others based on the - # database schema. (http://github.com/ctran/annotate_models) - gem 'annotate' + # Annotates models from the database schema under Rails 8. + gem 'annotaterb', '~> 4.24.0' # Add comments to your Gemfile with each dependency's description. # (https://github.com/ivantsepp/annotate_gem) diff --git a/Gemfile.lock b/Gemfile.lock index 56db857b5c..08bc08896e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,122 +1,123 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.1.5.2) - actionpack (= 7.1.5.2) - activesupport (= 7.1.5.2) + action_text-trix (2.1.19) + railties + actioncable (8.1.4) + actionpack (= 8.1.4) + activesupport (= 8.1.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.5.2) - actionpack (= 7.1.5.2) - activejob (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.5.2) - actionpack (= 7.1.5.2) - actionview (= 7.1.5.2) - activejob (= 7.1.5.2) - activesupport (= 7.1.5.2) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (8.1.4) + actionpack (= 8.1.4) + activejob (= 8.1.4) + activerecord (= 8.1.4) + activestorage (= 8.1.4) + activesupport (= 8.1.4) + mail (>= 2.8.0) + actionmailer (8.1.4) + actionpack (= 8.1.4) + actionview (= 8.1.4) + activejob (= 8.1.4) + activesupport (= 8.1.4) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.5.2) - actionview (= 7.1.5.2) - activesupport (= 7.1.5.2) + actionpack (8.1.4) + actionview (= 8.1.4) + activesupport (= 8.1.4) nokogiri (>= 1.8.5) - racc rack (>= 2.2.4) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.5.2) - actionpack (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) + useragent (~> 0.16) + actiontext (8.1.4) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.4) + activerecord (= 8.1.4) + activestorage (= 8.1.4) + activesupport (= 8.1.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.5.2) - activesupport (= 7.1.5.2) + actionview (8.1.4) + activesupport (= 8.1.4) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.5.2) - activesupport (= 7.1.5.2) + activejob (8.1.4) + activesupport (= 8.1.4) globalid (>= 0.3.6) - activemodel (7.1.5.2) - activesupport (= 7.1.5.2) - activerecord (7.1.5.2) - activemodel (= 7.1.5.2) - activesupport (= 7.1.5.2) + activemodel (8.1.4) + activesupport (= 8.1.4) + activerecord (8.1.4) + activemodel (= 8.1.4) + activesupport (= 8.1.4) timeout (>= 0.4.0) activerecord_json_validator (3.1.0) activerecord (>= 4.2.0, < 9) json_schemer (~> 2.2) - activestorage (7.1.5.2) - actionpack (= 7.1.5.2) - activejob (= 7.1.5.2) - activerecord (= 7.1.5.2) - activesupport (= 7.1.5.2) + activestorage (8.1.4) + actionpack (= 8.1.4) + activejob (= 8.1.4) + activerecord (= 8.1.4) + activesupport (= 8.1.4) marcel (~> 1.0) - activesupport (7.1.5.2) + activesupport (8.1.4) base64 - benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + json logger (>= 1.4.2) minitest (>= 5.1) - mutex_m securerandom (>= 0.3) - tzinfo (~> 2.0) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + addressable (2.9.0) + public_suffix (>= 2.0.2, < 8.0) annotate_gem (0.0.14) bundler (>= 1.1) - api-pagination (6.0.0) + annotaterb (4.24.0) + activerecord (>= 6.0.0) + activesupport (>= 6.0.0) + anonymous_loader (0.1.3) + version_gem (~> 1.1, >= 1.1.14) + api-pagination (7.1.0) ast (2.4.3) + auth-sanitizer (0.2.3) + version_gem (~> 1.1, >= 1.1.14) autoprefixer-rails (10.4.21.0) execjs (~> 2) base64 (0.3.0) - bcrypt (3.1.20) - benchmark (0.4.1) + bcrypt (3.1.22) better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - bigdecimal (3.3.0) + bigdecimal (4.1.3) bindex (0.8.1) - binding_of_caller (1.0.1) + binding_of_caller (2.0.0) debug_inspector (>= 1.2.0) - bootsnap (1.18.6) - msgpack (~> 1.2) - brakeman (7.1.0) + bootsnap (1.26.0) + msgpack (~> 1.5) + brakeman (8.1.0) racc builder (3.3.0) - bullet (8.0.8) + bullet (8.2.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - bundle-audit (0.1.0) + bundle-audit (0.2.0) bundler-audit - bundler-audit (0.9.2) - bundler (>= 1.2.0, < 3) + bundler-audit (0.9.3) + bundler (>= 1.2.0) thor (~> 1.0) - byebug (12.0.0) + byebug (13.0.0) + reline (>= 0.6.0) capybara (3.40.0) addressable matrix @@ -126,7 +127,6 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - cgi (0.5.0) claide (1.1.0) claide-plugins (0.9.2) cork @@ -134,20 +134,20 @@ GEM open4 (~> 1.3) coderay (1.1.3) colored2 (3.1.2) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) + concurrent-ruby (1.3.8) + connection_pool (3.0.2) contact_us (1.2.0) rails (>= 4.2.0) cork (0.3.0) colored2 (~> 3.1) - crack (1.0.0) + crack (1.0.1) bigdecimal rexml - crass (1.0.6) + crass (1.0.7) cssbundling-rails (1.4.3) railties (>= 6.0.0) - csv (3.3.5) - danger (9.5.3) + csv (3.3.6) + danger (9.6.1) base64 (~> 0.2) claide (~> 1.0) claide-plugins (>= 0.9.2) @@ -155,7 +155,7 @@ GEM cork (~> 0.1) faraday (>= 0.9.0, < 3.0) faraday-http-cache (~> 2.0) - git (>= 1.13, < 3.0) + git (>= 1.13) kramdown (>= 2.5.1, < 3.0) kramdown-parser-gfm (~> 1.0) octokit (>= 4.0) @@ -166,24 +166,24 @@ GEM database_cleaner-active_record (2.2.2) activerecord (>= 5.a) database_cleaner-core (~> 2.0) - database_cleaner-core (2.0.1) - date (3.4.1) + database_cleaner-core (2.1.0) + date (3.5.1) debug_inspector (1.2.0) - devise (4.9.4) + devise (5.0.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 4.1.0) + railties (>= 7.0) responders warden (~> 1.2.3) - devise_invitable (2.0.11) + devise_invitable (2.0.14) actionmailer (>= 5.0) devise (>= 4.6) diff-lcs (1.6.2) - dotenv (3.1.8) - dotenv-rails (3.1.8) - dotenv (= 3.1.8) + dotenv (3.2.0) + dotenv-rails (3.2.0) + dotenv (= 3.2.0) railties (>= 6.1) - dragonfly (1.4.1) + dragonfly (1.4.2) addressable (~> 2.3) multi_json (~> 1.0) ostruct (~> 0.6.1) @@ -192,31 +192,34 @@ GEM dragonfly (~> 1.0) fog-aws drb (2.2.3) - erb (4.0.4) - cgi (>= 0.3.3) + erb (6.0.7) erubi (1.13.1) - excon (1.3.0) + excon (1.7.2) logger - execjs (2.10.0) - factory_bot (6.5.5) + execjs (2.10.2) + json (>= 2) + factory_bot (6.6.0) activesupport (>= 6.1.0) factory_bot_rails (6.5.1) factory_bot (~> 6.5) railties (>= 6.1.0) - faker (3.5.2) + faker (3.8.0) i18n (>= 1.8.11, < 2) - faraday (2.14.0) + faraday (2.14.4) faraday-net_http (>= 2.0, < 3.5) json logger - faraday-http-cache (2.5.1) + faraday-http-cache (2.8.0) faraday (>= 0.8) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) - ffi (1.17.2-arm64-darwin) - ffi (1.17.2-x86_64-linux-gnu) - flag_shih_tzu (0.3.23) - fog-aws (3.33.0) + faraday-net_http (3.4.4) + net-http (~> 0.5) + ffi (1.17.4-aarch64-linux-gnu) + ffi (1.17.4-arm64-darwin) + ffi (1.17.4-x86_64-linux-gnu) + fiddle (1.1.8) + flag_shih_tzu (1.0.6) + version_gem (~> 1.1, >= 1.1.15) + fog-aws (3.33.4) base64 (>= 0.2, < 0.4) fog-core (~> 2.6) fog-json (~> 1.1) @@ -226,15 +229,15 @@ GEM excon (~> 1.0) formatador (>= 0.2, < 2.0) mime-types - fog-json (1.2.0) + fog-json (1.5.0) fog-core - multi_json (~> 1.10) + json (>= 2.19, < 4) fog-xml (0.1.5) fog-core nokogiri (>= 1.5.11, < 2.0.0) - formatador (1.2.1) + formatador (1.2.3) reline - forwardable (1.3.3) + forwardable (1.4.0) fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) @@ -244,56 +247,57 @@ GEM prime racc text (>= 1.3.0) - git (2.3.3) + git (5.6.0) activesupport (>= 5.0) addressable (~> 2.8) - process_executer (~> 1.1) - rchardet (~> 1.8) - globalid (1.3.0) + process_executer (~> 4.1) + rchardet (~> 1.9) + globalid (1.4.0) activesupport (>= 6.1) - guard (2.19.1) + guard (2.20.2) formatador (>= 0.2.4) listen (>= 2.7, < 4.0) logger (~> 1.6) lumberjack (>= 1.0.12, < 2.0) nenv (~> 0.1) notiffany (~> 0.0) - ostruct (~> 0.6) pry (>= 0.13.0) shellany (~> 0.0) thor (>= 0.18.1) hana (1.3.7) hashdiff (1.2.1) - hashie (5.0.0) + hashie (5.1.0) + logger highline (3.1.2) reline htmltoword (1.1.1) actionpack nokogiri rubyzip (>= 1.0) - httparty (0.23.1) + httparty (0.24.3) csv mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - i18n (1.14.7) + i18n (1.15.2) concurrent-ruby (~> 1.0) - io-console (0.8.1) - irb (1.15.2) + io-console (0.9.4) + irb (1.18.0) pp (>= 0.6.0) + prism (>= 1.3.0) rdoc (>= 4.0.0) reline (>= 0.4.2) - jbuilder (2.14.1) + jbuilder (2.15.1) actionview (>= 7.0.0) activesupport (>= 7.0.0) jsbundling-rails (1.3.1) railties (>= 6.0.0) - json (2.15.1) - json_schemer (2.4.0) + json (2.21.2) + json_schemer (2.5.0) bigdecimal hana (~> 1.3) regexp_parser (~> 2.0) simpleidn (~> 0.2) - jwt (3.1.2) + jwt (3.3.0) base64 kaminari (1.2.2) activesupport (>= 4.1.0) @@ -307,75 +311,83 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kramdown (2.5.1) - rexml (>= 3.3.9) + kramdown (2.5.2) + rexml (>= 3.4.4) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - language_server-protocol (3.17.0.5) + language_server-protocol (3.17.0.6) ledermann-rails-settings (2.6.2) activerecord (>= 6.1) lint_roller (1.1.0) - listen (3.9.0) + listen (3.10.1) + logger rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - locale (2.1.4) + locale (2.1.5) + fiddle logger (1.7.0) - loofah (2.24.1) + loofah (2.25.2) crass (~> 1.0.2) nokogiri (>= 1.12.0) lumberjack (1.4.2) - mail (2.7.1) + mail (2.9.1) + logger mini_mime (>= 0.1.1) - marcel (1.1.0) + net-imap + net-pop + net-smtp + marcel (1.2.1) matrix (0.4.3) method_source (1.1.0) mime-types (3.7.0) logger mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0924) - mimemagic (0.4.3) - nokogiri (~> 1) - rake + mime-types-data (3.2026.0929) mini_mime (1.1.5) - minitest (5.25.5) - mocha (2.7.1) + minitest (6.0.6) + drb (~> 2.0) + prism (~> 1.5) + mocha (3.1.0) ruby2_keywords (>= 0.0.5) - msgpack (1.8.0) - multi_json (1.17.0) - multi_xml (0.7.1) - bigdecimal (~> 3.1) - mutex_m (0.3.0) + msgpack (1.8.5) + multi_json (1.21.2) + multi_xml (0.9.1) + bigdecimal (>= 3.1, < 5) mysql2 (0.5.7) bigdecimal nap (1.1.0) nenv (0.3.0) - net-http (0.6.0) - uri - net-imap (0.5.12) + net-http (0.9.1) + uri (>= 0.11.1) + net-imap (0.6.7) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.2) + net-protocol (0.4.0) timeout - net-smtp (0.5.1) + net-smtp (0.5.2) net-protocol - nio4r (2.7.4) - nokogiri (1.18.10-arm64-darwin) + nio4r (2.7.5) + nokogiri (1.19.4-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.19.4-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) + nokogiri (1.19.4-x86_64-linux-gnu) racc (~> 1.4) notiffany (0.1.3) nenv (~> 0.1) shellany (~> 0.0) - oauth2 (2.0.17) + oauth2 (2.0.25) + anonymous_loader (~> 0.1, >= 0.1.3) + auth-sanitizer (~> 0.2, >= 0.2.3) faraday (>= 0.17.3, < 4.0) jwt (>= 1.0, < 4.0) logger (~> 1.2) multi_xml (~> 0.5) rack (>= 1.2, < 4) - snaky_hash (~> 2.0, >= 2.0.3) - version_gem (~> 1.1, >= 1.1.9) + snaky_hash (~> 2.0, >= 2.0.7) + version_gem (~> 1.1, >= 1.1.14) octokit (10.0.0) faraday (>= 1, < 3) sawyer (~> 0.9) @@ -384,13 +396,13 @@ GEM logger rack (>= 2.2.3) rack-protection - omniauth-oauth2 (1.8.0) - oauth2 (>= 1.4, < 3) + omniauth-oauth2 (1.9.0) + oauth2 (>= 2.0.2, < 3) omniauth (~> 2.0) omniauth-orcid (2.1.1) omniauth-oauth2 (~> 1.3) ruby_dig (~> 0.0.2) - omniauth-rails_csrf_protection (1.0.2) + omniauth-rails_csrf_protection (2.0.1) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-shibboleth (1.3.0) @@ -399,32 +411,32 @@ GEM options (2.3.2) orm_adapter (0.5.0) ostruct (0.6.3) - parallel (1.27.0) - parser (3.3.9.0) + parallel (1.28.0) + parser (3.3.12.0) ast (~> 2.4.1) racc - pg (1.6.2-arm64-darwin) - pg (1.6.2-x86_64-linux) - pp (0.6.3) + pg (1.7.0-aarch64-linux) + pg (1.7.0-arm64-darwin) + pg (1.7.0-x86_64-linux) + pp (0.6.4) prettyprint prettyprint (0.2.0) prime (0.1.4) forwardable singleton - prism (1.5.1) - process_executer (1.3.0) + prism (1.9.0) + process_executer (4.1.1) + track_open_instances (~> 0.1) progress_bar (1.3.4) highline (>= 1.6) options (~> 2.3.0) - pry (0.15.2) + pry (0.16.0) coderay (~> 1.1) method_source (~> 1.0) - pstore (0.2.0) - psych (5.2.6) - date - stringio - public_suffix (6.0.2) - puma (7.0.4) + reline (>= 0.6.0) + pstore (0.2.1) + public_suffix (7.0.5) + puma (8.0.2) nio4r (~> 2.0) pundit (2.5.2) activesupport (>= 3.0.0) @@ -434,36 +446,36 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) racc (1.8.1) - rack (3.2.2) - rack-attack (6.7.0) + rack (3.2.7) + rack-attack (6.8.0) rack (>= 1.0, < 4) - rack-mini-profiler (4.0.1) + rack-mini-profiler (5.0.0) rack (>= 1.2.0) - rack-protection (4.1.1) + rack-protection (4.2.1) base64 (>= 0.1.0) logger (>= 1.6.0) rack (>= 3.0.0, < 4) - rack-session (2.1.1) + rack-session (2.1.2) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) rack (>= 1.3) - rackup (2.2.1) + rackup (2.3.1) rack (>= 3) - rails (7.1.5.2) - actioncable (= 7.1.5.2) - actionmailbox (= 7.1.5.2) - actionmailer (= 7.1.5.2) - actionpack (= 7.1.5.2) - actiontext (= 7.1.5.2) - actionview (= 7.1.5.2) - activejob (= 7.1.5.2) - activemodel (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) + rails (8.1.4) + actioncable (= 8.1.4) + actionmailbox (= 8.1.4) + actionmailer (= 8.1.4) + actionpack (= 8.1.4) + actiontext (= 8.1.4) + actionview (= 8.1.4) + activejob (= 8.1.4) + activemodel (= 8.1.4) + activerecord (= 8.1.4) + activestorage (= 8.1.4) + activesupport (= 8.1.4) bundler (>= 1.15.0) - railties (= 7.1.5.2) + railties (= 8.1.4) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -472,57 +484,64 @@ GEM activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) + rails-html-sanitizer (1.7.1) + loofah (~> 2.25, >= 2.25.2) nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.1.5.2) - actionpack (= 7.1.5.2) - activesupport (= 7.1.5.2) - irb + railties (8.1.4) + actionpack (= 8.1.4) + activesupport (= 8.1.4) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.3.0) + rake (13.4.2) rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rchardet (1.10.0) - rdoc (6.15.0) + rbs (4.2.0) + logger + prism (>= 1.6.0) + tsort + rchardet (1.10.2) + rdoc (8.1.0) erb - psych (>= 4.0.0) + prism (>= 1.6.0) + rbs (>= 4.0.0) tsort - recaptcha (5.21.1) - regexp_parser (2.11.3) - reline (0.6.2) + recaptcha (5.21.2) + regexp_parser (2.13.1) + reline (0.7.0) io-console (~> 0.5) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) + responders (3.2.1) + actionpack (>= 7.0) + railties (>= 7.0) rexml (3.4.4) - rollbar (3.6.2) - rouge (4.6.1) + rollbar (3.8.0) + rouge (5.1.0) + strscan (~> 3.1) rspec-collection_matchers (1.2.1) rspec-expectations (>= 2.99.0.beta1) - rspec-core (3.13.5) + rspec-core (3.13.6) rspec-support (~> 3.13.0) rspec-expectations (3.13.5) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-mocks (3.13.5) + rspec-mocks (3.13.8) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (7.1.1) - actionpack (>= 7.0) - activesupport (>= 7.0) - railties (>= 7.0) - rspec-core (~> 3.13) - rspec-expectations (~> 3.13) - rspec-mocks (~> 3.13) - rspec-support (~> 3.13) - rspec-support (3.13.6) - rubocop (1.81.1) + rspec-rails (8.0.4) + actionpack (>= 7.2) + activesupport (>= 7.2) + railties (>= 7.2) + rspec-core (>= 3.13.0, < 5.0.0) + rspec-expectations (>= 3.13.0, < 5.0.0) + rspec-mocks (>= 3.13.0, < 5.0.0) + rspec-support (>= 3.13.0, < 5.0.0) + rspec-support (3.13.7) + rubocop (1.81.7) json (~> 2.3) language_server-protocol (~> 3.17.0.2) lint_roller (~> 1.1.0) @@ -533,29 +552,28 @@ GEM rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.47.1) + rubocop-ast (1.50.0) parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-i18n (3.2.3) + prism (~> 1.7) + rubocop-i18n (3.3.0) lint_roller (~> 1.1) rubocop (>= 1.72.1) - rubocop-performance (1.26.0) + rubocop-performance (1.26.1) lint_roller (~> 1.1) rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.44.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) ruby_dig (0.0.2) - rubyzip (2.4.1) - sawyer (0.9.2) + rubyzip (3.7.0) + sawyer (0.9.3) addressable (>= 2.3.5) faraday (>= 0.17.3, < 3) securerandom (0.4.1) - selenium-webdriver (4.32.0) + selenium-webdriver (4.50.0) base64 (~> 0.2) logger (~> 1.4) - rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) + rubyzip (>= 1.2.2, < 4.0) websocket (~> 1.0) shellany (0.0.1) shoulda (4.0.0) @@ -564,59 +582,54 @@ GEM shoulda-context (2.0.0) shoulda-matchers (4.5.1) activesupport (>= 4.2.0) - simpleidn (0.2.3) + simpleidn (0.3.0) singleton (0.3.0) - snaky_hash (2.0.3) + snaky_hash (2.0.7) hashie (>= 0.1.0, < 6) - version_gem (>= 1.1.8, < 3) - spring (4.4.0) - spring-commands-rspec (1.0.4) - spring (>= 0.9.1) - spring-watcher-listen (2.1.0) - listen (>= 2.7, < 4.0) - spring (>= 4) - sprockets (4.2.2) - concurrent-ruby (~> 1.0) + version_gem (~> 1.1, >= 1.1.14) + sprockets (4.4.1) + concurrent-ruby (~> 1.1) logger rack (>= 2.2.4, < 4) sprockets-rails (3.5.2) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) - stringio (3.1.7) + strscan (3.1.8) terminal-table (4.0.0) unicode-display_width (>= 1.1.1, < 4) text (1.3.1) - thor (1.4.0) - timeout (0.4.3) + thor (1.5.0) + timeout (0.6.1) tomparse (0.4.2) + track_open_instances (0.1.15) translation (1.41) gettext (~> 3.2, >= 3.2.5, <= 3.4.9) tsort (0.2.0) - turbo-rails (2.0.17) + turbo-rails (2.0.23) actionpack (>= 7.1.0) railties (>= 7.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (3.2.0) - unicode-emoji (~> 4.1) - unicode-emoji (4.1.0) + unicode-display_width (3.3.0) + unicode-emoji (~> 4.3) + unicode-emoji (4.3.0) uniform_notifier (1.18.0) - uri (1.0.4) - version_gem (1.1.9) + uri (1.1.1) + useragent (0.16.11) + version_gem (1.1.15) warden (1.2.9) rack (>= 2.0.9) - web-console (4.2.1) - actionview (>= 6.0.0) - activemodel (>= 6.0.0) + web-console (4.3.0) + actionview (>= 8.0.0) bindex (>= 0.4.0) - railties (>= 6.0.0) - webmock (3.25.1) + railties (>= 8.0.0) + webmock (3.26.4) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) websocket (1.2.11) - websocket-driver (0.8.0) + websocket-driver (0.8.2) base64 websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -626,21 +639,23 @@ GEM wkhtmltopdf-binary (0.12.6.10) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.37) + yard (0.9.45) yard-tomdoc (0.7.1) tomparse (>= 0.4.0) yard - zeitwerk (2.6.18) + zeitwerk (2.8.3) PLATFORMS + aarch64-linux arm64-darwin-21 arm64-darwin-22 + arm64-darwin-25 x86_64-linux DEPENDENCIES activerecord_json_validator - annotate annotate_gem + annotaterb (~> 4.24.0) api-pagination autoprefixer-rails better_errors @@ -653,9 +668,10 @@ DEPENDENCIES capybara contact_us cssbundling-rails + csv danger database_cleaner - devise + devise (~> 5.0) devise_invitable dotenv-rails dragonfly @@ -667,17 +683,19 @@ DEPENDENCIES guard htmltoword httparty - jbuilder + jbuilder (~> 2.15) jsbundling-rails jwt kaminari ledermann-rails-settings listen - mail (= 2.7.1) - mimemagic + logger (~> 1.7) + mail mocha mysql2 - net-smtp + net-imap (~> 0.5) + net-pop (~> 0.1) + net-smtp (~> 0.5) omniauth omniauth-orcid omniauth-rails_csrf_protection @@ -690,25 +708,22 @@ DEPENDENCIES pundit-matchers rack-attack (~> 6.6, >= 6.6.1) rack-mini-profiler - rails (~> 7.1) + rails (~> 8.1.0) rails-controller-testing + rake (~> 13.4) recaptcha rollbar rspec-collection_matchers - rspec-rails - rubocop + rspec-rails (~> 8.0) + rubocop (~> 1.81.0) rubocop-i18n - rubocop-performance - ruby-progressbar - selenium-webdriver + rubocop-performance (~> 1.26.0) + selenium-webdriver (~> 4.25) shoulda - spring - spring-commands-rspec - spring-watcher-listen sprockets-rails text translation - turbo-rails + turbo-rails (~> 2.0) web-console webmock wicked_pdf @@ -717,7 +732,7 @@ DEPENDENCIES yard-tomdoc RUBY VERSION - ruby 3.1.4p223 + ruby 3.4.11p137 BUNDLED WITH - 2.4.17 + 2.7.2 diff --git a/app/javascript/src/utils/tinymce.js b/app/javascript/src/utils/tinymce.js index c1112b1a35..9708ab9e90 100644 --- a/app/javascript/src/utils/tinymce.js +++ b/app/javascript/src/utils/tinymce.js @@ -119,9 +119,8 @@ export const Tinymce = { if (isString(className)) { const elements = Array.from(document.getElementsByClassName(className)); // Fetch the textarea elements and then return the TinyMCE editors associated with the element ids - return elements.map((el) => { - return Tinymce.findEditorById(el.getAttribute('id')); - }); + return elements.map((el) => Tinymce.findEditorById(el.getAttribute('id'))) + .filter((editor) => isTinymceEditor(editor)); } return []; }, @@ -133,7 +132,7 @@ export const Tinymce = { */ findEditorById(id) { if (isString(id)) { - return tinymce.get(id); + return tinymce.get(id) || undefined; } return undefined; }, diff --git a/app/models/annotation.rb b/app/models/annotation.rb index 4689352a0d..ed13669c0a 100644 --- a/app/models/annotation.rb +++ b/app/models/annotation.rb @@ -33,7 +33,7 @@ class Annotation < ApplicationRecord # I liked type as the name for the enum so overriding inheritance column self.inheritance_column = nil - enum type: %i[example_answer guidance] + enum :type, %i[example_answer guidance] # ================ # = Associations = diff --git a/app/models/api_client.rb b/app/models/api_client.rb index 0c20193c53..3bafc3ab18 100644 --- a/app/models/api_client.rb +++ b/app/models/api_client.rb @@ -4,25 +4,29 @@ # # Table name: api_clients # -# id :integer not null, primary key -# name :string, not null -# homepage :string -# contact_name :string -# contact_email :string, not null -# client_id :string, not null -# client_secret :string, not null -# last_access :datetime -# created_at :datetime -# updated_at :datetime -# org_id :integer +# id :integer not null, primary key +# callback_method :integer +# callback_uri :string +# client_secret :string not null +# confidential :boolean default(TRUE) +# contact_email :string +# contact_name :string +# description :string +# homepage :string +# last_access :datetime +# name :string not null +# redirect_uri :text +# scopes :string default(""), not null +# trusted :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# client_id :string not null +# org_id :integer # # Indexes # -# index_api_clients_on_name (name) +# index_oauth_applications_on_name (name) # -# Foreign Keys -# -# fk_rails_... (org_id => orgs.id) # Object that represents an external system class ApiClient < ApplicationRecord diff --git a/app/models/condition.rb b/app/models/condition.rb index 4887de31df..963f962ba9 100644 --- a/app/models/condition.rb +++ b/app/models/condition.rb @@ -4,15 +4,15 @@ # # Table name: conditions # -# id :integer not null, primary key -# question_id :integer -# number :integer -# action_type :integer -# option_list :text -# remove_data :text -# webhook_data :text -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# action_type :integer +# number :integer +# option_list :text +# remove_data :text +# webhook_data :text +# created_at :datetime not null +# updated_at :datetime not null +# question_id :integer # # Indexes # @@ -20,8 +20,7 @@ # # Foreign Keys # -# fk_rails_... (question_id => question.id) -# +# fk_rails_... (question_id => questions.id) # # Object that represents a condition of a conditional question diff --git a/app/models/contributor.rb b/app/models/contributor.rb index 739d40aae7..3d80826e78 100644 --- a/app/models/contributor.rb +++ b/app/models/contributor.rb @@ -4,27 +4,24 @@ # # Table name: contributors # -# id :integer not null, primary key -# firstname :string -# surname :string -# email :string -# phone :string -# roles :integer -# org_id :integer -# plan_id :integer -# created_at :datetime -# updated_at :datetime +# id :integer not null, primary key +# email :string +# name :string +# phone :string +# roles :integer not null +# created_at :datetime +# updated_at :datetime +# org_id :integer +# plan_id :integer not null # # Indexes # -# index_contributors_on_id (id) -# index_contributors_on_email (email) -# index_contributors_on_org_id (org_id) +# index_contrib_id_and_org_id (name,id,org_id) +# index_contributors_on_email (email) +# index_contributors_on_org_id (org_id) +# index_contributors_on_plan_id (plan_id) +# index_contributors_on_roles (roles) # -# Foreign Keys -# -# fk_rails_... (org_id => orgs.id) -# fk_rails_... (plan_id => plans.id) # Object that represents a contributor to a plan class Contributor < ApplicationRecord diff --git a/app/models/identifier.rb b/app/models/identifier.rb index 6ec4ec5bd1..64b0082b7e 100644 --- a/app/models/identifier.rb +++ b/app/models/identifier.rb @@ -11,11 +11,13 @@ # created_at :datetime # updated_at :datetime # identifiable_id :integer -# identifier_scheme_id :integer not null +# identifier_scheme_id :integer # # Indexes # # index_identifiers_on_identifiable_type_and_identifiable_id (identifiable_type,identifiable_id) +# index_identifiers_on_identifier_scheme_id_and_value (identifier_scheme_id,value) +# index_identifiers_on_scheme_and_type_and_id (identifier_scheme_id,identifiable_id,identifiable_type) # # Object that represents an identifier for an object diff --git a/app/models/identifier_scheme.rb b/app/models/identifier_scheme.rb index da664144eb..55ec94f129 100644 --- a/app/models/identifier_scheme.rb +++ b/app/models/identifier_scheme.rb @@ -4,15 +4,16 @@ # # Table name: identifier_schemes # -# id :integer not null, primary key -# active :boolean -# description :string -# context :integer -# logo_url :text -# name :string -# user_landing_url :string -# created_at :datetime -# updated_at :datetime +# id :integer not null, primary key +# active :boolean +# context :integer +# description :string +# external_service :string +# identifier_prefix :string +# logo_url :string +# name :string +# created_at :datetime +# updated_at :datetime # # Object that represents a type of identifiaction (e.g. ORCID, ROR, etc.) diff --git a/app/models/license.rb b/app/models/license.rb index e59f74250d..1668a62010 100644 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -4,7 +4,7 @@ # # Table name: licenses # -# id :bigint not null, primary key +# id :bigint(8) not null, primary key # deprecated :boolean default(FALSE) # identifier :string not null # name :string not null diff --git a/app/models/metadata_standard.rb b/app/models/metadata_standard.rb index 02eaccfd1f..ca546a5255 100644 --- a/app/models/metadata_standard.rb +++ b/app/models/metadata_standard.rb @@ -4,15 +4,15 @@ # # Table name: metadata_standards # -# id :bigint not null, primary key -# description :text -# locations :json -# related_entities :json -# title :string -# uri :string -# created_at :datetime not null -# updated_at :datetime not null -# rdamsc_id :string +# id :bigint(8) not null, primary key +# description :text +# locations :json +# related_entities :json +# title :string +# uri :string +# created_at :datetime not null +# updated_at :datetime not null +# rdamsc_id :string # class MetadataStandard < ApplicationRecord # ============= diff --git a/app/models/notification.rb b/app/models/notification.rb index b26be026f7..3c98da768c 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -7,20 +7,20 @@ # id :integer not null, primary key # body :text # dismissable :boolean +# enabled :boolean default(TRUE) # expires_at :date # level :integer # notification_type :integer # starts_at :date # title :string -# enabled :boolean # created_at :datetime not null # updated_at :datetime not null # # Object that represents a global notification class Notification < ApplicationRecord - enum level: %i[info warning danger] - enum notification_type: %i[global] + enum :level, %i[info warning danger] + enum :notification_type, %i[global] # ================ # = Associations = diff --git a/app/models/org.rb b/app/models/org.rb index 6a6eac55d2..d4d0885bda 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -4,31 +4,37 @@ # # Table name: orgs # -# id :integer not null, primary key -# abbreviation :string -# contact_email :string -# contact_name :string -# feedback_msg :text -# feedback_enabled :boolean default(FALSE) -# is_other :boolean default(FALSE), not null -# links :text -# logo_name :string -# logo_uid :string -# managed :boolean default(FALSE), not null -# name :string -# org_type :integer default(0), not null -# sort_name :string -# target_url :string -# created_at :datetime not null -# updated_at :datetime not null -# language_id :integer -# region_id :integer -# managed :boolean default(false), not null -# helpdesk_email :string +# id :integer not null, primary key +# abbreviation :string +# api_create_plan_email_body :text +# api_create_plan_email_subject :string +# contact_email :string +# contact_name :string +# feedback_enabled :boolean default(FALSE) +# feedback_msg :text +# helpdesk_email :string +# is_other :boolean default(FALSE), not null +# links :text +# logo_name :string +# logo_uid :string +# managed :boolean default(FALSE), not null +# name :string +# org_type :integer default(0), not null +# target_url :string +# created_at :datetime not null +# updated_at :datetime not null +# language_id :integer +# region_id :integer +# +# Indexes +# +# fk_rails_5640112cab (language_id) +# fk_rails_5a6adf6bab (region_id) # # Foreign Keys # # fk_rails_... (language_id => languages.id) +# fk_rails_... (region_id => regions.id) # # Object that represents an Organization/Institution/Funder diff --git a/app/models/plan.rb b/app/models/plan.rb index 83fac933e9..22630c6f20 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -7,39 +7,41 @@ # # Table name: plans # -# id :integer not null, primary key -# complete :boolean default(FALSE) -# description :text -# feedback_requested :boolean default(FALSE) -# identifier :string -# title :string -# visibility :integer default(3), not null -# created_at :datetime -# updated_at :datetime -# template_id :integer -# org_id :integer -# funder_id :integer -# grant_id :integer -# api_client_id :integer -# research_domain_id :bigint -# funding_status :integer -# ethical_issues :boolean -# ethical_issues_description :text -# ethical_issues_report :string +# id :integer not null, primary key +# complete :boolean default(FALSE) +# description :text +# end_date :datetime +# ethical_issues :boolean +# ethical_issues_description :text +# ethical_issues_report :string +# feedback_requested :boolean default(FALSE) +# funding_status :integer +# identifier :string +# start_date :datetime +# title :string +# visibility :integer default(3), not null +# created_at :datetime +# updated_at :datetime +# api_client_id :integer +# funder_id :integer +# grant_id :integer +# org_id :integer +# research_domain_id :bigint(8) +# template_id :integer # # Indexes # -# index_plans_on_template_id (template_id) -# index_plans_on_funder_id (funder_id) -# index_plans_on_grant_id (grant_id) -# index_plans_on_api_client_id (api_client_id) +# index_plans_on_api_client_id (api_client_id) +# index_plans_on_fos_id (research_domain_id) +# index_plans_on_funder_id (funder_id) +# index_plans_on_grant_id (grant_id) +# index_plans_on_org_id (org_id) +# index_plans_on_template_id (template_id) # # Foreign Keys # -# fk_rails_... (template_id => templates.id) # fk_rails_... (org_id => orgs.id) -# fk_rails_... (api_client_id => api_clients.id) -# fk_rails_... (research_domain_id => research_domains.id) +# fk_rails_... (template_id => templates.id) # # Object that represents an DMP @@ -76,10 +78,10 @@ class Plan < ApplicationRecord # ============== # public is a Ruby keyword so using publicly - enum visibility: %i[organisationally_visible publicly_visible - is_test privately_visible] + enum :visibility, %i[organisationally_visible publicly_visible + is_test privately_visible] - enum funding_status: %i[planned funded denied] + enum :funding_status, %i[planned funded denied] alias_attribute :name, :title diff --git a/app/models/question_format.rb b/app/models/question_format.rb index 803e5725f4..5625cef4fc 100644 --- a/app/models/question_format.rb +++ b/app/models/question_format.rb @@ -24,7 +24,7 @@ class QuestionFormat < ApplicationRecord # = Attributes = # ============== - enum formattype: FORMAT_TYPES + enum :formattype, FORMAT_TYPES alias_attribute :to_s, :title diff --git a/app/models/question_option.rb b/app/models/question_option.rb index 9de8fb6451..2c855eb92a 100644 --- a/app/models/question_option.rb +++ b/app/models/question_option.rb @@ -4,17 +4,19 @@ # # Table name: question_options # -# id :integer not null, primary key -# is_default :boolean -# number :integer -# text :string -# created_at :datetime -# updated_at :datetime -# question_id :integer +# id :integer not null, primary key +# is_default :boolean +# number :integer +# text :string +# created_at :datetime +# updated_at :datetime +# question_id :integer +# versionable_id :string(36) # # Indexes # -# index_question_options_on_question_id (question_id) +# index_question_options_on_question_id (question_id) +# index_question_options_on_versionable_id (versionable_id) # # Foreign Keys # diff --git a/app/models/region.rb b/app/models/region.rb index 514671e44d..a191b8db31 100644 --- a/app/models/region.rb +++ b/app/models/region.rb @@ -4,12 +4,11 @@ # # Table name: regions # -# id :integer not null, primary key -# abbreviation :string -# description :string -# name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# abbreviation :string +# description :string +# name :string +# super_region_id :integer # # Object that represents a regional area diff --git a/app/models/repository.rb b/app/models/repository.rb index 344dcb889b..64cb64fea2 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -4,21 +4,21 @@ # # Table name: repositories # -# id :bigint not null, primary key +# id :bigint(8) not null, primary key # contact :string # description :text not null +# homepage :string # info :json # name :string not null -# homepage :string +# uri :string not null # created_at :datetime not null # updated_at :datetime not null -# uri :string not null # # Indexes # -# index_repositories_on_name (name) -# index_repositories_on_homepage (homepage) -# index_repositories_on_uri (uri) +# index_repositories_on_homepage (homepage) +# index_repositories_on_name (name) +# index_repositories_on_uri (uri) # # Object that represents a research output repository (e.g. GitHub or Zenodo) class Repository < ApplicationRecord diff --git a/app/models/research_domain.rb b/app/models/research_domain.rb index 87f8abd4a6..06d4bfb3d7 100644 --- a/app/models/research_domain.rb +++ b/app/models/research_domain.rb @@ -4,12 +4,12 @@ # # Table name: research_domains # -# id :bigint not null, primary key -# identifier :string not null -# label :string not null -# created_at :datetime not null -# updated_at :datetime not null -# parent_id :bigint +# id :bigint(8) not null, primary key +# identifier :string not null +# label :string not null +# created_at :datetime not null +# updated_at :datetime not null +# parent_id :bigint(8) # # Indexes # diff --git a/app/models/research_output.rb b/app/models/research_output.rb index 243b925185..05e684172c 100644 --- a/app/models/research_output.rb +++ b/app/models/research_output.rb @@ -4,14 +4,14 @@ # # Table name: research_outputs # -# id :bigint not null, primary key +# id :bigint(8) not null, primary key # abbreviation :string -# access :integer default("open"), not null -# byte_size :bigint +# access :integer default(0), not null +# byte_size :bigint(8) # description :text # display_order :integer # is_default :boolean -# output_type :integer default("dataset"), not null +# output_type :integer default(3), not null # output_type_description :string # personal_data :boolean # release_date :datetime @@ -19,16 +19,17 @@ # title :string not null # created_at :datetime not null # updated_at :datetime not null -# license_id :bigint +# license_id :bigint(8) # plan_id :integer # # Indexes # +# index_research_outputs_on_license_id (license_id) # index_research_outputs_on_output_type (output_type) +# index_research_outputs_on_plan_id (plan_id) # # Foreign Keys # -# fk_rails_... (plan_id => plans.id) # fk_rails_... (license_id => licenses.id) # @@ -37,11 +38,11 @@ class ResearchOutput < ApplicationRecord include Identifiable include ValidationMessages - enum output_type: %i[audiovisual collection data_paper dataset event image - interactive_resource model_representation physical_object - service software sound text workflow other] + enum :output_type, %i[audiovisual collection data_paper dataset event image + interactive_resource model_representation physical_object + service software sound text workflow other] - enum access: %i[open embargoed restricted closed] + enum :access, %i[open embargoed restricted closed] # ================ # = Associations = diff --git a/app/models/settings/template.rb b/app/models/settings/template.rb index 79b7fb21e2..cf6e450efa 100644 --- a/app/models/settings/template.rb +++ b/app/models/settings/template.rb @@ -5,9 +5,9 @@ # Table name: settings # # id :integer not null, primary key -# target_type :string not null +# target_type :string # value :text -# var :string not null +# var :string # created_at :datetime not null # updated_at :datetime not null # target_id :integer not null diff --git a/app/models/stat_created_plan.rb b/app/models/stat_created_plan.rb index 4c2c7f2c1f..6c2b226bed 100644 --- a/app/models/stat_created_plan.rb +++ b/app/models/stat_created_plan.rb @@ -15,8 +15,6 @@ # org_id :integer # -require 'set' - # Object that represents a Nbr of Plans created usage statistic class StatCreatedPlan < Stat serialize :details, coder: JSON diff --git a/app/models/template.rb b/app/models/template.rb index cf4d547510..d99697dcef 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -44,7 +44,7 @@ class Template < ApplicationRecord # that are meant for external use will be publicly visible. This allows a # funder to create 'funder' as well as organisational templates. The default # template should also always be publicly_visible. - enum visibility: %i[organisationally_visible publicly_visible] + enum :visibility, %i[organisationally_visible publicly_visible] # Stores links as an JSON object: # {funder: [{"link":"www.example.com","text":"foo"}, ...], diff --git a/app/models/tracker.rb b/app/models/tracker.rb index 7e62838d12..6acdd5b781 100644 --- a/app/models/tracker.rb +++ b/app/models/tracker.rb @@ -1,6 +1,24 @@ # frozen_string_literal: true # Object that represents a Google Analytics tracker code +# == Schema Information +# +# Table name: trackers +# +# id :integer not null, primary key +# code :string +# created_at :datetime not null +# updated_at :datetime not null +# org_id :integer +# +# Indexes +# +# index_trackers_on_org_id (org_id) +# +# Foreign Keys +# +# fk_rails_... (org_id => orgs.id) +# class Tracker < ApplicationRecord belongs_to :org validates :code, format: { with: /\A\z|\AUA-[0-9]+-[0-9]+\z/, diff --git a/app/models/user.rb b/app/models/user.rb index 94d0035eec..389a81d306 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,9 +21,12 @@ # invitation_sent_at :datetime # invitation_token :string # invited_by_type :string +# last_api_access :datetime # last_sign_in_at :datetime # last_sign_in_ip :string -# other_organisation :string +# ldap_password :string +# ldap_username :string +# other_organisation :string # recovery_email :string # remember_created_at :datetime # reset_password_sent_at :datetime diff --git a/app/views/devise/invitations/edit.html.erb b/app/views/devise/invitations/edit.html.erb index 744c37e8e3..488286afa9 100644 --- a/app/views/devise/invitations/edit.html.erb +++ b/app/views/devise/invitations/edit.html.erb @@ -9,7 +9,7 @@
<%= form_for resource, as: resource_name, url: invitation_path(resource_name), html: {method: :put, id: "invitation_create_account_form"} do |f| %> - <%= devise_error_messages! %> + <%= render 'devise/shared/error_messages', resource: resource %> <%= f.hidden_field :invitation_token %>
<%= f.label(:password, _('New password'), class: 'form-label') %> diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index 3e296747c2..1ff2ad32cd 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -8,7 +8,7 @@
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: {method: :put, id: "user_reset_password_form"}) do |f| %> - <%= devise_error_messages! %> + <%= render 'devise/shared/error_messages', resource: resource %> <%= f.hidden_field :reset_password_token %>
diff --git a/bin/rails b/bin/rails index bfa6cbda65..0739660237 100755 --- a/bin/rails +++ b/bin/rails @@ -1,10 +1,4 @@ #!/usr/bin/env ruby -begin - load File.expand_path('../spring', __FILE__) -rescue LoadError => e - raise unless e.message.include?('spring') -end -load File.expand_path("spring", __dir__) APP_PATH = File.expand_path('../config/application', __dir__) require_relative '../config/boot' require 'rails/commands' diff --git a/bin/rake b/bin/rake index e8aefa15ac..17240489f6 100755 --- a/bin/rake +++ b/bin/rake @@ -1,10 +1,4 @@ #!/usr/bin/env ruby -begin - load File.expand_path('../spring', __FILE__) -rescue LoadError => e - raise unless e.message.include?('spring') -end -load File.expand_path("spring", __dir__) require_relative '../config/boot' require 'rake' Rake.application.run diff --git a/bin/rspec b/bin/rspec index 6021396d7c..7492e31c10 100755 --- a/bin/rspec +++ b/bin/rspec @@ -1,10 +1,5 @@ #!/usr/bin/env ruby # frozen_string_literal: true -begin - load File.expand_path('../spring', __FILE__) -rescue LoadError => e - raise unless e.message.include?('spring') -end # # This file was generated by Bundler. # diff --git a/bin/spring b/bin/spring deleted file mode 100755 index 4080d890e1..0000000000 --- a/bin/spring +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby - -# This file loads Spring without using loading other gems in the Gemfile, in order to be fast. -# It gets overwritten when you run the `spring binstub` command. - -if !defined?(Spring) && [nil, 'development', 'test'].include?(ENV['RAILS_ENV']) - require 'bundler' - - Bundler.locked_gems.specs.find { |spec| spec.name == 'spring' }&.tap do |spring| - Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path - gem 'spring', spring.version - require 'spring/binstub' - end -end diff --git a/config/application.rb b/config/application.rb index 882ebb0def..708e3675db 100644 --- a/config/application.rb +++ b/config/application.rb @@ -14,7 +14,7 @@ module DMPRoadmap # DMPRoadmap application class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 7.1 + config.load_defaults 8.1 # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers diff --git a/config/boot.rb b/config/boot.rb index c04863fa7d..dd774bf242 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -3,4 +3,6 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) require 'bundler/setup' # Set up gems listed in the Gemfile. +# Load Logger before Rails boot rather than relying on a transitive require. +require 'logger' require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/config/environments/development.rb b/config/environments/development.rb index cb49bdc466..3bd8407719 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -67,6 +67,11 @@ # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true + # PostgreSQL owns the shared schema.rb. MySQL table options and column types + # are adapter-specific, so a MySQL development migration must not rewrite it. + database_url_is_mysql = ENV['DATABASE_URL']&.match?(/\Amysql(?:2)?:/) + config.active_record.dump_schema_after_migration = false if ENV['DB_ADAPTER'] == 'mysql2' || database_url_is_mysql + # Debug mode disables concatenation and preprocessing of assets. # This option may cause significant delays in view rendering with a large # number of complex assets. diff --git a/config/environments/test.rb b/config/environments/test.rb index 122ad051b6..a39cba6bfa 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -9,9 +9,15 @@ # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped # and recreated between test runs. Don't rely on the data there! - config.cache_classes = false + # Keep one set of model/service classes for the whole suite. Reloading + # between browser requests invalidates references held by examples. + config.enable_reloading = false config.action_view.cache_template_loading = true + # The checked-in schema is generated with PostgreSQL and loaded by both CI + # adapters; a MySQL migration must not rewrite it with MySQL table options. + config.active_record.dump_schema_after_migration = false + # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that # preloads Rails for running tests, you may have to set it to true. diff --git a/config/initializers/dmproadmap_schema_dumper.rb b/config/initializers/dmproadmap_schema_dumper.rb index 1305d80189..784c215746 100644 --- a/config/initializers/dmproadmap_schema_dumper.rb +++ b/config/initializers/dmproadmap_schema_dumper.rb @@ -1,72 +1,18 @@ # frozen_string_literal: true -module ActiveRecord - # The Rails 5.x SchemaDumper includes an `options:` arrgument on table definitions - # that is not DB agnostic. This Monkey Patch comments out the `options:` section. - # - # TODO: Determine if this is still necessary in Rails 6.x+ - class SchemaDumper - # Method definition taken from the 5.2-stable branch of ActiveRecord: - # https://github.com/rails/rails/blob/5-2-stable/activerecord/lib/active_record/schema_dumper.rb - # rubocop:disable Metrics/AbcSize, Metrics/MethodLength - # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity - def table(table, stream) - columns = @connection.columns(table) - begin - tbl = StringIO.new - - # first dump primary key column - pk = @connection.primary_key(table) - - tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}" - - case pk - when String - tbl.print ", primary_key: #{pk.inspect}" unless pk == 'id' - pkcol = columns.detect { |c| c.name == pk } - pkcolspec = column_spec_for_primary_key(pkcol) - tbl.print ", #{format_colspec(pkcolspec)}" if pkcolspec.present? - when Array - tbl.print ", primary_key: #{pk.inspect}" - else - tbl.print ', id: false' - end - - # Commenting out Table Options because they are not DB agnostic - # table_options = @connection.table_options(table) - # if table_options.present? - # tbl.print ", #{format_options(table_options)}" - # end - - tbl.puts ', force: :cascade do |t|' - - # then dump all non-primary key columns - columns.each do |column| - unless @connection.valid_type?(column.type) - raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" - end - next if column.name == pk - - type, colspec = column_spec(column) - tbl.print " t.#{type} #{column.name.inspect}" - tbl.print ", #{format_colspec(colspec)}" if colspec.present? - tbl.puts - end - - indexes_in_create(table, tbl) - - tbl.puts ' end' - tbl.puts - - tbl.rewind - stream.print tbl.read - rescue StandardError => e - stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}" - stream.puts "# #{e.message}" - stream.puts - end - end - # rubocop:enable Metrics/AbcSize, Metrics/MethodLength - # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity +# Legacy Roadmap tables use signed 32-bit primary keys and matching integer +# foreign keys. PostgreSQL reports those auto-incrementing keys as :serial; +# MySQL interprets :serial as unsigned bigint, so a PostgreSQL schema dump +# cannot be loaded into MySQL. :integer creates an auto-incrementing 32-bit +# primary key on both adapters without changing the stored key values. +module DMPRoadmapSchemaDumper + private + + def column_spec_for_primary_key(column) + spec = super + spec[:id] = ':integer' if spec[:id] == ':serial' + spec end end + +ActiveRecord::ConnectionAdapters::SchemaDumper.prepend(DMPRoadmapSchemaDumper) diff --git a/config/puma.rb b/config/puma.rb index 54bce1183a..938e1054a1 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -29,19 +29,19 @@ # This directive tells Puma to first boot the application and load code # before forking the application. This takes advantage of Copy On Write # process behavior so workers use less memory. If you use this option -# you need to make sure to reconnect any threads in the `on_worker_boot` +# you need to make sure to reconnect any threads in the `before_worker_boot` # block. # preload_app! -# The code in the `on_worker_boot` will be called if you are using +# The code in the `before_worker_boot` will be called if you are using # clustered mode by specifying a number of `workers`. After each worker # process is booted this block will be run, if you are using `preload_app!` # option you will want to use this block to reconnect to any threads # or connections that may have been created at application boot, Ruby # cannot share connections between processes. # -on_worker_boot do +before_worker_boot do ActiveRecord::Base.establish_connection if defined?(ActiveRecord) end diff --git a/config/routes.rb b/config/routes.rb index 5954d44591..0155b2d406 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -112,7 +112,7 @@ # Question Formats controller, currently just the one action get 'question_formats/rda_api_address' => 'question_formats#rda_api_address' - resources :notes, only: %i[create update archive] do + resources :notes, only: %i[create update] do member do patch 'archive' end diff --git a/config/spring.rb b/config/spring.rb deleted file mode 100644 index 37a3543421..0000000000 --- a/config/spring.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -Spring.watch( - ".ruby-version", - ".rbenv-vars", - "tmp/restart.txt", - "tmp/caching-dev.txt" -) diff --git a/config/webpack/test.js b/config/webpack/test.js new file mode 100644 index 0000000000..0ce22bf9a0 --- /dev/null +++ b/config/webpack/test.js @@ -0,0 +1,22 @@ +const webpack = require('webpack'); + +module.exports = { + mode: 'development', + devtool: 'inline-source-map', + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: ['babel-loader'], + }, + ], + }, + plugins: [ + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + 'window.jQuery': 'jquery', + }), + ], +}; diff --git a/db/schema.rb b/db/schema.rb index 3b6036f2bf..e0ec6d6956 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,11 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2025_01_15_102816) do +ActiveRecord::Schema[8.1].define(version: 2025_01_15_102816) do # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" + enable_extension "pg_catalog.plpgsql" - create_table "annotations", id: :serial, force: :cascade do |t| + create_table "annotations", id: :integer, force: :cascade do |t| t.integer "question_id" t.integer "org_id" t.text "text" @@ -27,7 +27,7 @@ t.index ["versionable_id"], name: "index_annotations_on_versionable_id" end - create_table "answers", id: :serial, force: :cascade do |t| + create_table "answers", id: :integer, force: :cascade do |t| t.text "text" t.integer "plan_id" t.integer "user_id" @@ -48,7 +48,7 @@ t.index ["answer_id"], name: "index_answers_question_options_on_answer_id" end - create_table "api_clients", id: :serial, force: :cascade do |t| + create_table "api_clients", id: :integer, force: :cascade do |t| t.string "name", null: false t.string "description" t.string "homepage" @@ -69,7 +69,7 @@ t.index ["name"], name: "index_oauth_applications_on_name" end - create_table "conditions", id: :serial, force: :cascade do |t| + create_table "conditions", id: :integer, force: :cascade do |t| t.integer "question_id" t.text "option_list" t.integer "action_type" @@ -81,7 +81,7 @@ t.index ["question_id"], name: "index_conditions_on_question_id" end - create_table "contributors", id: :serial, force: :cascade do |t| + create_table "contributors", id: :integer, force: :cascade do |t| t.string "name" t.string "email" t.string "phone" @@ -97,7 +97,7 @@ t.index ["roles"], name: "index_contributors_on_roles" end - create_table "departments", id: :serial, force: :cascade do |t| + create_table "departments", id: :integer, force: :cascade do |t| t.string "name" t.string "code" t.integer "org_id" @@ -106,7 +106,7 @@ t.index ["org_id"], name: "index_departments_on_org_id" end - create_table "exported_plans", id: :serial, force: :cascade do |t| + create_table "exported_plans", id: :integer, force: :cascade do |t| t.integer "plan_id" t.integer "user_id" t.string "format" @@ -130,7 +130,7 @@ t.index ["user_id"], name: "index_external_api_access_tokens_on_user_id" end - create_table "guidance_groups", id: :serial, force: :cascade do |t| + create_table "guidance_groups", id: :integer, force: :cascade do |t| t.string "name" t.integer "org_id" t.datetime "created_at", precision: nil, null: false @@ -140,7 +140,7 @@ t.index ["org_id"], name: "index_guidance_groups_on_org_id" end - create_table "guidances", id: :serial, force: :cascade do |t| + create_table "guidances", id: :integer, force: :cascade do |t| t.text "text" t.integer "guidance_group_id" t.datetime "created_at", precision: nil, null: false @@ -149,7 +149,7 @@ t.index ["guidance_group_id"], name: "index_guidances_on_guidance_group_id" end - create_table "identifier_schemes", id: :serial, force: :cascade do |t| + create_table "identifier_schemes", id: :integer, force: :cascade do |t| t.string "name" t.string "description" t.boolean "active" @@ -161,7 +161,7 @@ t.string "external_service" end - create_table "identifiers", id: :serial, force: :cascade do |t| + create_table "identifiers", id: :integer, force: :cascade do |t| t.string "value", null: false t.text "attrs" t.integer "identifier_scheme_id" @@ -174,7 +174,7 @@ t.index ["identifier_scheme_id", "value"], name: "index_identifiers_on_identifier_scheme_id_and_value" end - create_table "languages", id: :serial, force: :cascade do |t| + create_table "languages", id: :integer, force: :cascade do |t| t.string "abbreviation" t.string "description" t.string "name" @@ -212,7 +212,7 @@ t.index ["research_output_id"], name: "metadata_research_outputs_on_ro" end - create_table "notes", id: :serial, force: :cascade do |t| + create_table "notes", id: :integer, force: :cascade do |t| t.integer "user_id" t.text "text" t.boolean "archived", default: false, null: false @@ -224,7 +224,7 @@ t.index ["user_id"], name: "fk_rails_7f2323ad43" end - create_table "notification_acknowledgements", id: :serial, force: :cascade do |t| + create_table "notification_acknowledgements", id: :integer, force: :cascade do |t| t.integer "user_id" t.integer "notification_id" t.datetime "created_at", precision: nil @@ -233,7 +233,7 @@ t.index ["user_id"], name: "index_notification_acknowledgements_on_user_id" end - create_table "notifications", id: :serial, force: :cascade do |t| + create_table "notifications", id: :integer, force: :cascade do |t| t.integer "notification_type" t.string "title" t.integer "level" @@ -246,7 +246,7 @@ t.boolean "enabled", default: true end - create_table "org_token_permissions", id: :serial, force: :cascade do |t| + create_table "org_token_permissions", id: :integer, force: :cascade do |t| t.integer "org_id" t.integer "token_permission_type_id" t.datetime "created_at", precision: nil @@ -255,7 +255,7 @@ t.index ["token_permission_type_id"], name: "fk_rails_2aa265f538" end - create_table "orgs", id: :serial, force: :cascade do |t| + create_table "orgs", id: :integer, force: :cascade do |t| t.string "name" t.string "abbreviation" t.string "target_url" @@ -280,13 +280,13 @@ t.index ["region_id"], name: "fk_rails_5a6adf6bab" end - create_table "perms", id: :serial, force: :cascade do |t| + create_table "perms", id: :integer, force: :cascade do |t| t.string "name" t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false end - create_table "phases", id: :serial, force: :cascade do |t| + create_table "phases", id: :integer, force: :cascade do |t| t.string "title" t.text "description" t.integer "number" @@ -299,7 +299,7 @@ t.index ["versionable_id"], name: "index_phases_on_versionable_id" end - create_table "plans", id: :serial, force: :cascade do |t| + create_table "plans", id: :integer, force: :cascade do |t| t.string "title" t.integer "template_id" t.datetime "created_at", precision: nil @@ -328,7 +328,7 @@ t.index ["template_id"], name: "index_plans_on_template_id" end - create_table "plans_guidance_groups", id: :serial, force: :cascade do |t| + create_table "plans_guidance_groups", id: :integer, force: :cascade do |t| t.integer "guidance_group_id" t.integer "plan_id" t.index ["guidance_group_id", "plan_id"], name: "index_plans_guidance_groups_on_guidance_group_id_and_plan_id" @@ -336,7 +336,7 @@ t.index ["plan_id"], name: "fk_rails_13d0671430" end - create_table "prefs", id: :serial, force: :cascade do |t| + create_table "prefs", id: :integer, force: :cascade do |t| t.text "settings" t.integer "user_id" end @@ -350,7 +350,7 @@ t.datetime "updated_at", precision: nil end - create_table "question_formats", id: :serial, force: :cascade do |t| + create_table "question_formats", id: :integer, force: :cascade do |t| t.string "title" t.text "description" t.datetime "created_at", precision: nil, null: false @@ -359,7 +359,7 @@ t.integer "formattype", default: 0 end - create_table "question_options", id: :serial, force: :cascade do |t| + create_table "question_options", id: :integer, force: :cascade do |t| t.integer "question_id" t.string "text" t.integer "number" @@ -371,7 +371,7 @@ t.index ["versionable_id"], name: "index_question_options_on_versionable_id" end - create_table "questions", id: :serial, force: :cascade do |t| + create_table "questions", id: :integer, force: :cascade do |t| t.text "text" t.text "default_value" t.integer "number" @@ -393,7 +393,7 @@ t.index ["question_id"], name: "index_questions_themes_on_question_id" end - create_table "regions", id: :serial, force: :cascade do |t| + create_table "regions", id: :integer, force: :cascade do |t| t.string "abbreviation" t.string "description" t.string "name" @@ -467,7 +467,7 @@ t.index ["plan_id"], name: "index_research_outputs_on_plan_id" end - create_table "roles", id: :serial, force: :cascade do |t| + create_table "roles", id: :integer, force: :cascade do |t| t.integer "user_id" t.integer "plan_id" t.datetime "created_at", precision: nil @@ -478,7 +478,7 @@ t.index ["user_id"], name: "index_roles_on_user_id" end - create_table "sections", id: :serial, force: :cascade do |t| + create_table "sections", id: :integer, force: :cascade do |t| t.string "title" t.text "description" t.integer "number" @@ -491,7 +491,7 @@ t.index ["versionable_id"], name: "index_sections_on_versionable_id" end - create_table "sessions", id: :serial, force: :cascade do |t| + create_table "sessions", id: :integer, force: :cascade do |t| t.string "session_id", limit: 64, null: false t.text "data" t.datetime "created_at", precision: nil @@ -500,7 +500,7 @@ t.index ["updated_at"], name: "index_sessions_on_updated_at" end - create_table "settings", id: :serial, force: :cascade do |t| + create_table "settings", id: :integer, force: :cascade do |t| t.string "var" t.text "value" t.integer "target_id", null: false @@ -509,7 +509,7 @@ t.datetime "updated_at", precision: nil, null: false end - create_table "stats", id: :serial, force: :cascade do |t| + create_table "stats", id: :integer, force: :cascade do |t| t.bigint "count", default: 0 t.date "date", null: false t.string "type", null: false @@ -533,7 +533,7 @@ t.index ["subscriber_id", "subscriber_type", "plan_id"], name: "index_subscribers_on_identifiable_and_plan_id" end - create_table "templates", id: :serial, force: :cascade do |t| + create_table "templates", id: :integer, force: :cascade do |t| t.string "title" t.text "description" t.boolean "published" @@ -554,7 +554,7 @@ t.index ["org_id"], name: "index_templates_on_org_id" end - create_table "themes", id: :serial, force: :cascade do |t| + create_table "themes", id: :integer, force: :cascade do |t| t.string "title" t.text "description" t.datetime "created_at", precision: nil, null: false @@ -569,14 +569,14 @@ t.index ["theme_id"], name: "index_themes_in_guidance_on_theme_id" end - create_table "token_permission_types", id: :serial, force: :cascade do |t| + create_table "token_permission_types", id: :integer, force: :cascade do |t| t.string "token_type" t.text "text_description" t.datetime "created_at", precision: nil t.datetime "updated_at", precision: nil end - create_table "trackers", id: :serial, force: :cascade do |t| + create_table "trackers", id: :integer, force: :cascade do |t| t.integer "org_id" t.string "code" t.datetime "created_at", precision: nil, null: false @@ -584,7 +584,7 @@ t.index ["org_id"], name: "index_trackers_on_org_id" end - create_table "users", id: :serial, force: :cascade do |t| + create_table "users", id: :integer, force: :cascade do |t| t.string "firstname" t.string "surname" t.string "email", limit: 80, default: "", null: false diff --git a/lib/tasks/annotate_rb.rake b/lib/tasks/annotate_rb.rake new file mode 100644 index 0000000000..a4f254325b --- /dev/null +++ b/lib/tasks/annotate_rb.rake @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# This rake task was added by annotate_rb gem. + +# Can set `ANNOTATERB_SKIP_ON_DB_TASKS` to be anything to skip this +if Rails.env.development? && ENV['ANNOTATERB_SKIP_ON_DB_TASKS'].nil? + require 'annotate_rb' + + # Can modify the config path here if needed - by default, it's .annotaterb.yml in the root of the project + # AnnotateRb::ConfigFinder.config_path = "" + AnnotateRb::Core.load_rake_tasks +end diff --git a/lib/tasks/auto_annotate_models.rake b/lib/tasks/auto_annotate_models.rake deleted file mode 100644 index 8e036abf37..0000000000 --- a/lib/tasks/auto_annotate_models.rake +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -# NOTE: only doing this in development as some production environments (Heroku) -# NOTE: are sensitive to local FS writes, and besides -- it's just not proper -# NOTE: to have a dev-mode tool do its thing in production. -if Rails.env.development? - require 'annotate' - task :set_annotation_options do - # You can override any of these by setting an environment variable of the - # same name. - Annotate.set_defaults( - 'routes' => 'false', - 'position_in_routes' => 'before', - 'position_in_class' => 'before', - 'position_in_test' => 'before', - 'position_in_fixture' => 'before', - 'position_in_factory' => 'before', - 'position_in_serializer' => 'before', - 'show_foreign_keys' => 'true', - 'show_complete_foreign_keys' => 'false', - 'show_indexes' => 'true', - 'simple_indexes' => 'false', - 'model_dir' => 'app/models', - 'root_dir' => '', - 'include_version' => 'false', - 'require' => '', - 'exclude_tests' => 'true', - 'exclude_fixtures' => 'true', - 'exclude_factories' => 'false', - 'exclude_serializers' => 'true', - 'exclude_scaffolds' => 'true', - 'exclude_controllers' => 'true', - 'exclude_helpers' => 'true', - 'exclude_sti_subclasses' => 'false', - 'ignore_model_sub_dir' => 'false', - 'ignore_columns' => nil, - 'ignore_routes' => 'true', - 'ignore_unknown_models' => 'false', - 'hide_limit_column_types' => 'integer,boolean', - 'hide_default_column_types' => 'json,jsonb,hstore', - 'skip_on_db_migrate' => 'false', - 'format_bare' => 'true', - 'format_rdoc' => 'false', - 'format_markdown' => 'false', - 'sort' => 'false', - 'force' => 'false', - 'classified_sort' => 'true', - 'trace' => 'false', - 'wrapper_open' => nil, - 'wrapper_close' => nil, - 'with_comment' => true - ) - end - - Annotate.load_tasks -end diff --git a/lib/tasks/upgrade.rake b/lib/tasks/upgrade.rake index 39c83aacf9..3e4931ad14 100644 --- a/lib/tasks/upgrade.rake +++ b/lib/tasks/upgrade.rake @@ -2,8 +2,6 @@ # Upgrade tasks for versions < 3.0. See https://github.com/DMPRoadmap/roadmap/releases for information # on how and when to run each task. -require 'set' - # rubocop:disable Naming/VariableNumber namespace :upgrade do desc 'upgrade to Rails 5, rename task after naming release' diff --git a/package.json b/package.json index fb0792e659..e3cbd309fa 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "devDependencies": { "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "babel-plugin-dynamic-import-node": "^2.3.3", "eslint": "^8.18.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-import": "^2.26.0", diff --git a/spec/factories/api_clients.rb b/spec/factories/api_clients.rb index b5ea773667..e55f5df398 100644 --- a/spec/factories/api_clients.rb +++ b/spec/factories/api_clients.rb @@ -4,25 +4,29 @@ # # Table name: api_clients # -# id :integer not null, primary key -# name :string, not null -# homepage :string -# contact_name :string -# contact_email :string, not null -# client_id :string, not null -# client_secret :string, not null -# last_access :datetime -# created_at :datetime -# updated_at :datetime -# org_id :integer +# id :integer not null, primary key +# callback_method :integer +# callback_uri :string +# client_secret :string not null +# confidential :boolean default(TRUE) +# contact_email :string +# contact_name :string +# description :string +# homepage :string +# last_access :datetime +# name :string not null +# redirect_uri :text +# scopes :string default(""), not null +# trusted :boolean default(FALSE) +# created_at :datetime not null +# updated_at :datetime not null +# client_id :string not null +# org_id :integer # # Indexes # -# index_api_clients_on_name (name) +# index_oauth_applications_on_name (name) # -# Foreign Keys -# -# fk_rails_... (org_id => orgs.id) FactoryBot.define do factory :api_client do diff --git a/spec/factories/conditions.rb b/spec/factories/conditions.rb index afaf5fdea2..ff6fcd221a 100644 --- a/spec/factories/conditions.rb +++ b/spec/factories/conditions.rb @@ -4,15 +4,15 @@ # # Table name: conditions # -# id :integer not null, primary key -# question_id :integer -# number :integer -# action_type :integer -# option_list :text -# remove_data :text -# webhook_data :text -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# action_type :integer +# number :integer +# option_list :text +# remove_data :text +# webhook_data :text +# created_at :datetime not null +# updated_at :datetime not null +# question_id :integer # # Indexes # @@ -20,8 +20,7 @@ # # Foreign Keys # -# fk_rails_... (question_id => question.id) -# +# fk_rails_... (question_id => questions.id) # FactoryBot.define do diff --git a/spec/factories/contributors.rb b/spec/factories/contributors.rb index 4d38bfafbf..51e0097bbd 100644 --- a/spec/factories/contributors.rb +++ b/spec/factories/contributors.rb @@ -4,26 +4,24 @@ # # Table name: contributors # -# id :integer not null, primary key -# name :string -# email :string -# phone :string -# roles :integer -# org_id :integer -# plan_id :integer -# created_at :datetime -# updated_at :datetime +# id :integer not null, primary key +# email :string +# name :string +# phone :string +# roles :integer not null +# created_at :datetime +# updated_at :datetime +# org_id :integer +# plan_id :integer not null # # Indexes # -# index_contributors_on_id (id) -# index_contributors_on_email (email) -# index_contributors_on_org_id (org_id) +# index_contrib_id_and_org_id (name,id,org_id) +# index_contributors_on_email (email) +# index_contributors_on_org_id (org_id) +# index_contributors_on_plan_id (plan_id) +# index_contributors_on_roles (roles) # -# Foreign Keys -# -# fk_rails_... (org_id => orgs.id) -# fk_rails_... (plan_id => plans.id) FactoryBot.define do factory :contributor do diff --git a/spec/factories/identifier_schemes.rb b/spec/factories/identifier_schemes.rb index 3e52d43b66..609d469226 100644 --- a/spec/factories/identifier_schemes.rb +++ b/spec/factories/identifier_schemes.rb @@ -6,11 +6,12 @@ # # id :integer not null, primary key # active :boolean -# description :string # context :integer -# logo_url :text -# name :string +# description :string +# external_service :string # identifier_prefix :string +# logo_url :string +# name :string # created_at :datetime # updated_at :datetime # diff --git a/spec/factories/identifiers.rb b/spec/factories/identifiers.rb index 49d4a1b832..7ef6b26864 100644 --- a/spec/factories/identifiers.rb +++ b/spec/factories/identifiers.rb @@ -11,11 +11,13 @@ # created_at :datetime # updated_at :datetime # identifiable_id :integer -# identifier_scheme_id :integer not null +# identifier_scheme_id :integer # # Indexes # # index_identifiers_on_identifiable_type_and_identifiable_id (identifiable_type,identifiable_id) +# index_identifiers_on_identifier_scheme_id_and_value (identifier_scheme_id,value) +# index_identifiers_on_scheme_and_type_and_id (identifier_scheme_id,identifiable_id,identifiable_type) # FactoryBot.define do diff --git a/spec/factories/licenses.rb b/spec/factories/licenses.rb index 3564d800c5..02de62c86c 100644 --- a/spec/factories/licenses.rb +++ b/spec/factories/licenses.rb @@ -4,7 +4,7 @@ # # Table name: licenses # -# id :bigint not null, primary key +# id :bigint(8) not null, primary key # deprecated :boolean default(FALSE) # identifier :string not null # name :string not null diff --git a/spec/factories/metadata_standards.rb b/spec/factories/metadata_standards.rb index ca8136b37e..9af28d9a40 100644 --- a/spec/factories/metadata_standards.rb +++ b/spec/factories/metadata_standards.rb @@ -4,15 +4,15 @@ # # Table name: metadata_standards # -# id :bigint not null, primary key -# description :text -# locations :json -# related_entities :json -# title :string -# uri :string -# created_at :datetime not null -# updated_at :datetime not null -# rdamsc_id :string +# id :bigint(8) not null, primary key +# description :text +# locations :json +# related_entities :json +# title :string +# uri :string +# created_at :datetime not null +# updated_at :datetime not null +# rdamsc_id :string # FactoryBot.define do factory :metadata_standard do diff --git a/spec/factories/notifications.rb b/spec/factories/notifications.rb index cf6c130195..947f185257 100644 --- a/spec/factories/notifications.rb +++ b/spec/factories/notifications.rb @@ -7,12 +7,12 @@ # id :integer not null, primary key # body :text # dismissable :boolean +# enabled :boolean default(TRUE) # expires_at :date # level :integer # notification_type :integer # starts_at :date # title :string -# enable :boolean # created_at :datetime not null # updated_at :datetime not null # diff --git a/spec/factories/orgs.rb b/spec/factories/orgs.rb index 88bc858b0b..2565006758 100644 --- a/spec/factories/orgs.rb +++ b/spec/factories/orgs.rb @@ -4,31 +4,37 @@ # # Table name: orgs # -# id :integer not null, primary key -# abbreviation :string -# contact_email :string -# contact_name :string -# feedback_msg :text -# feedback_enabled :boolean default(FALSE) -# is_other :boolean default(FALSE), not null -# links :text -# logo_name :string -# logo_uid :string -# managed :boolean default(FALSE), not null -# name :string -# org_type :integer default(0), not null -# target_url :string -# created_at :datetime not null -# updated_at :datetime not null -# language_id :integer +# id :integer not null, primary key +# abbreviation :string +# api_create_plan_email_body :text +# api_create_plan_email_subject :string +# contact_email :string +# contact_name :string +# feedback_enabled :boolean default(FALSE) +# feedback_msg :text +# helpdesk_email :string +# is_other :boolean default(FALSE), not null +# links :text +# logo_name :string +# logo_uid :string +# managed :boolean default(FALSE), not null +# name :string +# org_type :integer default(0), not null +# target_url :string +# created_at :datetime not null +# updated_at :datetime not null +# language_id :integer +# region_id :integer # # Indexes # # fk_rails_5640112cab (language_id) +# fk_rails_5a6adf6bab (region_id) # # Foreign Keys # # fk_rails_... (language_id => languages.id) +# fk_rails_... (region_id => regions.id) # FactoryBot.define do diff --git a/spec/factories/plans.rb b/spec/factories/plans.rb index c07d002ec7..67d1aee4f1 100644 --- a/spec/factories/plans.rb +++ b/spec/factories/plans.rb @@ -4,39 +4,41 @@ # # Table name: plans # -# id :integer not null, primary key -# complete :boolean default(FALSE) -# description :text -# ethical_issues :boolean -# ethical_issues_description :text -# ethical_issues_report :string -# feedback_requested :boolean default(FALSE) -# funding_status :integer -# identifier :string -# title :string -# visibility :integer default(3), not null -# created_at :datetime -# updated_at :datetime -# template_id :integer -# org_id :integer -# funder_id :integer -# grant_id :integer -# api_client_id :integer -# research_domain_id :bigint +# id :integer not null, primary key +# complete :boolean default(FALSE) +# description :text +# end_date :datetime +# ethical_issues :boolean +# ethical_issues_description :text +# ethical_issues_report :string +# feedback_requested :boolean default(FALSE) +# funding_status :integer +# identifier :string +# start_date :datetime +# title :string +# visibility :integer default(3), not null +# created_at :datetime +# updated_at :datetime +# api_client_id :integer +# funder_id :integer +# grant_id :integer +# org_id :integer +# research_domain_id :bigint(8) +# template_id :integer # # Indexes # -# index_plans_on_template_id (template_id) -# index_plans_on_funder_id (funder_id) -# index_plans_on_grant_id (grant_id) -# index_plans_on_api_client_id (api_client_id) +# index_plans_on_api_client_id (api_client_id) +# index_plans_on_fos_id (research_domain_id) +# index_plans_on_funder_id (funder_id) +# index_plans_on_grant_id (grant_id) +# index_plans_on_org_id (org_id) +# index_plans_on_template_id (template_id) # # Foreign Keys # -# fk_rails_... (template_id => templates.id) # fk_rails_... (org_id => orgs.id) -# fk_rails_... (api_client_id => api_clients.id) -# fk_rails_... (research_domain_id => research_domains.id) +# fk_rails_... (template_id => templates.id) # FactoryBot.define do diff --git a/spec/factories/question_options.rb b/spec/factories/question_options.rb index 415d55537a..b973d24809 100644 --- a/spec/factories/question_options.rb +++ b/spec/factories/question_options.rb @@ -4,17 +4,19 @@ # # Table name: question_options # -# id :integer not null, primary key -# is_default :boolean -# number :integer -# text :string -# created_at :datetime -# updated_at :datetime -# question_id :integer +# id :integer not null, primary key +# is_default :boolean +# number :integer +# text :string +# created_at :datetime +# updated_at :datetime +# question_id :integer +# versionable_id :string(36) # # Indexes # -# index_question_options_on_question_id (question_id) +# index_question_options_on_question_id (question_id) +# index_question_options_on_versionable_id (versionable_id) # # Foreign Keys # diff --git a/spec/factories/regions.rb b/spec/factories/regions.rb index 81148dc330..258799784b 100644 --- a/spec/factories/regions.rb +++ b/spec/factories/regions.rb @@ -4,12 +4,11 @@ # # Table name: regions # -# id :integer not null, primary key -# abbreviation :string -# description :string -# name :string not null -# created_at :datetime not null -# updated_at :datetime not null +# id :integer not null, primary key +# abbreviation :string +# description :string +# name :string +# super_region_id :integer # FactoryBot.define do diff --git a/spec/factories/repositories.rb b/spec/factories/repositories.rb index 922a8a47b2..11577df273 100644 --- a/spec/factories/repositories.rb +++ b/spec/factories/repositories.rb @@ -4,25 +4,25 @@ # # Table name: repositories # -# id :bigint not null, primary key +# id :bigint(8) not null, primary key # contact :string # description :text not null +# homepage :string # info :json # name :string not null -# homepage :string +# uri :string not null # created_at :datetime not null # updated_at :datetime not null -# uri :string not null # # Indexes # -# index_repositories_on_name (name) -# index_repositories_on_url (homepage) -# index_repositories_on_url (uri) +# index_repositories_on_homepage (homepage) +# index_repositories_on_name (name) +# index_repositories_on_uri (uri) # FactoryBot.define do factory :repository do - name { Faker::Music::PearlJam.song } + sequence(:name) { |n| "#{Faker::Music::PearlJam.song}-#{n}" } description { Faker::Lorem.paragraph } homepage { Faker::Internet.unique.url } uri { Faker::Internet.unique.url } diff --git a/spec/factories/research_domains.rb b/spec/factories/research_domains.rb index 7d4017f924..0823ed3d12 100644 --- a/spec/factories/research_domains.rb +++ b/spec/factories/research_domains.rb @@ -5,15 +5,15 @@ # Table name: research_domains # # id :bigint(8) not null, primary key -# identifier :string(255) not null -# label :string(255) not null +# identifier :string not null +# label :string not null # created_at :datetime not null # updated_at :datetime not null # parent_id :bigint(8) # # Indexes # -# index_research_domain_on_parent_id (parent_id) +# index_research_domains_on_parent_id (parent_id) # # Foreign Keys # diff --git a/spec/factories/research_outputs.rb b/spec/factories/research_outputs.rb index 4f62a881a1..d49288d97a 100644 --- a/spec/factories/research_outputs.rb +++ b/spec/factories/research_outputs.rb @@ -5,18 +5,18 @@ # Table name: research_outputs # # id :bigint(8) not null, primary key -# abbreviation :string(255) -# access :integer default("open"), not null +# abbreviation :string +# access :integer default(0), not null # byte_size :bigint(8) -# description :text(65535) +# description :text # display_order :integer # is_default :boolean -# output_type :integer default("dataset"), not null -# output_type_description :string(255) +# output_type :integer default(3), not null +# output_type_description :string # personal_data :boolean # release_date :datetime # sensitive_data :boolean -# title :string(255) not null +# title :string not null # created_at :datetime not null # updated_at :datetime not null # license_id :bigint(8) @@ -28,6 +28,10 @@ # index_research_outputs_on_output_type (output_type) # index_research_outputs_on_plan_id (plan_id) # +# Foreign Keys +# +# fk_rails_... (license_id => licenses.id) +# FactoryBot.define do factory :research_output do license diff --git a/spec/factories/trackers.rb b/spec/factories/trackers.rb index 875480d4e1..448b92e02b 100644 --- a/spec/factories/trackers.rb +++ b/spec/factories/trackers.rb @@ -1,5 +1,23 @@ # frozen_string_literal: true +# == Schema Information +# +# Table name: trackers +# +# id :integer not null, primary key +# code :string +# created_at :datetime not null +# updated_at :datetime not null +# org_id :integer +# +# Indexes +# +# index_trackers_on_org_id (org_id) +# +# Foreign Keys +# +# fk_rails_... (org_id => orgs.id) +# FactoryBot.define do factory :tracker do org { nil } diff --git a/spec/factories/users.rb b/spec/factories/users.rb index c91c756604..61f0a2137d 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -21,8 +21,11 @@ # invitation_sent_at :datetime # invitation_token :string # invited_by_type :string +# last_api_access :datetime # last_sign_in_at :datetime # last_sign_in_ip :string +# ldap_password :string +# ldap_username :string # other_organisation :string # recovery_email :string # remember_created_at :datetime diff --git a/spec/features/annotations/annotations_editing_spec.rb b/spec/features/annotations/annotations_editing_spec.rb index 0edfc4a25e..52d91941b5 100644 --- a/spec/features/annotations/annotations_editing_spec.rb +++ b/spec/features/annotations/annotations_editing_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'rails_helper' +require 'timeout' RSpec.feature 'Annotations::Editing', type: :feature do let!(:funder) { create(:org, :funder) } @@ -35,9 +36,10 @@ within("#template_#{template.id}") do click_button 'Actions' end - expect do - click_link 'Customise' - end.to change { Template.count }.by(1) + template_count = Template.count + click_link 'Customise' + expect(page).to have_current_path(%r{\A/org_admin/templates/\d+\z}) + expect(Template.count).to eq(template_count + 1) # New Template created template = Template.last @@ -45,18 +47,22 @@ click_link section.title - within("fieldset#fields_annotation_#{template.annotation_ids.last}") do - id = "question_annotations_attributes_annotation_#{template.annotation_ids.last}_text" + copied_annotation_id = template.annotation_ids.last + within("fieldset#fields_annotation_#{copied_annotation_id}") do + id = "question_annotations_attributes_annotation_#{copied_annotation_id}_text" tinymce_fill_in(id, with: 'Noo bar') end # NOTE: This is question 2, since Annotation was copied upon clicking "Customise" - within("#edit_question_#{template.question_ids.last}") do - # Expect it to destroy the newly cleared Annotation - expect { click_button 'Save' }.not_to change { Annotation.count } + annotation_count = Annotation.count + question_id = template.question_ids.last + within("#edit_question_#{question_id}") { click_button 'Save' } + Timeout.timeout(Capybara.default_max_wait_time) do + sleep 0.05 until Annotation.uncached { Annotation.find(copied_annotation_id).text == '

Noo bar

' } end + expect(Annotation.uncached { Annotation.count }).to eq(annotation_count) expect(annotation.text).to eql('Foo bar') - expect(Annotation.order('created_at').last.text).to eql('

Noo bar

') + expect(Annotation.uncached { Annotation.find(copied_annotation_id).text }).to eql('

Noo bar

') expect(page).not_to have_errors end @@ -65,22 +71,27 @@ within("#template_#{template.id}") do click_button 'Actions' end - expect do - click_link 'Customise' - end.to change { Template.count }.by(1) + template_count = Template.count + click_link 'Customise' + expect(page).to have_current_path(%r{\A/org_admin/templates/\d+\z}) + expect(Template.count).to eq(template_count + 1) template = Template.last click_link 'Customise phase' click_link section.title # NOTE: This is annotation 2, since Annotation was copied upon clicking "Customise" - within("fieldset#fields_annotation_#{template.annotation_ids.last}") do - id = "question_annotations_attributes_annotation_#{template.annotation_ids.last}_text" + copied_annotation_id = template.annotation_ids.last + within("fieldset#fields_annotation_#{copied_annotation_id}") do + id = "question_annotations_attributes_annotation_#{copied_annotation_id}_text" tinymce_fill_in(:"#{id}", with: ' ') end # NOTE: This is question 2, since Annotation was copied upon clicking "Customise" - within("#edit_question_#{template.question_ids.last}") do - # Expect it to destroy the newly cleared Annotation - expect { click_button 'Save' }.to change { Annotation.count }.by(-1) + annotation_count = Annotation.count + question_id = template.question_ids.last + within("#edit_question_#{question_id}") { click_button 'Save' } + Timeout.timeout(Capybara.default_max_wait_time) do + sleep 0.05 while Annotation.uncached { Annotation.exists?(copied_annotation_id) } end + expect(Annotation.uncached { Annotation.count }).to eq(annotation_count - 1) expect(page).not_to have_errors end end diff --git a/spec/features/feedback_requests_spec.rb b/spec/features/feedback_requests_spec.rb index 4d6eaccfdf..edfafbaebf 100644 --- a/spec/features/feedback_requests_spec.rb +++ b/spec/features/feedback_requests_spec.rb @@ -40,6 +40,7 @@ end # Expectations + expect(page).to have_text('Feedback has been requested.') expect(plan.reload).to be_feedback_requested expect(ActionMailer::Base.deliveries).to have_exactly(1).item end diff --git a/spec/features/modal_search_spec.rb b/spec/features/modal_search_spec.rb index c2b3f990bc..1eed171760 100644 --- a/spec/features/modal_search_spec.rb +++ b/spec/features/modal_search_spec.rb @@ -63,7 +63,7 @@ def perform_modal_actions close_modal end # Verify that the selection was added to the main page's dom - expect(page).not_to have_text('Repository search') + expect(page).to have_no_css('#modal-search-repositories', visible: true) expect(page).to have_text(@model.description) end @@ -84,9 +84,6 @@ def search_and_select_repository_within_modal end def close_modal - # Using JS to click on button, as click_button '.modal-header button.btn-close' did not work. - modal_close_button = find('.modal-header button.btn-close') - # Close the modal - execute_script('arguments[0].click();', modal_close_button) + find('.modal-header button.btn-close').click end end diff --git a/spec/features/plans_spec.rb b/spec/features/plans_spec.rb index eb7ba84a43..ab3c03ad85 100644 --- a/spec/features/plans_spec.rb +++ b/spec/features/plans_spec.rb @@ -45,10 +45,10 @@ click_button 'Create plan' # Expectations + expect(page).to have_css("input[type=text][value='My test plan']") expect(@user.plans).to be_one @plan = Plan.last - expect(current_path).to eql(plan_path(@plan)) - expect(page).to have_css("input[type=text][value='#{@plan.title}']") + expect(page).to have_current_path(plan_path(@plan)) expect(@plan.title).to eql('My test plan') expect(@plan.org_id).to eql(@research_org.id) expect(@plan.funder_id).to eql(@funding_org.id) diff --git a/spec/features/questions/dropdown_questions_spec.rb b/spec/features/questions/dropdown_questions_spec.rb index f157dd4621..9f252da43b 100644 --- a/spec/features/questions/dropdown_questions_spec.rb +++ b/spec/features/questions/dropdown_questions_spec.rb @@ -24,7 +24,7 @@ click_link 'Write plan' # Expectations - expect(current_path).to eql(edit_plan_path(@plan)) + expect(page).to have_current_path(edit_plan_path(@plan), ignore_query: true) # 4 sections x 3 questions expect(page).to have_text('(0 / 1)') diff --git a/spec/features/questions/textarea_questions_spec.rb b/spec/features/questions/textarea_questions_spec.rb index 34e3fcf84c..37b32e711e 100644 --- a/spec/features/questions/textarea_questions_spec.rb +++ b/spec/features/questions/textarea_questions_spec.rb @@ -24,7 +24,7 @@ click_link 'Write plan' # Expectations - expect(current_path).to eql(edit_plan_path(@plan)) + expect(page).to have_current_path(edit_plan_path(@plan), ignore_query: true) # 4 sections x 3 questions expect(page).to have_text('(0 / 1)') diff --git a/spec/features/questions/textfield_questions_spec.rb b/spec/features/questions/textfield_questions_spec.rb index 7df6366f37..2b72e2e140 100644 --- a/spec/features/questions/textfield_questions_spec.rb +++ b/spec/features/questions/textfield_questions_spec.rb @@ -24,7 +24,7 @@ click_link 'Write plan' # Expectations - expect(current_path).to eql(edit_plan_path(@plan)) + expect(page).to have_current_path(edit_plan_path(@plan), ignore_query: true) # 4 sections x 3 questions expect(page).to have_text('(0 / 1)') diff --git a/spec/features/registrations_spec.rb b/spec/features/registrations_spec.rb index 50ef4d60ab..b00b93b793 100644 --- a/spec/features/registrations_spec.rb +++ b/spec/features/registrations_spec.rb @@ -26,7 +26,7 @@ click_button 'Create account' # Expectations - expect(current_path).to eql(plans_path) + expect(page).to have_current_path(plans_path) expect(page).to have_text(user_attributes[:firstname]) expect(page).to have_text(user_attributes[:surname]) end @@ -49,7 +49,7 @@ click_button 'Create account' # Expectations - expect(current_path).to eql(root_path) + expect(page).to have_current_path(root_path) expect(User.count).to be_zero end end diff --git a/spec/features/sessions_spec.rb b/spec/features/sessions_spec.rb index 9fb3d7682e..d96c192ec9 100644 --- a/spec/features/sessions_spec.rb +++ b/spec/features/sessions_spec.rb @@ -15,7 +15,7 @@ click_button 'Sign in' # Expectation - expect(current_path).to eql(plans_path) + expect(page).to have_current_path(plans_path) expect(page).to have_text(user.firstname) expect(page).to have_text(user.surname) end @@ -30,7 +30,7 @@ click_button 'Sign in' # Expectation - expect(current_path).to eql(root_path) + expect(page).to have_current_path(root_path) expect(page).not_to have_text(user.firstname) expect(page).not_to have_text(user.surname) expect(page).to have_text('Error') diff --git a/spec/features/templates/templates_copying_spec.rb b/spec/features/templates/templates_copying_spec.rb index 6910c47c5d..025389395e 100644 --- a/spec/features/templates/templates_copying_spec.rb +++ b/spec/features/templates/templates_copying_spec.rb @@ -34,6 +34,7 @@ end # Expectations + expect(page).to have_current_path(%r{\A/org_admin/templates/\d+/edit\z}) expect(Template.count).to eql(2) new_template = Template.last expect(new_template.title).to include(parent_template.title) diff --git a/spec/features/templates/templates_editings_spec.rb b/spec/features/templates/templates_editings_spec.rb index a56237f880..7a299a3dc6 100644 --- a/spec/features/templates/templates_editings_spec.rb +++ b/spec/features/templates/templates_editings_spec.rb @@ -30,6 +30,7 @@ click_button 'Actions' end click_link 'Customise' + expect(page).to have_current_path(%r{\A/org_admin/templates/\d+\z}) # New template created template = Template.last within("#phase_#{template.phase_ids.first}") do diff --git a/spec/features/templates/templates_upgrade_customisations_spec.rb b/spec/features/templates/templates_upgrade_customisations_spec.rb index 715691b69c..517feef0e6 100644 --- a/spec/features/templates/templates_upgrade_customisations_spec.rb +++ b/spec/features/templates/templates_upgrade_customisations_spec.rb @@ -36,7 +36,10 @@ click_link('Customisable Templates') click_button 'Actions' - expect { click_link 'Customise' }.to change { Template.count }.by(1) + template_count = Template.count + click_link 'Customise' + expect(page).to have_current_path(%r{\A/org_admin/templates/\d+\z}) + expect(Template.count).to eq(template_count + 1) customized_template = Template.last @@ -48,6 +51,7 @@ # Publish our customisation click_button 'Actions' click_link 'Publish' + expect(page).to have_css("#template_#{funder_template.id} td:nth-child(3)", text: 'Published') expect(customized_template.reload.published?).to eql(true) # Move to the other funder Org's Templates @@ -64,11 +68,14 @@ click_link(funder_template.phases.first.title) click_link 'Add a new section' + section_count = Section.count within('#new_section_new_section') do fill_in :new_section_section_title, with: 'Cool New section title' tinymce_fill_in :new_section_section_description, with: 'New section Description' - expect { click_button('Save') }.to change { Section.count }.by(3) + click_button 'Save' end + expect(page).to have_no_css('#new_section_new_section') + expect(Section.count).to eq(section_count + 3) within("#section-#{Section.last.id}") do within('.new-question-button') do @@ -76,10 +83,13 @@ end expect(page).to have_selector('#new_question_new_question') + question_count = Question.count within('#new_question_new_question') do tinymce_fill_in :new_question_question_text, with: 'Text for this specific question' - expect { click_button('Save') }.to change { Question.count }.by(1) + click_button 'Save' end + expect(page).to have_no_css('#new_question_new_question') + expect(Question.count).to eq(question_count + 1) end new_funder_template = Template.last @@ -88,6 +98,7 @@ click_button 'Actions' click_link 'Publish changes' + expect(page).to have_text('has been published and is now available to users.') expect(new_funder_template.reload.published?).to eql(true) # Go back to the original Org... diff --git a/spec/javascripts/autoCompleteSpec.js b/spec/javascripts/autoCompleteSpec.js index 552d3f9735..ed30ced8d1 100644 --- a/spec/javascripts/autoCompleteSpec.js +++ b/spec/javascripts/autoCompleteSpec.js @@ -1,19 +1,21 @@ -import initAutoComplete from '../../app/javascript/src/utils/autoComplete'; +import { initAutocomplete } from '../../app/javascript/src/utils/autoComplete'; -describe('autoComplete test suite', () => { - beforeAll(() => fixture.setBase('./spec/javascripts/fixtures')); +describe('autocomplete', () => { + afterEach(() => $('body').empty()); - beforeEach(() => { - $('body').html(fixture.load('autoComplete.html')); - initAutoComplete(); - // Override the form submission, we are just going to validate the ariatisation of the form - $('form').trigger('submit', (e) => { e.preventDefault(); }); - }); + it('keeps the selected organisation record in the hidden field', () => { + $('body').append(` +
+ + + + +
+
+ `); - // TODO : Needs fixing, tests need to have at least one it() in a describe() + initAutocomplete('#org_name'); - afterEach(() => { - fixture.cleanup(); - $('body').html(''); + expect($('.autocomplete-result').val()).toBe('{"name":"Example University","id":42}'); }); }); diff --git a/spec/javascripts/tinymceSpec.js b/spec/javascripts/tinymceSpec.js index ad92ca6ab5..e31a9d5f1e 100644 --- a/spec/javascripts/tinymceSpec.js +++ b/spec/javascripts/tinymceSpec.js @@ -1,4 +1,4 @@ -import { Tinymce } from '../../app/javascript/src/utils/tinymce.js.erb'; +import { Tinymce } from '../../app/javascript/src/utils/tinymce'; beforeEach(() => { $('body').append(''); diff --git a/spec/models/flag_shih_tzu_compatibility_spec.rb b/spec/models/flag_shih_tzu_compatibility_spec.rb new file mode 100644 index 0000000000..799308324f --- /dev/null +++ b/spec/models/flag_shih_tzu_compatibility_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'FlagShihTzu stored values', type: :model do + it 'selects organisation types from the same stored bits' do + org = create(:org, org_type: 3) + + expect(org).to be_institution + expect(org).to be_funder + expect(Org.institution).to include(org) + expect(Org.funder).to include(org) + expect(Org.school).not_to include(org) + end + + it 'selects plan access from the same stored bits' do + role = create(:role, access: 5) + + expect(role).to be_creator + expect(role).to be_editor + expect(Role.creator).to include(role) + expect(Role.editor).to include(role) + expect(Role.reviewer).not_to include(role) + end + + it 'selects contributor roles from the same stored bits' do + contributor = create(:contributor, plan: create(:plan), roles: 3, roles_count: 0) + + expect(contributor).to be_data_curation + expect(contributor).to be_investigation + expect(Contributor.data_curation).to include(contributor) + expect(Contributor.investigation).to include(contributor) + expect(Contributor.other).not_to include(contributor) + end +end diff --git a/spec/requests/api/v1/templates_controller_spec.rb b/spec/requests/api/v1/templates_controller_spec.rb index 3cb6f5d427..61e654e7fb 100644 --- a/spec/requests/api/v1/templates_controller_spec.rb +++ b/spec/requests/api/v1/templates_controller_spec.rb @@ -11,6 +11,14 @@ end describe 'GET /api/v1/templates - index' do + it 'keeps the existing pagination header contract' do + create_list(:template, 2, :publicly_visible, :published, customization_of: nil) + get api_v1_templates_path, params: { per_page: 1 } + + expect(response).to have_http_status(:ok) + expect(response.headers.keys).not_to include('Link', 'X-Total', 'X-Per-Page') + end + it 'returns a even if there are no public templates' do get api_v1_templates_path expect(response.code).to eql('200') diff --git a/spec/requests/devise_5_views_spec.rb b/spec/requests/devise_5_views_spec.rb new file mode 100644 index 0000000000..9e5beb9b92 --- /dev/null +++ b/spec/requests/devise_5_views_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Devise 5 views', type: :request do + it 'renders the password reset form with the supported error partial' do + get edit_user_password_path, params: { reset_password_token: 'invalid' } + + expect(response).to have_http_status(:ok) + expect(response.body).to include('user_reset_password_form') + end + + it 'renders an invitation acceptance form with devise_invitable' do + invited_user = User.invite!({ email: 'invited@example.org' }, create(:user)) + + get accept_user_invitation_path, params: { invitation_token: invited_user.raw_invitation_token } + + expect(response).to have_http_status(:ok) + expect(response.body).to include('invitation_create_account_form') + end +end diff --git a/spec/requests/plan_docx_export_spec.rb b/spec/requests/plan_docx_export_spec.rb new file mode 100644 index 0000000000..4f99f1e757 --- /dev/null +++ b/spec/requests/plan_docx_export_spec.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'rails_helper' +require 'zip' + +RSpec.describe 'Plan DOCX export', type: :request do + it 'returns a readable Word document with the plan title' do + template = create(:template, phases: 1) + phase = template.phases.first + section = create(:section, phase: phase) + create(:question, section: section) + plan = create(:plan, :publicly_visible, template: template, title: 'Rubyzip compatibility plan') + + get plan_export_path(plan, format: :docx), params: { export: { question_headings: '1' } } + + expect(response).to have_http_status(:ok) + Zip::File.open_buffer(response.body) do |archive| + document = Nokogiri::XML(archive.read('word/document.xml')) + expect(document.text).to include(plan.title, 'Plan Overview') + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2904a6894d..28ca1b3921 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -98,14 +98,17 @@ # Capture the current time so that we can compare against files afterward # to clear out any downloaded/exported plans/templates @start_time = Time.now + @existing_export_files = Dir.glob(Rails.root.join('*.{csv,txt,docx,pdf}').to_s) end config.after(:context) do # Clean up any files generated by the Export/Download UI pages path = Rails.root.join('*.{csv,txt,docx,pdf}').to_s Dir.glob(path).each do |file| + next if @existing_export_files.include?(file) || File.ctime(file) <= @start_time + puts "Deleting test file generated by Download/Export: #{file}" - File.delete(file) if File.ctime(file) > @start_time + File.delete(file) end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index c6e8ee618c..e398a29b47 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -11,6 +11,7 @@ options.add_argument('--window-size=1920,1080') options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') + options.binary = ENV['CHROME_BIN'] if ENV['CHROME_BIN'] # Create a new Selenium driver with the customised options Capybara::Selenium::Driver.new(app, browser: :chrome, options: options) end diff --git a/spec/support/helpers/sessions_helper.rb b/spec/support/helpers/sessions_helper.rb index 3fa530d4e9..339e1f27fd 100644 --- a/spec/support/helpers/sessions_helper.rb +++ b/spec/support/helpers/sessions_helper.rb @@ -20,5 +20,6 @@ def sign_in_as_user(user) fill_in 'Password', with: user.password.presence || 'password' click_button 'Sign in' end + expect(page).to have_css("a[href='#{destroy_user_session_path}']", visible: :all) end end diff --git a/yarn.lock b/yarn.lock index ec52161252..9f5646f477 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1494,6 +1494,13 @@ babel-loader@^9.1.2: find-cache-dir "^4.0.0" schema-utils "^4.0.0" +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -3373,7 +3380,7 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.2, object.assign@^4.1.7: +object.assign@^4.1.0, object.assign@^4.1.2, object.assign@^4.1.7: version "4.1.7" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==