From e8acb37a680574098bf463a5f2aee39d8c988b3f Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Mon, 15 Apr 2024 22:17:22 +0300 Subject: [PATCH 01/11] Update Setup of the rails_admin gem in the project accessed through /admin route --- Gemfile | 3 +++ Gemfile.lock | 34 ++++++++++++++++++++++++ config/initializers/rails_admin.rb | 42 ++++++++++++++++++++++++++++++ config/routes.rb | 1 + 4 files changed, 80 insertions(+) create mode 100644 config/initializers/rails_admin.rb diff --git a/Gemfile b/Gemfile index ce35e710..d9653d8a 100644 --- a/Gemfile +++ b/Gemfile @@ -70,3 +70,6 @@ group :test do gem 'simplecov', require: false # Code coverage analysis tool for ruby gem 'webdrivers' end + +gem "rails_admin", "~> 3.1" +gem "sassc-rails" diff --git a/Gemfile.lock b/Gemfile.lock index cd1df74a..6733f768 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -56,6 +56,10 @@ GEM globalid (>= 0.3.6) activemodel (7.0.3) activesupport (= 7.0.3) + activemodel-serializers-xml (1.0.2) + activemodel (> 5.x) + activesupport (> 5.x) + builder (~> 3.1) activerecord (7.0.3) activemodel (= 7.0.3) activesupport (= 7.0.3) @@ -180,6 +184,18 @@ GEM jsbundling-rails (1.0.2) railties (>= 6.0.0) json (2.6.3) + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) launchy (2.5.0) addressable (~> 2.7) letter_opener (1.8.1) @@ -202,6 +218,7 @@ GEM fugit (~> 1.0) rails (>= 5.2) msgpack (1.5.2) + nested_form (0.3.2) net-imap (0.2.3) digest net-protocol @@ -266,6 +283,12 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.4.2) loofah (~> 2.3) + rails_admin (3.1.2) + activemodel-serializers-xml (>= 1.0) + kaminari (>= 0.14, < 2.0) + nested_form (~> 0.3) + rails (>= 6.0, < 8) + turbo-rails (~> 1.0) railties (7.0.3) actionpack (= 7.0.3) activesupport (= 7.0.3) @@ -307,6 +330,14 @@ GEM ffi (~> 1.12) ruby_http_client (3.5.5) rubyzip (2.3.2) + sassc (2.4.0) + ffi (~> 1.9) + sassc-rails (2.1.2) + railties (>= 4.0.0) + sassc (>= 2.0) + sprockets (> 3.0) + sprockets-rails + tilt selenium-webdriver (4.2.0) childprocess (>= 0.5, < 5.0) rexml (~> 3.2, >= 3.2.5) @@ -346,6 +377,7 @@ GEM railties (>= 6.0.0) strscan (3.0.3) thor (1.2.1) + tilt (2.3.0) timeout (0.3.0) turbo-rails (1.1.1) actionpack (>= 6.0.0) @@ -406,10 +438,12 @@ DEPENDENCIES premailer-rails (~> 1.12) puma (~> 5.0) rails (~> 7.0.3) + rails_admin (~> 3.1) redis (~> 4.0) rubocop (~> 1.51.0) rubocop-performance (~> 1.18) rubocop-rails (~> 2.19.1) + sassc-rails selenium-webdriver sendgrid-actionmailer (~> 3.2) simple_form (~> 5.1) diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb new file mode 100644 index 00000000..c6d97926 --- /dev/null +++ b/config/initializers/rails_admin.rb @@ -0,0 +1,42 @@ +RailsAdmin.config do |config| + config.asset_source = :sprockets + + ### Popular gems integration + + ## == Devise == + # config.authenticate_with do + # warden.authenticate! scope: :user + # end + # config.current_user_method(&:current_user) + + ## == CancanCan == + # config.authorize_with :cancancan + + ## == Pundit == + # config.authorize_with :pundit + + ## == PaperTrail == + # config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0 + + ### More at https://github.com/railsadminteam/rails_admin/wiki/Base-configuration + + ## == Gravatar integration == + ## To disable Gravatar integration in Navigation Bar set to false + # config.show_gravatar = true + + config.actions do + dashboard # mandatory + index # mandatory + new + export + bulk_delete + show + edit + delete + show_in_app + + ## With an audit adapter, you can add: + # history_index + # history_show + end +end diff --git a/config/routes.rb b/config/routes.rb index 0a04f5e9..2b9a737d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true Rails.application.routes.draw do + mount RailsAdmin::Engine => '/admin', as: 'rails_admin' authenticate :user do mount Motor::Admin => '/admin' end From 8717427ef13f1c95753382fcc4414689c42d4991 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Tue, 16 Apr 2024 12:08:13 +0300 Subject: [PATCH 02/11] Update include: - Create the learning materials resource - Migrate the learning materials resource to update the schema file --- .../20240416055500_create_learning_materials.rb | 14 ++++++++++++++ db/schema.rb | 15 ++++++++++++++- .../learning_materials_controller_test.rb | 7 +++++++ test/fixtures/learning_materials.yml | 17 +++++++++++++++++ test/models/learning_material_test.rb | 7 +++++++ 5 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20240416055500_create_learning_materials.rb create mode 100644 test/controllers/learning_materials_controller_test.rb create mode 100644 test/fixtures/learning_materials.yml create mode 100644 test/models/learning_material_test.rb diff --git a/db/migrate/20240416055500_create_learning_materials.rb b/db/migrate/20240416055500_create_learning_materials.rb new file mode 100644 index 00000000..2d2c8054 --- /dev/null +++ b/db/migrate/20240416055500_create_learning_materials.rb @@ -0,0 +1,14 @@ +class CreateLearningMaterials < ActiveRecord::Migration[7.0] + def change + create_table :learning_materials do |t| + t.references :user, null: false, foreign_key: true + t.string :thumbnail + t.integer :tag + t.string :learning_material_title + t.text :learning_material_description + t.string :learning_material_link + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 0f6705eb..d014ce41 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_05_31_154135) do +ActiveRecord::Schema[7.0].define(version: 2024_04_16_055500) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -67,6 +67,18 @@ t.datetime "updated_at", null: false end + create_table "learning_materials", force: :cascade do |t| + t.bigint "user_id", null: false + t.string "thumbnail" + t.integer "tag" + t.string "learning_material_title" + t.text "learning_material_description" + t.string "learning_material_link" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_learning_materials_on_user_id" + end + create_table "motor_alert_locks", force: :cascade do |t| t.bigint "alert_id", null: false t.string "lock_timestamp", null: false @@ -313,6 +325,7 @@ add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "learning_materials", "users" add_foreign_key "motor_alert_locks", "motor_alerts", column: "alert_id" add_foreign_key "motor_alerts", "motor_queries", column: "query_id" add_foreign_key "motor_note_tag_tags", "motor_note_tags", column: "tag_id" diff --git a/test/controllers/learning_materials_controller_test.rb b/test/controllers/learning_materials_controller_test.rb new file mode 100644 index 00000000..ab3652d9 --- /dev/null +++ b/test/controllers/learning_materials_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class LearningMaterialsControllerTest < ActionDispatch::IntegrationTest + # test "the truth" do + # assert true + # end +end diff --git a/test/fixtures/learning_materials.yml b/test/fixtures/learning_materials.yml new file mode 100644 index 00000000..15fcfff2 --- /dev/null +++ b/test/fixtures/learning_materials.yml @@ -0,0 +1,17 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + user: one + thumbnail: MyString + tag: 1 + learning_material_title: MyString + learning_material_description: MyText + learning_material_link: MyString + +two: + user: two + thumbnail: MyString + tag: 1 + learning_material_title: MyString + learning_material_description: MyText + learning_material_link: MyString diff --git a/test/models/learning_material_test.rb b/test/models/learning_material_test.rb new file mode 100644 index 00000000..b7c7b600 --- /dev/null +++ b/test/models/learning_material_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class LearningMaterialTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From a6d167f4f3fab2fb80672c695718abc88b3d23c2 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Tue, 16 Apr 2024 12:10:28 +0300 Subject: [PATCH 03/11] Update include: - Update routes with the admin route and the learning materials routes - Add associations between User and Learning materials models - Create Learning materials controller with index action --- app/controllers/learning_materials_controller.rb | 5 +++++ app/helpers/learning_materials_helper.rb | 2 ++ app/models/learning_material.rb | 8 ++++++++ app/models/user.rb | 1 + config/routes.rb | 1 + 5 files changed, 17 insertions(+) create mode 100644 app/controllers/learning_materials_controller.rb create mode 100644 app/helpers/learning_materials_helper.rb create mode 100644 app/models/learning_material.rb diff --git a/app/controllers/learning_materials_controller.rb b/app/controllers/learning_materials_controller.rb new file mode 100644 index 00000000..2cd749a9 --- /dev/null +++ b/app/controllers/learning_materials_controller.rb @@ -0,0 +1,5 @@ +class LearningMaterialsController < ApplicationController + def index + @learningmaterials = LearningMaterial.all + end +end diff --git a/app/helpers/learning_materials_helper.rb b/app/helpers/learning_materials_helper.rb new file mode 100644 index 00000000..d929ed10 --- /dev/null +++ b/app/helpers/learning_materials_helper.rb @@ -0,0 +1,2 @@ +module LearningMaterialsHelper +end diff --git a/app/models/learning_material.rb b/app/models/learning_material.rb new file mode 100644 index 00000000..c7eac92e --- /dev/null +++ b/app/models/learning_material.rb @@ -0,0 +1,8 @@ +class LearningMaterial < ApplicationRecord + # Associations + belongs_to :user + has_one_attached :thumbnail + + # Enum + enum tag: { beginners: 0, intermediates: 1, experts: 2 } +end diff --git a/app/models/user.rb b/app/models/user.rb index 614c5056..8d0333d0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,6 +10,7 @@ class User < ApplicationRecord # Associations has_many :users_chapters, dependent: :nullify has_many :chapters, through: :users_chapters + has_many :learning_materials # Callbacks before_create :set_defaults # Set model defaults before create diff --git a/config/routes.rb b/config/routes.rb index 2b9a737d..a7f917cd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,7 @@ resources :projects, only: %i[index show] resources :chapters, only: %i[index show] resources :countries, only: %i[index show] + resources :learning_materials, only: %i[index show] devise_for :users, controllers: { registrations: 'users/registrations' # Override devise registration controller } From 5a18fcc9ce12b9ac847e17fa0d355dee00069867 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Tue, 16 Apr 2024 13:10:27 +0300 Subject: [PATCH 04/11] Update include: - Add CSS variables to reduce the number of repetitions of color codes - Add the default thumbnail that will display when no image is uploaded when learning material is created - Create the learning materials index view listing all the currently available learning materials --- .../images/learningmaterialsthumbnail.jpeg | Bin 0 -> 8317 bytes app/assets/stylesheets/mailgun_mails.css | 39 +++++--- app/views/learning_materials/index.html.erb | 88 ++++++++++++++++++ 3 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 app/assets/images/learningmaterialsthumbnail.jpeg create mode 100644 app/views/learning_materials/index.html.erb diff --git a/app/assets/images/learningmaterialsthumbnail.jpeg b/app/assets/images/learningmaterialsthumbnail.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..a672a2f17aceacacbbdfb85b365cc0cead55e94a GIT binary patch literal 8317 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 literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/mailgun_mails.css b/app/assets/stylesheets/mailgun_mails.css index 11f9a3d5..c828fda3 100644 --- a/app/assets/stylesheets/mailgun_mails.css +++ b/app/assets/stylesheets/mailgun_mails.css @@ -9,6 +9,15 @@ font-size: 14px; } +/* Add CSS variable for repetitive colors */ + +:root { + --red: #D0021B; + --lightblue: #348eda; + --orange: #ff9f00; + --lightgreen: #68B90F; + } + img { max-width: 100%; } @@ -136,15 +145,15 @@ p li, ul li, ol li { LINKS & BUTTONS ------------------------------------- */ a { - color: #348eda; + color: var(--lightblue); text-decoration: underline; } .btn-primary { text-decoration: none; color: #FFF; - background-color: #348eda; - border: solid #348eda; + background-color: var(--lightblue); + border: solid var(--lightblue); border-width: 10px 20px; line-height: 2em; /* 2em * 14px = 28px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */ @@ -160,9 +169,9 @@ a { .btn-warning { text-decoration: none; color: #FFF; - background-color: #ff9f00; - border: solid #ff9f00; - border-color: #ff9f00; + background-color: var(--orange); + border: solid var(--orange); + border-color: var(--orange); border-width: 10px 20px; line-height: 2em; /* 2em * 14px = 28px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */ @@ -178,9 +187,9 @@ a { .btn-success { text-decoration: none; color: #FFF; - background-color: #68B90F; - border: solid #68B90F; - border-color: #68B90F; + background-color: var(--lightgreen); + border: solid var(--lightgreen); + border-color: var(--lightgreen); border-width: 10px 20px; line-height: 2em; /* 2em * 14px = 28px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */ @@ -196,9 +205,9 @@ a { .btn-danger { text-decoration: none; color: #FFF; - background-color: #D0021B; - border: solid #D0021B; - border-color: #D0021B; + background-color: var(--red); + border: solid var(--red); + border-color: var(--red); border-width: 10px 20px; line-height: 2em; /* 2em * 14px = 28px, use px to get airier line-height also in Thunderbird, and Yahoo!, Outlook.com, AOL webmail clients */ @@ -257,13 +266,13 @@ a { font-size: 16px; } .alert.alert-warning { - background-color: #FF9F00; + background-color: var(--orange); } .alert.alert-bad { - background-color: #D0021B; + background-color: var(--red); } .alert.alert-good { - background-color: #68B90F; + background-color: var(--lightgreen); } /* ------------------------------------- diff --git a/app/views/learning_materials/index.html.erb b/app/views/learning_materials/index.html.erb new file mode 100644 index 00000000..6ee5700c --- /dev/null +++ b/app/views/learning_materials/index.html.erb @@ -0,0 +1,88 @@ +<% content_for(:title,"Learning Materials") %> +<% content_for(:description,"A list of ruby and ruby on rails learning resources compiled by the ARC community") %> + +
+
+

