From f1570f60d410f14c22c77771c70bf252b678feb3 Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 14:13:25 -0400 Subject: [PATCH 1/8] changed to dockerfile a bit; updated bundler; got rid of env vars in dockerfile --- Dockerfile | 21 ++--- Gemfile | 2 - Gemfile.lock | 214 +++++++++++++++++++++++++-------------------------- 3 files changed, 113 insertions(+), 124 deletions(-) diff --git a/Dockerfile b/Dockerfile index c9c24e8..51cad3e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ -FROM ruby:2.7.2 +ARG RUBY_VERSION=2.7 +FROM ruby:${RUBY_VERSION} + +ARG BUNDLER_VERSION=2.3 ARG UNAME=app ARG UID=1000 ARG GID=1000 @@ -8,16 +11,16 @@ LABEL maintainer="mrio@umich.edu" RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ apt-transport-https -RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ nodejs \ - vim + vim-tiny #so wait-for works RUN apt install -y netcat -RUN gem install bundler:2.1.4 +RUN gem install bundler:${BUNDLER_VERSION} RUN groupadd -g ${GID} -o ${UNAME} @@ -30,16 +33,8 @@ USER $UNAME ENV BUNDLE_PATH /gems -ENV ALMA_API_KEY YOUR_ALMA_API_KEY -ENV ALMA_API_HOST http://falma:4567 -ENV CIRC_REPORT_PATH /circ/report/path -ENV PATRON_REPORT_PATH /patron/report/path -ENV MYSQL_ROOT_PASSWORD mysqlrootpassword -ENV DATABASE_HOST database -ENV PUSHMON_URL YOUR_PUSHMON_URL - WORKDIR /app -RUN bundle install +RUN bundle _${BUNDLER_VERSION}_ install COPY --chown=${UID}:${GID} . /app diff --git a/Gemfile b/Gemfile index b17e377..abf99c7 100644 --- a/Gemfile +++ b/Gemfile @@ -1,8 +1,6 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.7.2' - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 6.1.1' # Use mysql as the database for Active Record diff --git a/Gemfile.lock b/Gemfile.lock index e3bfdc5..eef2854 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,60 +11,60 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (6.1.4) - actionpack (= 6.1.4) - activesupport (= 6.1.4) + actioncable (6.1.5) + actionpack (= 6.1.5) + activesupport (= 6.1.5) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.4) - actionpack (= 6.1.4) - activejob (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + actionmailbox (6.1.5) + actionpack (= 6.1.5) + activejob (= 6.1.5) + activerecord (= 6.1.5) + activestorage (= 6.1.5) + activesupport (= 6.1.5) mail (>= 2.7.1) - actionmailer (6.1.4) - actionpack (= 6.1.4) - actionview (= 6.1.4) - activejob (= 6.1.4) - activesupport (= 6.1.4) + actionmailer (6.1.5) + actionpack (= 6.1.5) + actionview (= 6.1.5) + activejob (= 6.1.5) + activesupport (= 6.1.5) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.4) - actionview (= 6.1.4) - activesupport (= 6.1.4) + actionpack (6.1.5) + actionview (= 6.1.5) + activesupport (= 6.1.5) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.4) - actionpack (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + actiontext (6.1.5) + actionpack (= 6.1.5) + activerecord (= 6.1.5) + activestorage (= 6.1.5) + activesupport (= 6.1.5) nokogiri (>= 1.8.5) - actionview (6.1.4) - activesupport (= 6.1.4) + actionview (6.1.5) + activesupport (= 6.1.5) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.4) - activesupport (= 6.1.4) + activejob (6.1.5) + activesupport (= 6.1.5) globalid (>= 0.3.6) - activemodel (6.1.4) - activesupport (= 6.1.4) - activerecord (6.1.4) - activemodel (= 6.1.4) - activesupport (= 6.1.4) - activestorage (6.1.4) - actionpack (= 6.1.4) - activejob (= 6.1.4) - activerecord (= 6.1.4) - activesupport (= 6.1.4) - marcel (~> 1.0.0) + activemodel (6.1.5) + activesupport (= 6.1.5) + activerecord (6.1.5) + activemodel (= 6.1.5) + activesupport (= 6.1.5) + activestorage (6.1.5) + actionpack (= 6.1.5) + activejob (= 6.1.5) + activerecord (= 6.1.5) + activesupport (= 6.1.5) + marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.4) + activesupport (6.1.5) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -72,12 +72,12 @@ GEM zeitwerk (~> 2.3) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - amazing_print (1.3.0) - bootsnap (1.7.5) - msgpack (~> 1.0) + amazing_print (1.4.0) + bootsnap (1.11.1) + msgpack (~> 1.2) builder (3.2.4) byebug (11.1.3) - concurrent-ruby (1.1.9) + concurrent-ruby (1.1.10) crack (0.4.5) rexml crass (1.0.6) @@ -87,101 +87,100 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - diff-lcs (1.4.4) + diff-lcs (1.5.0) docile (1.4.0) erubi (1.10.0) - factory_bot (6.2.0) + factory_bot (6.2.1) activesupport (>= 5.0.0) factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) - faker (2.18.0) - i18n (>= 1.6, < 2) - ffi (1.15.3) - globalid (0.4.2) - activesupport (>= 4.2.0) + faker (2.20.0) + i18n (>= 1.8.11, < 2) + ffi (1.15.5) + globalid (1.0.0) + activesupport (>= 5.0) hashdiff (1.0.1) httparty (0.20.0) mime-types (~> 3.0) multi_xml (>= 0.5.2) - i18n (1.8.10) + i18n (1.10.0) concurrent-ruby (~> 1.0) - jbuilder (2.11.2) + jbuilder (2.11.5) + actionview (>= 5.0.0) activesupport (>= 5.0.0) - listen (3.5.1) + listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - loofah (2.10.0) + loofah (2.16.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.1) + marcel (1.0.2) method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.1115) - mini_mime (1.1.0) - mini_portile2 (2.5.3) - minitest (5.14.4) - msgpack (1.4.2) + mime-types-data (3.2022.0105) + mini_mime (1.1.2) + minitest (5.15.0) + msgpack (1.4.5) multi_xml (0.6.0) mysql2 (0.5.3) - nio4r (2.5.7) - nokogiri (1.11.7) - mini_portile2 (~> 2.5.0) + nio4r (2.5.8) + nokogiri (1.13.3-x86_64-linux) racc (~> 1.4) - prometheus-client (2.1.0) + prometheus-client (4.0.0) public_suffix (4.0.6) - puma (5.3.2) + puma (5.6.4) nio4r (~> 2.0) - racc (1.5.2) + racc (1.6.0) rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.1.4) - actioncable (= 6.1.4) - actionmailbox (= 6.1.4) - actionmailer (= 6.1.4) - actionpack (= 6.1.4) - actiontext (= 6.1.4) - actionview (= 6.1.4) - activejob (= 6.1.4) - activemodel (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + rails (6.1.5) + actioncable (= 6.1.5) + actionmailbox (= 6.1.5) + actionmailer (= 6.1.5) + actionpack (= 6.1.5) + actiontext (= 6.1.5) + actionview (= 6.1.5) + activejob (= 6.1.5) + activemodel (= 6.1.5) + activerecord (= 6.1.5) + activestorage (= 6.1.5) + activesupport (= 6.1.5) bundler (>= 1.15.0) - railties (= 6.1.4) + railties (= 6.1.5) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) + rails-html-sanitizer (1.4.2) loofah (~> 2.3) - rails_semantic_logger (4.6.0) + rails_semantic_logger (4.10.0) rack - railties (>= 3.2) - semantic_logger (~> 4.8) - railties (6.1.4) - actionpack (= 6.1.4) - activesupport (= 6.1.4) + railties (>= 5.1) + semantic_logger (~> 4.9) + railties (6.1.5) + actionpack (= 6.1.5) + activesupport (= 6.1.5) method_source - rake (>= 0.13) + rake (>= 12.2) thor (~> 1.0) rake (13.0.6) - rb-fsevent (0.11.0) + rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) rexml (3.2.5) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-core (3.11.0) + rspec-support (~> 3.11.0) + rspec-expectations (3.11.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.11.0) + rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) + rspec-support (~> 3.11.0) rspec-rails (4.0.2) actionpack (>= 4.2) activesupport (>= 4.2) @@ -190,36 +189,36 @@ GEM rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) rspec-support (~> 3.10) - rspec-support (3.10.2) - semantic_logger (4.8.1) + rspec-support (3.11.0) + semantic_logger (4.10.0) concurrent-ruby (~> 1.0) simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) - simplecov_json_formatter (0.1.3) - sprockets (4.0.2) + simplecov_json_formatter (0.1.4) + sprockets (4.0.3) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) + sprockets-rails (3.4.2) + actionpack (>= 5.2) + activesupport (>= 5.2) sprockets (>= 3.0.0) - thor (1.1.0) + thor (1.2.1) tzinfo (2.0.4) concurrent-ruby (~> 1.0) - webmock (3.13.0) - addressable (>= 2.3.6) + webmock (3.14.0) + addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - zeitwerk (2.4.2) + zeitwerk (2.5.4) PLATFORMS - ruby + x86_64-linux DEPENDENCIES alma_rest_client! @@ -241,8 +240,5 @@ DEPENDENCIES tzinfo-data webmock -RUBY VERSION - ruby 2.7.2p137 - BUNDLED WITH - 2.1.4 + 2.3.7 From 36e9dc59c8c1e7276e7828296d423788bfba919c Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 14:24:43 -0400 Subject: [PATCH 2/8] added a Dockerfile.prod so in development don't have to bundle install twice when building; updated the workflows to match --- .github/workflows/build-from-main.yml | 1 + .github/workflows/manual-deploy-staging.yaml | 1 + .github/workflows/manual-deploy-testing.yaml | 1 + Dockerfile | 6 --- Dockerfile.prod | 39 ++++++++++++++++++++ 5 files changed, 42 insertions(+), 6 deletions(-) create mode 100644 Dockerfile.prod diff --git a/.github/workflows/build-from-main.yml b/.github/workflows/build-from-main.yml index 1118168..3a4aa18 100644 --- a/.github/workflows/build-from-main.yml +++ b/.github/workflows/build-from-main.yml @@ -26,6 +26,7 @@ jobs: uses: docker/build-push-action@v2 with: context: . + file: Dockerfile.prod push: true tags: | ghcr.io/mlibrary/${{ secrets.IMAGE_NAME }}:latest diff --git a/.github/workflows/manual-deploy-staging.yaml b/.github/workflows/manual-deploy-staging.yaml index c201833..c9435c0 100644 --- a/.github/workflows/manual-deploy-staging.yaml +++ b/.github/workflows/manual-deploy-staging.yaml @@ -57,6 +57,7 @@ jobs: uses: docker/build-push-action@v2 with: context: . + file: Dockerfile.prod push: true tags: ghcr.io/mlibrary/${{ secrets.IMAGE_NAME }}:${{steps.tag_check.outputs.tag}} - name: Deploy to ${{ env.environment }} diff --git a/.github/workflows/manual-deploy-testing.yaml b/.github/workflows/manual-deploy-testing.yaml index a230380..64c9895 100644 --- a/.github/workflows/manual-deploy-testing.yaml +++ b/.github/workflows/manual-deploy-testing.yaml @@ -56,6 +56,7 @@ jobs: uses: docker/build-push-action@v2 with: context: . + file: Dockerfile.prod push: true tags: ghcr.io/mlibrary/${{ secrets.IMAGE_NAME }}:${{steps.tag_check.outputs.tag}} - name: Deploy to ${{ env.environment }} diff --git a/Dockerfile b/Dockerfile index 51cad3e..c0bb7fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,9 +17,6 @@ RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ nodejs \ vim-tiny -#so wait-for works -RUN apt install -y netcat - RUN gem install bundler:${BUNDLER_VERSION} @@ -27,14 +24,11 @@ RUN groupadd -g ${GID} -o ${UNAME} RUN useradd -m -d /app -u ${UID} -g ${GID} -o -s /bin/bash ${UNAME} RUN mkdir -p /gems && chown ${UID}:${GID} /gems - -COPY --chown=${UID}:${GID} Gemfile* /app/ USER $UNAME ENV BUNDLE_PATH /gems WORKDIR /app -RUN bundle _${BUNDLER_VERSION}_ install COPY --chown=${UID}:${GID} . /app diff --git a/Dockerfile.prod b/Dockerfile.prod new file mode 100644 index 0000000..8925cdd --- /dev/null +++ b/Dockerfile.prod @@ -0,0 +1,39 @@ +ARG RUBY_VERSION=2.7 +FROM ruby:${RUBY_VERSION} + +ARG BUNDLER_VERSION=2.3 +ARG UNAME=app +ARG UID=1000 +ARG GID=1000 + +LABEL maintainer="mrio@umich.edu" + +RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ + apt-transport-https + +RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - + +RUN apt-get update -yqq && apt-get install -yqq --no-install-recommends \ + nodejs \ + vim-tiny + +RUN gem install bundler:${BUNDLER_VERSION} + +RUN groupadd -g ${GID} -o ${UNAME} +RUN useradd -m -d /app -u ${UID} -g ${GID} -o -s /bin/bash ${UNAME} +RUN mkdir -p /gems && chown ${UID}:${GID} /gems + + +COPY --chown=${UID}:${GID} Gemfile* /app/ +USER $UNAME + +ENV BUNDLE_PATH /gems +ENV BUNDLE_WITHOUT development:test + +WORKDIR /app +RUN bundle _${BUNDLER_VERSION}_ install + +COPY --chown=${UID}:${GID} . /app + +CMD ["bin/rails", "s", "-b", "0.0.0.0"] + From 248f0e1a00ccfc824c69125c945c0249227f06cf Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 14:45:40 -0400 Subject: [PATCH 3/8] updated test to use action service instead of docker compose --- .env-dev-values | 7 ++++ .github/workflows/tests.yml | 77 ++++++++++++++++--------------------- docker-compose.yml | 42 +------------------- 3 files changed, 41 insertions(+), 85 deletions(-) create mode 100644 .env-dev-values diff --git a/.env-dev-values b/.env-dev-values new file mode 100644 index 0000000..7a944df --- /dev/null +++ b/.env-dev-values @@ -0,0 +1,7 @@ +MARIADB_ROOT_PASSWORD=pass +CIRCULATION_HISTORY_DATABASE_PASSWORD=circulation_history_db_password +DATABASE_HOST=database +CIRC_REPORT_PATH=/circ/report/path +PATRON_REPORT_PATH=/patron/report/path +ALMA_API_HOST=http://falma:4567 +RAILS_LOG_TO_STDOUT=1 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f11fccb..a677227 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,52 +7,41 @@ jobs: test: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - - name: Cache ruby gems - uses: actions/cache@v2 + services: + mariadb: + image: mariadb:10 env: - cache-name: ruby-gems - with: - path: .gems - key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }} - restore-keys: | - ${{ runner.os }}-gems- - - - uses: satackey/action-docker-layer-caching@v0.0.11 - # Ignore the failure of a step and avoid terminating the job. - continue-on-error: true + MARIADB_USER: circulation_history + MARIADB_PASSWORD: circulation_history_db_password + MARIADB_DATABASE: circulation_history_test + MARIADB_ROOT_PASSWORD: pass + ports: ["3306:3306"] + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 - - name: make coverage directory - run: mkdir -m777 coverage - - name: make tmp directory writeable - run: chmod -R 777 tmp - - name: make fixtures writeable - run: chmod -R 777 spec/fixtures - - name: make app/log/development.log writeable - run: | - mkdir -m777 log - touch log/development.log - chmod 777 log/development.log - - name: list files with permissions - run: | - ls -al - ls -al log - - name: Set up .env - run: cp .env-example .env - - name: Set up tests + steps: + - uses: actions/checkout@v2 + - name: Create .env file run: | - docker-compose build - docker-compose run web bundle install - - name: boot up database - run: docker-compose up -d database - - name: docker state - run: docker-compose ps - - name: wait for db - run: docker-compose run web bin/wait-for database:3306 - - name: create databases - run: docker-compose run web bundle exec rails db:create + sed 's/DATABASE_HOST=database/DATABASE_HOST=127.0.0.1/' .env-dev-values > .env-actions + cat .env-example .env-actions > .env + - name: Load .env file + uses: xom9ikk/dotenv@v1.0.2 + - name: Set up Ruby 2.7.5 + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7.5 + bundler-cache: true + - name: Setup up node 16.14.2 + uses: actions/setup-node@v2 + with: + node-version: '16.14.2' + - name: Verify MariaDB connection + run: | + while ! mysqladmin ping -h"127.0.0.1" -P"3306" --silent; do + sleep 1 + done + - name: Set up DB + run: bundle exec rails db:schema:load RAILS_ENV=test - name: Run tests - run: docker-compose run web bundle exec rspec + run: bundle exec rspec diff --git a/docker-compose.yml b/docker-compose.yml index ed0c141..6f84825 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,17 +8,9 @@ services: volumes: - .:/app - gem_cache:/gems - environment: - - MARIADB_ROOT_PASSWORD=pass - - CIRCULATION_HISTORY_DATABASE_PASSWORD=circulation_history_db_password - - DATABASE_HOST=database - - CIRC_REPORT_PATH=/circ/report/path - - PATRON_REPORT_PATH=/patron/report/path - - ALMA_API_HOST=http://falma:4567 - - RAILS_LOG_TO_STDOUT=1 - #- RAILS_ENV=production env_file: - .env + - .env-dev-values database: build: lib/dev_db/. @@ -29,39 +21,7 @@ services: - "4444:4567" volumes: - ./fake_alma/.:/app - - - #promtail: - #image: grafana/promtail - #ports: - #- "9080:9080" - #volumes: - #- ./log/development.log:/development.log - #- ./config/promtail.yml:/promtail.yml - #command: -config.file=/promtail.yml - - #grafana: - #image: grafana/grafana:7.1.1 - #ports: - #- "3000:3000" - #volumes: - #- ./.env/grafana.ini:/etc/grafana/grafana.ini - #- grafana_storage:/var/lib/grafana - #loki: - #image: grafana/loki:master - #ports: - #- "3100:3100" - #command: -config.file=/etc/loki/local-config.yaml - - #prometheus: - #image: prom/prometheus - #ports: - #- "9090:9090" - #volumes: - #- ./config/prometheus.yml:/etc/prometheus/prometheus.yml - volumes: gem_cache: db_data: -# grafana_storage: From f74521982e6432857b21eee07c9229f331a016a2 Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 15:40:02 -0400 Subject: [PATCH 4/8] basic upgrade to Rails 7 --- Gemfile | 6 +- Gemfile.lock | 164 ++++++++++++++++++++++++++++----------------------- 2 files changed, 93 insertions(+), 77 deletions(-) diff --git a/Gemfile b/Gemfile index abf99c7..b9f696d 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 6.1.1' +gem 'rails', '~> 7.0.0' # Use mysql as the database for Active Record gem 'mysql2', '~> 0.5' # Use Puma as the app server @@ -29,12 +29,12 @@ gem 'rails_semantic_logger' gem 'prometheus-client' gem 'alma_rest_client', git: 'https://github.com/mlibrary/alma_rest_client', - tag: '1.2.1' + tag: '1.3.1' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] - gem 'rspec-rails', '~> 4.0.2' + gem 'rspec-rails' gem 'simplecov' end diff --git a/Gemfile.lock b/Gemfile.lock index eef2854..1db7ca0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,75 +1,81 @@ GIT remote: https://github.com/mlibrary/alma_rest_client - revision: 60c86b4ad5b3739787093169fc45449e4913070f - tag: 1.2.1 + revision: 2014809367ece3f21935bd24b45a12285f61e253 + tag: 1.3.1 specs: - alma_rest_client (1.2.0) - activesupport (~> 6.0, >= 4.2) + alma_rest_client (1.3.1) + activesupport (~> 7.0, >= 4.2) httparty rexml GEM remote: https://rubygems.org/ specs: - actioncable (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + actioncable (7.0.2.3) + actionpack (= 7.0.2.3) + activesupport (= 7.0.2.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actionmailbox (7.0.2.3) + actionpack (= 7.0.2.3) + activejob (= 7.0.2.3) + activerecord (= 7.0.2.3) + activestorage (= 7.0.2.3) + activesupport (= 7.0.2.3) mail (>= 2.7.1) - actionmailer (6.1.5) - actionpack (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activesupport (= 6.1.5) + net-imap + net-pop + net-smtp + actionmailer (7.0.2.3) + actionpack (= 7.0.2.3) + actionview (= 7.0.2.3) + activejob (= 7.0.2.3) + activesupport (= 7.0.2.3) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.5) - actionview (= 6.1.5) - activesupport (= 6.1.5) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.2.3) + actionview (= 7.0.2.3) + activesupport (= 7.0.2.3) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.5) - actionpack (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + actiontext (7.0.2.3) + actionpack (= 7.0.2.3) + activerecord (= 7.0.2.3) + activestorage (= 7.0.2.3) + activesupport (= 7.0.2.3) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.5) - activesupport (= 6.1.5) + actionview (7.0.2.3) + activesupport (= 7.0.2.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.5) - activesupport (= 6.1.5) + activejob (7.0.2.3) + activesupport (= 7.0.2.3) globalid (>= 0.3.6) - activemodel (6.1.5) - activesupport (= 6.1.5) - activerecord (6.1.5) - activemodel (= 6.1.5) - activesupport (= 6.1.5) - activestorage (6.1.5) - actionpack (= 6.1.5) - activejob (= 6.1.5) - activerecord (= 6.1.5) - activesupport (= 6.1.5) + activemodel (7.0.2.3) + activesupport (= 7.0.2.3) + activerecord (7.0.2.3) + activemodel (= 7.0.2.3) + activesupport (= 7.0.2.3) + activestorage (7.0.2.3) + actionpack (= 7.0.2.3) + activejob (= 7.0.2.3) + activerecord (= 7.0.2.3) + activesupport (= 7.0.2.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.5) + activesupport (7.0.2.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) amazing_print (1.4.0) @@ -88,6 +94,7 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) diff-lcs (1.5.0) + digest (3.1.0) docile (1.4.0) erubi (1.10.0) factory_bot (6.2.1) @@ -127,6 +134,20 @@ GEM msgpack (1.4.5) multi_xml (0.6.0) mysql2 (0.5.3) + net-imap (0.2.3) + digest + net-protocol + strscan + net-pop (0.1.1) + digest + net-protocol + timeout + net-protocol (0.1.3) + timeout + net-smtp (0.3.1) + digest + net-protocol + timeout nio4r (2.5.8) nokogiri (1.13.3-x86_64-linux) racc (~> 1.4) @@ -138,21 +159,20 @@ GEM rack (2.2.3) rack-test (1.1.0) rack (>= 1.0, < 3) - rails (6.1.5) - actioncable (= 6.1.5) - actionmailbox (= 6.1.5) - actionmailer (= 6.1.5) - actionpack (= 6.1.5) - actiontext (= 6.1.5) - actionview (= 6.1.5) - activejob (= 6.1.5) - activemodel (= 6.1.5) - activerecord (= 6.1.5) - activestorage (= 6.1.5) - activesupport (= 6.1.5) + rails (7.0.2.3) + actioncable (= 7.0.2.3) + actionmailbox (= 7.0.2.3) + actionmailer (= 7.0.2.3) + actionpack (= 7.0.2.3) + actiontext (= 7.0.2.3) + actionview (= 7.0.2.3) + activejob (= 7.0.2.3) + activemodel (= 7.0.2.3) + activerecord (= 7.0.2.3) + activestorage (= 7.0.2.3) + activesupport (= 7.0.2.3) bundler (>= 1.15.0) - railties (= 6.1.5) - sprockets-rails (>= 2.0.0) + railties (= 7.0.2.3) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) @@ -162,12 +182,13 @@ GEM rack railties (>= 5.1) semantic_logger (~> 4.9) - railties (6.1.5) - actionpack (= 6.1.5) - activesupport (= 6.1.5) + railties (7.0.2.3) + actionpack (= 7.0.2.3) + activesupport (= 7.0.2.3) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rake (13.0.6) rb-fsevent (0.11.1) rb-inotify (0.10.1) @@ -181,10 +202,10 @@ GEM rspec-mocks (3.11.1) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.11.0) - rspec-rails (4.0.2) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) + rspec-rails (5.1.1) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (>= 5.2) rspec-core (~> 3.10) rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) @@ -198,14 +219,9 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - sprockets (4.0.3) - concurrent-ruby (~> 1.0) - rack (> 1, < 3) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - sprockets (>= 3.0.0) + strscan (3.0.1) thor (1.2.1) + timeout (0.2.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) webmock (3.14.0) @@ -233,12 +249,12 @@ DEPENDENCIES mysql2 (~> 0.5) prometheus-client puma (~> 5.0) - rails (~> 6.1.1) + rails (~> 7.0.0) rails_semantic_logger - rspec-rails (~> 4.0.2) + rspec-rails simplecov tzinfo-data webmock BUNDLED WITH - 2.3.7 + 2.3.0 From dcefa90bdc3a55362d5e4758a61cf5c6bf3b177a Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 16:20:50 -0400 Subject: [PATCH 5/8] updated rails to rails 7 --- bin/rails | 3 +- bin/rake | 1 - bin/setup | 18 ++++---- config/application.rb | 17 +------ config/boot.rb | 2 +- config/environments/development.rb | 11 +++-- config/environments/production.rb | 45 ++++--------------- config/environments/test.rb | 14 +++--- config/initializers/cors.rb | 4 +- .../initializers/filter_parameter_logging.rb | 4 +- config/initializers/inflections.rb | 8 ++-- db/schema.rb | 19 ++++---- 12 files changed, 52 insertions(+), 94 deletions(-) diff --git a/bin/rails b/bin/rails index 21d3e02..efc0377 100755 --- a/bin/rails +++ b/bin/rails @@ -1,5 +1,4 @@ #!/usr/bin/env ruby -load File.expand_path("spring", __dir__) -APP_PATH = File.expand_path('../config/application', __dir__) +APP_PATH = File.expand_path("../config/application", __dir__) require_relative "../config/boot" require "rails/commands" diff --git a/bin/rake b/bin/rake index 7327f47..4fbf10b 100755 --- a/bin/rake +++ b/bin/rake @@ -1,5 +1,4 @@ #!/usr/bin/env ruby -load File.expand_path("spring", __dir__) require_relative "../config/boot" require "rake" Rake.application.run diff --git a/bin/setup b/bin/setup index 5792302..ec47b79 100755 --- a/bin/setup +++ b/bin/setup @@ -2,7 +2,7 @@ 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,21 +13,21 @@ FileUtils.chdir APP_ROOT do # This script is idempotent, so that you can run it at any time and get an expectable outcome. # Add necessary setup steps to this file. - puts '== Installing dependencies ==' - 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== Copying sample files ==" - # unless File.exist?('config/database.yml') - # FileUtils.cp 'config/database.yml.sample', 'config/database.yml' + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" # end puts "\n== Preparing database ==" - system! 'bin/rails db: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/application.rb b/config/application.rb index 8a947ca..d4c4403 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,19 +1,6 @@ require_relative "boot" -require "rails" -# Pick the frameworks you want: -require "active_model/railtie" -require "active_job/railtie" -require "active_record/railtie" -require "active_storage/engine" -require "action_controller/railtie" -require "action_mailer/railtie" -require "action_mailbox/engine" -require "action_text/engine" -require "action_view/railtie" -require "action_cable/engine" -# require "sprockets/railtie" -# require "rails/test_unit/railtie" +require "rails/all" # Require the gems listed in Gemfile, including any gems # you've limited to :test, :development, or :production. @@ -22,7 +9,7 @@ module CirculationHistory class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. - config.load_defaults 6.1 + config.load_defaults 7.0 # Configuration for the application, engines, and railties goes here. # diff --git a/config/boot.rb b/config/boot.rb index 3cda23b..988a5dd 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. diff --git a/config/environments/development.rb b/config/environments/development.rb index 231c2a6..3d6b073 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -14,12 +14,15 @@ # Show full error reports. config.consider_all_requests_local = true + # Enable server timing + config.server_timing = true + # 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.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 @@ -57,10 +60,6 @@ # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true - # Use an evented file watcher to asynchronously detect changes in source code, - # routes, locales, etc. This feature depends on the listen gem. - config.file_watcher = ActiveSupport::EventedFileUpdateChecker - # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true end diff --git a/config/environments/production.rb b/config/environments/production.rb index a98cb22..334adf5 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -21,22 +21,22 @@ # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. - config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.asset_host = 'http://assets.example.com' + # config.asset_host = "http://assets.example.com" # 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 + # 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 = :local # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil - # config.action_cable.url = 'wss://example.com/cable' - # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + # config.action_cable.url = "wss://example.com/cable" + # 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 @@ -65,21 +65,15 @@ # the I18n.default_locale when a translation cannot be found). config.i18n.fallbacks = true - # Send deprecation notices to registered listeners. - config.active_support.deprecation = :notify - - # Log disallowed deprecations. - config.active_support.disallowed_deprecation = :log - - # Tell Active Support which deprecation messages to disallow. - config.active_support.disallowed_deprecation_warnings = [] + # Don't log any deprecations. + config.active_support.report_deprecations = false # Use default logging formatter so that PID and timestamp are not suppressed. config.log_formatter = ::Logger::Formatter.new # Use a different logger for distributed setups. # require "syslog/logger" - # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") if ENV["RAILS_LOG_TO_STDOUT"].present? $stdout.sync = true @@ -89,25 +83,4 @@ # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - - # Inserts middleware to perform automatic connection switching. - # The `database_selector` hash is used to pass options to the DatabaseSelector - # middleware. The `delay` is used to determine how long to wait after a write - # to send a subsequent read to the primary. - # - # The `database_resolver` class is used by the middleware to determine which - # database is appropriate to use based on the time delay. - # - # The `database_resolver_context` class is used by the middleware to set - # timestamps for the last write to the primary. The resolver uses the context - # class timestamps to determine how long to wait before reading from the - # replica. - # - # By default Rails will store a last write timestamp in the session. The - # DatabaseSelector middleware is designed as such you can define your own - # strategy for connection switching and pass that into the middleware through - # these configuration options. - # config.active_record.database_selector = { delay: 2.seconds } - # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver - # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session end diff --git a/config/environments/test.rb b/config/environments/test.rb index 93ed4f1..6ea4d1e 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -8,18 +8,18 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - config.cache_classes = false - config.action_view.cache_template_loading = true + # Turn false under Spring and add config.action_view.cache_template_loading = true. + config.cache_classes = true - # Do not eager load code on boot. This avoids loading your whole application - # just for the purpose of running a single test. If you are using a tool that - # preloads Rails for running tests, you may have to set it to true. - config.eager_load = false + # Eager loading loads your whole application. When running a single test locally, + # this probably isn't necessary. It's a good idea to do in a continuous integration + # system, or in some way before deploying your code. + config.eager_load = ENV["CI"].present? # 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/cors.rb b/config/initializers/cors.rb index 3b1c1b5..e5a82f1 100644 --- a/config/initializers/cors.rb +++ b/config/initializers/cors.rb @@ -7,9 +7,9 @@ # Rails.application.config.middleware.insert_before 0, Rack::Cors do # allow do -# origins 'example.com' +# origins "example.com" # -# resource '*', +# resource "*", # headers: :any, # methods: [:get, :post, :put, :patch, :delete, :options, :head] # end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 4b34a03..adc6568 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -1,6 +1,8 @@ # Be sure to restart your server when you modify this file. -# Configure sensitive parameters which will be filtered from the log file. +# Configure parameters to be filtered from the log file. Use this to limit dissemination of +# sensitive information. See the ActiveSupport::ParameterFilter documentation for supported +# notations and behaviors. Rails.application.config.filter_parameters += [ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index ac033bf..3860f65 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -4,13 +4,13 @@ # are locale specific, and you may define rules for as many different # locales as you wish. All of these examples are active by default: # ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.plural /^(ox)$/i, '\1en' -# inflect.singular /^(ox)en/i, '\1' -# inflect.irregular 'person', 'people' +# inflect.plural /^(ox)$/i, "\\1en" +# inflect.singular /^(ox)en/i, "\\1" +# inflect.irregular "person", "people" # inflect.uncountable %w( fish sheep ) # end # These inflection rules are supported but not enabled by default: # ActiveSupport::Inflector.inflections(:en) do |inflect| -# inflect.acronym 'RESTful' +# inflect.acronym "RESTful" # end diff --git a/db/schema.rb b/db/schema.rb index ce9bee3..0008dc3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,12 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_05_06_133110) do - +ActiveRecord::Schema[7.0].define(version: 2021_05_06_133110) do create_table "auth_tokens", charset: "utf8mb4", force: :cascade do |t| t.string "token" t.string "name" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "loans", id: :string, charset: "utf8mb4", force: :cascade do |t| @@ -24,10 +23,10 @@ t.string "title" t.string "author" t.string "mms_id" - t.datetime "return_date" - t.datetime "checkout_date" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "return_date", precision: nil + t.datetime "checkout_date", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "barcode" t.string "call_number" t.string "description" @@ -37,8 +36,8 @@ create_table "users", primary_key: "uniqname", id: :string, charset: "utf8mb4", force: :cascade do |t| t.boolean "retain_history", default: false t.boolean "confirmed", default: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_foreign_key "loans", "users", column: "user_uniqname", primary_key: "uniqname" From 6b4230fba84f1be7c4f9964267b19d990409a864 Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 16:25:48 -0400 Subject: [PATCH 6/8] updated ruby to 3.1 --- .github/workflows/tests.yml | 4 ++-- Dockerfile | 2 +- Dockerfile.prod | 2 +- Gemfile.lock | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a677227..5b76f89 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,10 +27,10 @@ jobs: - name: Load .env file uses: xom9ikk/dotenv@v1.0.2 - - name: Set up Ruby 2.7.5 + - name: Set up Ruby 3.1.1 uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7.5 + ruby-version: 3.1.1 bundler-cache: true - name: Setup up node 16.14.2 uses: actions/setup-node@v2 diff --git a/Dockerfile b/Dockerfile index c0bb7fa..a565581 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG RUBY_VERSION=2.7 +ARG RUBY_VERSION=3.1 FROM ruby:${RUBY_VERSION} ARG BUNDLER_VERSION=2.3 diff --git a/Dockerfile.prod b/Dockerfile.prod index 8925cdd..2142b26 100644 --- a/Dockerfile.prod +++ b/Dockerfile.prod @@ -1,4 +1,4 @@ -ARG RUBY_VERSION=2.7 +ARG RUBY_VERSION=3.1 FROM ruby:${RUBY_VERSION} ARG BUNDLER_VERSION=2.3 diff --git a/Gemfile.lock b/Gemfile.lock index 1db7ca0..59bd2cb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -257,4 +257,4 @@ DEPENDENCIES webmock BUNDLED WITH - 2.3.0 + 2.3.7 From 73c1086e58c4bf26eddf3d088924ec0d057e961e Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 16:50:54 -0400 Subject: [PATCH 7/8] lots of standardrb fixes --- .gitignore | 1 + Gemfile | 45 +++---- Gemfile.lock | 28 +++++ app/controllers/application_controller.rb | 5 +- app/controllers/test_controller.rb | 6 +- app/controllers/v1/loans_controller.rb | 27 ++-- app/controllers/v1/users_controller.rb | 16 ++- app/mailers/application_mailer.rb | 4 +- app/models/loan.rb | 6 +- app/models/user.rb | 10 +- app/presenters/loans_presenter.rb | 15 ++- app/views/v1/users/show.json.jbuilder | 2 +- config.ru | 4 +- config/application.rb | 10 +- config/environment.rb | 1 - config/environments/development.rb | 1 - config/environments/production.rb | 4 +- config/environments/test.rb | 2 +- config/routes.rb | 8 +- db/migrate/20210208204259_create_users.rb | 2 +- db/migrate/20210209194645_create_loans.rb | 2 +- .../20210506133110_create_auth_tokens.rb | 4 +- fake_alma/Gemfile | 8 +- fake_alma/fake_alma.rb | 6 +- lib/prometheus/controller.rb | 2 +- lib/tasks/alma_circ_history.rake | 43 ++++--- lib/tasks/dev_seed.rake | 23 ++-- lib/tasks/retain_history_dump.rake | 6 +- lib/tasks/token.rake | 20 ++- spec/models/user_spec.rb | 16 +-- spec/presenters/loan_presenter_spec.rb | 14 +-- spec/rails_helper.rb | 21 ++-- spec/requests/user_spec.rb | 41 +++---- spec/spec_helper.rb | 116 +++++++++--------- spec/support/factories.rb | 9 +- spec/support/request_spec_helpers.rb | 6 +- spec/tasks/alma_circ_history_task_spec.rb | 91 +++++++------- spec/tasks/token_task_spec.rb | 34 ++--- 38 files changed, 341 insertions(+), 318 deletions(-) diff --git a/.gitignore b/.gitignore index 445ccc5..b2722cf 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ # Ignore bundler config. /.bundle +/.cache/ # Ignore all logfiles and tempfiles. /log/* diff --git a/Gemfile b/Gemfile index b9f696d..bddc997 100644 --- a/Gemfile +++ b/Gemfile @@ -1,14 +1,14 @@ -source 'https://rubygems.org' +source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' -gem 'rails', '~> 7.0.0' +gem "rails", "~> 7.0.0" # Use mysql as the database for Active Record -gem 'mysql2', '~> 0.5' +gem "mysql2", "~> 0.5" # Use Puma as the app server -gem 'puma', '~> 5.0' +gem "puma", "~> 5.0" # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder -gem 'jbuilder', '~> 2.7' +gem "jbuilder", "~> 2.7" # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use Active Model has_secure_password @@ -18,38 +18,39 @@ gem 'jbuilder', '~> 2.7' # gem 'image_processing', '~> 1.2' # Reduces boot times through caching; required in config/boot.rb -gem 'bootsnap', '>= 1.4.4', require: false +gem "bootsnap", ">= 1.4.4", require: false # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible # gem 'rack-cors' -gem 'amazing_print' -gem 'rails_semantic_logger' +gem "amazing_print" +gem "rails_semantic_logger" -gem 'prometheus-client' -gem 'alma_rest_client', - git: 'https://github.com/mlibrary/alma_rest_client', - tag: '1.3.1' +gem "prometheus-client" +gem "alma_rest_client", + git: "https://github.com/mlibrary/alma_rest_client", + tag: "1.3.1" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console - gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] - gem 'rspec-rails' - gem 'simplecov' + gem "byebug", platforms: [:mri, :mingw, :x64_mingw] + gem "rspec-rails" + gem "simplecov" + gem "standardrb" end group :test do - gem 'factory_bot_rails' - gem 'faker' - gem 'database_cleaner' - gem 'webmock' + gem "factory_bot_rails" + gem "faker" + gem "database_cleaner" + gem "webmock" end group :development do - gem 'listen', '~> 3.3' + gem "listen", "~> 3.3" # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring - #gem 'spring' + # gem 'spring' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] +gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 59bd2cb..83226a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,6 +79,7 @@ GEM addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) amazing_print (1.4.0) + ast (2.4.2) bootsnap (1.11.1) msgpack (~> 1.2) builder (3.2.4) @@ -151,6 +152,9 @@ GEM nio4r (2.5.8) nokogiri (1.13.3-x86_64-linux) racc (~> 1.4) + parallel (1.22.1) + parser (3.1.1.0) + ast (~> 2.4.1) prometheus-client (4.0.0) public_suffix (4.0.6) puma (5.6.4) @@ -189,10 +193,12 @@ GEM rake (>= 12.2) thor (~> 1.0) zeitwerk (~> 2.5) + rainbow (3.1.1) rake (13.0.6) rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) + regexp_parser (2.2.1) rexml (3.2.5) rspec-core (3.11.0) rspec-support (~> 3.11.0) @@ -211,6 +217,21 @@ GEM rspec-mocks (~> 3.10) rspec-support (~> 3.10) rspec-support (3.11.0) + rubocop (1.26.1) + parallel (~> 1.10) + parser (>= 3.1.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.16.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.16.0) + parser (>= 3.1.1.0) + rubocop-performance (1.13.3) + rubocop (>= 1.7.0, < 2.0) + rubocop-ast (>= 0.4.0) + ruby-progressbar (1.11.0) semantic_logger (4.10.0) concurrent-ruby (~> 1.0) simplecov (0.21.2) @@ -219,11 +240,17 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) + standard (1.9.1) + rubocop (= 1.26.1) + rubocop-performance (= 1.13.3) + standardrb (1.0.1) + standard strscan (3.0.1) thor (1.2.1) timeout (0.2.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) + unicode-display_width (2.1.0) webmock (3.14.0) addressable (>= 2.8.0) crack (>= 0.3.2) @@ -253,6 +280,7 @@ DEPENDENCIES rails_semantic_logger rspec-rails simplecov + standardrb tzinfo-data webmock diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 74c5eda..c4ea5d6 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,10 +5,11 @@ class ApplicationController < ActionController::API before_action :require_authorization_token private + def require_authorization_token - token = request.headers["Authorization"]&.split(' ')&.at(1) + token = request.headers["Authorization"]&.split(" ")&.at(1) unless AuthToken.exists?(token: token) - render json: {}, status: 401 + render json: {}, status: 401 end end end diff --git a/app/controllers/test_controller.rb b/app/controllers/test_controller.rb index 8e497b5..b3f07f9 100644 --- a/app/controllers/test_controller.rb +++ b/app/controllers/test_controller.rb @@ -3,13 +3,13 @@ class TestController < ActionController::Base def gauge GAUGE_EXAMPLE .set(rand(0..100), labels: {route: :gauge}) - Rails.logger.tagged("MRIO").info("Hiya") + Rails.logger.tagged("MRIO").info("Hiya") respond_to do |r| r.any do render json: { - message: "Success", }, status: 200 + message: "Success" + }, status: 200 end end end end - diff --git a/app/controllers/v1/loans_controller.rb b/app/controllers/v1/loans_controller.rb index 9e75991..f53051a 100644 --- a/app/controllers/v1/loans_controller.rb +++ b/app/controllers/v1/loans_controller.rb @@ -1,27 +1,26 @@ module V1 class LoansController < ApplicationController def index - begin - user = User.find(params[:user_uniqname]) - rescue - render template: "v1/errors/no_user", status: :bad_request - else - @loans = LoansPresenter.new(user: user, - limit: params[:limit], offset: params[:offset], - order_by: params[:order_by], direction: params[:direction]) - end - #render json: @loans + user = User.find(params[:user_uniqname]) + rescue + render template: "v1/errors/no_user", status: :bad_request + else + @loans = LoansPresenter.new(user: user, + limit: params[:limit], offset: params[:offset], + order_by: params[:order_by], direction: params[:direction]) + + # render json: @loans end + def download user = User.find_or_create_by_uniqname(params[:user_uniqname]) loans = Loan.where(user: user) respond_to do |format| - format.csv { send_data loans.to_csv, - filename: "circulation_history_#{Date.today}.csv" + format.csv { + send_data loans.to_csv, + filename: "circulation_history_#{Date.today}.csv" } end - end end end - diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index 3b3ce31..b7834cb 100644 --- a/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -1,21 +1,19 @@ module V1 class UsersController < ApplicationController def show - begin - @user = User.find(params[:uniqname]) - rescue - render template: "v1/errors/no_user", status: :bad_request - else - end + @user = User.find(params[:uniqname]) + rescue + render template: "v1/errors/no_user", status: :bad_request + else end + def update @user = User.find_or_create_by(uniqname: params[:uniqname].downcase) if @user.update(retain_history: params[:retain_history]) - redirect_to action: 'show', uniqname: @user.uniqname + redirect_to action: "show", uniqname: @user.uniqname else - #error? + # error? end end end end - diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 286b223..3c34c81 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: 'from@example.com' - layout 'mailer' + default from: "from@example.com" + layout "mailer" end diff --git a/app/models/loan.rb b/app/models/loan.rb index 54badf4..4964a1d 100644 --- a/app/models/loan.rb +++ b/app/models/loan.rb @@ -1,14 +1,14 @@ class Loan < ApplicationRecord validates_uniqueness_of :id - belongs_to :user, foreign_key: 'user_uniqname' + belongs_to :user, foreign_key: "user_uniqname" def self.to_csv - attributes = %w{mms_id title author description call_number barcode checkout_date return_date} + attributes = %w[mms_id title author description call_number barcode checkout_date return_date] CSV.generate(headers: true) do |csv| csv << attributes all.each do |loan| - csv << attributes.map {|attr| loan.send(attr) } + csv << attributes.map { |attr| loan.send(attr) } end end end diff --git a/app/models/user.rb b/app/models/user.rb index 1980ba7..6049ed7 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ class User < ApplicationRecord - has_many :loans, primary_key: 'uniqname', foreign_key: 'user_uniqname', dependent: :destroy + has_many :loans, primary_key: "uniqname", foreign_key: "user_uniqname", dependent: :destroy before_update :set_confirmed before_update :purge_loans_if_opt_out @@ -7,18 +7,22 @@ class User < ApplicationRecord def loans_page(limit: 10, offset: 0) loans.limit(limit).offset(offset) end - def self.find_or_create_by_uniqname(uniqname, retain_history=false) - self.find_or_create_by(uniqname: uniqname.downcase) do |u| + + def self.find_or_create_by_uniqname(uniqname, retain_history = false) + find_or_create_by(uniqname: uniqname.downcase) do |u| u.retain_history = retain_history u.confirmed = false end end + private + def purge_loans_if_opt_out if !retain_history loans.destroy_all end end + def set_confirmed self.confirmed = true end diff --git a/app/presenters/loans_presenter.rb b/app/presenters/loans_presenter.rb index 55612b6..cd09727 100644 --- a/app/presenters/loans_presenter.rb +++ b/app/presenters/loans_presenter.rb @@ -1,12 +1,12 @@ class LoansPresenter attr_reader :count - def initialize(user:, limit: 15, offset: 0, direction: 'ASC', order_by: 'checkout_date') - @order_by = protect_order_by(order_by) || 'checkout_date' - @direction = protect_direction(direction) || 'ASC' + def initialize(user:, limit: 15, offset: 0, direction: "ASC", order_by: "checkout_date") + @order_by = protect_order_by(order_by) || "checkout_date" + @direction = protect_direction(direction) || "ASC" @order = "#{@order_by} #{@direction}" @limit = (limit || 15).to_i @offset = (offset || 0).to_i - + @list = user.loans.order(@order).limit(@limit).offset(@offset) @count = user.loans.all.count end @@ -16,11 +16,14 @@ def map(&block) block.call(l) end end + private + def protect_order_by(order_by) - ['checkout_date','return_date','title','author','call_number'].include?(order_by) ? order_by : nil + ["checkout_date", "return_date", "title", "author", "call_number"].include?(order_by) ? order_by : nil end + def protect_direction(direction) - ['ASC', 'DESC'].include?(direction) ? direction : nil + ["ASC", "DESC"].include?(direction) ? direction : nil end end diff --git a/app/views/v1/users/show.json.jbuilder b/app/views/v1/users/show.json.jbuilder index 9a8be29..9ac2c54 100644 --- a/app/views/v1/users/show.json.jbuilder +++ b/app/views/v1/users/show.json.jbuilder @@ -1 +1 @@ -json.(@user, :uniqname, :retain_history, :confirmed, :updated_at, :created_at) +json.call(@user, :uniqname, :retain_history, :confirmed, :updated_at, :created_at) diff --git a/config.ru b/config.ru index 005639a..f8ad876 100644 --- a/config.ru +++ b/config.ru @@ -1,8 +1,8 @@ # This file is used by Rack-based servers to start the application. require_relative "config/environment" -require 'prometheus/middleware/collector' -require 'prometheus/middleware/exporter' +require "prometheus/middleware/collector" +require "prometheus/middleware/exporter" use Prometheus::Middleware::Collector use Prometheus::Middleware::Exporter diff --git a/config/application.rb b/config/application.rb index d4c4403..1a9de40 100644 --- a/config/application.rb +++ b/config/application.rb @@ -23,13 +23,11 @@ class Application < Rails::Application # Middleware like session, flash, cookies can be added back manually. # Skip views, helpers and assets when generating a new resource. config.api_only = true - config.autoload_paths << Rails.root.join('lib') - config.rails_semantic_logger.started = true + config.autoload_paths << Rails.root.join("lib") + config.rails_semantic_logger.started = true config.rails_semantic_logger.processing = true - config.rails_semantic_logger.rendered = true + config.rails_semantic_logger.rendered = true config.colorize_logging = false - config.time_zone = 'Eastern Time (US & Canada)' - - + config.time_zone = "Eastern Time (US & Canada)" end end diff --git a/config/environment.rb b/config/environment.rb index 06607e3..7008cc7 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -4,4 +4,3 @@ # Initialize the Rails application. Rails.application.initialize! Rails.logger.datetime_format = "%FT%T%:z" - diff --git a/config/environments/development.rb b/config/environments/development.rb index 3d6b073..08c1576 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -53,7 +53,6 @@ # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true - # Raises error for missing translations. # config.i18n.raise_on_missing_translations = true diff --git a/config/environments/production.rb b/config/environments/production.rb index 334adf5..7c48775 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -13,7 +13,7 @@ config.eager_load = true # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false + config.consider_all_requests_local = false # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). @@ -46,7 +46,7 @@ config.log_level = :info # 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 diff --git a/config/environments/test.rb b/config/environments/test.rb index 6ea4d1e..9de8427 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -23,7 +23,7 @@ } # Show full error reports and disable caching. - config.consider_all_requests_local = true + config.consider_all_requests_local = true config.action_controller.perform_caching = false config.cache_store = :null_store diff --git a/config/routes.rb b/config/routes.rb index 1529bba..6442d8c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,9 +1,9 @@ Rails.application.routes.draw do namespace :v1, defaults: {format: :json} do - resources :users, param: :uniqname, only: ['show', 'update'], :constraints => { :uniqname => /.*/ } do - resources :loans, only: ['index'] - get '/loans/download', to: 'loans#download' + resources :users, param: :uniqname, only: ["show", "update"], constraints: {uniqname: /.*/} do + resources :loans, only: ["index"] + get "/loans/download", to: "loans#download" end end - get 'test_gauge', to: 'test#gauge' + get "test_gauge", to: "test#gauge" end diff --git a/db/migrate/20210208204259_create_users.rb b/db/migrate/20210208204259_create_users.rb index f90d0c4..e019c2b 100644 --- a/db/migrate/20210208204259_create_users.rb +++ b/db/migrate/20210208204259_create_users.rb @@ -1,6 +1,6 @@ class CreateUsers < ActiveRecord::Migration[6.1] def change - create_table(:users, primary_key: 'uniqname', id: :string) do |t| + create_table(:users, primary_key: "uniqname", id: :string) do |t| t.boolean :retain_history, default: false t.boolean :confirmed, default: false t.timestamps diff --git a/db/migrate/20210209194645_create_loans.rb b/db/migrate/20210209194645_create_loans.rb index 42eda3b..2fab127 100644 --- a/db/migrate/20210209194645_create_loans.rb +++ b/db/migrate/20210209194645_create_loans.rb @@ -10,6 +10,6 @@ def change t.timestamps end rename_column :loans, :uniqname_id, :user_uniqname - add_foreign_key :loans, :users, column: 'user_uniqname', primary_key: 'uniqname' + add_foreign_key :loans, :users, column: "user_uniqname", primary_key: "uniqname" end end diff --git a/db/migrate/20210506133110_create_auth_tokens.rb b/db/migrate/20210506133110_create_auth_tokens.rb index 9b304a1..0c336eb 100644 --- a/db/migrate/20210506133110_create_auth_tokens.rb +++ b/db/migrate/20210506133110_create_auth_tokens.rb @@ -1,8 +1,8 @@ class CreateAuthTokens < ActiveRecord::Migration[6.1] def change create_table :auth_tokens do |t| - t.string :token, :unique => true - t.string :name, :unique => true + t.string :token, unique: true + t.string :name, unique: true t.timestamps end diff --git a/fake_alma/Gemfile b/fake_alma/Gemfile index b4803e7..0619ef5 100644 --- a/fake_alma/Gemfile +++ b/fake_alma/Gemfile @@ -1,7 +1,7 @@ -source 'https://rubygems.org' +source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.7.2' +ruby "2.7.2" -gem 'sinatra' -gem 'sinatra-contrib' +gem "sinatra" +gem "sinatra-contrib" diff --git a/fake_alma/fake_alma.rb b/fake_alma/fake_alma.rb index e29ee1c..5074966 100644 --- a/fake_alma/fake_alma.rb +++ b/fake_alma/fake_alma.rb @@ -1,6 +1,6 @@ -require 'sinatra' -require 'sinatra/json' +require "sinatra" +require "sinatra/json" get "/almaws/v1/analytics/reports" do - json JSON.parse(File.read('./circ_history.json')) + json JSON.parse(File.read("./circ_history.json")) end diff --git a/lib/prometheus/controller.rb b/lib/prometheus/controller.rb index ccd90a8..12a39bc 100644 --- a/lib/prometheus/controller.rb +++ b/lib/prometheus/controller.rb @@ -2,7 +2,7 @@ module Prometheus module Controller prometheus = Prometheus::Client.registry - GAUGE_EXAMPLE = Prometheus::Client::Gauge.new(:gauge_example, docstring: 'A simple guage that rands between 1 and 100 inclusively.', labels: [:route]) + GAUGE_EXAMPLE = Prometheus::Client::Gauge.new(:gauge_example, docstring: "A simple guage that rands between 1 and 100 inclusively.", labels: [:route]) prometheus.register(GAUGE_EXAMPLE) end diff --git a/lib/tasks/alma_circ_history.rake b/lib/tasks/alma_circ_history.rake index 70a8752..ddc794e 100644 --- a/lib/tasks/alma_circ_history.rake +++ b/lib/tasks/alma_circ_history.rake @@ -1,16 +1,16 @@ -require 'alma_rest_client' +require "alma_rest_client" namespace :alma_circ_history do desc "retrieves and loads latest circ history" - task :load => :environment do - summary = { active_loans: 0, loans_loaded: 0} - Rails.logger.tagged('Circ Load') do - Rails.logger.info('Started') - HTTParty.post(ENV.fetch('SLACK_URL'), body: {text: "Load Started"}.to_json) + task load: :environment do + summary = {active_loans: 0, loans_loaded: 0} + Rails.logger.tagged("Circ Load") do + Rails.logger.info("Started") + HTTParty.post(ENV.fetch("SLACK_URL"), body: {text: "Load Started"}.to_json) client = AlmaRestClient.client - response = client.get_report(path: ENV.fetch('CIRC_REPORT_PATH')) + response = client.get_report(path: ENV.fetch("CIRC_REPORT_PATH")) if response.code != 200 - Rails.logger.error('Alma Report Failed to Load') - HTTParty.post(ENV.fetch('SLACK_URL'), body: {text: "Load FAILED"}.to_json) + Rails.logger.error("Alma Report Failed to Load") + HTTParty.post(ENV.fetch("SLACK_URL"), body: {text: "Load FAILED"}.to_json) next end summary[:active_loans] = response.parsed_response.count @@ -18,13 +18,13 @@ namespace :alma_circ_history do u = User.find_or_create_by_uniqname(row["Primary Identifier"]) unless u.retain_history Rails.logger.warn("item_loan '#{row["Item Loan Id"]}' not saved: patron opt out") - next + next end loan = Loan.new do |l| l.user = u l.id = row["Item Loan Id"] - l.title = row["Title"]&.slice(0,255) - l.author = row["Author"]&.slice(0,255) + l.title = row["Title"]&.slice(0, 255) + l.author = row["Author"]&.slice(0, 255) l.mms_id = row["MMS Id"] l.return_date = row["Return Date"] l.checkout_date = row["Loan Date"] @@ -39,24 +39,23 @@ namespace :alma_circ_history do Rails.logger.warn("item_loan '#{loan.id}' not saved: #{loan.errors.full_messages}") end end - Rails.logger.info('Finished') + Rails.logger.info("Finished") Rails.logger.info("Summary: #{summary}") - HTTParty.post(ENV.fetch('SLACK_URL'), body: {text: "Load Finished\n#{summary}"}.to_json) + HTTParty.post(ENV.fetch("SLACK_URL"), body: {text: "Load Finished\n#{summary}"}.to_json) begin - HTTParty.get(ENV.fetch('PUSHMON_URL')) + HTTParty.get(ENV.fetch("PUSHMON_URL")) rescue Rails.logger.error("Failed to contact Pushmon") end - end end - task :purge => :environment do - Rails.logger.tagged('Purge Expired Users') do - Rails.logger.info('Started') + task purge: :environment do + Rails.logger.tagged("Purge Expired Users") do + Rails.logger.info("Started") client = AlmaRestClient.client - response = client.get_report(path: ENV.fetch('PATRON_REPORT_PATH')) + response = client.get_report(path: ENV.fetch("PATRON_REPORT_PATH")) if response.code != 200 - Rails.logger.error('Alma Report Failed to Load') + Rails.logger.error("Alma Report Failed to Load") next end non_expired_users = response.parsed_response.map { |row| row["Primary Identifier"].downcase } @@ -69,7 +68,7 @@ namespace :alma_circ_history do Rails.logger.info("Deleted User: #{uniqname}") end end - Rails.logger.info('Finished') + Rails.logger.info("Finished") end end end diff --git a/lib/tasks/dev_seed.rake b/lib/tasks/dev_seed.rake index a3298ee..1e48c8f 100644 --- a/lib/tasks/dev_seed.rake +++ b/lib/tasks/dev_seed.rake @@ -1,17 +1,16 @@ -#:nocov: -require 'faker' +# :nocov: +require "faker" namespace :dev do desc "seeds db with development data" - task :seed => :environment do - - ['mlibrary.acct.testing1@gmail.com','mlibrary.acct.testing2@gmail.com', 'mlibrary.acct.testing3@gmail.com'].each do |uniqname| - User.find_or_create_by(uniqname: uniqname) do |u| + task seed: :environment do + ["mlibrary.acct.testing1@gmail.com", "mlibrary.acct.testing2@gmail.com", "mlibrary.acct.testing3@gmail.com"].each do |uniqname| + User.find_or_create_by(uniqname: uniqname) do |u| u.retain_history = true u.confirmed = false end - (1..35).each do + 35.times do Loan.create do |l| - return_date = Faker::Date.between(from: 2.years.ago, to: Date.today) + return_date = Faker::Date.between(from: 2.years.ago, to: Date.today) l.user_uniqname = uniqname l.id = SecureRandom.alphanumeric(16) l.title = Faker::Book.title @@ -21,14 +20,14 @@ namespace :dev do l.checkout_date = return_date - rand(0..50).days l.barcode = Faker::Number.number(digits: 16) l.call_number = "call number" - l.description = '' + l.description = "" end end end end task :reset do - Rake::Task['db:migrate:reset'].invoke + Rake::Task["db:migrate:reset"].invoke end - task :all => [:reset, :seed] + task all: [:reset, :seed] end -#:nocov: +# :nocov: diff --git a/lib/tasks/retain_history_dump.rake b/lib/tasks/retain_history_dump.rake index 65bec91..e47cc54 100644 --- a/lib/tasks/retain_history_dump.rake +++ b/lib/tasks/retain_history_dump.rake @@ -1,5 +1,5 @@ -desc "dump retain history status" -task :dump_retain_history => :environment do +desc "dump retain history status" +task dump_retain_history: :environment do puts User.first.attributes.keys.to_csv - puts User.all.map{|x| x.attributes.keys.map{|y| x[y] }.to_csv} + puts User.all.map { |x| x.attributes.keys.map { |y| x[y] }.to_csv } end diff --git a/lib/tasks/token.rake b/lib/tasks/token.rake index 4be362a..baf813c 100644 --- a/lib/tasks/token.rake +++ b/lib/tasks/token.rake @@ -1,28 +1,26 @@ -require 'securerandom' +require "securerandom" namespace :token do desc "generates a new token with associated name" task :generate, [:name] => :environment do |t, args| a = AuthToken.new(name: args[:name]) - unless (a.save) - puts "Errors: #{a.errors.full_messages.join('; ')}" - else + if a.save puts "token: #{a.token} for app: #{a.name}" + else + puts "Errors: #{a.errors.full_messages.join("; ")}" end end - desc "regenerates token for app name" + desc "regenerates token for app name" task :regenerate, [:name] => :environment do |t, args| a = AuthToken.find_by(name: args[:name]) if a.nil? puts "Error: app: '#{args[:name]}' does not exist" + elsif a.regenerate_token + puts "token: #{a.token} for app: #{a.name}" else - unless (a.regenerate_token) - puts "Errors: #{a.errors.full_messages.join('; ')}" - else - puts "token: #{a.token} for app: #{a.name}" - end + puts "Errors: #{a.errors.full_messages.join("; ")}" end end - desc "gets token for app" + desc "gets token for app" task :get, [:name] => :environment do |t, args| a = AuthToken.find_by(name: args[:name]) if a.nil? diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 47b279d..879b8a4 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,11 +1,11 @@ -require 'rails_helper' +require "rails_helper" RSpec.describe User, type: :model do context "#loans_page(limit:, offset:)" do before(:each) do @user = create(:user, retain_history: true) @loans = [] - (1..5).each do + 5.times do @loans.push(create(:loan, user: @user)) end end @@ -15,15 +15,15 @@ end context ".find_or_create_by_uniqname" do it "downcases uniqname" do - user = User.find_or_create_by_uniqname('SOANDSO') - expect(user.uniqname).to eq('soandso') + user = User.find_or_create_by_uniqname("SOANDSO") + expect(user.uniqname).to eq("soandso") end end context "after setting retain history" do it "to false purges items from the history" do user = create(:user, retain_history: true) loans = [] - (1..5).each do + 5.times do loans.push(create(:loan, user: user)) end expect(User.first.loans.count).to eq(5) @@ -31,10 +31,10 @@ expect(User.first.loans.count).to eq(0) end it "to true it does not purge items from the history" do - #from false to true; not something that should happen. - user = create(:user, retain_history: false) + # from false to true; not something that should happen. + user = create(:user, retain_history: false) loans = [] - (1..5).each do + 5.times do loans.push(create(:loan, user: user)) end expect(User.first.loans.count).to eq(5) diff --git a/spec/presenters/loan_presenter_spec.rb b/spec/presenters/loan_presenter_spec.rb index 0dcdab7..c3b66f4 100644 --- a/spec/presenters/loan_presenter_spec.rb +++ b/spec/presenters/loan_presenter_spec.rb @@ -1,17 +1,17 @@ -require 'rails_helper' +require "rails_helper" RSpec.describe LoansPresenter do before(:each) do @user = create(:user, retain_history: true) - @returned_most_recently = create(:loan, user: @user, checkout_date: Time.current - 5.days, return_date: Time.current - 1.days) - @returned_longest_ago = create(:loan, user: @user, checkout_date: Time.current - 5.days, return_date: Time.current - 3.days) + @returned_most_recently = create(:loan, user: @user, checkout_date: Time.current - 5.days, return_date: Time.current - 1.days) + @returned_longest_ago = create(:loan, user: @user, checkout_date: Time.current - 5.days, return_date: Time.current - 3.days) end - it "can order by return_date least recent first" do - loans_presenter = LoansPresenter.new(user: @user, order_by: 'return_date').map{|x| x} + it "can order by return_date least recent first" do + loans_presenter = LoansPresenter.new(user: @user, order_by: "return_date").map { |x| x } expect(loans_presenter.first.return_date).to eq(@returned_longest_ago.return_date) end - it "can order by return_date least recent first" do - loans_presenter = LoansPresenter.new(user: @user, order_by: 'return_date', direction: 'DESC').map{|x| x} + it "can order by return_date least recent first" do + loans_presenter = LoansPresenter.new(user: @user, order_by: "return_date", direction: "DESC").map { |x| x } expect(loans_presenter.first.return_date).to eq(@returned_most_recently.return_date) end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 05b0adc..b90c060 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,17 +1,17 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' -require 'spec_helper' -require 'webmock/rspec' -require 'simplecov' +require "spec_helper" +require "webmock/rspec" +require "simplecov" SimpleCov.start -ENV['RAILS_ENV'] ||= 'test' -require File.expand_path('../config/environment', __dir__) +ENV["RAILS_ENV"] ||= "test" +require File.expand_path("../config/environment", __dir__) -#for testing rake tasks +# for testing rake tasks Rails.application.load_tasks # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? -require 'rspec/rails' +require "rspec/rails" # Add additional requires below this line. Rails is not loaded until this point! # Requires supporting ruby files with custom matchers and macros, etc, in @@ -27,7 +27,7 @@ # directory. Alternatively, in the individual `*_spec.rb` files, manually # require only the support files necessary. # -Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f } +Dir[Rails.root.join("spec", "support", "**", "*.rb")].sort.each { |f| require f } # Checks for pending migrations and applies them before tests are run. # If you are not using ActiveRecord, you can remove these lines. @@ -68,9 +68,8 @@ config.filter_rails_from_backtrace! # arbitrary gems may also be filtered via: # config.filter_gems_from_backtrace("gem name") - #config.include Rack::Test::Methods + # config.include Rack::Test::Methods config.include FactoryBot::Syntax::Methods - config.include RequestSpecHelpers, :type => :request + config.include RequestSpecHelpers, type: :request config.include ActiveSupport::Testing::TimeHelpers end - diff --git a/spec/requests/user_spec.rb b/spec/requests/user_spec.rb index bdbbd78..d6f692a 100644 --- a/spec/requests/user_spec.rb +++ b/spec/requests/user_spec.rb @@ -1,5 +1,5 @@ require "rails_helper" -describe "get /v1/users/:uniqname/loans", :type => :request do +describe "get /v1/users/:uniqname/loans", type: :request do context "unauthorized request" do it "shows a patron's loan history" do loan = create(:loan) @@ -20,7 +20,7 @@ it "returns appropriate response if user doesn't exist" do get "/v1/users/soandso/loans" expect(response).to have_http_status(:bad_request) - expect(response.body).to eq({"error": "User not found"}.to_json) + expect(response.body).to eq({error: "User not found"}.to_json) end it "does not create a patron if one doesn't exist" do get "/v1/users/soandso/loans" @@ -45,17 +45,17 @@ expect(loans.first["title"]).to eq(@loan2.title) end it "handles sorting" do - @loan1.update(title: 'ZZZZ') - @loan2.update(title: 'AAAA') - loan3 = create(:loan, user: @user, title: 'BBBB') - get "/v1/users/#{@user.uniqname}/loans", params: {order_by: 'title'} + @loan1.update(title: "ZZZZ") + @loan2.update(title: "AAAA") + loan3 = create(:loan, user: @user, title: "BBBB") + get "/v1/users/#{@user.uniqname}/loans", params: {order_by: "title"} loans = JSON.parse(response.body)["loans"] - expect(loans[0]["title"]).to eq('AAAA') - expect(loans[1]["title"]).to eq('BBBB') - expect(loans[2]["title"]).to eq('ZZZZ') + expect(loans[0]["title"]).to eq("AAAA") + expect(loans[1]["title"]).to eq("BBBB") + expect(loans[2]["title"]).to eq("ZZZZ") end end - end + end end describe "get /v1/users/:uniqname/loans/download" do before(:each) do @@ -72,25 +72,24 @@ end it "creates a new user if one doesn't exist" do get "/v1/users/soandso/loans/download.csv" - expect(User.first.uniqname).to eq('soandso') + expect(User.first.uniqname).to eq("soandso") end end end describe "get /v1/users/:uniqname" do context "unauthorized" do it "returns unauthorized" do - user = create(:user, uniqname: 'emcard') + user = create(:user, uniqname: "emcard") get "/v1/users/#{CGI.escape(user.uniqname)}" expect(response).to have_http_status(:unauthorized) end end context "authorized" do - before(:each) do authorize end it "handle patron with email address uniqname" do - user = create(:user, uniqname: 'so.and.so@example.com') + user = create(:user, uniqname: "so.and.so@example.com") get "/v1/users/#{CGI.escape(user.uniqname)}" expect(response).to have_http_status(:success) end @@ -98,8 +97,8 @@ user = create(:user) get "/v1/users/#{user.uniqname}" expect(response).to have_http_status(:success) - expect(response.body).to include('retain_history') - expect(response.body).to include('confirmed') + expect(response.body).to include("retain_history") + expect(response.body).to include("confirmed") expect(response.body).to include(user.uniqname) end it "creates a new user if one doesn't exist" do @@ -116,17 +115,17 @@ it "changes a patron's loan retention status and confirmation status and deletes existing loans; returns updated user" do user = create(:user, retain_history: true, confirmed: false) loan = create(:loan, user: user) - put "/v1/users/#{user.uniqname}", params: {:retain_history => false } + put "/v1/users/#{user.uniqname}", params: {retain_history: false} expect(response).to redirect_to("/v1/users/#{user.uniqname}") - updated_user = User.first + updated_user = User.first expect(updated_user.retain_history).to be_falsey expect(updated_user.confirmed).to be_truthy expect(Loan.all.count).to eq(0) end it "creates a user if one doesn't exist" do - put "/v1/users/so_and_so", params: {:retain_history => false } + put "/v1/users/so_and_so", params: {retain_history: false} expect(response).to redirect_to("/v1/users/so_and_so") - updated_user = User.first + updated_user = User.first expect(updated_user.retain_history).to be_falsey expect(updated_user.confirmed).to be_truthy expect(Loan.all.count).to eq(0) @@ -136,7 +135,7 @@ it "returns unauthorized" do user = create(:user, retain_history: true, confirmed: false) loan = create(:loan, user: user) - put "/v1/users/#{user.uniqname}", params: {:retain_history => false } + put "/v1/users/#{user.uniqname}", params: {retain_history: false} expect(response).to have_http_status(:unauthorized) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 1253c93..19f5bbb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,64 +44,62 @@ # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin - # This allows you to limit a spec run to individual examples or groups - # you care about by tagging them with `:focus` metadata. When nothing - # is tagged with `:focus`, all examples get run. RSpec also provides - # aliases for `it`, `describe`, and `context` that include `:focus` - # metadata: `fit`, `fdescribe` and `fcontext`, respectively. - config.filter_run_when_matching :focus - - # Allows RSpec to persist some state between runs in order to support - # the `--only-failures` and `--next-failure` CLI options. We recommend - # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" - - # Limits the available syntax to the non-monkey patched syntax that is - # recommended. For more details, see: - # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ - # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ - # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode - config.disable_monkey_patching! - - # Many RSpec users commonly either run the entire suite or an individual - # file, and it's useful to allow more verbose output when running an - # individual spec file. - if config.files_to_run.one? - # Use the documentation formatter for detailed output, - # unless a formatter has already been configured - # (e.g. via a command-line flag). - config.default_formatter = "doc" - end - - # Print the 10 slowest examples and example groups at the - # end of the spec run, to help surface which specs are running - # particularly slow. - config.profile_examples = 10 - - # Run specs in random order to surface order dependencies. If you find an - # order dependency and want to debug it, you can fix the order by providing - # the seed, which is printed after each run. - # --seed 1234 - config.order = :random - - # Seed global randomization in this process using the `--seed` CLI option. - # Setting this allows you to use `--seed` to deterministically reproduce - # test failures related to randomization by passing the same `--seed` value - # as the one that triggered the failure. - Kernel.srand config.seed -=end + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. + # # This allows you to limit a spec run to individual examples or groups + # # you care about by tagging them with `:focus` metadata. When nothing + # # is tagged with `:focus`, all examples get run. RSpec also provides + # # aliases for `it`, `describe`, and `context` that include `:focus` + # # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + # config.filter_run_when_matching :focus + # + # # Allows RSpec to persist some state between runs in order to support + # # the `--only-failures` and `--next-failure` CLI options. We recommend + # # you configure your source control system to ignore this file. + # config.example_status_persistence_file_path = "spec/examples.txt" + # + # # Limits the available syntax to the non-monkey patched syntax that is + # # recommended. For more details, see: + # # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ + # # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode + # config.disable_monkey_patching! + # + # # Many RSpec users commonly either run the entire suite or an individual + # # file, and it's useful to allow more verbose output when running an + # # individual spec file. + # if config.files_to_run.one? + # # Use the documentation formatter for detailed output, + # # unless a formatter has already been configured + # # (e.g. via a command-line flag). + # config.default_formatter = "doc" + # end + # + # # Print the 10 slowest examples and example groups at the + # # end of the spec run, to help surface which specs are running + # # particularly slow. + # config.profile_examples = 10 + # + # # Run specs in random order to surface order dependencies. If you find an + # # order dependency and want to debug it, you can fix the order by providing + # # the seed, which is printed after each run. + # # --seed 1234 + # config.order = :random + # + # # Seed global randomization in this process using the `--seed` CLI option. + # # Setting this allows you to use `--seed` to deterministically reproduce + # # test failures related to randomization by passing the same `--seed` value + # # as the one that triggered the failure. + # Kernel.srand config.seed end -def stub_alma_get_request(url:, body: "{}",status: 200, query: {}) - stub_request(:get, "#{ENV["ALMA_API_HOST"]}/almaws/v1/#{url}").with( - headers: { - accept: 'application/json', - Authorization: "apikey #{ENV['ALMA_API_KEY']}", - 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - 'User-Agent'=>'Ruby' - }, - query: query, - ).to_return(body: body, status: status, headers: {content_type: 'application/json'}) +def stub_alma_get_request(url:, body: "{}", status: 200, query: {}) + stub_request(:get, "#{ENV["ALMA_API_HOST"]}/almaws/v1/#{url}").with( + headers: { + :accept => "application/json", + :Authorization => "apikey #{ENV["ALMA_API_KEY"]}", + "Accept-Encoding" => "gzip;q=1.0,deflate;q=0.6,identity;q=0.3", + "User-Agent" => "Ruby" + }, + query: query + ).to_return(body: body, status: status, headers: {content_type: "application/json"}) end diff --git a/spec/support/factories.rb b/spec/support/factories.rb index 8da2f53..6c8baa5 100644 --- a/spec/support/factories.rb +++ b/spec/support/factories.rb @@ -6,20 +6,19 @@ uniqname { Faker::Internet.username(specifier: 3..8, separators: []) } end factory :loan do - association :user, strategy: :build + association :user, strategy: :build id { Faker::Number.number(digits: 16) } title { Faker::Book.title } author { Faker::Book.author } mms_id { "99#{Faker::Number.number(digits: 12)}6000" } - before(:create) do |loan| + before(:create) do |loan| if loan.checkout_date.nil? loan.return_date = Faker::Date.backward(days: 365) - loan.checkout_date = Faker::Date.between(from: loan.return_date - 180.days, - to: loan.return_date) + loan.checkout_date = Faker::Date.between(from: loan.return_date - 180.days, + to: loan.return_date) elsif loan.return_date.nil? loan.return_date = Faker::Date.between(from: loan.checkout_date, to: DateTime.now) end - end end end diff --git a/spec/support/request_spec_helpers.rb b/spec/support/request_spec_helpers.rb index 843aac3..4c4ec23 100644 --- a/spec/support/request_spec_helpers.rb +++ b/spec/support/request_spec_helpers.rb @@ -2,14 +2,16 @@ module RequestSpecHelpers def authorize create(:auth_token) end + def get(path, **args) token = AuthToken&.first&.token - args[:headers] ||= {"Authorization" =>"apikey #{token}"} if token + args[:headers] ||= {"Authorization" => "apikey #{token}"} if token super end + def put(path, **args) token = AuthToken&.first&.token - args[:headers] ||= {"Authorization" =>"apikey #{token}"} if token + args[:headers] ||= {"Authorization" => "apikey #{token}"} if token super end end diff --git a/spec/tasks/alma_circ_history_task_spec.rb b/spec/tasks/alma_circ_history_task_spec.rb index eaf4b29..f991f12 100644 --- a/spec/tasks/alma_circ_history_task_spec.rb +++ b/spec/tasks/alma_circ_history_task_spec.rb @@ -1,29 +1,29 @@ -require 'rails_helper' +require "rails_helper" describe "alma_circ_history:load_history" do before(:each) do stub_request(:post, ENV["SLACK_URL"]) stub_request(:get, ENV["PUSHMON_URL"]) - @stub = stub_alma_get_request(url: 'analytics/reports', - query: {path: ENV.fetch('CIRC_REPORT_PATH'), col_names: true, limit: 1000}, - body: File.read('./spec/fixtures/circ_history.json') ) + @stub = stub_alma_get_request(url: "analytics/reports", + query: {path: ENV.fetch("CIRC_REPORT_PATH"), col_names: true, limit: 1000}, + body: File.read("./spec/fixtures/circ_history.json")) end after(:each) do Rake::Task["alma_circ_history:load"].reenable end - let(:user_ajones) { create(:user, uniqname: 'ajones', retain_history: true) } - let(:user_emcard) { create(:user, uniqname: 'emcard', retain_history: true) } - let(:load_circ_history){ Rake::Task["alma_circ_history:load"].invoke } + let(:user_ajones) { create(:user, uniqname: "ajones", retain_history: true) } + let(:user_emcard) { create(:user, uniqname: "emcard", retain_history: true) } + let(:load_circ_history) { Rake::Task["alma_circ_history:load"].invoke } it "calls alma for latest circ history report" do load_circ_history expect(@stub).to have_been_requested.times(1) end - it "logs an error if it can't load the report" do - @stub.to_return(body: File.read('./spec/fixtures/alma_error.json'), status: 500, headers: {content_type: 'application/json'}) - @stub.response #clear out original response - expect(Rails.logger).to receive(:error).with('Alma Report Failed to Load') + it "logs an error if it can't load the report" do + @stub.to_return(body: File.read("./spec/fixtures/alma_error.json"), status: 500, headers: {content_type: "application/json"}) + @stub.response # clear out original response + expect(Rails.logger).to receive(:error).with("Alma Report Failed to Load") load_circ_history end it "loads new circ history into the db and downcases uniqnames" do @@ -36,11 +36,11 @@ it "skips over already loaded history" do user_ajones user_emcard - loan = create(:loan, id: '3159980960006381', title: 'my_title') + loan = create(:loan, id: "3159980960006381", title: "my_title") expect(Loan.all.count).to eq(1) load_circ_history expect(Loan.all.count).to eq(2) - expect(Loan.find(loan.id).title).to eq('my_title') + expect(Loan.find(loan.id).title).to eq("my_title") end it "it adds user if they don't exist" do @@ -63,75 +63,74 @@ it "handles giant title" do user_ajones user_emcard - loans = File.read('./spec/fixtures/circ_history.json') - super_long_title = 'a'*1000 - loans.gsub!('Between the world and me',super_long_title) - @stub.to_return(body: loans, headers: {content_type: 'application/json'}) - @stub.response #clear out original response + loans = File.read("./spec/fixtures/circ_history.json") + super_long_title = "a" * 1000 + loans.gsub!("Between the world and me", super_long_title) + @stub.to_return(body: loans, headers: {content_type: "application/json"}) + @stub.response # clear out original response load_circ_history expect(Loan.all.count).to eq(2) end it "handles giant author" do user_ajones user_emcard - loans = File.read('./spec/fixtures/circ_history.json') - super_long_author = 'a'*1000 - loans.gsub!('Caldwell, John, 1938-',super_long_author) - @stub.to_return(body: loans, headers: {content_type: 'application/json'}) - @stub.response #clear out original response + loans = File.read("./spec/fixtures/circ_history.json") + super_long_author = "a" * 1000 + loans.gsub!("Caldwell, John, 1938-", super_long_author) + @stub.to_return(body: loans, headers: {content_type: "application/json"}) + @stub.response # clear out original response load_circ_history expect(Loan.all.count).to eq(2) end it "handles nil author" do user_ajones user_emcard - loans = File.read('./spec/fixtures/circ_history.json') - loans.gsub!('Caldwell, John, 1938-\n','') - @stub.to_return(body: loans, headers: {content_type: 'application/json'}) - @stub.response #clear out original response + loans = File.read("./spec/fixtures/circ_history.json") + loans.gsub!('Caldwell, John, 1938-\n', "") + @stub.to_return(body: loans, headers: {content_type: "application/json"}) + @stub.response # clear out original response load_circ_history expect(Loan.all.count).to eq(2) end it "handles nil title" do user_ajones user_emcard - loans = File.read('./spec/fixtures/circ_history.json') - loans.gsub!('Between the world and me /\n','') - @stub.to_return(body: loans, headers: {content_type: 'application/json'}) - @stub.response #clear out original response + loans = File.read("./spec/fixtures/circ_history.json") + loans.gsub!('Between the world and me /\n', "") + @stub.to_return(body: loans, headers: {content_type: "application/json"}) + @stub.response # clear out original response load_circ_history expect(Loan.all.count).to eq(2) end - end describe "alma_circ_history:purge" do before(:each) do - @stub = stub_alma_get_request(url: 'analytics/reports', - query: {path: ENV.fetch('PATRON_REPORT_PATH'), col_names: true, limit: 1000}, - body: File.read('./spec/fixtures/non_expired_patrons.json') ) + @stub = stub_alma_get_request(url: "analytics/reports", + query: {path: ENV.fetch("PATRON_REPORT_PATH"), col_names: true, limit: 1000}, + body: File.read("./spec/fixtures/non_expired_patrons.json")) end after(:each) do Rake::Task["alma_circ_history:purge"].reenable end - let(:user_ajones) { create(:user, uniqname: 'ajones', retain_history: true) } - let(:user_emcard) { create(:user, uniqname: 'emcard', retain_history: true) } - let(:purge_users){ Rake::Task["alma_circ_history:purge"].invoke } - it "purges users not in the report" do + let(:user_ajones) { create(:user, uniqname: "ajones", retain_history: true) } + let(:user_emcard) { create(:user, uniqname: "emcard", retain_history: true) } + let(:purge_users) { Rake::Task["alma_circ_history:purge"].invoke } + it "purges users not in the report" do emcard = user_emcard ajones = user_ajones create(:loan, user: emcard) create(:loan, user: ajones) expect(Loan.count).to eq(2) expect(User.count).to eq(2) - purge_users #Report only has user with uniqname: 'EMCARD' + purge_users # Report only has user with uniqname: 'EMCARD' expect(Loan.count).to eq(1) - expect(Loan.first.user_uniqname).to eq('emcard') - expect(User.first.uniqname).to eq('emcard') + expect(Loan.first.user_uniqname).to eq("emcard") + expect(User.first.uniqname).to eq("emcard") end - it "logs an error if it can't load the report" do - @stub.to_return(body: File.read('./spec/fixtures/alma_error.json'), status: 500, headers: {content_type: 'application/json'}) - @stub.response #clear out original response - expect(Rails.logger).to receive(:error).with('Alma Report Failed to Load') + it "logs an error if it can't load the report" do + @stub.to_return(body: File.read("./spec/fixtures/alma_error.json"), status: 500, headers: {content_type: "application/json"}) + @stub.response # clear out original response + expect(Rails.logger).to receive(:error).with("Alma Report Failed to Load") purge_users end end diff --git a/spec/tasks/token_task_spec.rb b/spec/tasks/token_task_spec.rb index d722db9..48d0d5d 100644 --- a/spec/tasks/token_task_spec.rb +++ b/spec/tasks/token_task_spec.rb @@ -1,10 +1,10 @@ -require 'rails_helper' +require "rails_helper" describe "token:generate" do after(:each) do Rake::Task["token:generate"].reenable end subject do - Rake::Task["token:generate"].invoke('app_name') + Rake::Task["token:generate"].invoke("app_name") end it "creates a new token" do expect(AuthToken.all.count).to eq(0) @@ -12,15 +12,15 @@ expect(AuthToken.all.count).to eq(1) end it "displays the new token" do - expect{subject}.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout + expect { subject }.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout end it "has name that's given as parameter" do subject - expect(AuthToken.first.name).to eq('app_name') + expect(AuthToken.first.name).to eq("app_name") end it "prints error if unable to save" do - create(:auth_token, name: 'app_name') - expect{subject}.to output("Errors: Name has already been taken\n").to_stdout + create(:auth_token, name: "app_name") + expect { subject }.to output("Errors: Name has already been taken\n").to_stdout end end describe "token:regenerate" do @@ -28,10 +28,10 @@ Rake::Task["token:regenerate"].reenable end before(:each) do - create(:auth_token, name: 'app_name') + create(:auth_token, name: "app_name") end subject do - Rake::Task["token:regenerate"].invoke('app_name') + Rake::Task["token:regenerate"].invoke("app_name") end it "creates a new token" do old_token = AuthToken.first.token @@ -39,18 +39,18 @@ expect(AuthToken.first.token).not_to eq(old_token) end it "displays a token" do - expect{subject}.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout + expect { subject }.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout end it "does not display the old token" do old_token = AuthToken.first.token - expect{subject}.not_to output("token: #{old_token} for app: app_name").to_stdout + expect { subject }.not_to output("token: #{old_token} for app: app_name").to_stdout end it "has name that's given as parameter" do subject - expect(AuthToken.first.name).to eq('app_name') + expect(AuthToken.first.name).to eq("app_name") end it "prints error if app name doesn't exist" do - expect{Rake::Task["token:regenerate"].invoke('non_existent_app')}.to output("Error: app: 'non_existent_app' does not exist\n").to_stdout + expect { Rake::Task["token:regenerate"].invoke("non_existent_app") }.to output("Error: app: 'non_existent_app' does not exist\n").to_stdout end end describe "token:get" do @@ -58,13 +58,13 @@ Rake::Task["token:get"].reenable end subject do - Rake::Task["token:get"].invoke('app_name') + Rake::Task["token:get"].invoke("app_name") end it "prints token if token app exists" do - create(:auth_token, name: 'app_name') - expect{subject}.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout + create(:auth_token, name: "app_name") + expect { subject }.to output(/token: [[:alnum:]]{36} for app: app_name/).to_stdout end - it "prints error if app doesn't exist" do - expect{subject}.to output("Error: app: 'app_name' does not exist\n").to_stdout + it "prints error if app doesn't exist" do + expect { subject }.to output("Error: app: 'app_name' does not exist\n").to_stdout end end From 01c3dd201c522e9fdc096f5e38faf858ab18306f Mon Sep 17 00:00:00 2001 From: Monique Rio Date: Mon, 4 Apr 2022 16:59:17 -0400 Subject: [PATCH 8/8] more standrb fixes --- .github/workflows/tests.yml | 2 ++ app/controllers/v1/users_controller.rb | 3 +-- app/views/v1/errors/no_user.json | 1 - app/views/v1/errors/update_failed.json.jbuilder | 1 + config/puma.rb | 4 ++-- spec/requests/user_spec.rb | 6 +++--- 6 files changed, 9 insertions(+), 8 deletions(-) delete mode 100644 app/views/v1/errors/no_user.json create mode 100644 app/views/v1/errors/update_failed.json.jbuilder diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5b76f89..fe2980b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,5 +43,7 @@ jobs: done - name: Set up DB run: bundle exec rails db:schema:load RAILS_ENV=test + - name: Run linter for Ruby + run: bundle exec standardrb - name: Run tests run: bundle exec rspec diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index b7834cb..12ffffe 100644 --- a/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -4,7 +4,6 @@ def show @user = User.find(params[:uniqname]) rescue render template: "v1/errors/no_user", status: :bad_request - else end def update @@ -12,7 +11,7 @@ def update if @user.update(retain_history: params[:retain_history]) redirect_to action: "show", uniqname: @user.uniqname else - # error? + render template: "v1/errors/update_failed", status: :bad_request end end end diff --git a/app/views/v1/errors/no_user.json b/app/views/v1/errors/no_user.json deleted file mode 100644 index 8b13789..0000000 --- a/app/views/v1/errors/no_user.json +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/views/v1/errors/update_failed.json.jbuilder b/app/views/v1/errors/update_failed.json.jbuilder new file mode 100644 index 0000000..de4b71d --- /dev/null +++ b/app/views/v1/errors/update_failed.json.jbuilder @@ -0,0 +1 @@ +json.error "User unable to be updated" diff --git a/config/puma.rb b/config/puma.rb index d9b3e83..fa40ee6 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -4,7 +4,7 @@ # 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 } +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 @@ -15,7 +15,7 @@ # Specifies the `port` that Puma will listen on to receive requests; default is 3000. # -port ENV.fetch("PORT") { 3000 } +port ENV.fetch("PORT", 3000) # Specifies the `environment` that Puma will run in. # diff --git a/spec/requests/user_spec.rb b/spec/requests/user_spec.rb index d6f692a..c492603 100644 --- a/spec/requests/user_spec.rb +++ b/spec/requests/user_spec.rb @@ -47,7 +47,7 @@ it "handles sorting" do @loan1.update(title: "ZZZZ") @loan2.update(title: "AAAA") - loan3 = create(:loan, user: @user, title: "BBBB") + create(:loan, user: @user, title: "BBBB") get "/v1/users/#{@user.uniqname}/loans", params: {order_by: "title"} loans = JSON.parse(response.body)["loans"] expect(loans[0]["title"]).to eq("AAAA") @@ -114,7 +114,7 @@ end it "changes a patron's loan retention status and confirmation status and deletes existing loans; returns updated user" do user = create(:user, retain_history: true, confirmed: false) - loan = create(:loan, user: user) + create(:loan, user: user) put "/v1/users/#{user.uniqname}", params: {retain_history: false} expect(response).to redirect_to("/v1/users/#{user.uniqname}") updated_user = User.first @@ -134,7 +134,7 @@ context "unauthorized" do it "returns unauthorized" do user = create(:user, retain_history: true, confirmed: false) - loan = create(:loan, user: user) + create(:loan, user: user) put "/v1/users/#{user.uniqname}", params: {retain_history: false} expect(response).to have_http_status(:unauthorized) end