From 2d6c960e8dbbf1955831741e636b680ca6f8cc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Fri, 2 Feb 2024 15:11:11 +0100 Subject: [PATCH 01/17] setup dockerfile, readme and optimize for production --- .env.example | 10 +- .gitignore | 1 + .ruby-version | 2 +- Capfile | 22 -- Dockerfile | 101 ++++++++ Gemfile | 12 +- Gemfile.lock | 217 ++++++++---------- README.md | 53 +++++ app/assets/javascripts/libs.js | 6 +- .../vendor}/highcharts-exporting.js | 0 .../assets/javascripts/vendor}/highcharts.js | 0 .../javascripts/vendor}/jquery.validate.js | 0 bin/cap | 16 -- config/application.rb | 1 + config/database.yml | 8 +- config/deploy.rb | 81 ------- config/deploy/production.rb | 1 - config/deploy/staging.rb | 1 - config/environments/production.rb | 24 +- config/initializers/sidekiq.rb | 5 - config/puma.rb | 47 ++++ config/sidekiq.yml | 1 + config/unicorn.rb | 29 --- docker-compose.yml | 51 ++++ entrypoint.sh | 63 +++++ spec/spec_helper.rb | 2 +- supervisord.conf | 25 ++ vendor/assets/stylesheets/.keep | 0 28 files changed, 481 insertions(+), 298 deletions(-) delete mode 100644 Capfile create mode 100644 Dockerfile rename {vendor/assets/javascripts => app/assets/javascripts/vendor}/highcharts-exporting.js (100%) rename {vendor/assets/javascripts => app/assets/javascripts/vendor}/highcharts.js (100%) rename {vendor/assets/javascripts => app/assets/javascripts/vendor}/jquery.validate.js (100%) delete mode 100755 bin/cap delete mode 100644 config/deploy.rb delete mode 100644 config/deploy/production.rb delete mode 100644 config/deploy/staging.rb delete mode 100644 config/initializers/sidekiq.rb create mode 100644 config/puma.rb delete mode 100644 config/unicorn.rb create mode 100644 docker-compose.yml create mode 100755 entrypoint.sh create mode 100644 supervisord.conf delete mode 100644 vendor/assets/stylesheets/.keep diff --git a/.env.example b/.env.example index 329465ffd..93b9d594a 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,14 @@ DATABASE_USER=postgres DATABASE_NAME=timeoverflow_development +#RAILS CONFIG +RAILS_SERVE_STATIC_FILES=true +RAILS_LOG_TO_STDOUT=true +RAILS_LOG_LEVEL=debug +QUEUE_ADAPTER=sidekiq +STORAGE_PROVIDER=amazon +FORCE_SSL=true + # Host part of the url for mail links: MAIL_LINK_HOST=localhost:3000 MAIL_LINK_PROTO=http @@ -26,7 +34,7 @@ SMTP_PORT=587 # List of emails for superadmin users ADMINS="admin@timeoverflow.org" -# AWS settings +# AWS settings (if STORAGE_PROVIDER=amazon) AWS_ACCESS_KEY_ID=XXXXXXXX AWS_SECRET_ACCESS_KEY=XXXXXXXX AWS_BUCKET=timeoverflow_development diff --git a/.gitignore b/.gitignore index 85dbc60e4..5c942096a 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ tags .sass-cache capybara-*.html /vendor/bundle +/public/assets /storage/ /coverage/ /spec/tmp/* diff --git a/.ruby-version b/.ruby-version index ec1cf33c3..1f7da99d4 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.6.3 +2.7.7 diff --git a/Capfile b/Capfile deleted file mode 100644 index 0f81c1684..000000000 --- a/Capfile +++ /dev/null @@ -1,22 +0,0 @@ -# Load DSL and set up stages -require 'capistrano/setup' - -# Include default deployment tasks -require 'capistrano/deploy' - -# Include tasks from other gems included in your Gemfile -# -# For documentation on these, see for example: -# -# https://github.com/capistrano/rvm -# https://github.com/capistrano/rbenv -# https://github.com/capistrano/chruby -# https://github.com/capistrano/bundler -# https://github.com/capistrano/rails -# https://github.com/capistrano/passenger -# -require 'capistrano/rails' -require 'capistrano/rbenv' - -# Load custom tasks from `lib/capistrano/tasks` if you have any defined -Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..f3943b148 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,101 @@ +FROM ruby:2.7 AS builder + +RUN apt-get update && apt-get upgrade -y && apt-get install -y ca-certificates curl gnupg && \ + curl -fsSL https://deb.nodesource.com/setup_21.x | bash - && \ + apt-get install -y \ + build-essential \ + nodejs \ + postgresql-client \ + libpq-dev && \ + apt-get clean + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +WORKDIR /app + +# Copy package dependencies files only to ensure maximum cache hit +COPY ./Gemfile /app/Gemfile +COPY ./Gemfile.lock /app/Gemfile.lock + +RUN gem install bundler:$(grep -A 1 'BUNDLED WITH' Gemfile.lock | tail -n 1 | xargs) && \ + bundle config --local without 'development test' && \ + bundle install -j4 --retry 3 && \ + # Remove unneeded gems + bundle clean --force && \ + # Remove unneeded files from installed gems (cache, *.o, *.c) + rm -rf /usr/local/bundle/cache && \ + find /usr/local/bundle/ -name "*.c" -delete && \ + find /usr/local/bundle/ -name "*.o" -delete && \ + find /usr/local/bundle/ -name ".git" -exec rm -rf {} + && \ + find /usr/local/bundle/ -name ".github" -exec rm -rf {} + && \ + find /usr/local/bundle/ -name "spec" -exec rm -rf {} + + +# copy the rest of files +COPY ./app /app/app +COPY ./bin /app/bin +COPY ./config /app/config +COPY ./db /app/db +COPY ./lib /app/lib +COPY ./public/*.* /app/public/ +COPY ./config.ru /app/config.ru +COPY ./Rakefile /app/Rakefile + +# Compile assets with Webpacker or Sprockets +# +# Notes: +# 1. Executing "assets:precompile" runs "webpacker:compile", too +# 2. For an app using encrypted credentials, Rails raises a `MissingKeyError` +# if the master key is missing. Because on CI there is no master key, +# we hide the credentials while compiling assets (by renaming them before and after) +# +RUN mv config/credentials.yml.enc config/credentials.yml.enc.bak 2>/dev/null || true +RUN mv config/credentials config/credentials.bak 2>/dev/null || true + +RUN RAILS_ENV=production \ + SECRET_KEY_BASE=dummy \ + RAILS_MASTER_KEY=dummy \ + DB_ADAPTER=nulldb \ + bundle exec rails assets:precompile + +RUN mv config/credentials.yml.enc.bak config/credentials.yml.enc 2>/dev/null || true +RUN mv config/credentials.bak config/credentials 2>/dev/null || true + +RUN rm -rf tmp/cache vendor/bundle test spec .git + +# This image is for production env only +FROM ruby:2.7-slim AS final + +RUN apt-get update && \ + apt-get install -y postgresql-client \ + imagemagick \ + curl \ + supervisor && \ + apt-get clean + +EXPOSE 3000 + +ENV RAILS_LOG_TO_STDOUT true +ENV RAILS_SERVE_STATIC_FILES true +ENV RAILS_ENV production + +ARG RUN_RAILS +ARG RUN_SIDEKIQ + +# Add user +RUN addgroup --system --gid 1000 app && \ + adduser --system --uid 1000 --home /app --group app + +WORKDIR /app +COPY ./entrypoint.sh /app/entrypoint.sh +COPY ./supervisord.conf /etc/supervisord.conf +COPY --from=builder --chown=app:app /usr/local/bundle/ /usr/local/bundle/ +COPY --from=builder --chown=app:app /app /app + +USER app +HEALTHCHECK --interval=1m --timeout=5s --start-period=10s \ + CMD (curl -IfSs http://localhost:3000/ -A "HealthCheck: Docker/1.0") || exit 1 + + +ENTRYPOINT ["/app/entrypoint.sh"] +CMD ["/usr/bin/supervisord"] \ No newline at end of file diff --git a/Gemfile b/Gemfile index ff1ac20da..d0b1fb044 100644 --- a/Gemfile +++ b/Gemfile @@ -2,6 +2,7 @@ source 'https://rubygems.org' gem 'rails', '~> 6.1.1' gem 'rails-i18n', '~> 7.0' +gem "puma", ">= 5.0.0" gem 'rdiscount', '~> 2.2.7' gem 'rubyzip', '~> 2.3.0' gem 'activeadmin', '~> 2.14' @@ -13,7 +14,6 @@ gem 'json_translate', '~> 4.0.0' gem 'devise', '~> 4.9.1' gem 'devise-i18n', '~> 1.11.0' gem 'http_accept_language', '~> 2.1.1' -gem 'unicorn', '~> 5.5.1' gem 'kaminari', '~> 1.2.1' gem 'simple_form', '~> 5.0.2' gem 'rollbar', '~> 2.22.1' @@ -31,17 +31,19 @@ gem 'active_storage_validations', '~> 1.1.3' gem 'jquery-rails', '~> 4.4.0' gem 'bootstrap-sass', '~> 3.4' gem 'sassc-rails', '~> 2.1.2' -gem 'uglifier', '~> 4.2.0' gem 'select2-rails', '~> 4.0.13' +group :production do + # we are using an ExecJS runtime only on the precompilation phase + gem 'uglifier', '~> 4.2.0', require: false +end + group :development do gem 'listen', '~> 3.2.0' gem 'localeapp', '~> 3.3', require: false gem 'letter_opener', '~> 1.7.0' gem 'web-console', '~> 4.1.0' - gem 'capistrano', '~> 3.1' - gem 'capistrano-rails', '~> 1.1' - gem 'capistrano-rbenv', '~> 2.1' + gem 'uglifier', '~> 4.2.0' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 7aaf022bb..3f40050f6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -39,7 +39,7 @@ GEM erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - active_storage_validations (1.1.3) + active_storage_validations (1.1.4) activejob (>= 5.2.0) activemodel (>= 5.2.0) activestorage (>= 5.2.0) @@ -74,33 +74,31 @@ GEM minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - airbrussh (1.4.0) - sshkit (>= 1.6.1, != 1.7.0) - arbre (1.5.0) - activesupport (>= 3.0.0, < 7.1) - ruby2_keywords (>= 0.0.2, < 1.0) + arbre (1.7.0) + activesupport (>= 3.0.0) + ruby2_keywords (>= 0.0.2) ast (2.4.2) - autoprefixer-rails (10.4.13.0) + autoprefixer-rails (10.4.16.0) execjs (~> 2) - aws-eventstream (1.1.1) - aws-partitions (1.451.0) - aws-sdk-core (3.114.0) - aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.239.0) + aws-eventstream (1.3.0) + aws-partitions (1.886.0) + aws-sdk-core (3.191.0) + aws-eventstream (~> 1, >= 1.3.0) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.8) + jmespath (~> 1, >= 1.6.1) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - jmespath (~> 1.0) - aws-sdk-kms (1.43.0) - aws-sdk-core (~> 3, >= 3.112.0) - aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.94.1) - aws-sdk-core (~> 3, >= 3.112.0) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.1) - aws-sigv4 (1.2.3) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) - bcrypt (3.1.18) + bcrypt (3.1.20) bindex (0.8.1) bootsnap (1.12.0) msgpack (~> 1.2) @@ -109,20 +107,7 @@ GEM sassc (>= 2.0.0) builder (3.2.4) byebug (11.1.3) - capistrano (3.15.0) - airbrussh (>= 1.0.0) - i18n - rake (>= 10.0.0) - sshkit (>= 1.9.0) - capistrano-bundler (2.0.1) - capistrano (~> 3.1) - capistrano-rails (1.6.1) - capistrano (~> 3.1) - capistrano-bundler (>= 1.1, < 3) - capistrano-rbenv (2.2.0) - capistrano (~> 3.1) - sshkit (~> 1.3) - capybara (3.36.0) + capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) @@ -132,23 +117,22 @@ GEM regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) childprocess (4.1.0) - concurrent-ruby (1.2.2) + concurrent-ruby (1.2.3) connection_pool (2.4.1) crass (1.0.6) database_cleaner (1.8.5) date (3.3.4) - devise (4.9.1) + devise (4.9.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-i18n (1.11.0) + devise-i18n (1.11.1) devise (>= 4.9.0) - diff-lcs (1.4.4) + diff-lcs (1.5.1) docile (1.4.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) + domain_name (0.6.20240107) dotenv (2.7.6) dotenv-rails (2.7.6) dotenv (= 2.7.6) @@ -156,18 +140,18 @@ GEM erubi (1.12.0) et-orbi (1.2.7) tzinfo - execjs (2.8.1) - fabrication (2.22.0) - faker (2.17.0) - i18n (>= 1.6, < 2) - ffi (1.15.5) + execjs (2.9.1) + fabrication (2.30.0) + faker (2.23.0) + i18n (>= 1.8.11, < 2) + ffi (1.16.3) formtastic (4.0.0) actionpack (>= 5.2.0) formtastic_i18n (0.7.0) fugit (1.9.0) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) - gli (2.21.0) + gli (2.21.1) globalid (1.2.1) activesupport (>= 6.1) has_scope (0.7.2) @@ -182,17 +166,17 @@ GEM image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) - inherited_resources (1.13.1) - actionpack (>= 5.2, < 7.1) - has_scope (~> 0.6) - railties (>= 5.2, < 7.1) - responders (>= 2, < 4) - jmespath (1.6.1) + inherited_resources (1.14.0) + actionpack (>= 6.0) + has_scope (>= 0.6) + railties (>= 6.0) + responders (>= 2) + jmespath (1.6.2) jquery-rails (4.4.0) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (2.6.3) + json (2.7.1) json_translate (4.0.1) activerecord (>= 4.2.0) kaminari (1.2.2) @@ -207,9 +191,9 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - kgio (2.11.3) - launchy (2.5.0) - addressable (~> 2.7) + language_server-protocol (3.17.0.3) + launchy (2.5.2) + addressable (~> 2.8) letter_opener (1.7.0) launchy (~> 2.2) listen (3.2.1) @@ -231,38 +215,36 @@ GEM marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) - mime-types (3.4.1) + mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - mini_magick (4.11.0) + mime-types-data (3.2023.1205) + mini_magick (4.12.0) mini_mime (1.1.5) mini_portile2 (2.8.5) - minitest (5.20.0) - msgpack (1.5.2) - net-imap (0.3.7) + minitest (5.21.2) + msgpack (1.7.2) + net-imap (0.4.9.1) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.2) timeout - net-scp (3.0.0) - net-ssh (>= 2.6.5, < 7.0.0) - net-smtp (0.4.0) + net-smtp (0.4.0.1) net-protocol - net-ssh (6.1.0) netrc (0.11.0) - nio4r (2.6.0) - nokogiri (1.13.10) - mini_portile2 (~> 2.8.0) + nio4r (2.7.0) + nokogiri (1.15.5) + mini_portile2 (~> 2.8.2) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.20.1) - parser (3.0.1.1) + parallel (1.24.0) + parser (3.3.0.5) ast (~> 2.4.1) + racc pdf-core (0.9.0) - pg (1.4.6) - pg_search (2.3.5) + pg (1.5.4) + pg_search (2.3.6) activerecord (>= 5.2) activesupport (>= 5.2) prawn (2.4.0) @@ -271,7 +253,9 @@ GEM prawn-table (0.2.2) prawn (>= 1.3.0, < 3.0.0) public_suffix (5.0.4) - pundit (2.1.0) + puma (6.4.2) + nio4r (~> 2.0) + pundit (2.1.1) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.7.3) @@ -301,8 +285,9 @@ GEM activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.5.0) - loofah (~> 2.19, >= 2.19.1) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) rails-i18n (7.0.8) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) @@ -312,19 +297,18 @@ GEM method_source rake (>= 12.2) thor (~> 1.0) - rainbow (3.0.0) - raindrops (0.19.1) + rainbow (3.1.1) rake (13.1.0) - ransack (3.0.1) - activerecord (>= 6.0.4) - activesupport (>= 6.0.4) + ransack (3.2.1) + activerecord (>= 6.1.5) + activesupport (>= 6.1.5) i18n - rb-fsevent (0.10.4) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rdiscount (2.2.7) + rdiscount (2.2.7.3) redis (4.8.1) - regexp_parser (2.8.2) + regexp_parser (2.9.0) responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) @@ -333,16 +317,16 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 4.0) netrc (~> 0.8) - rexml (3.2.5) + rexml (3.2.6) rollbar (2.22.1) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) + rspec-support (~> 3.12.0) rspec-rails (4.0.2) actionpack (>= 4.2) activesupport (>= 4.2) @@ -351,24 +335,27 @@ GEM rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) rspec-support (~> 3.10) - rspec-support (3.10.2) - rubocop (1.13.0) + rspec-support (3.12.1) + rubocop (1.60.2) + json (~> 2.3) + language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.0.0.0) + parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) - rexml - rubocop-ast (>= 1.2.0, < 2.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.5.0) - parser (>= 3.0.1.1) - rubocop-rails (2.9.1) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.30.0) + parser (>= 3.2.1.0) + rubocop-rails (2.23.1) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.90.0, < 2.0) - ruby-progressbar (1.11.0) - ruby-vips (2.1.4) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) + ruby-progressbar (1.13.0) + ruby-vips (2.2.0) ffi (~> 1.12) ruby2_keywords (0.0.5) rubyzip (2.3.2) @@ -403,7 +390,7 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - skylight (5.0.1) + skylight (5.3.5) activesupport (>= 5.2.0) sprockets (4.2.1) concurrent-ruby (~> 1.0) @@ -412,24 +399,15 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - sshkit (1.21.2) - net-scp (>= 1.1.2) - net-ssh (>= 2.8.0) thor (1.3.0) - tilt (2.0.10) + tilt (2.3.0) timeout (0.4.1) ttfunk (1.7.0) tzinfo (2.0.6) 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 (2.0.0) - unicorn (5.5.5) - kgio (~> 2.6) - raindrops (~> 0.7) + unicode-display_width (2.5.0) warden (1.2.9) rack (>= 2.0.9) web-console (4.1.0) @@ -458,9 +436,6 @@ DEPENDENCIES bootsnap (~> 1.12.0) bootstrap-sass (~> 3.4) byebug (~> 11.0) - capistrano (~> 3.1) - capistrano-rails (~> 1.1) - capistrano-rbenv (~> 2.1) capybara (~> 3.29) database_cleaner (~> 1.8.5) devise (~> 4.9.1) @@ -481,6 +456,7 @@ DEPENDENCIES pg_search (~> 2.3.5) prawn (~> 2.4.0) prawn-table (~> 0.2.2) + puma (>= 5.0.0) pundit (~> 2.1.0) rails (~> 6.1.1) rails-controller-testing @@ -501,7 +477,6 @@ DEPENDENCIES simplecov (~> 0.22) skylight (~> 5.0) uglifier (~> 4.2.0) - unicorn (~> 5.5.1) web-console (~> 4.1.0) webdrivers (~> 5.3) diff --git a/README.md b/README.md index 1479d11a2..72503cbe4 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,59 @@ as well as being able to post offers / demand ads explained in detail. On the other hand the members can be paid the services of virtual way to save the passage through the office of the Bank of Time and also have the possibility to consult the extract of their account. +## Docker deploying + +This site is ready to be deployed in production with an optimized Docker image which uses two stages in order to minimize the final image size. + +You can locally test the production deployment by the include docker-compose.yml file: + +```bash +docker-compose up +``` + +The first time running it will build the image and setup the database along with some seeds in it (testing data). If the database already exists, it will run migrations (if needed) and just start the application. + +Go to `http://localhost:3000` to see the application running. + +> Note that the current docker-compose.yml is not suitable for a real production deployment, it's just for testing the production Dockerfile locally. +> For production deployment you should use a real database and a reverse proxy like Nginx or Apache (with SSL enabled). +> Refer to the next section in order to see the relevant ENV variables to configure the application. + +### ENV variables + +In order to configure the application you can use the following ENV variables: + +> Make sure to configure at least the ones without a default value (empty). + +| ENV | Description | Default | +| --- | --- | +| `RAILS_ENV` | Define the rails environment (not necessary to setup unless you have some special requirements) | `production` | +| `SECRET_KEY_BASE` | Secret key for the application, generate a new one with the command `rails secret` | | +| `DATABASE_URL` | Database URL, the format is `postgresql://user:password@host:port/database` | | +| `RAILS_SERVE_STATIC_FILES` | Tell the application to serve static files (you might want to turn this off if you are using an external web server to serve files from the `public` folder) | `true` | +| `RAILS_LOG_TO_STDOUT` | Tell the application to log to STDOUT (useful for Docker) | `true` | +| `RAILS_LOG_LEVEL` | Log level for the application (use `debug` for maximum information) | `info` | +| `QUEUE_ADAPTER` | Adapter to use for background jobs (currently the application is using exclusively Sidekiq, so no other options here right now) | `sidekiq` | +| `SIDEKIQ_CONCURRENCY` | Number of threads to use in Sidekiq | `5` | +| `STORAGE_PROVIDER` | Storage provider for the application (currently the application supports `local` and `amazon`) | `local` | +| `FORCE_SSL` | Force SSL connections | `false` | +| `MAIL_LINK_HOST` | Host to use in the links sent by email (use your domain without protocol `mydomain.tld`) | | +| `MAIL_LINK_PROTOCOL` | Protocol to use in the previous host defined for links sent by email | `https` | +| `SMTP_ADDRESS` | SMTP server address (ie: `smtp.mailgun.org`) | | +| `SMTP_PORT` | SMTP server port (ie: `587`) | | +| `SMTP_DOMAIN` | SMTP domain (usually the application's domain) | | +| `SMTP_USER_NAME` | SMTP username | | +| `SMTP_PASSWORD` | SMTP password | | +| `SMTP_AUTHENTICATION` | SMTP authentication method | `plain` | +| `SMTP_ENABLE_STARTTLS_AUTO` | Enable STARTTLS | `true` | +| `SMTP_OPENSSL_VERIFY_MODE` | OpenSSL verify mode | `none` | +| `AWS_ACCESS_KEY_ID` | AWS access key ID (only if `STORAGE_PROVIDER` is `amazon`) | | +| `AWS_SECRET_ACCESS_KEY` | AWS secret access key (only if `STORAGE_PROVIDER` is `amazon`) | | +| `AWS_BUCKET` | AWS bucket name (only if `STORAGE_PROVIDER` is `amazon`) | | +| `AWS_REGION` | AWS region (only if `STORAGE_PROVIDER` is `amazon`) | | +| `ADMINS` | Space separated list of emails for the superadmins (ie: `admin@timeoverflow.org` | | + + ## Contributions **Join our collaborators team!** diff --git a/app/assets/javascripts/libs.js b/app/assets/javascripts/libs.js index 1c941bd13..c304764cd 100644 --- a/app/assets/javascripts/libs.js +++ b/app/assets/javascripts/libs.js @@ -1,7 +1,7 @@ //= require jquery2 //= require jquery_ujs -//= require jquery.validate +//= require vendor/jquery.validate //= require bootstrap -//= require highcharts -//= require highcharts-exporting +//= require ./vendor/highcharts +//= require ./vendor/highcharts-exporting //= require select2 diff --git a/vendor/assets/javascripts/highcharts-exporting.js b/app/assets/javascripts/vendor/highcharts-exporting.js similarity index 100% rename from vendor/assets/javascripts/highcharts-exporting.js rename to app/assets/javascripts/vendor/highcharts-exporting.js diff --git a/vendor/assets/javascripts/highcharts.js b/app/assets/javascripts/vendor/highcharts.js similarity index 100% rename from vendor/assets/javascripts/highcharts.js rename to app/assets/javascripts/vendor/highcharts.js diff --git a/vendor/assets/javascripts/jquery.validate.js b/app/assets/javascripts/vendor/jquery.validate.js similarity index 100% rename from vendor/assets/javascripts/jquery.validate.js rename to app/assets/javascripts/vendor/jquery.validate.js diff --git a/bin/cap b/bin/cap deleted file mode 100755 index 30352d4d4..000000000 --- a/bin/cap +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env ruby -# -# This file was generated by Bundler. -# -# The application 'cap' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require 'pathname' -ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require 'rubygems' -require 'bundler/setup' - -load Gem.bin_path('capistrano', 'cap') diff --git a/config/application.rb b/config/application.rb index 2598506d6..5abfe24d0 100644 --- a/config/application.rb +++ b/config/application.rb @@ -31,6 +31,7 @@ class Application < Rails::Application config.active_record.schema_format = :sql # Guard against DNS rebinding attacks by permitting hosts + config.hosts << 'localhost' config.hosts << 'timeoverflow.local' config.hosts << 'staging.timeoverflow.org' config.hosts << 'www.timeoverflow.org' diff --git a/config/database.yml b/config/database.yml index a840d2a02..fd8d03892 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,8 +1,14 @@ defaults: &defaults adapter: postgresql - username: <%= ENV['DATABASE_USER'] || ENV["POSTGRES_USER"] %> + username: <%= ENV['DATABASE_USER'] || ENV["POSTGRES_USER"] || ENV["DATABASE_USERNAME"] %> + password: <%= ENV['DATABASE_PASSWORD'] || ENV["POSTGRES_PASSWORD"] %> + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + host: <%= ENV.fetch("DATABASE_HOST") { "localhost" } %> + port: <%= ENV.fetch("DATABASE_PORT") { "5432" } %> template: 'template0' encoding: 'UTF8' + # For details on connection pooling, see rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling development: <<: *defaults diff --git a/config/deploy.rb b/config/deploy.rb deleted file mode 100644 index a58a3f616..000000000 --- a/config/deploy.rb +++ /dev/null @@ -1,81 +0,0 @@ -# config valid only for current version of Capistrano -lock '3.15.0' - -set :application, 'timeoverflow' -set :repo_url, 'git@github.com:coopdevs/timeoverflow.git' - -set :rbenv_type, :user - -# Default branch is :master -ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp - -# Default deploy_to directory is /var/www/my_app_name -# set :deploy_to, '/var/www/my_app_name' - -# Default value for :scm is :git -# set :scm, :git - -# Default value for :format is :pretty -# set :format, :pretty - -# Default value for :log_level is :debug -# set :log_level, :debug - -# Default value for :pty is false -# set :pty, true - -# Default value for :linked_files is [] -set :linked_files, fetch(:linked_files, []).push( - # "config/database.yml", - # "config/secrets.yml", - # ".env", -) - -# Default value for linked_dirs is [] -set :linked_dirs, fetch(:linked_dirs, []).push( - 'log', - 'tmp/pids', - 'tmp/cache', - 'tmp/sockets', - 'vendor/bundle', - 'public/system' -) - -# Default value for default_env is {} -# set :default_env, { path: "/opt/ruby/bin:$PATH" } - -# Default value for keep_releases is 5 -# set :keep_releases, 5 - -namespace :unicorn do - desc 'reload Unicorn' - task :reload do - on roles(:app) do - execute "sudo systemctl reload timeoverflow" - end - end -end - -namespace :sidekiq do - desc 'reload Sidekiq' - task :restart do - on roles(:app) do - execute "sudo systemctl restart sidekiq" - end - end -end - -task "deploy:db:load" do - on primary :db do - within release_path do - with rails_env: fetch(:rails_env) do - execute :rake, "db:schema:load" - end - end - end -end - -before "deploy:migrate", "deploy:db:load" if ENV["COLD"] - -after "deploy:finishing", "unicorn:reload" -after "deploy:finishing", "sidekiq:restart" diff --git a/config/deploy/production.rb b/config/deploy/production.rb deleted file mode 100644 index 240ae0b0a..000000000 --- a/config/deploy/production.rb +++ /dev/null @@ -1 +0,0 @@ -server 'www.timeoverflow.org', user: 'timeoverflow', roles: %w(app db web) diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb deleted file mode 100644 index 59ea3607c..000000000 --- a/config/deploy/staging.rb +++ /dev/null @@ -1 +0,0 @@ -server 'staging.timeoverflow.org', user: 'timeoverflow', roles: %w(app db web) diff --git a/config/environments/production.rb b/config/environments/production.rb index c005b5320..70249b0ef 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,3 +1,5 @@ +require "uglifier" if ENV["SECRET_KEY_BASE"] == "dummy" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -20,28 +22,30 @@ # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.public_file_server.enabled = true + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? - # Compress CSS & JS using preprocessors. - config.assets.js_compressor = Uglifier.new(harmony: true) - config.assets.css_compressor = :sass + # Compress CSS & JS using preprocessors only on the precompile phase + if ENV["SECRET_KEY_BASE"] == "dummy" + config.assets.js_compressor = Uglifier.new(harmony: true) + config.assets.css_compressor = :sass + end # Do not fallback to assets pipeline if a precompiled asset is missed. - config.assets.compile = true + config.assets.compile = false # Asset digests allow you to set far-future HTTP expiration dates on all assets, # yet still be able to expire them through the digest params. config.assets.digest = true # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = 'http://assets.example.com' + config.asset_host = ENV.fetch("RAILS_ASSET_HOST", nil) if ENV["RAILS_ASSET_HOST"].present? # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX # Store uploaded files on the local file system (see config/storage.yml for options). - config.active_storage.service = :amazon + config.active_storage.service = ENV.fetch("STORAGE_PROVIDER", :local) # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil @@ -49,11 +53,11 @@ # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true + config.force_ssl = ENV.fetch("FORCE_SSL", "true") == "true" # Use the lowest log level to ensure availability of diagnostic information # when problems arise. - config.log_level = :debug + config.log_level = %w(debug info warn error fatal).include?(ENV.fetch("RAILS_LOG_LEVEL", nil)) ? ENV["RAILS_LOG_LEVEL"] : :info # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] @@ -62,7 +66,7 @@ # config.cache_store = :mem_cache_store # Use a real queuing backend for Active Job (and separate queues per environment). - # config.active_job.queue_adapter = :resque + config.active_job.queue_adapter = ENV.fetch("QUEUE_ADAPTER", nil) if ENV["QUEUE_ADAPTER"].present? # config.active_job.queue_name_prefix = "timeoverflow_production" config.action_mailer.perform_caching = false diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb deleted file mode 100644 index c90629cc4..000000000 --- a/config/initializers/sidekiq.rb +++ /dev/null @@ -1,5 +0,0 @@ -schedule_file = 'config/schedule.yml' - -if File.exist?(schedule_file) && Sidekiq.server? - Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file) -end diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..db11c1ed7 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +max_threads_count = ENV.fetch("RAILS_MAX_THREADS", 5) +min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count } +threads min_threads_count, max_threads_count + +# Specifies the `worker_timeout` threshold that Puma will use to wait before +# terminating a worker in development environments. +# +worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development" + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT", 3000) + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV", "development") + +# Specifies the `pidfile` that Puma will use. +pidfile ENV.fetch("PIDFILE", "tmp/pids/server.pid") + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked web server processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +if ENV.fetch("RAILS_ENV") == "production" + workers ENV.fetch("WEB_CONCURRENCY", 2) + + # Use the `preload_app!` method when specifying a `workers` number. + # This directive tells Puma to first boot the application and load code + # before forking the application. This takes advantage of Copy On Write + # process behavior so workers use less memory. + # + preload_app! +else + # Allow puma to be restarted by `rails restart` command. + plugin :tmp_restart +end diff --git a/config/sidekiq.yml b/config/sidekiq.yml index d9d221a4c..25f4cd85c 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -1,3 +1,4 @@ +:concurrency: <%= ENV.fetch("SIDEKIQ_CONCURRENCY", "5").to_i %> :queues: - default - cron diff --git a/config/unicorn.rb b/config/unicorn.rb deleted file mode 100644 index 68fc5017c..000000000 --- a/config/unicorn.rb +++ /dev/null @@ -1,29 +0,0 @@ -app_path = File.expand_path(File.dirname(__FILE__) + '/..') - -worker_processes 2 - -listen 8080, tcp_nopush: true - -working_directory app_path - -pid app_path + '/tmp/unicorn.pid' - -stderr_path '/var/www/timeoverflow/shared/log/unicorn.err.log' -stdout_path '/var/www/timeoverflow/shared/log/unicorn.std.log' - -# Load the app up before forking -# Combine Ruby 2.0.0+ with "preload_app true" for memory savings -preload_app true - -before_fork do |server, worker| - # the following is highly recomended for Rails + "preload_app true" - # as there's no need for the master process to hold a connection - defined?(ActiveRecord::Base) and - ActiveRecord::Base.connection.disconnect! -end - -after_fork do |server, worker| - # the following is *required* for Rails + "preload_app true" - defined?(ActiveRecord::Base) and - ActiveRecord::Base.establish_connection -end diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..1bd82f243 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,51 @@ +version: '3' +services: + app: + build: . + volumes: + - ./entrypoint.sh:/app/entrypoint.sh + - ./db/seeds.rb:/app/db/seeds.rb + - ./storage:/app/storage + environment: + - DATABASE_URL=postgres://postgres:timeoverflow@db/timeoverflow + - SECRET_KEY_BASE=d2a645fb46fbd3d4380fb22230ddea4062570eb00853ca5dfe97f8bb1cbff1ad6891c573a4b4b06beb2d0baf59afc9e00794314490a644fc5808ad6cbc3a6379 + - QUEUE_ADAPTER=sidekiq + - FORCE_SSL=false + - RAILS_LOG_LEVEL=debug + - REDIS_URL=redis://redis:6379/0 + - ADMINS=admin@timeoverflow.org + ports: + - 3000:3000 + depends_on: + - db + - redis + sidekiq: + build: . + volumes: + - ./entrypoint.sh:/app/entrypoint.sh + - ./storage:/app/storage + environment: + - DATABASE_URL=postgres://postgres:timeoverflow@db/timeoverflow + - SECRET_KEY_BASE=d2a645fb46fbd3d4380fb22230ddea4062570eb00853ca5dfe97f8bb1cbff1ad6891c573a4b4b06beb2d0baf59afc9e00794314490a644fc5808ad6cbc3a6379 + - QUEUE_ADAPTER=sidekiq + - FORCE_SSL=false + - RAILS_LOG_LEVEL=debug + - REDIS_URL=redis://redis:6379/0 + - ADMINS=admin@timeoverflow.org + - RUN_SIDEKIQ=true + depends_on: + - db + - redis + db: + image: postgres:14-alpine + environment: + - POSTGRES_PASSWORD=timeoverflow + volumes: + - pg_data:/var/lib/postgresql/data + redis: + image: redis + volumes: + - redis_data:/data +volumes: + pg_data: + redis_data: diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 000000000..48b5c3842 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +# Run rails by default if sidekiq is specified +if [ -z "$RUN_RAILS" ] && [ -z "$RUN_SIDEKIQ" ]; then + RUN_RAILS=true + echo "⚠️ RUN_RAILS and RUN_SIDEKIQ are not set, defaulting to RUN_RAILS=true" +fi + +if [ "$QUEUE_ADAPTER" != "sidekiq" ]; then + RUN_SIDEKIQ=false + echo "⚠️ Sidekiq is disabled because QUEUE_ADAPTER is not set to sidekiq" +fi + +# ensure booleans +if [ "$RUN_RAILS" == "true" ] || [ "$RUN_RAILS" == "1" ]; then + RUN_RAILS=true +else + RUN_RAILS=false +fi +if [ "$RUN_SIDEKIQ" == "true" ] || [ "$RUN_SIDEKIQ" == "1" ]; then + RUN_SIDEKIQ=true +else + RUN_SIDEKIQ=false +fi + +if [ "$RUN_RAILS" == "true" ]; then + echo "✅ Running Rails" +fi + +if [ "$RUN_SIDEKIQ" == "true" ]; then + echo "✅ Running Sidekiq" +fi + +export RUN_RAILS +export RUN_SIDEKIQ + +# Check all the gems are installed or fails. +bundle check +if [ $? -ne 0 ]; then + echo "❌ Gems in Gemfile are not installed, aborting..." + exit 1 +else + echo "✅ Gems in Gemfile are installed" +fi + +# if no database, run setup +if [ -z "$SKIP_DATABASE_SETUP" ]; then + bundle exec rails db:setup +else + echo "⚠️ Skipping database setup" +fi + +# Check no migrations are pending migrations +if [ -z "$SKIP_MIGRATIONS" ]; then + bundle exec rails db:migrate +else + echo "⚠️ Skipping migrations" +fi + +echo "✅ Migrations are all up" + +echo "🚀 $@" +exec "$@" \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1ab96aa99..92af9f357 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,7 +22,7 @@ require 'faker' require 'shoulda/matchers' -Capybara.server = :webrick +Capybara.server = :puma Capybara.register_driver :headless_chrome do |app| browser_options = Selenium::WebDriver::Chrome::Options.new( args: %w(headless disable-gpu no-sandbox) diff --git a/supervisord.conf b/supervisord.conf new file mode 100644 index 000000000..118c3133a --- /dev/null +++ b/supervisord.conf @@ -0,0 +1,25 @@ +[supervisord] +nodaemon=true +logfile=/tmp/supervisord.log +pidfile=/tmp/supervisord.pid + +[program:puma] +command=bin/rails server -b 0.0.0.0 +directory=/app +# If RUN_RAILS is not set, defaults to RUN_SIDEKIQ not being defined +autostart=%(ENV_RUN_RAILS)s +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:sidekiq] +command=bundle exec sidekiq -C config/sidekiq.yml +directory=/app +autostart=%(ENV_RUN_SIDEKIQ)s +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[supervisorctl] diff --git a/vendor/assets/stylesheets/.keep b/vendor/assets/stylesheets/.keep deleted file mode 100644 index e69de29bb..000000000 From ac47a8048d2cb9b1784f22dfb04965907f3b2bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Fri, 2 Feb 2024 15:16:13 +0100 Subject: [PATCH 02/17] readme --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 72503cbe4..cc34c39f1 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,11 @@ In order to configure the application you can use the following ENV variables: | `RAILS_SERVE_STATIC_FILES` | Tell the application to serve static files (you might want to turn this off if you are using an external web server to serve files from the `public` folder) | `true` | | `RAILS_LOG_TO_STDOUT` | Tell the application to log to STDOUT (useful for Docker) | `true` | | `RAILS_LOG_LEVEL` | Log level for the application (use `debug` for maximum information) | `info` | +| `RAILS_MAX_THREADS` | Maximum number of threads to use in the application (use `1` if multithreading is not desired) | `5` | +| `RAILS_MIN_THREADS` | Minimum number of threads to use in the application | `RAILS_MAX_THREADS` value | +| `WEB_CONCURRENCY` | Number of web server processes to use | `2` | +| `RUN_SIDEKIQ` | Run Sidekiq worker process in the docker instance (you might want to change this if want to run different docker instances for Sidekiq and Rails) | `true` | +| `RUN_RAILS` | Run Rails web server process in the docker instance | `true` | | `QUEUE_ADAPTER` | Adapter to use for background jobs (currently the application is using exclusively Sidekiq, so no other options here right now) | `sidekiq` | | `SIDEKIQ_CONCURRENCY` | Number of threads to use in Sidekiq | `5` | | `STORAGE_PROVIDER` | Storage provider for the application (currently the application supports `local` and `amazon`) | `local` | From aff13d459aa091e2975d96420a4d66ef39b67f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Fri, 2 Feb 2024 15:16:33 +0100 Subject: [PATCH 03/17] rubocop --- Gemfile | 100 +++++------ Rakefile | 2 +- app/admin/category.rb | 3 +- app/admin/organization.rb | 2 +- app/admin/post.rb | 2 +- app/admin/transfer.rb | 2 +- app/admin/user.rb | 2 +- app/controllers/application_controller.rb | 6 +- .../concerns/with_transfer_params.rb | 10 +- app/controllers/errors_controller.rb | 4 +- app/controllers/multi_transfers_controller.rb | 15 +- app/controllers/organizations_controller.rb | 2 +- app/controllers/pages_controller.rb | 8 +- app/controllers/petitions_controller.rb | 15 +- app/controllers/posts_controller.rb | 4 +- app/controllers/reports_controller.rb | 28 ++-- app/controllers/statistics_controller.rb | 34 ++-- app/controllers/transfers_controller.rb | 3 +- app/controllers/users_controller.rb | 27 +-- app/decorators/member_decorator.rb | 6 +- app/decorators/report/transfer_decorator.rb | 13 +- app/decorators/view_model.rb | 3 +- app/helpers/active_admin_helper.rb | 4 +- app/helpers/application_helper.rb | 36 ++-- app/helpers/glyph_helper.rb | 2 +- app/helpers/posts_helper.rb | 2 +- app/helpers/transfers_helper.rb | 9 +- app/helpers/users_helper.rb | 2 +- app/jobs/create_push_notifications_job.rb | 2 +- app/jobs/organization_notifier_job.rb | 4 +- app/mailers/organization_notifier.rb | 4 +- app/models/account.rb | 4 +- app/models/concerns/taggable.rb | 12 +- app/models/event.rb | 2 +- app/models/member.rb | 2 +- app/models/movement.rb | 2 +- app/models/organization.rb | 16 +- app/models/petition.rb | 2 +- app/models/post.rb | 20 +-- app/models/push_notification.rb | 4 +- app/models/transfer.rb | 4 +- app/models/transfer_factory.rb | 6 +- app/models/transfer_sources_options.rb | 6 +- app/models/user.rb | 25 +-- app/services/operations/transfers.rb | 7 +- app/services/operations/transfers/base.rb | 6 +- .../operations/transfers/one_to_many.rb | 1 - app/services/persister/member_persister.rb | 4 +- app/services/persister/post_persister.rb | 4 +- app/services/persister/transfer_persister.rb | 4 +- app/services/push_notifications/broadcast.rb | 2 +- .../push_notifications/creator/base.rb | 6 +- .../push_notifications/creator/post.rb | 6 +- .../push_notifications/event_notifier/post.rb | 12 +- .../event_notifier_factory.rb | 2 +- app/services/transfer_importer.rb | 10 +- app/services/user_importer.rb | 7 +- bin/bundle | 4 +- bin/rails | 6 +- bin/rake | 4 +- bin/setup | 16 +- config.ru | 2 +- config/application.rb | 18 +- config/boot.rb | 6 +- config/environment.rb | 2 +- config/environments/development.rb | 6 +- config/environments/production.rb | 14 +- config/environments/staging.rb | 2 +- config/environments/test.rb | 2 +- config/initializers/active_admin.rb | 4 +- config/initializers/assets.rb | 2 +- config/initializers/devise.rb | 14 +- config/initializers/ransack.rb | 6 +- config/initializers/rollbar.rb | 17 +- config/initializers/session_store.rb | 2 +- config/initializers/simple_form.rb | 14 +- config/initializers/simple_form_bootstrap.rb | 28 ++-- config/initializers/superadmins.rb | 2 +- config/routes.rb | 35 ++-- db/migrate/00000000000001_setup_hstore.rb | 1 + db/migrate/00000000000002_setup_pg_trgm.rb | 1 + db/migrate/20121019101022_create_users.rb | 9 +- .../20121104085711_create_categories.rb | 10 +- db/migrate/20130222185624_create_transfer.rb | 6 +- ...1102219_remove_features_from_categories.rb | 1 - ...621105452_acts_as_taggable_on_migration.rb | 8 +- ...02608_add_name_translations_to_category.rb | 1 + .../20131027215517_add_tags_to_posts.rb | 14 +- ...1029202724_create_active_admin_comments.rb | 10 +- .../20131104013829_migrate_membership_data.rb | 1 - .../20131220160257_add_active_to_user.rb | 2 +- db/migrate/20131227110122_create_documents.rb | 2 +- ...131227155440_add_devise_things_to_users.rb | 6 +- ...20140119161433_add_organization_to_post.rb | 1 + ...13141718_add_new_fields_to_organization.rb | 2 +- ...40514225527_add_active_fields_to_member.rb | 2 +- .../20180221161343_create_device_tokens.rb | 6 +- db/migrate/20180501093846_create_events.rb | 14 +- .../20180529144243_change_index_on_events.rb | 6 +- ...04145622_add_title_to_push_notification.rb | 2 +- ...828160700_add_body_to_push_notification.rb | 2 +- ...831161349_add_data_to_push_notification.rb | 2 +- ...4456_process_invalid_push_notifications.rb | 2 +- ...0104_add_amount_constraint_to_movements.rb | 2 +- ...te_active_storage_tables.active_storage.rb | 8 +- .../20230312231058_migrate_hstore_to_json.rb | 3 +- ...30314233504_add_icon_name_to_categories.rb | 22 +-- .../20230401114456_make_terms_translatable.rb | 6 +- ...d_unique_index_on_member_uid_in_members.rb | 2 +- db/seeds.rb | 32 ++-- spec/admin/organizations_controller_spec.rb | 8 +- .../application_controller_spec.rb | 4 +- .../device_tokens_controller_spec.rb | 16 +- spec/controllers/inquiries_controller_spec.rb | 4 +- .../multi_transfers_controller_spec.rb | 23 ++- spec/controllers/offers_controller_spec.rb | 59 ++++--- .../organizations_controller_spec.rb | 70 ++++---- spec/controllers/pages_controller_spec.rb | 6 +- spec/controllers/petitions_controller_spec.rb | 28 ++-- spec/controllers/reports_controller_spec.rb | 52 +++--- spec/controllers/sessions_controller_spec.rb | 12 +- .../controllers/statistics_controller_spec.rb | 28 ++-- spec/controllers/tags_controller_spec.rb | 22 +-- spec/controllers/transfers_controller_spec.rb | 102 ++++++------ spec/controllers/users_controller_spec.rb | 157 +++++++++--------- spec/decorators/member_decorator_spec.rb | 66 ++++---- .../report/member_decorator_spec.rb | 44 ++--- spec/decorators/report/post_decorator_spec.rb | 19 ++- spec/fabricators/device_token_fabricator.rb | 2 +- spec/fabricators/organization_fabricator.rb | 2 +- spec/fabricators/post_fabricator.rb | 1 - spec/fabricators/user_fabricator.rb | 6 +- spec/features/create_offer_spec.rb | 25 ++- spec/features/sign_in_spec.rb | 22 +-- spec/features/sign_out_spec.rb | 10 +- spec/features/transfer_spec.rb | 24 +-- spec/helpers/active_admin_helper_spec.rb | 6 +- spec/helpers/application_helper_spec.rb | 25 +-- spec/helpers/glyph_helper_spec.rb | 8 +- spec/helpers/posts_helper_spec.rb | 2 +- spec/helpers/transfers_helper_spec.rb | 19 ++- .../create_push_notifications_job_spec.rb | 20 +-- spec/jobs/organization_notifier_job_spec.rb | 6 +- spec/jobs/send_push_notifications_job_spec.rb | 18 +- spec/mailers/organization_notifier_spec.rb | 4 +- spec/models/account_spec.rb | 20 +-- spec/models/event_spec.rb | 25 +-- spec/models/member_spec.rb | 14 +- spec/models/organization_spec.rb | 20 +-- spec/models/post_spec.rb | 2 +- spec/models/push_notification_spec.rb | 26 +-- spec/models/taggable_spec.rb | 18 +- spec/models/transfer_factory_spec.rb | 30 ++-- spec/models/transfer_sources_options_spec.rb | 10 +- spec/models/transfer_spec.rb | 2 +- spec/services/operations/many_to_one_spec.rb | 18 +- spec/services/operations/one_to_many_spec.rb | 18 +- spec/services/operations/one_to_one_spec.rb | 19 ++- spec/services/operations/transfers_spec.rb | 18 +- .../persister/member_persister_spec.rb | 16 +- .../services/persister/post_persister_spec.rb | 38 ++--- .../persister/transfer_persister_spec.rb | 16 +- .../push_notifications/broadcast_spec.rb | 37 +++-- .../event_notifier/post_spec.rb | 40 ++--- .../event_notifier_factory_spec.rb | 14 +- spec/services/push_notifications/post_spec.rb | 56 +++---- spec/services/user_importer_spec.rb | 50 +++--- spec/spec_helper.rb | 38 ++--- spec/support/controller_macros.rb | 2 +- spec/support/features/session_helpers.rb | 8 +- spec/views/inquiries/show.html.erb_spec.rb | 25 +-- spec/views/offers/show.html.erb_spec.rb | 84 +++++----- .../views/organizations/show.html.erb_spec.rb | 61 +++---- 173 files changed, 1309 insertions(+), 1260 deletions(-) mode change 100644 => 100755 Rakefile diff --git a/Gemfile b/Gemfile index d0b1fb044..fa73ca513 100644 --- a/Gemfile +++ b/Gemfile @@ -1,67 +1,67 @@ -source 'https://rubygems.org' +source "https://rubygems.org" -gem 'rails', '~> 6.1.1' -gem 'rails-i18n', '~> 7.0' +gem "activeadmin", "~> 2.14" +gem "active_storage_validations", "~> 1.1.3" +gem "aws-sdk-s3", "~> 1.94", require: false +gem "bootsnap", "~> 1.12.0", require: false +gem "devise", "~> 4.9.1" +gem "devise-i18n", "~> 1.11.0" +gem "has_scope", "~> 0.7.2" +gem "http_accept_language", "~> 2.1.1" +gem "image_processing", "~> 1.12" +gem "json_translate", "~> 4.0.0" +gem "kaminari", "~> 1.2.1" +gem "pg", "~> 1.4" +gem "pg_search", "~> 2.3.5" +gem "prawn", "~> 2.4.0" +gem "prawn-table", "~> 0.2.2" gem "puma", ">= 5.0.0" -gem 'rdiscount', '~> 2.2.7' -gem 'rubyzip', '~> 2.3.0' -gem 'activeadmin', '~> 2.14' -gem 'bootsnap', '~> 1.12.0', require: false -gem 'has_scope', '~> 0.7.2' -gem 'pundit', '~> 2.1.0' -gem 'pg', '~> 1.4' -gem 'json_translate', '~> 4.0.0' -gem 'devise', '~> 4.9.1' -gem 'devise-i18n', '~> 1.11.0' -gem 'http_accept_language', '~> 2.1.1' -gem 'kaminari', '~> 1.2.1' -gem 'simple_form', '~> 5.0.2' -gem 'rollbar', '~> 2.22.1' -gem 'prawn', '~> 2.4.0' -gem 'prawn-table', '~> 0.2.2' -gem 'pg_search', '~> 2.3.5' -gem 'skylight', '~> 5.0' -gem 'sidekiq', '~> 6.5' -gem 'sidekiq-cron', '~> 1.9.1' -gem 'aws-sdk-s3', '~> 1.94', require: false -gem 'image_processing', '~> 1.12' -gem 'active_storage_validations', '~> 1.1.3' +gem "pundit", "~> 2.1.0" +gem "rails", "~> 6.1.1" +gem "rails-i18n", "~> 7.0" +gem "rdiscount", "~> 2.2.7" +gem "rollbar", "~> 2.22.1" +gem "rubyzip", "~> 2.3.0" +gem "sidekiq", "~> 6.5" +gem "sidekiq-cron", "~> 1.9.1" +gem "simple_form", "~> 5.0.2" +gem "skylight", "~> 5.0" # Assets -gem 'jquery-rails', '~> 4.4.0' -gem 'bootstrap-sass', '~> 3.4' -gem 'sassc-rails', '~> 2.1.2' -gem 'select2-rails', '~> 4.0.13' +gem "bootstrap-sass", "~> 3.4" +gem "jquery-rails", "~> 4.4.0" +gem "sassc-rails", "~> 2.1.2" +gem "select2-rails", "~> 4.0.13" group :production do # we are using an ExecJS runtime only on the precompilation phase - gem 'uglifier', '~> 4.2.0', require: false + gem "uglifier", "~> 4.2.0", require: false end group :development do - gem 'listen', '~> 3.2.0' - gem 'localeapp', '~> 3.3', require: false - gem 'letter_opener', '~> 1.7.0' - gem 'web-console', '~> 4.1.0' - gem 'uglifier', '~> 4.2.0' + gem "letter_opener", "~> 1.7.0" + gem "listen", "~> 3.2.0" + gem "localeapp", "~> 3.3", require: false + gem "uglifier", "~> 4.2.0" + gem "web-console", "~> 4.1.0" end group :development, :test do - gem 'byebug', '~> 11.0' - gem 'rubocop', '~> 1.6', require: false - gem 'rubocop-rails', '~> 2.9', require: false - gem 'dotenv-rails', '~> 2.7.1' + gem "byebug", "~> 11.0" + gem "dotenv-rails", "~> 2.7.1" + gem "rubocop", "~> 1.6", require: false + gem "rubocop-rails", "~> 2.9", require: false end group :test do - gem 'rspec-rails', '~> 4.0.0' - gem 'rails-controller-testing' - gem 'database_cleaner', '~> 1.8.5' - gem 'shoulda-matchers', '~> 4.4' - gem 'fabrication', '~> 2.20' - gem 'faker', '~> 2.15' - gem 'capybara', '~> 3.29' - gem 'selenium-webdriver', '~> 4.1.0' - gem 'webdrivers', '~> 5.3' - gem 'simplecov', '~> 0.22', require: false + gem "capybara", "~> 3.29" + gem "database_cleaner", "~> 1.8.5" + gem "fabrication", "~> 2.20" + gem "faker", "~> 2.15" + gem "rails-controller-testing" + gem "rspec-rails", "~> 4.0.0" + gem "selenium-webdriver", "~> 4.1.0" + gem "shoulda-matchers", "~> 4.4" + gem "simplecov", "~> 0.22", require: false + gem "webdrivers", "~> 5.3" end diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 index baff55158..1015d36a8 --- a/Rakefile +++ b/Rakefile @@ -2,6 +2,6 @@ # Add your own tasks in files placed in lib/tasks ending in .rake, # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. -require File.expand_path('../config/application', __FILE__) +require File.expand_path("config/application", __dir__) Rails.application.load_tasks diff --git a/app/admin/category.rb b/app/admin/category.rb index 009b14c12..bb07c7e69 100644 --- a/app/admin/category.rb +++ b/app/admin/category.rb @@ -13,7 +13,8 @@ form do |f| f.inputs do f.input :name - f.input :icon_name, hint: "See all available icons here".html_safe + f.input :icon_name, + hint: "See all available icons here".html_safe end f.actions end diff --git a/app/admin/organization.rb b/app/admin/organization.rb index 62f85c35d..b04e18587 100644 --- a/app/admin/organization.rb +++ b/app/admin/organization.rb @@ -73,5 +73,5 @@ def destroy filter :updated_at permit_params :name, :email, :web, :phone, :city, :neighborhood, - :address, :description, :public_opening_times, :logo + :address, :description, :public_opening_times, :logo end diff --git a/app/admin/post.rb b/app/admin/post.rb index c0d0e5057..cdfdf9527 100644 --- a/app/admin/post.rb +++ b/app/admin/post.rb @@ -46,7 +46,7 @@ end permit_params :type, :tag_list, :title, :category_id, :user_id, - :description, :organization_id, :active, :is_group + :description, :organization_id, :active, :is_group filter :type, as: :select, collection: -> { Post.subclasses } filter :id diff --git a/app/admin/transfer.rb b/app/admin/transfer.rb index 7857e1422..88b752a93 100644 --- a/app/admin/transfer.rb +++ b/app/admin/transfer.rb @@ -1,5 +1,5 @@ ActiveAdmin.register Transfer do - includes :post, movements: { account: [:accountable, :organization] } + includes :post, movements: { account: %i[accountable organization] } actions :index, :destroy diff --git a/app/admin/user.rb b/app/admin/user.rb index 060f9e844..83faec2f3 100644 --- a/app/admin/user.rb +++ b/app/admin/user.rb @@ -85,5 +85,5 @@ end permit_params :username, :email, :phone, :postcode, :gender, :locale, - members_attributes: [:id, :organization_id, :active, :manager, :_destroy] + members_attributes: %i[id organization_id active manager _destroy] end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a8823c0c8..e90142817 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -114,18 +114,18 @@ def set_locale def user_not_authorized flash[:error] = "You are not authorized to perform this action." - redirect_to(request.referrer || root_path) + redirect_to(request.referer || root_path) end def resource_not_found - render 'errors/not_found', status: 404 + render "errors/not_found", status: :not_found end def member_should_exist_and_be_active if !current_member redirect_to organizations_path elsif !current_member.active - flash[:error] = I18n.t('users.index.account_deactivated') + flash[:error] = I18n.t("users.index.account_deactivated") redirect_to select_organization_path end end diff --git a/app/controllers/concerns/with_transfer_params.rb b/app/controllers/concerns/with_transfer_params.rb index a9b766369..934cf6e8c 100644 --- a/app/controllers/concerns/with_transfer_params.rb +++ b/app/controllers/concerns/with_transfer_params.rb @@ -1,10 +1,10 @@ module WithTransferParams def transfer_params - permitted_transfer_params = [ - :destination, - :amount, - :reason, - :post_id, + permitted_transfer_params = %i[ + destination + amount + reason + post_id ] permitted_transfer_params.push(:source) if admin? diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb index 479fe79df..c000e9c97 100644 --- a/app/controllers/errors_controller.rb +++ b/app/controllers/errors_controller.rb @@ -1,9 +1,9 @@ class ErrorsController < ApplicationController def not_found - render status: 404 + render status: :not_found end def internal_server_error - render status: 500 + render status: :internal_server_error end end diff --git a/app/controllers/multi_transfers_controller.rb b/app/controllers/multi_transfers_controller.rb index 91f45a0b9..e78a6bc54 100644 --- a/app/controllers/multi_transfers_controller.rb +++ b/app/controllers/multi_transfers_controller.rb @@ -1,12 +1,12 @@ class MultiTransfersController < ApplicationController include WithTransferParams - STEPS = [ - 'select_type', - 'select_source', - 'select_target', - 'set_params', - 'confirm' + STEPS = %w[ + select_type + select_source + select_target + set_params + confirm ] def step @@ -60,11 +60,10 @@ def prepare_template_vars @target_accountable = Account.find(@to.first).accountable end - @should_render_offer_selector = ( + @should_render_offer_selector = @type_of_transfer.to_sym == :many_to_one && @target_accountable && @target_accountable.offers.length > 0 - ) @from_names = Account.find(@from).map(&:accountable).map(&:to_s) @to_names = Account.find(@to).map(&:accountable).map(&:to_s) diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 37daeafcc..45d1b747c 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -1,5 +1,5 @@ class OrganizationsController < ApplicationController - before_action :load_resource, only: [:show, :edit, :update, :set_current] + before_action :load_resource, only: %i[show edit update set_current] before_action :user_should_be_confirmed def index diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 771445e51..f4264dbae 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,9 +1,7 @@ class PagesController < ApplicationController def show - begin - render template: "pages/#{params[:page]}" - rescue ActionView::MissingTemplate - render "errors/not_found", status: 404 - end + render template: "pages/#{params[:page]}" + rescue ActionView::MissingTemplate + render "errors/not_found", status: :not_found end end diff --git a/app/controllers/petitions_controller.rb b/app/controllers/petitions_controller.rb index 8dc4d432b..a897f4e9a 100644 --- a/app/controllers/petitions_controller.rb +++ b/app/controllers/petitions_controller.rb @@ -9,9 +9,9 @@ def create OrganizationNotifier.new_petition(petition).deliver_now OrganizationNotifier.petition_sent(petition).deliver_now - flash[:notice] = t('petitions.application_status', status: t("petitions.status.sent")) + flash[:notice] = t("petitions.application_status", status: t("petitions.status.sent")) else - flash[:error] = t('errors.internal_server_error.description') + flash[:error] = t("errors.internal_server_error.description") end redirect_back fallback_location: organization_path(petition.organization) @@ -22,18 +22,19 @@ def update status = params[:status] if petition.update(status: status) - petition.user.add_to_organization(petition.organization) if status == 'accepted' - flash[:notice] = t('petitions.application_status', status: t("petitions.status.#{status}")) + petition.user.add_to_organization(petition.organization) if status == "accepted" + flash[:notice] = t("petitions.application_status", status: t("petitions.status.#{status}")) else - flash[:error] = t('errors.internal_server_error.description') + flash[:error] = t("errors.internal_server_error.description") end redirect_to manage_petitions_path end def manage - @status = params[:status] || 'pending' - @users = User.joins(:petitions).where(petitions: { organization_id: current_organization.id, status: @status }).page(params[:page]).per(20) + @status = params[:status] || "pending" + @users = User.joins(:petitions).where(petitions: { organization_id: current_organization.id, + status: @status }).page(params[:page]).per(20) end private diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 373c6cee8..21e6062ba 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -1,4 +1,4 @@ -class PostsController < ApplicationController +class PostsController < ApplicationController has_scope :by_category, as: :cat has_scope :tagged_with, as: :tag has_scope :by_organization, as: :org @@ -94,7 +94,7 @@ def set_user_id(p) def post_params permitted_fields = [:description, :end_on, :start_on, :title, :category_id, - :user_id, :is_group, :active, tag_list: []] + :user_id, :is_group, :active, { tag_list: [] }] params.fetch(resource, {}).permit(*permitted_fields).tap do |p| set_user_id(p) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 5b2b271fa..d7749ea35 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -1,4 +1,4 @@ -require 'zip' +require "zip" class ReportsController < ApplicationController before_action :authenticate_user! @@ -8,20 +8,20 @@ class ReportsController < ApplicationController def user_list @members = report_collection("Member") - report_responder('Member', current_organization, @members) + report_responder("Member", current_organization, @members) end def post_list @post_type = (params[:type] || "offer").capitalize.constantize @posts = report_collection(@post_type) - report_responder('Post', current_organization, @posts, @post_type) + report_responder("Post", current_organization, @posts, @post_type) end def transfer_list - @transfers = report_collection('Transfer') + @transfers = report_collection("Transfer") - report_responder('Transfer', current_organization, @transfers) + report_responder("Transfer", current_organization, @transfers) end def download_all @@ -35,7 +35,7 @@ def download_all end end zip_data = File.read(temp_file.path) - send_data(zip_data, type: 'application/zip', disposition: 'attachment', filename: filename) + send_data(zip_data, type: "application/zip", disposition: "attachment", filename: filename) rescue Errno::ENOENT redirect_to download_all_report_path ensure @@ -65,11 +65,11 @@ def get_report(report_class, *args) def report_collection(report_class) case report_class.to_s - when 'Member' - current_organization.members.active.includes(:user).order('members.member_uid') - when 'Transfer' + when "Member" + current_organization.members.active.includes(:user).order("members.member_uid") + when "Transfer" current_organization.all_transfers_with_accounts - when 'Inquiry', 'Offer' + when "Inquiry", "Offer" report_class = report_class.constantize if report_class.is_a?(String) current_organization.posts.of_active_members.active. @@ -84,10 +84,10 @@ def add_csv_to_zip(report_class, zip) collection = report_collection(report_class) report = if report_class.in? %w(Inquiry Offer) - get_report("Csv::Post", current_organization, collection, report_class.constantize) - else - get_report("Csv::#{report_class}", current_organization, collection) - end + get_report("Csv::Post", current_organization, collection, report_class.constantize) + else + get_report("Csv::#{report_class}", current_organization, collection) + end file = Tempfile.new file.write(report.run) diff --git a/app/controllers/statistics_controller.rb b/app/controllers/statistics_controller.rb index aa719b219..8d705c327 100644 --- a/app/controllers/statistics_controller.rb +++ b/app/controllers/statistics_controller.rb @@ -8,16 +8,16 @@ def global_activity @total_hours = num_movements = 0 members.each do |m| num_movements += m.account.movements.count - @total_hours += m.account.movements.map do - |a| (a.amount > 0) ? a.amount : 0 + @total_hours += m.account.movements.map do |a| + a.amount > 0 ? a.amount : 0 end.inject(0, :+) end @total_hours += current_organization.account.movements. - map { |a| (a.amount > 0) ? a.amount : 0 }.inject(0, :+) + map { |a| a.amount > 0 ? a.amount : 0 }.inject(0, :+) @num_swaps = (num_movements + current_organization.account.movements.count) / 2 - from = params[:from].presence.try(:to_date) || DateTime.now.to_date - 5.month + from = params[:from].presence.try(:to_date) || DateTime.now.to_date - 5.months to = params[:to].presence.try(:to_date) || DateTime.now.to_date num_months = (to.year * 12 + to.month) - (from.year * 12 + from.month) + 1 date = from @@ -38,10 +38,10 @@ def global_activity sum_hours = 0 swaps_members.flatten.each do |s| - sum_hours += (s.amount > 0) ? s.amount : 0 + sum_hours += s.amount > 0 ? s.amount : 0 end - sum_hours += swaps_organization.map do - |a| (a.amount > 0) ? a.amount : 0 + sum_hours += swaps_organization.map do |a| + a.amount > 0 ? a.amount : 0 end.inject(0, :+) sum_hours = sum_hours / 3600.0 if sum_hours > 0 @hours_swaps_months << sum_hours @@ -147,12 +147,12 @@ def compute_age(date_of_birth) def age_group_labels { - 0..17 => "-17", - 18..24 => "18-24", - 25..34 => "25-34", - 35..44 => "35-44", - 45..54 => "45-54", - 55..64 => "55-64", + 0..17 => "-17", + 18..24 => "18-24", + 25..34 => "25-34", + 35..44 => "35-44", + 45..54 => "45-54", + 55..64 => "55-64", 65..100 => "65+", } end @@ -161,10 +161,10 @@ def gender_counts(members) members.each_with_object(Hash.new(0)) do |member, counts| gender = member.user_gender gender_label = if gender.present? - t("simple_form.options.user.gender.#{gender}") - else - t("statistics.demographics.unknown") - end + t("simple_form.options.user.gender.#{gender}") + else + t("statistics.demographics.unknown") + end counts[gender_label] += 1 end end diff --git a/app/controllers/transfers_controller.rb b/app/controllers/transfers_controller.rb index e65506566..5baf275ba 100644 --- a/app/controllers/transfers_controller.rb +++ b/app/controllers/transfers_controller.rb @@ -14,7 +14,8 @@ def create if persister.save redirect_to redirect_target else - redirect_back fallback_location: redirect_target, alert: transfer.errors.full_messages.to_sentence + redirect_back fallback_location: redirect_target, + alert: transfer.errors.full_messages.to_sentence end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 689adef37..c464d76bd 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,8 @@ class UsersController < ApplicationController before_action :authenticate_user!, except: %i[signup create] before_action :user_should_be_confirmed, except: %i[signup create please_confirm] - before_action :member_should_exist_and_be_active, except: %i[signup create edit show update please_confirm] + before_action :member_should_exist_and_be_active, + except: %i[signup create edit show update please_confirm] has_scope :tagged_with, as: :tag @@ -9,11 +10,11 @@ def index members = current_organization.members.active members = apply_scopes(members) - search_and_load_members members, { s: 'user_last_sign_in_at DESC' } + search_and_load_members members, { s: "user_last_sign_in_at DESC" } end def manage - search_and_load_members current_organization.members, { s: 'member_uid ASC' } + search_and_load_members current_organization.members, { s: "member_uid ASC" } end def show @@ -55,7 +56,7 @@ def create else @user.email = "" if empty_email - render action: @user.from_signup ? 'signup' : 'new' + render action: @user.from_signup ? "signup" : "new" end end @@ -98,7 +99,9 @@ def search_and_load_members(members_scope, default_search_params) @search = members_scope.ransack(default_search_params.merge(params.to_unsafe_h.fetch(:q, {}))) result = @search.result - orders = result.order_values.map { |order| order.direction == :asc ? "#{order.to_sql} NULLS FIRST" : "#{order.to_sql} NULLS LAST" } + orders = result.order_values.map do |order| + order.direction == :asc ? "#{order.to_sql} NULLS FIRST" : "#{order.to_sql} NULLS LAST" + end result = result.except(:order).order(orders.join(", ")) if orders.count > 0 @members = result.eager_load(:account, :user).page(params[:page]).per(20) @@ -114,8 +117,10 @@ def scoped_users def user_params fields_to_permit = %w"gender username email date_of_birth phone alt_phone active locale description notifications push_notifications postcode" - fields_to_permit += %w"admin registration_number - registration_date" if admin? + if admin? + fields_to_permit += %w"admin registration_number + registration_date" + end fields_to_permit += %w"organization_id superadmin" if superadmin? fields_to_permit += %w"password" if params[:from_signup].present? @@ -139,13 +144,13 @@ def redirect_to_after_create if params[:more] redirect_to new_user_path, notice: I18n.t("users.new.user_created_add", - uid: id, - name: @user.username) + uid: id, + name: @user.username) else redirect_to users_path, notice: I18n.t("users.index.user_created", - uid: id, - name: @user.username) + uid: id, + name: @user.username) end end end diff --git a/app/decorators/member_decorator.rb b/app/decorators/member_decorator.rb index c3d0aaefe..f522da9b1 100644 --- a/app/decorators/member_decorator.rb +++ b/app/decorators/member_decorator.rb @@ -7,11 +7,11 @@ def manager? end def row_css_class - 'bg-danger' unless active? + "bg-danger" unless active? end def inactive_icon - view.glyph('time') unless active? + view.glyph("time") unless active? end def link_to_self @@ -20,7 +20,7 @@ def link_to_self def mail_to email = user.unconfirmed_email || user.email - view.mail_to(email) if email && !email.end_with?('example.com') + view.mail_to(email) if email && !email.end_with?("example.com") end def account_balance diff --git a/app/decorators/report/transfer_decorator.rb b/app/decorators/report/transfer_decorator.rb index 305a4dcdc..323bfea53 100644 --- a/app/decorators/report/transfer_decorator.rb +++ b/app/decorators/report/transfer_decorator.rb @@ -1,7 +1,8 @@ class Report::TransferDecorator include Rails.application.routes.url_helpers include ActionView::Helpers - include ApplicationHelper, TransfersHelper + include TransfersHelper + include ApplicationHelper def initialize(org, collection) @org = org @@ -17,11 +18,11 @@ def name(extension) def headers [ - I18n.t('statistics.all_transfers.date'), - I18n.t('statistics.all_transfers.from'), - I18n.t('statistics.all_transfers.to'), - I18n.t('statistics.all_transfers.post'), - I18n.t('statistics.all_transfers.quantity') + I18n.t("statistics.all_transfers.date"), + I18n.t("statistics.all_transfers.from"), + I18n.t("statistics.all_transfers.to"), + I18n.t("statistics.all_transfers.post"), + I18n.t("statistics.all_transfers.quantity") ] end diff --git a/app/decorators/view_model.rb b/app/decorators/view_model.rb index 8de925637..ee45101bf 100644 --- a/app/decorators/view_model.rb +++ b/app/decorators/view_model.rb @@ -26,7 +26,7 @@ # # From controllers, one can pass `self.class.helpers`, and from tests it is # enough to use ApplicationController.new.view_context. -# +# class ViewModel attr_reader :object, :view, :routes @@ -36,4 +36,3 @@ def initialize(object, view) @routes = Rails.application.routes.url_helpers end end - diff --git a/app/helpers/active_admin_helper.rb b/app/helpers/active_admin_helper.rb index 8e43496a7..ea899b730 100644 --- a/app/helpers/active_admin_helper.rb +++ b/app/helpers/active_admin_helper.rb @@ -1,8 +1,8 @@ module ActiveAdminHelper def render_translations(attribute, joiner = " | ") - attribute.map do |locale, translation| + attribute.map do |locale, translation| tag.strong("#{I18n.t("locales.#{locale}", locale: locale)}: ") + - tag.span(translation) + tag.span(translation) end.join(joiner).html_safe end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5fe37cdd8..b655d9407 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,15 +1,17 @@ module ApplicationHelper - TEXT_SUCCESS = 'text-success'.freeze - TEXT_DANGER = 'text-danger'.freeze + TEXT_SUCCESS = "text-success".freeze + TEXT_DANGER = "text-danger".freeze def page_title - current_organization || 'TimeOverflow' + current_organization || "TimeOverflow" end def avatar_url(user, size = 32) - user.avatar.attached? ? - user.avatar.variant(resize: "#{size}x#{size}") : + if user.avatar.attached? + user.avatar.variant(resize: "#{size}x#{size}") + else gravatar_url(user, size) + end end def gravatar_url(user, size = 32) @@ -76,7 +78,7 @@ def show_error_messages!(resource) # Content can be nil, in that case # it will be the same as an empty string. def markdown(content) - RDiscount.new(content || ''.freeze).to_html.html_safe + RDiscount.new(content || "".freeze).to_html.html_safe end alias m markdown @@ -92,12 +94,12 @@ def green_red(amount) def get_body_css_class(controller) classes = { - 'home' => 'landing-page', - 'sessions' => 'login-page', - 'pages' => 'pages', - 'unlocks' => 'unlocks-page', - 'passwords' => 'passwords-page', - 'confirmations' => 'confirmations-page' + "home" => "landing-page", + "sessions" => "login-page", + "pages" => "pages", + "unlocks" => "unlocks-page", + "passwords" => "passwords-page", + "confirmations" => "confirmations-page" } "#{classes[controller]}" @@ -105,12 +107,12 @@ def get_body_css_class(controller) def alert_class(alert) case alert - when 'error', 'alert' - 'alert-danger' - when 'notice' - 'alert-success' + when "error", "alert" + "alert-danger" + when "notice" + "alert-success" else - 'alert-info' + "alert-info" end end end diff --git a/app/helpers/glyph_helper.rb b/app/helpers/glyph_helper.rb index ddff8d266..56640eb71 100644 --- a/app/helpers/glyph_helper.rb +++ b/app/helpers/glyph_helper.rb @@ -8,7 +8,7 @@ module GlyphHelper "organization" => "tower" } - def glyph(kind, title=nil) + def glyph(kind, title = nil) kind = kind.to_s.underscore content_tag :span, "", class: "glyphicon glyphicon-#{glyph_name(kind)}", diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index bc8f14619..079fce2b2 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -1,7 +1,7 @@ module PostsHelper def members_for_select(post) members = current_organization.members.active.order("members.member_uid"). - map { |mem| ["#{mem.member_uid} #{mem.user.to_s}", mem.user_id] } + map { |mem| ["#{mem.member_uid} #{mem.user}", mem.user_id] } options_for_select(members, selected: post.user.id || current_user.id) end diff --git a/app/helpers/transfers_helper.rb b/app/helpers/transfers_helper.rb index 7e6cf20f0..acf960f1a 100644 --- a/app/helpers/transfers_helper.rb +++ b/app/helpers/transfers_helper.rb @@ -12,13 +12,14 @@ def accounts_from_movements(transfer, with_links: false) account = movement.account if account.accountable.blank? - I18n.t('users.show.deleted_user') - elsif account.accountable_type == 'Organization' + I18n.t("users.show.deleted_user") + elsif account.accountable_type == "Organization" link_to_if(with_links, account, organization_path(account.accountable)) elsif account.accountable.active - link_to_if(with_links, account.accountable.display_name_with_uid, user_path(account.accountable.user)) + link_to_if(with_links, account.accountable.display_name_with_uid, + user_path(account.accountable.user)) else - I18n.t('users.show.inactive_user') + I18n.t("users.show.inactive_user") end end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index e0562469b..0c5b937c7 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -40,6 +40,6 @@ def can_toggle_active?(_member) end def status_applications(status) - t('petitions.status_applications', status: t("petitions.status.#{status}").humanize) + t("petitions.status_applications", status: t("petitions.status.#{status}").humanize) end end diff --git a/app/jobs/create_push_notifications_job.rb b/app/jobs/create_push_notifications_job.rb index 64a7ab5a6..049da2bb9 100644 --- a/app/jobs/create_push_notifications_job.rb +++ b/app/jobs/create_push_notifications_job.rb @@ -4,7 +4,7 @@ class CreatePushNotificationsJob < ActiveJob::Base def perform(event_id:) event = ::Event.find_by_id(event_id) - raise 'A valid Event must be provided' unless event + raise "A valid Event must be provided" unless event if event.post_id ::PushNotifications::Creator::Post.new(event: event).create! diff --git a/app/jobs/organization_notifier_job.rb b/app/jobs/organization_notifier_job.rb index e8949bba6..fac2df25d 100644 --- a/app/jobs/organization_notifier_job.rb +++ b/app/jobs/organization_notifier_job.rb @@ -27,8 +27,8 @@ def users_by_locale(organization) with_notifications = organization.users.online_active.actives.notifications org_locales = with_notifications.pluck(:locale).uniq - org_locales.each_with_object({}) do |locale, hash| - hash[locale] = with_notifications.where(locale: locale) + org_locales.index_with do |locale| + with_notifications.where(locale: locale) end end end diff --git a/app/mailers/organization_notifier.rb b/app/mailers/organization_notifier.rb index d3ed1fcd5..6579fbcd7 100644 --- a/app/mailers/organization_notifier.rb +++ b/app/mailers/organization_notifier.rb @@ -19,7 +19,7 @@ def new_petition(petition) I18n.with_locale(locale) do mail( - subject: 'New Application', + subject: "New Application", to: organization.users.joins(:members).where(members: { manager: true }).pluck(:email).uniq ) end @@ -30,7 +30,7 @@ def petition_sent(petition) I18n.with_locale(locale) do mail( - subject: 'Application sent correctly', + subject: "Application sent correctly", to: petition.user.email ) end diff --git a/app/models/account.rb b/app/models/account.rb index c441349ba..012534264 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -23,9 +23,7 @@ def update_balance end # Print the account as its accountable reference - def to_s - accountable.to_s - end + delegate :to_s, to: :accountable protected diff --git a/app/models/concerns/taggable.rb b/app/models/concerns/taggable.rb index 4dba82ec7..2bec8aaa5 100644 --- a/app/models/concerns/taggable.rb +++ b/app/models/concerns/taggable.rb @@ -34,16 +34,18 @@ def tag_list # @return [Hash Integer>] def tag_cloud Hash[ - all_tags - .group_by(&:to_s) - .map { |tag_name, values| [tag_name, values.size] } - .sort_by { |array| array.first.downcase } + all_tags. + group_by(&:to_s). + map { |tag_name, values| [tag_name, values.size] }. + sort_by { |array| array.first.downcase } ] end def find_like_tag(pattern) transliterated_pattern = pattern.present? ? ActiveSupport::Inflector.transliterate(pattern) : "" - all_tags.uniq.select { |t| ActiveSupport::Inflector.transliterate(t) =~ /#{transliterated_pattern}/i } + all_tags.uniq.select do |t| + ActiveSupport::Inflector.transliterate(t) =~ /#{transliterated_pattern}/i + end end # Builds a hash where the keys are the capital letters of the tags and the diff --git a/app/models/event.rb b/app/models/event.rb index fa05bfd21..0b2fd0cea 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -16,6 +16,6 @@ class Event < ApplicationRecord def resource_presence return if post_id.present? ^ member_id.present? ^ transfer_id.present? - errors.add(:base, 'Specify only one resource id: `post_id`, `member_id` or `transfer_id`') + errors.add(:base, "Specify only one resource id: `post_id`, `member_id` or `transfer_id`") end end diff --git a/app/models/member.rb b/app/models/member.rb index 28285f486..c97b54902 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -27,7 +27,7 @@ class Member < ApplicationRecord delegate :balance, to: :account, prefix: true, allow_nil: true delegate :gender, :date_of_birth, to: :user, prefix: true, allow_nil: true - scope :by_month, -> (month) { where(created_at: month.beginning_of_month..month.end_of_month) } + scope :by_month, ->(month) { where(created_at: month.beginning_of_month..month.end_of_month) } scope :active, -> { where active: true } scope :by_organization, ->(org) { where(organization_id: org) if org } diff --git a/app/models/movement.rb b/app/models/movement.rb index 078a427c7..3cad5edde 100644 --- a/app/models/movement.rb +++ b/app/models/movement.rb @@ -9,7 +9,7 @@ class Movement < ApplicationRecord belongs_to :account, optional: true belongs_to :transfer, optional: true - scope :by_month, -> (month) { where(created_at: month.beginning_of_month..month.end_of_month) } + scope :by_month, ->(month) { where(created_at: month.beginning_of_month..month.end_of_month) } validates :amount, numericality: { other_than: 0 } diff --git a/app/models/organization.rb b/app/models/organization.rb index cec867101..d97efc08d 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -2,13 +2,13 @@ class Organization < ApplicationRecord include PgSearch::Model pg_search_scope :search_by_query, - against: %i[city neighborhood address name], - ignoring: :accents, - using: { - tsearch: { - prefix: true - } - } + against: %i[city neighborhood address name], + ignoring: :accents, + using: { + tsearch: { + prefix: true + } + } has_one_attached :logo @@ -73,7 +73,7 @@ def next_reg_number_seq def ensure_url return if web.blank? || URI.parse(web).is_a?(URI::HTTP) - rescue + rescue StandardError errors.add(:web, :url_format_invalid) else if URI.parse("http://#{web}").is_a?(URI::HTTP) diff --git a/app/models/petition.rb b/app/models/petition.rb index 24ad28376..dbad7ee41 100644 --- a/app/models/petition.rb +++ b/app/models/petition.rb @@ -1,5 +1,5 @@ class Petition < ApplicationRecord - enum status: %i[pending accepted declined] + enum status: { pending: 0, accepted: 1, declined: 2 } belongs_to :user belongs_to :organization diff --git a/app/models/post.rb b/app/models/post.rb index 199755bf3..0c63f5486 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -3,14 +3,14 @@ class Post < ApplicationRecord include PgSearch::Model pg_search_scope :search_by_query, - against: [:title, :description, :tags], - ignoring: :accents, - using: { - tsearch: { - prefix: true, - tsvector_column: 'tsv' - } - } + against: %i[title description tags], + ignoring: :accents, + using: { + tsearch: { + prefix: true, + tsvector_column: "tsv" + } + } attr_reader :member_id @@ -47,7 +47,7 @@ class Post < ApplicationRecord validates :title, presence: true def as_indexed_json(*) - as_json(only: [:title, :description, :tags, :organization_id]) + as_json(only: %i[title description tags organization_id]) end def to_s @@ -71,6 +71,6 @@ def member end def rendered_description - RDiscount.new(description || '', :autolink) + RDiscount.new(description || "", :autolink) end end diff --git a/app/models/push_notification.rb b/app/models/push_notification.rb index 8344537b8..26872ed82 100644 --- a/app/models/push_notification.rb +++ b/app/models/push_notification.rb @@ -1,6 +1,6 @@ class PushNotification < ApplicationRecord - belongs_to :event, foreign_key: 'event_id' - belongs_to :device_token, foreign_key: 'device_token_id' + belongs_to :event + belongs_to :device_token validates :title, :body, presence: true, allow_blank: false diff --git a/app/models/transfer.rb b/app/models/transfer.rb index 41e4db8ca..10419f19b 100644 --- a/app/models/transfer.rb +++ b/app/models/transfer.rb @@ -24,7 +24,8 @@ class Transfer < ApplicationRecord def make_movements movements.create(account: Account.find(source_id), amount: -amount.to_i, created_at: created_at) - movements.create(account: Account.find(destination_id), amount: amount.to_i, created_at: created_at) + movements.create(account: Account.find(destination_id), amount: amount.to_i, + created_at: created_at) end def source_id @@ -37,6 +38,7 @@ def destination_id def different_source_and_destination return unless source == destination + errors.add(:base, :same_account) end end diff --git a/app/models/transfer_factory.rb b/app/models/transfer_factory.rb index a093299cd..29769d8d2 100644 --- a/app/models/transfer_factory.rb +++ b/app/models/transfer_factory.rb @@ -73,8 +73,8 @@ def admin? # # @return [Account] def destination_account - @destination_account ||= current_organization - .all_accounts - .find(destination_account_id) + @destination_account ||= current_organization. + all_accounts. + find(destination_account_id) end end diff --git a/app/models/transfer_sources_options.rb b/app/models/transfer_sources_options.rb index f9c2b2a9d..252d5fda2 100644 --- a/app/models/transfer_sources_options.rb +++ b/app/models/transfer_sources_options.rb @@ -13,9 +13,9 @@ def initialize(sources) # # @return [Array] def to_a - sources - .sort_by { |account| to_accountable_type_and_uid(account) } - .map { |account| to_text_and_value(account) } + sources. + sort_by { |account| to_accountable_type_and_uid(account) }. + map { |account| to_text_and_value(account) } end private diff --git a/app/models/user.rb b/app/models/user.rb index 49f462f19..8a3b58cd0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,16 +1,9 @@ class User < ApplicationRecord - devise *[ - :database_authenticatable, - :recoverable, - :rememberable, - :confirmable, - :lockable, - :trackable, - :timeoutable - ] + devise :database_authenticatable, :recoverable, :rememberable, :confirmable, :lockable, + :trackable, :timeoutable ransacker :username do - Arel.sql('unaccent(users.username)') + Arel.sql("unaccent(users.username)") end GENDERS = %w( @@ -20,8 +13,7 @@ class User < ApplicationRecord prefer_not_to_answer ) - attr_accessor :empty_email - attr_accessor :from_signup + attr_accessor :empty_email, :from_signup has_one_attached :avatar @@ -47,8 +39,8 @@ class User < ApplicationRecord validates :password, presence: true, if: :from_signup? # Allows @domain.com for dummy emails but does not allow pure invalid # emails like 'without email' - validates_format_of :email, - with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i + validates :email, + format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i } validates :gender, inclusion: { in: GENDERS, allow_blank: true } def as_member_of(organization) @@ -85,7 +77,7 @@ def add_to_organization(organization) persister = ::Persister::MemberPersister.new(member) persister.save - return member if member.persisted? + member if member.persisted? end def active?(organization) @@ -133,7 +125,8 @@ def email_if_real end def was_member?(petition) - petition.status == 'accepted' && Member.where(organization: petition.organization, user: self).none? + petition.status == "accepted" && Member.where(organization: petition.organization, + user: self).none? end def from_signup? diff --git a/app/services/operations/transfers.rb b/app/services/operations/transfers.rb index 8bd56a59b..003f78c8c 100644 --- a/app/services/operations/transfers.rb +++ b/app/services/operations/transfers.rb @@ -11,12 +11,11 @@ def create(from:, to:, transfer_params:) end def transfer_klass(from:, to:) - case - when from.length == 1 && to.length == 1 + if from.length == 1 && to.length == 1 OneToOne - when from.length > 1 && to.length == 1 + elsif from.length > 1 && to.length == 1 ManyToOne - when from.length == 1 && to.length > 1 + elsif from.length == 1 && to.length > 1 OneToMany else raise ArgumentError, "Unknown type of transfer" diff --git a/app/services/operations/transfers/base.rb b/app/services/operations/transfers/base.rb index 7950b069b..67d265424 100644 --- a/app/services/operations/transfers/base.rb +++ b/app/services/operations/transfers/base.rb @@ -37,9 +37,9 @@ def transfers def build_transfer(source:, destination:) ::Transfer.new(transfer_params_for( - source: source, - destination: destination - )) + source: source, + destination: destination + )) end def transfer_params_for(source:, destination:) diff --git a/app/services/operations/transfers/one_to_many.rb b/app/services/operations/transfers/one_to_many.rb index f24f4e9ae..629e749b6 100644 --- a/app/services/operations/transfers/one_to_many.rb +++ b/app/services/operations/transfers/one_to_many.rb @@ -22,4 +22,3 @@ def destinations end end end - diff --git a/app/services/persister/member_persister.rb b/app/services/persister/member_persister.rb index c03bcd201..b790740c6 100644 --- a/app/services/persister/member_persister.rb +++ b/app/services/persister/member_persister.rb @@ -12,7 +12,7 @@ def save create_save_event! member end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end @@ -22,7 +22,7 @@ def update(params) create_update_event! member end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end diff --git a/app/services/persister/post_persister.rb b/app/services/persister/post_persister.rb index c5287647c..c9bea3a34 100644 --- a/app/services/persister/post_persister.rb +++ b/app/services/persister/post_persister.rb @@ -13,7 +13,7 @@ def save enqueue_push_notification_job! post end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end @@ -24,7 +24,7 @@ def update(params) enqueue_push_notification_job! post end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end diff --git a/app/services/persister/transfer_persister.rb b/app/services/persister/transfer_persister.rb index 2a48cfa20..c540d6f6f 100644 --- a/app/services/persister/transfer_persister.rb +++ b/app/services/persister/transfer_persister.rb @@ -12,7 +12,7 @@ def save create_save_event! transfer end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end @@ -22,7 +22,7 @@ def update(params) create_update_event! transfer end - rescue ActiveRecord::RecordInvalid => _exception + rescue ActiveRecord::RecordInvalid => _e false end diff --git a/app/services/push_notifications/broadcast.rb b/app/services/push_notifications/broadcast.rb index 9681ea9d2..09f07c987 100644 --- a/app/services/push_notifications/broadcast.rb +++ b/app/services/push_notifications/broadcast.rb @@ -46,7 +46,7 @@ def client end def uri - URI('https://exp.host/--/api/v2/push/send') + URI("https://exp.host/--/api/v2/push/send") end def headers diff --git a/app/services/push_notifications/creator/base.rb b/app/services/push_notifications/creator/base.rb index b7fdec805..f08f0eef9 100644 --- a/app/services/push_notifications/creator/base.rb +++ b/app/services/push_notifications/creator/base.rb @@ -27,15 +27,15 @@ def create! attr_accessor :event def title - raise 'implement the private method `title`' + raise "implement the private method `title`" end def body - raise 'implement the private method `body`' + raise "implement the private method `body`" end def data - raise 'implement the private method `data`' + raise "implement the private method `data`" end end end diff --git a/app/services/push_notifications/creator/post.rb b/app/services/push_notifications/creator/post.rb index 66e047d6e..6a2fdf94d 100644 --- a/app/services/push_notifications/creator/post.rb +++ b/app/services/push_notifications/creator/post.rb @@ -11,16 +11,16 @@ def body description = event.post.description if description.blank? - 'No description' + "No description" else description.truncate(20) end end def data - if event.post.class.to_s == 'Offer' + if event.post.class.to_s == "Offer" { url: Rails.application.routes.url_helpers.offer_path(event.post) } - elsif event.post.class.to_s == 'Inquiry' + elsif event.post.class.to_s == "Inquiry" { url: Rails.application.routes.url_helpers.inquiry_path(event.post) } else {} diff --git a/app/services/push_notifications/event_notifier/post.rb b/app/services/push_notifications/event_notifier/post.rb index 0a685c03e..9ed81e156 100644 --- a/app/services/push_notifications/event_notifier/post.rb +++ b/app/services/push_notifications/event_notifier/post.rb @@ -29,12 +29,12 @@ def device_tokens # # @return def user_ids - post - .organization - .users - .select(:id) - .where('members.active = true') - .where('users.push_notifications = true') + post. + organization. + users. + select(:id). + where("members.active = true"). + where("users.push_notifications = true") end end end diff --git a/app/services/push_notifications/event_notifier_factory.rb b/app/services/push_notifications/event_notifier_factory.rb index 092583084..2f0a4e480 100644 --- a/app/services/push_notifications/event_notifier_factory.rb +++ b/app/services/push_notifications/event_notifier_factory.rb @@ -7,7 +7,7 @@ def initialize(event:) def build return EventNotifier::Post.new(event: event) if event.post_id - raise 'The resource associated to the Event is not supported' + raise "The resource associated to the Event is not supported" end private diff --git a/app/services/transfer_importer.rb b/app/services/transfer_importer.rb index 93acbc135..617909c51 100644 --- a/app/services/transfer_importer.rb +++ b/app/services/transfer_importer.rb @@ -15,8 +15,9 @@ class TransferImporter :post_id ) do def transfer_from_row(organization_id, errors) - source = find_account(source_id, source_type, organization_id, errors, 'source') - destination = find_account(destination_id, destination_type, organization_id, errors, 'destination') + source = find_account(source_id, source_type, organization_id, errors, "source") + destination = find_account(destination_id, destination_type, organization_id, errors, + "destination") return unless source && destination Transfer.new( @@ -32,14 +33,15 @@ def transfer_from_row(organization_id, errors) private def find_account(id, type, organization_id, errors, direction) - acc = if type.downcase == 'organization' + acc = if type.downcase == "organization" Organization.find(organization_id).account else Member.find_by(member_uid: id, organization_id: organization_id)&.account end unless acc - errors.push(account_id: id, errors: "#{direction}_id #{id} not found in organization #{organization_id}") + errors.push(account_id: id, + errors: "#{direction}_id #{id} not found in organization #{organization_id}") return false end acc diff --git a/app/services/user_importer.rb b/app/services/user_importer.rb index b75ac273c..8a9c2f1e6 100644 --- a/app/services/user_importer.rb +++ b/app/services/user_importer.rb @@ -68,9 +68,10 @@ def member_from_row(row, user, organization, errors) entry_date: row.entry_date, user_id: user.id) - errors.push(member_id: row.member_id, email: row.email, - errors: member.errors.full_messages - ) if member.errors.present? + if member.errors.present? + errors.push(member_id: row.member_id, email: row.email, + errors: member.errors.full_messages) + end end end end diff --git a/bin/bundle b/bin/bundle index 66e9889e8..67efc37fb 100755 --- a/bin/bundle +++ b/bin/bundle @@ -1,3 +1,3 @@ #!/usr/bin/env ruby -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) -load Gem.bin_path('bundler', 'bundle') +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) +load Gem.bin_path("bundler", "bundle") diff --git a/bin/rails b/bin/rails index 073966023..efc037749 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 17240489f..4fbf10b96 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 f1b194644..8a019fb31 100755 --- a/bin/setup +++ b/bin/setup @@ -1,8 +1,8 @@ #!/usr/bin/env ruby -require 'fileutils' +require "fileutils" # path to your application root. -APP_ROOT = File.expand_path('..', __dir__) +APP_ROOT = File.expand_path("..", __dir__) def system!(*args) system(*args) || abort("\n== Command #{args} failed ==") @@ -13,16 +13,16 @@ FileUtils.chdir APP_ROOT do # This script is idempotent, so that you can run it at anytime and get an expectable outcome. # Add necessary setup steps to this file. - puts '== Installing dependencies ==' - system! 'gem install bundler --conservative' - system('bundle check') || system!('bundle install') + puts "== Installing dependencies ==" + system! "gem install bundler --conservative" + system("bundle check") || system!("bundle install") puts "\n== Preparing database ==" - system! 'bin/rails db:prepare' + system! "bin/rails db:prepare" puts "\n== Removing old logs and tempfiles ==" - system! 'bin/rails log:clear tmp:clear' + system! "bin/rails log:clear tmp:clear" puts "\n== Restarting application server ==" - system! 'bin/rails restart' + system! "bin/rails restart" end diff --git a/config.ru b/config.ru index f7ba0b527..441e6ff0c 100644 --- a/config.ru +++ b/config.ru @@ -1,5 +1,5 @@ # This file is used by Rack-based servers to start the application. -require_relative 'config/environment' +require_relative "config/environment" run Rails.application diff --git a/config/application.rb b/config/application.rb index 5abfe24d0..ffa5a692f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,6 @@ -require File.expand_path('../boot', __FILE__) +require File.expand_path("boot", __dir__) -require 'rails/all' +require "rails/all" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -13,11 +13,11 @@ class Application < Rails::Application # I18n configuration config.i18n.default_locale = :es - config.i18n.available_locales = [:es, :ca, :eu, :gl, :en, :'pt-BR', :fr] + config.i18n.available_locales = %i[es ca eu gl en pt-BR fr] config.i18n.fallbacks = true # This tells Rails to serve error pages from the app itself, rather than using static error pages in public/ - config.exceptions_app = self.routes + config.exceptions_app = routes # Activate the Skylight agent in staging. You need to provision the # SKYLIGHT_AUTHENTICATION env var for this to work. @@ -31,10 +31,10 @@ class Application < Rails::Application config.active_record.schema_format = :sql # Guard against DNS rebinding attacks by permitting hosts - config.hosts << 'localhost' - config.hosts << 'timeoverflow.local' - config.hosts << 'staging.timeoverflow.org' - config.hosts << 'www.timeoverflow.org' - config.hosts << 'timeoverflow.org' + config.hosts << "localhost" + config.hosts << "timeoverflow.local" + config.hosts << "staging.timeoverflow.org" + config.hosts << "www.timeoverflow.org" + config.hosts << "timeoverflow.org" end end diff --git a/config/boot.rb b/config/boot.rb index b9e460cef..988a5ddc4 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,4 +1,4 @@ -ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) -require 'bundler/setup' # Set up gems listed in the Gemfile. -require 'bootsnap/setup' # Speed up boot time by caching expensive operations. +require "bundler/setup" # Set up gems listed in the Gemfile. +require "bootsnap/setup" # Speed up boot time by caching expensive operations. diff --git a/config/environment.rb b/config/environment.rb index 426333bb4..cac531577 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -1,5 +1,5 @@ # Load the Rails application. -require_relative 'application' +require_relative "application" # Initialize the Rails application. Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb index c2189cb2a..532c74d5f 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -14,13 +14,13 @@ # Enable/disable caching. By default caching is disabled. # Run rails dev:cache to toggle caching. - if Rails.root.join('tmp', 'caching-dev.txt').exist? + if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true config.cache_store = :memory_store config.public_file_server.headers = { - 'Cache-Control' => "public, max-age=#{2.days.to_i}" + "Cache-Control" => "public, max-age=#{2.days.to_i}" } else config.action_controller.perform_caching = false @@ -38,7 +38,7 @@ config.action_mailer.delivery_method = :letter_opener config.action_mailer.default_url_options = { - host: (ENV["MAIL_LINK_HOST"] || "localhost:3000") + host: ENV["MAIL_LINK_HOST"] || "localhost:3000" } # Print deprecation notices to the Rails logger. diff --git a/config/environments/production.rb b/config/environments/production.rb index 70249b0ef..34ae293aa 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -57,10 +57,16 @@ # Use the lowest log level to ensure availability of diagnostic information # when problems arise. - config.log_level = %w(debug info warn error fatal).include?(ENV.fetch("RAILS_LOG_LEVEL", nil)) ? ENV["RAILS_LOG_LEVEL"] : :info + config.log_level = if %w(debug info warn error + fatal).include?(ENV.fetch("RAILS_LOG_LEVEL", + nil)) + ENV["RAILS_LOG_LEVEL"] + else + :info + end # Prepend all log lines with the following tags. - config.log_tags = [ :request_id ] + config.log_tags = [:request_id] # Use a different cache store in production. # config.cache_store = :mem_cache_store @@ -78,10 +84,10 @@ config.action_mailer.delivery_method = :smtp config.action_mailer.default_url_options = { host: ENV["MAIL_LINK_HOST"], - protocol: (ENV["MAIL_LINK_PROTO"] || "https") + protocol: ENV["MAIL_LINK_PROTO"] || "https" } - smtp_env = Hash[ENV.map do |k,v| + smtp_env = Hash[ENV.map do |k, v| if /^SMTP_(.*)$/ === k [$1.downcase.to_sym, YAML.load(v)] end diff --git a/config/environments/staging.rb b/config/environments/staging.rb index cb080f68a..221c983cc 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -1,2 +1,2 @@ -# Use same settings we use for production +#  Use same settings we use for production require_relative "production" diff --git a/config/environments/test.rb b/config/environments/test.rb index a897f877b..e7efdf9fd 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -16,7 +16,7 @@ # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true config.public_file_server.headers = { - 'Cache-Control' => "public, max-age=#{1.hour.to_i}" + "Cache-Control" => "public, max-age=#{1.hour.to_i}" } # Show full error reports and disable caching. diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb index 135f86fa6..9419a5c4d 100644 --- a/config/initializers/active_admin.rb +++ b/config/initializers/active_admin.rb @@ -13,7 +13,9 @@ admin.build_menu :utility_navigation do |menu| menu.add id: :languages, label: -> { "Languages (#{I18n.t("locales.#{locale}")})" } do |lang| I18n.available_locales.each do |locale| - lang.add label: I18n.t("locales.#{locale}", locale: locale), url: ->{ url_for(locale: locale) } + lang.add label: I18n.t("locales.#{locale}", locale: locale), url: -> { + url_for(locale: locale) + } end end admin.add_current_user_to_menu menu diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index ee1f11b3a..487324424 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -1,7 +1,7 @@ # Be sure to restart your server when you modify this file. # Version of your assets, change this if you want to expire all your assets. -Rails.application.config.assets.version = '1.0' +Rails.application.config.assets.version = "1.0" # Add additional assets to the asset load path. # Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index b26fd5bae..a9531aa03 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -4,13 +4,13 @@ # The secret key used by Devise. Devise uses this key to generate # random tokens. Changing this key will render invalid all existing # confirmation, reset password and unlock tokens in the database. - config.secret_key = '314feb2dc06c4ff725d7c53e4d9d9aeda03dc2b7aa9ee1a9b74fbb48991c3dfb937165d752108c6406942f40ac4cf7786d71cf30869eeece2e8d9be1a5c3b1cb' + config.secret_key = "314feb2dc06c4ff725d7c53e4d9d9aeda03dc2b7aa9ee1a9b74fbb48991c3dfb937165d752108c6406942f40ac4cf7786d71cf30869eeece2e8d9be1a5c3b1cb" # ==> Mailer Configuration # Configure the e-mail address which will be shown in Devise::Mailer, # note that it will be overwritten if you use your own mailer class # with default "from" parameter. - config.mailer_sender = ENV['MAILER_SENDER'] || 'please-change-me-at-config-initializers-devise@example.com' + config.mailer_sender = ENV["MAILER_SENDER"] || "please-change-me-at-config-initializers-devise@example.com" # Configure the class responsible to send e-mails. # config.mailer = 'Devise::Mailer' @@ -19,7 +19,7 @@ # Load and configure the ORM. Supports :active_record (default) and # :mongoid (bson_ext recommended) by default. Other ORMs may be # available as additional gems. - require 'devise/orm/active_record' + require "devise/orm/active_record" # ==> Configuration for any authentication mechanism # Configure which keys are used when authenticating a user. The default is @@ -41,12 +41,12 @@ # Configure which authentication keys should be case-insensitive. # These keys will be downcased upon creating or modifying a user and when used # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [ :email ] + config.case_insensitive_keys = [:email] # Configure which authentication keys should have whitespace stripped. # These keys will have whitespace before and after removed upon creating or # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [ :email ] + config.strip_whitespace_keys = [:email] # Tell if authentication through request.params is enabled. True by default. # It can be set to an array that will enable params authentication only for the @@ -123,7 +123,7 @@ config.reconfirmable = true # Defines which key will be used when confirming an account - config.confirmation_keys = [ :email ] + config.confirmation_keys = [:email] # ==> Configuration for :rememberable # The time the user will be remembered without asking for credentials again. @@ -160,7 +160,7 @@ config.lock_strategy = :failed_attempts # Defines which key will be used when locking and unlocking an account - config.unlock_keys = [ :email ] + config.unlock_keys = [:email] # Defines which strategy will be used to unlock an account. # :email = Sends an unlock link to the user email diff --git a/config/initializers/ransack.rb b/config/initializers/ransack.rb index 145aa5491..8f6fee546 100644 --- a/config/initializers/ransack.rb +++ b/config/initializers/ransack.rb @@ -1,8 +1,8 @@ Ransack.configure do |config| - config.add_predicate 'unaccent_cont', - arel_predicate: 'matches', + config.add_predicate "unaccent_cont", + arel_predicate: "matches", formatter: proc { |s| ActiveSupport::Inflector.transliterate("%#{s}%") }, validator: proc { |s| s.present? }, compounds: true, type: :string -end \ No newline at end of file +end diff --git a/config/initializers/rollbar.rb b/config/initializers/rollbar.rb index b31bdac41..f8ff7b923 100644 --- a/config/initializers/rollbar.rb +++ b/config/initializers/rollbar.rb @@ -1,15 +1,14 @@ -require 'rollbar/rails' +require "rollbar/rails" Rollbar.configure do |config| # Without configuration, Rollbar is enabled in all environments. # To disable in specific environments, set config.enabled=false. - - config.access_token = ENV['ROLLBAR_ACCESS_TOKEN'] + + config.access_token = ENV["ROLLBAR_ACCESS_TOKEN"] # Here we'll disable in 'test': - if Rails.env.test? or ENV['ROLLBAR_ACCESS_TOKEN'].blank? + if Rails.env.test? or ENV["ROLLBAR_ACCESS_TOKEN"].blank? config.enabled = false end - # By default, Rollbar will try to call the `current_user` controller method # to fetch the logged-in user object, and then call that object's `id`, @@ -34,13 +33,13 @@ # You can also specify a callable, which will be called with the exception instance. # Ignore the typical "attacks..." - config.exception_level_filters.merge!('ActionController::RoutingError' => lambda { |e| + config.exception_level_filters.merge!("ActionController::RoutingError" => lambda { |e| e.message =~ %r(No route matches \[[A-Z]+\] "/(.+)") case $1.split("/").first.to_s.downcase - when *%w(myadmin phpmyadmin w00tw00t pma cgi-bin xmlrpc.php wp wordpress cfide) - 'ignore' + when "myadmin", "phpmyadmin", "w00tw00t", "pma", "cgi-bin", "xmlrpc.php", "wp", "wordpress", "cfide" + "ignore" else - 'warning' + "warning" end }) diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index 3de777e44..5d93e9e06 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,3 +1,3 @@ # Be sure to restart your server when you modify this file. -Rails.application.config.session_store :cookie_store, key: '_timeoverflow_session' +Rails.application.config.session_store :cookie_store, key: "_timeoverflow_session" diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb index d86db2045..681614454 100644 --- a/config/initializers/simple_form.rb +++ b/config/initializers/simple_form.rb @@ -5,8 +5,8 @@ # wrapper, change the order or even add your own to the # stack. The options given below are used to wrap the # whole input. - config.wrappers :default, :class => :input, - :hint_class => :field_with_hint, :error_class => :field_with_errors do |b| + config.wrappers :default, class: :input, + hint_class: :field_with_hint, error_class: :field_with_errors do |b| ## Extensions enabled by default # Any of these extensions can be disabled for a # given input by passing: `f.input EXTENSION_NAME => false`. @@ -41,8 +41,8 @@ ## Inputs b.use :label_input - b.use :hint, :wrap_with => { :tag => :span, :class => :hint } - b.use :error, :wrap_with => { :tag => :span, :class => :error } + b.use :hint, wrap_with: { tag: :span, class: :hint } + b.use :error, wrap_with: { tag: :span, class: :error } end # The default wrapper to be used by the FormBuilder. @@ -55,7 +55,7 @@ config.boolean_style = :nested # Default class for buttons - config.button_class = 'btn btn-default' + config.button_class = "btn btn-default" # Method used to tidy up errors. Specify any Rails Array method. # :first lists the first message for each field. @@ -66,7 +66,7 @@ config.error_notification_tag = :div # CSS class to add for error notification helper. - config.error_notification_class = 'alert alert-danger' + config.error_notification_class = "alert alert-danger" # ID to add for error notification helper. # config.error_notification_id = nil @@ -95,7 +95,7 @@ # config.label_text = lambda { |label, required| "#{required} #{label}" } # You can define the class to use on all labels. Default is nil. - config.label_class = 'control-label' + config.label_class = "control-label" # You can define the class to use on all forms. Default is simple_form. # config.form_class = :simple_form diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb index d18446f2f..e420612f3 100644 --- a/config/initializers/simple_form_bootstrap.rb +++ b/config/initializers/simple_form_bootstrap.rb @@ -1,39 +1,39 @@ # Use this setup block to configure all options available in SimpleForm. SimpleForm.setup do |config| - config.wrappers :bootstrap, :tag => 'div', :class => 'form-group', :error_class => 'error' do |b| + config.wrappers :bootstrap, tag: "div", class: "form-group", error_class: "error" do |b| b.use :html5 b.use :placeholder b.use :label # b.wrapper :tag => 'div', :class => 'controls' do |ba| - b.use :input, :class => "form-control" - # ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } - # ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } + b.use :input, class: "form-control" + # ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + # ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' } # end end - config.wrappers :prepend, :tag => 'div', :class => "form-group", :error_class => 'error' do |b| + config.wrappers :prepend, tag: "div", class: "form-group", error_class: "error" do |b| b.use :html5 b.use :placeholder b.use :label - b.wrapper :tag => 'div', :class => 'controls' do |input| - input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend| + b.wrapper tag: "div", class: "controls" do |input| + input.wrapper tag: "div", class: "input-prepend" do |prepend| prepend.use :input end - input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } - input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + input.use :hint, wrap_with: { tag: "span", class: "help-block" } + input.use :error, wrap_with: { tag: "span", class: "help-inline" } end end - config.wrappers :append, :tag => 'div', :class => "form-group", :error_class => 'error' do |b| + config.wrappers :append, tag: "div", class: "form-group", error_class: "error" do |b| b.use :html5 b.use :placeholder b.use :label - b.wrapper :tag => 'div', :class => 'controls' do |input| - input.wrapper :tag => 'div', :class => 'input-append' do |append| + b.wrapper tag: "div", class: "controls" do |input| + input.wrapper tag: "div", class: "input-append" do |append| append.use :input end - input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' } - input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' } + input.use :hint, wrap_with: { tag: "span", class: "help-block" } + input.use :error, wrap_with: { tag: "span", class: "help-inline" } end end diff --git a/config/initializers/superadmins.rb b/config/initializers/superadmins.rb index e1105cb00..7774a493a 100644 --- a/config/initializers/superadmins.rb +++ b/config/initializers/superadmins.rb @@ -1 +1 @@ -ADMINS = ENV["ADMINS"].to_s.split \ No newline at end of file +ADMINS = ENV["ADMINS"].to_s.split diff --git a/config/routes.rb b/config/routes.rb index 500c4581d..f5002e932 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,11 @@ -require 'sidekiq/web' -require 'sidekiq/cron/web' +require "sidekiq/web" +require "sidekiq/cron/web" Rails.application.routes.draw do root to: "home#index" authenticate :user, lambda { |u| Rails.env.development? || u.superadmin? } do - mount Sidekiq::Web => '/sidekiq' + mount Sidekiq::Web => "/sidekiq" end devise_for :users, controllers: { sessions: "sessions" } @@ -16,7 +16,7 @@ ActiveAdmin.routes(self) - get :switch_lang, to: 'application#switch_lang' + get :switch_lang, to: "application#switch_lang" get "/pages/:page" => "pages#show", as: :page @@ -28,34 +28,35 @@ get :give_time, on: :member end - resources :organizations, except: [:new, :create, :destroy], concerns: :accountable do + resources :organizations, except: %i[new create destroy], concerns: :accountable do member do post :set_current end end - get :select_organization, to: 'organizations#select_organization' + get :select_organization, to: "organizations#select_organization" - resources :users, concerns: :accountable, except: :destroy, :path => "members" do + resources :users, concerns: :accountable, except: :destroy, path: "members" do collection do - get 'signup' - get 'manage' - get 'please_confirm' + get "signup" + get "manage" + get "please_confirm" end end - put :update_avatar, to: 'users#update_avatar' + put :update_avatar, to: "users#update_avatar" - resources :petitions, only: [:create, :update] do + resources :petitions, only: %i[create update] do collection do - get 'manage' + get "manage" end end - resources :transfers, only: [:new, :create] do + resources :transfers, only: %i[new create] do member do put :delete_reason end end - match "multi/step/:step", to: "multi_transfers#step", via: [:get, :post], as: :multi_transfers_step + match "multi/step/:step", to: "multi_transfers#step", via: %i[get post], + as: :multi_transfers_step post "multi/create", to: "multi_transfers#create", as: :multi_transfers_create resources :documents @@ -99,6 +100,6 @@ end end - match '/404', to: 'errors#not_found', via: :all - match '/500', to: 'errors#internal_server_error', via: :all + match "/404", to: "errors#not_found", via: :all + match "/500", to: "errors#internal_server_error", via: :all end diff --git a/db/migrate/00000000000001_setup_hstore.rb b/db/migrate/00000000000001_setup_hstore.rb index 9557de413..10c203dc4 100644 --- a/db/migrate/00000000000001_setup_hstore.rb +++ b/db/migrate/00000000000001_setup_hstore.rb @@ -2,6 +2,7 @@ class SetupHstore < ActiveRecord::Migration def self.up enable_extension "hstore" end + def self.down disable_extension "hstore" end diff --git a/db/migrate/00000000000002_setup_pg_trgm.rb b/db/migrate/00000000000002_setup_pg_trgm.rb index 1176b668f..6ccb8321a 100644 --- a/db/migrate/00000000000002_setup_pg_trgm.rb +++ b/db/migrate/00000000000002_setup_pg_trgm.rb @@ -2,6 +2,7 @@ class SetupPgTrgm < ActiveRecord::Migration def self.up enable_extension "pg_trgm" end + def self.down disable_extension "pg_trgm" end diff --git a/db/migrate/20121019101022_create_users.rb b/db/migrate/20121019101022_create_users.rb index d2b872d91..c20e05d0e 100644 --- a/db/migrate/20121019101022_create_users.rb +++ b/db/migrate/20121019101022_create_users.rb @@ -1,9 +1,9 @@ class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| - t.string :username, :null => false # if you use another field as a username, for example email, you can safely remove this field. - t.string :email, :null => false # if you use this field as a username, you might want to make it :null => false. - t.string :password_digest, :default => nil + t.string :username, null: false # if you use another field as a username, for example email, you can safely remove this field. + t.string :email, null: false # if you use this field as a username, you might want to make it :null => false. + t.string :password_digest, default: nil t.date :date_of_birth t.string :identity_document t.string :member_code @@ -22,7 +22,4 @@ def change add_index :users, :email add_index :users, :organization_id end - end - - diff --git a/db/migrate/20121104085711_create_categories.rb b/db/migrate/20121104085711_create_categories.rb index b3728d16b..c1680b540 100644 --- a/db/migrate/20121104085711_create_categories.rb +++ b/db/migrate/20121104085711_create_categories.rb @@ -8,14 +8,14 @@ def change end add_index :categories, :parent_id - create_table :category_hierarchies, :id => false do |t| - t.integer :ancestor_id, :null => false # ID of the parent/grandparent/great-grandparent/... tag - t.integer :descendant_id, :null => false # ID of the target tag - t.integer :generations, :null => false # Number of generations between the ancestor and the descendant. Parent/child = 1, for example. + create_table :category_hierarchies, id: false do |t| + t.integer :ancestor_id, null: false # ID of the parent/grandparent/great-grandparent/... tag + t.integer :descendant_id, null: false # ID of the target tag + t.integer :generations, null: false # Number of generations between the ancestor and the descendant. Parent/child = 1, for example. end # For "all progeny of…" selects: - add_index :category_hierarchies, [:ancestor_id, :descendant_id], :unique => true + add_index :category_hierarchies, %i[ancestor_id descendant_id], unique: true # For "all ancestors of…" selects add_index :category_hierarchies, [:descendant_id] diff --git a/db/migrate/20130222185624_create_transfer.rb b/db/migrate/20130222185624_create_transfer.rb index 75d3ce923..2bb13225f 100644 --- a/db/migrate/20130222185624_create_transfer.rb +++ b/db/migrate/20130222185624_create_transfer.rb @@ -1,7 +1,5 @@ class CreateTransfer < ActiveRecord::Migration - def up - end + def up; end - def down - end + def down; end end diff --git a/db/migrate/20130621102219_remove_features_from_categories.rb b/db/migrate/20130621102219_remove_features_from_categories.rb index 6cdb6f10b..ba90f3dc7 100644 --- a/db/migrate/20130621102219_remove_features_from_categories.rb +++ b/db/migrate/20130621102219_remove_features_from_categories.rb @@ -11,4 +11,3 @@ def change drop_table :category_hierarchies end end - diff --git a/db/migrate/20130621105452_acts_as_taggable_on_migration.rb b/db/migrate/20130621105452_acts_as_taggable_on_migration.rb index e8b978d96..9c74afa67 100644 --- a/db/migrate/20130621105452_acts_as_taggable_on_migration.rb +++ b/db/migrate/20130621105452_acts_as_taggable_on_migration.rb @@ -9,18 +9,18 @@ def self.up # You should make sure that the column created is # long enough to store the required class names. - t.references :taggable, :polymorphic => true - t.references :tagger, :polymorphic => true + t.references :taggable, polymorphic: true + t.references :tagger, polymorphic: true # Limit is created to prevent MySQL error on index # length for MyISAM table type: http://bit.ly/vgW2Ql - t.string :context, :limit => 128 + t.string :context, limit: 128 t.datetime :created_at end add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] + add_index :taggings, %i[taggable_id taggable_type context] end def self.down diff --git a/db/migrate/20131025202608_add_name_translations_to_category.rb b/db/migrate/20131025202608_add_name_translations_to_category.rb index 5cbcfa938..5c8cc5923 100644 --- a/db/migrate/20131025202608_add_name_translations_to_category.rb +++ b/db/migrate/20131025202608_add_name_translations_to_category.rb @@ -3,6 +3,7 @@ def up add_column :categories, :name_translations, :hstore remove_column :categories, :name end + def down remove_column :categories, :name_translations, :hstore add_column :categories, :name diff --git a/db/migrate/20131027215517_add_tags_to_posts.rb b/db/migrate/20131027215517_add_tags_to_posts.rb index e03410a22..009b2bfcd 100644 --- a/db/migrate/20131027215517_add_tags_to_posts.rb +++ b/db/migrate/20131027215517_add_tags_to_posts.rb @@ -6,7 +6,7 @@ def up say "Tag column added" ActiveRecord::Base.connection.execute( - <<-SQL + <<-SQL WITH prepared_tags AS ( SELECT "posts"."id" AS "id", array_agg("tags"."name") AS "tags" FROM "posts" @@ -28,7 +28,6 @@ def up drop_table :tags say "acts_as_taggable_on tables removed" - end def down @@ -43,23 +42,20 @@ def down # You should make sure that the column created is # long enough to store the required class names. - t.references :taggable, :polymorphic => true - t.references :tagger, :polymorphic => true + t.references :taggable, polymorphic: true + t.references :tagger, polymorphic: true # Limit is created to prevent MySQL error on index # length for MyISAM table type: http://bit.ly/vgW2Ql - t.string :context, :limit => 128 + t.string :context, limit: 128 t.datetime :created_at end add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] - + add_index :taggings, %i[taggable_id taggable_type context] remove_column :posts, :tags remove_index :posts, :tags end end - - diff --git a/db/migrate/20131029202724_create_active_admin_comments.rb b/db/migrate/20131029202724_create_active_admin_comments.rb index 90ed7b93a..c521d5d8b 100644 --- a/db/migrate/20131029202724_create_active_admin_comments.rb +++ b/db/migrate/20131029202724_create_active_admin_comments.rb @@ -3,14 +3,14 @@ def self.up create_table :active_admin_comments do |t| t.string :namespace t.text :body - t.string :resource_id, :null => false - t.string :resource_type, :null => false - t.references :author, :polymorphic => true + t.string :resource_id, null: false + t.string :resource_type, null: false + t.references :author, polymorphic: true t.timestamps end add_index :active_admin_comments, [:namespace] - add_index :active_admin_comments, [:author_type, :author_id] - add_index :active_admin_comments, [:resource_type, :resource_id] + add_index :active_admin_comments, %i[author_type author_id] + add_index :active_admin_comments, %i[resource_type resource_id] end def self.down diff --git a/db/migrate/20131104013829_migrate_membership_data.rb b/db/migrate/20131104013829_migrate_membership_data.rb index 42b2c3188..c0ca46737 100644 --- a/db/migrate/20131104013829_migrate_membership_data.rb +++ b/db/migrate/20131104013829_migrate_membership_data.rb @@ -1,5 +1,4 @@ class MigrateMembershipData < ActiveRecord::Migration - class User < ActiveRecord::Base has_one :account, as: :accountable has_many :members diff --git a/db/migrate/20131220160257_add_active_to_user.rb b/db/migrate/20131220160257_add_active_to_user.rb index 00de4c4a7..3e3c034d4 100644 --- a/db/migrate/20131220160257_add_active_to_user.rb +++ b/db/migrate/20131220160257_add_active_to_user.rb @@ -1,5 +1,5 @@ class AddActiveToUser < ActiveRecord::Migration def change - add_column :users, :active, :boolean, :default => true + add_column :users, :active, :boolean, default: true end end diff --git a/db/migrate/20131227110122_create_documents.rb b/db/migrate/20131227110122_create_documents.rb index 0fd364b7b..1be4a0173 100644 --- a/db/migrate/20131227110122_create_documents.rb +++ b/db/migrate/20131227110122_create_documents.rb @@ -9,7 +9,7 @@ def change t.timestamps end - add_index :documents, [:documentable_id, :documentable_type] + add_index :documents, %i[documentable_id documentable_type] add_index :documents, :label end end diff --git a/db/migrate/20131227155440_add_devise_things_to_users.rb b/db/migrate/20131227155440_add_devise_things_to_users.rb index 6d9a6d2b1..e1bd0c7f8 100644 --- a/db/migrate/20131227155440_add_devise_things_to_users.rb +++ b/db/migrate/20131227155440_add_devise_things_to_users.rb @@ -3,7 +3,7 @@ def change change_table :users do |t| ## Database authenticatable # t.string :email, :null => false, :default => '' - t.string :encrypted_password, :null => false, :default => '' + t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token @@ -13,7 +13,7 @@ def change t.datetime :remember_created_at ## Trackable - t.integer :sign_in_count, :default => 0 + t.integer :sign_in_count, default: 0 t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip @@ -26,7 +26,7 @@ def change t.string :unconfirmed_email ## Lockable - t.integer :failed_attempts, :default => 0 + t.integer :failed_attempts, default: 0 t.string :unlock_token t.datetime :locked_at diff --git a/db/migrate/20140119161433_add_organization_to_post.rb b/db/migrate/20140119161433_add_organization_to_post.rb index 7208af3e1..9328fd5d3 100644 --- a/db/migrate/20140119161433_add_organization_to_post.rb +++ b/db/migrate/20140119161433_add_organization_to_post.rb @@ -10,6 +10,7 @@ def up end end end + def down remove_reference :posts, :organization, index: true end diff --git a/db/migrate/20140513141718_add_new_fields_to_organization.rb b/db/migrate/20140513141718_add_new_fields_to_organization.rb index d7a7dfa6e..788d344e3 100644 --- a/db/migrate/20140513141718_add_new_fields_to_organization.rb +++ b/db/migrate/20140513141718_add_new_fields_to_organization.rb @@ -1,6 +1,6 @@ class AddNewFieldsToOrganization < ActiveRecord::Migration def change - change_table :organizations do |t| + change_table :organizations do |t| t.string :email t.string :phone t.string :web diff --git a/db/migrate/20140514225527_add_active_fields_to_member.rb b/db/migrate/20140514225527_add_active_fields_to_member.rb index 2ac77b470..534e0b240 100644 --- a/db/migrate/20140514225527_add_active_fields_to_member.rb +++ b/db/migrate/20140514225527_add_active_fields_to_member.rb @@ -1,5 +1,5 @@ class AddActiveFieldsToMember < ActiveRecord::Migration def change - add_column :members, :active, :boolean, :default => true + add_column :members, :active, :boolean, default: true end end diff --git a/db/migrate/20180221161343_create_device_tokens.rb b/db/migrate/20180221161343_create_device_tokens.rb index e2d368e3f..6963e5921 100644 --- a/db/migrate/20180221161343_create_device_tokens.rb +++ b/db/migrate/20180221161343_create_device_tokens.rb @@ -1,11 +1,11 @@ class CreateDeviceTokens < ActiveRecord::Migration def change create_table :device_tokens do |t| - t.integer :user_id, :null => false - t.string :token, :null => false + t.integer :user_id, null: false + t.string :token, null: false t.timestamps end - add_index :device_tokens, [:user_id, :token], unique: true + add_index :device_tokens, %i[user_id token], unique: true end end diff --git a/db/migrate/20180501093846_create_events.rb b/db/migrate/20180501093846_create_events.rb index af3fffbee..2014ab0d6 100644 --- a/db/migrate/20180501093846_create_events.rb +++ b/db/migrate/20180501093846_create_events.rb @@ -9,20 +9,20 @@ class CreateEvents < ActiveRecord::Migration def up create_table :events do |t| - t.integer :action, null:false + t.integer :action, null: false t.integer :post_id t.integer :member_id t.integer :transfer_id t.timestamps end - add_foreign_key :events, :posts, name: 'events_post_id_fkey' - add_foreign_key :events, :members, name: 'events_member_id_fkey' - add_foreign_key :events, :transfers, name: 'events_transfer_id_fkey' + add_foreign_key :events, :posts, name: "events_post_id_fkey" + add_foreign_key :events, :members, name: "events_member_id_fkey" + add_foreign_key :events, :transfers, name: "events_transfer_id_fkey" - add_index :events, :post_id, unique: true, where: 'post_id IS NOT NULL' - add_index :events, :member_id, unique: true, where: 'member_id IS NOT NULL' - add_index :events, :transfer_id, unique: true, where: 'transfer_id IS NOT NULL' + add_index :events, :post_id, unique: true, where: "post_id IS NOT NULL" + add_index :events, :member_id, unique: true, where: "member_id IS NOT NULL" + add_index :events, :transfer_id, unique: true, where: "transfer_id IS NOT NULL" execute <<-SQL ALTER TABLE events diff --git a/db/migrate/20180529144243_change_index_on_events.rb b/db/migrate/20180529144243_change_index_on_events.rb index f0753c69b..8696e9720 100644 --- a/db/migrate/20180529144243_change_index_on_events.rb +++ b/db/migrate/20180529144243_change_index_on_events.rb @@ -4,8 +4,8 @@ def change remove_index :events, :member_id remove_index :events, :transfer_id - add_index :events, :post_id, where: 'post_id IS NOT NULL' - add_index :events, :member_id, where: 'member_id IS NOT NULL' - add_index :events, :transfer_id, where: 'transfer_id IS NOT NULL' + add_index :events, :post_id, where: "post_id IS NOT NULL" + add_index :events, :member_id, where: "member_id IS NOT NULL" + add_index :events, :transfer_id, where: "transfer_id IS NOT NULL" end end diff --git a/db/migrate/20180604145622_add_title_to_push_notification.rb b/db/migrate/20180604145622_add_title_to_push_notification.rb index 9b4a91ed2..1e3c3fe68 100644 --- a/db/migrate/20180604145622_add_title_to_push_notification.rb +++ b/db/migrate/20180604145622_add_title_to_push_notification.rb @@ -1,6 +1,6 @@ class AddTitleToPushNotification < ActiveRecord::Migration def up - add_column :push_notifications, :title, :string, null: false, default: '' + add_column :push_notifications, :title, :string, null: false, default: "" end def down diff --git a/db/migrate/20180828160700_add_body_to_push_notification.rb b/db/migrate/20180828160700_add_body_to_push_notification.rb index 52e697ca0..811f718b5 100644 --- a/db/migrate/20180828160700_add_body_to_push_notification.rb +++ b/db/migrate/20180828160700_add_body_to_push_notification.rb @@ -1,6 +1,6 @@ class AddBodyToPushNotification < ActiveRecord::Migration def up - add_column :push_notifications, :body, :string, null: false, default: '' + add_column :push_notifications, :body, :string, null: false, default: "" end def down diff --git a/db/migrate/20180831161349_add_data_to_push_notification.rb b/db/migrate/20180831161349_add_data_to_push_notification.rb index 410349f2f..d7ecb2374 100644 --- a/db/migrate/20180831161349_add_data_to_push_notification.rb +++ b/db/migrate/20180831161349_add_data_to_push_notification.rb @@ -1,6 +1,6 @@ class AddDataToPushNotification < ActiveRecord::Migration def up - add_column :push_notifications, :data, :json, null: false, default: '{}' + add_column :push_notifications, :data, :json, null: false, default: "{}" end def down diff --git a/db/migrate/20180924164456_process_invalid_push_notifications.rb b/db/migrate/20180924164456_process_invalid_push_notifications.rb index c29bde849..3e2bf2d94 100644 --- a/db/migrate/20180924164456_process_invalid_push_notifications.rb +++ b/db/migrate/20180924164456_process_invalid_push_notifications.rb @@ -12,6 +12,6 @@ def up end def down - puts 'no.' + puts "no." end end diff --git a/db/migrate/20181004200104_add_amount_constraint_to_movements.rb b/db/migrate/20181004200104_add_amount_constraint_to_movements.rb index 978eb0269..667162c1d 100644 --- a/db/migrate/20181004200104_add_amount_constraint_to_movements.rb +++ b/db/migrate/20181004200104_add_amount_constraint_to_movements.rb @@ -5,6 +5,6 @@ def change movement.transfer&.destroy end - execute 'ALTER TABLE movements ADD CONSTRAINT non_zero_amount CHECK(amount != 0)' + execute "ALTER TABLE movements ADD CONSTRAINT non_zero_amount CHECK(amount != 0)" end end diff --git a/db/migrate/20210502160343_create_active_storage_tables.active_storage.rb b/db/migrate/20210502160343_create_active_storage_tables.active_storage.rb index 87798267b..f8c490258 100644 --- a/db/migrate/20210502160343_create_active_storage_tables.active_storage.rb +++ b/db/migrate/20210502160343_create_active_storage_tables.active_storage.rb @@ -11,7 +11,7 @@ def change t.string :checksum, null: false t.datetime :created_at, null: false - t.index [ :key ], unique: true + t.index [:key], unique: true end create_table :active_storage_attachments do |t| @@ -21,7 +21,8 @@ def change t.datetime :created_at, null: false - t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true + t.index %i[record_type record_id name blob_id], + name: "index_active_storage_attachments_uniqueness", unique: true t.foreign_key :active_storage_blobs, column: :blob_id end @@ -29,7 +30,8 @@ def change t.belongs_to :blob, null: false, index: false t.string :variation_digest, null: false - t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + 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 diff --git a/db/migrate/20230312231058_migrate_hstore_to_json.rb b/db/migrate/20230312231058_migrate_hstore_to_json.rb index 7ab08b7af..23be0cae5 100644 --- a/db/migrate/20230312231058_migrate_hstore_to_json.rb +++ b/db/migrate/20230312231058_migrate_hstore_to_json.rb @@ -1,7 +1,8 @@ class MigrateHstoreToJson < ActiveRecord::Migration[6.1] def up rename_column :categories, :name_translations, :name_translations_hstore - add_column :categories, :name_translations, :jsonb, default: {}, null: false, index: { using: 'gin' } + add_column :categories, :name_translations, :jsonb, default: {}, null: false, + index: { using: "gin" } execute 'UPDATE "categories" SET "name_translations" = json_object(hstore_to_matrix("name_translations_hstore"))::jsonb' remove_column :categories, :name_translations_hstore end diff --git a/db/migrate/20230314233504_add_icon_name_to_categories.rb b/db/migrate/20230314233504_add_icon_name_to_categories.rb index 7376d3a85..82c3efce6 100644 --- a/db/migrate/20230314233504_add_icon_name_to_categories.rb +++ b/db/migrate/20230314233504_add_icon_name_to_categories.rb @@ -4,19 +4,19 @@ def change # Initialize icon names for each category with mapping defined in #673 icon_mapping = { - 'Acompañamiento' => 'random', - 'Asesoramiento' => 'briefcase', - 'Clases' => 'education', - 'Estética' => 'scissors', - 'Ocio' => 'music', - 'Otros' => 'asterisk', - 'Préstamo de herramientas, material, libros, ...' => 'wrench', - 'Salud' => 'apple', - 'Tareas administrativas' => 'list-alt', - 'Tareas domésticas' => 'shopping-cart' + "Acompañamiento" => "random", + "Asesoramiento" => "briefcase", + "Clases" => "education", + "Estética" => "scissors", + "Ocio" => "music", + "Otros" => "asterisk", + "Préstamo de herramientas, material, libros, ..." => "wrench", + "Salud" => "apple", + "Tareas administrativas" => "list-alt", + "Tareas domésticas" => "shopping-cart" } Category.all.each do |category| - category.update(icon_name: icon_mapping[category.name] || 'folder-open') + category.update(icon_name: icon_mapping[category.name] || "folder-open") end end end diff --git a/db/migrate/20230401114456_make_terms_translatable.rb b/db/migrate/20230401114456_make_terms_translatable.rb index c03e9ed2c..c65e675f2 100644 --- a/db/migrate/20230401114456_make_terms_translatable.rb +++ b/db/migrate/20230401114456_make_terms_translatable.rb @@ -3,7 +3,8 @@ def up add_column :documents, :title_translations, :jsonb, default: {}, null: false add_column :documents, :content_translations, :jsonb, default: {}, null: false Document.find_each do |doc| - doc.update_columns(title_translations: { es: doc[:title] }, content_translations: { es: doc[:content] }) + doc.update_columns(title_translations: { es: doc[:title] }, + content_translations: { es: doc[:content] }) end remove_column :documents, :title remove_column :documents, :content @@ -13,7 +14,8 @@ def down add_column :documents, :title, :text add_column :documents, :content, :text Document.find_each do |doc| - doc.update_columns(title: doc.title_translations["es"], content: doc.content_translations["es"]) + doc.update_columns(title: doc.title_translations["es"], + content: doc.content_translations["es"]) end remove_column :documents, :title_translations remove_column :documents, :content_translations diff --git a/db/migrate/20231120164346_add_unique_index_on_member_uid_in_members.rb b/db/migrate/20231120164346_add_unique_index_on_member_uid_in_members.rb index 563154534..4da1e26eb 100644 --- a/db/migrate/20231120164346_add_unique_index_on_member_uid_in_members.rb +++ b/db/migrate/20231120164346_add_unique_index_on_member_uid_in_members.rb @@ -1,5 +1,5 @@ class AddUniqueIndexOnMemberUidInMembers < ActiveRecord::Migration[6.1] def change - add_index :members, [:organization_id, :member_uid], unique: true + add_index :members, %i[organization_id member_uid], unique: true end end diff --git a/db/seeds.rb b/db/seeds.rb index f0aece735..fcdcea84c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -144,7 +144,7 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Rails", "Ruby", "programación"] + post.tags = %w[Rails Ruby programación] post.organization_id = 1 end @@ -154,7 +154,7 @@ EOF post.category_id = 7 post.user_id = 1 - post.tags = ["Cocinar", "Cocina"] + post.tags = %w[Cocinar Cocina] post.organization_id = 1 end @@ -165,7 +165,7 @@ EOF post.category_id = 5 post.user_id = 2 - post.tags = ["Yoga", "Estiramientos", "Respiración", "Meditación"] + post.tags = %w[Yoga Estiramientos Respiración Meditación] post.organization_id = 1 end @@ -175,7 +175,7 @@ EOF post.category_id = 5 post.user_id = 2 - post.tags = ["Inglés", "English", "Conversación"] + post.tags = %w[Inglés English Conversación] post.organization_id = 1 end @@ -203,7 +203,7 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Markdown", "programación"] + post.tags = %w[Markdown programación] post.organization_id = 1 end @@ -213,7 +213,7 @@ EOF post.category_id = 3 post.user_id = 3 - post.tags = ["casa", "manitas"] + post.tags = %w[casa manitas] post.organization_id = 1 end @@ -223,7 +223,7 @@ EOF post.category_id = 7 post.user_id = 1 - post.tags = ["Cocinar", "Cocina", "Tupper"] + post.tags = %w[Cocinar Cocina Tupper] post.organization_id = 1 end @@ -233,14 +233,14 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Rails", "Ruby", "programación"] + post.tags = %w[Rails Ruby programación] post.organization_id = 1 end Inquiry.find_or_create_by(title: "Cocina Tailandesa") do |post| post.category_id = 7 post.user_id = 1 - post.tags = ["Tailandesa", "Cocina"] + post.tags = %w[Tailandesa Cocina] post.organization_id = 1 end @@ -250,7 +250,7 @@ EOF post.category_id = 7 post.user_id = 3 - post.tags = ["Cocinar", "Cocina", "Tupper"] + post.tags = %w[Cocinar Cocina Tupper] post.organization_id = 1 end @@ -260,7 +260,7 @@ EOF post.category_id = 7 post.user_id = 3 - post.tags = ["Cocinar", "Cocina", "Tupper"] + post.tags = %w[Cocinar Cocina Tupper] post.organization_id = 1 end @@ -270,7 +270,7 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Inglés", "gramática", "Conversación"] + post.tags = %w[Inglés gramática Conversación] post.organization_id = 1 end @@ -288,7 +288,7 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Italiano", "clases", "Conversación"] + post.tags = %w[Italiano clases Conversación] post.organization_id = 1 end @@ -308,7 +308,7 @@ EOF post.category_id = 5 post.user_id = 2 - post.tags = ["Yoga", "Estiramientos", "Respiración", "flexibilidad"] + post.tags = %w[Yoga Estiramientos Respiración flexibilidad] post.organization_id = 1 end @@ -318,7 +318,7 @@ EOF post.category_id = 5 post.user_id = 2 - post.tags = ["Meditación", "Estiramientos", "Respiración", "flexibilidad"] + post.tags = %w[Meditación Estiramientos Respiración flexibilidad] post.organization_id = 1 end @@ -328,7 +328,7 @@ EOF post.category_id = 5 post.user_id = 1 - post.tags = ["Aleman", "Deutsche", "Conversación"] + post.tags = %w[Aleman Deutsche Conversación] post.organization_id = 1 end diff --git a/spec/admin/organizations_controller_spec.rb b/spec/admin/organizations_controller_spec.rb index cf0f77f2e..18218fc90 100644 --- a/spec/admin/organizations_controller_spec.rb +++ b/spec/admin/organizations_controller_spec.rb @@ -12,10 +12,12 @@ it "sign out if current user is logged to organization deleted" do session[:current_organization_id] = organization.id - expect { + expect do delete :destroy, params: { id: organization.id } - }.to change { controller.current_user }.to(nil) - .and change { session[:current_organization_id] }.to(nil) + end.to change { controller.current_user }.to(nil). + and change { + session[:current_organization_id] + }.to(nil) end end end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index ade414f43..c8a96495f 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -1,5 +1,5 @@ RSpec.describe ApplicationController do - describe '#switch_lang' do + describe "#switch_lang" do let(:original_locale) { I18n.locale } before do @@ -10,7 +10,7 @@ I18n.locale = original_locale end - it 'switches locale to passed language via params' do + it "switches locale to passed language via params" do new_locale = (I18n.available_locales - [original_locale]).sample expect do diff --git a/spec/controllers/device_tokens_controller_spec.rb b/spec/controllers/device_tokens_controller_spec.rb index f97c6d62a..c8ae67d76 100644 --- a/spec/controllers/device_tokens_controller_spec.rb +++ b/spec/controllers/device_tokens_controller_spec.rb @@ -2,27 +2,27 @@ let (:organization) { Fabricate(:organization) } let (:member) { Fabricate(:member, organization: organization) } - describe 'POST #create' do - context 'without login' do - it 'responds with error' do + describe "POST #create" do + context "without login" do + it "responds with error" do expect do post :create end.to change(DeviceToken, :count).by(0) end end - context 'with valid params' do - it 'creates a new device_token' do + context "with valid params" do + it "creates a new device_token" do login(member.user) expect do - post :create, params: { token: 'xxx' } + post :create, params: { token: "xxx" } end.to change(DeviceToken, :count).by(1) end end - context 'with invalid params' do - it 'responds with error' do + context "with invalid params" do + it "responds with error" do login(member.user) post :create expect(response.status).to eq(422) diff --git a/spec/controllers/inquiries_controller_spec.rb b/spec/controllers/inquiries_controller_spec.rb index 0a78b1982..0a443d210 100644 --- a/spec/controllers/inquiries_controller_spec.rb +++ b/spec/controllers/inquiries_controller_spec.rb @@ -42,8 +42,8 @@ expect do post "create", params: { inquiry: { user: another_member.user, - category_id: test_category.id, - title: "New title" }} + category_id: test_category.id, + title: "New title" } } end.to change(Inquiry, :count).by(1) end end diff --git a/spec/controllers/multi_transfers_controller_spec.rb b/spec/controllers/multi_transfers_controller_spec.rb index 1d243a0e7..2817c759e 100644 --- a/spec/controllers/multi_transfers_controller_spec.rb +++ b/spec/controllers/multi_transfers_controller_spec.rb @@ -12,7 +12,7 @@ category: test_category) end - it 'creates one to many transfers' do + it "creates one to many transfers" do expect do login(admin.user) @@ -37,14 +37,14 @@ post :step, params: params.merge!( step: 5, - transfer: {amount: 3600, reason: 'because of reasons'} + transfer: { amount: 3600, reason: "because of reasons" } ) post :create, params: params end.to change { Transfer.count }.by(2) end - it 'creates many to one transfers' do + it "creates many to one transfers" do expect do login(admin.user) @@ -69,15 +69,15 @@ post :step, params: params.merge!( step: 5, - transfer: {amount: 3600, reason: 'because of reasons'} + transfer: { amount: 3600, reason: "because of reasons" } ) post :create, params: params end.to change { Transfer.count }.by(2) end - context 'when only one source and one target is selected' do - it 'creates one to one transfers' do + context "when only one source and one target is selected" do + it "creates one to one transfers" do expect do login(admin.user) @@ -102,7 +102,7 @@ post :step, params: params.merge!( step: 5, - transfer: {amount: 3600, reason: 'because of reasons'} + transfer: { amount: 3600, reason: "because of reasons" } ) post :create, params: params @@ -110,8 +110,8 @@ end end - context 'non admins' do - it 'cannot access step route' do + context "non admins" do + it "cannot access step route" do login(member.user) get :step, params: { step: 1 } @@ -119,13 +119,12 @@ expect(response).not_to have_http_status(:success) end - it 'cannot access create route' do + it "cannot access create route" do login(member.user) post :create - expect(response).to redirect_to('/') + expect(response).to redirect_to("/") end end end - diff --git a/spec/controllers/offers_controller_spec.rb b/spec/controllers/offers_controller_spec.rb index d8b1319e0..bff601f8c 100644 --- a/spec/controllers/offers_controller_spec.rb +++ b/spec/controllers/offers_controller_spec.rb @@ -74,13 +74,13 @@ end it "populates an array of offers" do - get :index, params: { q: 'compañeros' } + get :index, params: { q: "compañeros" } expect(assigns(:offers)).to eq([offer]) end it "allows to search by partial word" do - get :index, params: { q: 'compañ' } + get :index, params: { q: "compañ" } expect(assigns(:offers)).to eq([offer]) end @@ -122,48 +122,48 @@ end end - describe 'GET #show' do - context 'when the user is logged in' do + describe "GET #show" do + context "when the user is logged in" do before { login(another_member.user) } - context 'when the requested offer' do - context 'is not active' do + context "when the requested offer" do + context "is not active" do before do offer.active = false offer.save! end - it 'renders the 404 page' do + it "renders the 404 page" do get :show, params: { id: offer.id } expect(response.status).to eq(404) end end - context 'is active' do - context 'and the user that created the offer is not active anymore' do + context "is active" do + context "and the user that created the offer is not active anymore" do before do member.active = false member.save! end - it 'renders the 404 page' do + it "renders the 404 page" do get :show, params: { id: offer.id } expect(response.status).to eq(404) end end - context 'and the user that created the offer is active' do - it 'renders a successful response' do + context "and the user that created the offer is active" do + it "renders a successful response" do get :show, params: { id: offer.id } expect(response.status).to eq(200) end - it 'assigns the requested offer to @offer' do + it "assigns the requested offer to @offer" do get :show, params: { id: offer.id } expect(assigns(:offer)).to eq(offer) end - it 'assigns the account destination of the transfer' do + it "assigns the account destination of the transfer" do get :show, params: { id: offer.id } expect(assigns(:destination_account)).to eq(member.account) end @@ -171,8 +171,8 @@ end end - context 'when the user pertains to multiple organizations' do - context 'and user\'s current organization is different than offer\'s organization' do + context "when the user pertains to multiple organizations" do + context "and user's current organization is different than offer's organization" do let(:another_organization) { Fabricate(:organization) } before do @@ -180,7 +180,7 @@ allow(controller).to receive(:@current_organization).and_return(another_organization) end - it 'sets the offer\'s organization as user\'s current organization' do + it "sets the offer's organization as user's current organization" do get :show, params: { id: offer.id } expect(session[:current_organization_id]).to eq(offer.organization_id) expect(assigns(:current_organization)).to eq(offer.organization) @@ -189,18 +189,17 @@ end end - context 'when the user is not a member of the organization where the offer is published' do + context "when the user is not a member of the organization where the offer is published" do let(:another_user) { Fabricate(:user) } before { login(another_user) } end - context 'when the user is not logged in' do - it 'assigns the requested offer to @offer' do + context "when the user is not logged in" do + it "assigns the requested offer to @offer" do get :show, params: { id: offer.id } expect(assigns(:offer)).to eq(offer) end - end end @@ -212,8 +211,8 @@ expect do post "create", params: { offer: { user: another_member.user, - category_id: test_category, - title: "New title" } } + category_id: test_category, + title: "New title" } } end.to change(Offer, :count).by(1) end end @@ -234,10 +233,10 @@ login(member.user) put "update", params: { id: offer.id, offer: Fabricate.to_params(:offer, - user: member, - title: "New title", - description: "New description", - tag_list: ["foo"]) } + user: member, + title: "New title", + description: "New description", + tag_list: ["foo"]) } offer.reload expect(offer.title).to eq("New title") @@ -253,9 +252,9 @@ login(member.user) put :update, params: { id: offer.id, offer: Fabricate.to_params(:offer, - user: nil, - title: "New title", - description: "New description") } + user: nil, + title: "New title", + description: "New description") } expect(offer.title).not_to eq("New title") expect(offer.description).not_to eq("New description") diff --git a/spec/controllers/organizations_controller_spec.rb b/spec/controllers/organizations_controller_spec.rb index e09b320d7..5f4ecf471 100644 --- a/spec/controllers/organizations_controller_spec.rb +++ b/spec/controllers/organizations_controller_spec.rb @@ -4,16 +4,16 @@ let(:member) { Fabricate(:member, organization: organization) } let(:user) { member.user } - describe 'GET #index' do - context 'without parameters' do - it 'populates and array of organizations' do + describe "GET #index" do + context "without parameters" do + it "populates and array of organizations" do get :index expect(assigns(:organizations)).to include(organization, second_organization) end end - context 'a search is made' do + context "a search is made" do before do second_organization.name = "Banco del tiempo Doe" second_organization.city = "Sevilla" @@ -25,47 +25,47 @@ organization.save! end - it 'populates an array of organizations searching by city' do - get :index, params: { q: 'Sevilla' } + it "populates an array of organizations searching by city" do + get :index, params: { q: "Sevilla" } expect(assigns(:organizations)).to eq([second_organization]) end - it 'populates an array of organizations searching by name' do - get :index, params: { q: 'Doe' } + it "populates an array of organizations searching by name" do + get :index, params: { q: "Doe" } expect(assigns(:organizations)).to eq([second_organization]) end - it 'populates an array of organizations searching by address' do - get :index, params: { q: 'gloria' } + it "populates an array of organizations searching by address" do + get :index, params: { q: "gloria" } expect(assigns(:organizations)).to eq([second_organization]) end - it 'populates an array of organizations searching by neighborhood' do - get :index, params: { q: 'Paz' } + it "populates an array of organizations searching by neighborhood" do + get :index, params: { q: "Paz" } expect(assigns(:organizations)).to eq([organization, second_organization]) end - it 'allows to search by partial word' do - get :index, params: { q: 'Sev' } + it "allows to search by partial word" do + get :index, params: { q: "Sev" } expect(assigns(:organizations)).to eq([second_organization]) end - it 'populates an array of organizations ignoring accents' do - get :index, params: { q: 'Sevillá' } + it "populates an array of organizations ignoring accents" do + get :index, params: { q: "Sevillá" } expect(assigns(:organizations)).to eq([second_organization]) end end - context 'a user is logged' do + context "a user is logged" do before { login(member.user) } - it 'populates an array of user organizations' do + it "populates an array of user organizations" do get :index expect(assigns(:user_organizations)).to include(member.organization) @@ -74,17 +74,17 @@ end end - describe 'GET #show' do - it 'displays the organization page' do - get 'show', params: { id: organization.id } + describe "GET #show" do + it "displays the organization page" do + get "show", params: { id: organization.id } expect(assigns(:organization)).to eq(organization) expect(response.status).to eq(200) end end - describe 'GET #select_organization' do - it 'it shows the organizations in which the user is a member' do + describe "GET #select_organization" do + it "it shows the organizations in which the user is a member" do login(member.user) get :select_organization @@ -94,35 +94,35 @@ end end - describe 'POST #update' do - context 'with a logged user (admins organization)' do + describe "POST #update" do + context "with a logged user (admins organization)" do let(:member) { Fabricate(:member, organization: organization, manager: true) } - it 'allows to update organization' do + it "allows to update organization" do login(member.user) - post :update, params: { id: organization.id, organization: { name: 'New org name' } } + post :update, params: { id: organization.id, organization: { name: "New org name" } } organization.reload - expect(organization.name).to eq('New org name') + expect(organization.name).to eq("New org name") end end - context 'without a logged user' do - it 'does not allow to update organization' do - post :update, params: { id: organization.id, organization: { name: 'New org name' } } + context "without a logged user" do + it "does not allow to update organization" do + post :update, params: { id: organization.id, organization: { name: "New org name" } } expect(response).to redirect_to(root_path) - expect(flash[:error]).to eq('You are not authorized to perform this action.') + expect(flash[:error]).to eq("You are not authorized to perform this action.") end end end - describe '#set_current' do + describe "#set_current" do before { login(user) } - it 'stores the given organization as current organization in session' do - post 'set_current', params: { id: organization.id } + it "stores the given organization as current organization in session" do + post "set_current", params: { id: organization.id } expect(session[:current_organization_id]).to eq(organization.id) end diff --git a/spec/controllers/pages_controller_spec.rb b/spec/controllers/pages_controller_spec.rb index eba90f4ed..9abe843b6 100644 --- a/spec/controllers/pages_controller_spec.rb +++ b/spec/controllers/pages_controller_spec.rb @@ -1,12 +1,12 @@ RSpec.describe PagesController do - describe '#show' do - it 'renders the page successfully' do + describe "#show" do + it "renders the page successfully" do get :show, params: { page: :about } expect(response).to render_template(:about) end - it 'returns a 404 if the page does not exist' do + it "returns a 404 if the page does not exist" do get :show, params: { page: :foo } expect(response.status).to eq(404) diff --git a/spec/controllers/petitions_controller_spec.rb b/spec/controllers/petitions_controller_spec.rb index 0d7bb916c..b16c80b2f 100644 --- a/spec/controllers/petitions_controller_spec.rb +++ b/spec/controllers/petitions_controller_spec.rb @@ -3,11 +3,11 @@ let(:user) { Fabricate(:user) } let!(:admin) { Fabricate(:member, organization: organization, manager: true) } - describe 'POST #create' do + describe "POST #create" do before { login(user) } - it 'creates the petition' do - request.env['HTTP_REFERER'] = organizations_path + it "creates the petition" do + request.env["HTTP_REFERER"] = organizations_path expect do post :create, params: { user_id: user.id, organization_id: organization.id } @@ -16,34 +16,34 @@ end end - describe 'PUT #update' do + describe "PUT #update" do before { login(admin.user) } - let(:petition) { Petition.create(user: user, organization: organization, status: 'pending') } + let(:petition) { Petition.create(user: user, organization: organization, status: "pending") } - it 'decline the petition' do - put :update, params: { status: 'declined', id: petition.id } + it "decline the petition" do + put :update, params: { status: "declined", id: petition.id } petition.reload - expect(petition.status).to eq('declined') + expect(petition.status).to eq("declined") end - it 'accept the petition and add the user to the org' do - put :update, params: { status: 'accepted', id: petition.id } + it "accept the petition and add the user to the org" do + put :update, params: { status: "accepted", id: petition.id } petition.reload expect(user.members.last.organization.id).to eq(organization.id) - expect(petition.status).to eq('accepted') + expect(petition.status).to eq("accepted") end end - describe 'GET #manage' do + describe "GET #manage" do before do allow(controller).to receive(:current_organization) { organization } login(admin.user) end - let!(:petition) { Petition.create(user: user, organization: organization, status: 'pending') } + let!(:petition) { Petition.create(user: user, organization: organization, status: "pending") } - it 'populates a list of users with pending petitions' do + it "populates a list of users with pending petitions" do get :manage expect(assigns(:users)).to include(user) diff --git a/spec/controllers/reports_controller_spec.rb b/spec/controllers/reports_controller_spec.rb index 369402369..231f92749 100644 --- a/spec/controllers/reports_controller_spec.rb +++ b/spec/controllers/reports_controller_spec.rb @@ -23,20 +23,20 @@ end end - context 'with a logged user' do + context "with a logged user" do before { login(member1.user) } - describe 'GET #user_list' do - it 'downloads a csv' do - get :user_list, params: { format: 'csv' } + describe "GET #user_list" do + it "downloads a csv" do + get :user_list, params: { format: "csv" } report = Report::Csv::Member.new(test_organization, test_organization.members.active) expect(response.body).to match(report.run) expect(response.media_type).to eq("text/csv") end - it 'downloads a pdf' do - get :user_list, params: { format: 'pdf' } + it "downloads a pdf" do + get :user_list, params: { format: "pdf" } report = Report::Pdf::Member.new(test_organization, test_organization.members.active) expect(response.body).to eq(report.run) @@ -44,27 +44,27 @@ end end - describe 'GET #post_list' do + describe "GET #post_list" do let(:report_posts) { test_organization.posts.of_active_members.group_by(&:category) } - it 'do NOT show the inactive members' do - get :post_list, params: { type: 'offer' } + it "do NOT show the inactive members" do + get :post_list, params: { type: "offer" } posts = assigns(:posts)[0][1] expect(posts.size).to eq(active_organization_offers.size) expect(posts.map(&:id)).to match_array(active_organization_offers.map(&:id)) end - it 'downloads a csv' do - get :post_list, params: { type: 'offer', format: 'csv' } + it "downloads a csv" do + get :post_list, params: { type: "offer", format: "csv" } report = Report::Csv::Post.new(test_organization, report_posts, Offer) expect(response.body).to eq(report.run) expect(response.media_type).to eq("text/csv") end - it 'downloads a pdf' do - get :post_list, params: { type: 'offer', format: 'pdf' } + it "downloads a pdf" do + get :post_list, params: { type: "offer", format: "pdf" } report = Report::Pdf::Post.new(test_organization, report_posts, Offer) expect(response.body).to eq(report.run) @@ -72,17 +72,17 @@ end end - describe 'GET #transfer_list' do - it 'downloads a csv' do - get :transfer_list, params: { format: 'csv' } + describe "GET #transfer_list" do + it "downloads a csv" do + get :transfer_list, params: { format: "csv" } report = Report::Csv::Transfer.new(test_organization, test_organization.all_transfers) expect(response.body).to eq(report.run) expect(response.media_type).to eq("text/csv") end - it 'downloads a pdf' do - get :transfer_list, params: { format: 'pdf' } + it "downloads a pdf" do + get :transfer_list, params: { format: "pdf" } report = Report::Pdf::Transfer.new(test_organization, test_organization.all_transfers) expect(response.body).to eq(report.run) @@ -90,18 +90,18 @@ end end - describe 'GET #download_all' do - it 'downloads a zip' do + describe "GET #download_all" do + it "downloads a zip" do get :download_all - expect(response.media_type).to eq('application/zip') - expect(response.body).to include('Inquiries') - expect(response.body).to include('Offers') - expect(response.body).to include('Members') - expect(response.body).to include('Transfers') + expect(response.media_type).to eq("application/zip") + expect(response.body).to include("Inquiries") + expect(response.body).to include("Offers") + expect(response.body).to include("Members") + expect(response.body).to include("Transfers") end - it 'redirects to download_all_report_path (retry) if zip is not ready' do + it "redirects to download_all_report_path (retry) if zip is not ready" do allow(subject).to receive(:add_csv_to_zip).and_raise(Errno::ENOENT) get :download_all diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index aa52e9a52..d65837b54 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -1,18 +1,18 @@ RSpec.describe SessionsController do - let(:user) { Fabricate(:user, password: 'papapa22', password_confirmation: 'papapa22') } + let(:user) { Fabricate(:user, password: "papapa22", password_confirmation: "papapa22") } before do request.env["devise.mapping"] = Devise.mappings[:user] end - describe '#create' do - it 'does not show a notice flash message' do + describe "#create" do + it "does not show a notice flash message" do post :create, params: { user: { email: user.email, password: user.password } } expect(flash[:notice]).to be_nil end - it 'redirects to the previous page' do + it "redirects to the previous page" do session["user_return_to"] = offers_path post :create, params: { user: { email: user.email, password: user.password } } @@ -21,12 +21,12 @@ end end - describe '#destroy' do + describe "#destroy" do before do post :create, params: { user: { email: user.email, password: user.password } } end - it 'does not show a notice flash message' do + it "does not show a notice flash message" do delete :destroy expect(flash[:notice]).to be_nil diff --git a/spec/controllers/statistics_controller_spec.rb b/spec/controllers/statistics_controller_spec.rb index 9907d7bc0..690c3e816 100644 --- a/spec/controllers/statistics_controller_spec.rb +++ b/spec/controllers/statistics_controller_spec.rb @@ -1,12 +1,12 @@ RSpec.describe StatisticsController do let(:organization) { Fabricate(:organization) } - let(:user) { Fabricate(:user, date_of_birth: '1980-1-1', gender: 'others') } + let(:user) { Fabricate(:user, date_of_birth: "1980-1-1", gender: "others") } let(:member) { Fabricate(:member, organization: organization, user: user) } before(:each) { login(member.user) } - describe 'GET #all_transfers' do - it 'populates all transfers from current organization' do + describe "GET #all_transfers" do + it "populates all transfers from current organization" do transfer = Fabricate(:transfer, source: organization.account, destination: member.account) transfer2 = Fabricate(:transfer) @@ -16,8 +16,8 @@ end end - describe 'GET #global_activity' do - it 'populates some variables' do + describe "GET #global_activity" do + it "populates some variables" do 2.times { Fabricate(:transfer, source: organization.account, destination: member.account) } get :global_activity @@ -27,22 +27,24 @@ end end - describe 'GET #type_swaps' do - it 'populates offers variable' do + describe "GET #type_swaps" do + it "populates offers variable" do category = Fabricate(:category) - Fabricate(:offer, organization: organization, user: member.user, category: category, tag_list: ["foo"]) - Fabricate(:transfer, source: organization.account, destination: member.account, post: Offer.all.sample) + Fabricate(:offer, organization: organization, user: member.user, category: category, + tag_list: ["foo"]) + Fabricate(:transfer, source: organization.account, destination: member.account, + post: Offer.all.sample) get :type_swaps expect(assigns(:offers)).to eq([ - [category.name, "foo", 10, 1, 1.0] - ]) + [category.name, "foo", 10, 1, 1.0] + ]) end end - describe 'GET #demographics' do - it 'populates age_counts and gender_counts variables' do + describe "GET #demographics" do + it "populates age_counts and gender_counts variables" do get :demographics expect(assigns(:age_counts)).to eq({ "35-44" => 1 }) diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index 412445d88..8048c072a 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -5,7 +5,9 @@ let (:organization) { Fabricate(:organization) } let (:member) { Fabricate(:member, organization: organization, tags: member_tags) } let! (:offer) { Fabricate(:offer, user: member.user, organization: organization, tags: tags) } - let! (:inquiry) { Fabricate(:inquiry, user: member.user, organization: organization, tags: more_tags) } + let! (:inquiry) do + Fabricate(:inquiry, user: member.user, organization: organization, tags: more_tags) + end before(:each) do login(member.user) @@ -53,27 +55,27 @@ get :alpha_grouped_index expect(assigns(:tags)).to eq({ - "H" => [["html", 2], ["html5", 1]], - "C" => [["css", 1]] - }) + "H" => [["html", 2], ["html5", 1]], + "C" => [["css", 1]] + }) end it "load offer tags" do get :alpha_grouped_index, params: { post_type: "offer" } expect(assigns(:tags)).to eq({ - "B" => [["bar", 1], ["baz", 1]], - "F" => [["foo", 1]] - }) + "B" => [["bar", 1], ["baz", 1]], + "F" => [["foo", 1]] + }) end it "load inquiries tags" do get :alpha_grouped_index, params: { post_type: "inquiry" } expect(assigns(:tags)).to eq({ - "J" => [["js", 1]], - "R" => [["rails", 1], ["ruby", 1]] - }) + "J" => [["js", 1]], + "R" => [["rails", 1], ["ruby", 1]] + }) end it "renders a partial with format js" do diff --git a/spec/controllers/transfers_controller_spec.rb b/spec/controllers/transfers_controller_spec.rb index a034f778c..af00858bd 100644 --- a/spec/controllers/transfers_controller_spec.rb +++ b/spec/controllers/transfers_controller_spec.rb @@ -4,12 +4,12 @@ let (:member_giver) { Fabricate(:member, organization: test_organization) } let (:member_taker) { Fabricate(:member, organization: test_organization) } - describe '#new' do + describe "#new" do let(:user) { member_giver.user } before { login(user) } - context 'when the destination is a user account' do + context "when the destination is a user account" do let(:user_account) do user.members.find_by(organization: user.organizations.first).account end @@ -20,48 +20,48 @@ } end - it 'finds the accountable' do + it "finds the accountable" do get :new, params: params - expect(response.body) - .to include("#{member_giver.display_name_with_uid}") + expect(response.body). + to include("#{member_giver.display_name_with_uid}") end - it 'finds the destination account' do + it "finds the destination account" do get :new, params: params expect(response.body).to include("") end - it 'builds a transfer with the id of the destination' do + it "builds a transfer with the id of the destination" do get :new, params: params - expect(response.body) - .to include("") + expect(response.body). + to include("") end - context 'when the offer is specified' do + context "when the offer is specified" do let(:offer) { Fabricate(:offer, organization: user.organizations.first) } - it 'finds the transfer offer' do + it "finds the transfer offer" do get :new, params: params.merge(offer: offer.id) expect(response.body).to include("

#{offer}

") end - it 'builds a transfer with the offer as post' do + it "builds a transfer with the offer as post" do get :new, params: params.merge(offer: offer.id) expect(response.body).to include("") end end - context 'when the offer is not specified' do - it 'does not find any offer' do + context "when the offer is not specified" do + it "does not find any offer" do get :new, params: params expect(response.body).to include('