Featured Materials

+
+ +
+ <% if @learningmaterials.empty? %> +

There are no created learning materials yet

+ <% else %> + <% # Select records with attached thumbnails %> + <% learningmaterials_with_thumbnails = @learningmaterials.select { |learningmaterial| learningmaterial.thumbnail.attached? } %> + + <% # Select and display two random records with thumbnails %> + <% random_learningmaterials = learningmaterials_with_thumbnails.sample(2) %> + + <% # Display the selected random records with thumbnails %> + <% random_learningmaterials.each do |learningmaterial| %> +
+ +
+
+ +
+
+ <%= learningmaterial.created_at.strftime("%b %d") %> +
+
+
+

<%= learningmaterial.learning_material_title %>

+

<%= learningmaterial.tag %>

+
+
+

<%= learningmaterial.learning_material_description %>

+
+
+ + <%= link_to "READ MORE HERE", learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> + +
+
+ <% end %> + <% end %> +
+ +
+

Other Resources

+
+ + + <% # Display the remaining records regardless of whether it has thumbnail or not %> + <% learningmaterials_with_or_without_thumbnails = @learningmaterials - random_learningmaterials %> +
+ <% learningmaterials_with_or_without_thumbnails.each do |learningmaterial| %> +
+ +
+ <% if learningmaterial.thumbnail.attached? %> +
+ +
+ <% else %> +
+ +
+ <% end %> +
+ <%= learningmaterial.created_at.strftime("%b %d") %> +
+
+
+

