diff --git a/.ruby-version b/.ruby-version index 15a27998..9c25013d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.0 +3.3.6 diff --git a/.tool-versions b/.tool-versions index 02c5ae8a..50fa0015 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,2 +1,2 @@ -ruby 3.3.0 +ruby 3.3.6 nodejs 20.10.0 diff --git a/Dockerfile b/Dockerfile index f81a9173..3ff411a1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:3.3.0 +FROM ruby:3.3.6 # Install packages RUN apt-get update && apt-get install -y build-essential nodejs libpq-dev npm fop=1:2.* libsaxon-java libsaxonb-java chromium \ diff --git a/Gemfile b/Gemfile index 0101fe06..603cfd89 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,11 @@ source 'https://rubygems.org' -ruby '3.3.0' +ruby '3.3.6' gem 'rails', '~> 7.1' gem 'rails-i18n' -gem 'pg', '~> 1.5' +gem 'pg' gem 'with_advisory_lock' gem 'puma', '~> 6.4' @@ -13,8 +13,8 @@ gem 'puma', '~> 6.4' gem 'turbo-rails' # Styles -gem 'sprockets-rails' gem 'importmap-rails' +gem 'sprockets-rails' gem 'tailwindcss-rails' gem 'view_component' @@ -22,7 +22,7 @@ gem 'view_component' gem 'clockwork' # Workers -gem 'good_job' +gem 'good_job', '3.99' # intermediate version to avoid breaking changes # Auth gem 'omniauth-google-oauth2' diff --git a/Gemfile.lock b/Gemfile.lock index 4362ba58..dc151130 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,83 +1,80 @@ GEM remote: https://rubygems.org/ specs: - Ascii85 (1.1.0) - actioncable (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) + Ascii85 (2.0.1) + actioncable (7.2.2) + actionpack (= 7.2.2) + activesupport (= 7.2.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.3) - actionpack (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activesupport (= 7.1.3) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp + actionmailbox (7.2.2) + actionpack (= 7.2.2) + activejob (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) + mail (>= 2.8.0) + actionmailer (7.2.2) + actionpack (= 7.2.2) + actionview (= 7.2.2) + activejob (= 7.2.2) + activesupport (= 7.2.2) + mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.1.3) - actionview (= 7.1.3) - activesupport (= 7.1.3) + actionpack (7.2.2) + actionview (= 7.2.2) + activesupport (= 7.2.2) nokogiri (>= 1.8.5) racc - rack (>= 2.2.4) + rack (>= 2.2.4, < 3.2) rack-session (>= 1.0.1) rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3) - actionpack (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) + useragent (~> 0.16) + actiontext (7.2.2) + actionpack (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3) - activesupport (= 7.1.3) + actionview (7.2.2) + activesupport (= 7.2.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.3) - activesupport (= 7.1.3) + activejob (7.2.2) + activesupport (= 7.2.2) globalid (>= 0.3.6) - activemodel (7.1.3) - activesupport (= 7.1.3) - activerecord (7.1.3) - activemodel (= 7.1.3) - activesupport (= 7.1.3) + activemodel (7.2.2) + activesupport (= 7.2.2) + activerecord (7.2.2) + activemodel (= 7.2.2) + activesupport (= 7.2.2) timeout (>= 0.4.0) - activestorage (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activesupport (= 7.1.3) + activestorage (7.2.2) + actionpack (= 7.2.2) + activejob (= 7.2.2) + activerecord (= 7.2.2) + activesupport (= 7.2.2) marcel (~> 1.0) - activesupport (7.1.3) + activesupport (7.2.2) base64 + benchmark (>= 0.3) bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) + concurrent-ruby (~> 1.0, >= 1.3.1) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) - mutex_m - tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) afm (0.2.2) annotate (3.2.0) activerecord (>= 3.2, < 8.0) @@ -85,21 +82,21 @@ GEM ast (2.4.2) backport (1.2.0) base64 (0.2.0) - benchmark (0.3.0) - better_html (2.0.2) + benchmark (0.4.0) + better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) ast (~> 2.0) erubi (~> 1.4) parser (>= 2.4) smart_properties - bigdecimal (3.1.6) + bigdecimal (3.1.8) bindex (0.8.1) - bootsnap (1.18.3) + bootsnap (1.18.4) msgpack (~> 1.2) - brakeman (6.1.2) + brakeman (6.2.2) racc - builder (3.2.4) + builder (3.3.0) byebug (11.1.3) capybara (3.40.0) addressable @@ -113,100 +110,106 @@ GEM capybara-screenshot (1.0.26) capybara (>= 1.0, < 4) launchy + childprocess (5.1.0) + logger (~> 1.5) clockwork (3.0.2) activesupport tzinfo coderay (1.1.3) - combine_pdf (1.0.26) - matrix - ruby-rc4 (>= 0.1.5) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) crack (1.0.0) bigdecimal rexml crass (1.0.6) - date (3.3.4) - debug (1.9.1) + date (3.4.0) + debug (1.9.2) irb (~> 1.10) reline (>= 0.3.8) diff-lcs (1.5.1) - docile (1.4.0) + docile (1.4.1) domain_name (0.6.20240107) - dotenv (3.1.0) - dotenv-rails (3.1.0) - dotenv (= 3.1.0) + dotenv (3.1.4) + dotenv-rails (3.1.4) + dotenv (= 3.1.4) railties (>= 6.1) drb (2.2.1) e2mmap (0.1.0) - erb_lint (0.5.0) + erb_lint (0.7.0) activesupport better_html (>= 2.0.1) parser (>= 2.7.1.4) rainbow - rubocop + rubocop (>= 1) smart_properties - erubi (1.12.0) - et-orbi (1.2.7) + erubi (1.13.0) + et-orbi (1.2.11) tzinfo - faraday (2.9.0) - faraday-net_http (>= 2.0, < 3.2) - faraday-net_http (3.1.0) - net-http - ffi (1.16.3) - foreman (0.87.2) - fugit (1.9.0) - et-orbi (~> 1, >= 1.2.7) + faraday (2.12.1) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-net_http (3.4.0) + net-http (>= 0.5.0) + ffi (1.17.0) + ffi (1.17.0-aarch64-linux-gnu) + ffi (1.17.0-arm64-darwin) + ffi (1.17.0-x86_64-darwin) + ffi (1.17.0-x86_64-linux-gnu) + foreman (0.88.1) + fugit (1.11.1) + et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) - good_job (3.24.0) + good_job (3.99.0) activejob (>= 6.0.0) activerecord (>= 6.0.0) concurrent-ruby (>= 1.0.2) fugit (>= 1.1) railties (>= 6.0.0) thor (>= 0.14.1) - grover (1.1.11) - combine_pdf (~> 1.0) - nokogiri (~> 1.0) - hashdiff (1.1.0) + grover (1.2.0) + nokogiri (~> 1) + hashdiff (1.1.2) hashery (2.1.2) hashie (5.0.0) - htmlbeautifier (1.4.2) + htmlbeautifier (1.4.3) http-accept (1.7.0) - http-cookie (1.0.5) + http-cookie (1.0.7) domain_name (~> 0.5) - i18n (1.14.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) - importmap-rails (2.0.1) + importmap-rails (2.0.3) actionpack (>= 6.0.0) activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.7.2) - irb (1.11.2) - rdoc + irb (1.14.1) + rdoc (>= 4.0.0) reline (>= 0.4.2) - jaro_winkler (1.5.6) - jbuilder (2.11.5) + jaro_winkler (1.6.0) + jbuilder (2.13.0) actionview (>= 5.0.0) activesupport (>= 5.0.0) - jsbundling-rails (1.3.0) + jsbundling-rails (1.3.1) railties (>= 6.0.0) - json (2.7.1) - jwt (2.8.1) + json (2.8.2) + jwt (2.9.3) base64 - kramdown (2.4.0) - rexml + kramdown (2.5.1) + rexml (>= 3.3.9) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) language_server-protocol (3.17.0.3) - launchy (2.5.2) + launchy (3.0.1) addressable (~> 2.8) - listen (3.8.0) + childprocess (~> 5.0) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.22.0) + logger (1.6.1) + loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -214,41 +217,42 @@ GEM net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) matrix (0.4.2) - method_source (1.0.0) - mime-types (3.5.2) + method_source (1.1.0) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.0206) + mime-types-data (3.2024.1105) mini_mime (1.1.5) - mini_portile2 (2.8.6) - minitest (5.22.2) - msgpack (1.7.2) - multi_xml (0.6.0) - mutex_m (0.2.0) - net-http (0.4.1) + mini_portile2 (2.8.8) + minitest (5.25.2) + msgpack (1.7.5) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + net-http (0.5.0) uri - net-imap (0.4.10) + net-imap (0.5.1) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-smtp (0.4.0.1) + net-smtp (0.5.0) net-protocol netrc (0.11.0) - nio4r (2.7.0) - nokogiri (1.16.2) + nio4r (2.7.4) + nokogiri (1.16.7) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.16.2-aarch64-linux) + nokogiri (1.16.7-aarch64-linux) racc (~> 1.4) - nokogiri (1.16.2-arm64-darwin) + nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.2-x86_64-darwin) + nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.2-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) @@ -261,79 +265,79 @@ GEM hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection - omniauth-google-oauth2 (1.1.1) - jwt (>= 2.0) - oauth2 (~> 2.0.6) + omniauth-google-oauth2 (1.2.0) + jwt (>= 2.9) + oauth2 (~> 2.0) omniauth (~> 2.0) - omniauth-oauth2 (~> 1.8.0) + omniauth-oauth2 (~> 1.8) omniauth-oauth2 (1.8.0) oauth2 (>= 1.4, < 3) omniauth (~> 2.0) - omniauth-rails_csrf_protection (1.0.1) + omniauth-rails_csrf_protection (1.0.2) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-saml (2.2.1) omniauth (~> 2.1) ruby-saml (~> 1.17) - parallel (1.24.0) - parser (3.3.0.5) + parallel (1.26.3) + parser (3.3.6.0) ast (~> 2.4.1) racc - pdf-reader (2.12.0) - Ascii85 (~> 1.0) + pdf-reader (2.13.0) + Ascii85 (>= 1.0, < 3.0, != 2.0.0) afm (~> 0.2.1) hashery (~> 2.0) ruby-rc4 ttfunk - pg (1.5.6) - pg_search (2.3.6) - activerecord (>= 5.2) - activesupport (>= 5.2) - prism (0.19.0) + pg (1.5.9) + pg_search (2.3.7) + activerecord (>= 6.1) + activesupport (>= 6.1) + prism (0.29.0) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) pry-byebug (3.10.1) byebug (~> 11.0) pry (>= 0.13, < 0.15) - pry-rails (0.3.9) - pry (>= 0.10.4) - psych (5.1.2) + pry-rails (0.3.11) + pry (>= 0.13.0) + psych (5.2.0) stringio - public_suffix (5.0.4) - puma (6.4.2) + public_suffix (6.0.1) + puma (6.5.0) nio4r (~> 2.0) - pundit (2.3.1) + pundit (2.4.0) activesupport (>= 3.0.0) raabro (1.4.0) - racc (1.7.3) - rack (3.0.9.1) + racc (1.8.1) + rack (3.1.8) rack-attack (6.7.0) rack (>= 1.0, < 4) - rack-protection (4.0.0) + rack-protection (4.1.1) base64 (>= 0.1.0) + logger (>= 1.6.0) rack (>= 3.0.0, < 4) rack-session (2.0.0) rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) - rackup (2.1.0) + rackup (2.2.1) rack (>= 3) - webrick (~> 1.8) - rails (7.1.3) - actioncable (= 7.1.3) - actionmailbox (= 7.1.3) - actionmailer (= 7.1.3) - actionpack (= 7.1.3) - actiontext (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activemodel (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) + rails (7.2.2) + actioncable (= 7.2.2) + actionmailbox (= 7.2.2) + actionmailer (= 7.2.2) + actionpack (= 7.2.2) + actiontext (= 7.2.2) + actionview (= 7.2.2) + activejob (= 7.2.2) + activemodel (= 7.2.2) + activerecord (= 7.2.2) + activestorage (= 7.2.2) + activesupport (= 7.2.2) bundler (>= 1.15.0) - railties (= 7.1.3) + railties (= 7.2.2) rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest @@ -341,29 +345,29 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - rails-i18n (7.0.8) + rails-i18n (7.0.10) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) - irb + railties (7.2.2) + actionpack (= 7.2.2) + activesupport (= 7.2.2) + irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) rainbow (3.1.1) - rake (13.1.0) + rake (13.2.1) rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) rbs (2.8.4) rdbg (0.1.0) debug (>= 1.2.2) - rdoc (6.6.2) + rdoc (6.8.1) psych (>= 4.0.0) - regexp_parser (2.9.0) - reline (0.4.3) + regexp_parser (2.9.2) + reline (0.5.11) io-console (~> 0.5) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) @@ -372,44 +376,41 @@ GEM netrc (~> 0.8) reverse_markdown (2.1.1) nokogiri - rexml (3.2.6) - rollbar (3.5.1) - rubocop (1.60.2) + rexml (3.3.9) + rollbar (3.6.0) + rubocop (1.68.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8, < 3.0) - rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + regexp_parser (>= 2.4, < 3.0) + rubocop-ast (>= 1.32.2, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-rails (2.23.1) + rubocop-ast (1.36.1) + parser (>= 3.3.1.0) + rubocop-rails (2.27.0) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.33.0, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - ruby-lsp (0.13.4) + rubocop (>= 1.52.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + ruby-lsp (0.17.2) language_server-protocol (~> 3.17.0) - prism (>= 0.19.0, < 0.20) + prism (>= 0.29.0, < 0.30) sorbet-runtime (>= 0.5.10782) - ruby-lsp-rails (0.2.9) - actionpack (>= 6.0) - activerecord (>= 6.0) - railties (>= 6.0) - ruby-lsp (>= 0.13.0, < 0.14.0) - sorbet-runtime (>= 0.5.9897) + ruby-lsp-rails (0.3.11) + ruby-lsp (>= 0.17.2, < 0.18.0) ruby-progressbar (1.13.0) ruby-rc4 (0.1.5) ruby-saml (1.17.0) nokogiri (>= 1.13.10) rexml rubyzip (2.3.2) - selenium-webdriver (4.18.1) + securerandom (0.3.2) + selenium-webdriver (4.27.0) base64 (~> 0.2) + logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) @@ -417,7 +418,7 @@ GEM docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) - simplecov-html (0.12.3) + simplecov-html (0.13.1) simplecov_json_formatter (0.1.4) smart_properties (1.17.0) snaky_hash (2.0.1) @@ -439,42 +440,41 @@ GEM thor (~> 1.0) tilt (~> 2.0) yard (~> 0.9, >= 0.9.24) - sorbet-runtime (0.5.11247) + sorbet-runtime (0.5.11663) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) - stimulus-rails (1.3.3) - railties (>= 6.0.0) - stringio (3.1.0) - tailwindcss-rails (2.3.0) - railties (>= 6.0.0) - tailwindcss-rails (2.3.0-aarch64-linux) + stimulus-rails (1.3.4) railties (>= 6.0.0) - tailwindcss-rails (2.3.0-arm64-darwin) - railties (>= 6.0.0) - tailwindcss-rails (2.3.0-x86_64-darwin) - railties (>= 6.0.0) - tailwindcss-rails (2.3.0-x86_64-linux) - railties (>= 6.0.0) - thor (1.3.1) - tilt (2.3.0) - timeout (0.4.1) - ttfunk (1.7.0) - turbo-rails (2.0.2) + stringio (3.1.2) + tailwindcss-rails (3.0.0) + railties (>= 7.0.0) + tailwindcss-ruby + tailwindcss-ruby (3.4.15) + tailwindcss-ruby (3.4.15-aarch64-linux) + tailwindcss-ruby (3.4.15-arm64-darwin) + tailwindcss-ruby (3.4.15-x86_64-darwin) + tailwindcss-ruby (3.4.15-x86_64-linux) + thor (1.3.2) + tilt (2.4.0) + timeout (0.4.2) + ttfunk (1.8.0) + bigdecimal (~> 3.1) + turbo-rails (2.0.11) actionpack (>= 6.0.0) - activejob (>= 6.0.0) railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.5.0) - uri (0.13.0) - version_gem (1.1.3) - view_component (3.10.0) - activesupport (>= 5.2.0, < 8.0) + unicode-display_width (2.6.0) + uri (1.0.2) + useragent (0.16.10) + version_gem (1.1.4) + view_component (3.20.0) + activesupport (>= 5.2.0, < 8.1) concurrent-ruby (~> 1.0) method_source (~> 1.0) web-console (4.2.1) @@ -482,12 +482,11 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.20.0) + webmock (3.24.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.1) - websocket (1.2.10) + websocket (1.2.11) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -496,8 +495,8 @@ GEM zeitwerk (>= 2.6) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.34) - zeitwerk (2.6.13) + yard (0.9.37) + zeitwerk (2.7.1) PLATFORMS aarch64-linux @@ -517,7 +516,7 @@ DEPENDENCIES dotenv-rails erb_lint foreman - good_job + good_job (= 3.99) grover htmlbeautifier importmap-rails @@ -529,7 +528,7 @@ DEPENDENCIES omniauth-rails_csrf_protection omniauth-saml (~> 2.2.1) pdf-reader - pg (~> 1.5) + pg pg_search pry-byebug pry-rails @@ -558,7 +557,7 @@ DEPENDENCIES with_advisory_lock RUBY VERSION - ruby 3.3.0p0 + ruby 3.3.6p108 BUNDLED WITH 2.4.12 diff --git a/app/models/filter_subscription.rb b/app/models/filter_subscription.rb index 4360ad25..b8cbcec7 100644 --- a/app/models/filter_subscription.rb +++ b/app/models/filter_subscription.rb @@ -56,7 +56,7 @@ def scope_searchable(searchable) scope = searchable .where(tenant_id: tenant) - .where("tag_ids && ARRAY[?]", tag_ids) + .where("tag_ids && ARRAY[?]::integer[]", tag_ids) query = Searchable::MessageThreadQuery.labels_to_ids( Searchable::MessageThreadQuery.parse(filter.query), @@ -66,10 +66,10 @@ def scope_searchable(searchable) if query[:filter_tag_ids].present? return scope.none if query[:filter_tag_ids] == :missing_tag - scope = scope.where("tag_ids @> ARRAY[?]", query[:filter_tag_ids]) + scope = scope.where("tag_ids @> ARRAY[?]::integer[]", query[:filter_tag_ids]) end - scope = scope.where.not("tag_ids && ARRAY[?]", query[:filter_out_tag_ids]) if query[:filter_out_tag_ids].present? + scope = scope.where.not("tag_ids && ARRAY[?]::integer[]", query[:filter_out_tag_ids]) if query[:filter_out_tag_ids].present? scope = scope.fulltext_search(query[:fulltext], prefix_search: query[:prefix_search]) if query[:fulltext].present? scope diff --git a/app/models/message_drafts_import.rb b/app/models/message_drafts_import.rb index de9aaf1f..7637c5d3 100644 --- a/app/models/message_drafts_import.rb +++ b/app/models/message_drafts_import.rb @@ -16,7 +16,7 @@ class MessageDraftsImport < ApplicationRecord validates_with MessageDraftsImportValidator, if: :unzipped? - enum status: { uploaded: 0, unzipped: 1, parsed: 2 } + enum :status, { uploaded: 0, unzipped: 1, parsed: 2 } def base_name name.split('_', 2).last diff --git a/app/models/searchable/message_thread.rb b/app/models/searchable/message_thread.rb index 0867c890..059b5150 100644 --- a/app/models/searchable/message_thread.rb +++ b/app/models/searchable/message_thread.rb @@ -19,7 +19,7 @@ class Searchable::MessageThread < ApplicationRecord belongs_to :message_thread, class_name: '::MessageThread' belongs_to :tenant, class_name: '::Tenant' - scope :with_tag_id, ->(tag_id) { where("tag_ids && ARRAY[?]", [tag_id]) } + scope :with_tag_id, ->(tag_id) { where("tag_ids && ARRAY[?]::integer[]", [tag_id]) } include PgSearch::Model @@ -68,7 +68,7 @@ def self.search_ids(query_filter, search_permissions:, cursor:, per_page:, direc if search_permissions[:tag_ids] if search_permissions[:tag_ids].any? - scope = scope.where("tag_ids && ARRAY[?]", search_permissions[:tag_ids]) + scope = scope.where("tag_ids && ARRAY[?]::integer[]", search_permissions[:tag_ids]) end end @@ -76,10 +76,10 @@ def self.search_ids(query_filter, search_permissions:, cursor:, per_page:, direc if query_filter[:filter_tag_ids] == :missing_tag scope = scope.none else - scope = scope.where("tag_ids @> ARRAY[?]", query_filter[:filter_tag_ids]) + scope = scope.where("tag_ids @> ARRAY[?]::integer[]", query_filter[:filter_tag_ids]) end end - scope = scope.where.not("tag_ids && ARRAY[?]", query_filter[:filter_out_tag_ids]) if query_filter[:filter_out_tag_ids].present? + scope = scope.where.not("tag_ids && ARRAY[?]::integer[]", query_filter[:filter_out_tag_ids]) if query_filter[:filter_out_tag_ids].present? scope = scope.fulltext_search(query_filter[:fulltext], prefix_search: query_filter[:prefix_search]).with_pg_search_highlight if query_filter[:fulltext].present? scope = scope.select(:message_thread_id, :last_message_delivered_at) @@ -113,7 +113,7 @@ def self.search_ids(query_filter, search_permissions:, cursor:, per_page:, direc end def self.reindex_with_tag_id(tag_id) - Searchable::MessageThread.select(:id, :message_thread_id).where("tag_ids && ARRAY[?]", [tag_id]).find_each do |searchable_mt| + Searchable::MessageThread.select(:id, :message_thread_id).where("tag_ids && ARRAY[?]::integer[]", [tag_id]).find_each do |searchable_mt| Searchable::ReindexMessageThreadJob.perform_later(searchable_mt.message_thread_id) end end diff --git a/db/migrate/20241125070056_create_good_job_execution_error_backtrace.rb b/db/migrate/20241125070056_create_good_job_execution_error_backtrace.rb new file mode 100644 index 00000000..c6d3f64c --- /dev/null +++ b/db/migrate/20241125070056_create_good_job_execution_error_backtrace.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class CreateGoodJobExecutionErrorBacktrace < ActiveRecord::Migration[7.2] + def change + reversible do |dir| + dir.up do + # Ensure this incremental update migration is idempotent + # with monolithic install migration. + return if connection.column_exists?(:good_job_executions, :error_backtrace) + end + end + + add_column :good_job_executions, :error_backtrace, :text, array: true + end +end diff --git a/db/migrate/20241125070057_create_good_job_process_lock_ids.rb b/db/migrate/20241125070057_create_good_job_process_lock_ids.rb new file mode 100644 index 00000000..94b8b674 --- /dev/null +++ b/db/migrate/20241125070057_create_good_job_process_lock_ids.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class CreateGoodJobProcessLockIds < ActiveRecord::Migration[7.2] + def change + reversible do |dir| + dir.up do + # Ensure this incremental update migration is idempotent + # with monolithic install migration. + return if connection.column_exists?(:good_jobs, :locked_by_id) + end + end + + add_column :good_jobs, :locked_by_id, :uuid + add_column :good_jobs, :locked_at, :datetime + add_column :good_job_executions, :process_id, :uuid + add_column :good_job_processes, :lock_type, :integer, limit: 2 + end +end diff --git a/db/migrate/20241125070058_create_good_job_process_lock_indexes.rb b/db/migrate/20241125070058_create_good_job_process_lock_indexes.rb new file mode 100644 index 00000000..11b04538 --- /dev/null +++ b/db/migrate/20241125070058_create_good_job_process_lock_indexes.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +class CreateGoodJobProcessLockIndexes < ActiveRecord::Migration[7.2] + disable_ddl_transaction! + + def change + reversible do |dir| + dir.up do + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked) + add_index :good_jobs, [:priority, :scheduled_at], + order: { priority: "ASC NULLS LAST", scheduled_at: :asc }, + where: "finished_at IS NULL AND locked_by_id IS NULL", + name: :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked, + algorithm: :concurrently + end + + unless connection.index_name_exists?(:good_jobs, :index_good_jobs_on_locked_by_id) + add_index :good_jobs, :locked_by_id, + where: "locked_by_id IS NOT NULL", + name: :index_good_jobs_on_locked_by_id, + algorithm: :concurrently + end + + unless connection.index_name_exists?(:good_job_executions, :index_good_job_executions_on_process_id_and_created_at) + add_index :good_job_executions, [:process_id, :created_at], + name: :index_good_job_executions_on_process_id_and_created_at, + algorithm: :concurrently + end + end + + dir.down do + remove_index(:good_jobs, name: :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked) if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_priority_scheduled_at_unfinished_unlocked) + remove_index(:good_jobs, name: :index_good_jobs_on_locked_by_id) if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_locked_by_id) + remove_index(:good_job_executions, name: :index_good_job_executions_on_process_id_and_created_at) if connection.index_name_exists?(:good_job_executions, :index_good_job_executions_on_process_id_and_created_at) + end + end + end +end diff --git a/db/migrate/20241125070059_create_good_job_execution_duration.rb b/db/migrate/20241125070059_create_good_job_execution_duration.rb new file mode 100644 index 00000000..4b17b33d --- /dev/null +++ b/db/migrate/20241125070059_create_good_job_execution_duration.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class CreateGoodJobExecutionDuration < ActiveRecord::Migration[7.2] + def change + reversible do |dir| + dir.up do + # Ensure this incremental update migration is idempotent + # with monolithic install migration. + return if connection.column_exists?(:good_job_executions, :duration) + end + end + + add_column :good_job_executions, :duration, :interval + end +end diff --git a/db/schema.rb b/db/schema.rb index ba2de7a6..3c1b30e4 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.1].define(version: 2024_11_06_152337) do +ActiveRecord::Schema[7.2].define(version: 2024_11_25_070059) do # These are extensions that must be enabled in order to support this database enable_extension "pgcrypto" enable_extension "plpgsql" @@ -262,13 +262,18 @@ t.datetime "finished_at" t.text "error" t.integer "error_event", limit: 2 + t.text "error_backtrace", array: true + t.uuid "process_id" + t.interval "duration" t.index ["active_job_id", "created_at"], name: "index_good_job_executions_on_active_job_id_and_created_at" + t.index ["process_id", "created_at"], name: "index_good_job_executions_on_process_id_and_created_at" end create_table "good_job_processes", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.datetime "created_at", null: false t.datetime "updated_at", null: false t.jsonb "state" + t.integer "lock_type", limit: 2 end create_table "good_job_settings", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -301,6 +306,8 @@ t.text "job_class" t.integer "error_event", limit: 2 t.text "labels", array: true + t.uuid "locked_by_id" + t.datetime "locked_at" t.index ["active_job_id", "created_at"], name: "index_good_jobs_on_active_job_id_and_created_at" t.index ["batch_callback_id"], name: "index_good_jobs_on_batch_callback_id", where: "(batch_callback_id IS NOT NULL)" t.index ["batch_id"], name: "index_good_jobs_on_batch_id", where: "(batch_id IS NOT NULL)" @@ -309,8 +316,10 @@ t.index ["cron_key", "cron_at"], name: "index_good_jobs_on_cron_key_and_cron_at_cond", unique: true, where: "(cron_key IS NOT NULL)" t.index ["finished_at"], name: "index_good_jobs_jobs_on_finished_at", where: "((retried_good_job_id IS NULL) AND (finished_at IS NOT NULL))" t.index ["labels"], name: "index_good_jobs_on_labels", where: "(labels IS NOT NULL)", using: :gin + t.index ["locked_by_id"], name: "index_good_jobs_on_locked_by_id", where: "(locked_by_id IS NOT NULL)" t.index ["priority", "created_at"], name: "index_good_job_jobs_for_candidate_lookup", where: "(finished_at IS NULL)" t.index ["priority", "created_at"], name: "index_good_jobs_jobs_on_priority_created_at_when_unfinished", order: { priority: "DESC NULLS LAST" }, where: "(finished_at IS NULL)" + t.index ["priority", "scheduled_at"], name: "index_good_jobs_on_priority_scheduled_at_unfinished_unlocked", where: "((finished_at IS NULL) AND (locked_by_id IS NULL))" t.index ["queue_name", "scheduled_at"], name: "index_good_jobs_on_queue_name_and_scheduled_at", where: "(finished_at IS NULL)" t.index ["scheduled_at"], name: "index_good_jobs_on_scheduled_at", where: "(finished_at IS NULL)" end @@ -575,7 +584,7 @@ t.enum "color", enum_type: "color" t.index "tenant_id, type, lower((name)::text)", name: "index_tags_on_tenant_id_and_type_and_lowercase_name", unique: true t.index ["owner_id"], name: "index_tags_on_owner_id" - t.index ["tenant_id", "type"], name: "signings_tags", unique: true, where: "((type)::text = ANY ((ARRAY['SignatureRequestedTag'::character varying, 'SignedTag'::character varying])::text[]))" + t.index ["tenant_id", "type"], name: "signings_tags", unique: true, where: "((type)::text = ANY (ARRAY[('SignatureRequestedTag'::character varying)::text, ('SignedTag'::character varying)::text]))" t.index ["tenant_id"], name: "index_tags_on_tenant_id" end diff --git a/test/jobs/govbox/process_unathorized_delivery_notification_job_test.rb b/test/jobs/govbox/process_unathorized_delivery_notification_job_test.rb index 519c0f2e..0e021ccf 100644 --- a/test/jobs/govbox/process_unathorized_delivery_notification_job_test.rb +++ b/test/jobs/govbox/process_unathorized_delivery_notification_job_test.rb @@ -19,7 +19,8 @@ class Govbox::ProcessMessageJobTest < ActiveJob::TestCase Govbox::ProcessUnauthorizedDeliveryNotificationJob.new.perform(govbox_message) end - assert_enqueued_with(job: Govbox::ProcessUnauthorizedDeliveryNotificationJob, at: Time.parse(govbox_message.delivery_notification['delivery_period_end_at'])) + assert_equal "Govbox::ProcessUnauthorizedDeliveryNotificationJob", GoodJob::Job.last.job_class + assert_equal Time.parse(govbox_message.delivery_notification['delivery_period_end_at']), GoodJob::Job.last.scheduled_at assert_equal message.changed?, false assert_equal govbox_message.changed?, false end diff --git a/test/jobs/govbox/sync_box_job_test.rb b/test/jobs/govbox/sync_box_job_test.rb index 56c21100..c4889e47 100644 --- a/test/jobs/govbox/sync_box_job_test.rb +++ b/test/jobs/govbox/sync_box_job_test.rb @@ -34,9 +34,9 @@ class Govbox::SyncBoxJobTest < ActiveJob::TestCase ]] ::Upvs::GovboxApi::Edesk.stub :new, edesk_api_mock do - assert_enqueued_with(job: Govbox::SyncFolderJob, priority: 1000) do - Govbox::SyncBoxJob.set(job_context: :later).perform_now(box) - end + Govbox::SyncBoxJob.set(job_context: :later).perform_now(box) + assert_equal "Govbox::SyncFolderJob", GoodJob::Job.last.job_class + assert_equal 1000, GoodJob::Job.last.priority end end @@ -73,9 +73,9 @@ class Govbox::SyncBoxJobTest < ActiveJob::TestCase ]] ::Upvs::GovboxApi::Edesk.stub :new, edesk_api_mock do - assert_enqueued_with(job: Govbox::SyncFolderJob, priority: nil) do - Govbox::SyncBoxJob.perform_now(box) - end + Govbox::SyncBoxJob.perform_now(box) + assert_equal "Govbox::SyncFolderJob", GoodJob::Job.first.job_class + assert_equal 0, GoodJob::Job.first.priority end end end diff --git a/test/jobs/govbox/sync_folder_job_test.rb b/test/jobs/govbox/sync_folder_job_test.rb index 069793fb..6f778122 100644 --- a/test/jobs/govbox/sync_folder_job_test.rb +++ b/test/jobs/govbox/sync_folder_job_test.rb @@ -46,7 +46,7 @@ class Govbox::SyncFolderJobTest < ActiveJob::TestCase Govbox::SyncFolderJob.new.perform(folder) end - assert_enqueued_jobs 4 + assert_equal 4, GoodJob::Job.count end test "does not download older messages than box sync_since value in box settings" do @@ -96,6 +96,6 @@ class Govbox::SyncFolderJobTest < ActiveJob::TestCase Govbox::SyncFolderJob.new.perform(folder) end - assert_enqueued_jobs 2 + assert_equal 2, GoodJob::Job.count end end diff --git a/test/lib/event_bus_test.rb b/test/lib/event_bus_test.rb index e4f58b8c..c553dd17 100644 --- a/test/lib/event_bus_test.rb +++ b/test/lib/event_bus_test.rb @@ -3,14 +3,11 @@ require "test_helper" class EventBusTest < ActiveSupport::TestCase - include ActiveJob::TestHelper - - test ":message_draft_changed event schedules Searchable::ReindexMessageThreadJob" do + test ":message_draft_changed event schedules Searchable::ReindexMessageThreadJob" do message = messages(:ssd_main_general_draft_one) - assert_enqueued_with(job: Searchable::ReindexMessageThreadJob) do - message.update(html_visualization: 'some junktext') - end + message.update(html_visualization: 'some junktext') + assert_equal "Searchable::ReindexMessageThreadJob", GoodJob::Job.last.job_class end test "should fire matching subscribers" do diff --git a/test/models/box_test.rb b/test/models/box_test.rb index c3dd7c0e..5e6d1429 100644 --- a/test/models/box_test.rb +++ b/test/models/box_test.rb @@ -1,8 +1,6 @@ require "test_helper" class BoxTest < ActiveSupport::TestCase - include ActiveJob::TestHelper - test "should not be valid if obo value present in settings when api_connection is a Govbox::ApiConnection without tenant" do box = boxes(:google_box_with_govbox_api_connection) assert box.valid? @@ -33,17 +31,16 @@ class BoxTest < ActiveSupport::TestCase test "sync method schedules Govbox::SyncBoxJob with highest priority" do box = boxes(:ssd_main) - assert_enqueued_with(job: Govbox::SyncBoxJob, priority: -1000) do - box.sync - end + box.sync + assert_equal "Govbox::SyncBoxJob", GoodJob::Job.last.job_class + assert_equal -1000, GoodJob::Job.last.priority end test "sync_all schedules sync of all boxes" do - assert_enqueued_with(job: Govbox::SyncBoxJob) do - Box.sync_all - end + Box.sync_all + assert_equal "Govbox::SyncBoxJob", GoodJob::Job.last.job_class - assert_enqueued_jobs Upvs::Box.where(syncable: true).count + assert_equal Upvs::Box.where(syncable: true).count, GoodJob::Job.count end test "should not be valid if same obo value present in other boxes within connection" do diff --git a/test/models/fs/message_draft_test.rb b/test/models/fs/message_draft_test.rb index 8787de5a..b6a44274 100644 --- a/test/models/fs/message_draft_test.rb +++ b/test/models/fs/message_draft_test.rb @@ -3,7 +3,6 @@ require "test_helper" class Fs::MessageDraftTest < ActiveSupport::TestCase - include ActiveJob::TestHelper include ActionDispatch::TestProcess::FixtureFile test "create_and_validate_with_fs_form method schedules Fs::ValidateMessageDraftJob" do @@ -17,9 +16,8 @@ class Fs::MessageDraftTest < ActiveSupport::TestCase [file_fixture("fs/dic1122334455_fs3055_781__sprava_dani_2023.xml").read] FsEnvironment.fs_client.stub :api, fs_api do - assert_enqueued_with(job: Fs::ValidateMessageDraftJob) do - Fs::MessageDraft.create_and_validate_with_fs_form(form_files: [fixture_file_upload("fs/dic1122334455_fs3055_781__sprava_dani_2023.xml", "application/xml")], author: author) - end + Fs::MessageDraft.create_and_validate_with_fs_form(form_files: [fixture_file_upload("fs/dic1122334455_fs3055_781__sprava_dani_2023.xml", "application/xml")], author: author) + assert_equal "Fs::ValidateMessageDraftJob", GoodJob::Job.last.job_class end message_draft = Fs::MessageDraft.last diff --git a/test/models/govbox/authorize_delivery_notification_action_test.rb b/test/models/govbox/authorize_delivery_notification_action_test.rb index 744e760b..8b6d3930 100644 --- a/test/models/govbox/authorize_delivery_notification_action_test.rb +++ b/test/models/govbox/authorize_delivery_notification_action_test.rb @@ -1,13 +1,11 @@ require "test_helper" class Govbox::AuthorizeDeliveryNotificationActionTest < ActiveSupport::TestCase - include ActiveJob::TestHelper - test "schedules Govbox::AuthorizeDeliveryNotificationJob with highest priority" do message = messages(:solver_main_delivery_notification_two) - assert_enqueued_with(job: Govbox::AuthorizeDeliveryNotificationJob, priority: -1000) do - Govbox::AuthorizeDeliveryNotificationAction.run(message) - end + Govbox::AuthorizeDeliveryNotificationAction.run(message) + assert_equal "Govbox::AuthorizeDeliveryNotificationJob", GoodJob::Job.last.job_class + assert_equal -1000, GoodJob::Job.last.priority end end diff --git a/test/models/message_draft_test.rb b/test/models/message_draft_test.rb index c2d4921c..23831369 100644 --- a/test/models/message_draft_test.rb +++ b/test/models/message_draft_test.rb @@ -1,8 +1,6 @@ require "test_helper" class MessageDraftTest < ActiveSupport::TestCase - include ActiveJob::TestHelper - test "created! method publishes events on EventBus" do box = boxes(:ssd_main) message = MessageDraft.create( @@ -138,8 +136,8 @@ class MessageDraftTest < ActiveSupport::TestCase test "single draft submission schedules jobs with highest priority" do message_draft = messages(:ssd_main_draft) - assert_enqueued_with(job: Govbox::SubmitMessageDraftJob, priority: -1000) do - message_draft.submit - end + message_draft.submit + assert_equal "Govbox::SubmitMessageDraftJob", GoodJob::Job.first.job_class + assert_equal -1000, GoodJob::Job.first.priority end end diff --git a/test/system/message_drafts_test.rb b/test/system/message_drafts_test.rb index 24e8e6cb..312b6a10 100644 --- a/test/system/message_drafts_test.rb +++ b/test/system/message_drafts_test.rb @@ -19,6 +19,7 @@ class MessageDraftsTest < ApplicationSystemTestCase end test "user can create message draft as reply on replyable message" do + skip end test "templated message draft content is searchable" do