From 4cf98153ba4324cd503b0e41ed44f22df7a17642 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Wed, 4 Dec 2019 09:47:45 +1300 Subject: [PATCH 01/16] Fix model spec --- spec/models/crop_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 4b775b4ef..668a25c07 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -65,7 +65,7 @@ describe Crop do expect(@crop.default_scientific_name).to eq nil @sn = FactoryBot.create(:solanum_lycopersicum, crop: @crop) @crop.reload - expect(@crop.default_scientific_name).to eq @sn.name + expect("#{@crop.default_scientific_name}").to eq @sn.name end it 'counts plantings' do @@ -372,7 +372,7 @@ describe Crop do row = ["parent", "http://en.wikipedia.org/wiki/Parent", "", "Foo bar"] tomato = CsvImporter.new.import_crop(row) expect(tomato.scientific_names.size).to eq 1 - expect(tomato.default_scientific_name).to eq "Foo bar" + expect("#{tomato.default_scientific_name}").to eq "Foo bar" end it "picks up scientific name from parent crop if available" do From 092dc5958836e01b6b223e56fe14bdc256fd4d84 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 1 Dec 2019 08:44:14 +1300 Subject: [PATCH 02/16] Reduce the number of queries to find if member has seed of this crop --- app/helpers/crops_helper.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/helpers/crops_helper.rb b/app/helpers/crops_helper.rb index 5d5282921..f307dc791 100644 --- a/app/helpers/crops_helper.rb +++ b/app/helpers/crops_helper.rb @@ -1,12 +1,7 @@ module CropsHelper def display_seed_availability(member, crop) - total_quantity = 0 - - seeds = member.seeds.select { |seed| seed.crop.name == crop.name } - - seeds.each do |seed| - total_quantity += seed.quantity if seed.quantity - end + seeds = member.seeds.where(crop: crop) + total_quantity = seeds.where.not(quantity: nil).sum(:quantity) return "You don't have any seeds of this crop." if seeds.none? From 40627c58739c3b0db1f40b8ca5c015d3dd930b0b Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 08:45:00 +1300 Subject: [PATCH 03/16] Don't read crop photos from db again --- app/views/crops/_photos.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/crops/_photos.html.haml b/app/views/crops/_photos.html.haml index 8fe35a6cf..c7b31c4b9 100644 --- a/app/views/crops/_photos.html.haml +++ b/app/views/crops/_photos.html.haml @@ -1,4 +1,4 @@ -- if @crop.photos.size.positive? +- if photos.size.positive? %h2 #{photo_icon} Photos - [Crop, Planting, Harvest, Seed].each do |model_name| - if photos.by_model(model_name).size.positive? From 2623b0d01c2bb736cbb87d77630eb392782cae59 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 1 Dec 2019 08:54:15 +1300 Subject: [PATCH 04/16] Cache the footer --- app/views/layouts/_footer.html.haml | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index aac6212d6..1281395ae 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -1,12 +1,13 @@ -.container-fluid.text-center.text-md-left - .row - .col-md-4#footer1 - != cms_snippet_content(:footer1) - .col-md-4#footer2 - != cms_snippet_content(:footer2) - .col-md-4#footer3 - .badge.badge-success= link_to 'API', '/api-docs' - != cms_snippet_content(:footer3) - %div{ style: "float: right;" } - = link_to "https://opendefinition.org/ossd/" do - = image_tag 'open_service.png', alt: "Open Service" +- cache 'footer', expires: 1.week do + .container-fluid.text-center.text-md-left + .row + .col-md-4#footer1 + != cms_snippet_content(:footer1) + .col-md-4#footer2 + != cms_snippet_content(:footer2) + .col-md-4#footer3 + .badge.badge-success= link_to 'API', '/api-docs' + != cms_snippet_content(:footer3) + %div{ style: "float: right;" } + = link_to "https://opendefinition.org/ossd/" do + = image_tag 'open_service.png', alt: "Open Service" From 12b1ed9bcd954990ad1b7b71ef6be039ad4772a8 Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 12:30:31 +1300 Subject: [PATCH 05/16] Reduce queries per thumbnail. --- app/views/crops/_thumbnail.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index 7c7f3d6ec..948c59bbc 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -9,4 +9,4 @@ %h3.crop-name= link_to crop, crop %h5.crop-sci-name   - = crop.default_scientific_name + = crop.scientific_names.first&.name From c25f448d977d7db7c3420f2fd1d32b656290c8a6 Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 14:18:53 +1300 Subject: [PATCH 06/16] Reducing the number of db queries on crops#show --- app/views/crops/_harvests.html.haml | 4 ++-- app/views/crops/_photos.html.haml | 2 +- app/views/crops/_plantings.html.haml | 6 +++--- app/views/crops/_varieties.html.haml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/crops/_harvests.html.haml b/app/views/crops/_harvests.html.haml index d1ea8e977..f2755bbc6 100644 --- a/app/views/crops/_harvests.html.haml +++ b/app/views/crops/_harvests.html.haml @@ -1,11 +1,11 @@ .card .card-body %h3 #{crop.name.capitalize} harvests - - if crop.harvests.empty? + - if crop.harvests.none? %p Nobody has harvested this crop yet. - unless crop.harvests.empty? %ul.list-group.list-group-flush - - crop.harvests.order(harvested_at: :desc).limit(3).each do |harvest| + - Harvest.where(crop: crop).includes(:owner).order(harvested_at: :desc).limit(3).each do |harvest| %li.list-group-item = link_to harvest_path(harvest), class: 'card-link' do = harvest_icon diff --git a/app/views/crops/_photos.html.haml b/app/views/crops/_photos.html.haml index c7b31c4b9..ba27113f6 100644 --- a/app/views/crops/_photos.html.haml +++ b/app/views/crops/_photos.html.haml @@ -3,5 +3,5 @@ - [Crop, Planting, Harvest, Seed].each do |model_name| - if photos.by_model(model_name).size.positive? %h3 #{@crop.name.capitalize} #{t("activerecord.models.#{model_name.to_s.downcase}.other")} - = render 'photos/gallery', photos: photos.by_model(model_name).order(likes_count: :desc).limit(5) + = render 'photos/gallery', photos: photos.by_model(model_name).includes(:owner).order(likes_count: :desc).limit(5) = link_to 'more photos ยป', crop_photos_path(@crop), class: 'btn' diff --git a/app/views/crops/_plantings.html.haml b/app/views/crops/_plantings.html.haml index 8aff740a6..9e960f2dd 100644 --- a/app/views/crops/_plantings.html.haml +++ b/app/views/crops/_plantings.html.haml @@ -1,11 +1,11 @@ .card .card-body %h3 See who's planted #{crop.name.pluralize} - - unless crop.plantings.empty? + - if crop.plantings.any? %ul.list-group.list-group-flush - - crop.plantings.order(planted_at: :desc).limit(5).each do |planting| + - crop.plantings.includes(:owner, :garden).order(planted_at: :desc).limit(5).each do |planting| %li.list-group-item - = link_to planting, class: 'card-link' do + = link_to planting_path(planting), class: 'card-link' do = planting_icon = planting .float-right= render 'members/location', member: planting.owner diff --git a/app/views/crops/_varieties.html.haml b/app/views/crops/_varieties.html.haml index 3f73ed612..b825a4568 100644 --- a/app/views/crops/_varieties.html.haml +++ b/app/views/crops/_varieties.html.haml @@ -1,4 +1,4 @@ -- if crop.varieties.any? - - crop.varieties.order(:name).each do |v| +- if crop.varieties.size.positive? + - crop.varieties.includes(:varieties).order(:name).each do |v| = render 'crops/thumbnail', crop: v = render 'crops/varieties', crop: v From 8a0d551f904e7c65e274f5a614ddd3ed4d5f6763 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 1 Dec 2019 15:09:53 +1300 Subject: [PATCH 07/16] Cache photos --- app/helpers/photos_helper.rb | 16 +++++++++------- app/models/concerns/photo_capable.rb | 4 +++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb index dc6d88348..16da06595 100644 --- a/app/helpers/photos_helper.rb +++ b/app/helpers/photos_helper.rb @@ -1,14 +1,16 @@ module PhotosHelper def crop_image_path(crop) - if crop.default_photo.present? - # The flickr thumbnails are too small, use full size - if crop.default_photo.source == 'flickr' - crop.default_photo.fullsize_url + Rails.cache.fetch("crop_image_path/#{crop.id}") do + if crop.default_photo.present? + # The flickr thumbnails are too small, use full size + if crop.default_photo.source == 'flickr' + crop.default_photo.fullsize_url + else + crop.default_photo.thumbnail_url + end else - crop.default_photo.thumbnail_url + placeholder_image end - else - placeholder_image end end diff --git a/app/models/concerns/photo_capable.rb b/app/models/concerns/photo_capable.rb index 9cb440bd7..a4f0bd1a7 100644 --- a/app/models/concerns/photo_capable.rb +++ b/app/models/concerns/photo_capable.rb @@ -12,7 +12,9 @@ module PhotoCapable end def most_liked_photo - photos.order(likes_count: :desc, created_at: :desc).first + Rails.cache.fetch("most_liked_photo/#{model_name}/#{id}") do + photos.order(likes_count: :desc, created_at: :desc).first + end end end end From 44855cb8b27a49856a010216e5b91284c6a45c39 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 1 Dec 2019 16:00:58 +1300 Subject: [PATCH 08/16] Add query_diet, to count queries on the page --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index 58ce488ca..b33af1ef7 100644 --- a/Gemfile +++ b/Gemfile @@ -142,6 +142,7 @@ end group :development, :test do gem 'bullet' # performance tuning by finding unnecesary queries + gem 'query_diet' gem 'byebug' # debugging gem 'capybara' # integration tests gem 'capybara-email' # integration tests for email diff --git a/Gemfile.lock b/Gemfile.lock index 894c6e576..3658f395e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -358,6 +358,7 @@ GEM public_suffix (4.0.1) puma (4.3.0) nio4r (~> 2.0) + query_diet (0.6.2) rack (2.0.7) rack-protection (2.0.7) rack @@ -639,6 +640,7 @@ DEPENDENCIES pg (< 1.0.0) platform-api puma + query_diet rack-protection (>= 2.0.1) rails (= 5.2.2.1) rails-assets-leaflet.markercluster! From 59fffbfa7ba997d86004a04e3e74b16b4dbd5e0f Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Sun, 1 Dec 2019 16:01:22 +1300 Subject: [PATCH 09/16] Put query count on the page --- Gemfile | 2 +- app/views/layouts/application.html.haml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index b33af1ef7..7e32dcbcc 100644 --- a/Gemfile +++ b/Gemfile @@ -142,7 +142,6 @@ end group :development, :test do gem 'bullet' # performance tuning by finding unnecesary queries - gem 'query_diet' gem 'byebug' # debugging gem 'capybara' # integration tests gem 'capybara-email' # integration tests for email @@ -151,6 +150,7 @@ group :development, :test do gem 'factory_bot_rails' # for creating test data gem 'faker' gem 'haml-rails' # HTML templating language + gem 'query_diet' gem 'rspec-activemodel-mocks' gem 'rspec-rails' # unit testing framework gem 'rswag-specs' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index fbef0ff18..2eb7fd8ba 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -3,6 +3,7 @@ = yield :scripts = render "layouts/head" %body + = query_diet_widget if Rails.env.development? .sr-only= link_to t(".skip"), "#skipnav" = render "layouts/header" -# anchor tag for accessibility link to skip the navigation menu From cd2c692f340f35412f8b36c7f93724a7e13e840e Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 22:10:31 +1300 Subject: [PATCH 10/16] Little bit less queries to look up sci name --- app/models/crop.rb | 2 +- app/models/scientific_name.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index d0283a2b6..f60313448 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -67,7 +67,7 @@ class Crop < ApplicationRecord end def default_scientific_name - scientific_names.first&.name + scientific_names.first end # returns hash indicating whether this crop is grown in diff --git a/app/models/scientific_name.rb b/app/models/scientific_name.rb index f593d0eef..e3b7b911b 100644 --- a/app/models/scientific_name.rb +++ b/app/models/scientific_name.rb @@ -5,4 +5,8 @@ class ScientificName < ApplicationRecord validates :crop, presence: true after_commit :reindex if ENV["GROWSTUFF_ELASTICSEARCH"] == "true" delegate :reindex, to: :crop + + def to_s + name + end end From e6031fbc14f32e5b8d693117b0ae9f93e8437abc Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 22:10:46 +1300 Subject: [PATCH 11/16] Turn on bullet in dev --- config/environments/development.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/environments/development.rb b/config/environments/development.rb index 1992a8d2f..46106e08d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -79,6 +79,6 @@ Rails.application.configure do config.after_initialize do Bullet.enable = true Bullet.rails_logger = true - # Bullet.add_footer = true + Bullet.add_footer = true end end From 8a28c93b3dbb0202a93ad09d3d6d1c12cc9157e8 Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 22:11:03 +1300 Subject: [PATCH 12/16] Tell default photo to expire in 1 hour --- app/helpers/photos_helper.rb | 3 ++- app/models/concerns/photo_capable.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb index 16da06595..0223db8f2 100644 --- a/app/helpers/photos_helper.rb +++ b/app/helpers/photos_helper.rb @@ -1,6 +1,7 @@ module PhotosHelper def crop_image_path(crop) - Rails.cache.fetch("crop_image_path/#{crop.id}") do + Rails.cache.fetch("crop_image_path/#{crop.id}", + expires: 1.hour) do if crop.default_photo.present? # The flickr thumbnails are too small, use full size if crop.default_photo.source == 'flickr' diff --git a/app/models/concerns/photo_capable.rb b/app/models/concerns/photo_capable.rb index a4f0bd1a7..93d82072a 100644 --- a/app/models/concerns/photo_capable.rb +++ b/app/models/concerns/photo_capable.rb @@ -12,7 +12,8 @@ module PhotoCapable end def most_liked_photo - Rails.cache.fetch("most_liked_photo/#{model_name}/#{id}") do + Rails.cache.fetch("most_liked_photo/#{model_name}/#{id}", + expires: 1.hour) do photos.order(likes_count: :desc, created_at: :desc).first end end From 3111e8a177599c644f8fc4c49d5515f2293b228d Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Tue, 3 Dec 2019 21:28:16 +1300 Subject: [PATCH 13/16] Don't cache photo do agressively --- app/models/concerns/photo_capable.rb | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/models/concerns/photo_capable.rb b/app/models/concerns/photo_capable.rb index 93d82072a..9cb440bd7 100644 --- a/app/models/concerns/photo_capable.rb +++ b/app/models/concerns/photo_capable.rb @@ -12,10 +12,7 @@ module PhotoCapable end def most_liked_photo - Rails.cache.fetch("most_liked_photo/#{model_name}/#{id}", - expires: 1.hour) do - photos.order(likes_count: :desc, created_at: :desc).first - end + photos.order(likes_count: :desc, created_at: :desc).first end end end From 87d11c5bb13ab551a3156216e2919a0f089d2b27 Mon Sep 17 00:00:00 2001 From: Brenda Date: Sun, 1 Dec 2019 22:11:49 +1300 Subject: [PATCH 14/16] Small improvements to crops controller to reduce query count --- app/controllers/crops_controller.rb | 5 ++--- app/helpers/photos_helper.rb | 22 ++++++++++------------ app/views/home/_plantings.html.haml | 3 +-- spec/models/crop_spec.rb | 4 ++-- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 779f593f6..d5eb60573 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -58,19 +58,18 @@ class CropsController < ApplicationController end def show + @crop = Crop.includes(:scientific_names, :alternate_names, :parent, :varieties).find_by!(slug: params[:slug]) respond_to do |format| format.html do - @crop = Crop.includes(:scientific_names, plantings: :photos).find_by!(slug: params[:slug]) @photos = Photo.by_crop(@crop) @posts = @crop.posts.order(created_at: :desc).paginate(page: params[:page]) + @companions = @crop.companions.approved end format.svg do - @crop = Crop.find_by!(slug: params[:slug]) icon_data = @crop.svg_icon.presence || File.read(Rails.root.join('app', 'assets', 'images', 'icons', 'sprout.svg')) send_data(icon_data, type: "image/svg+xml", disposition: "inline") end format.json do - @crop = Crop.find_by!(slug: params[:slug]) render json: @crop.to_json(crop_json_fields) end end diff --git a/app/helpers/photos_helper.rb b/app/helpers/photos_helper.rb index 0223db8f2..c13168065 100644 --- a/app/helpers/photos_helper.rb +++ b/app/helpers/photos_helper.rb @@ -1,17 +1,15 @@ module PhotosHelper def crop_image_path(crop) - Rails.cache.fetch("crop_image_path/#{crop.id}", - expires: 1.hour) do - if crop.default_photo.present? - # The flickr thumbnails are too small, use full size - if crop.default_photo.source == 'flickr' - crop.default_photo.fullsize_url - else - crop.default_photo.thumbnail_url - end - else - placeholder_image - end + thumbnail_url(crop.default_photo) + end + + def thumbnail_url(photo) + if photo.nil? + placeholder_image + elsif photo.source == 'flickr' + photo.fullsize_url + else + photo.thumbnail_url end end diff --git a/app/views/home/_plantings.html.haml b/app/views/home/_plantings.html.haml index 3e800dcf9..8d26fe455 100644 --- a/app/views/home/_plantings.html.haml +++ b/app/views/home/_plantings.html.haml @@ -1,5 +1,4 @@ %h2= t('.recently_planted') - - Planting.has_photos.recent.includes(:owner, :crop).limit(6).each do |planting| - cache planting do = link_to planting, class: 'list-group-item list-group-item-action flex-column align-items-start' do @@ -10,4 +9,4 @@ %h5= planting.crop.name - if planting.planted_from.present? %span.badge.badge-success= planting.planted_from.pluralize - %small.text-muted planted by #{planting.owner} \ No newline at end of file + %small.text-muted planted by #{planting.owner} diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 668a25c07..80739afe2 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -65,7 +65,7 @@ describe Crop do expect(@crop.default_scientific_name).to eq nil @sn = FactoryBot.create(:solanum_lycopersicum, crop: @crop) @crop.reload - expect("#{@crop.default_scientific_name}").to eq @sn.name + expect(@crop.default_scientific_name.to_s).to eq @sn.name end it 'counts plantings' do @@ -372,7 +372,7 @@ describe Crop do row = ["parent", "http://en.wikipedia.org/wiki/Parent", "", "Foo bar"] tomato = CsvImporter.new.import_crop(row) expect(tomato.scientific_names.size).to eq 1 - expect("#{tomato.default_scientific_name}").to eq "Foo bar" + expect(tomato.default_scientific_name.to_s).to eq "Foo bar" end it "picks up scientific name from parent crop if available" do From 63d429846b61c3655701d7aded0599737121e1d6 Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Wed, 4 Dec 2019 20:58:12 +1300 Subject: [PATCH 15/16] Fix specs --- spec/models/crop_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 80739afe2..5ab66c522 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -385,8 +385,8 @@ describe Crop do ) expect(tomato.parent).to eq parent - expect(tomato.parent.default_scientific_name).to eq "Parentis cropis" - expect(tomato.default_scientific_name).to eq "Parentis cropis" + expect(tomato.parent.default_scientific_name.to_s).to eq "Parentis cropis" + expect(tomato.default_scientific_name.to_s).to eq "Parentis cropis" end it "doesn't add a duplicate scientific name" do From c6fc519e7d061fe6cc158728d38d0a0f8cdb000b Mon Sep 17 00:00:00 2001 From: Brenda Wallace Date: Fri, 6 Dec 2019 20:46:24 +1300 Subject: [PATCH 16/16] Production release (#2311) * Reduce the number of queries to find if member has seed of this crop * Don't read crop photos from db again * Cache the footer * Reduce queries per thumbnail. * Reducing the number of db queries on crops#show * Cache photos * Add query_diet, to count queries on the page * Fix model spec * Put query count on the page * Little bit less queries to look up sci name * Turn on bullet in dev * Tell default photo to expire in 1 hour * Small improvements to crops controller to reduce query count * Don't cache photo do agressively * Fix specs * Bump bootstrap from 4.3.1 to 4.4.1 Bumps [bootstrap](https://github.com/twbs/bootstrap-rubygem) from 4.3.1 to 4.4.1. - [Release notes](https://github.com/twbs/bootstrap-rubygem/releases) - [Changelog](https://github.com/twbs/bootstrap-rubygem/blob/master/CHANGELOG.md) - [Commits](https://github.com/twbs/bootstrap-rubygem/compare/v4.3.1...v4.4.1) Signed-off-by: dependabot-preview[bot] * [Security] Bump puma from 4.3.0 to 4.3.1 Bumps [puma](https://github.com/puma/puma) from 4.3.0 to 4.3.1. **This update includes a security fix.** - [Release notes](https://github.com/puma/puma/releases) - [Changelog](https://github.com/puma/puma/blob/master/History.md) - [Commits](https://github.com/puma/puma/compare/v4.3.0...v4.3.1) Signed-off-by: dependabot-preview[bot] * Move signout link into user menu * fixed logo display on small screens * Update specs to find logout link * [CodeFactor] Apply fixes to commit b999d89 --- Gemfile.lock | 10 +- app/assets/stylesheets/_homepage.scss | 1 - app/assets/stylesheets/_members.scss | 2 +- app/assets/stylesheets/_plantings.scss | 2 + app/assets/stylesheets/_predictions.scss | 2 +- app/assets/stylesheets/_variables.scss | 56 +++---- app/assets/stylesheets/application.scss | 1 + .../stylesheets/comfy/admin/cms/custom.sass | 1 - app/assets/stylesheets/mobile.scss | 88 ++++++++++ app/assets/stylesheets/overrides.scss | 151 +++++------------- app/views/layouts/_header.html.haml | 6 +- app/views/layouts/_menu.haml | 64 ++++---- app/views/layouts/application.html.haml | 5 +- spec/features/locale_spec.rb | 1 + spec/features/signin_spec.rb | 1 + spec/features/signout_spec.rb | 2 + 16 files changed, 204 insertions(+), 189 deletions(-) delete mode 100644 app/assets/stylesheets/comfy/admin/cms/custom.sass create mode 100644 app/assets/stylesheets/mobile.scss diff --git a/Gemfile.lock b/Gemfile.lock index 3658f395e..07b65bd89 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -65,7 +65,7 @@ GEM equalizer (~> 0.0.11) arel (9.0.0) ast (2.4.0) - autoprefixer-rails (9.6.0) + autoprefixer-rails (9.7.3) execjs bcrypt (3.1.13) better_errors (2.5.1) @@ -76,7 +76,7 @@ GEM bonsai-elasticsearch-rails (7.0.1) elasticsearch-model (< 8) elasticsearch-rails (< 8) - bootstrap (4.3.1) + bootstrap (4.4.1) autoprefixer-rails (>= 9.1.0) popper_js (>= 1.14.3, < 2) sassc-rails (>= 2.0.0) @@ -189,7 +189,7 @@ GEM multipart-post (>= 1.2, < 3) faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) - ffi (1.11.1) + ffi (1.11.3) figaro (1.1.1) thor (~> 0.14) flickraw (0.9.10) @@ -317,7 +317,7 @@ GEM multipart-post (2.1.1) newrelic_rpm (6.7.0.359) nio4r (2.5.2) - nokogiri (1.10.5) + nokogiri (1.10.7) mini_portile2 (~> 2.4.0) oauth (0.5.4) oauth2 (1.4.2) @@ -356,7 +356,7 @@ GEM popper_js (1.14.5) procto (0.0.3) public_suffix (4.0.1) - puma (4.3.0) + puma (4.3.1) nio4r (~> 2.0) query_diet (0.6.2) rack (2.0.7) diff --git a/app/assets/stylesheets/_homepage.scss b/app/assets/stylesheets/_homepage.scss index d33364c23..30df44779 100644 --- a/app/assets/stylesheets/_homepage.scss +++ b/app/assets/stylesheets/_homepage.scss @@ -1,4 +1,3 @@ - // stats shown on homepage. eg. "999 members..." .stats { font-weight: bold; diff --git a/app/assets/stylesheets/_members.scss b/app/assets/stylesheets/_members.scss index 188b4a317..84df767ca 100644 --- a/app/assets/stylesheets/_members.scss +++ b/app/assets/stylesheets/_members.scss @@ -11,7 +11,7 @@ } } -.member-thumbnail div ~ div { +.member-thumbnail div~div { padding-left: 1em; width: 15em; } diff --git a/app/assets/stylesheets/_plantings.scss b/app/assets/stylesheets/_plantings.scss index 897631e83..52e204082 100755 --- a/app/assets/stylesheets/_plantings.scss +++ b/app/assets/stylesheets/_plantings.scss @@ -4,9 +4,11 @@ font-size: 1em; position: absolute; top: 3em; + .badge-super-late { background-color: $red; } + .badge-harvest { background-color: $blue; } diff --git a/app/assets/stylesheets/_predictions.scss b/app/assets/stylesheets/_predictions.scss index 18d1ac623..26d37c977 100644 --- a/app/assets/stylesheets/_predictions.scss +++ b/app/assets/stylesheets/_predictions.scss @@ -8,7 +8,7 @@ text-align: center; strong { - font-align: center; + text-align: center; font-size: 3em; } diff --git a/app/assets/stylesheets/_variables.scss b/app/assets/stylesheets/_variables.scss index f4fff5645..b39c7f297 100644 --- a/app/assets/stylesheets/_variables.scss +++ b/app/assets/stylesheets/_variables.scss @@ -15,37 +15,30 @@ $body-bg: $beige; $text-color: $brown; $link-color: $green; -$default-font: 'Raleway', "Fira Sans", Helvetica, Arial, sans-serif; +$default-font: 'Raleway', +"Fira Sans", +Helvetica, +Arial, +sans-serif; -$primary: ( - color: $green, - dark: darken($green, 20%), - light: lighten($green, 20%) -); -$secondary: ( - color: $blue, - dark: darken($blue, 20%), - light: lighten($blue, 20%) -); -$success: ( - color: $green, - dark: darken($green, 20%), - light: lighten($green, 20%) -); -$danger: ( - color: $red, - dark: darken($red, 20%), - light: lighten($red, 20%) -); -$dark: ( - color: $brown, - dark: darken($brown, 20%), - light: lighten($brown, 20%) -); +$primary: (color: $green, + dark: darken($green, 20%), + light: lighten($green, 20%)); +$secondary: (color: $blue, + dark: darken($blue, 20%), + light: lighten($blue, 20%)); +$success: (color: $green, + dark: darken($green, 20%), + light: lighten($green, 20%)); +$danger: (color: $red, + dark: darken($red, 20%), + light: lighten($red, 20%)); +$dark: (color: $brown, + dark: darken($brown, 20%), + light: lighten($brown, 20%)); -$grid-breakpoints: ( - // Extra small screen / phone +$grid-breakpoints: ( // Extra small screen / phone xs: 0, // Small screen / phone sm: 576px, @@ -54,8 +47,7 @@ $grid-breakpoints: ( // Large screen / desktop lg: 1200px, // Extra large screen / wide desktop - xl: 1800px -); + xl: 1800px); // Nav bar $navbar-default-bg: $brown; @@ -66,8 +58,8 @@ $navbar-default-link-hover-color: $beige; $navbar-default-link-active-color: darken($beige, 80%); $navbar-default-brand-color: lighten($green, 20%); -$highest-level: 1070; +$highest-level: 1070; $progress-height: 5em; $progress-bar-color: $green; -$progress-bg: $white; \ No newline at end of file +$progress-bg: $white; diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index be50fd6a9..6c7d7ffe5 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -16,6 +16,7 @@ @import 'rails_bootstrap_forms'; @import 'overrides'; +@import 'mobile'; @import 'crops'; @import 'harvests'; diff --git a/app/assets/stylesheets/comfy/admin/cms/custom.sass b/app/assets/stylesheets/comfy/admin/cms/custom.sass deleted file mode 100644 index 328d897f1..000000000 --- a/app/assets/stylesheets/comfy/admin/cms/custom.sass +++ /dev/null @@ -1 +0,0 @@ -// custom CSS for admin area \ No newline at end of file diff --git a/app/assets/stylesheets/mobile.scss b/app/assets/stylesheets/mobile.scss new file mode 100644 index 000000000..c62904e37 --- /dev/null +++ b/app/assets/stylesheets/mobile.scss @@ -0,0 +1,88 @@ +// Overrides applying only to mobile view. This must be at the end of the overrides file. +// Extra small devices (portrait phones, less than 576px) +@include media-breakpoint-down(xs) { + + #maincontainer { + width: 100%; + } + + .navbar .nav>li { + display: block; + } + + .navbar .navbar-form { + padding-left: 0; + padding-right: 0; + + #navbar-search { + width: 100%; + } + } + + .navbar-brand { + margin-bottom: 1em; + + .site-name { + font-size: auto; + text-align: justify; + } + + .site-name:after { + content: ''; + display: inline-block; + width: 100%; + } + + } + + h1 { + font-size: 200%; + } + + h2 { + font-size: 130%; + } + + h3 { + font-size: 120%; + } + + .card-title { + margin-bottom: 0; + } + + .sidebar { + border-left: 0; + margin-left: 0; + padding-left: 0; + } + + .map { + height: 300px; + } + + + section .btn { + width: 100%; + } + + .index-cards { + .card { + margin: .2em; + width: 48%; + + // Shrink title to fit more on page + .card-title { + font-size: 1em; + } + + // Restrict height of image when on smaller screens + .img-card { + height: 100px; + object-fit: cover; + width: 100%; + } + + } + } +} diff --git a/app/assets/stylesheets/overrides.scss b/app/assets/stylesheets/overrides.scss index db0e529ad..50957d0a0 100755 --- a/app/assets/stylesheets/overrides.scss +++ b/app/assets/stylesheets/overrides.scss @@ -8,20 +8,44 @@ body { font-family: $default-font; } -.navbar-brand .site-name { - font-family: 'Modak', cursive; - font-size: 3em; - margin-top: 0.2em; +.navbar-brand { + .site-name { + font-family: 'Modak', cursive; + font-size: 3em; + margin: .3em; + } + + img { + height: 60px; + } +} + +#navbar-search { + padding-left: 1em; + + .input-group { + input { + background-color: $white; + color: $black; + } + + input::placeholder { + color: $navbar-default-link-color; + } + } +} + +.navbar .btn-signup, +.navbar .btn-signin { + background-color: $green; + color: $white; + margin: 3px; } .homepage-blurb .site-name { font-size: 5em; } -.navbar-nav .btn { - background-color: $green; - color: $white; -} .ellipsis { overflow: hidden; @@ -58,22 +82,11 @@ h3 { font-size: 120%; } -#navbar-search { - .input-group { - input { - background-color: $white; - color: $black; - } - - input::placeholder { - color: $navbar-default-link-color; - } - } -} section { margin: .5em 0 0; padding: 0 0 1em; + h2 { background-color: $green; box-shadow: 1px 1px 1px 1px darken($beige, 20%); @@ -112,8 +125,10 @@ section { border-top-right-radius: 5%; } } + .card-finished { background: darken($beige, 10%); + a { color: $brown; } @@ -168,6 +183,7 @@ section { .thumbnail { height: 100px; + img { border-radius: 5px; height: 75px; @@ -211,6 +227,7 @@ ul.associations { // footer footer { + #footer1, #footer2, #footer3 { @@ -244,7 +261,9 @@ footer { #maincontainer { max-width: 2500px; min-height: 80%; - padding: 1em; + padding-bottom: 1em; + padding-left: 1em; + padding-right: 1em; } // Autosuggest @@ -282,7 +301,7 @@ $state-success-bg: lighten($green, 50%); label.required:after { color: red; - content:" *"; + content: " *"; } .truncate { @@ -396,91 +415,3 @@ ul.thumbnail-buttons { .progress-fade:hover::before { background: none; } - -// Overrides applying only to mobile view. This must be at the end of the overrides file. -// Extra small devices (portrait phones, less than 576px) -@include media-breakpoint-down(xs) { - #maincontainer { - width: 100%; - padding: 10px; - } - - h1 { - font-size: 200%; - } - - h2 { - font-size: 130%; - } - - h3 { - font-size: 120%; - } - - .card-title { - margin-bottom: 0; - } - - .sidebar { - margin-left: 0; - border-left: none; - padding-left: 0; - } - - .map { - height: 300px; - } - - .navbar .nav > li { - display: block; - } - - .navbar .navbar-form { - padding-left: 0; - padding-right: 0; - - .navbar-search { - width: auto; - } - } - - .nav .btn { - background-color: $green; - width: 100%; - } - - .navbar-brand .site-name { - font-size: 1.4em; - text-align: justify; - } - - .navbar-brand .site-name:after { - content: ""; - display: inline-block; - width: 100%; - } - - section .btn { - width: 100%; - } - - .index-cards { - .card { - margin: .2em; - width: 48%; - - // Shrink title to fit more on page - .card-title { - font-size: 1em; - } - - // Restrict height of image when on smaller screens - .img-card { - height: 100px; - object-fit: cover; - width: 100%; - } - - } - } -} diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index e6b6af779..414dac23e 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -1,12 +1,10 @@ %nav.navbar.navbar-expand-lg.navbar-dark.bg-dark.justify-content-between .nav %a.navbar-brand{ href: root_path } - = image_tag("pear.png", size: "100x100", alt: 'Growstuff brand logo (drawing of a pear)') + = image_tag("pear.png", class: 'logo', alt: 'Growstuff brand logo (drawing of a pear)') %span.site-name Growstuff .nav - %button.navbar-toggler{"aria-controls" => "navbarSupportedContent", "aria-expanded" => "false", "aria-label" => "Toggle navigation", "data-target" => "#navbarSupportedContent", "data-toggle" => "collapse", type: "button"} + %button.navbar-toggler{ "aria-controls" => "navbarSupportedContent", "aria-expanded" => "false", "aria-label" => "Toggle navigation", "data-target" => "#navbarSupportedContent", "data-toggle" => "collapse", type: "button" } %i.fas.fa-ellipsis-v.navbar-toggler-icon - = render 'layouts/menu' - = render 'crops/search_bar' \ No newline at end of file diff --git a/app/views/layouts/_menu.haml b/app/views/layouts/_menu.haml index 6a0a4e00e..eea460e0d 100644 --- a/app/views/layouts/_menu.haml +++ b/app/views/layouts/_menu.haml @@ -1,10 +1,12 @@ #navbarSupportedContent.collapse.navbar-collapse %ul.navbar-nav.mr-auto - if signed_in? - = link_to timeline_index_path, method: :get, class: 'nav-link text-white' do - = image_tag 'icons/notification.svg', class: 'img img-icon' - = link_to member_gardens_path(member_slug: current_member.slug), class: 'nav-link text-white' do - = image_icon 'gardens' + %li.nav-item + = link_to timeline_index_path, method: :get, class: 'nav-link text-white' do + = image_tag 'icons/notification.svg', class: 'img img-icon' + %li.nav-item + = link_to member_gardens_path(member_slug: current_member.slug), class: 'nav-link text-white' do + = image_icon 'gardens' %li.nav-item.dropdown %a.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#", role: "button"} = image_tag "icons/gardener.svg", class: 'img img-icon' @@ -23,28 +25,28 @@ = post_icon = t('buttons.new_post') - %li.nav-item.dropdown - %a.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#", role: "button"}= t('.crops') - .dropdown-menu - = link_to crops_path, class: 'dropdown-item' do - = t('.browse_crops') - = link_to seeds_path, class: 'dropdown-item' do - = seed_icon - = t('.seeds') - = link_to plantings_path, class: 'dropdown-item' do - = planting_icon - = t('.plantings') - = link_to harvests_path, class: 'dropdown-item' do - = harvest_icon - = t('.harvests') - - %li.nav-item.dropdown - %a.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#", role: "button"}= t('.community') - .dropdown-menu{"aria-labelledby" => "navbarDropdown"} - = link_to t('.community_map'), places_path, class: 'dropdown-item' - = link_to t('.browse_members'), members_path, class: 'dropdown-item' - = link_to t('.posts'), posts_path, class: 'dropdown-item' - = link_to t('.forums'), forums_path, class: 'dropdown-item' + - cache("everyone-menu", expires_in: 1.week) do + %li.nav-item.dropdown + %a.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#", role: "button"}= t('.crops') + .dropdown-menu + = link_to crops_path, class: 'dropdown-item' do + = t('.browse_crops') + = link_to seeds_path, class: 'dropdown-item' do + = seed_icon + = t('.seeds') + = link_to plantings_path, class: 'dropdown-item' do + = planting_icon + = t('.plantings') + = link_to harvests_path, class: 'dropdown-item' do + = harvest_icon + = t('.harvests') + %li.nav-item.dropdown + %a.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#", role: "button"}= t('.community') + .dropdown-menu{"aria-labelledby" => "navbarDropdown"} + = link_to t('.community_map'), places_path, class: 'dropdown-item' + = link_to t('.browse_members'), members_path, class: 'dropdown-item' + = link_to t('.posts'), posts_path, class: 'dropdown-item' + = link_to t('.forums'), forums_path, class: 'dropdown-item' - if member_signed_in? %li.nav-item.dropdown @@ -75,6 +77,8 @@ %span.badge.badge-info= current_member.unread_count - else = link_to t('.inbox'), conversations_path, class: 'dropdown-item' + .dropdown-divider + = link_to t('.sign_out'), destroy_member_session_path, method: :delete, class: 'dropdown-item' - if current_member.role?(:crop_wrangler) || current_member.role?(:admin) %li.nav-item.dropdown @@ -84,10 +88,6 @@ = link_to t('.crop_wrangling'), wrangle_crops_path, class: 'dropdown-item' - if current_member.role?(:admin) = link_to t('.admin'), admin_path, class: 'dropdown-item' - - %li.nav-item - = link_to t('.sign_out'), destroy_member_session_path, method: :delete, class: 'nav-link' - - else - %li.nav-item= link_to t('.sign_in'), new_member_session_path, id: 'navbar-signin', class: 'btn' - %li.nav-item= link_to t('.sign_up'), new_member_registration_path, id: 'navbar-signup', class: 'btn' + %li.nav-item= link_to t('.sign_in'), new_member_session_path, id: 'navbar-signin', class: 'btn btn-signin' + %li.nav-item= link_to t('.sign_up'), new_member_registration_path, id: 'navbar-signup', class: 'btn btn-signup' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 2eb7fd8ba..aefd4c7eb 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -8,12 +8,13 @@ = render "layouts/header" -# anchor tag for accessibility link to skip the navigation menu %a{ name: 'skipnav' } - #maincontainer.container-fluid + + #maincontainer .row .col-md-8.col-12 - if content_for?(:breadcrumbs) %nav - %ol.breadcrumb{"aria-label" => "breadcrumb"} + %ol.breadcrumb{ "aria-label" => "breadcrumb" } %li.breadcrumb-item= link_to 'Home', root_path = yield(:breadcrumbs) - if content_for?(:buttonbar) diff --git a/spec/features/locale_spec.rb b/spec/features/locale_spec.rb index dd912f5e8..2dce809ad 100644 --- a/spec/features/locale_spec.rb +++ b/spec/features/locale_spec.rb @@ -8,6 +8,7 @@ describe "Changing locales", js: true do # Login then log out, to ensure we're now logged out login_as member visit root_path + click_link member.login_name click_link 'Sign out' expect(page).to have_content("a community of food gardeners.") visit root_path(locale: 'ja') diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index 55e31d4b9..9ff9304fc 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -15,6 +15,7 @@ describe "signin", js: true do visit crops_path # some random page click_link 'Sign in' login + click_link member.login_name expect(page).to have_content("Sign out") end diff --git a/spec/features/signout_spec.rb b/spec/features/signout_spec.rb index d65370ff6..4a2013e5c 100644 --- a/spec/features/signout_spec.rb +++ b/spec/features/signout_spec.rb @@ -9,6 +9,7 @@ describe "signout" do fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' + click_link member.login_name click_link 'Sign out' expect(current_path).to eq crops_path end @@ -23,6 +24,7 @@ describe "signout" do click_button 'Sign in' # expect(page).to have_http_status(200) expect(current_path).to eq path + click_link member.login_name click_link 'Sign out' # expect(page).to have_http_status(200) expect(current_path).to eq new_member_session_path