<%= learningmaterial.learning_material_title %>

+

<%= learningmaterial.tag %>

+
+
+

<%= learningmaterial.learning_material_description %>

+
+
+ + <%= link_to "READ MORE HERE", learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> + +
+
+ <% end %> +
+
\ No newline at end of file From f0da3d407002cc9b405dc37cb438a485cea72b87 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Wed, 17 Apr 2024 09:41:49 +0300 Subject: [PATCH 05/11] Update include: - Update all links to the learning materials page with the correct updated one (learning_materials_path). - Add authorization rules to the rails admin config to only allow users with role "organization_admin" access the dashboard. --- app/views/layouts/_footer.html.erb | 2 +- app/views/layouts/application.html.erb | 4 ++-- config/initializers/rails_admin.rb | 8 ++++++++ config/routes.rb | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb index 1b99ece6..14cf70de 100644 --- a/app/views/layouts/_footer.html.erb +++ b/app/views/layouts/_footer.html.erb @@ -21,7 +21,7 @@
  • <%= link_to 'Chapters', chapters_path %>
  • -
  • <%= link_to 'Learning materials', landing_learn_path %>
  • +
  • <%= link_to 'Learning materials', learning_materials_path %>
  • <% if FeatureFlag.find_by(name: 'projects').try(:enabled) %>
  • <%= link_to 'Projects', '#' %>
  • diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d074c1bf..7968e3f9 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -44,7 +44,7 @@
  • Projects
  • <% end %> -
  • <%= link_to 'Learning Materials', landing_learn_path %>
  • +
  • <%= link_to 'Learning Materials', learning_materials_path %>
  • <% if user_signed_in? %>
  • <%= button_to "Sign out", destroy_user_session_path, method: :delete %>
  • @@ -85,7 +85,7 @@ <% end %> - <%= link_to 'Learning Materials', landing_learn_path, + <%= link_to 'Learning Materials', learning_materials_path, class: 'text-sm font-small text-gray-500 hover:text-red-600' %> <% if user_signed_in? %> diff --git a/config/initializers/rails_admin.rb b/config/initializers/rails_admin.rb index c6d97926..9283c387 100644 --- a/config/initializers/rails_admin.rb +++ b/config/initializers/rails_admin.rb @@ -39,4 +39,12 @@ # history_index # history_show end + + # Configuring rails admin to use cancancan for authorization + config.authorize_with :cancancan + config.authorize_with do + unless current_user && current_user.organization_admin? + redirect_to main_app.root_path, alert: 'You are not authorized to access this page.' + end + end end diff --git a/config/routes.rb b/config/routes.rb index a7f917cd..69ca3677 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -18,5 +18,5 @@ root 'landing#index' get 'about_us', to: 'landing#about', as: :landing_about - get 'learn', to: 'landing#learn', as: :landing_learn + # get 'learn', to: 'landing#learn', as: :landing_learn end From 78753a15d2518d0e9e840d512050b53eed83ae86 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Wed, 17 Apr 2024 09:57:58 +0300 Subject: [PATCH 06/11] Update include: - Setup rspec in the project for unit tests - Configured Capybara to work with rspec in the spec_helper.rb file for integration/ feature tests --- .rspec | 1 + Gemfile | 2 + Gemfile.lock | 19 ++++++++ spec/rails_helper.rb | 63 +++++++++++++++++++++++++++ spec/spec_helper.rb | 101 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 186 insertions(+) create mode 100644 .rspec create mode 100644 spec/rails_helper.rb create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 00000000..c99d2e73 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/Gemfile b/Gemfile index d9653d8a..e92d5292 100644 --- a/Gemfile +++ b/Gemfile @@ -73,3 +73,5 @@ end gem "rails_admin", "~> 3.1" gem "sassc-rails" + +gem "rspec-rails", "~> 6.1" diff --git a/Gemfile.lock b/Gemfile.lock index 6733f768..b0441f8b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -153,6 +153,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) + diff-lcs (1.5.1) digest (3.1.0) docile (1.4.0) dockerfile-rails (1.2.5) @@ -306,6 +307,23 @@ GEM actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (6.1.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-support (3.13.1) rubocop (1.51.0) json (~> 2.3) parallel (~> 1.10) @@ -440,6 +458,7 @@ DEPENDENCIES rails (~> 7.0.3) rails_admin (~> 3.1) redis (~> 4.0) + rspec-rails (~> 6.1) rubocop (~> 1.51.0) rubocop-performance (~> 1.18) rubocop-rails (~> 2.19.1) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 00000000..cda261fc --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,63 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +require 'spec_helper' +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +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 +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +# Rails.root.glob('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. +begin + ActiveRecord::Migration.maintain_test_schema! +rescue ActiveRecord::PendingMigrationError => e + abort e.to_s.strip +end +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = Rails.root.join('spec/fixtures') + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # You can uncomment this line to turn off ActiveRecord support entirely. + # config.use_active_record = false + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, type: :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://rspec.info/features/6-0/rspec-rails + config.infer_spec_type_from_file_location! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 00000000..7ed70a32 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,101 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # 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: + # https://rspec.info/features/3-12/rspec-core/configuration/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 + + # Capybara configuration + require 'capybara/rspec' + require 'capybara/rails' + + # Configure Capybara to use the Rack app + Capybara.app = Rails.application +end From a2ddd4ec79a5acb3f1a38cd9bf77a6d2275ae651 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Wed, 17 Apr 2024 18:03:56 +0300 Subject: [PATCH 07/11] Update include: - Write integration test to the application - Update learning materials code moving logic to the controller moving it from the views --- Gemfile | 2 +- .../learning_materials_controller.rb | 7 ++++++- app/views/learning_materials/index.html.erb | 14 +++----------- spec/features/learning_materials_spec.rb | 18 ++++++++++++++++++ spec/spec_helper.rb | 7 ------- 5 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 spec/features/learning_materials_spec.rb diff --git a/Gemfile b/Gemfile index e92d5292..c1c7e69b 100644 --- a/Gemfile +++ b/Gemfile @@ -65,6 +65,7 @@ end group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] gem 'capybara' + gem "rspec-rails", "~> 6.1" gem 'faker', '~> 3.1' gem 'selenium-webdriver' gem 'simplecov', require: false # Code coverage analysis tool for ruby @@ -74,4 +75,3 @@ end gem "rails_admin", "~> 3.1" gem "sassc-rails" -gem "rspec-rails", "~> 6.1" diff --git a/app/controllers/learning_materials_controller.rb b/app/controllers/learning_materials_controller.rb index 2cd749a9..caefa1d5 100644 --- a/app/controllers/learning_materials_controller.rb +++ b/app/controllers/learning_materials_controller.rb @@ -1,5 +1,10 @@ class LearningMaterialsController < ApplicationController + skip_before_action :authenticate_user!, only: %i[index show] + def index @learningmaterials = LearningMaterial.all - end + @learningmaterials_with_thumbnails = @learningmaterials.select { |learningmaterial| learningmaterial.thumbnail.attached? } + @random_learningmaterials = @learningmaterials_with_thumbnails.sample(2) + @learningmaterials_with_or_without_thumbnails = @learningmaterials - @random_learningmaterials + end end diff --git a/app/views/learning_materials/index.html.erb b/app/views/learning_materials/index.html.erb index 6ee5700c..27afac1b 100644 --- a/app/views/learning_materials/index.html.erb +++ b/app/views/learning_materials/index.html.erb @@ -9,15 +9,9 @@
    <% if @learningmaterials.empty? %>

    There are no created learning materials yet

    - <% else %> - <% # Select records with attached thumbnails %> - <% learningmaterials_with_thumbnails = @learningmaterials.select { |learningmaterial| learningmaterial.thumbnail.attached? } %> - - <% # Select and display two random records with thumbnails %> - <% random_learningmaterials = learningmaterials_with_thumbnails.sample(2) %> - + <% else %> <% # Display the selected random records with thumbnails %> - <% random_learningmaterials.each do |learningmaterial| %> + <% @random_learningmaterials.each do |learningmaterial| %>
    @@ -49,11 +43,9 @@

    Other Resources

    - <% # Display the remaining records regardless of whether it has thumbnail or not %> - <% learningmaterials_with_or_without_thumbnails = @learningmaterials - random_learningmaterials %>
    - <% learningmaterials_with_or_without_thumbnails.each do |learningmaterial| %> + <% @learningmaterials_with_or_without_thumbnails.each do |learningmaterial| %>
    diff --git a/spec/features/learning_materials_spec.rb b/spec/features/learning_materials_spec.rb new file mode 100644 index 00000000..3cf4116e --- /dev/null +++ b/spec/features/learning_materials_spec.rb @@ -0,0 +1,18 @@ +require 'rails_helper' + +RSpec.feature "LearningMaterials", type: :feature do + before :each do + visit learning_materials_path + end + + it 'Displays the two main page headers' do + visit learning_materials_path + expect(page).to have_content('Featured Materials') + expect(page).to have_content('Other Resources') + end + + it 'Display default text if there are no learning materials found' do + @learningmaterials = [] + expect(page).to have_content('There are no created learning materials yet') + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 7ed70a32..327b58ea 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -91,11 +91,4 @@ # as the one that triggered the failure. Kernel.srand config.seed =end - - # Capybara configuration - require 'capybara/rspec' - require 'capybara/rails' - - # Configure Capybara to use the Rack app - Capybara.app = Rails.application end From bc13a7fb9b70c54a904bdaa9ba1da27f85e2d427 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Wed, 17 Apr 2024 18:12:44 +0300 Subject: [PATCH 08/11] Update check and fix all found Rubocop offences --- Gemfile | 7 +- .../learning_materials_controller.rb | 18 ++-- app/helpers/learning_materials_helper.rb | 2 + app/models/learning_material.rb | 2 + app/models/user.rb | 2 +- spec/features/learning_materials_spec.rb | 4 +- spec/rails_helper.rb | 4 +- spec/spec_helper.rb | 94 +++++++++---------- .../learning_materials_controller_test.rb | 4 +- test/models/learning_material_test.rb | 4 +- 10 files changed, 78 insertions(+), 63 deletions(-) diff --git a/Gemfile b/Gemfile index c1c7e69b..c88a8244 100644 --- a/Gemfile +++ b/Gemfile @@ -65,13 +65,12 @@ end group :test do # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing] gem 'capybara' - gem "rspec-rails", "~> 6.1" gem 'faker', '~> 3.1' + gem 'rspec-rails', '~> 6.1' gem 'selenium-webdriver' gem 'simplecov', require: false # Code coverage analysis tool for ruby gem 'webdrivers' end -gem "rails_admin", "~> 3.1" -gem "sassc-rails" - +gem 'rails_admin', '~> 3.1' +gem 'sassc-rails' diff --git a/app/controllers/learning_materials_controller.rb b/app/controllers/learning_materials_controller.rb index caefa1d5..6a06b474 100644 --- a/app/controllers/learning_materials_controller.rb +++ b/app/controllers/learning_materials_controller.rb @@ -1,10 +1,14 @@ +# frozen_string_literal: true + class LearningMaterialsController < ApplicationController - skip_before_action :authenticate_user!, only: %i[index show] + skip_before_action :authenticate_user!, only: %i[index] - def index - @learningmaterials = LearningMaterial.all - @learningmaterials_with_thumbnails = @learningmaterials.select { |learningmaterial| learningmaterial.thumbnail.attached? } - @random_learningmaterials = @learningmaterials_with_thumbnails.sample(2) - @learningmaterials_with_or_without_thumbnails = @learningmaterials - @random_learningmaterials - end + def index + @learningmaterials = LearningMaterial.all + @learningmaterials_with_thumbnails = @learningmaterials.select do |learningmaterial| + learningmaterial.thumbnail.attached? + end + @random_learningmaterials = @learningmaterials_with_thumbnails.sample(2) + @learningmaterials_with_or_without_thumbnails = @learningmaterials - @random_learningmaterials + end end diff --git a/app/helpers/learning_materials_helper.rb b/app/helpers/learning_materials_helper.rb index d929ed10..7bef30b0 100644 --- a/app/helpers/learning_materials_helper.rb +++ b/app/helpers/learning_materials_helper.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + module LearningMaterialsHelper end diff --git a/app/models/learning_material.rb b/app/models/learning_material.rb index c7eac92e..4073e601 100644 --- a/app/models/learning_material.rb +++ b/app/models/learning_material.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class LearningMaterial < ApplicationRecord # Associations belongs_to :user diff --git a/app/models/user.rb b/app/models/user.rb index 8d0333d0..5ed48e99 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,7 +10,7 @@ class User < ApplicationRecord # Associations has_many :users_chapters, dependent: :nullify has_many :chapters, through: :users_chapters - has_many :learning_materials + has_many :learning_materials, dependent: :nullify # Callbacks before_create :set_defaults # Set model defaults before create diff --git a/spec/features/learning_materials_spec.rb b/spec/features/learning_materials_spec.rb index 3cf4116e..5f6fc713 100644 --- a/spec/features/learning_materials_spec.rb +++ b/spec/features/learning_materials_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'rails_helper' -RSpec.feature "LearningMaterials", type: :feature do +RSpec.feature 'LearningMaterials', type: :feature do before :each do visit learning_materials_path end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index cda261fc..c616c677 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,9 +1,11 @@ +# frozen_string_literal: true + # This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require_relative '../config/environment' # Prevent database truncation if the environment is production -abort("The Rails environment is running in production mode!") if Rails.env.production? +abort('The Rails environment is running in production mode!') if Rails.env.production? require 'rspec/rails' # Add additional requires below this line. Rails is not loaded until this point! diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 327b58ea..409c64b6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This file was generated by the `rails generate rspec:install` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause @@ -44,51 +46,49 @@ # 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: - # https://rspec.info/features/3-12/rspec-core/configuration/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: + # # https://rspec.info/features/3-12/rspec-core/configuration/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 diff --git a/test/controllers/learning_materials_controller_test.rb b/test/controllers/learning_materials_controller_test.rb index ab3652d9..037865c8 100644 --- a/test/controllers/learning_materials_controller_test.rb +++ b/test/controllers/learning_materials_controller_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class LearningMaterialsControllerTest < ActionDispatch::IntegrationTest # test "the truth" do diff --git a/test/models/learning_material_test.rb b/test/models/learning_material_test.rb index b7c7b600..84352f52 100644 --- a/test/models/learning_material_test.rb +++ b/test/models/learning_material_test.rb @@ -1,4 +1,6 @@ -require "test_helper" +# frozen_string_literal: true + +require 'test_helper' class LearningMaterialTest < ActiveSupport::TestCase # test "the truth" do From f4e6447077e979ade831b08c1f03004a8770e96c Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Thu, 18 Apr 2024 10:37:42 +0300 Subject: [PATCH 09/11] Update include: - Add a section that lists the currently available learning materials for people who do not want to view the cards listed above - Add validations in the learning materials model for the title, description and link - Refactor error message localization in LearningMaterial model to improve code maintainability --- app/models/learning_material.rb | 5 +++++ app/views/learning_materials/index.html.erb | 14 ++++++++++++++ config/locales/en.yml | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/app/models/learning_material.rb b/app/models/learning_material.rb index 4073e601..25e8fe7f 100644 --- a/app/models/learning_material.rb +++ b/app/models/learning_material.rb @@ -7,4 +7,9 @@ class LearningMaterial < ApplicationRecord # Enum enum tag: { beginners: 0, intermediates: 1, experts: 2 } + + # Validations + validates :tag, :learning_material_title, :learning_material_description, :learning_material_link, presence: true + validates :learning_material_link, + format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), message: :invalid_url } end diff --git a/app/views/learning_materials/index.html.erb b/app/views/learning_materials/index.html.erb index 27afac1b..fc4b4dc0 100644 --- a/app/views/learning_materials/index.html.erb +++ b/app/views/learning_materials/index.html.erb @@ -77,4 +77,18 @@
    <% end %>
    + +
    +

    If you may not want the view above, here is a list of the same details shown above.

    +
    + +
      + <% @learningmaterials.each do |learningmaterial| %> +
    1. + + <%= link_to learningmaterial.learning_material_title, learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> - <%= learningmaterial.learning_material_description %> + +
    2. + <% end %> +
    \ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index bb6f3755..c7fba7de 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -29,4 +29,8 @@ en: destroy: success: 'Project was successfully destroyed.' + errors: + messages: + invalid_url: "must be a valid URL" + From a5b1b1d3846c95ba68810a8b41ed04321d34f4b9 Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Tue, 23 Apr 2024 17:17:27 +0300 Subject: [PATCH 10/11] Update include: - Use recommended snake case format for naming my variables. - Eagerload thumbnails for the Learning materials to avoid N + 1 queries. --- .../learning_materials_controller.rb | 10 +++--- app/views/learning_materials/index.html.erb | 36 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/app/controllers/learning_materials_controller.rb b/app/controllers/learning_materials_controller.rb index 6a06b474..7b1912a0 100644 --- a/app/controllers/learning_materials_controller.rb +++ b/app/controllers/learning_materials_controller.rb @@ -4,11 +4,11 @@ class LearningMaterialsController < ApplicationController skip_before_action :authenticate_user!, only: %i[index] def index - @learningmaterials = LearningMaterial.all - @learningmaterials_with_thumbnails = @learningmaterials.select do |learningmaterial| - learningmaterial.thumbnail.attached? + @learning_materials = LearningMaterial.includes(:thumbnail_blob).all + @learning_materials_with_thumbnails = @learning_materials.select do |learning_material| + learning_material.thumbnail.attached? end - @random_learningmaterials = @learningmaterials_with_thumbnails.sample(2) - @learningmaterials_with_or_without_thumbnails = @learningmaterials - @random_learningmaterials + @random_learning_materials = @learning_materials_with_thumbnails.sample(2) + @learning_materials_with_or_without_thumbnails = @learning_materials - @random_learning_materials end end diff --git a/app/views/learning_materials/index.html.erb b/app/views/learning_materials/index.html.erb index fc4b4dc0..252ff041 100644 --- a/app/views/learning_materials/index.html.erb +++ b/app/views/learning_materials/index.html.erb @@ -7,31 +7,31 @@
    - <% if @learningmaterials.empty? %> + <% if @learning_materials.empty? %>

    There are no created learning materials yet

    <% else %> <% # Display the selected random records with thumbnails %> - <% @random_learningmaterials.each do |learningmaterial| %> + <% @random_learning_materials.each do |learning_material| %>
    - +
    - <%= learningmaterial.created_at.strftime("%b %d") %> + <%= learning_material.created_at.strftime("%b %d") %>
    -

    <%= learningmaterial.learning_material_title %>

    -

    <%= learningmaterial.tag %>

    +

    <%= learning_material.learning_material_title %>

    +

    <%= learning_material.tag %>

    -

    <%= learningmaterial.learning_material_description %>

    +

    <%= learning_material.learning_material_description %>

    - <%= link_to "READ MORE HERE", learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> + <%= link_to "READ MORE HERE", learning_material.learning_material_link, class: "learning_materialslink ml-1", target: "_blank", style: "color: #D0021B;" %>
    @@ -45,13 +45,13 @@ <% # Display the remaining records regardless of whether it has thumbnail or not %>
    - <% @learningmaterials_with_or_without_thumbnails.each do |learningmaterial| %> + <% @learning_materials_with_or_without_thumbnails.each do |learning_material| %>
    - <% if learningmaterial.thumbnail.attached? %> + <% if learning_material.thumbnail.attached? %>
    - +
    <% else %>
    @@ -59,19 +59,19 @@
    <% end %>
    - <%= learningmaterial.created_at.strftime("%b %d") %> + <%= learning_material.created_at.strftime("%b %d") %>
    -

    <%= learningmaterial.learning_material_title %>

    -

    <%= learningmaterial.tag %>

    +

    <%= learning_material.learning_material_title %>

    +

    <%= learning_material.tag %>

    -

    <%= learningmaterial.learning_material_description %>

    +

    <%= learning_material.learning_material_description %>

    - <%= link_to "READ MORE HERE", learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> + <%= link_to "READ MORE HERE", learning_material.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %>
    @@ -83,10 +83,10 @@
      - <% @learningmaterials.each do |learningmaterial| %> + <% @learning_materials.each do |learning_material| %>
    1. - <%= link_to learningmaterial.learning_material_title, learningmaterial.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> - <%= learningmaterial.learning_material_description %> + <%= link_to learning_material.learning_material_title, learning_material.learning_material_link, class: "learningmaterialslink ml-1", target: "_blank", style: "color: #D0021B;" %> - <%= learning_material.learning_material_description %>
    2. <% end %> From a944f543c89b6762f6db719882baa40c8fef1c8a Mon Sep 17 00:00:00 2001 From: Nemwel-Boniface Date: Wed, 24 Apr 2024 10:44:39 +0300 Subject: [PATCH 11/11] Update: - Remove Motor admin from the project along with its config files - Test application to make sure it works still as required after removing motor admin --- Gemfile | 2 - Gemfile.lock | 17 -- app/models/motor/ability.rb | 16 -- config/motor.yml | 40 --- config/routes.rb | 4 - .../20230305084113_install_motor_admin.rb | 268 ------------------ 6 files changed, 347 deletions(-) delete mode 100644 app/models/motor/ability.rb delete mode 100644 config/motor.yml delete mode 100644 db/migrate/20230305084113_install_motor_admin.rb diff --git a/Gemfile b/Gemfile index c88a8244..4458447c 100644 --- a/Gemfile +++ b/Gemfile @@ -16,8 +16,6 @@ gem 'image_processing', '~> 1.2' gem 'jbuilder' # Build JSON APIs with ease [https://github.com/rails/jbuilder] gem 'jsbundling-rails' # Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails] gem 'mini_magick', '~> 4.12' -# Motor Admin allows you to deploy a no-code admin panel for your application in less than a minute -gem 'motor-admin', '~> 0.4.7' gem 'pg', '~> 1.1' # Use postgresql as the database for Active Record gem 'premailer-rails', '~> 1.12' # This gem is a drop in solution for styling HTML emails with CSS gem 'puma', '~> 5.0' # Use the Puma web server [https://github.com/puma/puma] diff --git a/Gemfile.lock b/Gemfile.lock index b0441f8b..d01e491d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -79,11 +79,7 @@ GEM public_suffix (>= 2.0.2, < 5.0) airbrussh (1.4.1) sshkit (>= 1.6.1, != 1.7.0) - ar_lazy_preload (1.1.2) - rails (>= 5.2) ast (2.4.2) - audited (5.3.2) - activerecord (>= 5.0, < 7.1) aws-eventstream (1.2.0) aws-partitions (1.721.0) aws-sdk-core (3.170.0) @@ -159,14 +155,9 @@ GEM dockerfile-rails (1.2.5) rails erubi (1.10.0) - et-orbi (1.2.7) - tzinfo faker (3.1.0) i18n (>= 1.8.11, < 2) ffi (1.15.5) - fugit (1.8.1) - et-orbi (~> 1, >= 1.2.7) - raabro (~> 1.4) globalid (1.0.0) activesupport (>= 5.0) htmlentities (4.3.4) @@ -212,12 +203,6 @@ GEM mini_magick (4.12.0) mini_mime (1.1.2) minitest (5.15.0) - motor-admin (0.4.7) - ar_lazy_preload (~> 1.0) - audited (~> 5.0) - cancancan (~> 3.0) - fugit (~> 1.0) - rails (>= 5.2) msgpack (1.5.2) nested_form (0.3.2) net-imap (0.2.3) @@ -260,7 +245,6 @@ GEM public_suffix (4.0.7) puma (5.6.4) nio4r (~> 2.0) - raabro (1.4.0) racc (1.6.0) rack (2.2.3.1) rack-test (1.1.0) @@ -451,7 +435,6 @@ DEPENDENCIES jsbundling-rails letter_opener mini_magick (~> 4.12) - motor-admin (~> 0.4.7) pg (~> 1.1) premailer-rails (~> 1.12) puma (~> 5.0) diff --git a/app/models/motor/ability.rb b/app/models/motor/ability.rb deleted file mode 100644 index 6596b366..00000000 --- a/app/models/motor/ability.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -## -# CanCan permissions for motor_admin -module Motor - class Ability - include CanCan::Ability - - def initialize(user, _request) - case user.role - when 'organization_admin' - can :manage, :all - end - end - end -end diff --git a/config/motor.yml b/config/motor.yml deleted file mode 100644 index 53e043d0..00000000 --- a/config/motor.yml +++ /dev/null @@ -1,40 +0,0 @@ ---- -engine_version: 0.4.7 -file_version: 2023-03-09 16:16:17.698355000 Z -resources: -- name: chapter - preferences: - columns: - - column_type: richtext - name: description - updated_at: 2023-03-05 09:31:13.962854000 +00:00 -- name: feature_flag - preferences: - columns: - - column_type: richtext - name: description - updated_at: 2023-03-09 16:16:17.698355000 +00:00 -configs: -- key: header.links - value: - - name: Reports - link_type: reports - - name: Forms - link_type: forms - - conditions: [] - type: header - name: Exit admin portal - path: "/" - link_type: header - updated_at: 2023-03-05 09:37:51.799389000 +00:00 -queries: [] -dashboards: [] -forms: [] -alerts: [] -api_configs: -- id: 1 - name: origin - url: "/" - preferences: {} - description: - updated_at: 2023-03-05 08:41:14.200426000 +00:00 diff --git a/config/routes.rb b/config/routes.rb index 69ca3677..846be344 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,9 +2,6 @@ Rails.application.routes.draw do mount RailsAdmin::Engine => '/admin', as: 'rails_admin' - authenticate :user do - mount Motor::Admin => '/admin' - end resources :projects, only: %i[index show] resources :chapters, only: %i[index show] resources :countries, only: %i[index show] @@ -18,5 +15,4 @@ root 'landing#index' get 'about_us', to: 'landing#about', as: :landing_about - # get 'learn', to: 'landing#learn', as: :landing_learn end diff --git a/db/migrate/20230305084113_install_motor_admin.rb b/db/migrate/20230305084113_install_motor_admin.rb deleted file mode 100644 index 97821239..00000000 --- a/db/migrate/20230305084113_install_motor_admin.rb +++ /dev/null @@ -1,268 +0,0 @@ -class InstallMotorAdmin < ActiveRecord::Migration[7.0] - def self.up - create_table :motor_queries do |t| - t.column :name, :string, null: false - t.column :description, :text - t.column :sql_body, :text, null: false - t.column :preferences, :text, null: false - t.column :author_id, :bigint - t.column :author_type, :string - t.column :deleted_at, :datetime - - t.timestamps - - t.index :updated_at - t.index 'name', - name: 'motor_queries_name_unique_index', - unique: true, - where: 'deleted_at IS NULL' - end - - create_table :motor_dashboards do |t| - t.column :title, :string, null: false - t.column :description, :text - t.column :preferences, :text, null: false - t.column :author_id, :bigint - t.column :author_type, :string - t.column :deleted_at, :datetime - - t.timestamps - - t.index :updated_at - t.index 'title', - name: 'motor_dashboards_title_unique_index', - unique: true, - where: 'deleted_at IS NULL' - end - - create_table :motor_forms do |t| - t.column :name, :string, null: false - t.column :description, :text - t.column :api_path, :text, null: false - t.column :http_method, :string, null: false - t.column :preferences, :text, null: false - t.column :author_id, :bigint - t.column :author_type, :string - t.column :deleted_at, :datetime - t.column :api_config_name, :string, null: false - - t.timestamps - - t.index :updated_at - t.index 'name', - name: 'motor_forms_name_unique_index', - unique: true, - where: 'deleted_at IS NULL' - end - - create_table :motor_resources do |t| - t.column :name, :string, null: false, index: { unique: true } - t.column :preferences, :text, null: false - - t.timestamps - - t.index :updated_at - end - - create_table :motor_configs do |t| - t.column :key, :string, null: false, index: { unique: true } - t.column :value, :text, null: false - - t.timestamps - - t.index :updated_at - end - - create_table :motor_alerts do |t| - t.references :query, null: false, foreign_key: { to_table: :motor_queries }, index: true - t.column :name, :string, null: false - t.column :description, :text - t.column :to_emails, :text, null: false - t.column :is_enabled, :boolean, null: false, default: true - t.column :preferences, :text, null: false - t.column :author_id, :bigint - t.column :author_type, :string - t.column :deleted_at, :datetime - - t.timestamps - - t.index :updated_at - t.index 'name', - name: 'motor_alerts_name_unique_index', - unique: true, - where: 'deleted_at IS NULL' - end - - create_table :motor_alert_locks do |t| - t.references :alert, null: false, foreign_key: { to_table: :motor_alerts } - t.column :lock_timestamp, :string, null: false - - t.timestamps - - t.index %i[alert_id lock_timestamp], unique: true - end - - create_table :motor_tags do |t| - t.column :name, :string, null: false - - t.timestamps - - t.index 'name', - name: 'motor_tags_name_unique_index', - unique: true - end - - create_table :motor_taggable_tags do |t| - t.references :tag, null: false, foreign_key: { to_table: :motor_tags }, index: true - t.column :taggable_id, :bigint, null: false - t.column :taggable_type, :string, null: false - - t.index %i[taggable_id taggable_type tag_id], - name: 'motor_polymorphic_association_tag_index', - unique: true - end - - create_table :motor_audits do |t| - t.column :auditable_id, :string - t.column :auditable_type, :string - t.column :associated_id, :string - t.column :associated_type, :string - t.column :user_id, :bigint - t.column :user_type, :string - t.column :username, :string - t.column :action, :string - t.column :audited_changes, :text - t.column :version, :bigint, default: 0 - t.column :comment, :text - t.column :remote_address, :string - t.column :request_uuid, :string - t.column :created_at, :datetime - end - - create_table :motor_api_configs do |t| - t.column :name, :string, null: false - t.column :url, :string, null: false - t.column :preferences, :text, null: false - t.column :credentials, :text, null: false - t.column :description, :text - t.column :deleted_at, :datetime - - t.timestamps - - t.index 'name', - name: 'motor_api_configs_name_unique_index', - unique: true, - where: 'deleted_at IS NULL' - end - - create_table :motor_notes do |t| - t.column :body, :text - t.column :author_id, :bigint - t.column :author_type, :string - t.column :record_id, :string, null: false - t.column :record_type, :string, null: false - t.column :deleted_at, :datetime - - t.timestamps - - t.index %i[author_id author_type], - name: 'motor_notes_author_id_author_type_index' - end - - create_table :motor_note_tags do |t| - t.column :name, :string, null: false - - t.timestamps - - t.index 'name', - name: 'motor_note_tags_name_unique_index', - unique: true - end - - create_table :motor_note_tag_tags do |t| - t.references :tag, null: false, foreign_key: { to_table: :motor_note_tags }, index: true - t.references :note, null: false, foreign_key: { to_table: :motor_notes }, index: false - - t.index %i[note_id tag_id], - name: 'motor_note_tags_note_id_tag_id_index', - unique: true - end - - create_table :motor_reminders do |t| - t.column :author_id, :bigint, null: false - t.column :author_type, :string, null: false - t.column :recipient_id, :bigint, null: false - t.column :recipient_type, :string, null: false - t.column :record_id, :string - t.column :record_type, :string - t.column :scheduled_at, :datetime, null: false, index: true - - t.timestamps - - t.index %i[author_id author_type], - name: 'motor_reminders_author_id_author_type_index' - - t.index %i[recipient_id recipient_type], - name: 'motor_reminders_recipient_id_recipient_type_index' - - t.index %i[record_id record_type], - name: 'motor_reminders_record_id_record_type_index' - end - - create_table :motor_notifications do |t| - t.column :title, :string, null: false - t.column :description, :text - t.column :recipient_id, :bigint, null: false - t.column :recipient_type, :string, null: false - t.column :record_id, :string - t.column :record_type, :string - t.column :status, :string, null: false - - t.timestamps - - t.index %i[recipient_id recipient_type], - name: 'motor_notifications_recipient_id_recipient_type_index' - - t.index %i[record_id record_type], - name: 'motor_notifications_record_id_record_type_index' - end - - add_index :motor_audits, %i[auditable_type auditable_id version], name: 'motor_auditable_index' - add_index :motor_audits, %i[associated_type associated_id], name: 'motor_auditable_associated_index' - add_index :motor_audits, %i[user_id user_type], name: 'motor_auditable_user_index' - add_index :motor_audits, :request_uuid - add_index :motor_audits, :created_at - - model = Class.new(ApplicationRecord) - - model.table_name = 'motor_configs' - - model.create!(key: 'header.links', value: [{ - name: '⭐ Star on GitHub', - path: 'https://github.com/motor-admin/motor-admin-rails' - }].to_json) - - model.table_name = 'motor_api_configs' - - model.create!(name: 'origin', url: '/', preferences: {}, credentials: {}) - end - - def self.down - drop_table :motor_audits - drop_table :motor_alert_locks - drop_table :motor_alerts - drop_table :motor_forms - drop_table :motor_taggable_tags - drop_table :motor_tags - drop_table :motor_resources - drop_table :motor_configs - drop_table :motor_queries - drop_table :motor_dashboards - drop_table :motor_api_configs - drop_table :motor_note_tag_tags - drop_table :motor_note_tags - drop_table :motor_notes - drop_table :motor_notifications - drop_table :motor_reminders - end -end