From 30958bdba3c0402fc4a575f3eba192e605521bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 17 Jan 2023 15:19:27 +0100 Subject: [PATCH 01/26] WIP upgrade --- .ruby-version | 2 +- Gemfile | 41 +- Gemfile.lock | 662 +++++++++--------- app/assets/stylesheets/application.scss | 1 - app/controllers/api/v1/users_controller.rb | 0 app/models/formula_mapping.rb | 6 +- app/serializers/v2/activity_serializer.rb | 2 +- app/services/map_project_to_orbf_project.rb | 10 +- app/views/layouts/application.html.erb | 2 + app/views/layouts/private.html.erb | 2 + bin/rails | 6 +- bin/rake | 4 +- bin/setup | 15 +- config/application.rb | 3 +- config/environments/development.rb | 19 +- config/environments/test.rb | 2 +- .../new_framework_defaults_5_2.rb | 4 - config/initializers/rails_admin.rb | 1 + ..._to_active_storage_blobs.active_storage.rb | 22 + ..._storage_variant_records.active_storage.rb | 27 + ...e_storage_blobs_checksum.active_storage.rb | 8 + db/schema.rb | 151 ++-- spec/factories/projects.rb | 2 +- spec/models/project_spec.rb | 7 +- 24 files changed, 549 insertions(+), 450 deletions(-) delete mode 100644 app/controllers/api/v1/users_controller.rb create mode 100644 db/migrate/20230117110948_add_service_name_to_active_storage_blobs.active_storage.rb create mode 100644 db/migrate/20230117110949_create_active_storage_variant_records.active_storage.rb create mode 100644 db/migrate/20230117110950_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb diff --git a/.ruby-version b/.ruby-version index ecd7ee50..944880fa 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.5.8 +3.2.0 diff --git a/Gemfile b/Gemfile index 9aaaa365..61afafef 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source "https://rubygems.org" -ruby "2.5.8" +ruby "3.2.0" git_source(:github) do |repo_name| repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") @@ -11,30 +11,30 @@ end ## Infrastructure +gem "activerecord-nulldb-adapter" gem "dhis2", github: "BLSQ/dhis2", branch: "legacy-v2" -gem "paper_trail", "~> 10.1.0" -gem "paper_trail-association_tracking", "~> 1.0.0" -gem "pg", "~> 0.18" +gem "paper_trail", "~> 13.0.0" +gem "paper_trail-association_tracking", "~> 2.2.1" +gem "pg", "~> 1.4.5" gem "puma", "~> 4.3" gem "rack", ">= 2.0.6" -gem "rails", "~> 5.2", "< 5.3" -gem "activerecord-nulldb-adapter" -gem "rails_admin", "~> 1.4.2" +gem "rails", "~> 7.0.4" +gem "rails_admin", "~> 3.1.1" gem "sidekiq", "< 6" gem "sidekiq-throttled", "~> 0.9.0" ## Tooling -gem "bootsnap", "~> 1.3.2" +gem "bootsnap", "~> 1.15.0" gem "figaro" -gem "lograge", "~> 0.10.0" +gem "lograge", "~> 0.12.0" gem "sentry-raven", "~> 2.7.4" # Feature flipper is the act of enabling/disabling features in your app... # [flipper](https://github.com/jnunemaker/flipper) -gem "flipper", "~> 0.16.1" -gem "flipper-active_record", "~> 0.16.1" -gem "flipper-ui", "~> 0.16.1" +gem "flipper", "~> 0.26.0" +gem "flipper-active_record", "~> 0.26.0" +gem "flipper-ui", "~> 0.26.0" ## Frontend and asset related @@ -45,17 +45,16 @@ gem "coffee-rails", "~> 4.2" gem "jquery-rails", "~> 4.3.3" gem "jquery-ui-rails", "~> 5.0.5" gem "rails-jquery-autocomplete" -gem "sassc-rails", "~> 2.0.0" +gem "sassc-rails", "~> 2.1.2" gem "simple_form" gem "sprockets", "~> 3.7.2" gem "turbolinks", "~> 5" gem "uglifier", ">= 1.3.0" - ## Authentication # Flexible authentication solution for Rails with Warden # [devise](https://github.com/plataformatec/devise) -gem "devise", "~> 4.7.1" +gem "devise", "~> 4.8.1" # Log in as another user in Rails # [pretender](https://github.com/ankane/pretender) @@ -86,7 +85,7 @@ else # We're using both of them against the latest master. We should set # them to versions when they become more stable gem "hesabu", github: "BLSQ/hesabu" - gem "orbf-rules_engine", github: "BLSQ/orbf-rules_engine", branch: "master" + gem "orbf-rules_engine", github: "BLSQ/orbf-rules_engine", branch: "ruby-3.2.0-test" # TODO: back to master end # Like a modern code version of the mythical beast with 100 serpent hea... # [typhoeus](https://github.com/typhoeus/typhoeus) @@ -96,17 +95,17 @@ group :development, :test do gem "byebug", platform: :mri # Use pry instead of irb: http://pryrepl.org - gem "pry", "~> 0.12.2" + gem "pry", "~> 0.14.2" gem "pry-rails", "~> 0.3.9" gem "database_cleaner" - gem "factory_bot_rails", "~> 4.11.1" + gem "factory_bot_rails", "~> 6.2.0" gem "faker" gem "immigrant" gem "rails-controller-testing" gem "rest-client-logger", github: "uswitch/rest-client-logger" gem "rspec-its" - gem "rspec-rails", "~> 3.0" + gem "rspec-rails", "~> 6.0.1" gem "ruby-prof" gem "shoulda-matchers", require: false @@ -117,7 +116,7 @@ group :development, :test do end group :development do - gem "annotate", "~> 2.7.4" + gem "annotate", "~> 3.2.0" gem "flamegraph" gem "listen", "~> 3.0.5" gem "memory_profiler" @@ -127,7 +126,7 @@ group :development do gem "pronto-simplecov", require: false gem "rack-mini-profiler" gem "rubocop", require: false - gem 'rubocop-rails', require: false + gem "rubocop-rails", require: false gem "spring" gem "spring-watcher-listen", "~> 2.0.0" gem "stackprof" diff --git a/Gemfile.lock b/Gemfile.lock index cfa99cae..36c0e778 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,13 +14,13 @@ GIT GIT remote: https://github.com/BLSQ/orbf-rules_engine.git - revision: 89c59c18608029348a0d2643e1d32c162656fe5d - branch: master + revision: c4676c756e1c411483dbd19285c825fe276e216e + branch: ruby-3.2.0-test specs: orbf-rules_engine (0.1.0) activesupport colorize - dentaku (= 3.1.0) + dentaku (= 3.5.1) descriptive_statistics dhis2 (= 2.3.8) hesabu @@ -36,96 +36,123 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (5.2.6.2) - actionpack (= 5.2.6.2) + actioncable (7.0.4) + actionpack (= 7.0.4) + activesupport (= 7.0.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.6.2) - actionpack (= 5.2.6.2) - actionview (= 5.2.6.2) - activejob (= 5.2.6.2) + actionmailbox (7.0.4) + actionpack (= 7.0.4) + activejob (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.0.4) + actionpack (= 7.0.4) + actionview (= 7.0.4) + activejob (= 7.0.4) + activesupport (= 7.0.4) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (5.2.6.2) - actionview (= 5.2.6.2) - activesupport (= 5.2.6.2) - rack (~> 2.0, >= 2.0.8) + actionpack (7.0.4) + actionview (= 7.0.4) + activesupport (= 7.0.4) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.6.2) - activesupport (= 5.2.6.2) + rails-html-sanitizer (~> 1.0, >= 1.2.0) + actiontext (7.0.4) + actionpack (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.0.4) + activesupport (= 7.0.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.6.2) - activesupport (= 5.2.6.2) + rails-html-sanitizer (~> 1.1, >= 1.2.0) + activejob (7.0.4) + activesupport (= 7.0.4) globalid (>= 0.3.6) - activemodel (5.2.6.2) - activesupport (= 5.2.6.2) - activerecord (5.2.6.2) - activemodel (= 5.2.6.2) - activesupport (= 5.2.6.2) - arel (>= 9.0) - activerecord-nulldb-adapter (0.7.0) - activerecord (>= 5.2.0, < 6.3) - activestorage (5.2.6.2) - actionpack (= 5.2.6.2) - activerecord (= 5.2.6.2) - marcel (~> 1.0.0) - activesupport (5.2.6.2) + activemodel (7.0.4) + activesupport (= 7.0.4) + activemodel-serializers-xml (1.0.2) + activemodel (> 5.x) + activesupport (> 5.x) + builder (~> 3.1) + activerecord (7.0.4) + activemodel (= 7.0.4) + activesupport (= 7.0.4) + activerecord-nulldb-adapter (0.8.0) + activerecord (>= 5.2.0, < 7.1) + activestorage (7.0.4) + actionpack (= 7.0.4) + activejob (= 7.0.4) + activerecord (= 7.0.4) + activesupport (= 7.0.4) + marcel (~> 1.0) + mini_mime (>= 1.1.0) + activesupport (7.0.4) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - annotate (2.7.4) - activerecord (>= 3.2, < 6.0) - rake (>= 10.4, < 13.0) - arel (9.0.0) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) + annotate (3.2.0) + activerecord (>= 3.2, < 8.0) + rake (>= 10.4, < 14.0) ast (2.4.2) - autoprefixer-rails (9.4.9) - execjs - aws-eventstream (1.1.0) - aws-partitions (1.329.0) - aws-sdk-core (3.99.2) + autoprefixer-rails (10.4.7.0) + execjs (~> 2) + aws-eventstream (1.2.0) + aws-partitions (1.693.0) + aws-sdk-core (3.168.4) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.239.0) - aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.34.1) - aws-sdk-core (~> 3, >= 3.99.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.61.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.68.1) - aws-sdk-core (~> 3, >= 3.99.0) + aws-sdk-s3 (1.117.2) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.1) - aws-sigv4 (1.1.4) - aws-eventstream (~> 1.0, >= 1.0.2) - bcrypt (3.1.13) - bindex (0.5.0) - bootsnap (1.3.2) - msgpack (~> 1.0) - bootstrap-datepicker-rails (1.8.0.1) + aws-sigv4 (~> 1.4) + aws-sigv4 (1.5.2) + aws-eventstream (~> 1, >= 1.0.2) + bcrypt (3.1.18) + bindex (0.8.1) + bootsnap (1.15.0) + msgpack (~> 1.2) + bootstrap-datepicker-rails (1.9.0.1) railties (>= 3.0) bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) sassc (>= 2.0.0) builder (3.2.4) - byebug (10.0.2) - capybara (3.33.0) + byebug (11.1.3) + capybara (3.38.0) addressable + matrix mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) - regexp_parser (~> 1.5) + regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - childprocess (3.0.0) - cocoon (1.2.12) - coderay (1.1.2) + cocoon (1.2.15) + coderay (1.1.3) coffee-rails (4.2.2) coffee-script (>= 2.2.0) railties (>= 4.0.0) @@ -135,87 +162,90 @@ GEM coffee-script-source (1.12.2) colorize (0.8.1) concurrent-ruby (1.1.10) - connection_pool (2.2.5) - crack (0.4.3) - safe_yaml (~> 1.0.0) + connection_pool (2.3.0) + crack (0.4.5) + rexml crass (1.0.6) - database_cleaner (1.7.0) - deep_cloneable (2.3.2) - activerecord (>= 3.1.0, < 6) - dentaku (3.1.0) + database_cleaner (2.0.1) + database_cleaner-active_record (~> 2.0.0) + database_cleaner-active_record (2.0.1) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) + date (3.3.3) + deep_cloneable (3.2.0) + activerecord (>= 3.1.0, < 8) + dentaku (3.5.1) + concurrent-ruby descriptive_statistics (2.5.1) - devise (4.7.1) + devise (4.8.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.3) + diff-lcs (1.5.0) differ (0.1.2) - docile (1.1.5) + docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - erubi (1.10.0) - erubis (2.7.0) - ethon (0.12.0) - ffi (>= 1.3.0) - execjs (2.7.0) - factory_bot (4.11.1) - activesupport (>= 3.0.0) - factory_bot_rails (4.11.1) - factory_bot (~> 4.11.1) - railties (>= 3.0.0) - faker (1.9.1) - i18n (>= 0.7) - faraday (0.17.4) + erubi (1.12.0) + ethon (0.16.0) + ffi (>= 1.15.0) + execjs (2.8.1) + factory_bot (6.2.1) + activesupport (>= 5.0.0) + factory_bot_rails (6.2.0) + factory_bot (~> 6.2.0) + railties (>= 5.0.0) + faker (3.1.0) + i18n (>= 1.8.11, < 2) + faraday (0.17.6) multipart-post (>= 1.2, < 3) fast_jsonapi (1.5) activesupport (>= 4.2) - ffi (1.9.25) - figaro (1.1.1) - thor (~> 0.14) + ffi (1.15.5) + figaro (1.2.0) + thor (>= 0.14.0, < 2) flamegraph (0.9.5) - flay (2.12.0) - erubis (~> 2.7.0) + flay (2.13.0) + erubi (~> 1.10) path_expander (~> 1.0) ruby_parser (~> 3.0) sexp_processor (~> 4.0) - flipper (0.16.1) - flipper-active_record (0.16.1) - activerecord (>= 3.2, < 6) - flipper (~> 0.16.1) - flipper-ui (0.16.1) - erubis (~> 2.7.0) - flipper (~> 0.16.1) + flipper (0.26.0) + concurrent-ruby (< 2) + flipper-active_record (0.26.0) + activerecord (>= 4.2, < 8) + flipper (~> 0.26.0) + flipper-ui (0.26.0) + erubi (>= 1.0.0, < 2.0.0) + flipper (~> 0.26.0) rack (>= 1.4, < 3) - rack-protection (>= 1.5.3, < 2.1.0) - font-awesome-rails (4.7.0.7) - railties (>= 3.2, < 7) - gitlab (4.18.0) - httparty (~> 0.18) + rack-protection (>= 1.5.3, <= 4.0.0) + sanitize (< 7) + gitlab (4.19.0) + httparty (~> 0.20) terminal-table (>= 1.5.1) globalid (1.0.0) activesupport (>= 5.0) - haml (5.2.1) - temple (>= 0.8.0) - tilt - hashdiff (0.3.7) + hashdiff (1.0.1) heroku-deflater (0.6.3) rack (>= 1.4.5) http-accept (1.7.0) http-cookie (1.0.5) domain_name (~> 0.5) - httparty (0.20.0) - mime-types (~> 3.0) + httparty (0.21.0) + mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) i18n (1.12.0) concurrent-ruby (~> 1.0) immigrant (0.3.6) activerecord (>= 3.0) - jbuilder (2.8.0) - activesupport (>= 4.2.0) - multi_json (>= 1.2) - jmespath (1.4.0) + jbuilder (2.11.5) + actionview (>= 5.0.0) + activesupport (>= 5.0.0) + jmespath (1.6.2) jquery-rails (4.3.5) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) @@ -224,157 +254,159 @@ GEM railties (>= 3.2.16) json (2.3.0) json-diff (0.4.1) - kaminari (1.2.1) + kaminari (1.2.2) activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.1) - kaminari-activerecord (= 1.2.1) - kaminari-core (= 1.2.1) - kaminari-actionview (1.2.1) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) actionview - kaminari-core (= 1.2.1) - kaminari-activerecord (1.2.1) + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) activerecord - kaminari-core (= 1.2.1) - kaminari-core (1.2.1) + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - lograge (0.10.0) + lograge (0.12.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.14.0) + loofah (2.19.1) crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.7.1) + mail (2.8.0.1) mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp marcel (1.0.2) - memory_profiler (0.9.12) - method_source (0.9.2) + matrix (0.4.2) + memory_profiler (1.0.1) + method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) mime-types-data (3.2022.0105) mini_mime (1.1.2) - mini_portile2 (2.6.1) - minitest (5.15.0) - msgpack (1.3.3) - multi_json (1.13.1) + minitest (5.17.0) + msgpack (1.6.0) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) naturalsort (1.2.0) nested_form (0.3.2) + net-imap (0.3.4) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.1) + timeout + net-smtp (0.3.3) + net-protocol netrc (0.11.0) nio4r (2.5.8) - nokogiri (1.12.5) - mini_portile2 (~> 2.6.1) + nokogiri (1.14.0-x86_64-linux) racc (~> 1.4) octokit (4.22.0) faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) orm_adapter (0.5.0) - paper_trail (10.1.0) - activerecord (>= 4.2, < 6.0) + paper_trail (13.0.0) + activerecord (>= 5.2) request_store (~> 1.1) - paper_trail-association_tracking (1.0.0) - parallel (1.21.0) - parser (3.1.0.0) + paper_trail-association_tracking (2.2.1) + paper_trail (>= 12.0) + parallel (1.22.1) + parser (3.2.0.0) ast (~> 2.4.1) - path_expander (1.0.3) - pg (0.21.0) + path_expander (1.1.1) + pg (1.4.5) pretender (0.3.4) actionpack (>= 4.2) - pronto (0.9.5) - gitlab (~> 4.0, >= 4.0.0) - httparty (>= 0.13.7) - octokit (~> 4.7, >= 4.7.0) - rainbow (~> 2.1) - rugged (~> 0.24, >= 0.23.0) - thor (~> 0.19.0) - pronto-flay (0.9.0) + pronto (0.11.1) + gitlab (>= 4.4.0, < 5.0) + httparty (>= 0.13.7, < 1.0) + octokit (>= 4.7.0, < 7.0) + rainbow (>= 2.2, < 4.0) + rexml (>= 3.2.5, < 4.0) + rugged (>= 0.23.0, < 2.0) + thor (>= 0.20.3, < 2.0) + pronto-flay (0.11.1) flay (~> 2.8) - pronto (~> 0.9.0) - pronto-rubocop (0.9.1) - pronto (~> 0.9.0) - rubocop (~> 0.50, >= 0.49.1) - pronto-simplecov (0.1.1) - pronto (~> 0.9.0) + pronto (~> 0.11.0) + pronto-rubocop (0.11.4) + pronto (~> 0.11.0) + rubocop (>= 0.63.1, < 2.0) + pronto-simplecov (0.11.0) + pronto (~> 0.11.0) simplecov - pry (0.12.2) - coderay (~> 1.1.0) - method_source (~> 0.9.0) + pry (0.14.2) + coderay (~> 1.1) + method_source (~> 1.0) pry-rails (0.3.9) pry (>= 0.10.4) - public_suffix (4.0.6) + public_suffix (5.0.1) puma (4.3.12) nio4r (~> 2.0) - racc (1.6.0) - rack (2.2.3) - rack-mini-profiler (1.0.1) + racc (1.6.2) + rack (2.2.6) + rack-mini-profiler (3.0.0) rack (>= 1.2.0) - rack-pjax (1.1.0) - nokogiri (~> 1.5) - rack (>= 1.1) - rack-protection (2.0.8.1) + rack-protection (3.0.5) rack - rack-test (1.1.0) - rack (>= 1.0, < 3) - rails (5.2.6.2) - actioncable (= 5.2.6.2) - actionmailer (= 5.2.6.2) - actionpack (= 5.2.6.2) - actionview (= 5.2.6.2) - activejob (= 5.2.6.2) - activemodel (= 5.2.6.2) - activerecord (= 5.2.6.2) - activestorage (= 5.2.6.2) - activesupport (= 5.2.6.2) - bundler (>= 1.3.0) - railties (= 5.2.6.2) - sprockets-rails (>= 2.0.0) - rails-controller-testing (1.0.4) - actionpack (>= 5.0.1.x) - actionview (>= 5.0.1.x) - activesupport (>= 5.0.1.x) + rack-test (2.0.2) + rack (>= 1.3) + rails (7.0.4) + actioncable (= 7.0.4) + actionmailbox (= 7.0.4) + actionmailer (= 7.0.4) + actionpack (= 7.0.4) + actiontext (= 7.0.4) + actionview (= 7.0.4) + activejob (= 7.0.4) + activemodel (= 7.0.4) + activerecord (= 7.0.4) + activestorage (= 7.0.4) + activesupport (= 7.0.4) + bundler (>= 1.15.0) + railties (= 7.0.4) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.2) - loofah (~> 2.3) + rails-html-sanitizer (1.4.4) + loofah (~> 2.19, >= 2.19.1) rails-jquery-autocomplete (1.0.5) rails (>= 3.2) - rails_admin (1.4.3) - builder (~> 3.1) - coffee-rails (~> 4.0) - font-awesome-rails (>= 3.0, < 5) - haml (>= 4.0, < 6) - jquery-rails (>= 3.0, < 5) - jquery-ui-rails (>= 5.0, < 7) + rails_admin (3.1.1) + activemodel-serializers-xml (>= 1.0) kaminari (>= 0.14, < 2.0) nested_form (~> 0.3) - rack-pjax (>= 0.7) - rails (>= 4.0, < 6) - remotipart (~> 1.3) - sass-rails (>= 4.0, < 6) - railties (5.2.6.2) - actionpack (= 5.2.6.2) - activesupport (= 5.2.6.2) + rails (>= 6.0, < 8) + turbo-rails (~> 1.0) + railties (7.0.4) + actionpack (= 7.0.4) + activesupport (= 7.0.4) method_source - rake (>= 0.8.7) - thor (>= 0.19.0, < 2.0) - rainbow (2.2.2) - rake - rake (12.3.3) - rb-fsevent (0.10.4) + rake (>= 12.2) + thor (~> 1.0) + zeitwerk (~> 2.5) + rainbow (3.1.1) + rake (13.0.6) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) redis (4.5.1) redis-prescription (1.0.0) - regexp_parser (1.7.1) - remotipart (1.4.4) - request_store (1.4.1) + regexp_parser (2.6.1) + request_store (1.5.1) rack (>= 1.4) - responders (3.0.0) + responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) rest-client (2.1.0) @@ -383,65 +415,57 @@ GEM mime-types (>= 1.16, < 4.0) netrc (~> 0.8) rexml (3.2.5) - rspec-core (3.8.0) - rspec-support (~> 3.8.0) - rspec-expectations (3.8.2) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-its (1.2.0) + rspec-support (~> 3.12.0) + rspec-its (1.3.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.8.0) + rspec-mocks (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-rails (3.8.1) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.8.0) - rspec-expectations (~> 3.8.0) - rspec-mocks (~> 3.8.0) - rspec-support (~> 3.8.0) - rspec-sidekiq (3.0.3) + rspec-support (~> 3.12.0) + rspec-rails (6.0.1) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.11) + rspec-expectations (~> 3.11) + rspec-mocks (~> 3.11) + rspec-support (~> 3.11) + rspec-sidekiq (3.1.0) rspec-core (~> 3.0, >= 3.0.0) sidekiq (>= 2.4.0) - rspec-support (3.8.0) - rubocop (0.92.0) + rspec-support (3.12.0) + rubocop (1.43.0) + json (~> 2.3) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.7) - rexml - rubocop-ast (>= 0.5.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.24.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.15.1) - parser (>= 3.0.1.1) - rubocop-rails (2.3.2) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.24.1) + parser (>= 3.1.1.0) + rubocop-rails (2.17.4) + activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.72.0) - ruby-prof (0.17.0) + rubocop (>= 1.33.0, < 2.0) + ruby-prof (1.4.5) ruby-progressbar (1.11.0) - ruby_parser (3.12.0) - sexp_processor (~> 4.9) + ruby_parser (3.19.2) + sexp_processor (~> 4.16) rubyzip (1.3.0) - rugged (0.99.0) - safe_yaml (1.0.4) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sass-rails (5.1.0) - railties (>= 5.2.0) - sass (~> 3.1) - sprockets (>= 2.8, < 4.0) - sprockets-rails (>= 2.0, < 4.0) - tilt (>= 1.1, < 3) - sassc (2.0.0) - ffi (~> 1.9.6) - rake - sassc-rails (2.0.0) + rugged (1.5.0.1) + sanitize (6.0.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) railties (>= 4.0.0) sassc (>= 2.0) sprockets (> 3.0) @@ -450,14 +474,15 @@ GEM sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) - selenium-webdriver (3.142.7) - childprocess (>= 0.5, < 4.0) - rubyzip (>= 1.2.2) + selenium-webdriver (4.7.1) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) sentry-raven (2.7.4) faraday (>= 0.7.6, < 1.0) - sexp_processor (4.11.0) - shoulda-matchers (3.1.2) - activesupport (>= 4.0.0) + sexp_processor (4.16.1) + shoulda-matchers (5.3.0) + activesupport (>= 5.2.0) sidekiq (5.2.10) connection_pool (~> 2.2, >= 2.2.2) rack (~> 2.0) @@ -467,16 +492,16 @@ GEM concurrent-ruby redis-prescription sidekiq - simple_form (5.0.0) - actionpack (>= 5.0) - activemodel (>= 5.0) - simplecov (0.13.0) - docile (~> 1.1.0) - json (>= 1.8, < 3) - simplecov-html (~> 0.10.0) - simplecov-html (0.10.2) - spring (2.0.2) - activesupport (>= 4.2) + simple_form (5.1.0) + actionpack (>= 5.2) + activemodel (>= 5.2) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.12.3) + simplecov_json_formatter (0.1.4) + spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) @@ -487,51 +512,56 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - stackprof (0.2.12) - temple (0.8.2) + stackprof (0.2.23) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - thor (0.19.4) - thread_safe (0.3.6) - tilt (2.0.10) - turbolinks (5.2.0) + thor (1.2.1) + tilt (2.0.11) + timeout (0.3.1) + turbo-rails (1.3.2) + actionpack (>= 6.0.0) + activejob (>= 6.0.0) + railties (>= 6.0.0) + turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) typhoeus (1.3.1) ethon (>= 0.9.0) - tzinfo (1.2.10) - thread_safe (~> 0.1) - uglifier (4.1.20) + tzinfo (2.0.5) + concurrent-ruby (~> 1.0) + uglifier (4.2.0) execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.8.2) - unicode-display_width (1.8.0) - warden (1.2.8) - rack (>= 2.0.6) - web-console (3.7.0) - actionview (>= 5.0) - activemodel (>= 5.0) + unicode-display_width (2.4.2) + warden (1.2.9) + rack (>= 2.0.9) + web-console (4.2.0) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) bindex (>= 0.4.0) - railties (>= 5.0) - webmock (3.4.2) - addressable (>= 2.3.6) + railties (>= 6.0.0) + webmock (3.18.1) + addressable (>= 2.8.0) crack (>= 0.3.2) - hashdiff + hashdiff (>= 0.4.0, < 2.0.0) + websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) + zeitwerk (2.6.6) PLATFORMS - ruby + x86_64-linux DEPENDENCIES activerecord-nulldb-adapter - annotate (~> 2.7.4) + annotate (~> 3.2.0) aws-sdk-s3 (~> 1.48) - bootsnap (~> 1.3.2) + bootsnap (~> 1.15.0) bootstrap-datepicker-rails bootstrap-sass (~> 3.4.1) byebug @@ -541,17 +571,17 @@ DEPENDENCIES database_cleaner deep_cloneable dentaku - devise (~> 4.7.1) + devise (~> 4.8.1) dhis2! differ - factory_bot_rails (~> 4.11.1) + factory_bot_rails (~> 6.2.0) faker fast_jsonapi figaro flamegraph - flipper (~> 0.16.1) - flipper-active_record (~> 0.16.1) - flipper-ui (~> 0.16.1) + flipper (~> 0.26.0) + flipper-active_record (~> 0.26.0) + flipper-ui (~> 0.26.0) hashdiff heroku-deflater hesabu! @@ -562,37 +592,37 @@ DEPENDENCIES json (= 2.3.0) json-diff (~> 0.4.1) listen (~> 3.0.5) - lograge (~> 0.10.0) + lograge (~> 0.12.0) loofah (>= 2.2.3) memory_profiler naturalsort orbf-rules_engine! - paper_trail (~> 10.1.0) - paper_trail-association_tracking (~> 1.0.0) - pg (~> 0.18) + paper_trail (~> 13.0.0) + paper_trail-association_tracking (~> 2.2.1) + pg (~> 1.4.5) pretender (~> 0.3.4) pronto pronto-flay pronto-rubocop pronto-simplecov - pry (~> 0.12.2) + pry (~> 0.14.2) pry-rails (~> 0.3.9) puma (~> 4.3) rack (>= 2.0.6) rack-mini-profiler - rails (~> 5.2, < 5.3) + rails (~> 7.0.4) rails-controller-testing rails-jquery-autocomplete - rails_admin (~> 1.4.2) + rails_admin (~> 3.1.1) rest-client-logger! rspec-its - rspec-rails (~> 3.0) + rspec-rails (~> 6.0.1) rspec-sidekiq rubocop rubocop-rails ruby-prof rubyzip (~> 1.3.0) - sassc-rails (~> 2.0.0) + sassc-rails (~> 2.1.2) selenium-webdriver sentry-raven (~> 2.7.4) shoulda-matchers @@ -612,7 +642,7 @@ DEPENDENCIES webmock RUBY VERSION - ruby 2.5.8p224 + ruby 3.2.0p0 BUNDLED WITH - 2.3.5 + 2.4.4 diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index f55f30e0..d3d30b24 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -14,7 +14,6 @@ // "bootstrap-sprockets" must be imported before "bootstrap" and "bootstrap/variables" @import "bootstrap-sprockets"; @import "bootstrap"; -@import "font-awesome"; @import "jquery-ui/core"; @import "jquery-ui/menu"; @import "jquery-ui/theme"; diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/app/models/formula_mapping.rb b/app/models/formula_mapping.rb index 0cc5c73a..031da4b0 100644 --- a/app/models/formula_mapping.rb +++ b/app/models/formula_mapping.rb @@ -36,7 +36,9 @@ class FormulaMapping < ApplicationRecord belongs_to :formula, inverse_of: :formula_mappings belongs_to :activity, optional: true - validates :activity, presence: true, if: -> { [Rule::RULE_TYPE_ACTIVITY, Rule::RULE_TYPE_ZONE_ACTIVITY].include?(kind) } + validates :activity, presence: true, if: lambda { + [Rule::RULE_TYPE_ACTIVITY, Rule::RULE_TYPE_ZONE_ACTIVITY].include?(kind) + } def project formula.rule.project @@ -55,7 +57,7 @@ def names short: format(naming_patterns[:short], substitutions).strip, code: format(naming_patterns[:code], substitutions).strip } - Dhis2Name.new(dhis2_name) + Dhis2Name.new(**dhis2_name) end def data_element_ext_ref diff --git a/app/serializers/v2/activity_serializer.rb b/app/serializers/v2/activity_serializer.rb index d34a9c57..e487ccf7 100644 --- a/app/serializers/v2/activity_serializer.rb +++ b/app/serializers/v2/activity_serializer.rb @@ -10,7 +10,7 @@ class V2::ActivitySerializer < V2::BaseSerializer attributes :updated_at attributes :stable_id - has_many :input_mappings, serializer: ActivityStateSerializer do |activity| + has_many :input_mappings, serializer: ::V2::ActivityStateSerializer do |activity| activity.activity_states end diff --git a/app/services/map_project_to_orbf_project.rb b/app/services/map_project_to_orbf_project.rb index 793f7e1f..c95073fe 100644 --- a/app/services/map_project_to_orbf_project.rb +++ b/app/services/map_project_to_orbf_project.rb @@ -27,7 +27,8 @@ def map private - attr_reader :project, :packages, :dhis2_indicators_by_id, :data_elements_by_id, :category_combos_by_id + attr_reader :project, :packages, :dhis2_indicators_by_id, :data_elements_by_id, + :category_combos_by_id PACKAGE_KINDS = { "multi-groupset" => "subcontract" @@ -129,7 +130,7 @@ def map_formulas(formulas) formula.code, formula.expression, formula.description, - map_formula_mappings(formula) + **map_formula_mappings(formula) ) end end @@ -137,7 +138,10 @@ def map_formulas(formulas) def map_formula_mappings(formula) formula_mappings = {} formula_mappings[:frequency] = formula.frequency if formula.frequency - formula_mappings[:exportable_formula_code] = formula.exportable_formula_code if formula.exportable_formula_code + if formula.exportable_formula_code + formula_mappings[:exportable_formula_code] = +formula.exportable_formula_code + end if formula.rule.activity_related_kind? && formula.formula_mappings.any? formula_mappings[:activity_mappings] = formula.formula_mappings .each_with_object({}) do |mapping, hash| diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 5b19c485..29432d26 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -3,6 +3,8 @@ Open RBF 2.0 <%= csrf_meta_tags %> + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> diff --git a/app/views/layouts/private.html.erb b/app/views/layouts/private.html.erb index 4f836be3..66dc66a3 100644 --- a/app/views/layouts/private.html.erb +++ b/app/views/layouts/private.html.erb @@ -3,6 +3,8 @@ Open RBF 2.0 <%= csrf_meta_tags %> + + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <% if log_rocket_token = ENV["LOG_ROCKET_TOKEN"] %> diff --git a/bin/rails b/bin/rails index 07396602..efc03774 100755 --- a/bin/rails +++ b/bin/rails @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -APP_PATH = File.expand_path('../config/application', __dir__) -require_relative '../config/boot' -require 'rails/commands' +APP_PATH = File.expand_path("../config/application", __dir__) +require_relative "../config/boot" +require "rails/commands" diff --git a/bin/rake b/bin/rake index 17240489..4fbf10b9 100755 --- a/bin/rake +++ b/bin/rake @@ -1,4 +1,4 @@ #!/usr/bin/env ruby -require_relative '../config/boot' -require 'rake' +require_relative "../config/boot" +require "rake" Rake.application.run diff --git a/bin/setup b/bin/setup index 4ccb4fac..ec47b79b 100755 --- a/bin/setup +++ b/bin/setup @@ -1,17 +1,16 @@ #!/usr/bin/env ruby -require "pathname" require "fileutils" -include FileUtils # path to your application root. -APP_ROOT = Pathname.new File.expand_path("../../", __FILE__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") end -chdir APP_ROOT do - # This script is a starting point to setup your application. +FileUtils.chdir APP_ROOT do + # This script is a way to set up or update your development environment automatically. + # This script is idempotent, so that you can run it at any time and get an expectable outcome. # Add necessary setup steps to this file. puts "== Installing dependencies ==" @@ -19,12 +18,12 @@ chdir APP_ROOT do system("bundle check") || system!("bundle install") # puts "\n== Copying sample files ==" - # unless File.exist?('config/database.yml') - # cp 'config/database.yml.sample', 'config/database.yml' + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" # end puts "\n== Preparing database ==" - system! "bin/rails db:setup" + system! "bin/rails db:prepare" puts "\n== Removing old logs and tempfiles ==" system! "bin/rails log:clear tmp:clear" diff --git a/config/application.rb b/config/application.rb index a7f21da5..8b3ddea4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -20,7 +20,8 @@ module Scorpio class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 5.1 + config.load_defaults 7.0 + config.autoloader = :zeitwerk # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/config/environments/development.rb b/config/environments/development.rb index 77f5b2c7..093528a5 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -27,7 +27,7 @@ end # Store uploaded files on the local file system (see config/storage.yml for options) - config.active_storage.service = ENV.fetch("RAILS_ACTIVE_STORAGE", 'amazon') + config.active_storage.service = ENV.fetch("RAILS_ACTIVE_STORAGE", "amazon") # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false @@ -61,24 +61,29 @@ config.action_mailer.default_url_options = { host: "localhost", port: 3000 } config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: "localhost", port: 1025 } + config.autoload_paths += %W[#{config.root}/app/services] ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::Dhis2ValuesPrinter, :print) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::Solver, :solve!) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::FetchAndSolve, :call) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::GroupOrgunitsResolver, :call) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ResolveArguments, :call) - ::Rack::MiniProfiler.profile_singleton_method(Orbf::RulesEngine::ActivityVariablesBuilder, :to_variables) - #::Rack::MiniProfiler.profile_singleton_method(Orbf::RulesEngine::PeriodIterator, :periods) + ::Rack::MiniProfiler.profile_singleton_method(Orbf::RulesEngine::ActivityVariablesBuilder, + :to_variables) + # ::Rack::MiniProfiler.profile_singleton_method(Orbf::RulesEngine::PeriodIterator, :periods) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::SolverFactory, :new_solver) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::DecisionVariablesBuilder, :to_variables) - ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ActivityConstantVariablesBuilder, :to_variables) - ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ActivityFormulaVariablesBuilder, :to_variables) + ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ActivityConstantVariablesBuilder, + :to_variables) + ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ActivityFormulaVariablesBuilder, + :to_variables) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::PackageVariablesBuilder, :to_variables) ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::ZoneFormulaVariablesBuilder, :to_variables) - ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::PaymentFormulaVariablesBuilder, :to_variables) + ::Rack::MiniProfiler.profile_method(Orbf::RulesEngine::PaymentFormulaVariablesBuilder, + :to_variables) ::Rack::MiniProfiler.profile_method(ActionView::Template, :render) ::Rack::MiniProfiler.profile_method(Hesabu::Solver, :solve!) - ::Rack::MiniProfiler.profile_method(Invoicing::InvoiceEntity, :call) + # ::Rack::MiniProfiler.profile_method(Invoicing::InvoiceEntity, :call) end diff --git a/config/environments/test.rb b/config/environments/test.rb index 36114db2..4526ceb6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,6 +1,6 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - config.paper_trail.enabled = true + # config.paper_trail.enabled = true # The test environment is used exclusively to run your application's # 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 diff --git a/config/initializers/new_framework_defaults_5_2.rb b/config/initializers/new_framework_defaults_5_2.rb index b3aebc13..3e92a4b3 100644 --- a/config/initializers/new_framework_defaults_5_2.rb +++ b/config/initializers/new_framework_defaults_5_2.rb @@ -29,10 +29,6 @@ # ApplicationController. # Rails.application.config.action_controller.default_protect_from_forgery = true -# Store boolean values are in sqlite3 databases as 1 and 0 instead of 't' and -# 'f' after migrating old data. -Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true - # Use SHA-1 instead of MD5 to generate non-sensitive digests, such as the ETag header. Rails.application.config.active_support.use_sha1_digests = true diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb index 9bc48a37..d5bd72d5 100644 --- a/config/initializers/rails_admin.rb +++ b/config/initializers/rails_admin.rb @@ -3,6 +3,7 @@ end RailsAdmin.config do |config| + config.asset_source = :sprockets EDITABLE_MODELS = %w[ Program User diff --git a/db/migrate/20230117110948_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20230117110948_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 00000000..a15c6ce8 --- /dev/null +++ b/db/migrate/20230117110948_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,22 @@ +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return unless table_exists?(:active_storage_blobs) + + unless column_exists?(:active_storage_blobs, :service_name) + add_column :active_storage_blobs, :service_name, :string + + if configured_service = ActiveStorage::Blob.service.name + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20230117110949_create_active_storage_variant_records.active_storage.rb b/db/migrate/20230117110949_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 00000000..94ac83af --- /dev/null +++ b/db/migrate/20230117110949_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,27 @@ +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20230117110950_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20230117110950_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 00000000..93c8b85a --- /dev/null +++ b/db/migrate/20230117110950_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,8 @@ +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index 5ed853bf..2c6b8857 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,17 +2,17 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_10_11_074011) do - +ActiveRecord::Schema[7.0].define(version: 2023_01_17_110950) do # These are extensions that must be enabled in order to support this database + enable_extension "pg_stat_statements" enable_extension "plpgsql" enable_extension "uuid-ossp" @@ -21,7 +21,7 @@ t.string "record_type", null: false t.bigint "record_id", null: false t.bigint "blob_id", null: false - t.datetime "created_at", null: false + t.datetime "created_at", precision: nil, null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end @@ -32,17 +32,24 @@ t.string "content_type" t.text "metadata" t.bigint "byte_size", null: false - t.string "checksum", null: false - t.datetime "created_at", null: false + t.string "checksum" + t.datetime "created_at", precision: nil, null: false + t.string "service_name", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + create_table "activities", force: :cascade do |t| t.string "name", null: false t.integer "project_id", null: false t.uuid "stable_id", default: -> { "uuid_generate_v4()" }, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "code" t.string "short_name" t.index ["name", "project_id"], name: "index_activities_on_name_and_project_id", unique: true @@ -54,8 +61,8 @@ t.integer "activity_id", null: false t.integer "package_id", null: false t.uuid "stable_id", default: -> { "uuid_generate_v4()" }, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["activity_id"], name: "index_activity_packages_on_activity_id" t.index ["package_id", "activity_id"], name: "index_activity_packages_on_package_id_and_activity_id", unique: true t.index ["package_id"], name: "index_activity_packages_on_package_id" @@ -67,8 +74,8 @@ t.integer "state_id", null: false t.integer "activity_id", null: false t.uuid "stable_id", default: -> { "uuid_generate_v4()" }, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "kind", default: "data_element", null: false t.string "formula" t.string "origin", default: "dataValueSets" @@ -92,11 +99,8 @@ t.jsonb "sent" t.jsonb "status" t.integer "project_anchor_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.bigint "invoicing_job_id" - t.string "sidekiq_job_ref" - t.index ["invoicing_job_id"], name: "index_dhis2_logs_on_invoicing_job_id" + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["project_anchor_id"], name: "index_dhis2_logs_on_project_anchor_id" end @@ -106,12 +110,12 @@ t.jsonb "values_before" t.jsonb "values_after" t.string "whodunnit" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["dhis2_snapshot_id"], name: "index_dhis2_snapshot_changes_on_dhis2_snapshot_id" end - create_table "dhis2_snapshots", force: :cascade do |t| + create_table "dhis2_snapshots", id: :serial, force: :cascade do |t| t.string "kind", null: false t.jsonb "content", null: false t.integer "project_anchor_id" @@ -119,8 +123,8 @@ t.integer "year", null: false t.integer "month", null: false t.string "job_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["project_anchor_id"], name: "index_dhis2_snapshots_on_project_anchor_id" end @@ -128,8 +132,8 @@ t.string "name" t.string "external_reference" t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.boolean "limit_snaphot_to_active_regions", default: false, null: false t.string "kind", default: "group_based" t.string "program_reference" @@ -141,8 +145,8 @@ create_table "flipper_features", force: :cascade do |t| t.string "key", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["key"], name: "index_flipper_features_on_key", unique: true end @@ -150,8 +154,8 @@ t.string "feature_key", null: false t.string "key", null: false t.string "value" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["feature_key", "key", "value"], name: "index_flipper_gates_on_feature_key_and_key_and_value", unique: true end @@ -169,8 +173,8 @@ t.string "description", null: false t.text "expression", null: false t.integer "rule_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "frequency" t.string "short_name" t.string "exportable_formula_code" @@ -182,14 +186,14 @@ t.string "orgunit_ref", null: false t.string "dhis2_period", null: false t.string "user_ref" - t.datetime "processed_at" - t.datetime "errored_at" + t.datetime "processed_at", precision: nil + t.datetime "errored_at", precision: nil t.string "last_error" t.integer "duration_ms" t.string "status", default: "enqueued" t.string "sidekiq_job_ref" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "type", default: "InvoicingJob" t.index ["project_anchor_id", "orgunit_ref", "dhis2_period", "type"], name: "index_invoicing_jobs_on_anchor_ou_period", unique: true t.index ["project_anchor_id"], name: "index_invoicing_jobs_on_project_anchor_id" @@ -199,8 +203,8 @@ t.string "name" t.integer "package_id" t.string "organisation_unit_group_ext_ref" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "kind", default: "main", null: false t.index ["package_id"], name: "index_package_entity_groups_on_package_id" end @@ -208,8 +212,8 @@ create_table "package_payment_rules", force: :cascade do |t| t.integer "package_id", null: false t.integer "payment_rule_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["package_id"], name: "index_package_payment_rules_on_package_id" t.index ["payment_rule_id"], name: "index_package_payment_rules_on_payment_rule_id" end @@ -217,8 +221,8 @@ create_table "package_states", force: :cascade do |t| t.integer "package_id" t.integer "state_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "ds_external_reference" t.string "deg_external_reference" t.string "de_external_reference" @@ -233,8 +237,8 @@ t.string "data_element_group_ext_ref", null: false t.string "frequency", null: false t.integer "project_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.uuid "stable_id", default: -> { "uuid_generate_v4()" }, null: false t.string "kind", default: "single" t.string "ogs_reference" @@ -250,27 +254,27 @@ t.integer "payment_rule_id" t.string "frequency" t.string "external_reference" - t.datetime "last_synched_at" + t.datetime "last_synched_at", precision: nil t.string "last_error" t.boolean "desynchronized" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.index ["payment_rule_id", "frequency"], name: "index_payment_rule_datasets_on_payment_rule_id_and_frequency", unique: true t.index ["payment_rule_id"], name: "index_payment_rule_datasets_on_payment_rule_id" end create_table "payment_rules", force: :cascade do |t| t.integer "project_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "frequency", default: "quarterly", null: false t.index ["project_id"], name: "index_payment_rules_on_project_id" end create_table "programs", force: :cascade do |t| t.string "code", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "oauth_client_id" t.string "oauth_client_secret" t.index ["code"], name: "index_programs_on_code", unique: true @@ -278,8 +282,8 @@ create_table "project_anchors", force: :cascade do |t| t.integer "program_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "token" t.index ["program_id"], name: "index_project_anchors_on_program_id" end @@ -291,18 +295,18 @@ t.string "password" t.boolean "bypass_ssl", default: false t.boolean "boolean", default: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.string "status", default: "draft", null: false - t.datetime "publish_date" + t.datetime "publish_date", precision: nil t.integer "project_anchor_id" t.integer "original_id" t.string "cycle", default: "quarterly", null: false t.integer "engine_version", default: 3, null: false + t.string "qualifier" t.string "default_coc_reference" t.string "default_aoc_reference" - t.string "qualifier" - t.datetime "publish_end_date" + t.datetime "publish_end_date", precision: nil t.string "calendar_name", default: "gregorian", null: false t.boolean "read_through_deg", default: true, null: false t.string "invoice_app_path", default: "/api/apps/ORBF2---Invoices-and-Reports/index.html", null: false @@ -315,8 +319,8 @@ t.string "name", null: false t.string "kind", null: false t.integer "package_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "payment_rule_id" t.uuid "stable_id", default: -> { "uuid_generate_v4()" }, null: false t.index ["package_id"], name: "index_rules_on_package_id" @@ -325,8 +329,8 @@ create_table "states", force: :cascade do |t| t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "project_id", null: false t.string "short_name" t.index ["project_id", "name"], name: "index_states_on_project_id_and_name", unique: true @@ -337,15 +341,15 @@ t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" + t.datetime "reset_password_sent_at", precision: nil + t.datetime "remember_created_at", precision: nil t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil t.inet "current_sign_in_ip" t.inet "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", precision: nil, null: false + t.datetime "updated_at", precision: nil, null: false t.integer "program_id" t.string "dhis2_user_ref" t.index ["email"], name: "index_users_on_email", unique: true @@ -367,7 +371,7 @@ t.string "event", null: false t.string "whodunnit" t.text "old_object" - t.datetime "created_at" + t.datetime "created_at", precision: nil t.integer "transaction_id" t.jsonb "object" t.integer "program_id" @@ -380,16 +384,13 @@ end add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "activities", "projects" add_foreign_key "activity_packages", "activities" add_foreign_key "activity_packages", "packages" add_foreign_key "activity_states", "activities" add_foreign_key "activity_states", "states" add_foreign_key "decision_tables", "rules" - add_foreign_key "dhis2_logs", "invoicing_jobs" - add_foreign_key "dhis2_logs", "project_anchors" - add_foreign_key "dhis2_snapshot_changes", "dhis2_snapshots" - add_foreign_key "dhis2_snapshots", "project_anchors" add_foreign_key "entity_groups", "projects" add_foreign_key "formula_mappings", "activities" add_foreign_key "formula_mappings", "formulas" diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index d28f4cc8..42a42d74 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -44,7 +44,7 @@ name { Faker::Address.country } dhis2_url { Faker::Internet.url } user { Faker::Internet.user_name } - password { Faker::Internet.password(8) } + password { "password123" } bypass_ssl { false } end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 4c16ea96..99298384 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # == Schema Information # # Table name: projects @@ -52,16 +53,16 @@ it "should validate url " do expect(project.valid?).to eq true - project.dhis2_url = "http:// bad : userexport@/dev:456.url" + project.dhis2_url = "http://bad:userexport@/dev:456.url" expect(project.valid?).to eq false end describe "#verify_connection" do it "should validate url before testing" do - project.dhis2_url = "http:// bad : userexport@/dev:456.url" + project.dhis2_url = "http://bad:userexport@/dev:456.url" expect(project.verify_connection).to eq( status: :ko, - message: "Dhis2 url is not an url" + message: "no host component for URI" ) end From 6edb9ee41ad31671393387fbab4ee9f0d9449cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 17 Jan 2023 15:48:28 +0100 Subject: [PATCH 02/26] Fix validation for activity state --- app/models/activity_state.rb | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/app/models/activity_state.rb b/app/models/activity_state.rb index 304ab568..a7be1242 100644 --- a/app/models/activity_state.rb +++ b/app/models/activity_state.rb @@ -30,16 +30,16 @@ class ActivityStateValidator def self.validate(activity_state) - if activity_state.kind_data_element_coc? && activity_state.external_reference.presence - if !activity_state.external_reference.include?(".") - activity_state.errors[:external_reference] << "should contains a dot like DATAELEMENTID.COCID" - end - end - if (activity_state.kind_indicator? || activity_state.kind_data_element?) && activity_state.external_reference.presence - if activity_state.external_reference.include?(".") - activity_state.errors[:external_reference] << "should NOT contains a dot like DATAELEMENTID.COCID" - end + if activity_state.kind_data_element_coc? && activity_state.external_reference.presence && !activity_state.external_reference.include?(".") + activity_state.errors.add(:external_reference, + "should contains a dot like DATAELEMENTID.COCID") end + de_or_indicator = activity_state.kind_indicator? || activity_state.kind_data_element? + return unless de_or_indicator && activity_state.external_reference.presence + return unless activity_state.external_reference.include?(".") + + activity_state.errors.add(:external_reference, + "should NOT contains a dot like DATAELEMENTID.COCID") end end @@ -52,7 +52,8 @@ class ActivityState < ApplicationRecord belongs_to :state validates :state, presence: { message: "Select a state or remove this activity from the list" } - validates :external_reference, presence: true, uniqueness: { scope: [:activity_id] }, if: :dhis2_related? + validates :external_reference, presence: true, uniqueness: { scope: [:activity_id] }, +if: :dhis2_related? validates :name, presence: true validates :formula, presence: true, if: :kind_formula? From 519828c7f9d306e9134ce461b60f47c78e6b2c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 17 Jan 2023 16:02:35 +0100 Subject: [PATCH 03/26] Fix formula validations --- app/models/rule_types/base_rule_type.rb | 5 +++-- app/models/rule_types/package_rule_type.rb | 4 ++-- app/services/rules/solver.rb | 23 +++++++++++----------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/app/models/rule_types/base_rule_type.rb b/app/models/rule_types/base_rule_type.rb index c8fdc805..d557fe8c 100644 --- a/app/models/rule_types/base_rule_type.rb +++ b/app/models/rule_types/base_rule_type.rb @@ -5,6 +5,7 @@ def initialize(rule) end attr_reader :rule + delegate :package, to: :rule delegate :formulas, to: :rule delegate :activity_kind?, to: :rule @@ -75,8 +76,8 @@ def package_formula_uniqness formula_by_codes.each do |code, formulas| next unless formulas.size > 1 - rule.errors[:formulas] << "Formula's code must be unique,"\ - " you have #{formulas.size} formulas with '#{code}'" + rule.errors.add(:formulas, "Formula's code must be unique,"\ + " you have #{formulas.size} formulas with '#{code}'") end end end diff --git a/app/models/rule_types/package_rule_type.rb b/app/models/rule_types/package_rule_type.rb index 701e13a7..ce14a017 100644 --- a/app/models/rule_types/package_rule_type.rb +++ b/app/models/rule_types/package_rule_type.rb @@ -57,14 +57,14 @@ def package_formula_uniqness next unless formula_by_codes[code] if non_uniq_formulas.size > 1 - rule.errors[:formulas] << "Formula's code must be unique accross packages, you have #{non_uniq_formulas.size} formulas with '#{code}' in #{non_uniq_formulas.map(&:rule).map(&:package).map(&:name).join(' and ')}" + rule.errors.add(:formulas, "Formula's code must be unique accross packages, you have #{non_uniq_formulas.size} formulas with '#{code}' in #{non_uniq_formulas.map(&:rule).map(&:package).map(&:name).join(' and ')}") end end end formula_by_codes.each do |code, formulas| if formulas.size > 1 - rule.errors[:formulas] << "Formula's code must be unique, you have #{formulas.size} formulas with '#{code}'" + rule.errors.add(:formulas, "Formula's code must be unique, you have #{formulas.size} formulas with '#{code}'") end end end diff --git a/app/services/rules/solver.rb b/app/services/rules/solver.rb index 15270fe5..249ebcbb 100644 --- a/app/services/rules/solver.rb +++ b/app/services/rules/solver.rb @@ -15,12 +15,12 @@ def solve!(message, facts_and_rules, debug = false) log "********** #{message} #{Time.new}\n#{JSON.pretty_generate(facts_and_rules)}\n" if debug begin solution = calculator.solve!(facts_and_rules) - rescue TSort::Cyclic => cycle_error + rescue TSort::Cyclic => e log JSON.pretty_generate(facts_and_rules) - log cycle_error.message - raise SolvingError.new("a cycle has been created : " + cycle_error.message, facts_and_rules), + log e.message + raise SolvingError.new("a cycle has been created : " + e.message, facts_and_rules), "Failed to solve this problem : a cycle exist between formulas: "\ - "#{message} : #{cycle_error.message}" + "#{message} : #{e.message}" rescue StandardError => e log JSON.pretty_generate(facts_and_rules) log e.message @@ -39,11 +39,11 @@ def validate_expression(formula) ) ) rescue KeyError => e - formula.errors[:expression] << "#{e.message}. " \ - "Remove extra spaces or verify it's in the available variables" + formula.errors.add(:expression, "#{e.message}. " \ + "Remove extra spaces or verify it's in the available variables") rescue StandardError => e Rails.logger.warn("FAILED to validate #{formula} : #{e.backtrace.join("\n")}") - formula.errors[:expression] << e.message + formula.errors.add(:expression, e.message) end def dependencies(formula) @@ -53,7 +53,7 @@ def dependencies(formula) formula.rule.available_variables_for_values ) ) - rescue StandardError => ignored + rescue StandardError => e [] end @@ -70,12 +70,13 @@ def validate_formulas(rule) facts[:actictity_rule_name] = Solver.escape_string(rule.name) solve!("validate_all_formulas", facts) rescue Rules::SolvingError => e - rule.errors[:formulas] << e.original_message + rule.errors.add(:formulas, e.original_message) rescue KeyError => e - rule.errors[:formulas] << "#{e.message}. Remove extra spaces or verify it's in the available variables" + rule.errors.add(:formulas, + "#{e.message}. Remove extra spaces or verify it's in the available variables") rescue StandardError => e log(e.message) - rule.errors[:formulas] << e.message + rule.errors.add(:formulas, e.message) end def self.escape_string(string) From d2aec13e3a9faabab9869c3616097865f87458fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 17 Jan 2023 16:52:19 +0100 Subject: [PATCH 04/26] fix more --- app/services/invoicing/invoice_entity.rb | 32 +++++++++---------- .../setup/changes_controller_spec.rb | 4 +-- spec/models/concerns/paper_trailed_spec.rb | 5 +++ .../invoice_for_project_anchor_worker_spec.rb | 15 ++++----- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/app/services/invoicing/invoice_entity.rb b/app/services/invoicing/invoice_entity.rb index 3c982ddd..f3f28b43 100644 --- a/app/services/invoicing/invoice_entity.rb +++ b/app/services/invoicing/invoice_entity.rb @@ -48,22 +48,22 @@ def ignore_non_contracted? def fetch_and_solve @fetch_and_solve ||= begin - solve_options = { - pyramid: pyramid, - mock_values: invoicing_request.mocked_data - } - - @fetch_and_solve = Orbf::RulesEngine::FetchAndSolve.new( - orbf_project, - invoicing_request.entity, - invoicing_request.year_quarter.to_dhis2, - solve_options - ) - @pyramid = @fetch_and_solve.pyramid - @dhis2_export_values = @fetch_and_solve.call - @dhis2_input_values = @fetch_and_solve.dhis2_values - @fetch_and_solve - end + solve_options = { + pyramid: pyramid, + mock_values: invoicing_request.mocked_data + } + + @fetch_and_solve = Orbf::RulesEngine::FetchAndSolve.new( + orbf_project, + invoicing_request.entity, + invoicing_request.year_quarter.to_dhis2, + **solve_options + ) + @pyramid = @fetch_and_solve.pyramid + @dhis2_export_values = @fetch_and_solve.call + @dhis2_input_values = @fetch_and_solve.dhis2_values + @fetch_and_solve + end end def publish_to_dhis2 diff --git a/spec/controllers/setup/changes_controller_spec.rb b/spec/controllers/setup/changes_controller_spec.rb index 3553b707..3d3a71d4 100644 --- a/spec/controllers/setup/changes_controller_spec.rb +++ b/spec/controllers/setup/changes_controller_spec.rb @@ -28,8 +28,8 @@ it "should display a form for current project with a few default" do with_versioning do project - project.update_attributes(dhis2_url: "http://new.url.be") - project.entity_group.update_attributes(name: "updategroup") + project.update(dhis2_url: "http://new.url.be") + project.entity_group.update(name: "updategroup") end get :index, params: { project_id: project.id } versions = assigns(:versions) diff --git a/spec/models/concerns/paper_trailed_spec.rb b/spec/models/concerns/paper_trailed_spec.rb index 6215af14..90a954f7 100644 --- a/spec/models/concerns/paper_trailed_spec.rb +++ b/spec/models/concerns/paper_trailed_spec.rb @@ -13,6 +13,7 @@ EXCEPTIONS = [ ActiveRecord::SchemaMigration, PaperTrail::Version, + PaperTrail::VersionAssociation, Version, Dhis2Log, Dhis2Snapshot, @@ -22,6 +23,10 @@ InvoicingSimulationJob, Flipper::Adapters::ActiveRecord::Feature, Flipper::Adapters::ActiveRecord::Gate, + ActiveStorage::Blob, + ActiveStorage::Attachment, + ActiveStorage::VariantRecord, + ActiveRecord::InternalMetadata ].freeze ActiveRecord::Base.descendants diff --git a/spec/workers/invoice_for_project_anchor_worker_spec.rb b/spec/workers/invoice_for_project_anchor_worker_spec.rb index 49566fbd..a869c444 100644 --- a/spec/workers/invoice_for_project_anchor_worker_spec.rb +++ b/spec/workers/invoice_for_project_anchor_worker_spec.rb @@ -12,7 +12,7 @@ let!(:project) do project = full_project project.save! - project.update_attributes(read_through_deg: false) + project.update(read_through_deg: false) user.save! user.program = program @@ -202,7 +202,7 @@ let(:org_unit_ids) do %w[AhnK8hb3JWm BLVKubgVxkF Bift1B4gjru Bq5nb7UAEGd C9uduqDZr9d DSBXsRQSXUW DmaLM8WYmWv ENHOJz3UH5L Ea3j0kUvyWg EmTN0L4EAVi GvFqTavdpGE HPg74Rr7UWp IXJg79fclDm ImspTQPwCqd JLKGG67z7oj JNJIPX9DfaW KIUCimTXf8Q KKkLOTpMXGV KuR0y0h0mOM LV2b3vaLRl1 LaxJ6CD2DHq Ls2ESQONh9S M2qEv692lS6 M721NHGtdZV O6uvpzGd5pu OuwX8H2CcRO PD1fqyvJssC PLoeN9CaL7z PMa2VCrupOd PQZJPIpTepd Qw7c6Ckb0XC QywkxFudXrC RUCp6OaTSAD T2Cn45nBY0u TEQlaapDQoK TQkG0sX9nca U6Kr7Gtpidn Uo4cyJwAhTW VCtF1DbspR5 VGAFxBXz16y Vnc2qIRLbyw Vth0fbpFcsO W5fN3G6y1VI XEyIRFd9pct XJ6DqDkMlPv at6UHUQatSo bM4Ky73uMao bPHn9IgjKLC bVZTNrnfn9G cDw53Ej8rju cM2BKSrj9F9 cZtKKa9eJZ3 cgqkFdShPzg ctfiYW0ePJ8 eIQbndfxQMb fXT1scbEObM fdc6uOvgoji gmen7SXL9CU jCnyQOKQBFX jUb8gELQApl jmIPBj66vD6 kBP1UvZpsNj kJq2mPyFEHo kLNQT4KQ9hT kMTHqMgenme lc3eMKXaEfw mTNOoGXuC39 nCh5dBoJVNw nV3OkyzF4US nq7F0t1Pz6t qhqAxPSTUXp qtr8GGlm4gg roQ2l7TX0eZ tHUYjt9cU6h u6ZGNI8yUmt uNEhNuBUr0i vRC0stJ5y9Q vn9KJsLyP5f vv1QJFONsT6 wNYYRm2c9EK wicmjKI3xiP yP2nhllbQPh] end - let(:dataset_ext_ids) { ["ds-0", "ds-1", "ds-2"] } + let(:dataset_ext_ids) { %w[ds-0 ds-1 ds-2] } let(:periods) { %w[2014July 2015 201501 201502 201503 2015Q1] } it "should perform for sub contracted entities pattern with new engine" do @@ -272,7 +272,7 @@ let(:org_unit_ids) do %w[AhnK8hb3JWm BLVKubgVxkF Bift1B4gjru Bq5nb7UAEGd C9uduqDZr9d DSBXsRQSXUW DmaLM8WYmWv ENHOJz3UH5L Ea3j0kUvyWg EmTN0L4EAVi GvFqTavdpGE HPg74Rr7UWp IXJg79fclDm ImspTQPwCqd JLKGG67z7oj JNJIPX9DfaW KIUCimTXf8Q KKkLOTpMXGV KuR0y0h0mOM LV2b3vaLRl1 LaxJ6CD2DHq Ls2ESQONh9S M2qEv692lS6 M721NHGtdZV O6uvpzGd5pu OuwX8H2CcRO PD1fqyvJssC PLoeN9CaL7z PMa2VCrupOd PQZJPIpTepd Qw7c6Ckb0XC QywkxFudXrC RUCp6OaTSAD T2Cn45nBY0u TEQlaapDQoK TQkG0sX9nca U6Kr7Gtpidn Uo4cyJwAhTW VCtF1DbspR5 VGAFxBXz16y Vnc2qIRLbyw Vth0fbpFcsO W5fN3G6y1VI XEyIRFd9pct XJ6DqDkMlPv at6UHUQatSo bM4Ky73uMao bPHn9IgjKLC bVZTNrnfn9G cDw53Ej8rju cM2BKSrj9F9 cZtKKa9eJZ3 cgqkFdShPzg ctfiYW0ePJ8 eIQbndfxQMb fXT1scbEObM fdc6uOvgoji gmen7SXL9CU jCnyQOKQBFX jUb8gELQApl jmIPBj66vD6 kBP1UvZpsNj kJq2mPyFEHo kLNQT4KQ9hT kMTHqMgenme lc3eMKXaEfw mTNOoGXuC39 nCh5dBoJVNw nV3OkyzF4US nq7F0t1Pz6t qhqAxPSTUXp qtr8GGlm4gg roQ2l7TX0eZ tHUYjt9cU6h u6ZGNI8yUmt uNEhNuBUr0i vRC0stJ5y9Q vn9KJsLyP5f vv1QJFONsT6 wNYYRm2c9EK wicmjKI3xiP yP2nhllbQPh] end - let(:dataset_ext_ids) { ["ds-0", "ds-1", "ds-2"] } + let(:dataset_ext_ids) { %w[ds-0 ds-1 ds-2] } let(:periods) { %w[2014July 2015 201501 201502 201503 2015Q1] } it "should perform for sub contracted entities pattern with new engine" do @@ -340,14 +340,14 @@ describe "retry logic" do it "doesn't fail if equation fails" do - expect(InvoicingJob).to receive(:execute) { raise Hesabu::Error.new("In equation and so on")} + expect(InvoicingJob).to receive(:execute) { raise Hesabu::Error, "In equation and so on" } expect { worker.perform(project.project_anchor.id, 2015, 1, ["Rp268JB6Ne4"]) }.to_not raise_error end - it 'fails if hesabu error other than equation fails' do - expect(InvoicingJob).to receive(:execute) { raise Hesabu::Error.new("Some error in Hesabu")} + it "fails if hesabu error other than equation fails" do + expect(InvoicingJob).to receive(:execute) { raise Hesabu::Error, "Some error in Hesabu" } expect { worker.perform(project.project_anchor.id, 2015, 1, ["Rp268JB6Ne4"]) @@ -376,8 +376,7 @@ def stub_export_values(expected_fixture) end def sorted_datavalues(json) - sorted = json["dataValues"].sort_by { |e| [e["dataElement"], e["orgUnit"], e["period"]] } + json["dataValues"].sort_by { |e| [e["dataElement"], e["orgUnit"], e["period"]] } # Rails.logger.info "sorted\n #{sorted}\n\n\n" - sorted end end From d4c68f9aac0266921ada40fb098b4fb1c1b7f0a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 07:50:39 +0100 Subject: [PATCH 05/26] regenerated schema.rb --- db/schema.rb | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 2c6b8857..981ee6f0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,7 +12,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_17_110950) do # These are extensions that must be enabled in order to support this database - enable_extension "pg_stat_statements" enable_extension "plpgsql" enable_extension "uuid-ossp" @@ -101,6 +100,9 @@ t.integer "project_anchor_id" t.datetime "created_at", precision: nil, null: false t.datetime "updated_at", precision: nil, null: false + t.bigint "invoicing_job_id" + t.string "sidekiq_job_ref" + t.index ["invoicing_job_id"], name: "index_dhis2_logs_on_invoicing_job_id" t.index ["project_anchor_id"], name: "index_dhis2_logs_on_project_anchor_id" end @@ -115,7 +117,7 @@ t.index ["dhis2_snapshot_id"], name: "index_dhis2_snapshot_changes_on_dhis2_snapshot_id" end - create_table "dhis2_snapshots", id: :serial, force: :cascade do |t| + create_table "dhis2_snapshots", force: :cascade do |t| t.string "kind", null: false t.jsonb "content", null: false t.integer "project_anchor_id" @@ -303,9 +305,9 @@ t.integer "original_id" t.string "cycle", default: "quarterly", null: false t.integer "engine_version", default: 3, null: false - t.string "qualifier" t.string "default_coc_reference" t.string "default_aoc_reference" + t.string "qualifier" t.datetime "publish_end_date", precision: nil t.string "calendar_name", default: "gregorian", null: false t.boolean "read_through_deg", default: true, null: false @@ -366,7 +368,8 @@ end create_table "versions", force: :cascade do |t| - t.string "item_type", null: false + t.string "item_type" + t.string "{:null=>false}" t.integer "item_id", null: false t.string "event", null: false t.string "whodunnit" @@ -391,6 +394,10 @@ add_foreign_key "activity_states", "activities" add_foreign_key "activity_states", "states" add_foreign_key "decision_tables", "rules" + add_foreign_key "dhis2_logs", "invoicing_jobs" + add_foreign_key "dhis2_logs", "project_anchors" + add_foreign_key "dhis2_snapshot_changes", "dhis2_snapshots" + add_foreign_key "dhis2_snapshots", "project_anchors" add_foreign_key "entity_groups", "projects" add_foreign_key "formula_mappings", "activities" add_foreign_key "formula_mappings", "formulas" From 6ac826c943c43433df6609ad59f34690e20557ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 10:16:41 +0100 Subject: [PATCH 06/26] More spec fixes --- app/models/invoicing_job.rb | 25 ++++++++++++------------- app/models/project.rb | 2 +- lib/data_test/file_helpers.rb | 2 +- spec/config/lint_data_files_spec.rb | 4 ++-- spec/lib/data_test_spec.rb | 8 ++++---- spec/models/invoicing_job_spec.rb | 12 ++++++------ 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/app/models/invoicing_job.rb b/app/models/invoicing_job.rb index 932e3e6f..1a2c40f9 100644 --- a/app/models/invoicing_job.rb +++ b/app/models/invoicing_job.rb @@ -62,18 +62,17 @@ def execute(project_anchor, period, orgunit_ref) start_time = time instrument :execute do |payload| - begin - payload[:found] = "FOUND #{invoicing_job.inspect} vs #{period} #{orgunit_ref}" - yield(invoicing_job) - ensure - payload[:processed] = "mark_as_processed #{invoicing_job.inspect}" - find_invoicing_job(project_anchor, period, orgunit_ref)&.mark_as_processed(start_time, time) - end + payload[:found] = "FOUND #{invoicing_job.inspect} vs #{period} #{orgunit_ref}" + yield(invoicing_job) + ensure + payload[:processed] = "mark_as_processed #{invoicing_job.inspect}" + find_invoicing_job(project_anchor, period, + orgunit_ref)&.mark_as_processed(start_time, time) end - rescue StandardError => err - warn "ERROR #{invoicing_job.inspect} #{err.message}" - find_invoicing_job(project_anchor, period, orgunit_ref)&.mark_as_error(start_time, time, err) - raise err + rescue StandardError => e + warn "ERROR #{invoicing_job.inspect} #{e.message}" + find_invoicing_job(project_anchor, period, orgunit_ref)&.mark_as_error(start_time, time, e) + raise e end private @@ -102,8 +101,8 @@ def find_invoicing_job(project_anchor, period, orgunit_ref) end def processed_after?(time_stamp: 10.minutes.ago) - return errored_at > time_stamp if errored? - return processed_at > time_stamp if processed? + return errored_at > time_stamp if errored? && errored_at + return processed_at > time_stamp if processed? && processed_at false end diff --git a/app/models/project.rb b/app/models/project.rb index dd2957f5..a6b1fab8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -394,7 +394,7 @@ def changelog(other_project = original) diff_symbols = { "+" => :added, "-" => :removed, "~" => :modified } all_names = to_unified_names.merge(other_project.to_unified_names) - HashDiff.diff(other_project.to_unified_h, to_unified_h).map do |hash_diff| + Hashdiff.diff(other_project.to_unified_h, to_unified_h).map do |hash_diff| operation, path, value, current = hash_diff ChangelogEntry.new( diff --git a/lib/data_test/file_helpers.rb b/lib/data_test/file_helpers.rb index 3805b6c4..a425cdd1 100644 --- a/lib/data_test/file_helpers.rb +++ b/lib/data_test/file_helpers.rb @@ -3,7 +3,7 @@ module DataTest module FileHelpers def read_yaml(file_path) - YAML.load_file(file_path) + YAML.unsafe_load_file(file_path) end def record_yaml(file_path, yamlable) diff --git a/spec/config/lint_data_files_spec.rb b/spec/config/lint_data_files_spec.rb index a261dfec..27eaf02f 100644 --- a/spec/config/lint_data_files_spec.rb +++ b/spec/config/lint_data_files_spec.rb @@ -16,7 +16,7 @@ yaml_paths.each do |path| it "load from #{path}" do - assert YAML.load_file(path) + assert YAML.unsafe_load_file(path) end end end @@ -24,7 +24,7 @@ describe "ruby version" do it "Gemfile and .ruby_version match" do ruby_version = File.read(".ruby-version").strip - gemfile_ruby_version = File.readlines("Gemfile").grep(/^ruby/).first.gsub("ruby ", "").gsub('"', '').strip + gemfile_ruby_version = File.readlines("Gemfile").grep(/^ruby/).first.gsub("ruby ", "").gsub('"', "").strip assert ruby_version == gemfile_ruby_version, ".ruby-version (#{ruby_version}) needs to have the same version as Gemfile (#{gemfile_ruby_version})" end diff --git a/spec/lib/data_test_spec.rb b/spec/lib/data_test_spec.rb index 3d712c63..585a6597 100644 --- a/spec/lib/data_test_spec.rb +++ b/spec/lib/data_test_spec.rb @@ -65,7 +65,7 @@ def result(name) it "exported_values" do original = artefact("#{name}-exported_values.json") new = result("#{name}-exported_values.json") - diff = HashDiff.diff(original, new, use_lcs: false) + diff = Hashdiff.diff(original, new, use_lcs: false) unless diff.empty? puts " + original: #{original.count} vs new: #{new.count}" puts " + diff (first 10): #{diff.sample(10)}" @@ -77,13 +77,13 @@ def result(name) else message = <<~DESC No FETCHER_S3_ACCESS and FETCHER_S3_KEY found in ENV-variables. - + These are needed to download the artefacts to verify the results with, so now skipping. DESC if ENV["CI"] - it 'has S3 configured' do - fail message + it "has S3 configured" do + raise message end else puts message diff --git a/spec/models/invoicing_job_spec.rb b/spec/models/invoicing_job_spec.rb index 384305c5..38616abf 100644 --- a/spec/models/invoicing_job_spec.rb +++ b/spec/models/invoicing_job_spec.rb @@ -137,19 +137,19 @@ def action end describe "processed_after?" do - it 'true for processed and after' do + it "true for processed and after" do job = FactoryBot.build_stubbed(:invoicing_simulation_job, :processed) job.processed_at = 9.minutes.ago expect(job.processed_after?(time_stamp: 10.minutes.ago)).to eq true end - it 'false for processed and before timestamp' do + it "false for processed and before timestamp" do job = FactoryBot.build_stubbed(:invoicing_simulation_job, :processed) job.processed_at = 11.minutes.ago expect(job.processed_after?(time_stamp: 10.minutes.ago)).to eq false end - it 'false for not processed' do + it "false for not processed" do job = FactoryBot.build_stubbed(:invoicing_simulation_job, :errored) job.processed_at = 11.minutes.ago expect(job.processed_after?(time_stamp: 10.minutes.ago)).to eq false @@ -157,7 +157,7 @@ def action end describe "status" do - it 'adds scopes' do + it "adds scopes" do processed_job = FactoryBot.create(:invoicing_simulation_job, :processed) errored_job = FactoryBot.create(:invoicing_simulation_job, :errored) new_job = FactoryBot.create(:invoicing_simulation_job) @@ -166,7 +166,7 @@ def action expect(InvoicingJob.enqueued.pluck(:id)).to eq([new_job.id]) end - it 'complains on invalid state' do + it "complains on invalid state" do new_job = FactoryBot.create(:invoicing_simulation_job) expect { @@ -174,7 +174,7 @@ def action }.to raise_error(ArgumentError) end - it 'defaults to enqueued' do + it "defaults to enqueued" do new_job = FactoryBot.create(:invoicing_simulation_job) expect(new_job.enqueued?).to eq(true) end From 7584e6f66c5376a865b8c2279918d8f479f1a01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 11:06:05 +0100 Subject: [PATCH 07/26] Allow some float tolerance since dentaku upgrade --- lib/data_test/compare.rb | 13 ++++++++----- spec/lib/data_test_spec.rb | 12 ++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/data_test/compare.rb b/lib/data_test/compare.rb index a48e70c1..61f14829 100644 --- a/lib/data_test/compare.rb +++ b/lib/data_test/compare.rb @@ -82,7 +82,8 @@ def json_diff(filename) if result.empty? Result.new(success: true) else - Result.new(success: false, key_count: [a.keys.count, b.keys.count], short: result.sample(10), full: result) + Result.new(success: false, key_count: [a.keys.count, b.keys.count], + short: result.sample(10), full: result) end end end @@ -94,11 +95,12 @@ def hash_diff(filename) a = JSON.parse(File.open(file_a).read) b = JSON.parse(File.open(file_b).read) guard_timeout do - diff = HashDiff.diff(a, b, use_lcs: false) + diff = Hashdiff.diff(a, b, use_lcs: false, numeric_tolerance: 0.000000001) if diff.empty? Result.new(success: true) else - Result.new(success: false, key_count: [a.count, b.count], short: diff.sample(10), full: diff) + Result.new(success: false, key_count: [a.count, b.count], short: diff.sample(10), + full: diff) end end end @@ -123,7 +125,8 @@ def handle_json_diff(name, result) puts " #{result.message}" puts " + Differences (first 10 out of #{result.full.count})" result.short.each do |item| - puts format(" [%s] Was: %s Is: %s Path: %s", item["op"], item["was"], item["value"], item["path"]) + puts format(" [%s] Was: %s Is: %s Path: %s", item["op"], item["was"], item["value"], + item["path"]) end end end @@ -148,7 +151,7 @@ def call handle_hash_diff(filename, hash_diff(filename)) [ %w[project yml], - ["data-compound", "yml"], + %w[data-compound yml], %w[pyramid yml] ].each do |(name, extension)| filename = subject.filename(name, extension) diff --git a/spec/lib/data_test_spec.rb b/spec/lib/data_test_spec.rb index 585a6597..8513a590 100644 --- a/spec/lib/data_test_spec.rb +++ b/spec/lib/data_test_spec.rb @@ -53,10 +53,14 @@ def result(name) it "solution" do original = artefact("#{name}-solution.json") - new = result("#{name}-solution.json") - result = JsonDiff.diff(original, new, include_was: true) + new_solution = result("#{name}-solution.json") + result = JsonDiff.diff(original, new_solution, include_was: true) + # omit type changes since dentaku upgrade (expected_float - actual_float).abs <= delta + result = result.reject do |change| + change["op"] == "replace" && (change["was"].to_f - change["value"].to_f).abs <= 0.000000001 + end unless result.empty? - puts " + original: #{original.keys.count} vs new: #{new.keys.count}" + puts " + original: #{original.keys.count} vs new: #{new_solution.keys.count}" puts " + diff (first 10): #{result.sample(10)}" end expect(result).to be_empty @@ -65,7 +69,7 @@ def result(name) it "exported_values" do original = artefact("#{name}-exported_values.json") new = result("#{name}-exported_values.json") - diff = Hashdiff.diff(original, new, use_lcs: false) + diff = Hashdiff.diff(original, new, use_lcs: false, numeric_tolerance: 0.000000001) unless diff.empty? puts " + original: #{original.count} vs new: #{new.count}" puts " + diff (first 10): #{diff.sample(10)}" From 32870dfc9d5a1e5bb1f222fed7a6b2331c968f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 11:34:18 +0100 Subject: [PATCH 08/26] Fix display_name arg error --- app/serializers/v2/dhis_value_item_serializer.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/serializers/v2/dhis_value_item_serializer.rb b/app/serializers/v2/dhis_value_item_serializer.rb index 072f5da8..f9403b19 100644 --- a/app/serializers/v2/dhis_value_item_serializer.rb +++ b/app/serializers/v2/dhis_value_item_serializer.rb @@ -1,10 +1,15 @@ # frozen_string_literal: true class V2::DhisValueItemSerializer < V2::BaseSerializer - attribute :value, &:display_name - + attribute :value do |rec| + rec.display_name + end attribute :id - attribute :name, &:display_name - attribute :display_name + attribute :name do |rec| + rec.display_name + end + attribute :display_name do |rec| + rec.display_name + end attribute :kind, if: Proc.new { |record, params| record.respond_to?(:kind) && record&.kind.present? } end From 7af0c7d6cc096ba02a9ed1be8a9ebc9a7e48aa8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 12:14:06 +0100 Subject: [PATCH 09/26] Fix some serialisation problem with lambda/proc --- app/serializers/invoicing_job_serializer.rb | 8 ++++---- app/serializers/v2/invoicing_job_serializer.rb | 8 ++++---- .../fetchers/organisation_units_snapshot_fetcher.rb | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/serializers/invoicing_job_serializer.rb b/app/serializers/invoicing_job_serializer.rb index 85165b48..c1bd0054 100644 --- a/app/serializers/invoicing_job_serializer.rb +++ b/app/serializers/invoicing_job_serializer.rb @@ -32,12 +32,12 @@ class InvoicingJobSerializer include FastJsonapi::ObjectSerializer set_key_transform :camel_lower - attribute :org_unit, &:orgunit_ref + attribute :org_unit do |rec| rec.orgunit_ref end attribute :dhis2_period - attribute :user, &:user_ref + attribute :user do |rec| rec.user_ref end attributes :created_at, :processed_at, :errored_at, :duration_ms, :status, :last_error attribute :sidekiq_job_ref - attribute :is_alive, &:alive? - attribute :result_url, &:result_url + attribute :is_alive do |rec| rec.alive? end + attribute :result_url do |rec| rec.result_url end end diff --git a/app/serializers/v2/invoicing_job_serializer.rb b/app/serializers/v2/invoicing_job_serializer.rb index 699f1194..0b5dcf64 100644 --- a/app/serializers/v2/invoicing_job_serializer.rb +++ b/app/serializers/v2/invoicing_job_serializer.rb @@ -1,13 +1,13 @@ # frozen_string_literal: true class V2::InvoicingJobSerializer < V2::BaseSerializer - attribute :org_unit, &:orgunit_ref + attribute :org_unit do |rec| rec.orgunit_ref end attribute :org_unit_name attribute :dhis2_period - attribute :user, &:user_ref + attribute :user do |rec| rec.user_ref end attributes :created_at, :processed_at, :errored_at, :duration_ms, :status, :last_error attribute :sidekiq_job_ref - attribute :is_alive, &:alive? - attribute :result_url, &:result_url + attribute :is_alive do |rec| rec.alive? end + attribute :result_url do |rec| rec.result_url end end diff --git a/app/workers/fetchers/organisation_units_snapshot_fetcher.rb b/app/workers/fetchers/organisation_units_snapshot_fetcher.rb index f5b5fafc..ce42a450 100644 --- a/app/workers/fetchers/organisation_units_snapshot_fetcher.rb +++ b/app/workers/fetchers/organisation_units_snapshot_fetcher.rb @@ -7,11 +7,13 @@ def initialize(fields:) end def fetch_data(project, kind, params) - raise "OrganisationUnitsSnapshotFetcher works only on organisation_units" unless kind == :organisation_units + unless kind == :organisation_units + raise "OrganisationUnitsSnapshotFetcher works only on organisation_units" + end filters = build_filters(project) filters.each_with_object([]) do |filter, data| - data.push(*fetcher.fetch_data(project, kind, { filter: filter }.merge(params))) + data.push(*fetcher.fetch_data(project, kind, **{ filter: filter }.merge(params))) end end From ba68394b04ce3e5992075213c5f21f853d06e516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 12:26:21 +0100 Subject: [PATCH 10/26] Fix validations on decision table --- app/models/decision_table.rb | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/app/models/decision_table.rb b/app/models/decision_table.rb index fda698b1..a8603868 100644 --- a/app/models/decision_table.rb +++ b/app/models/decision_table.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # == Schema Information # # Table name: decision_tables @@ -49,7 +50,7 @@ def normalize_blank_values def in_headers_belong_to_facts in_headers.each do |header| unless HEADER_PREFIXES.include?(header) || header.starts_with?("groupset_code_") - errors[:content] << "Not '#{header}' in available org unit facts !" + errors.add(:content, "Not '#{header}' in available org unit facts !") end end end @@ -59,8 +60,13 @@ def in_activity_code_exists available_codes = rule.package.activity_packages.map(&:activity).map(&:code).compact available_codes.push Decision::Rule::ANY - invalid_rules = decision_table.rules.reject { |rule| available_codes.include?(rule[HEADER_IN_ACTIVITY_CODE]) } - invalid_rules.each { |invalid_rule| errors[:content] << "#{invalid_rule.inspect} not in available package codes #{available_codes}!" } + invalid_rules = decision_table.rules.reject do |rule| + available_codes.include?(rule[HEADER_IN_ACTIVITY_CODE]) + end + invalid_rules.each do |invalid_rule| + errors.add(:content, + "#{invalid_rule.inspect} not in available package codes #{available_codes}!") + end end def period_start_before_end @@ -68,12 +74,12 @@ def period_start_before_end return if !start_period.presence && !end_period.presence if start_period.presence && !end_period.presence - errors[:end_period] << "Should be filled in if start period is filled" + errors.add(:end_period, "Should be filled in if start period is filled") elsif !start_period.presence && end_period.presence - errors[:start_period] << "Should be filled in if end period is filled" + errors.add(:start_period, "Should be filled in if end period is filled") else if start_period.presence > end_period.presence - errors[:start_period] << "Should be before end period" + errors.add(:start_period, "Should be before end period") end package_frequency = rule.package.frequency @@ -86,10 +92,10 @@ def period_start_before_end def validate_period_type(value, field, expected_frequency) frequency = Periods.detect(value) if frequency != expected_frequency - errors[field] << "Should be of period type " + expected_frequency + errors.add(field, "Should be of period type " + expected_frequency) end rescue StandardError => e - errors[field] << "Should be of period type " + expected_frequency + " : " + e.message + errors.add(field, "Should be of period type " + expected_frequency + " : " + e.message) end def in_headers From 946c708e022071525e716e35ad04683eb48842e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 13:24:21 +0100 Subject: [PATCH 11/26] Fix frozen error assertion --- spec/models/periods/year_quarter_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/models/periods/year_quarter_spec.rb b/spec/models/periods/year_quarter_spec.rb index 693f38df..62a4769d 100644 --- a/spec/models/periods/year_quarter_spec.rb +++ b/spec/models/periods/year_quarter_spec.rb @@ -5,19 +5,19 @@ let(:year_quarter) { Periods::YearQuarter.from_yyyyqq(yyyyqq) } let(:last_quarter) { Periods::YearQuarter.from_yyyyqq("2016Q4") } - describe 'fails fast' do + describe "fails fast" do it "when nil" do - expect {Periods::YearQuarter.new(nil)}.to raise_error(ArgumentError, "Argument yyyyqq can't be nil") + expect { Periods::YearQuarter.new(nil) }.to raise_error(ArgumentError, "Argument yyyyqq can't be nil") end it "when year is a alpha" do - expect {Periods::YearQuarter.new("yearQ1")}.to raise_error('invalid value for Integer(): "year"') + expect { Periods::YearQuarter.new("yearQ1") }.to raise_error('invalid value for Integer(): "year"') end it "when no Q for quarter" do - expect {Periods::YearQuarter.new("201601")}.to raise_error("no a valid quarter number for '201601'") + expect { Periods::YearQuarter.new("201601") }.to raise_error("no a valid quarter number for '201601'") end it "when alha for Q for quarter" do - expect {Periods::YearQuarter.new("2016Qa")}.to raise_error('invalid value for Integer(): "a"') + expect { Periods::YearQuarter.new("2016Qa") }.to raise_error('invalid value for Integer(): "a"') end end @@ -58,7 +58,7 @@ expect(Periods::YearQuarter.from_year_month(2016, 12).to_s).to eq "2016Q4" end it "should be immutable" do - expect { year_quarter.months.delete_at(1) }.to raise_error("can't modify frozen Array") + expect { year_quarter.months.delete_at(1) }.to raise_error(FrozenError) end end From 9a361dc0db23df245c8f2876b7ba250ab258265f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 13:24:44 +0100 Subject: [PATCH 12/26] Allow redirect to external server --- app/controllers/oauth/oauth_controller.rb | 59 +++++++++++++++-------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/app/controllers/oauth/oauth_controller.rb b/app/controllers/oauth/oauth_controller.rb index ac83ed44..ea1c3af3 100644 --- a/app/controllers/oauth/oauth_controller.rb +++ b/app/controllers/oauth/oauth_controller.rb @@ -1,48 +1,57 @@ -require 'net/http' -require 'uri' +require "net/http" +require "uri" class Oauth::OauthController < Devise::OmniauthCallbacksController def dhis2_login # https://sandbox.bluesquare.org/uaa/oauth/authorize?client_id=[client_id]&response_type=code - program = Program.find(params["program_id"]) rescue nil + program = begin + Program.find(params["program_id"]) + rescue StandardError + nil + end if program.nil? - flash[:failure] = "Log-in failed: program with ID #{params["program_id"]} does not exist" + flash[:failure] = "Log-in failed: program with ID #{params['program_id']} does not exist" redirect_to("/users/sign_in") return end oauth_client_id = program.oauth_client_id - + if oauth_client_id.blank? - flash[:failure] = "Log-in failed: program with ID #{params["program_id"]} is not configured for sign-in with DHIS2" + flash[:failure] = +"Log-in failed: program with ID #{params['program_id']} is not configured for sign-in with DHIS2" redirect_to("/users/sign_in") return end url_redirect = program.project_anchor.project.dhis2_url + "/uaa/oauth/authorize?client_id=#{oauth_client_id}&response_type=code" - redirect_to(url_redirect) + redirect_to(url_redirect, allow_other_host: true) end def callback - program = Program.find(params["program_id"]) rescue nil + program = begin + Program.find(params["program_id"]) + rescue StandardError + nil + end if program.nil? - flash[:failure] = "Log-in failed: program with ID #{params["program_id"]} does not exist" + flash[:failure] = "Log-in failed: program with ID #{params['program_id']} does not exist" redirect_to("/users/sign_in") return end - + url_post = program.project_anchor.project.dhis2_url + "/uaa/oauth/token" - + uri = URI.parse(url_post) request = Net::HTTP::Post.new(uri) request.basic_auth(program.oauth_client_id, program.oauth_client_secret) request["Accept"] = "application/json" request.set_form_data( - "code" => params["code"], + "code" => params["code"], "grant_type" => "authorization_code" ) req_options = { @@ -58,7 +67,11 @@ def callback return end - access_token = JSON.parse(response.body)["access_token"] rescue nil + access_token = begin + JSON.parse(response.body)["access_token"] + rescue StandardError + nil + end if access_token.nil? flash[:failure] = "Log-in failed: bad response from DHIS2, please check the logs" @@ -66,9 +79,14 @@ def callback return end - user_info = RestClient.get(program.project_anchor.project.dhis2_url + "/api/me", { "Authorization": "Bearer #{access_token}" }) + user_info = RestClient.get(program.project_anchor.project.dhis2_url + "/api/me", + { "Authorization": "Bearer #{access_token}" }) - user_info = JSON.parse(user_info) rescue nil + user_info = begin + JSON.parse(user_info) + rescue StandardError + nil + end if user_info.nil? flash[:failure] = "Log-in failed: bad response from DHIS2, please check the logs" @@ -79,13 +97,14 @@ def callback dhis2_user_ref = user_info["id"] user = program.users.find_by_dhis2_user_ref(dhis2_user_ref) - + if user sign_in_and_redirect(user) - else - flash[:failure] = "Log-in failed: no ORBF2 user associated to the DHIS2 user with name #{user_info["displayName"]} and ID #{dhis2_user_ref}" + else + flash[:failure] = +"Log-in failed: no ORBF2 user associated to the DHIS2 user with name #{user_info['displayName']} and ID #{dhis2_user_ref}" redirect_to("/users/sign_in") - return + nil end end -end \ No newline at end of file +end From 249c032c243579e0c600ff0b239ad13ce6443a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 14:27:36 +0100 Subject: [PATCH 13/26] Metadata initialize/new keyword args fix --- app/services/meta/meta_data_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/meta/meta_data_service.rb b/app/services/meta/meta_data_service.rb index 6cf79a6a..e5d59778 100644 --- a/app/services/meta/meta_data_service.rb +++ b/app/services/meta/meta_data_service.rb @@ -40,7 +40,7 @@ def build_package_formula_mappings_meta_datas def new_meta_formula_mapping(formula_mapping, package) name = formula_mapping.names Meta::Metadata.new( - dhis2_props(formula_mapping.external_reference).merge( + **dhis2_props(formula_mapping.external_reference).merge( formula_mapping: formula_mapping, package: package, orbf_type: "Formula mapping", @@ -68,7 +68,7 @@ def new_meta_activity_state(activity_state, activity_package) project.naming_patterns, activity_state.activity ) Meta::Metadata.new( - dhis2_props(activity_state.external_reference).merge( + **dhis2_props(activity_state.external_reference).merge( activity_state: activity_state, package: activity_package.package, orbf_type: "Activity state", From 260355992c764906347e064976ffde0c4d06afa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 15:27:30 +0100 Subject: [PATCH 14/26] Missing version associtations column --- ...dd_foreign_type_to_version_associations.rb | 21 +++++++++++++++++++ db/schema.rb | 5 +++-- 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20230118133922_add_foreign_type_to_version_associations.rb diff --git a/db/migrate/20230118133922_add_foreign_type_to_version_associations.rb b/db/migrate/20230118133922_add_foreign_type_to_version_associations.rb new file mode 100644 index 00000000..3778ab96 --- /dev/null +++ b/db/migrate/20230118133922_add_foreign_type_to_version_associations.rb @@ -0,0 +1,21 @@ +# This migration and AddTransactionIdColumnToVersions provide the necessary +# schema for tracking associations. +class AddForeignTypeToVersionAssociations < ActiveRecord::Migration[7.0] + def self.up + add_column :version_associations, :foreign_type, :string, index: true + remove_index :version_associations, + name: "index_version_associations_on_foreign_key" + add_index :version_associations, + %i(foreign_key_name foreign_key_id foreign_type), + name: "index_version_associations_on_foreign_key" + end + + def self.down + remove_index :version_associations, + name: "index_version_associations_on_foreign_key" + remove_column :version_associations, :foreign_type + add_index :version_associations, + %i(foreign_key_name foreign_key_id), + name: "index_version_associations_on_foreign_key" + end +end diff --git a/db/schema.rb b/db/schema.rb index 981ee6f0..dc7b4c22 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_01_17_110950) do +ActiveRecord::Schema[7.0].define(version: 2023_01_18_133922) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "uuid-ossp" @@ -363,7 +363,8 @@ t.integer "version_id" t.string "foreign_key_name", null: false t.integer "foreign_key_id" - t.index ["foreign_key_name", "foreign_key_id"], name: "index_version_associations_on_foreign_key" + t.string "foreign_type" + t.index ["foreign_key_name", "foreign_key_id", "foreign_type"], name: "index_version_associations_on_foreign_key" t.index ["version_id"], name: "index_version_associations_on_version_id" end From dba34fc3d37f7c12de60bc9c06800c16b729e995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 15:27:57 +0100 Subject: [PATCH 15/26] Delete unused spec --- spec/lib/font_awesome_upgrade_spec.rb | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 spec/lib/font_awesome_upgrade_spec.rb diff --git a/spec/lib/font_awesome_upgrade_spec.rb b/spec/lib/font_awesome_upgrade_spec.rb deleted file mode 100644 index d2e8e209..00000000 --- a/spec/lib/font_awesome_upgrade_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -require "rails_helper" - -RSpec.describe "Font Awesome" do - it 'alerts the developer if font-awesome-rails ever goes away' do - unless defined?(FontAwesome::Rails) - message = <<~STR - font-awesome-rails is dead, long live font-awesome! - - Great, font-awesome-rails disappeared from out stack. Less great is that now no one is providing us with the font-awesome assets. So to fix that: - - - Add the font-awesome-sass gem - - Remove our icon-helper - - Look for fa5 and fix those - - Remove this test - - Profit! - STR - fail message - end - end -end From ec60d30f04c4284bf5dbab7f8833ec40b45983a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 15:31:59 +0100 Subject: [PATCH 16/26] Fix clone rspec to ignore ActiveRecord::InternalMetadata --- spec/services/project_factory_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/services/project_factory_spec.rb b/spec/services/project_factory_spec.rb index 97f699ab..618350ee 100644 --- a/spec/services/project_factory_spec.rb +++ b/spec/services/project_factory_spec.rb @@ -25,7 +25,8 @@ PaperTrail::Version, PaperTrail::VersionAssociation, Flipper::Adapters::ActiveRecord::Feature, - Flipper::Adapters::ActiveRecord::Gate + Flipper::Adapters::ActiveRecord::Gate, + ActiveRecord::InternalMetadata ].freeze NON_PROJECT_AR = [ @@ -78,7 +79,7 @@ end old_activity_ids = project.activities.map(&:id) - formula_mappings_with_bad_activities = new_draft.packages.flat_map { |p| p.activity_rule.formulas.flat_map(&:formula_mappings)}.select { |fm| old_activity_ids.include?(fm.activity_id) } + formula_mappings_with_bad_activities = new_draft.packages.flat_map { |p| p.activity_rule.formulas.flat_map(&:formula_mappings) }.select { |fm| old_activity_ids.include?(fm.activity_id) } expect(formula_mappings_with_bad_activities).to(eq([])) end From 784f446b5e048c9eca95ca508b0d67f193553032 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 15:46:32 +0100 Subject: [PATCH 17/26] Fix url validator --- app/models/url_validator.rb | 2 +- spec/models/project_spec.rb | 2 +- spec/services/project_factory_spec.rb | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/url_validator.rb b/app/models/url_validator.rb index dae11808..01b3c740 100644 --- a/app/models/url_validator.rb +++ b/app/models/url_validator.rb @@ -8,6 +8,6 @@ def validate_each(record, attribute, value) rescue URI::InvalidURIError resp = false end - record.errors[attribute] << (options[:message] || "is not an url") unless resp == true + record.errors.add(attribute, (options[:message] || "is not an url")) unless resp == true end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 99298384..12a81c0d 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -53,7 +53,7 @@ it "should validate url " do expect(project.valid?).to eq true - project.dhis2_url = "http://bad:userexport@/dev:456.url" + project.dhis2_url = "http://:456.url" expect(project.valid?).to eq false end diff --git a/spec/services/project_factory_spec.rb b/spec/services/project_factory_spec.rb index 618350ee..97bdad46 100644 --- a/spec/services/project_factory_spec.rb +++ b/spec/services/project_factory_spec.rb @@ -26,7 +26,8 @@ PaperTrail::VersionAssociation, Flipper::Adapters::ActiveRecord::Feature, Flipper::Adapters::ActiveRecord::Gate, - ActiveRecord::InternalMetadata + ActiveRecord::InternalMetadata, + ActiveStorage::VariantRecord ].freeze NON_PROJECT_AR = [ From 8bc11bbf596bd76f9c2657139a373dec185e8ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 16:07:41 +0100 Subject: [PATCH 18/26] Update capybara, selenium and its config --- Gemfile | 2 +- Gemfile.lock | 4 ++-- spec/support/capybara.rb | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 61afafef..e872e8c1 100644 --- a/Gemfile +++ b/Gemfile @@ -112,7 +112,7 @@ group :development, :test do gem "capybara" gem "json-diff", "~> 0.4.1" gem "rubyzip", "~> 1.3.0" - gem "selenium-webdriver" + gem "selenium-webdriver", "~> 4.7.1" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 36c0e778..5a22da12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -351,7 +351,7 @@ GEM puma (4.3.12) nio4r (~> 2.0) racc (1.6.2) - rack (2.2.6) + rack (2.2.6.2) rack-mini-profiler (3.0.0) rack (>= 1.2.0) rack-protection (3.0.5) @@ -623,7 +623,7 @@ DEPENDENCIES ruby-prof rubyzip (~> 1.3.0) sassc-rails (~> 2.1.2) - selenium-webdriver + selenium-webdriver (~> 4.7.1) sentry-raven (~> 2.7.4) shoulda-matchers sidekiq (< 6) diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index b10a2f40..38c27857 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -26,8 +26,8 @@ Capybara::Selenium::Driver.new( app, - browser: :chrome, - desired_capabilities: capabilities, - options: options + browser: :chrome, + capabilities: capabilities, + options: options ) end From 2ac80b16368bf5551f980c376699152f8b460e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 21:04:18 +0100 Subject: [PATCH 19/26] Goodbye selenium --- Gemfile | 2 -- Gemfile.lock | 19 ----------------- spec/rails_helper.rb | 9 -------- spec/support/capybara.rb | 33 ----------------------------- spec/system/admin_dashboard_spec.rb | 14 ------------ 5 files changed, 77 deletions(-) delete mode 100644 spec/support/capybara.rb delete mode 100644 spec/system/admin_dashboard_spec.rb diff --git a/Gemfile b/Gemfile index e872e8c1..2c351876 100644 --- a/Gemfile +++ b/Gemfile @@ -109,10 +109,8 @@ group :development, :test do gem "ruby-prof" gem "shoulda-matchers", require: false - gem "capybara" gem "json-diff", "~> 0.4.1" gem "rubyzip", "~> 1.3.0" - gem "selenium-webdriver", "~> 4.7.1" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 5a22da12..886a769c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -142,15 +142,6 @@ GEM sassc (>= 2.0.0) builder (3.2.4) byebug (11.1.3) - capybara (3.38.0) - addressable - matrix - mini_mime (>= 0.1.3) - nokogiri (~> 1.8) - rack (>= 1.6.0) - rack-test (>= 0.6.3) - regexp_parser (>= 1.5, < 3.0) - xpath (~> 3.2) cocoon (1.2.15) coderay (1.1.3) coffee-rails (4.2.2) @@ -283,7 +274,6 @@ GEM net-pop net-smtp marcel (1.0.2) - matrix (0.4.2) memory_profiler (1.0.1) method_source (1.0.0) mime-types (3.4.1) @@ -474,10 +464,6 @@ GEM sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) - selenium-webdriver (4.7.1) - rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) - websocket (~> 1.0) sentry-raven (2.7.4) faraday (>= 0.7.6, < 1.0) sexp_processor (4.16.1) @@ -546,12 +532,9 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - xpath (3.2.0) - nokogiri (~> 1.8) zeitwerk (2.6.6) PLATFORMS @@ -565,7 +548,6 @@ DEPENDENCIES bootstrap-datepicker-rails bootstrap-sass (~> 3.4.1) byebug - capybara cocoon coffee-rails (~> 4.2) database_cleaner @@ -623,7 +605,6 @@ DEPENDENCIES ruby-prof rubyzip (~> 1.3.0) sassc-rails (~> 2.1.2) - selenium-webdriver (~> 4.7.1) sentry-raven (~> 2.7.4) shoulda-matchers sidekiq (< 6) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 677dda90..273c7f79 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -55,15 +55,6 @@ # The different available types are documented in the features, such as in # https://relishapp.com/rspec/rspec-rails/docs config.infer_spec_type_from_file_location! - - config.before(:each, type: :system) do - if ENV["SHOW_BROWSER"] - # This can be handy when diagnosing system tests that break - driven_by :selenium, using: :chrome, screen_size: [1400, 1400] - else - driven_by :headless_chrome - end - end end Shoulda::Matchers.configure do |config| diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb deleted file mode 100644 index 38c27857..00000000 --- a/spec/support/capybara.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -Capybara.register_driver :headless_chrome do |app| - capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( - # This enables access to logs with `page.driver.manage.get_log(:browser)` - loggingPrefs: { - browser: "ALL", - client: "ALL", - driver: "ALL", - server: "ALL" - } - ) - - options = Selenium::WebDriver::Chrome::Options.new - options.add_argument("window-size=1400,1400") - - # Chrome won't work properly in a Docker container in sandbox mode - # because the user namespace is not enabled in the container by default - options.add_argument("no-sandbox") - - # Run headless by default unless CHROME_HEADLESS specified - options.add_argument("headless") unless ENV["CHROME_HEADLESS"] =~ /^(false|no|0)$/i - - # Disable /dev/shm use in CI. See https://gitlab.com/gitlab-org/gitlab-ee/issues/4252 - options.add_argument("disable-dev-shm-usage") if ENV["CI"] || ENV["CI_SERVER"] - - Capybara::Selenium::Driver.new( - app, - browser: :chrome, - capabilities: capabilities, - options: options - ) -end diff --git a/spec/system/admin_dashboard_spec.rb b/spec/system/admin_dashboard_spec.rb deleted file mode 100644 index 11ec7568..00000000 --- a/spec/system/admin_dashboard_spec.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe "Rails Admin" do - before do - WebMock.disable_net_connect!(allow_localhost: true) - end - - it "can load the dashboard" do - visit rails_admin.dashboard_url - expect(page).to have_content "Scorpio Admin" - end -end From d8d802abb6691b9a1c39cefa5ee73bbcf9bea521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 21:14:03 +0100 Subject: [PATCH 20/26] Don't launch system tests --- script/cibuild | 5 ----- 1 file changed, 5 deletions(-) diff --git a/script/cibuild b/script/cibuild index b431ace6..b5a22c90 100755 --- a/script/cibuild +++ b/script/cibuild @@ -29,11 +29,6 @@ fi script/test status=$? -echo "[cibuild] Running system tests ..." -date "+%H:%M:%S" -SKIP_SIMPLECOV=1 bundle exec rails spec:system -status=$? - echo "[cibuild] Running data tests ..." date "+%H:%M:%S" SKIP_SIMPLECOV=1 bundle exec rails spec:data_test From 60e1df9cbba7a78202d811651dc2ccf6e3bfd480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 21:15:09 +0100 Subject: [PATCH 21/26] Stop caching chromedriver --- .github/workflows/ci.yml | 55 ++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 881e30e2..a39574e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,33 +33,28 @@ jobs: --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 - - name: Set up Ruby (uses .ruby-version) - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true # runs 'bundle install' and caches installed gems automatically - - name: Install postgres client - run: sudo apt-get install libpq-dev - - name: Cache chromedriver - uses: actions/cache@v2 - with: - path: "/usr/local/share/chromedriver" - key: chromedriver-${{ runner.os }}-${{ hashFiles('/usr/local/share/chromedriver') }} - - name: Cache clode climate reporter - uses: actions/cache@v2 - with: - path: "cc-test-reporter" - key: cc-${{ runner.os }}-${{ hashFiles('./cc-test-reporter') }} - - name: script/cibuild - run: | - script/cibuild - env: - DB_PASSWORD: ${{ env.POSTGRES_PASSWORD }} - DB_NAME: ${{ env.POSTGRES_DB }} - DB_USER: ${{ env.POSTGRES_USER }} - REDIS_URL: redis://localhost:6379/0 - DATA_TEST_S3_BUCKET: ${{ secrets.DATA_TEST_S3_BUCKET }} - DATA_TEST_S3_REGION: ${{ secrets.DATA_TEST_S3_REGION }} - FETCHER_S3_ACCESS: ${{ secrets.FETCHER_S3_ACCESS }} - FETCHER_S3_KEY: ${{ secrets.FETCHER_S3_KEY }} - CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} + - uses: actions/checkout@v2 + - name: Set up Ruby (uses .ruby-version) + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + - name: Install postgres client + run: sudo apt-get install libpq-dev + - name: Cache clode climate reporter + uses: actions/cache@v2 + with: + path: "cc-test-reporter" + key: cc-${{ runner.os }}-${{ hashFiles('./cc-test-reporter') }} + - name: script/cibuild + run: | + script/cibuild + env: + DB_PASSWORD: ${{ env.POSTGRES_PASSWORD }} + DB_NAME: ${{ env.POSTGRES_DB }} + DB_USER: ${{ env.POSTGRES_USER }} + REDIS_URL: redis://localhost:6379/0 + DATA_TEST_S3_BUCKET: ${{ secrets.DATA_TEST_S3_BUCKET }} + DATA_TEST_S3_REGION: ${{ secrets.DATA_TEST_S3_REGION }} + FETCHER_S3_ACCESS: ${{ secrets.FETCHER_S3_ACCESS }} + FETCHER_S3_KEY: ${{ secrets.FETCHER_S3_KEY }} + CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} From fb9e65a39b7b0c32f9930b97605e44fb6c79992d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 21:16:42 +0100 Subject: [PATCH 22/26] Stop installing chrome driver --- script/setup | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/script/setup b/script/setup index 955f1bc1..b28a59a9 100755 --- a/script/setup +++ b/script/setup @@ -33,45 +33,6 @@ if [ -z "${CI+x}" ]; then createuser --superuser --createdb hesabu-test-user fi else - # We're on CI - if ! command -v chromedriver &> /dev/null; then - echo "Chromedriver was already found" - which chromedriver - chromedriver --version - whoami - else - cat < $(/usr/bin/chromedriver --version) - - chromedriver --version - -> $(chromedriver --version) - - path - -> ${PATH} - - Me - -> $(whoami) - -STR - - if [ -f "/usr/local/bin/chromedriver" ]; then - echo "==> Using cached chromedriver" - sudo chmod +x /usr/local/share/chromedriver - sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver - else - echo "==> Fetching chromedriver" - version=$(curl -s https://chromedriver.storage.googleapis.com/LATEST_RELEASE) - wget -N https://chromedriver.storage.googleapis.com/$version/chromedriver_linux64.zip -P ~/ - unzip ~/chromedriver_linux64.zip -d ~/ - rm ~/chromedriver_linux64.zip - sudo mv -f ~/chromedriver /usr/local/share/ - sudo chmod +x /usr/local/share/chromedriver - sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver - fi - fi export RAILS_ENV="test" export RACK_ENV="test" export CI="CIJOE" From ed761f0323cf0119ee4cfc4aa39486bf8896a73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Wed, 18 Jan 2023 21:20:28 +0100 Subject: [PATCH 23/26] Forget about system tests --- lib/tasks/spec.rake | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 101fc5df..913ca983 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -4,7 +4,6 @@ if Rake::Task.task_defined?("spec") Rake::Task["spec"].clear # Clear out rspec/rails tasks as well, to avoid double run Rake::Task["spec:models"].clear - Rake::Task["spec:system"].clear end namespace :spec do @@ -16,14 +15,6 @@ namespace :spec do run_commands(cmds) end - desc "Run feature/request/system specs" - task :system do - cmds = [ - %w[rspec spec --tag @type:system] - ] - run_commands(cmds) - end - desc "Run full data test" task :data_test do cmds = [ From 6b5a40db54c016adb8e8b15ca4b6d0701f88b71e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Fri, 20 Jan 2023 15:11:05 +0100 Subject: [PATCH 24/26] Upgrade ruby, Allow docker compose .env --- .gitignore | 2 +- Dockerfile.build | 14 +++---- Gemfile | 2 +- Gemfile.lock | 6 +-- config/environments/production.rb | 9 ++-- docker/.env | 12 ++++++ docker/docker-compose.yml | 70 +++++++++++++++++++++++++++++++ 7 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 docker/.env create mode 100644 docker/docker-compose.yml diff --git a/.gitignore b/.gitignore index 64ef54eb..7d248786 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,7 @@ dump.rdb coverage spec/artefacts/* config/data_test.json -.env* +./.env* # I, pj, still vendor my ruby gems in the directory of the # application, this stops me from committing them here. diff --git a/Dockerfile.build b/Dockerfile.build index 4cef3c7d..d13d008a 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -1,4 +1,4 @@ -FROM ruby:2.5.8-alpine AS build-env +FROM ruby:3.2.0-alpine AS build-env ARG RAILS_ROOT=/app ARG BUILD_PACKAGES="build-base curl-dev git" @@ -19,23 +19,23 @@ RUN apk update \ COPY Gemfile* ./ # install rubygem COPY Gemfile Gemfile.lock $RAILS_ROOT/ -RUN gem update --system 3.2.3 && gem install bundler -i 2.2.3 && bundle config set --local without 'development test' && bundle config set --local path 'vendor/bundle' +RUN gem update --system 3.4.1 && gem install bundler -i 2.4.4 && bundle config set --local without 'development test' && bundle config set --local path 'vendor/bundle' RUN bundle install \ - && rm -rf vendor/bundle/ruby/2.5.0/cache/*.gem \ - && find vendor/bundle/ruby/2.5.0/gems/ -name "*.c" -delete \ - && find vendor/bundle/ruby/2.5.0/gems/ -name "*.o" -delete + && rm -rf vendor/bundle/ruby/3.2.0/cache/*.gem \ + && find vendor/bundle/ruby/3.2.0/gems/ -name "*.c" -delete \ + && find vendor/bundle/ruby/3.2.0/gems/ -name "*.o" -delete COPY . . RUN DATABASE_URL=nulldb:://null SECRET_KEY_BASE=1 RAILS_ENV=production bundle exec rake assets:precompile --trace # Remove folders not needed in resulting image RUN rm -rf node_modules tmp/cache app/assets vendor/assets spec -FROM ruby:2.5.8-alpine +FROM ruby:3.2.0-alpine ARG RAILS_ROOT=/app ARG PACKAGES="tzdata postgresql-client nodejs bash curl-dev" ENV RAILS_ENV=production ENV BUNDLE_APP_CONFIG="$RAILS_ROOT/.bundle" -RUN gem update --system 3.2.3 && gem install bundler -i 2.2.3 +RUN gem update --system 3.4.1 && gem install bundler -i 2.4.4 WORKDIR $RAILS_ROOT # install packages RUN apk update \ diff --git a/Gemfile b/Gemfile index 2c351876..1bdcd251 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,7 @@ gem "jquery-ui-rails", "~> 5.0.5" gem "rails-jquery-autocomplete" gem "sassc-rails", "~> 2.1.2" gem "simple_form" -gem "sprockets", "~> 3.7.2" +gem "sprockets", "~> 4.2.0" gem "turbolinks", "~> 5" gem "uglifier", ">= 1.3.0" ## Authentication diff --git a/Gemfile.lock b/Gemfile.lock index 886a769c..3245cf4b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -491,9 +491,9 @@ GEM spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) - sprockets (3.7.2) + sprockets (4.2.0) concurrent-ruby (~> 1.0) - rack (> 1, < 3) + rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) @@ -613,7 +613,7 @@ DEPENDENCIES simplecov spring spring-watcher-listen (~> 2.0.0) - sprockets (~> 3.7.2) + sprockets (~> 4.2.0) stackprof turbolinks (~> 5) typhoeus (~> 1.3.1) diff --git a/config/environments/production.rb b/config/environments/production.rb index 09586d39..44e2bc1b 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -23,9 +23,10 @@ config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Compress JavaScripts and CSS. - config.assets.js_compressor = Uglifier.new(harmony: true) - # config.assets.css_compressor = :sass - + config.assets.configure do |env| + env.js_compressor = :uglifier # or :closure, :yui + env.css_compressor = :sass # or :yui + end # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false @@ -38,7 +39,7 @@ # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX - config.active_storage.service = ENV.fetch("RAILS_ACTIVE_STORAGE", 'amazon') + config.active_storage.service = ENV.fetch("RAILS_ACTIVE_STORAGE", "amazon") # Mount Action Cable outside main process or domain # config.action_cable.mount_path = nil diff --git a/docker/.env b/docker/.env new file mode 100644 index 00000000..9a7b3cc0 --- /dev/null +++ b/docker/.env @@ -0,0 +1,12 @@ +HESABU_VERSION=ed761f0.. +REDIS_VERSION=5.0.6 +REDIS_PASSWORD=zersdfsdf +POSTGRES_VERSION=14.5 +POSTGRES_USER=orbf2 +POSTGRES_PASSWORD=12346547sdqd +POSTGRES_DB=orbf2-demo +MINIO_ROOT_USER=miniousr +MINIO_ROOT_PASSWORD=r8fgfd54g +MINIO_URL=http://minio +SECRET_KEY_BASE=a0d3846d697ce472fcbcce09bbe301482c56e41366bfa011511c82dca294b94b2de06bcb2f18d590b5603fd71e4aba33eeb81bb4f934f0b6ca8709832a8111d0 +ADMIN_PASSWORD=demoadmin diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 00000000..0f0c5e4a --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,70 @@ +version: "3" +services: + hesabu-db: + image: postgres:${POSTGRES_VERSION} + volumes: + - ./storage/db:/var/lib/postgresql/data + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: ${POSTGRES_DB} + + hesabu-redis: + image: redis:${REDIS_VERSION} + command: redis-server --requirepass ${REDIS_PASSWORD} + + hesabu-web: + image: blsq/hesabu + build: + context: .. + dockerfile: Dockerfile.build + command: bash -c "bundle exec rake db:migrate && rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" + ports: + - "3000:3000" + depends_on: + - hesabu-db + - hesabu-redis + environment: + - REDIS_URL=redis://:${REDIS_PASSWORD}@hesabu-redis:6379 + - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@hesabu-db:5432/${POSTGRES_DB} + - ADMIN_PASSWORD=${ADMIN_PASSWORD} + - DISABLE_FORCE_SSL=TRUE + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RAILS_ACTIVE_STORAGE=minio + - S3_SIMULATION_ACCESS=${MINIO_ROOT_USER} + - S3_SIMULATION_BUCKET=simulation + - S3_SIMULATION_REGION=us-east-1 + - S3_SIMULATION_SECRET=${MINIO_ROOT_PASSWORD} + - S3_SIMULATION_ENDPOINT=${MINIO_URL} + - RAILS_SERVE_STATIC_FILES=true + labels: + - "ofelia.enabled=true" + # job1 to flag in db jobs no more appearing in sidekiq + - "ofelia.job-exec.invoicing_jobs.schedule=@every 10m" + - "ofelia.job-exec.invoicing_jobs.command=rake invoicing_jobs:discard" + # job2 to remove from sidekiq queue duplicated jobs + - "ofelia.job-exec.duplicate_jobs.schedule=@every 11m" + - "ofelia.job-exec.duplicate_jobs.command=rake duplicate_jobs:clear" + + hesabu-worker: + image: blsq/hesabu + build: + context: .. + dockerfile: Dockerfile.build + command: bash -c "bundle exec sidekiq -q dhis2-safe -q default" + depends_on: + - hesabu-db + - hesabu-redis + environment: + - REDIS_URL=redis://:${REDIS_PASSWORD}@hesabu-redis:6379 + - DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@hesabu-db:5432/${POSTGRES_DB} + - RAILS_ENV=production + - RACK_ENV=production + - SECRET_KEY_BASE=${SECRET_KEY_BASE} + - RAILS_ACTIVE_STORAGE=minio + - S3_SIMULATION_ACCESS=${MINIO_ROOT_USER} + - S3_SIMULATION_BUCKET=simulation + - S3_SIMULATION_REGION=us-east-1 + - S3_SIMULATION_SECRET=${MINIO_ROOT_PASSWORD} + - S3_SIMULATION_ENDPOINT=${MINIO_URL} + - RAILS_SERVE_STATIC_FILES=true From 8020dcede014b74ff1ce64ddbe317c10ec5b64fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Mon, 23 Jan 2023 13:03:26 +0100 Subject: [PATCH 25/26] WIP asset upgrade and fixes --- .dockerignore | 3 ++- Dockerfile.build | 2 +- Gemfile | 4 ---- Gemfile.lock | 3 --- config/environments/production.rb | 2 +- docker/.env | 2 +- docker/README.md | 12 ++++++++++++ docker/docker-compose.yml | 12 ++++-------- script/docker_build | 2 +- 9 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 docker/README.md diff --git a/.dockerignore b/.dockerignore index b512c09d..454ee670 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +./docker \ No newline at end of file diff --git a/Dockerfile.build b/Dockerfile.build index d13d008a..7b92bc48 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -27,7 +27,7 @@ RUN bundle install \ COPY . . RUN DATABASE_URL=nulldb:://null SECRET_KEY_BASE=1 RAILS_ENV=production bundle exec rake assets:precompile --trace # Remove folders not needed in resulting image -RUN rm -rf node_modules tmp/cache app/assets vendor/assets spec +RUN rm -rf node_modules tmp/cache vendor/assets spec FROM ruby:3.2.0-alpine diff --git a/Gemfile b/Gemfile index 1bdcd251..378987ba 100644 --- a/Gemfile +++ b/Gemfile @@ -137,9 +137,5 @@ group :test do gem "webmock" end -group :production do - gem "heroku-deflater" -end - # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 3245cf4b..f85899d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -221,8 +221,6 @@ GEM globalid (1.0.0) activesupport (>= 5.0) hashdiff (1.0.1) - heroku-deflater (0.6.3) - rack (>= 1.4.5) http-accept (1.7.0) http-cookie (1.0.5) domain_name (~> 0.5) @@ -565,7 +563,6 @@ DEPENDENCIES flipper-active_record (~> 0.26.0) flipper-ui (~> 0.26.0) hashdiff - heroku-deflater hesabu! immigrant jbuilder (~> 2.5) diff --git a/config/environments/production.rb b/config/environments/production.rb index 44e2bc1b..1b1e388f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -29,7 +29,7 @@ end # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false - + config.assets.precompile = ["manifest.js"] # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb # Enable serving of images, stylesheets, and JavaScripts from an asset server. diff --git a/docker/.env b/docker/.env index 9a7b3cc0..42b27f9d 100644 --- a/docker/.env +++ b/docker/.env @@ -1,4 +1,4 @@ -HESABU_VERSION=ed761f0.. +HESABU_VERSION=6b5a40d.local.local REDIS_VERSION=5.0.6 REDIS_PASSWORD=zersdfsdf POSTGRES_VERSION=14.5 diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..1a6f2d28 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,12 @@ +# docker compose + +the goal isn't not to be used as dev environment (make a seperate docker-compose.yml with hot reload) + +test the "official" docker image "as if in prod/local hosting" + +``` +./script/docker_build +cd docker +# update .env HESABU_VERSION with the docker_build values +docker-compose up +``` diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 0f0c5e4a..45c9f807 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -14,10 +14,7 @@ services: command: redis-server --requirepass ${REDIS_PASSWORD} hesabu-web: - image: blsq/hesabu - build: - context: .. - dockerfile: Dockerfile.build + image: blsq/hesabu:${HESABU_VERSION} command: bash -c "bundle exec rake db:migrate && rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'" ports: - "3000:3000" @@ -37,6 +34,8 @@ services: - S3_SIMULATION_SECRET=${MINIO_ROOT_PASSWORD} - S3_SIMULATION_ENDPOINT=${MINIO_URL} - RAILS_SERVE_STATIC_FILES=true + - RAILS_ENV=production + - RACK_ENV=production labels: - "ofelia.enabled=true" # job1 to flag in db jobs no more appearing in sidekiq @@ -47,10 +46,7 @@ services: - "ofelia.job-exec.duplicate_jobs.command=rake duplicate_jobs:clear" hesabu-worker: - image: blsq/hesabu - build: - context: .. - dockerfile: Dockerfile.build + image: blsq/hesabu:${HESABU_VERSION} command: bash -c "bundle exec sidekiq -q dhis2-safe -q default" depends_on: - hesabu-db diff --git a/script/docker_build b/script/docker_build index 9806c08d..67b63a1d 100755 --- a/script/docker_build +++ b/script/docker_build @@ -10,7 +10,7 @@ PATCH=`echo $DESCRIBE | awk '{split($0,a,"-"); print a[3]}'` echo "version $DESCRIBE => VERSION:${VERSION} BUILD:${BUILD} PATCH:${PATCH}" -VERSION=${VERSION}"."${BUILD}"."${PATCH} +VERSION=${VERSION}"."${BUILD:-local}"."${PATCH:-local} echo "building image with tags : ${VERSION} patch ${PATCH} ($DESCRIBE)" docker build -t blsq/hesabu:$VERSION --file Dockerfile.build . From b358702c02f9ff4605ecbd957c9f4b243f74dcbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 24 Jan 2023 09:48:26 +0100 Subject: [PATCH 26/26] rails 7.0.4.1 --- Gemfile | 2 +- Gemfile.lock | 114 +++++++++++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Gemfile b/Gemfile index 378987ba..6e53a774 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem "paper_trail-association_tracking", "~> 2.2.1" gem "pg", "~> 1.4.5" gem "puma", "~> 4.3" gem "rack", ">= 2.0.6" -gem "rails", "~> 7.0.4" +gem "rails", "~> 7.0.4.1" gem "rails_admin", "~> 3.1.1" gem "sidekiq", "< 6" gem "sidekiq-throttled", "~> 0.9.0" diff --git a/Gemfile.lock b/Gemfile.lock index f85899d0..ea507608 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,73 +36,73 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4) - actionpack (= 7.0.4) - activesupport (= 7.0.4) + actioncable (7.0.4.1) + actionpack (= 7.0.4.1) + activesupport (= 7.0.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4) - actionpack (= 7.0.4) - activejob (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + actionmailbox (7.0.4.1) + actionpack (= 7.0.4.1) + activejob (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4) - actionpack (= 7.0.4) - actionview (= 7.0.4) - activejob (= 7.0.4) - activesupport (= 7.0.4) + actionmailer (7.0.4.1) + actionpack (= 7.0.4.1) + actionview (= 7.0.4.1) + activejob (= 7.0.4.1) + activesupport (= 7.0.4.1) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.4) - actionview (= 7.0.4) - activesupport (= 7.0.4) + actionpack (7.0.4.1) + actionview (= 7.0.4.1) + activesupport (= 7.0.4.1) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4) - actionpack (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + actiontext (7.0.4.1) + actionpack (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4) - activesupport (= 7.0.4) + actionview (7.0.4.1) + activesupport (= 7.0.4.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.4) - activesupport (= 7.0.4) + activejob (7.0.4.1) + activesupport (= 7.0.4.1) globalid (>= 0.3.6) - activemodel (7.0.4) - activesupport (= 7.0.4) + activemodel (7.0.4.1) + activesupport (= 7.0.4.1) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (7.0.4) - activemodel (= 7.0.4) - activesupport (= 7.0.4) + activerecord (7.0.4.1) + activemodel (= 7.0.4.1) + activesupport (= 7.0.4.1) activerecord-nulldb-adapter (0.8.0) activerecord (>= 5.2.0, < 7.1) - activestorage (7.0.4) - actionpack (= 7.0.4) - activejob (= 7.0.4) - activerecord (= 7.0.4) - activesupport (= 7.0.4) + activestorage (7.0.4.1) + actionpack (= 7.0.4.1) + activejob (= 7.0.4.1) + activerecord (= 7.0.4.1) + activesupport (= 7.0.4.1) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.4) + activesupport (7.0.4.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -152,7 +152,7 @@ GEM execjs coffee-script-source (1.12.2) colorize (0.8.1) - concurrent-ruby (1.1.10) + concurrent-ruby (1.2.0) connection_pool (2.3.0) crack (0.4.5) rexml @@ -218,7 +218,7 @@ GEM gitlab (4.19.0) httparty (~> 0.20) terminal-table (>= 1.5.1) - globalid (1.0.0) + globalid (1.0.1) activesupport (>= 5.0) hashdiff (1.0.1) http-accept (1.7.0) @@ -346,20 +346,20 @@ GEM rack rack-test (2.0.2) rack (>= 1.3) - rails (7.0.4) - actioncable (= 7.0.4) - actionmailbox (= 7.0.4) - actionmailer (= 7.0.4) - actionpack (= 7.0.4) - actiontext (= 7.0.4) - actionview (= 7.0.4) - activejob (= 7.0.4) - activemodel (= 7.0.4) - activerecord (= 7.0.4) - activestorage (= 7.0.4) - activesupport (= 7.0.4) + rails (7.0.4.1) + actioncable (= 7.0.4.1) + actionmailbox (= 7.0.4.1) + actionmailer (= 7.0.4.1) + actionpack (= 7.0.4.1) + actiontext (= 7.0.4.1) + actionview (= 7.0.4.1) + activejob (= 7.0.4.1) + activemodel (= 7.0.4.1) + activerecord (= 7.0.4.1) + activestorage (= 7.0.4.1) + activesupport (= 7.0.4.1) bundler (>= 1.15.0) - railties (= 7.0.4) + railties (= 7.0.4.1) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -367,7 +367,7 @@ GEM rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.4.4) + rails-html-sanitizer (1.5.0) loofah (~> 2.19, >= 2.19.1) rails-jquery-autocomplete (1.0.5) rails (>= 3.2) @@ -377,9 +377,9 @@ GEM nested_form (~> 0.3) rails (>= 6.0, < 8) turbo-rails (~> 1.0) - railties (7.0.4) - actionpack (= 7.0.4) - activesupport (= 7.0.4) + railties (7.0.4.1) + actionpack (= 7.0.4.1) + activesupport (= 7.0.4.1) method_source rake (>= 12.2) thor (~> 1.0) @@ -589,7 +589,7 @@ DEPENDENCIES puma (~> 4.3) rack (>= 2.0.6) rack-mini-profiler - rails (~> 7.0.4) + rails (~> 7.0.4.1) rails-controller-testing rails-jquery-autocomplete rails_admin (~> 3.1.1)