From 9a178c347fba207275e4cc60939983374f56901f Mon Sep 17 00:00:00 2001 From: Jeremy Prevost Date: Thu, 19 Oct 2023 14:23:22 -0400 Subject: [PATCH 1/3] Cleanup gemfile - reorder and change quotes mostly --- Gemfile | 58 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/Gemfile b/Gemfile index 83be901..e548314 100644 --- a/Gemfile +++ b/Gemfile @@ -1,30 +1,40 @@ -source "https://rubygems.org" +source 'https://rubygems.org' +ruby '3.2.2' -ruby "3.2.2" +git_source(:github) do |repo_name| + repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/') + "https://github.com/#{repo_name}.git" +end -# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.1.1" +# Reduces boot times through caching; required in config/boot.rb +gem 'bootsnap', require: false -# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] -gem "sprockets-rails" +# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] +gem 'importmap-rails' -# Use sqlite3 as the database for Active Record -gem "sqlite3", "~> 1.4" +# Build JSON APIs with ease [https://github.com/rails/jbuilder] +gem 'jbuilder' # Use the Puma web server [https://github.com/puma/puma] -gem "puma", ">= 5.0" +gem 'puma', '>= 5.0' -# Use JavaScript with ESM import maps [https://github.com/rails/importmap-rails] -gem "importmap-rails" +# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" +gem 'rails', '~> 7.1.1' + +# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] +gem 'sprockets-rails' + +# Use sqlite3 as the database for Active Record +gem 'sqlite3', '~> 1.4' # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] -gem "turbo-rails" +gem 'turbo-rails' # Hotwire's modest JavaScript framework [https://stimulus.hotwired.dev] -gem "stimulus-rails" +gem 'stimulus-rails' -# Build JSON APIs with ease [https://github.com/rails/jbuilder] -gem "jbuilder" +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: %i[windows jruby] # Use Redis adapter to run Action Cable in production # gem "redis", ">= 4.0.1" @@ -35,34 +45,24 @@ gem "jbuilder" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem "tzinfo-data", platforms: %i[ windows jruby ] - -# Reduces boot times through caching; required in config/boot.rb -gem "bootsnap", require: false - # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem - gem "debug", platforms: %i[ mri windows ] + gem 'debug', platforms: %i[mri windows] end group :development do # Use console on exceptions pages [https://github.com/rails/web-console] - gem "web-console" + gem 'web-console' # Add speed badges [https://github.com/MiniProfiler/rack-mini-profiler] # gem "rack-mini-profiler" - - # Speed up commands on slow machines / big apps [https://github.com/rails/spring] - # gem "spring" - end group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] - gem "capybara" - gem "selenium-webdriver" + gem 'capybara' + gem 'selenium-webdriver' end From 79930c243076222a3751a7f112cb2aacd509fa18 Mon Sep 17 00:00:00 2001 From: Jeremy Prevost Date: Thu, 19 Oct 2023 17:17:57 -0400 Subject: [PATCH 2/3] Adds SearchEvent and Term models Why are these changes being introduced: * this implements the first two models and will enable the storage of the data necessary to get started with this application Relevant ticket(s): * https://mitlibraries.atlassian.net/browse/ENGX-232 https://mitlibraries.atlassian.net/browse/ENGX-233 How does this address that need: * Rails Document any side effects to this change: - some of our typical developer gems, rubocop and annotate were added - rubocop was used to autoformat everything in the `/app` and `test` directories --- Gemfile | 8 +++ Gemfile.lock | 37 ++++++++++++ app/models/application_record.rb | 2 + app/models/search_event.rb | 17 ++++++ app/models/term.rb | 14 +++++ db/migrate/20231019183700_create_terms.rb | 9 +++ .../20231019191933_create_search_events.rb | 11 ++++ db/schema.rb | 30 ++++++++++ test/application_system_test_case.rb | 4 +- .../application_cable/connection_test.rb | 4 +- test/fixtures/search_events.yml | 17 ++++++ test/fixtures/terms.yml | 15 +++++ test/models/search_event_test.rb | 31 ++++++++++ test/models/term_test.rb | 57 +++++++++++++++++++ test/test_helper.rb | 8 ++- 15 files changed, 259 insertions(+), 5 deletions(-) create mode 100644 app/models/search_event.rb create mode 100644 app/models/term.rb create mode 100644 db/migrate/20231019183700_create_terms.rb create mode 100644 db/migrate/20231019191933_create_search_events.rb create mode 100644 db/schema.rb create mode 100644 test/fixtures/search_events.yml create mode 100644 test/fixtures/terms.yml create mode 100644 test/models/search_event_test.rb create mode 100644 test/models/term_test.rb diff --git a/Gemfile b/Gemfile index e548314..d01b55a 100644 --- a/Gemfile +++ b/Gemfile @@ -54,6 +54,14 @@ group :development, :test do end group :development do + # Add annotations to model, test, fixtures when run + gem 'annotate' + + # RuboCop is a Ruby static code analyzer (a.k.a. linter) and code formatter. + gem 'rubocop' + gem 'rubocop-capybara' + gem 'rubocop-rails' + # Use console on exceptions pages [https://github.com/rails/web-console] gem 'web-console' diff --git a/Gemfile.lock b/Gemfile.lock index 5ae8699..d6e2c2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,6 +76,10 @@ GEM tzinfo (~> 2.0) addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) + annotate (3.2.0) + activerecord (>= 3.2, < 8.0) + rake (>= 10.4, < 14.0) + ast (2.4.2) base64 (0.1.1) bigdecimal (3.1.4) bindex (0.8.1) @@ -115,6 +119,8 @@ GEM jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) + json (2.6.3) + language_server-protocol (3.17.0.3) loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) @@ -145,6 +151,10 @@ GEM racc (~> 1.4) nokogiri (1.15.4-x86_64-linux) racc (~> 1.4) + parallel (1.23.0) + parser (3.2.2.4) + ast (~> 2.4.1) + racc psych (5.1.1) stringio public_suffix (5.0.3) @@ -188,6 +198,7 @@ GEM rake (>= 12.2) thor (~> 1.0, >= 1.2.2) zeitwerk (~> 2.6) + rainbow (3.1.1) rake (13.0.6) rdoc (6.5.0) psych (>= 4.0.0) @@ -195,6 +206,27 @@ GEM reline (0.3.9) io-console (~> 0.5) rexml (3.2.6) + rubocop (1.57.1) + base64 (~> 0.1.1) + json (~> 2.3) + language_server-protocol (>= 3.17.0) + parallel (~> 1.10) + parser (>= 3.2.2.4) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + rubocop-capybara (2.19.0) + rubocop (~> 1.41) + rubocop-rails (2.21.2) + activesupport (>= 4.2.0) + rack (>= 1.1) + rubocop (>= 1.33.0, < 2.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) rubyzip (2.3.2) selenium-webdriver (4.14.0) @@ -222,6 +254,7 @@ GEM railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) + unicode-display_width (2.5.0) web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -242,6 +275,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + annotate bootsnap capybara debug @@ -249,6 +283,9 @@ DEPENDENCIES jbuilder puma (>= 5.0) rails (~> 7.1.1) + rubocop + rubocop-capybara + rubocop-rails selenium-webdriver sprockets-rails sqlite3 (~> 1.4) diff --git a/app/models/application_record.rb b/app/models/application_record.rb index b63caeb..08dc537 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class ApplicationRecord < ActiveRecord::Base primary_abstract_class end diff --git a/app/models/search_event.rb b/app/models/search_event.rb new file mode 100644 index 0000000..46cae56 --- /dev/null +++ b/app/models/search_event.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: search_events +# +# id :integer not null, primary key +# term_id :integer +# source :string +# created_at :datetime not null +# updated_at :datetime not null +# +class SearchEvent < ApplicationRecord + belongs_to :term + + validates :source, presence: true +end diff --git a/app/models/term.rb b/app/models/term.rb new file mode 100644 index 0000000..ce759d4 --- /dev/null +++ b/app/models/term.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: terms +# +# id :integer not null, primary key +# phrase :string +# created_at :datetime not null +# updated_at :datetime not null +# +class Term < ApplicationRecord + has_many :search_events, dependent: :destroy +end diff --git a/db/migrate/20231019183700_create_terms.rb b/db/migrate/20231019183700_create_terms.rb new file mode 100644 index 0000000..1f32d3d --- /dev/null +++ b/db/migrate/20231019183700_create_terms.rb @@ -0,0 +1,9 @@ +class CreateTerms < ActiveRecord::Migration[7.1] + def change + create_table :terms do |t| + t.string :phrase, index: { unique: true, name: 'unique_phrase' } + t.timestamps + end + + end +end diff --git a/db/migrate/20231019191933_create_search_events.rb b/db/migrate/20231019191933_create_search_events.rb new file mode 100644 index 0000000..3c44f57 --- /dev/null +++ b/db/migrate/20231019191933_create_search_events.rb @@ -0,0 +1,11 @@ +class CreateSearchEvents < ActiveRecord::Migration[7.1] + def change + create_table :search_events do |t| + t.belongs_to :term + t.string :source + t.timestamps + end + + add_index :search_events, :source + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..2ac49e5 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,30 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[7.1].define(version: 2023_10_19_191933) do + create_table "search_events", force: :cascade do |t| + t.integer "term_id" + t.string "source" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["source"], name: "index_search_events_on_source" + t.index ["term_id"], name: "index_search_events_on_term_id" + end + + create_table "terms", force: :cascade do |t| + t.string "phrase" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["phrase"], name: "unique_phrase", unique: true + end + +end diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index d19212a..652febb 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class ApplicationSystemTestCase < ActionDispatch::SystemTestCase driven_by :selenium, using: :chrome, screen_size: [1400, 1400] diff --git a/test/channels/application_cable/connection_test.rb b/test/channels/application_cable/connection_test.rb index 6340bf9..4aee9b3 100644 --- a/test/channels/application_cable/connection_test.rb +++ b/test/channels/application_cable/connection_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' module ApplicationCable class ConnectionTest < ActionCable::Connection::TestCase diff --git a/test/fixtures/search_events.yml b/test/fixtures/search_events.yml new file mode 100644 index 0000000..eb48a8b --- /dev/null +++ b/test/fixtures/search_events.yml @@ -0,0 +1,17 @@ +# == Schema Information +# +# Table name: search_events +# +# id :integer not null, primary key +# term_id :integer +# source :string +# created_at :datetime not null +# updated_at :datetime not null +# + +timdex_cool: + term: cool + source: timdex +bento_hi: + term: hi + source: bento diff --git a/test/fixtures/terms.yml b/test/fixtures/terms.yml new file mode 100644 index 0000000..128b327 --- /dev/null +++ b/test/fixtures/terms.yml @@ -0,0 +1,15 @@ +# == Schema Information +# +# Table name: terms +# +# id :integer not null, primary key +# phrase :string +# created_at :datetime not null +# updated_at :datetime not null +# + +cool: + phrase: Super cool search + +hi: + phrase: hello world diff --git a/test/models/search_event_test.rb b/test/models/search_event_test.rb new file mode 100644 index 0000000..dd87810 --- /dev/null +++ b/test/models/search_event_test.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: search_events +# +# id :integer not null, primary key +# term_id :integer +# source :string +# created_at :datetime not null +# updated_at :datetime not null +# +require 'test_helper' + +class SearchEventTest < ActiveSupport::TestCase + test 'term is required' do + s = search_events('timdex_cool') + assert(s.valid?) + + s.term = nil + refute(s.valid?) + end + + test 'source is required' do + s = search_events('timdex_cool') + assert(s.valid?) + + s.source = nil + refute(s.valid?) + end +end diff --git a/test/models/term_test.rb b/test/models/term_test.rb new file mode 100644 index 0000000..dad33f7 --- /dev/null +++ b/test/models/term_test.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: terms +# +# id :integer not null, primary key +# phrase :string +# created_at :datetime not null +# updated_at :datetime not null +# +require 'test_helper' + +class TermTest < ActiveSupport::TestCase + test 'duplicate terms are not allowed' do + initial_count = Term.count + Term.create!(phrase: 'popcorn') + + post_create_count = Term.count + + assert_equal((initial_count + 1), post_create_count) + + assert_raises(ActiveRecord::RecordNotUnique) do + Term.create!(phrase: 'popcorn') + end + + post_duplicate_count = Term.count + + assert_equal(post_create_count, post_duplicate_count) + end + + test 'destroying a Term will delete associated SearchEvents' do + term_pre_count = Term.count + event_pre_count = SearchEvent.count + + term = terms('hi') + term.destroy + + assert_equal((term_pre_count - 1), Term.count) + assert(SearchEvent.count < event_pre_count) + end + + test 'destroying a SearchEvent does not delete the Term' do + t = terms('hi') + s = t.search_events.first + + events_count = t.search_events.count + + assert_equal(events_count, t.search_events.count) + + s.destroy + t.reload + + assert_equal(events_count - 1, t.search_events.count) + assert(t.valid?) + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 0c22470..0c92e8e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,8 @@ -ENV["RAILS_ENV"] ||= "test" -require_relative "../config/environment" -require "rails/test_help" +# frozen_string_literal: true + +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +require 'rails/test_help' module ActiveSupport class TestCase From f3eae91cd5f29e166126e6f16e2cb69edd4f22eb Mon Sep 17 00:00:00 2001 From: Jeremy Prevost Date: Thu, 19 Oct 2023 17:33:30 -0400 Subject: [PATCH 3/3] Add standard CI and weekly dependabot checks --- .github/dependabot.yml | 11 +++++++++++ .github/workflows/mit-libraries-ruby-ci.yml | 10 ++++++++++ .gitignore | 3 +++ Gemfile | 2 ++ Gemfile.lock | 10 ++++++++++ test/test_helper.rb | 10 ++++++++++ 6 files changed, 46 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/mit-libraries-ruby-ci.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..0b1d040 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "bundler" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/mit-libraries-ruby-ci.yml b/.github/workflows/mit-libraries-ruby-ci.yml new file mode 100644 index 0000000..64996bc --- /dev/null +++ b/.github/workflows/mit-libraries-ruby-ci.yml @@ -0,0 +1,10 @@ +name: CI +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + shared: + uses: mitlibraries/.github/.github/workflows/ruby-shared-ci.yml@main diff --git a/.gitignore b/.gitignore index 5fb66c9..d3d889c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ # Ignore master key for decrypting credentials and more. /config/master.key + +# Ignore simplecov generated files +/coverage diff --git a/Gemfile b/Gemfile index d01b55a..bd95672 100644 --- a/Gemfile +++ b/Gemfile @@ -73,4 +73,6 @@ group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] gem 'capybara' gem 'selenium-webdriver' + gem 'simplecov' + gem 'simplecov-lcov' end diff --git a/Gemfile.lock b/Gemfile.lock index d6e2c2a..caba324 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -102,6 +102,7 @@ GEM debug (1.8.0) irb (>= 1.5.0) reline (>= 0.3.1) + docile (1.4.0) drb (2.1.1) ruby2_keywords erubi (1.12.0) @@ -233,6 +234,13 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + simplecov (0.22.0) + docile (~> 1.1) + simplecov-html (~> 0.11) + simplecov_json_formatter (~> 0.1) + simplecov-html (0.12.3) + simplecov-lcov (0.8.0) + simplecov_json_formatter (0.1.4) sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -287,6 +295,8 @@ DEPENDENCIES rubocop-capybara rubocop-rails selenium-webdriver + simplecov + simplecov-lcov sprockets-rails sqlite3 (~> 1.4) stimulus-rails diff --git a/test/test_helper.rb b/test/test_helper.rb index 0c92e8e..f027a8f 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,5 +1,15 @@ # frozen_string_literal: true +require 'simplecov' +require 'simplecov-lcov' +SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true +SimpleCov::Formatter::LcovFormatter.config.lcov_file_name = 'coverage.lcov' +SimpleCov.formatters = [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter +] +SimpleCov.start('rails') + ENV['RAILS_ENV'] ||= 'test' require_relative '../config/environment' require 'rails/test_help'