From 6d1385f00c25ecdd2bda5243a892ab4d9cc4f7f8 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 22 Jan 2015 23:41:44 +0000 Subject: [PATCH 001/392] Turn on PhantomJS for all feature tests. --- spec/features/admin/account_types_spec.rb | 2 +- spec/features/admin/forums_spec.rb | 2 +- spec/features/crops/alternate_name_spec.rb | 2 +- spec/features/crops/crop_detail_page_spec.rb | 2 +- spec/features/crops/crop_wranglers_spec.rb | 2 +- spec/features/following_spec.rb | 2 +- spec/features/footer_spec.rb | 2 +- spec/features/locale_spec.rb | 2 +- spec/features/member_profile_spec.rb | 2 +- spec/features/rss/comments_spec.rb | 4 ++-- spec/features/rss/crops_spec.rb | 4 ++-- spec/features/rss/members_spec.rb | 4 ++-- spec/features/rss/plantings_spec.rb | 4 ++-- spec/features/rss/posts_spec.rb | 4 ++-- spec/features/rss/seeds_spec.rb | 4 ++-- spec/features/scientific_name_spec.rb | 2 +- spec/features/seeds/misc_seeds_spec.rb | 2 +- spec/features/signin_spec.rb | 2 +- spec/features/signup_spec.rb | 2 +- 19 files changed, 25 insertions(+), 25 deletions(-) diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index b56144344..427d3fa70 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "account types" do +feature "account types", :js => true do context "admin user" do before(:each) do @member = FactoryGirl.create(:admin_member) diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index e9f8a43f9..d8c6fa81c 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "forums" do +feature "forums", :js => true do context "admin user" do before(:each) do @member = FactoryGirl.create(:admin_member) diff --git a/spec/features/crops/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb index 8ec2a21fe..6b95da0b1 100644 --- a/spec/features/crops/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Alternate names" do +feature "Alternate names", :js => true do let!(:alternate_eggplant) { FactoryGirl.create(:alternate_eggplant) } let(:crop) { alternate_eggplant.crop } diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 437d3e786..08e981c8d 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "crop detail page" do +feature "crop detail page", :js => true do let(:crop) { FactoryGirl.create(:crop) } diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 0e0b08fbe..d70a9a914 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "crop wranglers" do +feature "crop wranglers", :js => true do context "signed in wrangler" do let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } let(:wrangler){crop_wranglers.first} diff --git a/spec/features/following_spec.rb b/spec/features/following_spec.rb index 35b74ce16..72000b5bc 100644 --- a/spec/features/following_spec.rb +++ b/spec/features/following_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "follows" do +feature "follows", :js => true do context "when signed out" do let(:member) { FactoryGirl.create(:member) } diff --git a/spec/features/footer_spec.rb b/spec/features/footer_spec.rb index 749d948ba..6677f50cf 100644 --- a/spec/features/footer_spec.rb +++ b/spec/features/footer_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "footer" do +feature "footer", :js => true do scenario "has three columns" do visit root_path diff --git a/spec/features/locale_spec.rb b/spec/features/locale_spec.rb index 36b07b5c9..1f566b2eb 100644 --- a/spec/features/locale_spec.rb +++ b/spec/features/locale_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Changing locales" do +feature "Changing locales", :js => true do after do I18n.locale = :en diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 2c7343a8d..2f02c6194 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "member profile" do +feature "member profile", :js => true do context "signed out member" do let(:member) { FactoryGirl.create(:member) } diff --git a/spec/features/rss/comments_spec.rb b/spec/features/rss/comments_spec.rb index 3f7ce9dc8..34978822b 100644 --- a/spec/features/rss/comments_spec.rb +++ b/spec/features/rss/comments_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Comments RSS feed' do +feature 'Comments RSS feed', :js => true do scenario 'The index feed exists' do visit comments_path(:format => 'rss') expect(page.status_code).to equal 200 @@ -10,4 +10,4 @@ feature 'Comments RSS feed' do visit comments_path(:format => 'rss') expect(page).to have_content "Recent comments on all posts (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/rss/crops_spec.rb b/spec/features/rss/crops_spec.rb index 971ec1b80..75c5025d2 100644 --- a/spec/features/rss/crops_spec.rb +++ b/spec/features/rss/crops_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Crops RSS feed' do +feature 'Crops RSS feed', :js => true do scenario 'The index feed exists' do visit crops_path(:format => 'rss') expect(page.status_code).to equal 200 @@ -10,4 +10,4 @@ feature 'Crops RSS feed' do visit crops_path(:format => 'rss') expect(page).to have_content "Recently added crops (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/rss/members_spec.rb b/spec/features/rss/members_spec.rb index 69abb5a25..6dd587fe5 100644 --- a/spec/features/rss/members_spec.rb +++ b/spec/features/rss/members_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Members RSS feed' do +feature 'Members RSS feed', :js => true do let(:member) { FactoryGirl.create(:member) } scenario 'The show action exists' do @@ -12,4 +12,4 @@ feature 'Members RSS feed' do visit member_path(member, :format => 'rss') expect(page).to have_content "#{member.login_name}'s recent posts (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/rss/plantings_spec.rb b/spec/features/rss/plantings_spec.rb index 5a0e98371..36578424c 100644 --- a/spec/features/rss/plantings_spec.rb +++ b/spec/features/rss/plantings_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Plantings RSS feed' do +feature 'Plantings RSS feed', :js => true do scenario 'The index feed exists' do visit plantings_path(:format => 'rss') expect(page.status_code).to equal 200 @@ -10,4 +10,4 @@ feature 'Plantings RSS feed' do visit plantings_path(:format => 'rss') expect(page).to have_content "Recent plantings from #{ @owner ? @owner : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/rss/posts_spec.rb b/spec/features/rss/posts_spec.rb index 899c1427b..488fa5d1f 100644 --- a/spec/features/rss/posts_spec.rb +++ b/spec/features/rss/posts_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Posts RSS feed' do +feature 'Posts RSS feed', :js => true do scenario 'The index feed exists' do visit posts_path(:format => 'rss') expect(page.status_code).to equal 200 @@ -10,4 +10,4 @@ feature 'Posts RSS feed' do visit posts_path(:format => 'rss') expect(page).to have_content "Recent posts from #{ @author ? @author : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/rss/seeds_spec.rb b/spec/features/rss/seeds_spec.rb index e0d016939..b666455d2 100644 --- a/spec/features/rss/seeds_spec.rb +++ b/spec/features/rss/seeds_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -feature 'Seeds RSS feed' do +feature 'Seeds RSS feed', :js => true do scenario 'The index feed exists' do visit seeds_path(:format => 'rss') expect(page.status_code).to equal 200 @@ -10,4 +10,4 @@ feature 'Seeds RSS feed' do visit seeds_path(:format => 'rss') expect(page).to have_content "Recent seeds from #{ @owner ? @owner : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end -end \ No newline at end of file +end diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index c6cd60c6a..70b444cf5 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Scientific names" do +feature "Scientific names", :js => true do let!(:zea_mays) { FactoryGirl.create(:zea_mays) } let(:crop) { zea_mays.crop } diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 11f1d6c09..af727a3ba 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "seeds" do +feature "seeds", :js => true do context "signed in user" do before(:each) do @crop = FactoryGirl.create(:crop) diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index dced5f2ac..24a70e170 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "signin" do +feature "signin", :js => true do let(:member){FactoryGirl.create(:member)} let(:recipient){FactoryGirl.create(:member)} let(:notification){FactoryGirl.create(:notification)} diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb index aa4c9d65f..760325001 100644 --- a/spec/features/signup_spec.rb +++ b/spec/features/signup_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "signup" do +feature "signup", :js => true do scenario "sign up for new account from top menubar" do visit crops_path # something other than front page, which has multiple signup links From 656b0e44d8dbceb01a10c2b59ef6f07f724f111d Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Mon, 2 Feb 2015 18:40:24 +1100 Subject: [PATCH 002/392] fixing issue with elasticsearch option false in dev --- app/models/alternate_name.rb | 2 +- app/models/crop.rb | 2 +- app/models/scientific_name.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/alternate_name.rb b/app/models/alternate_name.rb index cb6f79e9d..857adf7ec 100644 --- a/app/models/alternate_name.rb +++ b/app/models/alternate_name.rb @@ -1,5 +1,5 @@ class AlternateName < ActiveRecord::Base - after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop } + after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" } belongs_to :crop belongs_to :creator, :class_name => 'Member' end diff --git a/app/models/crop.rb b/app/models/crop.rb index 82d1e24a0..831c8ccb4 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -85,7 +85,7 @@ class Crop < ActiveRecord::Base end def update_index(name_obj) - __elasticsearch__.index_document + __elasticsearch__.index_document if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" end #################################### diff --git a/app/models/scientific_name.rb b/app/models/scientific_name.rb index 7469b3946..aec8f1091 100644 --- a/app/models/scientific_name.rb +++ b/app/models/scientific_name.rb @@ -1,5 +1,5 @@ class ScientificName < ActiveRecord::Base - after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop } + after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" } belongs_to :crop belongs_to :creator, :class_name => 'Member' end From 36a9514addef1e10290f0c465b12eb7b7c96ed52 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Tue, 3 Feb 2015 23:20:58 +1100 Subject: [PATCH 003/392] linkback for harvests and gardens as well : Fixing #679 --- app/views/photos/show.html.haml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml index ad331bd48..0330a25f7 100644 --- a/app/views/photos/show.html.haml +++ b/app/views/photos/show.html.haml @@ -19,11 +19,19 @@ %p= link_to 'Delete Photo', @photo, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' .col-md-6 - - if @photo.plantings.count > 0 + - if @photo.plantings.count > 0 or @photo.harvests.count > 0 or @photo.gardens.count > 0 %p This photo depicts: %ul - - @photo.plantings.each do |p| - %li= link_to p, p + - if @photo.plantings.count > 0 + - @photo.plantings.each do |p| + %li= link_to p, p + - if @photo.harvests.count > 0 + - @photo.harvests.each do |h| + %li= link_to h, h + - if @photo.gardens.count > 0 + - @photo.gardens.each do |g| + %li= link_to g, g + .row .col-md-12 From 9bcd2d0aa6bdc9151f6b5209694ce35fa1d59ae0 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Tue, 10 Feb 2015 20:01:43 +1100 Subject: [PATCH 004/392] Test for linkback of photos to harvest/garden/planting --- spec/features/photos/show_photo_spec.rb | 48 +++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 spec/features/photos/show_photo_spec.rb diff --git a/spec/features/photos/show_photo_spec.rb b/spec/features/photos/show_photo_spec.rb new file mode 100644 index 000000000..aa02af988 --- /dev/null +++ b/spec/features/photos/show_photo_spec.rb @@ -0,0 +1,48 @@ +require 'rails_helper' + +feature "show photo page" do + + let (:photo) { FactoryGirl.create(:photo) } + + context "signed in member" do + let (:member) { FactoryGirl.create(:member) } + + background do + login_as(member) + end + + context "linked to planting" do + let (:planting) { FactoryGirl.create(:planting) } + + scenario "shows linkback to planting" do + planting.photos << photo + visit photo_path(photo) + expect(page).to have_link planting, :href => planting_path(planting) + end + end + + context "linked to harvest" do + let (:harvest) { FactoryGirl.create(:harvest) } + + scenario "shows linkback to harvest" do + harvest.photos << photo + visit photo_path(photo) + expect(page).to have_link harvest, :href => harvest_path(harvest) + end + end + + context "linked to garden" do + let (:garden) { FactoryGirl.create(:garden) } + + scenario "shows linkback to garden" do + garden.photos << photo + visit photo_path(photo) + expect(page).to have_link garden, :href => garden_path(garden) + end + + end + + end + +end + From 1c9081e7881561b16824353adebfa9a607e7e369 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Tue, 10 Feb 2015 20:52:42 +1100 Subject: [PATCH 005/392] remove duplicate test in views --- spec/views/photos/show.html.haml_spec.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/spec/views/photos/show.html.haml_spec.rb b/spec/views/photos/show.html.haml_spec.rb index 5ef9dc9c0..1b5b27990 100644 --- a/spec/views/photos/show.html.haml_spec.rb +++ b/spec/views/photos/show.html.haml_spec.rb @@ -46,19 +46,4 @@ describe "photos/show" do end - context "linked to a planting" do - before(:each) do - @photo = FactoryGirl.create(:photo) - @planting = FactoryGirl.create(:planting) - @planting.photos << @photo - @photo = assign(:photo, @photo) - render - end - - it "shows link to planting" do - assert_select "a[href=#{planting_path(@planting)}]" - end - - end - end From 102763f2ab37d891c8b82f0cbfd68982fcd99ed8 Mon Sep 17 00:00:00 2001 From: Taylor Griffin Date: Tue, 10 Feb 2015 22:12:22 +1100 Subject: [PATCH 006/392] link to new crop request form --- app/views/harvests/_form.html.haml | 2 +- app/views/plantings/_form.html.haml | 2 +- app/views/seeds/_form.html.haml | 2 +- config/environments/development.rb | 1 - config/environments/production.rb | 1 - config/environments/staging.rb | 1 - config/environments/test.rb | 1 - spec/views/plantings/edit.html.haml_spec.rb | 1 - spec/views/plantings/new.html.haml_spec.rb | 1 - 9 files changed, 3 insertions(+), 9 deletions(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 83aa71d08..806bf8701 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -14,7 +14,7 @@ = collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id }, { :class => 'form-control' }) %span.help-block.col-md-8 Can't find what you're looking for? - = link_to "Request new crops.", Growstuff::Application.config.new_crops_request_link + = link_to "Request new crops.", new_crop_path .form-group = f.label :harvested_at, 'When?', :class => 'control-label col-md-2' diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index b797d3523..9c166449a 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -12,7 +12,7 @@ = auto_suggest @planting, :crop, :class => 'form-control', :default => @crop %span.help-inline Can't find what you're looking for? - = link_to "Request new crops.", Growstuff::Application.config.new_crops_request_link + = link_to "Request new crops.", new_crop_path .form-group = f.label :garden_id, 'Where did you plant it?', :class => 'control-label col-md-2' .col-md-8 diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index 8d8eeaa97..4d80d8726 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -12,7 +12,7 @@ = auto_suggest @seed, :crop, :class => 'form-control', :default => @crop %span.help-inline Can't find what you're looking for? - = link_to "Request new crops.", Growstuff::Application.config.new_crops_request_link + = link_to "Request new crops.", new_crop_path .form-group = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2' .col-md-2 diff --git a/config/environments/development.rb b/config/environments/development.rb index 45d7b96bf..282071cda 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -44,7 +44,6 @@ Growstuff::Application.configure do # config.action_view.raise_on_missing_translations = true # Growstuff config - config.new_crops_request_link = "http://example.com/not-a-real-url" config.action_mailer.default_url_options = { :host => 'localhost:8080' } config.action_mailer.delivery_method = :letter_opener diff --git a/config/environments/production.rb b/config/environments/production.rb index 523418b32..2410617fb 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -67,7 +67,6 @@ Growstuff::Application.configure do config.active_record.dump_schema_after_migration = false # Growstuff configuration - config.new_crops_request_link = "http://growstuff.org/posts/skud-20130319-requests-for-new-crops" config.action_mailer.default_url_options = { :host => 'growstuff.org' } config.action_mailer.smtp_settings = { diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 150c62d8c..4b69b498c 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -69,7 +69,6 @@ Growstuff::Application.configure do config.active_record.dump_schema_after_migration = false # Growstuff configuration - config.new_crops_request_link = "http://example.com/not-a-real-url" config.action_mailer.default_url_options = { :host => 'staging.growstuff.org' } config.action_mailer.smtp_settings = { diff --git a/config/environments/test.rb b/config/environments/test.rb index ffdc4c972..8d99b4e84 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -40,7 +40,6 @@ Growstuff::Application.configure do # config.action_view.raise_on_missing_translations = true # Growstuff config - config.new_crops_request_link = "http://example.com/not-a-real-url" config.action_mailer.default_url_options = { :host => 'localhost:8080' } Growstuff::Application.configure do diff --git a/spec/views/plantings/edit.html.haml_spec.rb b/spec/views/plantings/edit.html.haml_spec.rb index 4cc06fcdc..2a690d0be 100644 --- a/spec/views/plantings/edit.html.haml_spec.rb +++ b/spec/views/plantings/edit.html.haml_spec.rb @@ -40,7 +40,6 @@ describe "plantings/edit" do it 'includes helpful links for crops and gardens' do assert_select "a[href=#{new_garden_path}]", :text => "Add a garden." - assert_select "a[href=#{Growstuff::Application.config.new_crops_request_link}]", :text => "Request new crops." end it "chooses the right crop" do diff --git a/spec/views/plantings/new.html.haml_spec.rb b/spec/views/plantings/new.html.haml_spec.rb index 455b9a411..2d35a47fb 100644 --- a/spec/views/plantings/new.html.haml_spec.rb +++ b/spec/views/plantings/new.html.haml_spec.rb @@ -41,7 +41,6 @@ describe "plantings/new" do it 'includes helpful links for crops and gardens' do assert_select "a[href=#{new_garden_path}]", :text => "Add a garden." - assert_select "a[href=#{Growstuff::Application.config.new_crops_request_link}]", :text => "Request new crops." end it "selects a garden given in a param" do From 7a064c0667f2daf5efbc9050b247253f22a41bb9 Mon Sep 17 00:00:00 2001 From: Nell Taylor & Heejin Park Date: Tue, 10 Feb 2015 15:02:10 -0600 Subject: [PATCH 007/392] Added 'current' scope to show only current plantings on gardens/index view and added accompanying view test --- app/views/gardens/index.html.haml | 4 ++-- spec/views/gardens/index.html.haml_spec.rb | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/views/gardens/index.html.haml b/app/views/gardens/index.html.haml index 2da035865..d1d26099e 100644 --- a/app/views/gardens/index.html.haml +++ b/app/views/gardens/index.html.haml @@ -50,14 +50,14 @@ None - else %ul - - garden.plantings.each do |p| + - garden.plantings.current.each do |p| %li = p.quantity = link_to p.crop.name, p - if p.planted_at planted on = p.planted_at - + %td= link_to 'Details', garden, :class => 'btn btn-default btn-xs' %div.pagination diff --git a/spec/views/gardens/index.html.haml_spec.rb b/spec/views/gardens/index.html.haml_spec.rb index a075822be..d5a8e8a5b 100644 --- a/spec/views/gardens/index.html.haml_spec.rb +++ b/spec/views/gardens/index.html.haml_spec.rb @@ -5,6 +5,7 @@ describe "gardens/index" do controller.stub(:current_user) { nil } @owner = FactoryGirl.create(:member) @garden = FactoryGirl.create(:garden, :owner => @owner) + @finished_planting = FactoryGirl.create(:finished_planting, :garden => @garden) page = 1 per_page = 2 total_entries = 2 @@ -22,4 +23,8 @@ describe "gardens/index" do assert_select "tr>td", :text => pluralize(@garden.area, @garden.area_unit), :count => 2 end + it "does not show finished plantings" do + render + expect(rendered).to_not have_content(@finished_planting.crop_name) + end end From 5bfab90b5b3d5a52f8cb67014aa78da76ea6b52f Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Thu, 12 Feb 2015 16:31:57 +1100 Subject: [PATCH 008/392] updated the crop search query for more accurate search --- app/models/crop.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/crop.rb b/app/models/crop.rb index 831c8ccb4..ff996143f 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -267,6 +267,7 @@ class Crop < ActiveRecord::Base query: { multi_match: { query: "#{search_str}", + analyzer: "standard", fields: ["name", "scientific_names.scientific_name", "alternate_names.name"] } }, From e09f050088bfeac5a0b85e64581fb84d16f2eda0 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Thu, 12 Feb 2015 16:31:57 +1100 Subject: [PATCH 009/392] updated the crop search query for more accurate search --- app/controllers/crops_controller.rb | 1 + app/models/crop.rb | 1 + 2 files changed, 2 insertions(+) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 92ee759a2..9e6bb005a 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -49,6 +49,7 @@ class CropsController < ApplicationController # GET /crops/search def search + @search = params[:search] @all_matches = Crop.search(params[:search]) exact_match = Crop.find_by_name(params[:search]) if exact_match diff --git a/app/models/crop.rb b/app/models/crop.rb index 831c8ccb4..ff996143f 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -267,6 +267,7 @@ class Crop < ActiveRecord::Base query: { multi_match: { query: "#{search_str}", + analyzer: "standard", fields: ["name", "scientific_names.scientific_name", "alternate_names.name"] } }, From 95974ab21bf669f46b5f6b7e42352fbbf6438f4c Mon Sep 17 00:00:00 2001 From: Taylor Griffin Date: Thu, 12 Feb 2015 19:52:53 +1100 Subject: [PATCH 010/392] add deprecation not to all controller and view specs --- .../account_types_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/accounts_controller_spec.rb | 16 ++++++++++++++++ .../controllers/admin/orders_controller_spec.rb | 17 +++++++++++++++++ spec/controllers/admin_controller_spec.rb | 16 ++++++++++++++++ .../authentications_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/comments_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/crops_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/forums_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/gardens_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/harvests_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/home_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/member_controller_spec.rb | 16 ++++++++++++++++ .../notifications_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/order_items_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/orders_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/photos_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/places_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/plant_parts_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/plantings_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/posts_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/products_controller_spec.rb | 16 ++++++++++++++++ .../registrations_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/roles_controller_spec.rb | 16 ++++++++++++++++ .../scientific_names_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/seeds_controller_spec.rb | 16 ++++++++++++++++ spec/controllers/shop_controller_spec.rb | 16 ++++++++++++++++ spec/views/about/contact_spec.rb | 16 ++++++++++++++++ spec/views/account_types/edit.html.haml_spec.rb | 16 ++++++++++++++++ .../views/account_types/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/account_types/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/account_types/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/accounts/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/accounts/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/accounts/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/accounts/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/admin/index_spec.rb | 16 ++++++++++++++++ spec/views/admin/newsletter_spec.rb | 16 ++++++++++++++++ spec/views/admin/orders/index_spec.rb | 16 ++++++++++++++++ spec/views/comments/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/comments/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/comments/index.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/comments/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/comments/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/_grown_for.html.haml_spec.rb | 16 ++++++++++++++++ .../crops/_planting_advice.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/_popover.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/hierarchy.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/index.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/crops/wrangle.html.haml_spec.rb | 16 ++++++++++++++++ .../mailer/confirmation_instructions_spec.rb | 16 ++++++++++++++++ .../mailer/reset_password_instructions_spec.rb | 16 ++++++++++++++++ .../devise/mailer/unlock_instructions_spec.rb | 16 ++++++++++++++++ spec/views/devise/registrations/edit_spec.rb | 16 ++++++++++++++++ spec/views/devise/registrations/new_spec.rb | 16 ++++++++++++++++ spec/views/devise/sessions/new_spec.rb | 16 ++++++++++++++++ spec/views/devise/unlocks/new_spec.rb | 16 ++++++++++++++++ spec/views/forums/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/forums/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/forums/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/forums/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/gardens/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/gardens/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/gardens/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/gardens/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/harvests/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/harvests/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/harvests/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/harvests/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/_blurb.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/_crops.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/_members.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/_seeds.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/_stats.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/home/index_spec.rb | 16 ++++++++++++++++ spec/views/layouts/_header_spec.rb | 16 ++++++++++++++++ spec/views/layouts/_meta_spec.rb | 16 ++++++++++++++++ spec/views/layouts/application_spec.rb | 16 ++++++++++++++++ spec/views/members/_location.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/members/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/members/show.rss.haml_spec.rb | 16 ++++++++++++++++ .../views/notifications/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/notifications/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/notifications/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/notifier/notify.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/orders/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/orders/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/photos/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/photos/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/photos/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/photos/show.html.haml_spec.rb | 16 ++++++++++++++++ .../places/_map_attribution.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/places/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/places/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plant_parts/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plant_parts/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plant_parts/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plant_parts/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/_form.html.haml_spec.rb | 16 ++++++++++++++++ .../plantings/_thumbnail.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/index.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/plantings/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/policy/community_spec.rb | 16 ++++++++++++++++ spec/views/policy/tos_spec.rb | 16 ++++++++++++++++ spec/views/posts/_single.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/index.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/posts/show.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/products/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/products/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/products/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/products/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/roles/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/roles/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/roles/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/roles/show.html.haml_spec.rb | 16 ++++++++++++++++ .../scientific_names/edit.html.haml_spec.rb | 16 ++++++++++++++++ .../scientific_names/index.html.haml_spec.rb | 16 ++++++++++++++++ .../scientific_names/new.html.haml_spec.rb | 16 ++++++++++++++++ .../scientific_names/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/seeds/edit.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/seeds/index.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/seeds/index.rss.haml_spec.rb | 16 ++++++++++++++++ spec/views/seeds/new.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/seeds/show.html.haml_spec.rb | 16 ++++++++++++++++ spec/views/shop/index_spec.rb | 16 ++++++++++++++++ spec/views/support/index_spec.rb | 16 ++++++++++++++++ 135 files changed, 2161 insertions(+) diff --git a/spec/controllers/account_types_controller_spec.rb b/spec/controllers/account_types_controller_spec.rb index a22146a79..eca67cfbc 100644 --- a/spec/controllers/account_types_controller_spec.rb +++ b/spec/controllers/account_types_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe AccountTypesController do diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index eb2ff7f65..d3ea69f87 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe AccountsController do diff --git a/spec/controllers/admin/orders_controller_spec.rb b/spec/controllers/admin/orders_controller_spec.rb index 08dfb9933..aa79e2895 100644 --- a/spec/controllers/admin/orders_controller_spec.rb +++ b/spec/controllers/admin/orders_controller_spec.rb @@ -1,3 +1,20 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + + require 'rails_helper' describe Admin::OrdersController do diff --git a/spec/controllers/admin_controller_spec.rb b/spec/controllers/admin_controller_spec.rb index fc31f80b9..d939b9f6b 100644 --- a/spec/controllers/admin_controller_spec.rb +++ b/spec/controllers/admin_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe AdminController do diff --git a/spec/controllers/authentications_controller_spec.rb b/spec/controllers/authentications_controller_spec.rb index 4fc5b98a5..9365ed782 100644 --- a/spec/controllers/authentications_controller_spec.rb +++ b/spec/controllers/authentications_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe AuthenticationsController do diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index 0e10ffe42..cac37fe7e 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe CommentsController do diff --git a/spec/controllers/crops_controller_spec.rb b/spec/controllers/crops_controller_spec.rb index 54226c27c..b9b6d44ba 100644 --- a/spec/controllers/crops_controller_spec.rb +++ b/spec/controllers/crops_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe CropsController do diff --git a/spec/controllers/forums_controller_spec.rb b/spec/controllers/forums_controller_spec.rb index 369919ff6..6d52321a5 100644 --- a/spec/controllers/forums_controller_spec.rb +++ b/spec/controllers/forums_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe ForumsController do diff --git a/spec/controllers/gardens_controller_spec.rb b/spec/controllers/gardens_controller_spec.rb index 2bba8a2f8..5905c8200 100644 --- a/spec/controllers/gardens_controller_spec.rb +++ b/spec/controllers/gardens_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe GardensController do diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb index efd762368..f8f87042a 100644 --- a/spec/controllers/harvests_controller_spec.rb +++ b/spec/controllers/harvests_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe HarvestsController do diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index da5edc384..8d4aa3569 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe HomeController do diff --git a/spec/controllers/member_controller_spec.rb b/spec/controllers/member_controller_spec.rb index 35d5b0c6d..55231ead8 100644 --- a/spec/controllers/member_controller_spec.rb +++ b/spec/controllers/member_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe MembersController do diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index d55b7df26..858444312 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe NotificationsController do diff --git a/spec/controllers/order_items_controller_spec.rb b/spec/controllers/order_items_controller_spec.rb index c8d23a4fd..5188b5127 100644 --- a/spec/controllers/order_items_controller_spec.rb +++ b/spec/controllers/order_items_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe OrderItemsController do diff --git a/spec/controllers/orders_controller_spec.rb b/spec/controllers/orders_controller_spec.rb index d01f37f92..c884bdca9 100644 --- a/spec/controllers/orders_controller_spec.rb +++ b/spec/controllers/orders_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe OrdersController do diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index e231c8b96..286b23b64 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe PhotosController do diff --git a/spec/controllers/places_controller_spec.rb b/spec/controllers/places_controller_spec.rb index 0c83c206a..1f6da6ed0 100644 --- a/spec/controllers/places_controller_spec.rb +++ b/spec/controllers/places_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe PlacesController do diff --git a/spec/controllers/plant_parts_controller_spec.rb b/spec/controllers/plant_parts_controller_spec.rb index e813e0f38..75b2ad53d 100644 --- a/spec/controllers/plant_parts_controller_spec.rb +++ b/spec/controllers/plant_parts_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe PlantPartsController do diff --git a/spec/controllers/plantings_controller_spec.rb b/spec/controllers/plantings_controller_spec.rb index aa6fcbe4e..2e6b2e366 100644 --- a/spec/controllers/plantings_controller_spec.rb +++ b/spec/controllers/plantings_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe PlantingsController do diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 8121b318e..b11434a98 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe PostsController do diff --git a/spec/controllers/products_controller_spec.rb b/spec/controllers/products_controller_spec.rb index 5804ad09d..84875191d 100644 --- a/spec/controllers/products_controller_spec.rb +++ b/spec/controllers/products_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe ProductsController do diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 8c0a669b4..028356209 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe RegistrationsController do diff --git a/spec/controllers/roles_controller_spec.rb b/spec/controllers/roles_controller_spec.rb index f34bb79e3..7a5e5fce8 100644 --- a/spec/controllers/roles_controller_spec.rb +++ b/spec/controllers/roles_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe RolesController do diff --git a/spec/controllers/scientific_names_controller_spec.rb b/spec/controllers/scientific_names_controller_spec.rb index 45dd92066..47f3ff29c 100644 --- a/spec/controllers/scientific_names_controller_spec.rb +++ b/spec/controllers/scientific_names_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe ScientificNamesController do diff --git a/spec/controllers/seeds_controller_spec.rb b/spec/controllers/seeds_controller_spec.rb index 7b0da6593..97016cf31 100644 --- a/spec/controllers/seeds_controller_spec.rb +++ b/spec/controllers/seeds_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe SeedsController do diff --git a/spec/controllers/shop_controller_spec.rb b/spec/controllers/shop_controller_spec.rb index 626757b52..51bb36437 100644 --- a/spec/controllers/shop_controller_spec.rb +++ b/spec/controllers/shop_controller_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe ShopController do diff --git a/spec/views/about/contact_spec.rb b/spec/views/about/contact_spec.rb index f655a1394..ce5b5afec 100644 --- a/spec/views/about/contact_spec.rb +++ b/spec/views/about/contact_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'about/contact.html.haml', :type => "view" do diff --git a/spec/views/account_types/edit.html.haml_spec.rb b/spec/views/account_types/edit.html.haml_spec.rb index cf77a0402..e8aeae7c0 100644 --- a/spec/views/account_types/edit.html.haml_spec.rb +++ b/spec/views/account_types/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "account_types/edit" do diff --git a/spec/views/account_types/index.html.haml_spec.rb b/spec/views/account_types/index.html.haml_spec.rb index 1bbd0dc72..aed40b2af 100644 --- a/spec/views/account_types/index.html.haml_spec.rb +++ b/spec/views/account_types/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "account_types/index" do diff --git a/spec/views/account_types/new.html.haml_spec.rb b/spec/views/account_types/new.html.haml_spec.rb index a9e97ee54..1fd496b55 100644 --- a/spec/views/account_types/new.html.haml_spec.rb +++ b/spec/views/account_types/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "account_types/new" do diff --git a/spec/views/account_types/show.html.haml_spec.rb b/spec/views/account_types/show.html.haml_spec.rb index bee9cebd5..84861f8a3 100644 --- a/spec/views/account_types/show.html.haml_spec.rb +++ b/spec/views/account_types/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "account_types/show" do diff --git a/spec/views/accounts/edit.html.haml_spec.rb b/spec/views/accounts/edit.html.haml_spec.rb index 124ec1d12..522707304 100644 --- a/spec/views/accounts/edit.html.haml_spec.rb +++ b/spec/views/accounts/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "accounts/edit" do diff --git a/spec/views/accounts/index.html.haml_spec.rb b/spec/views/accounts/index.html.haml_spec.rb index e8c0f1a79..98802ad6d 100644 --- a/spec/views/accounts/index.html.haml_spec.rb +++ b/spec/views/accounts/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "accounts/index" do diff --git a/spec/views/accounts/new.html.haml_spec.rb b/spec/views/accounts/new.html.haml_spec.rb index 3a2b7cdbc..2cf2dcef7 100644 --- a/spec/views/accounts/new.html.haml_spec.rb +++ b/spec/views/accounts/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "accounts/new" do diff --git a/spec/views/accounts/show.html.haml_spec.rb b/spec/views/accounts/show.html.haml_spec.rb index 13dfc3589..7b4e273d1 100644 --- a/spec/views/accounts/show.html.haml_spec.rb +++ b/spec/views/accounts/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "accounts/show" do diff --git a/spec/views/admin/index_spec.rb b/spec/views/admin/index_spec.rb index eb9dd9d01..e82f7b641 100644 --- a/spec/views/admin/index_spec.rb +++ b/spec/views/admin/index_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'admin/index.html.haml', :type => "view" do diff --git a/spec/views/admin/newsletter_spec.rb b/spec/views/admin/newsletter_spec.rb index d072aee2e..6ea4abeb0 100644 --- a/spec/views/admin/newsletter_spec.rb +++ b/spec/views/admin/newsletter_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'admin/newsletter.html.haml', :type => "view" do diff --git a/spec/views/admin/orders/index_spec.rb b/spec/views/admin/orders/index_spec.rb index e4279fdd0..00fbd811e 100644 --- a/spec/views/admin/orders/index_spec.rb +++ b/spec/views/admin/orders/index_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'admin/orders/index.html.haml', :type => "view" do diff --git a/spec/views/comments/edit.html.haml_spec.rb b/spec/views/comments/edit.html.haml_spec.rb index 87ba9c549..a3ba59479 100644 --- a/spec/views/comments/edit.html.haml_spec.rb +++ b/spec/views/comments/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "comments/edit" do diff --git a/spec/views/comments/index.html.haml_spec.rb b/spec/views/comments/index.html.haml_spec.rb index 7161978ab..2c237da3a 100644 --- a/spec/views/comments/index.html.haml_spec.rb +++ b/spec/views/comments/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "comments/index" do diff --git a/spec/views/comments/index.rss.haml_spec.rb b/spec/views/comments/index.rss.haml_spec.rb index 5278a8b56..58c07a6c8 100644 --- a/spec/views/comments/index.rss.haml_spec.rb +++ b/spec/views/comments/index.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'comments/index.rss.haml' do diff --git a/spec/views/comments/new.html.haml_spec.rb b/spec/views/comments/new.html.haml_spec.rb index 4df929a54..981211c8d 100644 --- a/spec/views/comments/new.html.haml_spec.rb +++ b/spec/views/comments/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "comments/new" do diff --git a/spec/views/comments/show.html.haml_spec.rb b/spec/views/comments/show.html.haml_spec.rb index 7152a2715..80b59d33d 100644 --- a/spec/views/comments/show.html.haml_spec.rb +++ b/spec/views/comments/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "comments/show" do diff --git a/spec/views/crops/_grown_for.html.haml_spec.rb b/spec/views/crops/_grown_for.html.haml_spec.rb index 88cf618e5..d77e6ee29 100644 --- a/spec/views/crops/_grown_for.html.haml_spec.rb +++ b/spec/views/crops/_grown_for.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/_grown_for" do diff --git a/spec/views/crops/_planting_advice.html.haml_spec.rb b/spec/views/crops/_planting_advice.html.haml_spec.rb index 6c2a35481..c902a7827 100644 --- a/spec/views/crops/_planting_advice.html.haml_spec.rb +++ b/spec/views/crops/_planting_advice.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/_planting_advice" do diff --git a/spec/views/crops/_popover.html.haml_spec.rb b/spec/views/crops/_popover.html.haml_spec.rb index d503a7235..a98cc6e10 100644 --- a/spec/views/crops/_popover.html.haml_spec.rb +++ b/spec/views/crops/_popover.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/_popover" do diff --git a/spec/views/crops/edit.html.haml_spec.rb b/spec/views/crops/edit.html.haml_spec.rb index 031addb30..9942a10f8 100644 --- a/spec/views/crops/edit.html.haml_spec.rb +++ b/spec/views/crops/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/edit" do diff --git a/spec/views/crops/hierarchy.html.haml_spec.rb b/spec/views/crops/hierarchy.html.haml_spec.rb index 22b02d18f..9cef87105 100644 --- a/spec/views/crops/hierarchy.html.haml_spec.rb +++ b/spec/views/crops/hierarchy.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/hierarchy" do diff --git a/spec/views/crops/index.html.haml_spec.rb b/spec/views/crops/index.html.haml_spec.rb index 33ab3e07e..096f1632e 100644 --- a/spec/views/crops/index.html.haml_spec.rb +++ b/spec/views/crops/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/index" do diff --git a/spec/views/crops/index.rss.haml_spec.rb b/spec/views/crops/index.rss.haml_spec.rb index 0e8887411..b07eab95a 100644 --- a/spec/views/crops/index.rss.haml_spec.rb +++ b/spec/views/crops/index.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'crops/index.rss.haml' do diff --git a/spec/views/crops/new.html.haml_spec.rb b/spec/views/crops/new.html.haml_spec.rb index 0c834d738..9375019ad 100644 --- a/spec/views/crops/new.html.haml_spec.rb +++ b/spec/views/crops/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/new" do diff --git a/spec/views/crops/wrangle.html.haml_spec.rb b/spec/views/crops/wrangle.html.haml_spec.rb index 4426382d2..c0a29b4cd 100644 --- a/spec/views/crops/wrangle.html.haml_spec.rb +++ b/spec/views/crops/wrangle.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "crops/wrangle" do diff --git a/spec/views/devise/mailer/confirmation_instructions_spec.rb b/spec/views/devise/mailer/confirmation_instructions_spec.rb index e42dd762c..d1805f2f9 100644 --- a/spec/views/devise/mailer/confirmation_instructions_spec.rb +++ b/spec/views/devise/mailer/confirmation_instructions_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/mailer/confirmation_instructions.html.haml', :type => "view" do diff --git a/spec/views/devise/mailer/reset_password_instructions_spec.rb b/spec/views/devise/mailer/reset_password_instructions_spec.rb index d75f69881..28c76144f 100644 --- a/spec/views/devise/mailer/reset_password_instructions_spec.rb +++ b/spec/views/devise/mailer/reset_password_instructions_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/mailer/reset_password_instructions.html.haml', :type => "view" do diff --git a/spec/views/devise/mailer/unlock_instructions_spec.rb b/spec/views/devise/mailer/unlock_instructions_spec.rb index fd4c444f8..5112da12c 100644 --- a/spec/views/devise/mailer/unlock_instructions_spec.rb +++ b/spec/views/devise/mailer/unlock_instructions_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/mailer/unlock_instructions.html.haml', :type => "view" do context "logged in" do diff --git a/spec/views/devise/registrations/edit_spec.rb b/spec/views/devise/registrations/edit_spec.rb index c99b84aed..50f44d6e7 100644 --- a/spec/views/devise/registrations/edit_spec.rb +++ b/spec/views/devise/registrations/edit_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/registrations/edit.html.haml', :type => "view" do diff --git a/spec/views/devise/registrations/new_spec.rb b/spec/views/devise/registrations/new_spec.rb index f7dcfffe1..8a63d0884 100644 --- a/spec/views/devise/registrations/new_spec.rb +++ b/spec/views/devise/registrations/new_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/registrations/new.html.haml', :type => "view" do diff --git a/spec/views/devise/sessions/new_spec.rb b/spec/views/devise/sessions/new_spec.rb index 6d66e6a48..418b53d56 100644 --- a/spec/views/devise/sessions/new_spec.rb +++ b/spec/views/devise/sessions/new_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/sessions/new.html.haml', :type => "view" do diff --git a/spec/views/devise/unlocks/new_spec.rb b/spec/views/devise/unlocks/new_spec.rb index fec998c4d..4a060d78f 100644 --- a/spec/views/devise/unlocks/new_spec.rb +++ b/spec/views/devise/unlocks/new_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'devise/unlocks/new.html.haml', :type => "view" do diff --git a/spec/views/forums/edit.html.haml_spec.rb b/spec/views/forums/edit.html.haml_spec.rb index 8a49b38be..762a6d806 100644 --- a/spec/views/forums/edit.html.haml_spec.rb +++ b/spec/views/forums/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "forums/edit" do diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index a946c2407..93d7090a9 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "forums/index" do diff --git a/spec/views/forums/new.html.haml_spec.rb b/spec/views/forums/new.html.haml_spec.rb index 86043eb8c..5785b1b21 100644 --- a/spec/views/forums/new.html.haml_spec.rb +++ b/spec/views/forums/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "forums/new" do diff --git a/spec/views/forums/show.html.haml_spec.rb b/spec/views/forums/show.html.haml_spec.rb index 45ff9aeed..119e411f6 100644 --- a/spec/views/forums/show.html.haml_spec.rb +++ b/spec/views/forums/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "forums/show" do diff --git a/spec/views/gardens/edit.html.haml_spec.rb b/spec/views/gardens/edit.html.haml_spec.rb index e5381c324..3900dad35 100644 --- a/spec/views/gardens/edit.html.haml_spec.rb +++ b/spec/views/gardens/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "gardens/edit" do diff --git a/spec/views/gardens/index.html.haml_spec.rb b/spec/views/gardens/index.html.haml_spec.rb index a075822be..a16964d11 100644 --- a/spec/views/gardens/index.html.haml_spec.rb +++ b/spec/views/gardens/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "gardens/index" do diff --git a/spec/views/gardens/new.html.haml_spec.rb b/spec/views/gardens/new.html.haml_spec.rb index ff52f1f28..056079f89 100644 --- a/spec/views/gardens/new.html.haml_spec.rb +++ b/spec/views/gardens/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "gardens/new" do diff --git a/spec/views/gardens/show.html.haml_spec.rb b/spec/views/gardens/show.html.haml_spec.rb index 6327073ee..7c4f2c143 100644 --- a/spec/views/gardens/show.html.haml_spec.rb +++ b/spec/views/gardens/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "gardens/show" do diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index 4802bab88..f7c175667 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "harvests/edit" do diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index 8751a5c41..eb5c0491b 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "harvests/index" do diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 93a595188..015b94dda 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "harvests/new" do diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb index 7c897a684..56d69b608 100644 --- a/spec/views/harvests/show.html.haml_spec.rb +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "harvests/show" do diff --git a/spec/views/home/_blurb.html.haml_spec.rb b/spec/views/home/_blurb.html.haml_spec.rb index 285363e5e..e61f2be63 100644 --- a/spec/views/home/_blurb.html.haml_spec.rb +++ b/spec/views/home/_blurb.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/_blurb.html.haml', :type => "view" do diff --git a/spec/views/home/_crops.html.haml_spec.rb b/spec/views/home/_crops.html.haml_spec.rb index 548e0a375..c82066b57 100644 --- a/spec/views/home/_crops.html.haml_spec.rb +++ b/spec/views/home/_crops.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/_crops.html.haml', :type => "view" do diff --git a/spec/views/home/_members.html.haml_spec.rb b/spec/views/home/_members.html.haml_spec.rb index 81f812a94..5bda606ed 100644 --- a/spec/views/home/_members.html.haml_spec.rb +++ b/spec/views/home/_members.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/_members.html.haml', :type => "view" do diff --git a/spec/views/home/_seeds.html.haml_spec.rb b/spec/views/home/_seeds.html.haml_spec.rb index 82efa194d..148cc2ea0 100644 --- a/spec/views/home/_seeds.html.haml_spec.rb +++ b/spec/views/home/_seeds.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/_seeds.html.haml', :type => "view" do diff --git a/spec/views/home/_stats.html.haml_spec.rb b/spec/views/home/_stats.html.haml_spec.rb index b067e44f8..f1a78b62c 100644 --- a/spec/views/home/_stats.html.haml_spec.rb +++ b/spec/views/home/_stats.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/_stats.html.haml', :type => "view" do diff --git a/spec/views/home/index_spec.rb b/spec/views/home/index_spec.rb index fe651e149..5d45dcb2d 100644 --- a/spec/views/home/index_spec.rb +++ b/spec/views/home/index_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'home/index.html.haml', :type => "view" do diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index f4ca3034a..57bf3263a 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'layouts/_header.html.haml', :type => "view" do diff --git a/spec/views/layouts/_meta_spec.rb b/spec/views/layouts/_meta_spec.rb index 8419ea129..a181a4414 100644 --- a/spec/views/layouts/_meta_spec.rb +++ b/spec/views/layouts/_meta_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'layouts/_meta.html.haml', :type => "view" do diff --git a/spec/views/layouts/application_spec.rb b/spec/views/layouts/application_spec.rb index 45f1e7553..0679af903 100644 --- a/spec/views/layouts/application_spec.rb +++ b/spec/views/layouts/application_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'layouts/application.html.haml', :type => "view" do diff --git a/spec/views/members/_location.html.haml_spec.rb b/spec/views/members/_location.html.haml_spec.rb index 54c5d1198..5c4b229a3 100644 --- a/spec/views/members/_location.html.haml_spec.rb +++ b/spec/views/members/_location.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "members/_location" do diff --git a/spec/views/members/index.html.haml_spec.rb b/spec/views/members/index.html.haml_spec.rb index e9174ffd7..02dda186a 100644 --- a/spec/views/members/index.html.haml_spec.rb +++ b/spec/views/members/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "members/index" do diff --git a/spec/views/members/show.rss.haml_spec.rb b/spec/views/members/show.rss.haml_spec.rb index e5619cdd6..e4aab16a7 100644 --- a/spec/views/members/show.rss.haml_spec.rb +++ b/spec/views/members/show.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'members/show.rss.haml', :type => "view" do diff --git a/spec/views/notifications/index.html.haml_spec.rb b/spec/views/notifications/index.html.haml_spec.rb index 43fd80ede..04ecdd176 100644 --- a/spec/views/notifications/index.html.haml_spec.rb +++ b/spec/views/notifications/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "notifications/index" do diff --git a/spec/views/notifications/new.html.haml_spec.rb b/spec/views/notifications/new.html.haml_spec.rb index 8b77f6422..2ec73bca3 100644 --- a/spec/views/notifications/new.html.haml_spec.rb +++ b/spec/views/notifications/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "notifications/new" do diff --git a/spec/views/notifications/show.html.haml_spec.rb b/spec/views/notifications/show.html.haml_spec.rb index cc33a07e4..4e9f27dbf 100644 --- a/spec/views/notifications/show.html.haml_spec.rb +++ b/spec/views/notifications/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "notifications/show" do diff --git a/spec/views/notifier/notify.html.haml_spec.rb b/spec/views/notifier/notify.html.haml_spec.rb index b5740b548..5cb6aac73 100644 --- a/spec/views/notifier/notify.html.haml_spec.rb +++ b/spec/views/notifier/notify.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'notifier/notify.html.haml', :type => "view" do diff --git a/spec/views/orders/index.html.haml_spec.rb b/spec/views/orders/index.html.haml_spec.rb index ad2116df7..1ca2889e0 100644 --- a/spec/views/orders/index.html.haml_spec.rb +++ b/spec/views/orders/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "orders/index" do diff --git a/spec/views/orders/show.html.haml_spec.rb b/spec/views/orders/show.html.haml_spec.rb index 98d0eb5e0..3779795e6 100644 --- a/spec/views/orders/show.html.haml_spec.rb +++ b/spec/views/orders/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "orders/show" do diff --git a/spec/views/photos/edit.html.haml_spec.rb b/spec/views/photos/edit.html.haml_spec.rb index f3a9a0ed7..a13aea7c6 100644 --- a/spec/views/photos/edit.html.haml_spec.rb +++ b/spec/views/photos/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "photos/edit" do diff --git a/spec/views/photos/index.html.haml_spec.rb b/spec/views/photos/index.html.haml_spec.rb index 5daaa1eda..866302895 100644 --- a/spec/views/photos/index.html.haml_spec.rb +++ b/spec/views/photos/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "photos/index" do diff --git a/spec/views/photos/new.html.haml_spec.rb b/spec/views/photos/new.html.haml_spec.rb index 8f0f241e3..3c2321aef 100644 --- a/spec/views/photos/new.html.haml_spec.rb +++ b/spec/views/photos/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "photos/new" do diff --git a/spec/views/photos/show.html.haml_spec.rb b/spec/views/photos/show.html.haml_spec.rb index 5ef9dc9c0..15013f6c0 100644 --- a/spec/views/photos/show.html.haml_spec.rb +++ b/spec/views/photos/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "photos/show" do diff --git a/spec/views/places/_map_attribution.html.haml_spec.rb b/spec/views/places/_map_attribution.html.haml_spec.rb index d85875376..e2bc7e5b0 100644 --- a/spec/views/places/_map_attribution.html.haml_spec.rb +++ b/spec/views/places/_map_attribution.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "places/_map_attribution.html.haml", :type => :view do diff --git a/spec/views/places/index.html.haml_spec.rb b/spec/views/places/index.html.haml_spec.rb index f3a3661ae..10c5caca6 100644 --- a/spec/views/places/index.html.haml_spec.rb +++ b/spec/views/places/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "places/index" do diff --git a/spec/views/places/show.html.haml_spec.rb b/spec/views/places/show.html.haml_spec.rb index 8e3e346c5..13884eb3b 100644 --- a/spec/views/places/show.html.haml_spec.rb +++ b/spec/views/places/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "places/show" do diff --git a/spec/views/plant_parts/edit.html.haml_spec.rb b/spec/views/plant_parts/edit.html.haml_spec.rb index 6193ef1b0..fc25b711b 100644 --- a/spec/views/plant_parts/edit.html.haml_spec.rb +++ b/spec/views/plant_parts/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plant_parts/edit" do diff --git a/spec/views/plant_parts/index.html.haml_spec.rb b/spec/views/plant_parts/index.html.haml_spec.rb index 1a9469c55..256810ac3 100644 --- a/spec/views/plant_parts/index.html.haml_spec.rb +++ b/spec/views/plant_parts/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plant_parts/index" do diff --git a/spec/views/plant_parts/new.html.haml_spec.rb b/spec/views/plant_parts/new.html.haml_spec.rb index d512ecee1..64b572ef7 100644 --- a/spec/views/plant_parts/new.html.haml_spec.rb +++ b/spec/views/plant_parts/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plant_parts/new" do diff --git a/spec/views/plant_parts/show.html.haml_spec.rb b/spec/views/plant_parts/show.html.haml_spec.rb index b65ecb154..fa839419f 100644 --- a/spec/views/plant_parts/show.html.haml_spec.rb +++ b/spec/views/plant_parts/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plant_parts/show" do diff --git a/spec/views/plantings/_form.html.haml_spec.rb b/spec/views/plantings/_form.html.haml_spec.rb index 88b12bd9e..f65fd82eb 100644 --- a/spec/views/plantings/_form.html.haml_spec.rb +++ b/spec/views/plantings/_form.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/_form" do diff --git a/spec/views/plantings/_thumbnail.html.haml_spec.rb b/spec/views/plantings/_thumbnail.html.haml_spec.rb index dd5cc2003..279dfda56 100644 --- a/spec/views/plantings/_thumbnail.html.haml_spec.rb +++ b/spec/views/plantings/_thumbnail.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/_thumbnail" do diff --git a/spec/views/plantings/edit.html.haml_spec.rb b/spec/views/plantings/edit.html.haml_spec.rb index 4cc06fcdc..08b4744f8 100644 --- a/spec/views/plantings/edit.html.haml_spec.rb +++ b/spec/views/plantings/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/edit" do diff --git a/spec/views/plantings/index.html.haml_spec.rb b/spec/views/plantings/index.html.haml_spec.rb index 6a130c8c9..9c890caf4 100644 --- a/spec/views/plantings/index.html.haml_spec.rb +++ b/spec/views/plantings/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/index" do diff --git a/spec/views/plantings/index.rss.haml_spec.rb b/spec/views/plantings/index.rss.haml_spec.rb index c953382ce..9f3d7ccc1 100644 --- a/spec/views/plantings/index.rss.haml_spec.rb +++ b/spec/views/plantings/index.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'plantings/index.rss.haml' do diff --git a/spec/views/plantings/new.html.haml_spec.rb b/spec/views/plantings/new.html.haml_spec.rb index 455b9a411..baa8188ae 100644 --- a/spec/views/plantings/new.html.haml_spec.rb +++ b/spec/views/plantings/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/new" do diff --git a/spec/views/plantings/show.html.haml_spec.rb b/spec/views/plantings/show.html.haml_spec.rb index 28a44078a..09fc18eed 100644 --- a/spec/views/plantings/show.html.haml_spec.rb +++ b/spec/views/plantings/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "plantings/show" do diff --git a/spec/views/policy/community_spec.rb b/spec/views/policy/community_spec.rb index 17f6d3b11..df7c828fb 100644 --- a/spec/views/policy/community_spec.rb +++ b/spec/views/policy/community_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'policy/community.html.haml', :type => "view" do diff --git a/spec/views/policy/tos_spec.rb b/spec/views/policy/tos_spec.rb index 24cacdf0d..56f08e928 100644 --- a/spec/views/policy/tos_spec.rb +++ b/spec/views/policy/tos_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'policy/tos.html.haml', :type => "view" do diff --git a/spec/views/posts/_single.html.haml_spec.rb b/spec/views/posts/_single.html.haml_spec.rb index 268db854d..284542965 100644 --- a/spec/views/posts/_single.html.haml_spec.rb +++ b/spec/views/posts/_single.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "posts/_single" do diff --git a/spec/views/posts/edit.html.haml_spec.rb b/spec/views/posts/edit.html.haml_spec.rb index 7b3f0b195..12fd02c27 100644 --- a/spec/views/posts/edit.html.haml_spec.rb +++ b/spec/views/posts/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "posts/edit" do diff --git a/spec/views/posts/index.html.haml_spec.rb b/spec/views/posts/index.html.haml_spec.rb index d5d49951a..2f2f42d78 100644 --- a/spec/views/posts/index.html.haml_spec.rb +++ b/spec/views/posts/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "posts/index" do diff --git a/spec/views/posts/index.rss.haml_spec.rb b/spec/views/posts/index.rss.haml_spec.rb index 0a303f19b..b29dae565 100644 --- a/spec/views/posts/index.rss.haml_spec.rb +++ b/spec/views/posts/index.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'posts/index.rss.haml', :type => "view" do diff --git a/spec/views/posts/new.html.haml_spec.rb b/spec/views/posts/new.html.haml_spec.rb index 73448e24c..8b0da615e 100644 --- a/spec/views/posts/new.html.haml_spec.rb +++ b/spec/views/posts/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "posts/new" do diff --git a/spec/views/posts/show.html.haml_spec.rb b/spec/views/posts/show.html.haml_spec.rb index e1ea7a77e..13faf053d 100644 --- a/spec/views/posts/show.html.haml_spec.rb +++ b/spec/views/posts/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "posts/show" do diff --git a/spec/views/posts/show.rss.haml_spec.rb b/spec/views/posts/show.rss.haml_spec.rb index 72e8e7347..08d6da814 100644 --- a/spec/views/posts/show.rss.haml_spec.rb +++ b/spec/views/posts/show.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'posts/show.rss.haml' do diff --git a/spec/views/products/edit.html.haml_spec.rb b/spec/views/products/edit.html.haml_spec.rb index 3505c0216..4574064a7 100644 --- a/spec/views/products/edit.html.haml_spec.rb +++ b/spec/views/products/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "products/edit" do diff --git a/spec/views/products/index.html.haml_spec.rb b/spec/views/products/index.html.haml_spec.rb index 2b96540c1..dcd85623d 100644 --- a/spec/views/products/index.html.haml_spec.rb +++ b/spec/views/products/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "products/index" do diff --git a/spec/views/products/new.html.haml_spec.rb b/spec/views/products/new.html.haml_spec.rb index ab7bc5f7e..08986cacf 100644 --- a/spec/views/products/new.html.haml_spec.rb +++ b/spec/views/products/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "products/new" do diff --git a/spec/views/products/show.html.haml_spec.rb b/spec/views/products/show.html.haml_spec.rb index c33fd2b81..6fcb35654 100644 --- a/spec/views/products/show.html.haml_spec.rb +++ b/spec/views/products/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "products/show" do diff --git a/spec/views/roles/edit.html.haml_spec.rb b/spec/views/roles/edit.html.haml_spec.rb index 2b12e05d5..e4b927471 100644 --- a/spec/views/roles/edit.html.haml_spec.rb +++ b/spec/views/roles/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "roles/edit" do diff --git a/spec/views/roles/index.html.haml_spec.rb b/spec/views/roles/index.html.haml_spec.rb index 1b732c381..6e821daff 100644 --- a/spec/views/roles/index.html.haml_spec.rb +++ b/spec/views/roles/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "roles/index" do diff --git a/spec/views/roles/new.html.haml_spec.rb b/spec/views/roles/new.html.haml_spec.rb index bba7e62b7..3073f7f35 100644 --- a/spec/views/roles/new.html.haml_spec.rb +++ b/spec/views/roles/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "roles/new" do diff --git a/spec/views/roles/show.html.haml_spec.rb b/spec/views/roles/show.html.haml_spec.rb index 16f48415f..889535194 100644 --- a/spec/views/roles/show.html.haml_spec.rb +++ b/spec/views/roles/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "roles/show" do diff --git a/spec/views/scientific_names/edit.html.haml_spec.rb b/spec/views/scientific_names/edit.html.haml_spec.rb index 3e5dc9e91..f85bab335 100644 --- a/spec/views/scientific_names/edit.html.haml_spec.rb +++ b/spec/views/scientific_names/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "scientific_names/edit" do diff --git a/spec/views/scientific_names/index.html.haml_spec.rb b/spec/views/scientific_names/index.html.haml_spec.rb index a49b9ef88..2fb36e99d 100644 --- a/spec/views/scientific_names/index.html.haml_spec.rb +++ b/spec/views/scientific_names/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "scientific_names/index" do diff --git a/spec/views/scientific_names/new.html.haml_spec.rb b/spec/views/scientific_names/new.html.haml_spec.rb index 151908e7d..2ca9f68c0 100644 --- a/spec/views/scientific_names/new.html.haml_spec.rb +++ b/spec/views/scientific_names/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "scientific_names/new" do diff --git a/spec/views/scientific_names/show.html.haml_spec.rb b/spec/views/scientific_names/show.html.haml_spec.rb index d2927c5a9..c16fbe444 100644 --- a/spec/views/scientific_names/show.html.haml_spec.rb +++ b/spec/views/scientific_names/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "scientific_names/show" do diff --git a/spec/views/seeds/edit.html.haml_spec.rb b/spec/views/seeds/edit.html.haml_spec.rb index 6a0235e4b..9bdcf9447 100644 --- a/spec/views/seeds/edit.html.haml_spec.rb +++ b/spec/views/seeds/edit.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "seeds/edit" do diff --git a/spec/views/seeds/index.html.haml_spec.rb b/spec/views/seeds/index.html.haml_spec.rb index a1d478544..0cf2ade0b 100644 --- a/spec/views/seeds/index.html.haml_spec.rb +++ b/spec/views/seeds/index.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "seeds/index" do diff --git a/spec/views/seeds/index.rss.haml_spec.rb b/spec/views/seeds/index.rss.haml_spec.rb index 485f390d0..5e88fc014 100644 --- a/spec/views/seeds/index.rss.haml_spec.rb +++ b/spec/views/seeds/index.rss.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'seeds/index.rss.haml' do diff --git a/spec/views/seeds/new.html.haml_spec.rb b/spec/views/seeds/new.html.haml_spec.rb index 9abb2f291..82bc32bd4 100644 --- a/spec/views/seeds/new.html.haml_spec.rb +++ b/spec/views/seeds/new.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "seeds/new" do diff --git a/spec/views/seeds/show.html.haml_spec.rb b/spec/views/seeds/show.html.haml_spec.rb index af00b4efe..660eadfb9 100644 --- a/spec/views/seeds/show.html.haml_spec.rb +++ b/spec/views/seeds/show.html.haml_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe "seeds/show" do diff --git a/spec/views/shop/index_spec.rb b/spec/views/shop/index_spec.rb index ee9ee59a9..cf4baae91 100644 --- a/spec/views/shop/index_spec.rb +++ b/spec/views/shop/index_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'shop/index.html.haml', :type => "view" do diff --git a/spec/views/support/index_spec.rb b/spec/views/support/index_spec.rb index fc3a96b12..5d9ce615d 100644 --- a/spec/views/support/index_spec.rb +++ b/spec/views/support/index_spec.rb @@ -1,3 +1,19 @@ +## DEPRECATION NOTICE: Do not add new tests to this file! +## +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. +## +## If you submit a pull request containing new view or controller tests, it will not be +## merged. + + + + + require 'rails_helper' describe 'support/index.html.haml', :type => "view" do From 70cdab96c4a4c792f598e88491dbfed886d410f9 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Thu, 12 Feb 2015 23:00:04 +1100 Subject: [PATCH 011/392] fixing issue with 1)paginating crop search and 2)crop name autocomplete --- app/controllers/crops_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index fc0ce9bb5..e1e246dbf 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -1,3 +1,5 @@ +require 'will_paginate/array' + class CropsController < ApplicationController before_filter :authenticate_member!, :except => [:index, :hierarchy, :search, :show] load_and_authorize_resource @@ -73,7 +75,7 @@ class CropsController < ApplicationController respond_to do |format| format.html - format.json { render :json => Crop.search(@search) } + format.json { render :json => Crop.search(params[:term]) } end end From 90ca5ec13beb42adc88fd3a5ea9dc2b005bc42d5 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Fri, 13 Feb 2015 23:39:31 +1100 Subject: [PATCH 012/392] added thumbnails of crops mentioned on post page --- app/views/posts/_single.html.haml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/views/posts/_single.html.haml b/app/views/posts/_single.html.haml index 8f5cc5507..e301ed76a 100644 --- a/app/views/posts/_single.html.haml +++ b/app/views/posts/_single.html.haml @@ -21,6 +21,14 @@ :growstuff_markdown #{ strip_tags post.body } + - unless post.crops.empty? + .hidden-xs + %h3 Crops mentioned in this post + - post.crops.each do |c| + - unless c.photos.empty? + .col-md-2{:style => 'padding-bottom: 6px'} + = render :partial => 'crops/image_with_popover', :locals => { :crop => c } + .col-md-11 - unless defined?(hide_comments) .post-comments %ul.list-inline From 6f80102f790f59d1b80ff96c6e37d8b547c89406 Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Mon, 16 Feb 2015 12:27:18 +0000 Subject: [PATCH 013/392] Adding autoloaded crop factory for later testing --- spec/factories/crop.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/factories/crop.rb b/spec/factories/crop.rb index c6839e983..92ec03572 100644 --- a/spec/factories/crop.rb +++ b/spec/factories/crop.rb @@ -53,6 +53,10 @@ FactoryGirl.define do factory :uppercasecrop do name "Swiss chard" end + + factory :autoloaded_crop do + creator "cropbot" + end end From eb76db93e469290b721d0ed766424091a036baba Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Mon, 16 Feb 2015 13:34:37 +0000 Subject: [PATCH 014/392] Switching to new secrets format as per http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#config-secrets-yml --- config/initializers/secret_token.rb | 7 ------- config/secrets.yml | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 7 deletions(-) delete mode 100644 config/initializers/secret_token.rb create mode 100644 config/secrets.yml diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb deleted file mode 100644 index 8ebcc27d3..000000000 --- a/config/initializers/secret_token.rb +++ /dev/null @@ -1,7 +0,0 @@ -# Be sure to restart your server when you modify this file. - -# Your secret key for verifying the integrity of signed cookies. -# If you change this key, all old signed cookies will become invalid! -# Make sure the secret is at least 30 characters and all random, -# no regular words or you'll be exposed to dictionary attacks. -Growstuff::Application.config.secret_token = ENV['RAILS_SECRET_TOKEN'] || "this is not a real secret token but it's here to make life easier for developers" diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..1abbd84c7 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,17 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. + +development: + secret_key_base: 'b1b67abb399261478f4721e704eb3851466daf60d9cd2b53a1839b056d641c4c1c2a476bcaf7addc6d6548926cfd32fa5a00a8de258880257ebb5a6fd86cb08f' + # run 'rake secret' to generate your own + +test: + secret_key_base: 'be557aa019b181f201c9906663dbf8f22efb1b70b11f78035bfeda86aa7dcfd1efb184e2ee894a0ae0dc37fe67d311f38e7731fa16d8d595f2e1ef5447bae020' + # run 'rake secret' to generate your own + +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> \ No newline at end of file From 9b195d1d2ef9724d44a1025598c5b8821f75b7d8 Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Mon, 16 Feb 2015 13:42:57 +0000 Subject: [PATCH 015/392] Fixing line break --- config/secrets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/secrets.yml b/config/secrets.yml index 1abbd84c7..c522ed925 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -14,4 +14,4 @@ test: # run 'rake secret' to generate your own production: - secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> \ No newline at end of file + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> From cd12412b46e988b23b3745350c73e847ef102c5b Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Mon, 16 Feb 2015 23:19:25 -0500 Subject: [PATCH 016/392] move cms admin to /admin/cms at skud's request --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 69680ae2d..542cf8c51 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -79,6 +79,7 @@ Growstuff::Application.routes.draw do get '/shop' => 'shop#index' get '/shop/:action' => 'shop#:action' + comfy_route :cms_admin, :path => '/admin/cms' get '/admin/orders' => 'admin/orders#index' get '/admin/orders/:action' => 'admin/orders#:action' get '/admin' => 'admin#index' @@ -86,7 +87,6 @@ Growstuff::Application.routes.draw do get '/admin/:action' => 'admin#:action' # CMS stuff -- must remain LAST - comfy_route :cms_admin, :path => '/cms/admin' comfy_route :cms, :path => '/', :sitemap => false end From d0f856d389842c1a9c807649693fed196a8623fa Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Feb 2015 19:20:25 +1100 Subject: [PATCH 017/392] Fixed various problems with search matching --- app/controllers/crops_controller.rb | 13 ++++--------- app/helpers/auto_suggest_helper.rb | 2 +- app/models/crop.rb | 16 +++++++++++++++- app/views/crops/search.html.haml | 16 ++++++++-------- app/views/layouts/_header.html.haml | 4 ++-- spec/features/crops/crop_search_spec.rb | 2 +- spec/features/shared_examples/crop_suggest.rb | 12 +++++++++--- spec/views/layouts/_header_spec.rb | 2 +- 8 files changed, 41 insertions(+), 26 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index e1e246dbf..b8ad4f5c8 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -64,18 +64,13 @@ class CropsController < ApplicationController # GET /crops/search def search - @search = params[:search] - @all_matches = Crop.search(@search) - @paginated_matches = @all_matches.paginate(:page => params[:page]) - exact_match = Crop.find_by_name(@search) - if exact_match - @all_matches.delete(exact_match) - @all_matches.unshift(exact_match) - end + @term = params[:term] + @matches = Crop.search(@term) + @paginated_matches = @matches.paginate(:page => params[:page]) respond_to do |format| format.html - format.json { render :json => Crop.search(params[:term]) } + format.json { render :json => @matches } end end diff --git a/app/helpers/auto_suggest_helper.rb b/app/helpers/auto_suggest_helper.rb index 3b6cb3ce8..f7722c59c 100644 --- a/app/helpers/auto_suggest_helper.rb +++ b/app/helpers/auto_suggest_helper.rb @@ -19,4 +19,4 @@ module AutoSuggestHelper }.html_safe end -end \ No newline at end of file +end diff --git a/app/models/crop.rb b/app/models/crop.rb index 0571feecd..96bf2120d 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -316,7 +316,21 @@ class Crop < ActiveRecord::Base ) return response.records.to_a else - where("name ILIKE ?", "%#{query}%").load + # if we don't have elasticsearch, just do a basic SQL query. + # also, make sure it's an actual array not an activerecord + # collection, so it matches what we get from elasticsearch and we can + # manipulate it in the same ways (eg. deleting elements without deleting + # the whole record from the db) + matches = where("name ILIKE ?", "%#{query}%").to_a + + # we want to make sure that exact matches come first, even if not + # using elasticsearch (eg. in development) + exact_match = Crop.find_by_name(query) + if exact_match + matches.delete(exact_match) + matches.unshift(exact_match) + end + return matches end end diff --git a/app/views/crops/search.html.haml b/app/views/crops/search.html.haml index 9b57e1b7a..a00574cee 100644 --- a/app/views/crops/search.html.haml +++ b/app/views/crops/search.html.haml @@ -1,21 +1,21 @@ -- if @search - - content_for :title, "Crops matching \"#{@search}\"" - - if @all_matches - - content_for :subtitle, "#{@all_matches.size} total" +- if @term + - content_for :title, "Crops matching \"#{@term}\"" + - if @matches + - content_for :subtitle, "#{@matches.size} total" - else - content_for :title, "Crop search" %div = form_tag crops_search_path, :method => :get, :id => 'crop-search', :class => 'form-inline' do .form-group - = label_tag :search, "Search crops:", :class => 'sr-only' - = text_field_tag 'search', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops', :value => @search + = label_tag :term, "Search crops:", :class => 'sr-only' + = text_field_tag 'term', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops', :value => @term = submit_tag "Search", :class => 'btn btn-primary' -- if @all_matches.empty? +- if @matches.empty? %h2 No results found %p - Sorry, we couldn't find any crops that matched your search for "#{@search}". + Sorry, we couldn't find any crops that matched your search for "#{@term}". %p Try = link_to "browsing our crop database", crops_path diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 7560ebeec..80ba2637b 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -70,8 +70,8 @@ = form_tag crops_search_path, :method => :get, :id => 'navbar-search', :class => 'navbar-form pull-right' do .input - = label_tag :search, "Search crop database:", :class => 'sr-only' - = text_field_tag 'search', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops' + = label_tag :term, "Search crop database:", :class => 'sr-only' + = text_field_tag 'term', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops' = submit_tag "Search", :class => 'btn sr-only' - # anchor tag for accessibility link to skip the navigation menu diff --git a/spec/features/crops/crop_search_spec.rb b/spec/features/crops/crop_search_spec.rb index 48e68dfc2..f2f86980c 100644 --- a/spec/features/crops/crop_search_spec.rb +++ b/spec/features/crops/crop_search_spec.rb @@ -4,7 +4,7 @@ feature "crop search" do scenario "search results show the search term in title" do visit root_path within "form#navbar-search" do - fill_in "search", with: "tomato" + fill_in "term", with: "tomato" click_button "Search" end expect(page).to have_css "h1", text: "Crops matching \"tomato\"" diff --git a/spec/features/shared_examples/crop_suggest.rb b/spec/features/shared_examples/crop_suggest.rb index 9856282ca..5e812e683 100644 --- a/spec/features/shared_examples/crop_suggest.rb +++ b/spec/features/shared_examples/crop_suggest.rb @@ -10,11 +10,11 @@ shared_examples "crop suggest" do |resource| sync_elasticsearch([pea, pear, maize, tomato]) end - scenario "See text in crop auto suggest field" do + scenario "placeholder text in crop auto suggest field" do expect(page).to have_selector("input[placeholder='e.g. lettuce']") end - scenario "Typing in the crop name displays suggestions" do + scenario "typing in the crop name displays suggestions" do within "form#new_#{resource}" do fill_autocomplete "crop", :with => "pe" end @@ -34,6 +34,12 @@ shared_examples "crop suggest" do |resource| end expect(page).to have_content("pear") + end + + scenario "selecting crop from dropdown" do + within "form#new_#{resource}" do + fill_autocomplete "crop", :with => "pear" + end select_from_autocomplete("pear") @@ -67,4 +73,4 @@ shared_examples "crop suggest" do |resource| expect(page).to have_content("Crop must be present and exist in our database") end -end \ No newline at end of file +end diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index f4ca3034a..de1c3c0ba 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -46,7 +46,7 @@ describe 'layouts/_header.html.haml', :type => "view" do it 'has a crop search' do assert_select("form[action=#{crops_search_path}]") - assert_select("input#search") + assert_select("input#term") end end From 1dfac3fb2f4f35a10d07e455d0666ed6833fb197 Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Feb 2015 20:44:24 +1100 Subject: [PATCH 018/392] Improving crop request form --- app/views/crops/_form.html.haml | 110 ++++++++++--------- app/views/crops/edit.html.haml | 21 +++- spec/features/crops/request_new_crop_spec.rb | 6 +- 3 files changed, 76 insertions(+), 61 deletions(-) diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index e7be7cd62..cd42ca758 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -6,86 +6,92 @@ - @crop.errors.full_messages.each do |msg| %li= msg + -# Handy link to crop wrangling policy/style guide, shown to wranglers only - if can? :wrangle, @crop %p %span.help-block For detailed crop wrangling guidelines, please consult the - =link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling" on the Growstuff wiki. + -# Everyone (wranglers and requesters) sees the basic info section + %h2 Basic information + .form-group = f.label :name, :class => 'control-label col-md-2' .col-md-8 = f.text_field :name, :class => 'form-control' - %span.help-block - - if can? :wrangle, @crop - Name in US English; singular; capitalize proper nouns only. - - else - Please provide the common name for the crop, in English, if you know it. + %span.help-block + The common name for the crop, in English (required). + - if can? :wrangle, @crop + Wranglers: please ensure this is singular, and capitalize + proper nouns only. .form-group = f.label :en_wikipedia_url, 'Wikipedia URL', :class => 'control-label col-md-2' .col-md-8 = f.text_field :en_wikipedia_url, :class => 'form-control' - %span.help-block - - if can? :wrangle, @crop - Link to this crop's page on the English language Wikipedia. - - else - Please provide a link to the crop's page on the English language Wikipedia. Crops without Wikipedia pages cannot be added to our database at this time. - - - if can? :wrangle, @crop + %span.help-block + Link to the crop's page on the English language Wikipedia (required). + -# Only crop wranglers see the crop hierarchy (for now) + - if can? :wrangle, @crop .form-group = f.label :parent_id, 'Parent crop', :class => 'control-label col-md-2' .col-md-8 = collection_select(:crop, :parent_id, Crop.all, :id, :name, {:include_blank => true}, :class => 'form-control') %span.help-block Optional. For setting up crop hierarchies for varieties etc. - %p - %span.help-block - You may enter up to 3 scientific names for a crop. Most crops will have only one. - = f.fields_for :scientific_names do |sn| - .form-group - = sn.label :scientific_name, "Scientific name", :class => 'control-label col-md-2' - .col-md-8 - = sn.text_field :scientific_name, :class => 'form-control' - .col-md-2 - - if sn.object && sn.object.persisted? - %label.checkbox - = sn.check_box :_destroy - = sn.label :_destroy, "Delete" - - unless @crop.new_record? - .form-group - = f.label :approval_status, 'Approval Status', :class=> 'control-label col-md-2' - .col-md-8 - = f.select(:approval_status, @crop.approval_statuses, {}, {:class => 'form-control'}) + -# Everyone (wranglers and requesters) gets to add scientific names + %h2 Scientific names + %p You may enter up to 3 scientific names for a crop. Most crops will have only one. - .form-group - = f.label :reason_for_rejection, 'Reason for rejection', :class => 'control-label col-md-2' - .col-md-8 - = f.select(:reason_for_rejection, @crop.reasons_for_rejection, {:include_blank => true}, {:class => 'form-control'}) - %p + = f.fields_for :scientific_names do |sn| + .form-group + = sn.label :scientific_name, "Scientific name", :class => 'control-label col-md-2' + .col-md-8 + = sn.text_field :scientific_name, :class => 'form-control' + .col-md-2 + - if sn.object && sn.object.persisted? + %label.checkbox + = sn.check_box :_destroy + = sn.label :_destroy, "Delete" + + -# This is used for comments from crop requesters. We need to show it + -# to everyone, but we don't include it on new crops from wranglers. + + - if (can? :wrangle, @crop and @crop.requester) or (cannot? :wrangle, @crop and @crop.new_record?) + %h2 Crop request notes + .form-group + = f.label :request_notes, 'Comments', :class => 'control-label col-md-2' + .col-md-8 + = f.text_area :request_notes, :rows => 3, :class => 'form-control' + + -# A final explanation of what's going to happen next, for crop requesters + - unless can? :wrangle, @crop + %p When you submit this form, your suggestion will be sent to our team of #{link_to 'volunteer crop wranglers', 'http://talk.growstuff.org/c/crop-wrangling'} for review. We'll let you know the outcome as soon as we can. + + -# Now, for crop wranglers, let's have approval/rejection at the bottom of the page + - if can? :wrangle, @crop and @crop.requester + %h2 Approve or reject pending crops + .form-group + = f.label :approval_status, 'Approval status', :class=> 'control-label col-md-2' + .col-md-8 + = f.select(:approval_status, @crop.approval_statuses, {}, {:class => 'form-control'}) + + .form-group + = f.label :reason_for_rejection, 'Reason for rejection', :class => 'control-label col-md-2' + .col-md-8 + = f.select(:reason_for_rejection, @crop.reasons_for_rejection, {:include_blank => true}, {:class => 'form-control'}) + + .form-group + = f.label :rejection_notes, 'Rejection notes', :class => 'control-label col-md-2' + .col-md-8 + = f.text_area :rejection_notes, :rows => 3, :class => 'form-control' %span.help-block Please provide additional notes why this crop request was rejected if the above reasons do not apply. - .form-group - = f.label :rejection_notes, 'Rejection Notes', :class => 'control-label col-md-2' - .col-md-8= f.text_area :rejection_notes, :rows => 6, :class => 'form-control' - - - else - %p - %span.help-block - Provide any additional information that might help us assess your request. - - .form-group - = f.label :request_notes, 'Comments', :class => 'control-label col-md-2' - .col-md-8= f.text_area :request_notes, :rows => 6, :class => 'form-control' - - %p - %span.help-block - When you submit this form, your suggestion will be sent to our team of #{link_to 'volunteer crop wranglers', 'http://talk.growstuff.org/c/crop-wrangling'} for review. We'll let you know the outcome as soon as we can. .form-group .form-actions.col-md-offset-2.col-md-8 diff --git a/app/views/crops/edit.html.haml b/app/views/crops/edit.html.haml index dca7fb221..da8863252 100644 --- a/app/views/crops/edit.html.haml +++ b/app/views/crops/edit.html.haml @@ -1,10 +1,19 @@ -- content_for :title, "Review crop: #{@crop.name}" +- content_for :title, "Edit crop: #{@crop.name}" -%p - Added by - = @crop.creator - = distance_of_time_in_words(@crop.created_at, Time.zone.now) - ago. +- if @crop.approval_status == "approved" + - if @crop.requester + %p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago. + %p Approved by #{link_to @crop.creator, @crop.creator}. + - else + %p Added by #{link_to @crop.creator, @crop.creator} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago. +- elsif @crop.approval_status == "pending" + .alert.alert-danger + %p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago. + %p Status: #{@crop.approval_status}. +- elsif @crop.approval_status == "rejected" + .alert.alert-danger + %p Requested by #{link_to @crop.requester, @crop.requester} #{distance_of_time_in_words(@crop.created_at, Time.zone.now)} ago. + %p Status: #{@crop.approval_status} by #{link_to @crop.creator, @crop.creator}. = render 'form' diff --git a/spec/features/crops/request_new_crop_spec.rb b/spec/features/crops/request_new_crop_spec.rb index 0a1cac2a7..afe03a0a1 100644 --- a/spec/features/crops/request_new_crop_spec.rb +++ b/spec/features/crops/request_new_crop_spec.rb @@ -29,7 +29,7 @@ feature "Requesting a new crop" do scenario "Approve a request" do visit edit_crop_path(crop) - select "approved", from: "Approval Status" + select "approved", from: "Approval status" click_button "Save" expect(page).to have_content "En wikipedia url is not a valid English Wikipedia URL" fill_in "Wikipedia URL", with: "http://en.wikipedia.org/wiki/Aung_San_Suu_Kyi" @@ -39,7 +39,7 @@ feature "Requesting a new crop" do scenario "Rejecting a crop" do visit edit_crop_path(crop) - select "rejected", from: "Approval Status" + select "rejected", from: "Approval status" select "not edible", from: "Reason for rejection" click_button "Save" expect(page).to have_content "Crop was successfully updated." @@ -47,4 +47,4 @@ feature "Requesting a new crop" do end -end \ No newline at end of file +end From e4dabd172572f000627f22884f7ddaee94e7a78d Mon Sep 17 00:00:00 2001 From: Skud Date: Tue, 17 Feb 2015 20:54:16 +1100 Subject: [PATCH 019/392] Fix action links in sidebar - can't do stuff if not approved --- app/views/crops/_find_seeds.html.haml | 9 +++++---- app/views/crops/_harvests.html.haml | 10 +++++----- app/views/crops/_plantings.html.haml | 10 +++++----- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/views/crops/_find_seeds.html.haml b/app/views/crops/_find_seeds.html.haml index 66990ed69..0e31f6916 100644 --- a/app/views/crops/_find_seeds.html.haml +++ b/app/views/crops/_find_seeds.html.haml @@ -10,7 +10,8 @@ = render :partial => 'members/location', :locals => { :member => seed.owner } %p = link_to "View all #{crop.name} seeds", seeds_by_crop_path(crop) -- if current_member - = link_to "List achiote seeds to trade", new_seed_path(:crop_id => crop.id) -- else - = render :partial => 'shared/signin_signup', :locals => { :to => 'list your seeds to trade' } +- if crop.approved? + - if current_member + %p= link_to "List #{crop.name} seeds to trade", new_seed_path(:crop_id => crop.id) + - else + = render :partial => 'shared/signin_signup', :locals => { :to => 'list your seeds to trade' } diff --git a/app/views/crops/_harvests.html.haml b/app/views/crops/_harvests.html.haml index 003e72bfa..8962a6d81 100644 --- a/app/views/crops/_harvests.html.haml +++ b/app/views/crops/_harvests.html.haml @@ -13,9 +13,9 @@ ago. %p = link_to "View all #{crop.name} harvests", harvests_by_crop_path(crop) -- if current_member - %p - = link_to "Harvest #{crop.name}", new_harvest_path(:crop_id => crop.id) -- else - = render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} harvests" } +- if crop.approved? + - if current_member + %p= link_to "Harvest #{crop.name}", new_harvest_path(:crop_id => crop.id) + - else + = render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} harvests" } diff --git a/app/views/crops/_plantings.html.haml b/app/views/crops/_plantings.html.haml index 621a6d125..026f6f7fb 100644 --- a/app/views/crops/_plantings.html.haml +++ b/app/views/crops/_plantings.html.haml @@ -13,9 +13,9 @@ ago. %p = link_to "View all #{crop.name} plantings", plantings_by_crop_path(crop) -- if current_member - %p - = link_to "Plant #{crop.name}", new_planting_path(:crop_id => crop.id) -- else - = render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} plantings" } +- if crop.approved? + - if current_member + %p= link_to "Plant #{crop.name}", new_planting_path(:crop_id => crop.id) + - else + = render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} plantings" } From 2241a760c2f9fa52411c93038ebedea6d4a95f98 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Tue, 17 Feb 2015 23:33:39 +1100 Subject: [PATCH 020/392] exclude unapproved crops from search --- app/models/crop.rb | 6 +++++- spec/models/crop_spec.rb | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 0571feecd..89471f90f 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -76,6 +76,7 @@ class Crop < ActiveRecord::Base mappings dynamic: 'false' do indexes :id, type: 'long' indexes :name, type: 'string', analyzer: 'gs_edgeNGram_analyzer' + indexes :approval_status, type: 'string' indexes :scientific_names do indexes :scientific_name, type: 'string', @@ -92,7 +93,7 @@ class Crop < ActiveRecord::Base def as_indexed_json(options={}) self.as_json( - only: [:id, :name], + only: [:id, :name, :approval_status], include: { scientific_names: { only: :scientific_name }, alternate_names: { only: :name } @@ -311,6 +312,9 @@ class Crop < ActiveRecord::Base fields: ["name", "scientific_names.scientific_name", "alternate_names.name"] } }, + filter: { + term: {approval_status: "approved"} + }, size: 50 } ) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 9cda818e8..02f3149ae 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -342,6 +342,16 @@ describe Crop do it "searches case insensitively" do Crop.search('mUsH').should include @mushroom end + it "doesn't find 'rejected' crop" do + @mushroom.approval_status = "rejected" + sync_elasticsearch([@mushroom]) + Crop.search('mushroom').should_not include @mushroom + end + it "doesn't find 'pending' crop" do + @mushroom.approval_status = "pending" + sync_elasticsearch([@mushroom]) + Crop.search('mushroom').should_not include @mushroom + end end context "csv loading" do From 023333b15f096353203a12cdf3431ff0330cd7f1 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Tue, 17 Feb 2015 23:33:39 +1100 Subject: [PATCH 021/392] exclude unapproved crops from search --- app/models/crop.rb | 6 +++++- spec/models/crop_spec.rb | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 0571feecd..89471f90f 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -76,6 +76,7 @@ class Crop < ActiveRecord::Base mappings dynamic: 'false' do indexes :id, type: 'long' indexes :name, type: 'string', analyzer: 'gs_edgeNGram_analyzer' + indexes :approval_status, type: 'string' indexes :scientific_names do indexes :scientific_name, type: 'string', @@ -92,7 +93,7 @@ class Crop < ActiveRecord::Base def as_indexed_json(options={}) self.as_json( - only: [:id, :name], + only: [:id, :name, :approval_status], include: { scientific_names: { only: :scientific_name }, alternate_names: { only: :name } @@ -311,6 +312,9 @@ class Crop < ActiveRecord::Base fields: ["name", "scientific_names.scientific_name", "alternate_names.name"] } }, + filter: { + term: {approval_status: "approved"} + }, size: 50 } ) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 9cda818e8..9332d9c0f 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -342,6 +342,16 @@ describe Crop do it "searches case insensitively" do Crop.search('mUsH').should include @mushroom end + it "doesn't find 'rejected' crop" do + @mushroom.update_attributes(approval_status: "rejected") + sync_elasticsearch([@mushroom]) + Crop.search('mushroom').should_not include @mushroom + end + it "doesn't find 'pending' crop" do + @mushroom.update_attributes(approval_status: "pending") + sync_elasticsearch([@mushroom]) + Crop.search('mushroom').should_not include @mushroom + end end context "csv loading" do From ef2d1eb68358dd16d481829b0fdd0587094af7d1 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 00:17:53 +1100 Subject: [PATCH 022/392] fixing Travis CI error --- 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 9332d9c0f..f4e12d6db 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -343,12 +343,12 @@ describe Crop do Crop.search('mUsH').should include @mushroom end it "doesn't find 'rejected' crop" do - @mushroom.update_attributes(approval_status: "rejected") + @mushroom.assign_attributes(approval_status: "rejected") sync_elasticsearch([@mushroom]) Crop.search('mushroom').should_not include @mushroom end it "doesn't find 'pending' crop" do - @mushroom.update_attributes(approval_status: "pending") + @mushroom.assign_attributes(approval_status: "pending") sync_elasticsearch([@mushroom]) Crop.search('mushroom').should_not include @mushroom end From eb5e9e926bf42d28080849fdb9fb32fd03eaad57 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 00:17:53 +1100 Subject: [PATCH 023/392] fixing Travis CI error --- spec/models/crop_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 9332d9c0f..96ed1ea0b 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -343,14 +343,14 @@ describe Crop do Crop.search('mUsH').should include @mushroom end it "doesn't find 'rejected' crop" do - @mushroom.update_attributes(approval_status: "rejected") - sync_elasticsearch([@mushroom]) - Crop.search('mushroom').should_not include @mushroom + @rejected_crop = FactoryGirl.create(:rejected_crop, :name => 'mushroom') + sync_elasticsearch([@rejected_crop]) + Crop.search('mushroom').should_not include @rejected_crop end it "doesn't find 'pending' crop" do - @mushroom.update_attributes(approval_status: "pending") - sync_elasticsearch([@mushroom]) - Crop.search('mushroom').should_not include @mushroom + @crop_request = FactoryGirl.create(:crop_request, :name => 'mushroom') + sync_elasticsearch([@crop_request]) + Crop.search('mushroom').should_not include @crop_request end end From da955810997d8bc8c2fcd637bc2b4a763e369faa Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Tue, 10 Feb 2015 22:10:20 +1100 Subject: [PATCH 024/392] :using size instead of count --- app/views/photos/show.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml index 0330a25f7..d09464152 100644 --- a/app/views/photos/show.html.haml +++ b/app/views/photos/show.html.haml @@ -19,16 +19,16 @@ %p= link_to 'Delete Photo', @photo, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' .col-md-6 - - if @photo.plantings.count > 0 or @photo.harvests.count > 0 or @photo.gardens.count > 0 + - if @photo.plantings.size > 0 or @photo.harvests.size > 0 or @photo.gardens.size > 0 %p This photo depicts: %ul - - if @photo.plantings.count > 0 + - if @photo.plantings.size > 0 - @photo.plantings.each do |p| %li= link_to p, p - - if @photo.harvests.count > 0 + - if @photo.harvests.size > 0 - @photo.harvests.each do |h| %li= link_to h, h - - if @photo.gardens.count > 0 + - if @photo.gardens.size > 0 - @photo.gardens.each do |g| %li= link_to g, g From 3b1e855da3288730954d2de940e97fb77d114fb4 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Tue, 17 Feb 2015 13:51:06 -0500 Subject: [PATCH 025/392] change footer section names to generic footer1, footer2, footer3 because we're going to CMS mode --- app/assets/stylesheets/overrides.css.less | 2 +- app/views/layouts/_footer.html.haml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 679e48f7d..4279c890f 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -217,7 +217,7 @@ li.crop-hierarchy { // footer footer { - #contact, #about-growstuff, #policies { + #footer1, #footer2, #footer3 { text-align: left; padding-top: 1em; padding-bottom: 2em; diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index e7dba1d25..946f45529 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -1,9 +1,9 @@ .navbar.navbar-default.navbar-bottom .container .row - .col-md-4#about-growstuff + .col-md-4#footer1 != cms_snippet_content(:footer1) - .col-md-4#policies + .col-md-4#footer2 != cms_snippet_content(:footer2) - .col-md-4#contact + .col-md-4#footer3 != cms_snippet_content(:footer3) From 8ab3167a2851cc8d5995150c7e0ca5d73a973009 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 11:15:15 +1100 Subject: [PATCH 026/392] update sql search to excludes unapproved crops --- app/models/crop.rb | 2 ++ spec/models/crop_spec.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/models/crop.rb b/app/models/crop.rb index 7d880a3b5..d321353a7 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -334,6 +334,8 @@ class Crop < ActiveRecord::Base matches.delete(exact_match) matches.unshift(exact_match) end + + matches = matches.select {|c| c.approval_status == 'approved'} return matches end end diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index d58c46ee3..ee773e7cb 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'pry' describe Crop do context 'all fields present' do From 506e3e550cd1a529de8786d50cfd3037cd973a12 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 11:15:15 +1100 Subject: [PATCH 027/392] update sql search to excludes unapproved crops --- app/models/crop.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/crop.rb b/app/models/crop.rb index 7d880a3b5..d321353a7 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -334,6 +334,8 @@ class Crop < ActiveRecord::Base matches.delete(exact_match) matches.unshift(exact_match) end + + matches = matches.select {|c| c.approval_status == 'approved'} return matches end end From 35f8c126b6426ded0f2dda30e920cd151938f386 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 15:38:28 +1100 Subject: [PATCH 028/392] using scope for searching only approved records --- app/models/crop.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index d321353a7..4d898c73c 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -27,6 +27,7 @@ class Crop < ActiveRecord::Base scope :popular, -> { where(:approval_status => "approved").reorder("plantings_count desc, lower(name) asc") } scope :randomized, -> { where(:approval_status => "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql scope :pending_approval, -> { where(:approval_status => "pending") } + scope :approved, -> { where(:approval_status => "approved") } scope :rejected, -> { where(:approval_status => "rejected") } ## Wikipedia urls are only necessary when approving a crop @@ -325,17 +326,16 @@ class Crop < ActiveRecord::Base # collection, so it matches what we get from elasticsearch and we can # manipulate it in the same ways (eg. deleting elements without deleting # the whole record from the db) - matches = where("name ILIKE ?", "%#{query}%").to_a + matches = Crop.approved.where("name ILIKE ?", "%#{query}%").to_a # we want to make sure that exact matches come first, even if not # using elasticsearch (eg. in development) - exact_match = Crop.find_by_name(query) + exact_match = Crop.approved.find_by_name(query) if exact_match matches.delete(exact_match) matches.unshift(exact_match) end - matches = matches.select {|c| c.approval_status == 'approved'} return matches end end From d338bab82bf3255efefa63c55ab2ee39a52420a6 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 18 Feb 2015 16:18:24 +1100 Subject: [PATCH 029/392] travis to test both with and without elasticsearch --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dd6853a02..8b8d9a6b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ language: ruby cache: bundler env: matrix: - - GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + - GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' GROWSTUFF_ELASTICSEARCH='true' + - GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' GROWSTUFF_ELASTICSEARCH='false' global: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" bundler_args: "--without development production staging" From 17ccea4b280282593b5527842392f523a3347141 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Mon, 23 Feb 2015 21:41:42 +1100 Subject: [PATCH 030/392] moving photo on posts/show view --- app/views/posts/_single.html.haml | 8 -------- app/views/posts/show.html.haml | 30 +++++++++++++++++++----------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app/views/posts/_single.html.haml b/app/views/posts/_single.html.haml index e301ed76a..8f5cc5507 100644 --- a/app/views/posts/_single.html.haml +++ b/app/views/posts/_single.html.haml @@ -21,14 +21,6 @@ :growstuff_markdown #{ strip_tags post.body } - - unless post.crops.empty? - .hidden-xs - %h3 Crops mentioned in this post - - post.crops.each do |c| - - unless c.photos.empty? - .col-md-2{:style => 'padding-bottom: 6px'} - = render :partial => 'crops/image_with_popover', :locals => { :crop => c } - .col-md-11 - unless defined?(hide_comments) .post-comments %ul.list-inline diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml index b6e07bde7..e6cd99625 100644 --- a/app/views/posts/show.html.haml +++ b/app/views/posts/show.html.haml @@ -16,16 +16,24 @@ = render :partial => "single", :locals => { :post => @post, :subject => false, :hide_comments => true } -- if can? :edit, @post or can? :destroy, @post - .post-actions - - if can? :edit, @post - = link_to 'Edit Post', edit_post_path(@post), :class => 'btn btn-default btn-xs' - - if can? :destroy, @post - = link_to 'Delete Post', @post, method: :delete, | - data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' +- unless @post.crops.empty? + %h3 Crops mentioned in this post + - @post.crops.each do |c| + - unless c.photos.empty? + .col-md-2 + = render :partial => 'crops/thumbnail', :locals => { :crop => c } -= render :partial => "comments", :locals => { :post => @post } +.col-md-11 + - if can? :edit, @post or can? :destroy, @post + .post-actions + - if can? :edit, @post + = link_to 'Edit Post', edit_post_path(@post), :class => 'btn btn-default btn-xs' + - if can? :destroy, @post + = link_to 'Delete Post', @post, method: :delete, | + data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' -- if can? :create, Comment - .post-actions - =link_to 'Comment', new_comment_path(:post_id => @post.id), :class => 'btn btn-primary' + = render :partial => "comments", :locals => { :post => @post } + + - if can? :create, Comment + .post-actions + =link_to 'Comment', new_comment_path(:post_id => @post.id), :class => 'btn btn-primary' From 2740b5e47b3c638de3a9f32179b8730ddb08148e Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Mon, 23 Feb 2015 13:37:43 +0000 Subject: [PATCH 031/392] Correcting the environment variable name for secret token so Heroku is not impacted --- config/secrets.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/secrets.yml b/config/secrets.yml index c522ed925..4fc7f3b37 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -14,4 +14,4 @@ test: # run 'rake secret' to generate your own production: - secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> + secret_key_base: <%= ENV["RAILS_SECRET_TOKEN"] %> From 0f52ea5aada4b9f8ed213a120d5a158c49204f2a Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 25 Feb 2015 10:26:04 +1100 Subject: [PATCH 032/392] one click unsubscription --- app/controllers/members_controller.rb | 16 +++++++++++++++- app/mailers/notifier.rb | 11 +++++++++++ app/views/members/unsubscribe.html.haml | 8 ++++++++ app/views/notifier/notify.html.haml | 3 ++- app/views/notifier/planting_reminder.html.haml | 2 +- config/routes.rb | 3 +++ 6 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 app/views/members/unsubscribe.html.haml diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 744e93f4c..34eaff272 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -1,7 +1,7 @@ class MembersController < ApplicationController load_and_authorize_resource - skip_authorize_resource :only => :nearby + skip_authorize_resource :only => [:nearby, :unsubscribe] after_action :expire_cache_fragments, :only => :create @@ -49,6 +49,20 @@ class MembersController < ApplicationController @followers = @member.followers.paginate(:page => params[:page]) end + def unsubscribe + verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) + decrypted_message = verifier.verify(params[:message]) + + @member = Member.find(decrypted_message[:member_id]) + @type = decrypted_message[:email_type] + @member.update_attributes(@type => false) + + case @type + when :send_notification_email; @text = "Inbox Notification" + when :send_planting_reminder; @text = "Planting Reminder" + end + end + private def expire_cache_fragments diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 53bae3092..f60c9a45f 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -6,6 +6,10 @@ class Notifier < ActionMailer::Base @notification = notification @reply_link = reply_link(@notification) + # Encrypting + verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) + @signed_message = verifier.generate ({ member_id: @notification.recipient.id, email_type: :send_notification_email }) + mail(:to => @notification.recipient.email, :subject => @notification.subject) end @@ -16,6 +20,10 @@ class Notifier < ActionMailer::Base @plantings = @member.plantings.first(5) @harvests = @member.harvests.first(5) + # Encrypting + verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) + @signed_message = verifier.generate ({ member_id: @member.id, email_type: :send_planting_reminder }) + if @member.send_planting_reminder mail(:to => @member.email, :subject => "What have you planted lately?") @@ -37,4 +45,7 @@ class Notifier < ActionMailer::Base mail(:to => @member.email, :subject => "#{crop.name.capitalize} has been rejected") end + def encrypt_message(message) + + end end diff --git a/app/views/members/unsubscribe.html.haml b/app/views/members/unsubscribe.html.haml new file mode 100644 index 000000000..e6f61987a --- /dev/null +++ b/app/views/members/unsubscribe.html.haml @@ -0,0 +1,8 @@ +- content_for :title, "Unsubscribe" + +%p + You have been unsubscribed from + %strong + #{@text} + emails. If you wish to unsubscribe from other Growstuff emails, you may do so via + = link_to "your settings page", edit_member_registration_url diff --git a/app/views/notifier/notify.html.haml b/app/views/notifier/notify.html.haml index ed9cf32f2..d8b12d471 100644 --- a/app/views/notifier/notify.html.haml +++ b/app/views/notifier/notify.html.haml @@ -18,6 +18,7 @@ %br/ = link_to "View this message in your inbox", notification_url(@notification) %br/ - = link_to "Turn off these notifications", edit_member_registration_url + = link_to "Unsubscribe", unsubscribe_member_url(@signed_message) + from these notifications = render :partial => 'signature' \ No newline at end of file diff --git a/app/views/notifier/planting_reminder.html.haml b/app/views/notifier/planting_reminder.html.haml index 4dea05123..57678c156 100644 --- a/app/views/notifier/planting_reminder.html.haml +++ b/app/views/notifier/planting_reminder.html.haml @@ -64,5 +64,5 @@ %hr/ %p Don't want to get these emails any more? - = link_to "Turn off these notifications", edit_member_registration_url + = link_to "Unsubscribe", unsubscribe_member_url(@signed_message) diff --git a/config/routes.rb b/config/routes.rb index 542cf8c51..26b6bfccc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,9 @@ Growstuff::Application.routes.draw do resources :plant_parts devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" } + devise_scope :member do + get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member' + end resources :members From 1b62c5cb97cb8feb0de3c9ef9cf29dc63cf55e3b Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 Feb 2015 00:05:56 -0500 Subject: [PATCH 033/392] remove pending/rejected crops from browse and test that, change links on wrangling page to go directly to crop edit and update tests for that --- app/controllers/crops_controller.rb | 4 ++-- app/views/crops/wrangle.html.haml | 2 +- spec/features/crops/browse_crops_spec.rb | 11 +++++++++++ spec/features/crops/crop_wranglers_spec.rb | 10 ++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index b8ad4f5c8..917b72570 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -12,11 +12,11 @@ class CropsController < ApplicationController if @sort == 'alpha' # alphabetical order @crops = Crop.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.paginate(:page => params[:page]) + @paginated_crops = @crops.approved.paginate(:page => params[:page]) else # default to sorting by popularity @crops = Crop.popular.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.paginate(:page => params[:page]) + @paginated_crops = @crops.approved.paginate(:page => params[:page]) end respond_to do |format| diff --git a/app/views/crops/wrangle.html.haml b/app/views/crops/wrangle.html.haml index 549a737a1..3a13ec68e 100644 --- a/app/views/crops/wrangle.html.haml +++ b/app/views/crops/wrangle.html.haml @@ -50,7 +50,7 @@ %th When - @crops.each do |c| %tr - %td= link_to c.name, c + %td= link_to c.name, edit_crop_path(c) %td= link_to c.en_wikipedia_url, c.en_wikipedia_url %td - c.scientific_names.each do |s| diff --git a/spec/features/crops/browse_crops_spec.rb b/spec/features/crops/browse_crops_spec.rb index 5df5dbd36..08e0b9247 100644 --- a/spec/features/crops/browse_crops_spec.rb +++ b/spec/features/crops/browse_crops_spec.rb @@ -4,6 +4,8 @@ feature "browse crops" do let(:tomato) { FactoryGirl.create(:tomato) } let(:maize) { FactoryGirl.create(:maize) } + let(:pending_crop) { FactoryGirl.create(:crop_request) } + let(:rejected_crop) { FactoryGirl.create(:rejected_crop) } scenario "has a form for sorting by" do visit crops_path @@ -16,4 +18,13 @@ feature "browse crops" do expect(page).to have_content crop1.name end + scenario "pending crops are not listed" do + visit crops_path + expect(page).not_to have_content pending_crop.name + end + + scenario "rejected crops are not listed" do + visit crops_path + expect(page).not_to have_content rejected_crop.name + end end diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 1b2af3f06..b408e53bc 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -52,19 +52,13 @@ feature "crop wranglers" do end scenario "View pending crops" do - visit wrangle_crops_path(:approval_status => "pending") - within "#pending-crops" do - click_link "Ultra berry" - end + visit crop_path(requested_crop) expect(page).to have_content "This crop is currently pending approval." expect(page).to have_content "Please approve this even though it's fake." end scenario "View rejected crops" do - visit wrangle_crops_path(:approval_status => "rejected") - within "#rejected-crops" do - click_link "Fail bean" - end + visit crop_path(rejected_crop) expect(page).to have_content "This crop was rejected for the following reason: Totally fake" end From 8990e803a0fa466ada23b8f133331ea73aa84f7e Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Thu, 26 Feb 2015 17:28:26 +0000 Subject: [PATCH 034/392] Increasing coverage of plantings controller --- spec/features/plantings/planting_a_crop_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 16b47973f..81576cb0b 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -39,6 +39,14 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Planting was successfully created" expect(page).to have_content "maize" end + + scenario "Editing a planting to add details" do + visit planting_path(planting) + click_link "Edit" + fill_in "Tell us more about it", :with => "Some extra notes" + click_button "Save" + expect(page).to have_content "Planting was successfully updated" + end scenario "Marking a planting as finished" do fill_autocomplete "crop", :with => "m" From 3a9ec8cf6d9a75ed1544b77464494b1435bb2dfd Mon Sep 17 00:00:00 2001 From: Taylor Griffin Date: Fri, 27 Feb 2015 07:39:07 +1100 Subject: [PATCH 035/392] include crop approval status in sci and alt names --- app/views/alternate_names/show.html.haml | 2 ++ app/views/crops/_approval_status_message.html.haml | 11 +++++++++++ app/views/crops/show.html.haml | 12 +----------- app/views/scientific_names/show.html.haml | 2 ++ 4 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 app/views/crops/_approval_status_message.html.haml diff --git a/app/views/alternate_names/show.html.haml b/app/views/alternate_names/show.html.haml index 67dfc9a37..06012457b 100644 --- a/app/views/alternate_names/show.html.haml +++ b/app/views/alternate_names/show.html.haml @@ -1,5 +1,7 @@ %p#notice= notice += render :partial => 'crops/approval_status_message', :locals => { :crop => @alternate_name.crop } + %p %b Alternate name: = @alternate_name.name diff --git a/app/views/crops/_approval_status_message.html.haml b/app/views/crops/_approval_status_message.html.haml new file mode 100644 index 000000000..fffb822f4 --- /dev/null +++ b/app/views/crops/_approval_status_message.html.haml @@ -0,0 +1,11 @@ +- if crop.pending? + .alert.alert-danger + %b This crop is currently pending approval. + %p This crop was requested by #{crop.requester} #{time_ago_in_words(crop.created_at)} ago. + - unless crop.request_notes.blank? + %p + Request notes: #{crop.request_notes} + +- if crop.rejected? + .alert.alert-danger + %b This crop was rejected for the following reason: #{crop.reason_for_rejection == "other" ? crop.rejection_notes : crop.reason_for_rejection}. \ No newline at end of file diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index bda1804d2..57efa60a5 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -1,17 +1,7 @@ - content_for :title, @crop.name - content_for :subtitle, @crop.default_scientific_name -- if @crop.pending? - .alert.alert-danger - %b This crop is currently pending approval. - %p This crop was requested by #{@crop.requester} #{time_ago_in_words(@crop.created_at)} ago. - - unless @crop.request_notes.blank? - %p - Request notes: #{@crop.request_notes} - -- if @crop.rejected? - .alert.alert-danger - %b This crop was rejected for the following reason: #{@crop.reason_for_rejection == "other" ? @crop.rejection_notes : @crop.reason_for_rejection}. += render :partial => 'approval_status_message', :locals => { :crop => @crop } - if @crop.approved? - content_for :buttonbar do diff --git a/app/views/scientific_names/show.html.haml b/app/views/scientific_names/show.html.haml index a3efe2d6f..1c0a76357 100644 --- a/app/views/scientific_names/show.html.haml +++ b/app/views/scientific_names/show.html.haml @@ -1,5 +1,7 @@ %p#notice= notice += render :partial => 'crops/approval_status_message', :locals => { :crop => @scientific_name.crop } + %p %b Scientific name: = @scientific_name.scientific_name From ead9a250af8ec1656d77f39fbfcd61cbc7c4d534 Mon Sep 17 00:00:00 2001 From: Taylor Griffin Date: Fri, 27 Feb 2015 07:56:30 +1100 Subject: [PATCH 036/392] test that status message appears when rejected / pending --- spec/features/crops/alternate_name_spec.rb | 12 ++++++++++++ spec/features/scientific_name_spec.rb | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/spec/features/crops/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb index 8ec2a21fe..348cc3279 100644 --- a/spec/features/crops/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -69,6 +69,18 @@ feature "Alternate names" do expect(page).to have_content alternate_eggplant.crop.name end + context "When alternate name is rejected" do + let(:rejected_crop) { FactoryGirl.create(:rejected_crop) } + let(:pending_alt_name) { FactoryGirl.create(:alternate_name, :crop => rejected_crop) } + + scenario "Displays crop rejection message" do + visit alternate_name_path(pending_alt_name) + expect(page).to have_content "This crop was rejected for the following reason: Totally fake" + end + + end + + end end diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index c6cd60c6a..f8b93ce29 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -70,6 +70,14 @@ feature "Scientific names" do href: crop_path(zea_mays.crop) end - end + context "When scientific name is pending" do + let(:pending_crop) { FactoryGirl.create(:crop_request) } + let(:pending_sci_name) { FactoryGirl.create(:scientific_name, :crop => pending_crop) } + scenario "Displays crop pending message" do + visit scientific_name_path(pending_sci_name) + expect(page).to have_content "This crop is currently pending approval" + end + end + end end From 2abe6d7d122f5b23d5f078c7a24fb5fe0ac8aeb0 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 4 Mar 2015 12:53:08 +1100 Subject: [PATCH 037/392] show thumbnail even when there is no photo --- app/views/posts/show.html.haml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml index e6cd99625..1a656997d 100644 --- a/app/views/posts/show.html.haml +++ b/app/views/posts/show.html.haml @@ -19,9 +19,8 @@ - unless @post.crops.empty? %h3 Crops mentioned in this post - @post.crops.each do |c| - - unless c.photos.empty? - .col-md-2 - = render :partial => 'crops/thumbnail', :locals => { :crop => c } + .col-md-2 + = render :partial => 'crops/thumbnail', :locals => { :crop => c } .col-md-11 - if can? :edit, @post or can? :destroy, @post From 2d73dd2869df44122a800fc06377f36d58082993 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 Feb 2015 00:05:56 -0500 Subject: [PATCH 038/392] remove pending/rejected crops from browse and test that, change links on wrangling page to go directly to crop edit and update tests for that --- app/controllers/crops_controller.rb | 4 ++-- app/views/crops/wrangle.html.haml | 2 +- spec/features/crops/browse_crops_spec.rb | 11 +++++++++++ spec/features/crops/crop_wranglers_spec.rb | 10 ++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index b8ad4f5c8..917b72570 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -12,11 +12,11 @@ class CropsController < ApplicationController if @sort == 'alpha' # alphabetical order @crops = Crop.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.paginate(:page => params[:page]) + @paginated_crops = @crops.approved.paginate(:page => params[:page]) else # default to sorting by popularity @crops = Crop.popular.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.paginate(:page => params[:page]) + @paginated_crops = @crops.approved.paginate(:page => params[:page]) end respond_to do |format| diff --git a/app/views/crops/wrangle.html.haml b/app/views/crops/wrangle.html.haml index 549a737a1..3a13ec68e 100644 --- a/app/views/crops/wrangle.html.haml +++ b/app/views/crops/wrangle.html.haml @@ -50,7 +50,7 @@ %th When - @crops.each do |c| %tr - %td= link_to c.name, c + %td= link_to c.name, edit_crop_path(c) %td= link_to c.en_wikipedia_url, c.en_wikipedia_url %td - c.scientific_names.each do |s| diff --git a/spec/features/crops/browse_crops_spec.rb b/spec/features/crops/browse_crops_spec.rb index 5df5dbd36..08e0b9247 100644 --- a/spec/features/crops/browse_crops_spec.rb +++ b/spec/features/crops/browse_crops_spec.rb @@ -4,6 +4,8 @@ feature "browse crops" do let(:tomato) { FactoryGirl.create(:tomato) } let(:maize) { FactoryGirl.create(:maize) } + let(:pending_crop) { FactoryGirl.create(:crop_request) } + let(:rejected_crop) { FactoryGirl.create(:rejected_crop) } scenario "has a form for sorting by" do visit crops_path @@ -16,4 +18,13 @@ feature "browse crops" do expect(page).to have_content crop1.name end + scenario "pending crops are not listed" do + visit crops_path + expect(page).not_to have_content pending_crop.name + end + + scenario "rejected crops are not listed" do + visit crops_path + expect(page).not_to have_content rejected_crop.name + end end diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 1b2af3f06..b408e53bc 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -52,19 +52,13 @@ feature "crop wranglers" do end scenario "View pending crops" do - visit wrangle_crops_path(:approval_status => "pending") - within "#pending-crops" do - click_link "Ultra berry" - end + visit crop_path(requested_crop) expect(page).to have_content "This crop is currently pending approval." expect(page).to have_content "Please approve this even though it's fake." end scenario "View rejected crops" do - visit wrangle_crops_path(:approval_status => "rejected") - within "#rejected-crops" do - click_link "Fail bean" - end + visit crop_path(rejected_crop) expect(page).to have_content "This crop was rejected for the following reason: Totally fake" end From 9e53105f430eb3748e83d23b07817d2fcf37e06d Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 4 Mar 2015 22:02:35 -0500 Subject: [PATCH 039/392] make language for crop accept/reject friendlier and if reason for rejection is 'other', give the rejection notes --- app/views/notifier/crop_request_approved.html.haml | 2 +- app/views/notifier/crop_request_rejected.html.haml | 9 ++++++--- app/views/notifier/new_crop_request.html.haml | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/views/notifier/crop_request_approved.html.haml b/app/views/notifier/crop_request_approved.html.haml index 5fea20246..871522b0b 100644 --- a/app/views/notifier/crop_request_approved.html.haml +++ b/app/views/notifier/crop_request_approved.html.haml @@ -2,7 +2,7 @@ %p Hello #{@member.login_name}, %p - Your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been approved! + Your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been approved! Thank you for helping us make our listing ever more complete! %ul %li diff --git a/app/views/notifier/crop_request_rejected.html.haml b/app/views/notifier/crop_request_rejected.html.haml index c58e2546b..29585d8af 100644 --- a/app/views/notifier/crop_request_rejected.html.haml +++ b/app/views/notifier/crop_request_rejected.html.haml @@ -2,8 +2,11 @@ %p Hello #{@member.login_name}, %p - Your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been rejected for the following reason. + We're sorry, but your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been rejected for the following reason: - = @crop.reason_for_rejection + - if @crop.reason_for_rejection != "other" + = @crop.reason_for_rejection + - else + = @crop.rejection_notes -= render :partial => 'signature' \ No newline at end of file += render :partial => 'signature' diff --git a/app/views/notifier/new_crop_request.html.haml b/app/views/notifier/new_crop_request.html.haml index 163c898f4..0e8c65ab7 100644 --- a/app/views/notifier/new_crop_request.html.haml +++ b/app/views/notifier/new_crop_request.html.haml @@ -8,6 +8,7 @@ %ul %li Name: #{@request.name} %li Wikipedia URL: #{@request.en_wikipedia_url.present? ? @request.en_wikipedia_url : "not specified"} + %li Notes: #{@request.request_notes} %p As a crop wrangler, you can #{link_to "approve or reject this request", edit_crop_url(@request)}. @@ -18,4 +19,4 @@ %p Thanks for your help! -= render :partial => 'signature' \ No newline at end of file += render :partial => 'signature' From b9b2f4a57eb2fb0f6d1827977677b0028b53afb3 Mon Sep 17 00:00:00 2001 From: Manmeet Singh Date: Sat, 7 Mar 2015 16:36:15 +0530 Subject: [PATCH 040/392] Placing cursor in textarea on page load of write post and write comment views --- app/views/comments/_form.html.haml | 2 +- app/views/posts/_form.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 5d13ec6b5..de97b20f7 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -8,7 +8,7 @@ .form-group = f.label :body, "Your comment:" - = f.text_area :body, :rows => 6, :class => 'form-control' + = f.text_area :body, :rows => 6, :class => 'form-control', :autofocus => 'autofocus' %span.help-block = render :partial => "shared/markdown_help" .actions diff --git a/app/views/posts/_form.html.haml b/app/views/posts/_form.html.haml index 3ae4e5172..e252631c5 100644 --- a/app/views/posts/_form.html.haml +++ b/app/views/posts/_form.html.haml @@ -8,7 +8,7 @@ .form-group = label_tag :post, "Subject", :class => 'control-label' - = f.text_field :subject, :class => 'form-control' + = f.text_field :subject, :class => 'form-control', :autofocus => 'autofocus' .form-group - if @post.forum || @forum From ad6c1ba2dc62041693b15b70dae35471616472bb Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Sun, 8 Mar 2015 15:10:30 +1100 Subject: [PATCH 041/392] tiding up the code --- app/controllers/members_controller.rb | 6 +++--- app/mailers/notifier.rb | 4 ++-- spec/features/unsubscribing_spec.rb | 27 ++++++++++++++++----------- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index f8e21ca21..734d32d73 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -50,8 +50,8 @@ class MembersController < ApplicationController end EMAIL_TYPE_STRING = { - send_notification_email: "Inbox Notification", - send_planting_reminder: "Planting Reminder" + send_notification_email: "Inbox Notification", + send_planting_reminder: "Planting Reminder" } def unsubscribe @@ -60,7 +60,7 @@ class MembersController < ApplicationController decrypted_message = verifier.verify(params[:message]) @member = Member.find(decrypted_message[:member_id]) - @type = decrypted_message[:email_type] + @type = decrypted_message[:type] @member.update_attributes(@type => false) flash.now[:notice] = "You have been unsubscribed from #{EMAIL_TYPE_STRING[@type]} emails." diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 90b163729..a37d65d67 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -8,7 +8,7 @@ class Notifier < ActionMailer::Base # Encrypting verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) - @signed_message = verifier.generate ({ member_id: @notification.recipient.id, email_type: :send_notification_email }) + @signed_message = verifier.generate ({ member_id: @notification.recipient.id, type: :send_notification_email }) mail(:to => @notification.recipient.email, :subject => @notification.subject) @@ -22,7 +22,7 @@ class Notifier < ActionMailer::Base # Encrypting verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) - @signed_message = verifier.generate ({ member_id: @member.id, email_type: :send_planting_reminder }) + @signed_message = verifier.generate ({ member_id: @member.id, type: :send_planting_reminder }) if @member.send_planting_reminder mail(:to => @member.email, diff --git a/spec/features/unsubscribing_spec.rb b/spec/features/unsubscribing_spec.rb index 0e039e16c..96edef143 100644 --- a/spec/features/unsubscribing_spec.rb +++ b/spec/features/unsubscribing_spec.rb @@ -1,6 +1,5 @@ require 'rails_helper' require 'capybara/email/rspec' -require 'pry' feature "unsubscribe" do let(:member) { FactoryGirl.create(:member) } @@ -11,7 +10,7 @@ feature "unsubscribe" do end scenario "from planting reminder mailing list" do - # verifying the initial subscription status fo the member + # verifying the initial subscription status of the member expect(member.send_planting_reminder).to eq(true) expect(member.send_notification_email).to eq(true) @@ -20,14 +19,15 @@ feature "unsubscribe" do open_email(member.email) # clicking 'Unsubscribe' link will unsubscribe the member - current_email.click_link 'Unsubscribe' + current_email.click_link 'Turn off these notifications' + expect(page).to have_content "You have been unsubscribed from Planting Reminder" updated_member = Member.find(member.id) # reload the member expect(updated_member.send_planting_reminder).to eq(false) expect(updated_member.send_notification_email).to eq(true) end scenario "from inbox notification mailing list" do - # verifying the initial subscription status fo the member + # verifying the initial subscription status of the member expect(member.send_planting_reminder).to eq(true) expect(member.send_notification_email).to eq(true) @@ -37,18 +37,23 @@ feature "unsubscribe" do open_email(member.email) # clicking 'Unsubscribe' link will unsubscribe the member - current_email.click_link 'Unsubscribe' + current_email.click_link 'Turn off these notifications' + expect(page).to have_content "You have been unsubscribed from Inbox Notification" updated_member = Member.find(member.id) # reload the member expect(updated_member.send_planting_reminder).to eq(true) expect(updated_member.send_notification_email).to eq(false) end - scenario "visiting /members/unsubscribe/somestring" do - visit unsubscribe_member_url('somestring') - end + scenario "visit unsubscribe page with a non-encrypted parameter" do + # verifying the initial subscription status of the member + expect(member.send_planting_reminder).to eq(true) + expect(member.send_notification_email).to eq(true) - scenario "visiting /members/unsubscribe/" do - visit unsubscribe_member_url('') + # visit /members/unsubscribe/somestring ie.parameter to the URL is a random string + visit unsubscribe_member_url("type=send_planting_reminder&member_id=#{member.id}") + expect(page).to have_content "We're sorry, there was an error" + updated_member = Member.find(member.id) # reload the member + expect(member.send_planting_reminder).to eq(true) + expect(member.send_notification_email).to eq(true) end - end \ No newline at end of file From 920ca2948bac5c42098178b9497e941c937c5224 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Mon, 9 Mar 2015 00:50:34 -0400 Subject: [PATCH 042/392] add helper function for crop rejection explanation and use it on both notifier and status message --- app/models/crop.rb | 8 ++++++++ app/views/crops/_approval_status_message.html.haml | 2 +- app/views/notifier/crop_request_rejected.html.haml | 7 +------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 4d898c73c..e2d4c3fb0 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -299,6 +299,14 @@ class Crop < ActiveRecord::Base end end + def rejection_explanation + if reason_for_rejection != "other" + return reason_for_rejection + else + return rejection_notes + end + end + # Crop.search(string) def self.search(query) if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" diff --git a/app/views/crops/_approval_status_message.html.haml b/app/views/crops/_approval_status_message.html.haml index fffb822f4..54ae162db 100644 --- a/app/views/crops/_approval_status_message.html.haml +++ b/app/views/crops/_approval_status_message.html.haml @@ -8,4 +8,4 @@ - if crop.rejected? .alert.alert-danger - %b This crop was rejected for the following reason: #{crop.reason_for_rejection == "other" ? crop.rejection_notes : crop.reason_for_rejection}. \ No newline at end of file + %b This crop was rejected for the following reason: #{crop.rejection_explanation} diff --git a/app/views/notifier/crop_request_rejected.html.haml b/app/views/notifier/crop_request_rejected.html.haml index 29585d8af..d1ab14868 100644 --- a/app/views/notifier/crop_request_rejected.html.haml +++ b/app/views/notifier/crop_request_rejected.html.haml @@ -2,11 +2,6 @@ %p Hello #{@member.login_name}, %p - We're sorry, but your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been rejected for the following reason: - - - if @crop.reason_for_rejection != "other" - = @crop.reason_for_rejection - - else - = @crop.rejection_notes + We're sorry, but your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been rejected for the following reason: #{@crop.rejection_explanation} = render :partial => 'signature' From 9f33f497bc2f987d841e24502cb8efec6dd3aa9f Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Wed, 11 Mar 2015 13:06:23 +1100 Subject: [PATCH 043/392] improved coding --- app/controllers/members_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 734d32d73..dbd90ef71 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -61,7 +61,7 @@ class MembersController < ApplicationController @member = Member.find(decrypted_message[:member_id]) @type = decrypted_message[:type] - @member.update_attributes(@type => false) + @member.update(@type => false) flash.now[:notice] = "You have been unsubscribed from #{EMAIL_TYPE_STRING[@type]} emails." From 0c6b6e0e0ec4cf2c12b3a7e0e7d2ef70677d53ba Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Thu, 12 Mar 2015 13:49:37 +1100 Subject: [PATCH 044/392] added show all/less toggle button --- app/assets/javascripts/crops.js.erb | 4 ++ app/assets/stylesheets/overrides.css.less | 6 +++ app/views/crops/_hierarchy.html.haml | 4 +- app/views/crops/_varieties.html.haml | 3 ++ spec/features/crops/crop_detail_page_spec.rb | 55 ++++++++++++++++++++ 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/crops.js.erb b/app/assets/javascripts/crops.js.erb index fd9f2242e..4e30a95e0 100644 --- a/app/assets/javascripts/crops.js.erb +++ b/app/assets/javascripts/crops.js.erb @@ -47,3 +47,7 @@ function showCropMap(cropmap) { cropmap.addLayer(markers); } + +$('.btn.toggle').click(function () { + $('.toggle').toggleClass('hide'); +}); diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 4279c890f..f2fe8383d 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -316,3 +316,9 @@ html, body { * from ours */ @state-success-text: darken(@green, 10%); @state-success-bg: lighten(@green, 50%); + +.hide { + display: none; +} + + diff --git a/app/views/crops/_hierarchy.html.haml b/app/views/crops/_hierarchy.html.haml index dd1e87be6..7bc2a6726 100644 --- a/app/views/crops/_hierarchy.html.haml +++ b/app/views/crops/_hierarchy.html.haml @@ -1,7 +1,9 @@ %ul + - @count ||= 5 - display_crops.each do |c| - %li.crop-hierarchy + %li.crop-hierarchy{:class => @count <= 0 ? ['hide', 'toggle'] : []} = link_to c, c + - @count -= 1 - if c.varieties.present? - c.varieties.each do |v| = render :partial => 'hierarchy', :locals => { :display_crops => [ v ] } diff --git a/app/views/crops/_varieties.html.haml b/app/views/crops/_varieties.html.haml index 8fec3e3a3..07a8f4eb3 100644 --- a/app/views/crops/_varieties.html.haml +++ b/app/views/crops/_varieties.html.haml @@ -10,6 +10,9 @@ Varieties of #{crop.name}: = render :partial => 'hierarchy', :locals => { :display_crops => [ crop ] } + - if @count < 0 + = button_tag "Show all #{crop.varieties.size} varieties", :class => 'btn btn-link toggle' + = button_tag "Show less varieties", :class => 'btn btn-link toggle hide' - if ! crop.parent and crop.varieties.empty? %p None known. diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 437d3e786..f1e447a0b 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -4,6 +4,61 @@ feature "crop detail page" do let(:crop) { FactoryGirl.create(:crop) } + context "varieties" do + let!(:roma1) { FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) } + let!(:roma2) { FactoryGirl.create(:crop, :name => 'Roma tomato 2', :parent => crop) } + let!(:roma3) { FactoryGirl.create(:crop, :name => 'Roma tomato 3', :parent => crop) } + let!(:roma4) { FactoryGirl.create(:crop, :name => 'Roma tomato 4', :parent => crop) } + + scenario "The crop has 4 varieties" do + + visit crop_path(crop) + + # It lists all 5 items (note: including the top level item.) + # It DOES NOT have "Show all/less" toggle link + expect(page).to have_css('li', text: /tomato/i, count: 5) + expect(page).to have_no_css('button', text: /Show all+/i) + expect(page).to have_no_css('button', text: /Show less+/i) + end + + scenario "The crop has more than 4 varieties", :js => true do + roma5 = FactoryGirl.create(:crop, :name => 'Roma tomato 5', :parent => crop) + + visit crop_path(crop) + + # It lists the first 5 items (note: including the top level item.) + # It HAS have "Show all" toggle link but not "Show less" link + expect(page).to have_css('li', text: /tomato/i, count: 5) + expect(page).to have_css('li', text: 'Roma tomato 4') + expect(page).to have_no_css('li', text: 'Roma tomato 5') + expect(page).to have_css('button', text: /Show all+/i) + expect(page).to have_no_css('button', text: /Show less+/i) + + # Clik "Show all" link + page.find('button', :text => /Show all+/).click + + # It lists all 6 items (note: including the top level item.) + # It HAS have "Show all" toggle link but not "Show less" link + expect(page).to have_css('li', text: /tomato/i, count: 6) + expect(page).to have_css('li', text: 'Roma tomato 4') + expect(page).to have_css('li', text: 'Roma tomato 5') + expect(page).to have_no_selector('button', text: /Show all+/i) + expect(page).to have_selector('button', text: /Show less+/i) + + # Clik "Show less" link + page.find('button', :text => /Show less+/).click + + # It lists 5 items (note: including the top level item.) + # It HAS have "Show all" toggle link but not "Show less" link + expect(page).to have_css('li', text: /tomato/i, count: 5) + expect(page).to have_css('li', text: 'Roma tomato 4') + expect(page).to have_no_css('li', text: 'Roma tomato 5') + expect(page).to have_selector('button', text: /Show all+/i) + expect(page).to have_no_selector('button', text: /Show less+/i) + end + + end + context "signed in member" do let(:member) { FactoryGirl.create(:member) } From 8631b1fc99b7813da5c4063ba3eb4b561c250687 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Fri, 13 Mar 2015 11:33:20 +0100 Subject: [PATCH 045/392] Add background to thumbnail --- app/assets/stylesheets/leaflet_overrides.css.less | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/leaflet_overrides.css.less b/app/assets/stylesheets/leaflet_overrides.css.less index f60a1c2e3..ef47b5d79 100644 --- a/app/assets/stylesheets/leaflet_overrides.css.less +++ b/app/assets/stylesheets/leaflet_overrides.css.less @@ -1,3 +1,10 @@ .leaflet-popup-content-wrapper, .leaflet-popup-tip { border: none; } +.thumbnail{ + background: #ffff!important; + border: solid 1px whitesmoke; +} +.thumbnail .crop-thumbnail .cropinfo{ + padding-top: 14px; +} From 3a5cf37dc0755751e55341b3c7b0d08a82ac94e1 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Fri, 13 Mar 2015 12:58:06 +0100 Subject: [PATCH 046/392] "img-circle" class for members gravatar --- app/views/members/_image_with_popover.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_image_with_popover.html.haml b/app/views/members/_image_with_popover.html.haml index fb9caddfc..32e53fe98 100644 --- a/app/views/members/_image_with_popover.html.haml +++ b/app/views/members/_image_with_popover.html.haml @@ -5,7 +5,7 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => member.login_name, | - :class => 'img-responsive member-image' | + :class => 'img-responsive member-image img-circle' | ), | member, | :rel => "popover", | From c8903ba25f2a0820b6fbb460f06a99d588dd5112 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Sun, 15 Mar 2015 02:43:43 +0100 Subject: [PATCH 047/392] "img-circle" for users --- app/views/members/_avatar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index da33ac2da..594dfc6ed 100644 --- a/app/views/members/_avatar.html.haml +++ b/app/views/members/_avatar.html.haml @@ -5,5 +5,5 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => '', | - :class => 'img img-responsive avatar' ), | + :class => 'img img-responsive avatar img-circle' ),| member_path(member) From 59d823ff8bca8dec4b626a9c1e56c8528e8509ab Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Mon, 16 Mar 2015 22:17:21 +1100 Subject: [PATCH 048/392] bulk creating members, gardens and plantings --- db/seeds.rb | 40 ++- db/seeds/suburbs.csv | 570 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 607 insertions(+), 3 deletions(-) create mode 100644 db/seeds/suburbs.csv diff --git a/db/seeds.rb b/db/seeds.rb index 3fdd6226e..97dadc6ad 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -60,16 +60,50 @@ end def load_test_users puts "Loading test users..." - (1..3).each do |i| - @user = Member.create( + + # Open suburb csv + source_path = Rails.root.join('db', 'seeds') + begin + suburb_file = File.open("#{source_path}/suburbs.csv") + rescue + puts "Warning: unable to open suburbs.csv" + end + + + # rake parameter (eg. 'rake db:seed member_size=10') + member_size = ENV['member_size'] ? ENV['member_size'].to_i : 3 + + (1..member_size).each do |i| + @user = Member.new( :login_name => "test#{i}", :email => "test#{i}@example.com", :password => "password#{i}", :tos_agreement => true ) - @user.confirm! + @user.skip_confirmation! @user.save! + + # Populate member location and garden location + if suburb_file + suburb_file.pos = 0 if suburb_file.eof? + row = CSV.parse(suburb_file.readline) + + suburb,country,state,latitude,longitude = row[0] + # Using 'update_column' method instead of 'update' so that + # it avoids accessing Geocoding service for faster processing + @user.gardens.first.update_columns(location: suburb, latitude: latitude, longitude: longitude) + @user.update_columns(location: suburb, latitude: latitude, longitude: longitude) + end + + # Create a planting by the member + Planting.create( + owner_id: @user.id, + garden_id: @user.gardens.first.id, + planted_at: Date.today, + crop_id: Crop.find(i % Crop.all.size + 1).id + ) end + puts "Finished loading test users" end diff --git a/db/seeds/suburbs.csv b/db/seeds/suburbs.csv new file mode 100644 index 000000000..461f33a24 --- /dev/null +++ b/db/seeds/suburbs.csv @@ -0,0 +1,570 @@ +Downer,Australian Capital Territory,ACT,-35.244,149.1435 +O'Connor,Australian Capital Territory,ACT,-35.2564,149.1125 +Watson,Australian Capital Territory,ACT,-35.2347,149.1594 +Dickson,Australian Capital Territory,ACT,-35.2528,149.1417 +Lyneham,Australian Capital Territory,ACT,-35.2398,149.1307 +Hackett,Australian Capital Territory,ACT,-35.2495,149.1635 +Ainslie,Australian Capital Territory,ACT,-35.2622,149.1478 +Red Hill,Australian Capital Territory,ACT,-35.3334,149.1206 +Griffith,Australian Capital Territory,ACT,-35.3253,149.1371 +Forrest,Australian Capital Territory,ACT,-35.315,149.1286 +Manuka,Australian Capital Territory,ACT,-35.3126,149.1278 +Kingston,Australian Capital Territory,ACT,-35.3152,149.1466 +Narrabundah,Australian Capital Territory,ACT,-35.3357,149.1492 +Causeway,Australian Capital Territory,ACT,-35.3126,149.1278 +Garran,Australian Capital Territory,ACT,-35.331,149.0899 +Hughes,Australian Capital Territory,ACT,-35.3327,149.0949 +Curtin,Australian Capital Territory,ACT,-35.3246,149.0776 +Lyons,Australian Capital Territory,ACT,-35.3406,149.074 +Woden,Australian Capital Territory,ACT,-35.3481,149.0905 +O'Malley,Australian Capital Territory,ACT,-35.3525,149.1128 +Phillip,Australian Capital Territory,ACT,-35.3503,149.0915 +Swinger Hill,Australian Capital Territory,ACT,-35.3481,149.0905 +Chifley,Australian Capital Territory,ACT,-35.3534,149.0768 +Farrer,Australian Capital Territory,ACT,-35.3767,149.105 +Isaacs,Australian Capital Territory,ACT,-35.3686,149.1156 +Torrens,Australian Capital Territory,ACT,-35.372,149.0877 +Pearce,Australian Capital Territory,ACT,-35.3622,149.0834 +Mawson,Australian Capital Territory,ACT,-35.3634,149.0986 +Civic Square,Australian Capital Territory,ACT,-35.31,149.1933 +Pialligo,Australian Capital Territory,ACT,-35.3043,149.1792 +Fyshwick,Australian Capital Territory,ACT,-35.3333,149.1667 +Canberra Airport,Australian Capital Territory,ACT,-35.3172,149.1753 +Symonston,Australian Capital Territory,ACT,-35.3516,149.1592 +Majura,Australian Capital Territory,ACT,-35.2667,149.2 +Canberra Bc,Australian Capital Territory,ACT,-35.2778,149.0111 +Canberra Mc,Australian Capital Territory,ACT,-35.2498,149.0591 +Wright,Australian Capital Territory,ACT,-35.3503,149.0155 +Coombs,Australian Capital Territory,ACT,-35.3503,149.0155 +Rivett,Australian Capital Territory,ACT,-35.3471,149.0379 +Stromlo,Australian Capital Territory,ACT,-35.3503,149.0155 +Duffy,Australian Capital Territory,ACT,-35.3346,149.0319 +Coree,Australian Capital Territory,ACT,-35.3503,149.0155 +Chapman,Australian Capital Territory,ACT,-35.3562,149.0374 +Uriarra Village,Australian Capital Territory,ACT,-35.3503,149.0155 +Waramanga,Australian Capital Territory,ACT,-35.353,149.0621 +Weston Creek,Australian Capital Territory,ACT,-35.4171,148.7769 +Uriarra,Australian Capital Territory,ACT,-35.4171,148.7769 +Weston,Australian Capital Territory,ACT,-35.4171,148.7769 +Fisher,Australian Capital Territory,ACT,-35.4171,148.7769 +Stirling,Australian Capital Territory,ACT,-35.4171,148.7769 +Holder,Australian Capital Territory,ACT,-35.4171,148.7769 +Mount Stromlo,Australian Capital Territory,ACT,-35.4171,148.7769 +Braddon,Australian Capital Territory,ACT,-35.2708,149.1357 +Campbell,Australian Capital Territory,ACT,-35.2891,149.1538 +Turner,Australian Capital Territory,ACT,-35.2688,149.1247 +Reid,Australian Capital Territory,ACT,-35.2858,149.1391 +Scullin,Australian Capital Territory,ACT,-35.2346,149.039 +Aranda,Australian Capital Territory,ACT,-35.2582,149.0804 +Cook,Australian Capital Territory,ACT,-35.2601,149.0657 +Jamison Centre,Australian Capital Territory,ACT,-35.2498,149.0591 +Macquarie,Australian Capital Territory,ACT,-35.2513,149.0636 +Hawker,Australian Capital Territory,ACT,-35.2471,149.0367 +Page,Australian Capital Territory,ACT,-35.2386,149.0499 +Weetangera,Australian Capital Territory,ACT,-35.2498,149.0591 +Melba,Australian Capital Territory,ACT,-35.2102,149.0541 +Spence,Australian Capital Territory,ACT,-35.2101,149.034 +Higgins,Australian Capital Territory,ACT,-35.2324,149.0272 +Holt,Australian Capital Territory,ACT,-35.2244,149.0119 +Latham,Australian Capital Territory,ACT,-35.2165,149.0314 +Kippax Centre,Australian Capital Territory,ACT,-35.2101,149.034 +Flynn,Australian Capital Territory,ACT,-35.2059,149.0439 +Florey,Australian Capital Territory,ACT,-35.2259,149.05 +Fraser,Australian Capital Territory,ACT,-35.1917,149.0453 +Kippax,Australian Capital Territory,ACT,-35.2101,149.034 +Dunlop,Australian Capital Territory,ACT,-35.194,149.0198 +Macgregor,Australian Capital Territory,ACT,-35.2098,149.011 +Charnwood,Australian Capital Territory,ACT,-35.2002,149.0341 +Belconnen,Australian Capital Territory,ACT,-35.2167,149.0833 +Belconnen DC,Australian Capital Territory,ACT,-35.2199,149.0869 +Giralang,Australian Capital Territory,ACT,-35.2109,149.096 +Belconnen,Australian Capital Territory,ACT,-35.2167,149.0833 +Kaleen,Australian Capital Territory,ACT,-35.2181,149.1052 +Bruce,Australian Capital Territory,ACT,-35.2407,149.0466 +Evatt,Australian Capital Territory,ACT,-35.2119,149.0689 +University Of Canberra,Australian Capital Territory,ACT,-35.2498,149.0591 +Mckellar,Australian Capital Territory,ACT,-35.2407,149.0466 +Lawson,Australian Capital Territory,ACT,-35.2498,149.0591 +Hall,Australian Capital Territory,ACT,-35.1906,148.9137 +Oaks Estate,Australian Capital Territory,ACT,-35.3397,149.2121 +Kowen,Australian Capital Territory,ACT,-35.3914,149.2166 +Tharwa,Australian Capital Territory,ACT,-35.5714,149.1275 +Hume,Australian Capital Territory,ACT,-35.3855,149.1658 +Paddys River,Australian Capital Territory,ACT,-35.3914,149.2166 +Beard,Australian Capital Territory,ACT,-35.3914,149.2166 +Tuggeranong,Australian Capital Territory,ACT,-35.4158,149.0649 +Greenway,Australian Capital Territory,ACT,-35.4158,149.0649 +Tuggeranong Dc,Australian Capital Territory,ACT,-35.4333,149.15 +Kambah,Australian Capital Territory,ACT,-35.3862,149.058 +Kambah Village,Australian Capital Territory,ACT,-35.3862,149.058 +Erindale Centre,Australian Capital Territory,ACT,-35.3998,149.0888 +Wanniassa,Australian Capital Territory,ACT,-35.3978,149.0909 +Oxley,Australian Capital Territory,ACT,-35.4095,149.0786 +Fadden,Australian Capital Territory,ACT,-35.4019,149.1176 +Monash,Australian Capital Territory,ACT,-35.4158,149.0906 +Macarthur,Australian Capital Territory,ACT,-35.4086,149.132 +Gowrie,Australian Capital Territory,ACT,-35.4119,149.109 +Calwell,Australian Capital Territory,ACT,-35.4404,149.1071 +Gilmore,Australian Capital Territory,ACT,-35.4324,149.1099 +Theodore,Australian Capital Territory,ACT,-35.4496,149.1197 +Richardson,Australian Capital Territory,ACT,-35.4279,149.1138 +Chisholm,Australian Capital Territory,ACT,-35.422,149.1248 +Isabella Plains,Australian Capital Territory,ACT,-35.428,149.094 +Bonython,Australian Capital Territory,ACT,-35.4333,149.0782 +Gordon,Australian Capital Territory,ACT,-35.4568,149.085 +Banks,Australian Capital Territory,ACT,-35.4719,149.0997 +Conder,Australian Capital Territory,ACT,-35.4593,149.1042 +Crace,Australian Capital Territory,ACT,-35.2028,149.1074 +Mitchell,Australian Capital Territory,ACT,-35.2145,149.1293 +Gungahlin,Australian Capital Territory,ACT,-35.1867,149.1362 +Casey,Australian Capital Territory,ACT,-35.167,149.0947 +Kinlyside,Australian Capital Territory,ACT,-35.1842,149.1131 +Franklin,Australian Capital Territory,ACT,-35.1995,149.1433 +Ngunnawal,Australian Capital Territory,ACT,-35.1728,149.1115 +Taylor,Australian Capital Territory,ACT,-35.1842,149.1131 +Palmerston,Australian Capital Territory,ACT,-35.1945,149.1194 +Nicholls,Australian Capital Territory,ACT,-35.1873,149.0965 +Ginninderra Village,Australian Capital Territory,ACT,-35.1875,149.1244 +Forde,Australian Capital Territory,ACT,-35.1682,149.1461 +Moncrieff,Australian Capital Territory,ACT,-35.179,149.1435 +Harrison,Australian Capital Territory,ACT,-35.1991,149.1563 +Jacka,Australian Capital Territory,ACT,-35.179,149.1435 +Amaroo,Australian Capital Territory,ACT,-35.1696,149.128 +Bonner,Australian Capital Territory,ACT,-35.179,149.1435 +Sydney,New South Wales,NSW,-33.8678,151.2073 +Moree,New South Wales,NSW,-29.3965,149.5878 +Kempsey,New South Wales,NSW,-31.079,152.8309 +Seven Oaks,New South Wales,NSW,-31.0123,152.7651 +Clybucca,New South Wales,NSW,-30.95,152.95 +Lower Creek,New South Wales,NSW,-30.9307,152.6368 +Collombatti,New South Wales,NSW,-30.9812,152.8251 +Deep Creek,New South Wales,NSW,-31.0123,152.7651 +Hickeys Creek,New South Wales,NSW,-30.9,152.6 +Gladstone,New South Wales,NSW,-30.9307,152.6368 +Smithtown,New South Wales,NSW,-31.0186,152.9503 +Mungay Creek,New South Wales,NSW,-31.0123,152.7651 +Comara,New South Wales,NSW,-30.9307,152.6368 +Crescent Head,New South Wales,NSW,-31.1887,152.973 +Millbank,New South Wales,NSW,-30.9307,152.6368 +Pola Creek,New South Wales,NSW,-31.0123,152.7651 +Kinchela,New South Wales,NSW,-30.9667,153 +Verges Creek,New South Wales,NSW,-31.0878,152.8997 +Turners Flat,New South Wales,NSW,-31.0167,152.7 +Yessabah,New South Wales,NSW,-31.0123,152.7651 +Sherwood,New South Wales,NSW,-31.0667,152.7333 +Bellbrook,New South Wales,NSW,-30.8167,152.5167 +Hampden Hall,New South Wales,NSW,-31.0123,152.7651 +Old Station,New South Wales,NSW,-31.0123,152.7651 +Belmore River,New South Wales,NSW,-31.1167,152.9833 +Frederickton,New South Wales,NSW,-31.0375,152.8753 +Aldavilla,New South Wales,NSW,-31.0833,152.7667 +East Kempsey,New South Wales,NSW,-31.0123,152.7651 +Euroka,New South Wales,NSW,-31.077,152.8005 +Toorooka,New South Wales,NSW,-30.9307,152.6368 +Willi Willi,New South Wales,NSW,-30.9333,152.45 +Temagog,New South Wales,NSW,-31.0123,152.7651 +Mooneba,New South Wales,NSW,-31.05,152.6833 +South Kempsey,New South Wales,NSW,-31.079,152.8309 +Wittitrin,New South Wales,NSW,-31.1333,152.6667 +Rainbow Reach,New South Wales,NSW,-31.0123,152.7651 +Yarravel,New South Wales,NSW,-31.043,152.7619 +Hat Head,New South Wales,NSW,-31.0555,153.0472 +Burnt Bridge,New South Wales,NSW,-31.1,152.8167 +Moparrabah,New South Wales,NSW,-31.0123,152.7651 +Austral Eden,New South Wales,NSW,-31.0333,152.9167 +Bellimbopinni,New South Wales,NSW,-30.9307,152.6368 +Dondingalong,New South Wales,NSW,-31.1332,152.7514 +Corangula,New South Wales,NSW,-31.0123,152.7651 +Carrai,New South Wales,NSW,-30.9307,152.6368 +Summer Island,New South Wales,NSW,-31.0123,152.7651 +West Kempsey,New South Wales,NSW,-31.0123,152.7651 +Skillion Flat,New South Wales,NSW,-31.0167,152.7333 +Barraganyatti,New South Wales,NSW,-30.85,152.9333 +Telegraph Point,New South Wales,NSW,-31.3333,152.8 +Cooperabung,New South Wales,NSW,-31.3,152.8 +Yarrahapinni,New South Wales,NSW,-30.8281,152.9538 +Tamban,New South Wales,NSW,-30.8667,152.8333 +Grassy Head,New South Wales,NSW,-31.1374,152.7419 +Allgomera,New South Wales,NSW,-30.8182,152.7955 +Bonville,New South Wales,NSW,-30.3761,153.0349 +Upper Rollands Plains,New South Wales,NSW,-31.25,152.6333 +Rollands Plains,New South Wales,NSW,-31.1272,152.7256 +Eungai Rail,New South Wales,NSW,-30.8463,152.9006 +Fishermans Reach,New South Wales,NSW,-31.0274,152.8364 +Stuarts Point,New South Wales,NSW,-30.8208,152.9933 +Bril Bril,New South Wales,NSW,-31.0274,152.8364 +Eungai Creek,New South Wales,NSW,-30.8333,152.8833 +Hacks Ferry,New South Wales,NSW,-31.0274,152.8364 +Kundabung,New South Wales,NSW,-31.2,152.85 +Kippara,New South Wales,NSW,-31.0274,152.8364 +Gum Scrub,New South Wales,NSW,-31.1272,152.7256 +Marlo Merrican,New South Wales,NSW,-31.0274,152.8364 +Crossmaglen,New South Wales,NSW,-31.1374,152.7419 +Ballengarra,New South Wales,NSW,-31.1272,152.7256 +Mid North Coast Mc,New South Wales,NSW,-31.1374,152.7419 +Mid North Coast Msc,New South Wales,NSW,-31.1374,152.7419 +Stewarts River,New South Wales,NSW,-31.7333,152.65 +Deauville,New South Wales,NSW,-31.6915,152.7267 +Lakewood,New South Wales,NSW,-31.6321,152.7582 +North Haven,New South Wales,NSW,-31.7131,152.6781 +Crowdy Bay National Park,New South Wales,NSW,-31.788,152.7311 +Moorland,New South Wales,NSW,-31.7131,152.6781 +West Haven,New South Wales,NSW,-31.6344,152.7825 +Herons Creek,New South Wales,NSW,-31.5833,152.7333 +Camden Head,New South Wales,NSW,-31.6469,152.8346 +Waitui,New South Wales,NSW,-31.6915,152.7267 +Johns River,New South Wales,NSW,-31.75,152.7 +Dunbogan,New South Wales,NSW,-31.65,152.8167 +Glen Niven,Queensland,QLD,-28.6,151.9667 +The Summit,Queensland,QLD,-28.5833,151.9667 +Applethorpe,Queensland,QLD,-28.6167,151.9667 +Pikedale,Queensland,QLD,-28.65,151.6333 +Kyoomba,Queensland,QLD,-28.7421,151.6647 +Mingoola,Queensland,QLD,-28.9833,151.5167 +Mount Tully,Queensland,QLD,-28.7241,151.825 +Cannon Creek,Queensland,QLD,-28.5833,151.8667 +Stanthorpe,Queensland,QLD,-28.6572,151.9337 +Greenlands,Queensland,QLD,-28.7241,151.825 +Broadwater,Queensland,QLD,-28.7241,151.825 +Springdale,Queensland,QLD,-28.7241,151.825 +Thorndale,Queensland,QLD,-28.7241,151.825 +Pikes Creek,Queensland,QLD,-28.7241,151.825 +Eukey,Queensland,QLD,-28.7667,151.9833 +Sugarloaf,Queensland,QLD,-28.7241,151.825 +Storm King,Queensland,QLD,-28.7241,151.825 +Glenlyon,Queensland,QLD,-28.7241,151.825 +Dalcouth,Queensland,QLD,-28.7241,151.825 +Severnlea,Queensland,QLD,-28.7,151.9167 +Amiens,Queensland,QLD,-28.5833,151.8167 +Nundubbermere,Queensland,QLD,-28.7241,151.825 +Fletcher,Queensland,QLD,-28.7667,151.85 +Glen Aplin,Queensland,QLD,-28.7643,151.8918 +Wyberba,Queensland,QLD,-28.85,151.8667 +Ballandean,Queensland,QLD,-28.8576,151.8345 +Lyra,Queensland,QLD,-28.8333,151.8667 +Girraween,Queensland,QLD,-28.8278,151.8556 +Somme,Queensland,QLD,-28.8278,151.8556 +Wallangarra,Queensland,QLD,-28.9239,151.9282 +Limevale,Queensland,QLD,-28.7333,151.2 +Riverton,Queensland,QLD,-28.7884,151.01 +Glenarbon,Queensland,QLD,-28.7884,151.01 +Texas,Queensland,QLD,-28.7884,151.01 +Beebo,Queensland,QLD,-28.7884,151.01 +Watsons Crossing,Queensland,QLD,-28.7884,151.01 +Maidenhead,Queensland,QLD,-28.7884,151.01 +Silver Spur,Queensland,QLD,-28.7884,151.01 +Smithlea,Queensland,QLD,-28.7884,151.01 +Bonshaw,Queensland,QLD,-28.7884,151.01 +Coolmunda,Queensland,QLD,-28.4084,151.2129 +Inglewood,Queensland,QLD,-28.4789,151.1134 +Bybera,Queensland,QLD,-28.4789,151.1134 +Terrica,Queensland,QLD,-28.4789,151.1134 +Warroo,Queensland,QLD,-28.4789,151.1134 +Greenup,Queensland,QLD,-28.4789,151.1134 +Brush Creek,Queensland,QLD,-28.4789,151.1134 +Whetstone,Queensland,QLD,-28.4789,151.1134 +Mosquito Creek,Queensland,QLD,-28.4789,151.1134 +Yelarbon,Queensland,QLD,-28.5725,150.7513 +Kurumbul,Queensland,QLD,-28.2692,150.6904 +Wyaga,Queensland,QLD,-28.194,150.3565 +Lundavra,Queensland,QLD,-28.194,150.3565 +Goodar,Queensland,QLD,-28.194,150.3565 +Goondiwindi,Queensland,QLD,-28.5464,150.3073 +Billa Billa,Queensland,QLD,-28.194,150.3565 +Yagaburne,Queensland,QLD,-28.194,150.3565 +Callandoon,Queensland,QLD,-28.194,150.3565 +Calingunee,Queensland,QLD,-28.194,150.3565 +Kindon,Queensland,QLD,-28.194,150.3565 +Wondalli,Queensland,QLD,-28.194,150.3565 +Kingsthorpe,Queensland,QLD,-27.4756,151.8141 +Acland,Queensland,QLD,-27.3,151.6833 +Biddeston,Queensland,QLD,-27.5667,151.7167 +Muldu,Queensland,QLD,-27.4617,151.6957 +Aubigny,Queensland,QLD,-27.5167,151.65 +Oakey,Queensland,QLD,-27.4331,151.7206 +Yargullen,Queensland,QLD,-27.4617,151.6957 +Balgowan,Queensland,QLD,-27.4617,151.6957 +Rosalie Plains,Queensland,QLD,-27.4617,151.6957 +Silverleigh,Queensland,QLD,-27.4617,151.6957 +Mount Irving,Queensland,QLD,-27.4617,151.6957 +Kelvinhaugh,Queensland,QLD,-27.4617,151.6957 +Amamoor Creek,Queensland,QLD,-26.1931,152.5564 +Bells Bridge,Queensland,QLD,-26.1258,152.5387 +St Mary,Queensland,QLD,-26.1931,152.5564 +Tuchekoi,Queensland,QLD,-26.2008,152.6451 +Mcintosh Creek,Queensland,QLD,-26.1931,152.5564 +Woondum,Queensland,QLD,-26.25,152.7333 +Neusa Vale,Queensland,QLD,-26.1931,152.5564 +Cedar Pocket,Queensland,QLD,-26.2008,152.6451 +Widgee Crossing North,Queensland,QLD,-26.1931,152.5564 +Veteran,Queensland,QLD,-26.2008,152.6451 +Kandanga,Queensland,QLD,-26.3833,152.6667 +The Palms,Queensland,QLD,-26.205,152.5865 +Greens Creek,Queensland,QLD,-26.1931,152.5564 +Coondoo,Queensland,QLD,-26.1667,152.8833 +Ross Creek,Queensland,QLD,-26.1931,152.5564 +Dagun,Queensland,QLD,-26.3167,152.6833 +Bella Creek,Queensland,QLD,-26.1931,152.5564 +Langshaw,Queensland,QLD,-26.3,152.5667 +Kia Ora,Queensland,QLD,-26.1931,152.5564 +Willalo,South Australia,SA,-33.4,138.8833 +Whyte Yarcowie,South Australia,SA,-33.2047,139.0367 +Canowie Belt,South Australia,SA,-33.1833,138.75 +Terowie,South Australia,SA,-33.1667,138.9 +Franklyn,South Australia,SA,-32.9379,138.9062 +Mannanarie,South Australia,SA,-33.05,138.6167 +Ucolta,South Australia,SA,-32.95,138.9667 +Peterborough,South Australia,SA,-32.9721,138.8407 +Sunnybrae,South Australia,SA,-32.8905,138.9224 +Hardy,South Australia,SA,-32.8905,138.9224 +Cavenagh,South Australia,SA,-32.8905,138.9224 +Parnaroo,South Australia,SA,-32.9833,139.1333 +Oodla Wirra,South Australia,SA,-32.8833,139.0667 +Minvalara,South Australia,SA,-32.9,138.75 +Paratoo,South Australia,SA,-32.7,139.3667 +Dawson,South Australia,SA,-32.8,138.9667 +Erskine,South Australia,SA,-32.7333,138.85 +Yatina,South Australia,SA,-32.9333,138.6667 +Pekina,South Australia,SA,-32.8333,138.55 +Morchard,South Australia,SA,-32.8452,138.6651 +Orroroo,South Australia,SA,-32.7344,138.6139 +Amyton,South Australia,SA,-32.6,138.3333 +Hammond,South Australia,SA,-32.8452,138.6651 +Yalpara,South Australia,SA,-32.5333,138.9333 +Tarcowie,South Australia,SA,-32.8452,138.6651 +Eurelia,South Australia,SA,-32.55,138.5667 +Johnburgh,South Australia,SA,-32.45,138.7 +Black Rock,South Australia,SA,-32.8333,138.7 +Willowie,South Australia,SA,-32.6833,138.3333 +Walloway,South Australia,SA,-32.6333,138.5833 +Minburra,South Australia,SA,-32.6695,138.5539 +Coomooroo,South Australia,SA,-32.6695,138.5539 +Cradock,South Australia,SA,-32.3697,138.6443 +Yanyarrie,South Australia,SA,-32.3042,138.5417 +Carrieton,South Australia,SA,-32.3697,138.6443 +Belton,South Australia,SA,-32.2333,138.7 +Moockra,South Australia,SA,-32.4667,138.4333 +Quorn,South Australia,SA,-32.3468,138.0418 +Willochra,South Australia,SA,-32.2333,138.1333 +Saltia,South Australia,SA,-32.3489,138.125 +Bruce,South Australia,SA,-32.4667,138.2 +Stephenston,South Australia,SA,-32.3489,138.125 +Yarrah,South Australia,SA,-32.3489,138.125 +Hawker,South Australia,SA,-31.8892,138.42 +Kanyaka,South Australia,SA,-31.8892,138.42 +Barndioota,South Australia,SA,-31.8892,138.42 +Manna Hill,South Australia,SA,-32.325,140.0441 +Waukaringa,South Australia,SA,-32.3,139.4333 +Cockburn,South Australia,SA,-32.325,140.0441 +Nackara,South Australia,SA,-32.8,139.2333 +Yunta,South Australia,SA,-32.325,140.0441 +Mingary,South Australia,SA,-32.1333,140.7333 +Olary,South Australia,SA,-32.325,140.0441 +Auburn,South Australia,SA,-34.0269,138.6852 +Undalya,South Australia,SA,-34.0667,138.6833 +Leasingham,South Australia,SA,-33.9942,138.6248 +Watervale,South Australia,SA,-33.9942,138.6248 +Clare,South Australia,SA,-33.8332,138.6106 +Spring Farm,South Australia,SA,-33.8972,138.5785 +Hoyleton,South Australia,SA,-33.8532,138.5559 +Barinia,South Australia,SA,-33.8972,138.5785 +Benbournie,South Australia,SA,-33.8972,138.5785 +Stanley Flat,South Australia,SA,-33.8972,138.5785 +Sevenhill,South Australia,SA,-33.8972,138.5785 +Polish Hill River,South Australia,SA,-33.8972,138.5785 +Hill River,South Australia,SA,-33.8972,138.5785 +Kybunga,South Australia,SA,-33.8972,138.5785 +Gillentown,South Australia,SA,-33.8972,138.5785 +Boconnoc Park,South Australia,SA,-33.8972,138.5785 +Armagh,South Australia,SA,-33.825,138.5748 +Spring Gully,South Australia,SA,-33.8972,138.5785 +Emu Flat,South Australia,SA,-33.8972,138.5785 +Penwortham,South Australia,SA,-33.8972,138.5785 +Spalding,South Australia,SA,-33.4979,138.6075 +Andrews,South Australia,SA,-34.6763,138.662 +Broughton River Valley,South Australia,SA,-34.0871,138.6347 +Euromina,South Australia,SA,-34.0871,138.6347 +Mayfield,South Australia,SA,-34.0871,138.6347 +Washpool,South Australia,SA,-34.0871,138.6347 +Hacklins Corner,South Australia,SA,-34.0871,138.6347 +Hilltown,South Australia,SA,-33.8458,138.6125 +Barabba,South Australia,SA,-34.35,138.5833 +Owen,South Australia,SA,-34.272,138.5444 +Pinery,South Australia,SA,-34.3,138.45 +Risdon Park,South Australia,SA,-33.1966,137.994 +Lonnavale,Tasmania,TAS,-42.9754,146.8397 +Crabtree,Tasmania,TAS,-42.9633,147.0786 +Glaziers Bay,Tasmania,TAS,-43.1458,146.9984 +Wattle Grove,Tasmania,TAS,-43.2109,146.8676 +Waterloo,Tasmania,TAS,-43.2109,146.8676 +Strathblane,Tasmania,TAS,-43.2109,146.8676 +Lower Wattle Grove,Tasmania,TAS,-43.1269,147.0275 +Lower Longley,Tasmania,TAS,-42.9833,147.1333 +Catamaran,Tasmania,TAS,-43.2109,146.8676 +Petcheys Bay,Tasmania,TAS,-43.2109,146.8676 +Raminea,Tasmania,TAS,-43.2109,146.8676 +Cygnet,Tasmania,TAS,-43.1533,147.0725 +Abels Bay,Tasmania,TAS,-43.1696,147.1296 +Eggs And Bacon Bay,Tasmania,TAS,-43.2455,147.1047 +Nicholls Rivulet,Tasmania,TAS,-43.1696,147.1296 +Gardners Bay,Tasmania,TAS,-43.1696,147.1296 +Charlotte Cove,Tasmania,TAS,-43.189,147.148 +Randalls Bay,Tasmania,TAS,-43.1696,147.1296 +Verona Sands,Tasmania,TAS,-43.1696,147.1296 +Garden Island Creek,Tasmania,TAS,-43.25,147.1667 +Deep Bay,Tasmania,TAS,-43.2082,147.134 +Franklin,Tasmania,TAS,-43.0888,147.0091 +Brooks Bay,Tasmania,TAS,-43.1708,146.9784 +Geeveston,Tasmania,TAS,-43.1634,146.9255 +Surges Bay,Tasmania,TAS,-43.2775,146.4256 +Surveyors Bay,Tasmania,TAS,-43.1708,146.9784 +Castle Forbes Bay,Tasmania,TAS,-43.2775,146.4256 +Port Huon,Tasmania,TAS,-43.1554,146.9634 +Cairns Bay,Tasmania,TAS,-43.2775,146.4256 +Police Point,Tasmania,TAS,-43.2775,146.4256 +Dover,Tasmania,TAS,-43.2774,146.9734 +Stonor,Tasmania,TAS,-42.4,147.3833 +Swanston,Tasmania,TAS,-42.3482,147.4726 +Andover,Tasmania,TAS,-42.3333,147.45 +Rhyndaston,Tasmania,TAS,-42.3325,147.4857 +Oatlands,Tasmania,TAS,-42.3325,147.4857 +York Plains,Tasmania,TAS,-42.3325,147.4857 +Woodsdale,Tasmania,TAS,-42.4667,147.5667 +Tunbridge,Tasmania,TAS,-42.3325,147.4857 +Parattah,Tasmania,TAS,-42.35,147.4 +Woodbury,Tasmania,TAS,-42.3325,147.4857 +Baden,Tasmania,TAS,-42.3325,147.4857 +Mount Seymour,Tasmania,TAS,-42.3325,147.4857 +Lemont,Tasmania,TAS,-42.3325,147.4857 +Antill Ponds,Tasmania,TAS,-42.3325,147.4857 +Tunnack,Tasmania,TAS,-42.45,147.45 +Orford,Tasmania,TAS,-42.3064,147.9158 +Spring Beach,Tasmania,TAS,-42.5864,147.9145 +Dolphin Sands,Tasmania,TAS,-42.4221,147.8876 +Swansea,Tasmania,TAS,-42.3064,147.9158 +Runnymede,Tasmania,TAS,-42.3064,147.9158 +Little Swanport,Tasmania,TAS,-42.3225,147.9578 +Rheban,Tasmania,TAS,-42.6278,147.9236 +Triabunna,Tasmania,TAS,-42.5018,147.9136 +South Kingsville,Victoria,VIC,-37.8302,144.8709 +Spotswood,Victoria,VIC,-37.8299,144.8878 +Newport,Victoria,VIC,-37.8443,144.8848 +Williamstown North,Victoria,VIC,-37.857,144.8977 +Williamstown,Victoria,VIC,-37.857,144.8977 +Altona,Victoria,VIC,-37.8696,144.8304 +Seaholme,Victoria,VIC,-37.864,144.845 +Robinson,Victoria,VIC,-37.7867,144.8548 +Braybrook,Victoria,VIC,-37.7867,144.8548 +Glengala,Victoria,VIC,-37.775,144.8333 +Sunshine,Victoria,VIC,-37.7833,144.8333 +Sunshine North,Victoria,VIC,-37.775,144.8333 +Albion,Victoria,VIC,-37.7667,144.8333 +Sunshine West,Victoria,VIC,-37.775,144.8333 +St Albans,Victoria,VIC,-37.745,144.8005 +Kings Park,Victoria,VIC,-37.7337,144.772 +Albanvale,Victoria,VIC,-37.7461,144.7686 +Kealba,Victoria,VIC,-37.7371,144.8283 +Deer Park East,Victoria,VIC,-37.7764,144.8016 +Ardeer,Victoria,VIC,-37.7759,144.8014 +Ravenhall,Victoria,VIC,-37.7541,144.7651 +Deer Park,Victoria,VIC,-37.7667,144.7833 +Burnside Heights,Victoria,VIC,-37.7541,144.7651 +Caroline Springs,Victoria,VIC,-37.7412,144.7363 +Deer Park North,Victoria,VIC,-37.7541,144.7651 +Cairnlea,Victoria,VIC,-37.7593,144.7878 +Burnside,Victoria,VIC,-37.7494,144.753 +Mambourin,Victoria,VIC,-37.8291,144.5622 +Mount Cottrell,Victoria,VIC,-37.8167,144.5833 +Wyndham Vale,Victoria,VIC,-37.8415,144.541 +Altona East,Victoria,VIC,-37.8349,144.8474 +Altona North,Victoria,VIC,-37.8349,144.8474 +Altona Gate,Victoria,VIC,-37.8349,144.8474 +Laverton North,Victoria,VIC,-37.8259,144.6886 +Williams Landing,Victoria,VIC,-37.7963,144.7565 +Seabrook,Victoria,VIC,-37.8809,144.7587 +Altona Meadows,Victoria,VIC,-37.8739,144.772 +Laverton,Victoria,VIC,-37.862,144.7698 +Hoppers Crossing,Victoria,VIC,-37.8826,144.7003 +Tarneit,Victoria,VIC,-37.8667,144.6667 +Truganina,Victoria,VIC,-37.8167,144.75 +Cocoroc,Victoria,VIC,-37.8887,144.726 +Point Cook,Victoria,VIC,-37.9148,144.7509 +Quandong,Victoria,VIC,-37.8887,144.726 +Werribee,Victoria,VIC,-37.9,144.6667 +Gillieston,Victoria,VIC,-36.4516,145.181 +Mooroopna North West,Victoria,VIC,-36.4455,145.1411 +Cooma,Victoria,VIC,-36.4516,145.181 +Waranga,Victoria,VIC,-36.6,145.1167 +Girgarre East,Victoria,VIC,-36.4333,145.0667 +Byrneside,Victoria,VIC,-36.4167,145.1833 +Merrigum,Victoria,VIC,-36.3724,145.1322 +Yalca,Victoria,VIC,-35.9833,145.3167 +Nathalia,Victoria,VIC,-36.0577,145.2041 +Yielima,Victoria,VIC,-35.9333,145.2167 +Kotupna,Victoria,VIC,-36.15,145.15 +Picola,Victoria,VIC,-35.9818,145.0847 +Barmah,Victoria,VIC,-36.0167,144.9667 +Lower Moira,Victoria,VIC,-36.0833,144.9833 +Picola West,Victoria,VIC,-36.0333,145.0278 +Katunga,Victoria,VIC,-35.9666,145.4269 +Ulupna,Victoria,VIC,-35.8833,145.4 +Strathmerton,Victoria,VIC,-35.8774,145.4452 +Mywee,Victoria,VIC,-35.8667,145.5 +Bearii,Victoria,VIC,-35.8857,145.3453 +Cobram,Victoria,VIC,-35.9207,145.6407 +Koonoomoo,Victoria,VIC,-35.9503,145.6546 +Yarroweyah,Victoria,VIC,-35.9333,145.55 +Muckatah,Victoria,VIC,-36.0167,145.65 +Cobram,Victoria,VIC,-35.9207,145.6407 +Cobram East,Victoria,VIC,-35.9746,145.7364 +Dookie,Victoria,VIC,-36.3273,145.6897 +Yabba North,Victoria,VIC,-36.3077,145.6839 +Mount Major,Victoria,VIC,-36.2755,145.7146 +Youanmite,Victoria,VIC,-36.3077,145.6839 +Nalinga,Victoria,VIC,-36.4167,145.7167 +Waggarandall,Victoria,VIC,-36.25,145.8 +Yabba South,Victoria,VIC,-36.2755,145.7146 +Dookie College,Victoria,VIC,-36.0413,145.6097 +Katamatite,Victoria,VIC,-36.0759,145.6872 +Katamatite East,Victoria,VIC,-36.0759,145.6872 +Reedy Creek,Victoria,VIC,-37.2667,145.1333 +Waterford Park,Victoria,VIC,-37.3002,145.0668 +Strath Creek,Victoria,VIC,-37.2333,145.2167 +Clonbinane,Victoria,VIC,-37.292,145.1406 +Broadford,Victoria,VIC,-37.2028,145.0484 +Sunday Creek,Victoria,VIC,-37.2602,145.1482 +Tyaak,Victoria,VIC,-37.2167,145.1333 +Sugarloaf Creek,Victoria,VIC,-37.2602,145.1482 +Hazeldene,Victoria,VIC,-37.292,145.1406 +Tallarook,Victoria,VIC,-37.0937,145.1 +Northwood,Victoria,VIC,-36.9667,145.1167 +Caveat,Victoria,VIC,-37.0605,145.2132 +Highlands,Victoria,VIC,-37.1,145.4 +Hilldene,Victoria,VIC,-37.0333,145.0667 +Whiteheads Creek,Victoria,VIC,-37.0468,145.2864 +Seymour South,Victoria,VIC,-37.0605,145.2132 +Dropmore,Victoria,VIC,-37.0605,145.2132 +Kerrisdale,Victoria,VIC,-37.0517,145.3285 +Seymour,Victoria,VIC,-37.0517,145.3285 +Trawool,Victoria,VIC,-37.0517,145.3285 +Seymour,Victoria,VIC,-37.0266,145.1392 +Puckapunyal,Victoria,VIC,-36.9949,145.0401 +Puckapunyal Milpo,Victoria,VIC,-36.9604,145.0527 +Mangalore,Victoria,VIC,-36.9333,145.1833 +Avenel,Victoria,VIC,-36.9452,145.3379 +Upton Hill,Victoria,VIC,-36.9009,145.2337 +Locksley,Victoria,VIC,-36.9011,145.4139 +Longwood,Victoria,VIC,-36.9011,145.4139 +Strathbogie,Victoria,VIC,-36.85,145.75 +Moglonemby,Victoria,VIC,-36.65,145.5333 +Euroa,Victoria,VIC,-36.7555,145.5708 +Guthridge,Victoria,VIC,-38.106,147.0608 +Wurruk,Victoria,VIC,-38.1167,147.0333 +Cobains,Victoria,VIC,-38.0833,147.15 +Bundalaguah,Victoria,VIC,-38.0333,147.0167 +Flynn,Western Australia,WA,-31.9264,116.7354 +Balladong,Western Australia,WA,-31.9264,116.7354 +Cold Harbour,Western Australia,WA,-31.9264,116.7354 +Narraloggan,Western Australia,WA,-31.9264,116.7354 +Wilberforce,Western Australia,WA,-31.9264,116.7354 +Kelmscott Dc,Western Australia,WA,-32.1167,116.0056 \ No newline at end of file From c253c86787c044abfdc38fa3d57a4ece8062fd97 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Fri, 13 Mar 2015 18:45:09 +1100 Subject: [PATCH 049/392] minor improvements --- app/assets/javascripts/crops.js.erb | 4 +- app/assets/stylesheets/overrides.css.less | 2 - app/views/crops/_hierarchy.html.haml | 10 +- app/views/crops/_varieties.html.haml | 32 +++--- spec/features/crops/crop_detail_page_spec.rb | 108 ++++++++++++------- 5 files changed, 94 insertions(+), 62 deletions(-) diff --git a/app/assets/javascripts/crops.js.erb b/app/assets/javascripts/crops.js.erb index 4e30a95e0..c31666d23 100644 --- a/app/assets/javascripts/crops.js.erb +++ b/app/assets/javascripts/crops.js.erb @@ -48,6 +48,6 @@ function showCropMap(cropmap) { cropmap.addLayer(markers); } -$('.btn.toggle').click(function () { - $('.toggle').toggleClass('hide'); +$('.btn.toggle.crop-hierarchy').click(function () { + $('.toggle.crop-hierarchy').toggleClass('hide'); }); diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index f2fe8383d..e31ef791e 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -320,5 +320,3 @@ html, body { .hide { display: none; } - - diff --git a/app/views/crops/_hierarchy.html.haml b/app/views/crops/_hierarchy.html.haml index 7bc2a6726..27d09f866 100644 --- a/app/views/crops/_hierarchy.html.haml +++ b/app/views/crops/_hierarchy.html.haml @@ -1,9 +1,11 @@ %ul - - @count ||= 5 + - @count ||= 0 + - unless defined? max + - max = 0 # list all without "show all" toggle button - display_crops.each do |c| - %li.crop-hierarchy{:class => @count <= 0 ? ['hide', 'toggle'] : []} + %li.crop-hierarchy{:class => max != 0 && @count >= max ? ['hide', 'toggle'] : []} = link_to c, c - - @count -= 1 + - @count += 1 - if c.varieties.present? - c.varieties.each do |v| - = render :partial => 'hierarchy', :locals => { :display_crops => [ v ] } + = render :partial => 'hierarchy', :locals => { :display_crops => [ v ], :max => max } diff --git a/app/views/crops/_varieties.html.haml b/app/views/crops/_varieties.html.haml index 07a8f4eb3..e2afb628e 100644 --- a/app/views/crops/_varieties.html.haml +++ b/app/views/crops/_varieties.html.haml @@ -1,18 +1,20 @@ -- if crop.parent - %p - = crop.name - is a variety of - = succeed "." do - = link_to crop.parent, crop.parent +.varieties + - if crop.parent + %p + = crop.name + is a variety of + = succeed "." do + = link_to crop.parent, crop.parent -- unless crop.varieties.empty? - %p - Varieties of #{crop.name}: + - unless crop.varieties.empty? + %p + Varieties of #{crop.name}: - = render :partial => 'hierarchy', :locals => { :display_crops => [ crop ] } - - if @count < 0 - = button_tag "Show all #{crop.varieties.size} varieties", :class => 'btn btn-link toggle' - = button_tag "Show less varieties", :class => 'btn btn-link toggle hide' + - max = 5 + = render :partial => 'hierarchy', :locals => { :display_crops => [ crop ], :max => max } + - if max != 0 && @count > max + = button_tag "Show all #{@count-1} varieties", :class => 'btn btn-link toggle crop-hierarchy' + = button_tag "Show less varieties", :class => 'btn btn-link toggle crop-hierarchy hide' -- if ! crop.parent and crop.varieties.empty? - %p None known. + - if ! crop.parent and crop.varieties.empty? + %p None known. diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index f1e447a0b..1d26f0825 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -5,58 +5,88 @@ feature "crop detail page" do let(:crop) { FactoryGirl.create(:crop) } context "varieties" do - let!(:roma1) { FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) } - let!(:roma2) { FactoryGirl.create(:crop, :name => 'Roma tomato 2', :parent => crop) } - let!(:roma3) { FactoryGirl.create(:crop, :name => 'Roma tomato 3', :parent => crop) } - let!(:roma4) { FactoryGirl.create(:crop, :name => 'Roma tomato 4', :parent => crop) } - scenario "The crop has 4 varieties" do + scenario "The crop DOES NOT have varieties" do + visit crop_path(crop) + + within ".varieties" do + expect(page).to have_no_selector('li', text: /tomato/i) + expect(page).to have_no_selector('button', text: /Show+/i) + end + end + + scenario "The crop has one variety" do + roma1 = FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) visit crop_path(crop) - # It lists all 5 items (note: including the top level item.) - # It DOES NOT have "Show all/less" toggle link - expect(page).to have_css('li', text: /tomato/i, count: 5) - expect(page).to have_no_css('button', text: /Show all+/i) - expect(page).to have_no_css('button', text: /Show less+/i) + within ".varieties" do + # It lists all 2 items (note: including the top level item.) + expect(page).to have_selector('li', text: /tomato/i, count: 2) + # It DOES NOT have "Show all/less" toggle link + expect(page).to have_no_selector('button', text: /Show+/i) + end end - scenario "The crop has more than 4 varieties", :js => true do - roma5 = FactoryGirl.create(:crop, :name => 'Roma tomato 5', :parent => crop) + context "many" do - visit crop_path(crop) + let!(:roma1) { FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) } + let!(:roma2) { FactoryGirl.create(:crop, :name => 'Roma tomato 2', :parent => crop) } + let!(:roma3) { FactoryGirl.create(:crop, :name => 'Roma tomato 3', :parent => crop) } + let!(:roma4) { FactoryGirl.create(:crop, :name => 'Roma tomato 4', :parent => crop) } - # It lists the first 5 items (note: including the top level item.) - # It HAS have "Show all" toggle link but not "Show less" link - expect(page).to have_css('li', text: /tomato/i, count: 5) - expect(page).to have_css('li', text: 'Roma tomato 4') - expect(page).to have_no_css('li', text: 'Roma tomato 5') - expect(page).to have_css('button', text: /Show all+/i) - expect(page).to have_no_css('button', text: /Show less+/i) + scenario "The crop has 4 varieties" do - # Clik "Show all" link - page.find('button', :text => /Show all+/).click + visit crop_path(crop) - # It lists all 6 items (note: including the top level item.) - # It HAS have "Show all" toggle link but not "Show less" link - expect(page).to have_css('li', text: /tomato/i, count: 6) - expect(page).to have_css('li', text: 'Roma tomato 4') - expect(page).to have_css('li', text: 'Roma tomato 5') - expect(page).to have_no_selector('button', text: /Show all+/i) - expect(page).to have_selector('button', text: /Show less+/i) + within ".varieties" do + # It lists all 5 items (note: including the top level item.) + expect(page).to have_selector('li', text: /tomato/i, count: 5) + # It DOES NOT have "Show all/less" toggle link + expect(page).to have_no_selector('button', text: /Show+/i) + end + end - # Clik "Show less" link - page.find('button', :text => /Show less+/).click + scenario "The crop has 5 varieties, including grandchild", :js => true do + roma_child1 = FactoryGirl.create(:crop, :name => 'Roma tomato child 1', :parent => roma4) - # It lists 5 items (note: including the top level item.) - # It HAS have "Show all" toggle link but not "Show less" link - expect(page).to have_css('li', text: /tomato/i, count: 5) - expect(page).to have_css('li', text: 'Roma tomato 4') - expect(page).to have_no_css('li', text: 'Roma tomato 5') - expect(page).to have_selector('button', text: /Show all+/i) - expect(page).to have_no_selector('button', text: /Show less+/i) + visit crop_path(crop) + + within ".varieties" do + + # It lists the first 5 items (note: including the top level item.) + # It HAS have "Show all" toggle link but not "Show less" link + expect(page).to have_selector('li', text: /tomato/i, count: 5) + expect(page).to have_selector('li', text: 'Roma tomato 4') + expect(page).to have_no_selector('li', text: 'Roma tomato child 1') + # It shows the total number (5) correctly + expect(page).to have_selector('button', text: /Show all 5 +/i) + expect(page).to have_no_selector('button', text: /Show less+/i) + + # Clik "Show all" link + page.find('button', :text => /Show all+/).click + + # It lists all 6 items (note: including the top level item.) + # It HAS have "Show less" toggle link but not "Show all" link + expect(page).to have_selector('li', text: /tomato/i, count: 6) + expect(page).to have_selector('li', text: 'Roma tomato 4') + expect(page).to have_selector('li', text: 'Roma tomato child 1') + expect(page).to have_no_selector('button', text: /Show all+/i) + expect(page).to have_selector('button', text: /Show less+/i) + + # Clik "Show less" link + page.find('button', :text => /Show less+/).click + + # It lists 5 items (note: including the top level item.) + # It HAS have "Show all" toggle link but not "Show less" link + expect(page).to have_selector('li', text: /tomato/i, count: 5) + expect(page).to have_selector('li', text: 'Roma tomato 4') + expect(page).to have_no_selector('li', text: 'Roma tomato child 1') + expect(page).to have_selector('button', text: /Show all 5 +/i) + expect(page).to have_no_selector('button', text: /Show less+/i) + end + end end - end context "signed in member" do From 6dedf1b03090ce66169e6ec5bf1f9813fabcad76 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Mon, 16 Mar 2015 23:07:17 -0400 Subject: [PATCH 050/392] add test for crop.rejection_explanation function --- spec/models/crop_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index d58c46ee3..bf894b921 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -554,4 +554,19 @@ describe Crop do end end end + + context "crop rejections" do + let!(:rejected_reason) { FactoryGirl.create(:crop, :name => 'tomato', :approval_status => 'rejected', :reason_for_rejection => 'not edible') } + let!(:rejected_other) { FactoryGirl.create(:crop, :name => 'tomato', :approval_status => 'rejected', :reason_for_rejection => 'other', :rejection_notes => 'blah blah blah') } + + describe "rejecting a crop" do + it "should give reason if a default option" do + expect(rejected_reason.rejection_explanation).to eq "not edible" + end + + it "should show rejection notes if reason was other" do + expect(rejected_other.rejection_explanation).to eq "blah blah blah" + end + end + end end From bd0da36d6362b58209354c878a76df954160a3fa Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Tue, 17 Mar 2015 21:23:54 -0400 Subject: [PATCH 051/392] reverse the rejection_explanation logic to not use != --- app/models/crop.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index e2d4c3fb0..6bf902c4c 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -300,10 +300,10 @@ class Crop < ActiveRecord::Base end def rejection_explanation - if reason_for_rejection != "other" - return reason_for_rejection - else + if reason_for_rejection == "other" return rejection_notes + else + return reason_for_rejection end end From 7c1cce40b2e75d0d8187413a6e781f2cc06d2036 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Wed, 25 Mar 2015 15:50:43 +0100 Subject: [PATCH 052/392] Update leaflet_overrides.css.less --- app/assets/stylesheets/leaflet_overrides.css.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/leaflet_overrides.css.less b/app/assets/stylesheets/leaflet_overrides.css.less index ef47b5d79..57e648bf7 100644 --- a/app/assets/stylesheets/leaflet_overrides.css.less +++ b/app/assets/stylesheets/leaflet_overrides.css.less @@ -2,7 +2,7 @@ border: none; } .thumbnail{ - background: #ffff!important; + background: #fff !important; border: solid 1px whitesmoke; } .thumbnail .crop-thumbnail .cropinfo{ From 2aad8a0ed0f2cbc8eb33143403fc6b6c954c7cbf Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Wed, 25 Mar 2015 16:05:07 +0100 Subject: [PATCH 053/392] Change to "img-rounded" --- app/views/members/_avatar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index 594dfc6ed..f2aaca79a 100644 --- a/app/views/members/_avatar.html.haml +++ b/app/views/members/_avatar.html.haml @@ -5,5 +5,5 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => '', | - :class => 'img img-responsive avatar img-circle' ),| + :class => 'img img-responsive avatar img-rounded' ),| member_path(member) From bfb4053bb4cf3fa332781f2619aaf0b9725b4edc Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Wed, 25 Mar 2015 16:05:30 +0100 Subject: [PATCH 054/392] Change to "img-rounded" --- app/views/members/_image_with_popover.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_image_with_popover.html.haml b/app/views/members/_image_with_popover.html.haml index 32e53fe98..f15674c67 100644 --- a/app/views/members/_image_with_popover.html.haml +++ b/app/views/members/_image_with_popover.html.haml @@ -5,7 +5,7 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => member.login_name, | - :class => 'img-responsive member-image img-circle' | + :class => 'img-responsive member-image img-rounded' | ), | member, | :rel => "popover", | From 0c80a00f310ea2edfe16de4a23f842a4b55493fb Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Sat, 4 Apr 2015 22:56:35 +1100 Subject: [PATCH 055/392] Pupulate sunniness and planted_from field on planting. --- db/seeds.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index 97dadc6ad..c7b5f4c5e 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -100,7 +100,9 @@ def load_test_users owner_id: @user.id, garden_id: @user.gardens.first.id, planted_at: Date.today, - crop_id: Crop.find(i % Crop.all.size + 1).id + crop_id: Crop.find(i % Crop.all.size + 1).id, + sunniness: select_random_item(Planting::SUNNINESS_VALUES), + planted_from: select_random_item(Planting::PLANTED_FROM_VALUES) ) end @@ -196,6 +198,8 @@ def load_plant_parts end end - +def select_random_item(array) + array[rand(0..array.size-1) % array.size] +end load_data From d95bd0e0637783b8dee37d43d8889c03da6efaa3 Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Sat, 4 Apr 2015 22:57:19 +1100 Subject: [PATCH 056/392] Skip all user confirmation --- db/seeds.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/db/seeds.rb b/db/seeds.rb index c7b5f4c5e..37fb28204 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -111,35 +111,35 @@ end def load_admin_users puts "Adding admin and crop wrangler members..." - @admin_user = Member.create( + @admin_user = Member.new( :login_name => "admin1", :email => "admin1@example.com", :password => "password1", :tos_agreement => true ) - @admin_user.confirm! + @admin_user.skip_confirmation! @admin_user.roles << @admin @admin_user.save! - @wrangler_user = Member.create( + @wrangler_user = Member.new( :login_name => "wrangler1", :email => "wrangler1@example.com", :password => "password1", :tos_agreement => true ) - @wrangler_user.confirm! + @wrangler_user.skip_confirmation! @wrangler_user.roles << @wrangler @wrangler_user.save! end def create_cropbot - @cropbot_user = Member.create( + @cropbot_user = Member.new( :login_name => "cropbot", :email => Growstuff::Application.config.bot_email, :password => SecureRandom.urlsafe_base64(64), :tos_agreement => true ) - @cropbot_user.confirm! + @cropbot_user.skip_confirmation! @cropbot_user.roles << @wrangler @cropbot_user.save! @cropbot_user.account.account_type = AccountType.find_by_name("Staff") From 88e8e3a59e1a3223902025f8ea9a5018fb2e8f59 Mon Sep 17 00:00:00 2001 From: Gabrielle DeWitt Date: Sat, 4 Apr 2015 11:51:24 -0700 Subject: [PATCH 057/392] Added Helper for See Who's Planted Link Text Quantity and planted_from are not required to add a planting. This change handles the cases where one or both attributes are missing. Fixes #633 --- app/helpers/plantings_helper.rb | 15 ++++++ app/views/crops/_plantings.html.haml | 2 +- spec/helpers/plantings_helper_spec.rb | 78 +++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 app/helpers/plantings_helper.rb create mode 100644 spec/helpers/plantings_helper_spec.rb diff --git a/app/helpers/plantings_helper.rb b/app/helpers/plantings_helper.rb new file mode 100644 index 000000000..6478c8d5f --- /dev/null +++ b/app/helpers/plantings_helper.rb @@ -0,0 +1,15 @@ +module PlantingsHelper + + def display_planting(planting) + if planting.quantity.to_i > 0 && planting.planted_from.present? + return "#{planting.owner} planted #{pluralize(planting.quantity, planting.planted_from)}." + elsif planting.quantity.to_i > 0 + return "#{planting.owner} planted #{pluralize(planting.quantity, 'unit')}." + elsif planting.planted_from.present? + return "#{planting.owner} planted #{planting.planted_from.pluralize}." + else + return "#{planting.owner}." + end + end + +end \ No newline at end of file diff --git a/app/views/crops/_plantings.html.haml b/app/views/crops/_plantings.html.haml index 621a6d125..5018d99a3 100644 --- a/app/views/crops/_plantings.html.haml +++ b/app/views/crops/_plantings.html.haml @@ -6,7 +6,7 @@ %ul - crop.plantings.take(3).each do |planting| %li - = link_to "#{planting.owner} planted #{planting.quantity} #{planting.planted_from}.", planting_path(planting) + = link_to display_planting(planting), planting_path(planting) = render :partial => 'members/location', :locals => { :member => planting.owner } %small = distance_of_time_in_words(planting.created_at, Time.zone.now) diff --git a/spec/helpers/plantings_helper_spec.rb b/spec/helpers/plantings_helper_spec.rb new file mode 100644 index 000000000..127585810 --- /dev/null +++ b/spec/helpers/plantings_helper_spec.rb @@ -0,0 +1,78 @@ +require 'rails_helper' + +describe PlantingsHelper do + describe "display_planting" do + + before(:each) do + @member = FactoryGirl.build(:member, + :login_name => 'crop_lady' + ) + end + + it "neither quantity nor planted from provided" do + planting = FactoryGirl.build(:planting, + :quantity => nil, + :planted_from => '', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady." + end + + it "quantity not provided" do + planting = FactoryGirl.build(:planting, + :quantity => nil, + :planted_from => 'seed', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady planted seeds." + end + + context "multiple quantity" do + it "planted_from not provided" do + planting = FactoryGirl.build(:planting, + :quantity => 10, + :planted_from => '', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady planted 10 units." + end + + it "planted_from provided" do + planting = FactoryGirl.build(:planting, + :quantity => 5, + :planted_from => 'seed', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady planted 5 seeds." + end + end + + context "single quantity" do + it "planted_from not provided" do + planting = FactoryGirl.build(:planting, + :quantity => 1, + :planted_from => '', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady planted 1 unit." + end + + it "planted_from provided" do + planting = FactoryGirl.build(:planting, + :quantity => 1, + :planted_from => 'seed', + :owner => @member + ) + result = helper.display_planting(planting) + result.should eq "crop_lady planted 1 seed." + end + + end + + end +end \ No newline at end of file From b7d7f6896ef1fd73cc1440b63c781ad8790dea70 Mon Sep 17 00:00:00 2001 From: Gabrielle DeWitt Date: Sat, 4 Apr 2015 11:54:49 -0700 Subject: [PATCH 058/392] Updated Helper Spec to Match Coding Standards Replaced before and should with let and expect, respectively. Issue #633 --- spec/helpers/plantings_helper_spec.rb | 46 ++++++++++++--------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/spec/helpers/plantings_helper_spec.rb b/spec/helpers/plantings_helper_spec.rb index 127585810..4cb2c63a7 100644 --- a/spec/helpers/plantings_helper_spec.rb +++ b/spec/helpers/plantings_helper_spec.rb @@ -3,73 +3,69 @@ require 'rails_helper' describe PlantingsHelper do describe "display_planting" do - before(:each) do - @member = FactoryGirl.build(:member, - :login_name => 'crop_lady' - ) - end + let!(:member) { FactoryGirl.build(:member, :login_name => 'crop_lady') } - it "neither quantity nor planted from provided" do + it "does not have a quantity nor a planted from value provided" do planting = FactoryGirl.build(:planting, :quantity => nil, :planted_from => '', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady." + expect(result).to eq "crop_lady." end - it "quantity not provided" do + it "does not have a quantity provided" do planting = FactoryGirl.build(:planting, :quantity => nil, :planted_from => 'seed', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady planted seeds." + expect(result).to eq "crop_lady planted seeds." end - context "multiple quantity" do - it "planted_from not provided" do + context "when quantity is greater than 1" do + it "does not have a planted from value provided" do planting = FactoryGirl.build(:planting, :quantity => 10, :planted_from => '', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady planted 10 units." + expect(result).to eq "crop_lady planted 10 units." end - it "planted_from provided" do + it "does have a planted from value provided" do planting = FactoryGirl.build(:planting, :quantity => 5, :planted_from => 'seed', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady planted 5 seeds." + expect(result).to eq "crop_lady planted 5 seeds." end end - context "single quantity" do - it "planted_from not provided" do + context "when quantity is 1" do + it "does not have a planted from value provided" do planting = FactoryGirl.build(:planting, :quantity => 1, :planted_from => '', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady planted 1 unit." + expect(result).to eq "crop_lady planted 1 unit." end - it "planted_from provided" do + it "does have a planted from value provided" do planting = FactoryGirl.build(:planting, :quantity => 1, :planted_from => 'seed', - :owner => @member + :owner => member ) result = helper.display_planting(planting) - result.should eq "crop_lady planted 1 seed." + expect(result).to eq "crop_lady planted 1 seed." end end From 81d2f9829e580e9b57c37b42776c727cdf4e893a Mon Sep 17 00:00:00 2001 From: Gabrielle DeWitt Date: Sat, 4 Apr 2015 12:00:08 -0700 Subject: [PATCH 059/392] Updated Contributors --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ad76d09fa..845ddfc01 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -54,4 +54,5 @@ submit the change with your pull request. - Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal) - Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) - Savant Krishna / [sksavant](https://github.com/sksavant) +- Gabrielle DeWitt / [gabrielle27](https://github.com/gabrielle27) From 76608a981c6cd40ce5b19ae73238fde4ee711b24 Mon Sep 17 00:00:00 2001 From: soborok Date: Sun, 8 Mar 2015 11:32:18 -0500 Subject: [PATCH 060/392] resolved issue-610 to display only active planting --- app/views/gardens/index.html.haml | 2 +- spec/features/gardens_spec.rb | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/views/gardens/index.html.haml b/app/views/gardens/index.html.haml index 2da035865..749e76189 100644 --- a/app/views/gardens/index.html.haml +++ b/app/views/gardens/index.html.haml @@ -50,7 +50,7 @@ None - else %ul - - garden.plantings.each do |p| + - garden.plantings.current.each do |p| %li = p.quantity = link_to p.crop.name, p diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 8f311804e..31626d06f 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -3,7 +3,8 @@ require 'rails_helper' feature "Planting a crop", :js => true do let!(:garden) { FactoryGirl.create(:garden) } let!(:planting) { FactoryGirl.create(:planting, garden: garden, planted_at: Date.parse("2013-3-10")) } - + let!(:tomato) { FactoryGirl.create(:tomato) } + let!(:finished_planting) { FactoryGirl.create(:finished_planting, garden: garden, crop: tomato) } background do login_as(garden.owner) @@ -72,4 +73,9 @@ feature "Planting a crop", :js => true do it_behaves_like "append date" end + scenario "List only active plantings on a garden" do + visit gardens_path + expect(page).not_to have_content finished_planting.crop_name + end + end From 507e5a0ebc0c12fe65eea4199ae5237733c4e987 Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Mon, 4 May 2015 23:11:41 -0700 Subject: [PATCH 061/392] Robots controller and custom robots.txt files New route to /robots.txt and some specific logic to switch on if the subdomain is staging or not. Staging will not allow any crawlers at all, production does not have any current limitations --- app/controllers/robots_controller.rb | 17 ++++++++ config/robots.staging.txt | 5 +++ {public => config}/robots.txt | 0 config/routes.rb | 1 + spec/controllers/robots_controller_spec.rb | 47 ++++++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 app/controllers/robots_controller.rb create mode 100644 config/robots.staging.txt rename {public => config}/robots.txt (100%) create mode 100644 spec/controllers/robots_controller_spec.rb diff --git a/app/controllers/robots_controller.rb b/app/controllers/robots_controller.rb new file mode 100644 index 000000000..2b6542ac2 --- /dev/null +++ b/app/controllers/robots_controller.rb @@ -0,0 +1,17 @@ +class RobotsController < ApplicationController + def robots + subdomain = request.subdomain + + filename = if subdomain.present? && subdomain != 'www' + "robots.#{ subdomain }.txt" + else + "robots.txt" + end + + robots_text = File.read(Rails.root.join('config', filename)) + + respond_to do |format| + format.text { render text: robots_text, layout: false } + end + end +end diff --git a/config/robots.staging.txt b/config/robots.staging.txt new file mode 100644 index 000000000..8e1d42063 --- /dev/null +++ b/config/robots.staging.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +User-Agent: * +Disallow: / diff --git a/public/robots.txt b/config/robots.txt similarity index 100% rename from public/robots.txt rename to config/robots.txt diff --git a/config/routes.rb b/config/routes.rb index 542cf8c51..b40793264 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Growstuff::Application.routes.draw do + get '/robots.txt' => 'robots#robots' resources :plant_parts diff --git a/spec/controllers/robots_controller_spec.rb b/spec/controllers/robots_controller_spec.rb new file mode 100644 index 000000000..ee2b73196 --- /dev/null +++ b/spec/controllers/robots_controller_spec.rb @@ -0,0 +1,47 @@ +require 'rails_helper' +require 'pry' + +describe RobotsController do + describe '#robots' do + + before do + @request.host = "#{ subdomain }.localhost.com" + end + + context 'subdomain is staging' do + let(:subdomain) { 'staging' } + + it 'loads the staging robots.txt file' do + expect(File).to receive(:read).with(Rails.root.join('config', 'robots.staging.txt')) + + get :robots, format: :text + + expect(response).to be_success + end + end + + context 'subdomain is www' do + let(:subdomain) { 'www' } + + it 'loads the production robots.txt file' do + expect(File).to receive(:read).with(Rails.root.join('config', 'robots.txt')) + + get :robots, format: :text + + expect(response).to be_success + end + end + + context 'subdomain is not present' do + let(:subdomain) { '' } + + it 'loads the production robots.txt file' do + expect(File).to receive(:read).with(Rails.root.join('config', 'robots.txt')) + + get :robots, format: :text + + expect(response).to be_success + end + end + end +end From 0f8d1e7db13b566d621d8547a425b92d2e6780ab Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Mon, 4 May 2015 23:37:40 -0700 Subject: [PATCH 062/392] Change the render to render the file directly Also assert that the response is the actual file contents instead of mocking the method call --- app/controllers/robots_controller.rb | 6 +---- config/robots.staging.txt | 3 --- config/robots.txt | 5 ---- spec/controllers/robots_controller_spec.rb | 31 ++++++++++------------ 4 files changed, 15 insertions(+), 30 deletions(-) diff --git a/app/controllers/robots_controller.rb b/app/controllers/robots_controller.rb index 2b6542ac2..34e07d646 100644 --- a/app/controllers/robots_controller.rb +++ b/app/controllers/robots_controller.rb @@ -8,10 +8,6 @@ class RobotsController < ApplicationController "robots.txt" end - robots_text = File.read(Rails.root.join('config', filename)) - - respond_to do |format| - format.text { render text: robots_text, layout: false } - end + render file: "config/#{ filename }", layout: false, content_type: 'text/plain' end end diff --git a/config/robots.staging.txt b/config/robots.staging.txt index 8e1d42063..c6742d8a8 100644 --- a/config/robots.staging.txt +++ b/config/robots.staging.txt @@ -1,5 +1,2 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: User-Agent: * Disallow: / diff --git a/config/robots.txt b/config/robots.txt index 085187fa5..e69de29bb 100644 --- a/config/robots.txt +++ b/config/robots.txt @@ -1,5 +0,0 @@ -# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file -# -# To ban all spiders from the entire site uncomment the next two lines: -# User-Agent: * -# Disallow: / diff --git a/spec/controllers/robots_controller_spec.rb b/spec/controllers/robots_controller_spec.rb index ee2b73196..6b85ecdb2 100644 --- a/spec/controllers/robots_controller_spec.rb +++ b/spec/controllers/robots_controller_spec.rb @@ -1,46 +1,43 @@ require 'rails_helper' require 'pry' -describe RobotsController do - describe '#robots' do +describe RobotsController do + describe '#robots' do before do - @request.host = "#{ subdomain }.localhost.com" + @request.host = "#{ subdomain }.localhost.com" end context 'subdomain is staging' do let(:subdomain) { 'staging' } it 'loads the staging robots.txt file' do - expect(File).to receive(:read).with(Rails.root.join('config', 'robots.staging.txt')) - - get :robots, format: :text + get :robots expect(response).to be_success - end + expect(response.body).to eq(File.read('config/robots.staging.txt')) + end end context 'subdomain is www' do let(:subdomain) { 'www' } - it 'loads the production robots.txt file' do - expect(File).to receive(:read).with(Rails.root.join('config', 'robots.txt')) - - get :robots, format: :text + it 'loads the production robots.txt file' do + get :robots expect(response).to be_success - end + expect(response.body).to eq(File.read('config/robots.txt')) + end end - context 'subdomain is not present' do + context 'subdomain is not present' do let(:subdomain) { '' } - it 'loads the production robots.txt file' do - expect(File).to receive(:read).with(Rails.root.join('config', 'robots.txt')) - - get :robots, format: :text + it 'loads the production robots.txt file' do + get :robots expect(response).to be_success + expect(response.body).to eq(File.read('config/robots.txt')) end end end From 81ce6ed8a368f9ee9e01412464cbede75369ed37 Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Tue, 5 May 2015 08:58:33 -0700 Subject: [PATCH 063/392] Make sure file exists before attempting to render it --- app/controllers/robots_controller.rb | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/robots_controller.rb b/app/controllers/robots_controller.rb index 34e07d646..785c8a856 100644 --- a/app/controllers/robots_controller.rb +++ b/app/controllers/robots_controller.rb @@ -1,13 +1,17 @@ class RobotsController < ApplicationController def robots - subdomain = request.subdomain - - filename = if subdomain.present? && subdomain != 'www' - "robots.#{ subdomain }.txt" - else - "robots.txt" + filename = if subdomain && subdomain != 'www' + "config/robots.#{ subdomain }.txt" end - render file: "config/#{ filename }", layout: false, content_type: 'text/plain' + file_to_render = File.exists?(filename.to_s) ? filename : 'config/robots.txt' + + render file: file_to_render, layout: false, content_type: 'text/plain' + end + + private + + def subdomain + request.subdomain.present? ? request.subdomain : nil end end From 46ac06698ad2fcb6621566dad96ff6a27a86b482 Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Tue, 5 May 2015 09:02:42 -0700 Subject: [PATCH 064/392] Additional test for nonsense subdomain --- spec/controllers/robots_controller_spec.rb | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/spec/controllers/robots_controller_spec.rb b/spec/controllers/robots_controller_spec.rb index 6b85ecdb2..7b240f5dd 100644 --- a/spec/controllers/robots_controller_spec.rb +++ b/spec/controllers/robots_controller_spec.rb @@ -3,6 +3,8 @@ require 'pry' describe RobotsController do describe '#robots' do + let(:production_filename) { 'config/robots.txt' } + let(:staging_filename) { 'config/robots.staging.txt' } before do @request.host = "#{ subdomain }.localhost.com" @@ -15,7 +17,7 @@ describe RobotsController do get :robots expect(response).to be_success - expect(response.body).to eq(File.read('config/robots.staging.txt')) + expect(response.body).to eq(File.read(staging_filename)) end end @@ -26,7 +28,7 @@ describe RobotsController do get :robots expect(response).to be_success - expect(response.body).to eq(File.read('config/robots.txt')) + expect(response.body).to eq(File.read(production_filename)) end end @@ -37,7 +39,18 @@ describe RobotsController do get :robots expect(response).to be_success - expect(response.body).to eq(File.read('config/robots.txt')) + expect(response.body).to eq(File.read(production_filename)) + end + end + + context 'subdomain is nonsense' do + let(:subdomain) { '1874ajnfien' } + + it 'loads the production robots.txt file' do + get :robots + + expect(response).to be_success + expect(response.body).to eq(File.read(production_filename)) end end end From 0d55b5437144f21e757e1fb5e918b7a840b2a4b1 Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Tue, 5 May 2015 09:05:00 -0700 Subject: [PATCH 065/392] Use a constant for the default robots.txt filename --- app/controllers/robots_controller.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/controllers/robots_controller.rb b/app/controllers/robots_controller.rb index 785c8a856..090e0e031 100644 --- a/app/controllers/robots_controller.rb +++ b/app/controllers/robots_controller.rb @@ -1,10 +1,13 @@ class RobotsController < ApplicationController + + DEFAULT_FILENAME = 'config/robots.txt'.freeze + def robots filename = if subdomain && subdomain != 'www' "config/robots.#{ subdomain }.txt" end - file_to_render = File.exists?(filename.to_s) ? filename : 'config/robots.txt' + file_to_render = File.exists?(filename.to_s) ? filename : DEFAULT_FILENAME render file: file_to_render, layout: false, content_type: 'text/plain' end From c1ab161b89131d34a17390104e29ff3d2515be4f Mon Sep 17 00:00:00 2001 From: Jake Yesbeck Date: Tue, 5 May 2015 09:09:21 -0700 Subject: [PATCH 066/392] Added self to Contributors.md per guidelines --- CONTRIBUTORS.md | 1 + spec/controllers/robots_controller_spec.rb | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ad76d09fa..ca3c7191a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -54,4 +54,5 @@ submit the change with your pull request. - Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal) - Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) - Savant Krishna / [sksavant](https://github.com/sksavant) +- Jake Yesbeck / [yez](https://github.com/yez) diff --git a/spec/controllers/robots_controller_spec.rb b/spec/controllers/robots_controller_spec.rb index 7b240f5dd..16220cfe2 100644 --- a/spec/controllers/robots_controller_spec.rb +++ b/spec/controllers/robots_controller_spec.rb @@ -1,5 +1,4 @@ require 'rails_helper' -require 'pry' describe RobotsController do describe '#robots' do From 8ce7c253748e79cdad4ae7d0d006869dade9a399 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Wed, 6 May 2015 12:15:22 +0100 Subject: [PATCH 067/392] Upgrade poltergeist to v1.6. Poltergeist v1.5.1 is nearly a year old, and relies on PhantomJS 1.8, which is 2.5 years old and increasingly hard to find in OS package managers. --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index c36bd3640..bb774b703 100644 --- a/Gemfile +++ b/Gemfile @@ -117,7 +117,7 @@ group :development, :test do gem 'coveralls', require: false # coverage analysis gem 'capybara' # integration tests gem 'capybara-email' # integration tests for email - gem 'poltergeist', '~> 1.5.1' # for headless JS testing + gem 'poltergeist', '~> 1.6' # for headless JS testing gem 'i18n-tasks' # adds tests for finding missing and unused translations end diff --git a/Gemfile.lock b/Gemfile.lock index df217e647..fef7b8258 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -268,7 +268,7 @@ GEM pg (0.17.1) plupload-rails (1.2.1) rails (>= 3.1) - poltergeist (1.5.1) + poltergeist (1.6.0) capybara (~> 2.1) cliver (~> 0.3.1) multi_json (~> 1.0) @@ -384,9 +384,9 @@ GEM nokogiri (>= 1.2.0) rack (>= 1.0) rack-test (>= 0.5.3) - websocket-driver (0.5.0) + websocket-driver (0.5.4) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.0) + websocket-extensions (0.1.2) will_paginate (3.0.7) xpath (2.0.0) nokogiri (~> 1.3) @@ -443,7 +443,7 @@ DEPENDENCIES omniauth-flickr (>= 0.0.15) omniauth-twitter pg - poltergeist (~> 1.5.1) + poltergeist (~> 1.6) pry quiet_assets rails (= 4.1.9) From 38dbdc83071eda22b7d8427e0a0492c24d9bc88c Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 20 May 2015 17:08:21 -0400 Subject: [PATCH 068/392] Moving myself (maco) to the committer section, since I was given commit bit a couple months back --- CONTRIBUTORS.md | 2 +- db/schema.rb | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ca3c7191a..294e48dd3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -12,6 +12,7 @@ submit the change with your pull request. - Cesy / [cesy](https://github.com/cesy) - Miles Gould / [pozorvlak](https://github.com/pozorvlak) - Taylor Griffin / [tygriffin](https://github.com/tygriffin) +- Mackenzie Morgan / [maco](https://github.com/maco) ## Contributors @@ -23,7 +24,6 @@ submit the change with your pull request. - Maia Sauren / [sauramaia](https://github.com/sauramaia) - Norman Ancajas / [nbancajas](https://github.com/nbancajas) - Jonathan "Duke" Leto / [leto](https://github.com/leto) -- Mackenzie Morgan / [maco](https://github.com/maco) - Amy Hendrix / [sabreuse](https://github.com/sabreuse) - CephLPod / [cephLpod](https://github.com/cephLpod/) - Gemma Mason / [gemmaellen](https://github.com/gemmaellen) diff --git a/db/schema.rb b/db/schema.rb index 7f8c479ce..6cbdd91b2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -405,7 +405,6 @@ ActiveRecord::Schema.define(version: 20150209105410) do t.datetime "updated_at" t.string "slug" t.integer "forum_id" - t.integer "parent_id" end add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree From c5fbda02239e32ad6428d97615948f5a5ee314cc Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 20 May 2015 17:10:22 -0400 Subject: [PATCH 069/392] cleaning up inadvertent schema change --- db/schema.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/db/schema.rb b/db/schema.rb index 6cbdd91b2..7f8c479ce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -405,6 +405,7 @@ ActiveRecord::Schema.define(version: 20150209105410) do t.datetime "updated_at" t.string "slug" t.integer "forum_id" + t.integer "parent_id" end add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree From 3b42806b7700c06b0eeaddb0dd4675dce894113e Mon Sep 17 00:00:00 2001 From: Shiho Takagi Date: Fri, 22 May 2015 13:46:19 +1000 Subject: [PATCH 070/392] Modified wordings --- app/controllers/members_controller.rb | 4 ++-- app/views/notifier/notify.html.haml | 2 +- app/views/notifier/planting_reminder.html.haml | 2 +- spec/features/unsubscribing_spec.rb | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index dbd90ef71..013ae44de 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -50,8 +50,8 @@ class MembersController < ApplicationController end EMAIL_TYPE_STRING = { - send_notification_email: "Inbox Notification", - send_planting_reminder: "Planting Reminder" + send_notification_email: "direct message notifications", + send_planting_reminder: "planting reminders" } def unsubscribe diff --git a/app/views/notifier/notify.html.haml b/app/views/notifier/notify.html.haml index 3a8912fbb..08883a457 100644 --- a/app/views/notifier/notify.html.haml +++ b/app/views/notifier/notify.html.haml @@ -18,7 +18,7 @@ %br/ = link_to "View this message in your inbox", notification_url(@notification) %br/ - = link_to "Turn off these notifications", unsubscribe_member_url(@signed_message) + = link_to "Unsubscribe from direct message notifications", unsubscribe_member_url(@signed_message) from these notifications = render :partial => 'signature' \ No newline at end of file diff --git a/app/views/notifier/planting_reminder.html.haml b/app/views/notifier/planting_reminder.html.haml index 201ea3575..0c9d0d5ae 100644 --- a/app/views/notifier/planting_reminder.html.haml +++ b/app/views/notifier/planting_reminder.html.haml @@ -64,5 +64,5 @@ %hr/ %p Don't want to get these emails any more? - = link_to "Turn off these notifications", unsubscribe_member_url(@signed_message) + = link_to "Unsubscribe from planting reminders", unsubscribe_member_url(@signed_message) diff --git a/spec/features/unsubscribing_spec.rb b/spec/features/unsubscribing_spec.rb index 96edef143..2c37f3101 100644 --- a/spec/features/unsubscribing_spec.rb +++ b/spec/features/unsubscribing_spec.rb @@ -19,8 +19,8 @@ feature "unsubscribe" do open_email(member.email) # clicking 'Unsubscribe' link will unsubscribe the member - current_email.click_link 'Turn off these notifications' - expect(page).to have_content "You have been unsubscribed from Planting Reminder" + current_email.click_link 'Unsubscribe from planting reminders' + expect(page).to have_content "You have been unsubscribed from planting reminders" updated_member = Member.find(member.id) # reload the member expect(updated_member.send_planting_reminder).to eq(false) expect(updated_member.send_notification_email).to eq(true) @@ -37,8 +37,8 @@ feature "unsubscribe" do open_email(member.email) # clicking 'Unsubscribe' link will unsubscribe the member - current_email.click_link 'Turn off these notifications' - expect(page).to have_content "You have been unsubscribed from Inbox Notification" + current_email.click_link 'Unsubscribe from direct message notifications' + expect(page).to have_content "You have been unsubscribed from direct message notifications" updated_member = Member.find(member.id) # reload the member expect(updated_member.send_planting_reminder).to eq(true) expect(updated_member.send_notification_email).to eq(false) From e35ebab380a9a63dc7b6fdd132ad049be0336e8f Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 27 May 2015 11:56:24 +1000 Subject: [PATCH 071/392] Reply to notification action --- app/controllers/notifications_controller.rb | 15 +++++++++++ app/helpers/notifications_helper.rb | 7 +----- app/models/ability.rb | 1 + .../notifications/_notification.html.haml | 13 ++++++++++ app/views/notifications/reply.html.haml | 6 +++++ app/views/notifications/show.html.haml | 14 +---------- config/routes.rb | 4 ++- spec/features/notifications_spec.rb | 25 +++++++++++++++++++ spec/helpers/notifications_helper_spec.rb | 5 +--- 9 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 app/views/notifications/_notification.html.haml create mode 100644 app/views/notifications/reply.html.haml create mode 100644 spec/features/notifications_spec.rb diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 3d3a217ad..4608d3f99 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -36,6 +36,21 @@ class NotificationsController < ApplicationController end end + # GET /notifications/1/reply + def reply + @notification = Notification.new + @sender_notification = Notification.find(params[:id]) + @recipient = @sender_notification.sender + @subject = @sender_notification.subject =~ /^Re: / ? + @sender_notification.subject : + "Re: " + @sender_notification.subject + + + respond_to do |format| + format.html # reply.html.haml + end + end + # DELETE /notifications/1 def destroy @notification = Notification.find(params[:id]) diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index dab53df95..cef59c9c8 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -5,12 +5,7 @@ module NotificationsHelper new_comment_url(:post_id => notification.post.id) else # by default, reply link sends a PM in return - new_notification_url( - :recipient_id => notification.sender.id, - :subject => notification.subject =~ /^Re: / ? - notification.subject : - "Re: " + notification.subject - ) + reply_notification_url(notification) end end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 1997ddf49..6ec3aea25 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -46,6 +46,7 @@ class Ability # can read/delete notifications that were sent to them can :read, Notification, :recipient_id => member.id can :destroy, Notification, :recipient_id => member.id + can :reply, Notification, :recipient_id => member.id # can send a private message to anyone but themselves # note: sadly, we can't test for this from the view, but it works # for the model/controller diff --git a/app/views/notifications/_notification.html.haml b/app/views/notifications/_notification.html.haml new file mode 100644 index 000000000..00748e728 --- /dev/null +++ b/app/views/notifications/_notification.html.haml @@ -0,0 +1,13 @@ +%p + From + = link_to notification.sender, notification.sender + on + = notification.created_at + + - if notification.post_id + in response to: + = link_to notification.post.subject, notification.post + +.well + :growstuff_markdown + #{ strip_tags(notification.body) } \ No newline at end of file diff --git a/app/views/notifications/reply.html.haml b/app/views/notifications/reply.html.haml new file mode 100644 index 000000000..808985265 --- /dev/null +++ b/app/views/notifications/reply.html.haml @@ -0,0 +1,6 @@ += content_for :title, "Send a message to #{@recipient}" + += render @sender_notification + +=render 'form' + diff --git a/app/views/notifications/show.html.haml b/app/views/notifications/show.html.haml index 1926876a6..d6cd49472 100644 --- a/app/views/notifications/show.html.haml +++ b/app/views/notifications/show.html.haml @@ -1,18 +1,6 @@ = content_for :title, @notification.subject -%p - From - = link_to @notification.sender, @notification.sender - on - = @notification.created_at - - - if @notification.post_id - in response to: - = link_to @notification.post.subject, @notification.post - -.well - :growstuff_markdown - #{ strip_tags(@notification.body) } += render @notification %p =link_to 'Delete', @notification, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default' diff --git a/config/routes.rb b/config/routes.rb index b40793264..4f2546049 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -41,7 +41,9 @@ Growstuff::Application.routes.draw do resources :comments resources :roles resources :forums - resources :notifications + resources :notifications do + get 'reply', on: :member + end resources :follows, :only => [:create, :destroy] get '/members/:login_name/follows' => 'members#view_follows', :as => 'member_follows' diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb new file mode 100644 index 000000000..5135a1c72 --- /dev/null +++ b/spec/features/notifications_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +feature "Notifications", :js => true do + let(:sender) { FactoryGirl.create(:member) } + let(:recipient) { FactoryGirl.create(:member) } + + context "On existing notification" do + let!(:notification) { FactoryGirl.create(:notification, sender: sender, recipient: recipient, body: "Notification body", :post_id => nil) } + + background do + login_as(recipient) + visit notification_path(notification) + end + + scenario "Replying to the notification" do + click_link "Reply" + expect(page).to have_content "Notification body" + + fill_in 'notification_body', with: "Response body" + click_button "Send" + + expect(page).to have_content "Message was successfully sent" + end + end +end \ No newline at end of file diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 85f96d664..b233246ab 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -13,10 +13,7 @@ describe NotificationsHelper do link = helper.reply_link(notification) link.should_not be_nil - link.should eq new_notification_url( - :recipient_id => notification.sender_id, - :subject => subject - ) + link.should eq reply_notification_url(notification) end it "replies to post comments with post comments" do From ad5730a81caf77c38b8899aae54dadd66f4e98d0 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 27 May 2015 12:08:30 +1000 Subject: [PATCH 072/392] Removed excessive example from notification controller specs --- spec/controllers/notifications_controller_spec.rb | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 858444312..55bf1d72d 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -60,18 +60,6 @@ describe NotificationsController do assigns(:notification).should eq(notification) end - it "assigns the reply link for a PM" do - notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id, :post_id => nil) - subject = "Re: " + notification.subject - - get :show, {:id => notification.to_param} - assigns(:reply_link).should_not be_nil - assigns(:reply_link).should eq new_notification_url( - :recipient_id => notification.sender_id, - :subject => subject - ) - end - it "assigns the reply link for a post comment" do notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) From 3476d586423aab804506953d86e5a3567cb28391 Mon Sep 17 00:00:00 2001 From: Achal Channarasappa Date: Tue, 2 Jun 2015 20:52:03 -0500 Subject: [PATCH 073/392] added growstuff-apple-touch-icon-precomposed.png to meta partial --- app/views/layouts/_meta.html.haml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/views/layouts/_meta.html.haml b/app/views/layouts/_meta.html.haml index 13acb28bc..fecf8dff9 100644 --- a/app/views/layouts/_meta.html.haml +++ b/app/views/layouts/_meta.html.haml @@ -1,6 +1,9 @@ %head + + + - if (content_for?(:member_rss_login_name) && content_for(:member_rss_slug)) = auto_discovery_link_tag(:rss, { :controller => "/members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "#{ ENV['GROWSTUFF_SITE_NAME'] }- #{yield(:member_rss_login_name)}'s posts" }) From e3a620a109eb4edbe24823f33509e3228aff870e Mon Sep 17 00:00:00 2001 From: Mauricio Date: Tue, 2 Jun 2015 23:21:18 -0600 Subject: [PATCH 074/392] [#478] autofocus subject input --- CONTRIBUTORS.md | 1 + app/views/posts/_form.html.haml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 294e48dd3..0870d8ff4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -55,4 +55,5 @@ submit the change with your pull request. - Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) - Savant Krishna / [sksavant](https://github.com/sksavant) - Jake Yesbeck / [yez](https://github.com/yez) +- Mauricio Gonzalez / [mauricio-gonzalez](https://github.com/mauricio-gonzalez) diff --git a/app/views/posts/_form.html.haml b/app/views/posts/_form.html.haml index 3ae4e5172..bbb3fd352 100644 --- a/app/views/posts/_form.html.haml +++ b/app/views/posts/_form.html.haml @@ -8,7 +8,7 @@ .form-group = label_tag :post, "Subject", :class => 'control-label' - = f.text_field :subject, :class => 'form-control' + = f.text_field :subject, :class => 'form-control', :autofocus => true .form-group - if @post.forum || @forum From 60df62f3fa0828326b9e8ec35c20850664b92e21 Mon Sep 17 00:00:00 2001 From: Vincent Wong Date: Sat, 6 Jun 2015 14:36:03 +1000 Subject: [PATCH 075/392] added flash message when deleting messages --- app/controllers/photos_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 63672efe1..9f39aa7ab 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -124,7 +124,8 @@ class PhotosController < ApplicationController def destroy @photo = Photo.find(params[:id]) @photo.destroy - + flash[:alert] = "Photo successfully deleted." + respond_to do |format| format.html { redirect_to photos_url } format.json { head :no_content } From 4cb3444dcd108976261f9b53f42406a1e2ecf5d2 Mon Sep 17 00:00:00 2001 From: Andrey Date: Tue, 9 Jun 2015 17:47:21 +1000 Subject: [PATCH 076/392] Adding myself to contributors --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ca3c7191a..1139eaeba 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -55,4 +55,5 @@ submit the change with your pull request. - Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) - Savant Krishna / [sksavant](https://github.com/sksavant) - Jake Yesbeck / [yez](https://github.com/yez) +- Andrey Bazhutkin / [andrba](https://github.com/andrba) From 0e2a5fd20503c433f4e582ed752b4515f0778b4b Mon Sep 17 00:00:00 2001 From: gabrielsandoval Date: Sun, 21 Jun 2015 15:24:07 +0800 Subject: [PATCH 077/392] Added search form on the places index page. --- Gemfile.lock | 3 +++ app/views/places/_search_form.html.haml | 6 ++++++ app/views/places/index.html.haml | 2 +- app/views/places/show.html.haml | 7 +------ config/database.yml | 1 + 5 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 app/views/places/_search_form.html.haml diff --git a/Gemfile.lock b/Gemfile.lock index fef7b8258..7e3b4aa92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,3 +458,6 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) + +BUNDLED WITH + 1.10.3 diff --git a/app/views/places/_search_form.html.haml b/app/views/places/_search_form.html.haml new file mode 100644 index 000000000..e9f801c17 --- /dev/null +++ b/app/views/places/_search_form.html.haml @@ -0,0 +1,6 @@ +%form{:action => search_places_path, :method => :get, :class => 'form-inline', :role => 'form'} + .form-group + = label_tag :new_place, "Change location:", :class => 'sr-only' + = text_field_tag :new_place, '', :class => 'form-control', :placeholder => "New location..." + = submit_tag "Search", :class => 'btn btn-primary' +%br/ diff --git a/app/views/places/index.html.haml b/app/views/places/index.html.haml index 135d3a113..a81dd6ba8 100644 --- a/app/views/places/index.html.haml +++ b/app/views/places/index.html.haml @@ -1,4 +1,4 @@ -content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} Community Map" - += render partial: 'search_form' %div#placesmap diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index b34846b39..8cc9f86ef 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -1,11 +1,6 @@ -content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} members near #{@place}" -%form{:action => search_places_path, :method => :get, :class => 'form-inline', :role => 'form'} - .form-group - = label_tag :new_place, "Change location:", :class => 'sr-only' - = text_field_tag :new_place, '', :class => 'form-control', :placeholder => "New location..." - = submit_tag "Search", :class => 'btn btn-primary' -%br/ += render partial: 'search_form' %div#placesmap{ :style => "height:300px"} diff --git a/config/database.yml b/config/database.yml index 6b0ab1503..6aeb5d961 100644 --- a/config/database.yml +++ b/config/database.yml @@ -3,6 +3,7 @@ development: database: growstuff_dev host: localhost user: postgres + password: password test: adapter: postgresql From 87f1c6c26dc450f55ce097043f51cbb491af6920 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 23 Jun 2015 14:33:13 +0800 Subject: [PATCH 078/392] Added an alert for empty string search. --- Gemfile.lock | 3 --- app/controllers/places_controller.rb | 14 +++++++++--- app/views/places/_search_form.html.haml | 2 +- .../features/places/searching_a_place_spec.rb | 22 +++++++++++++++++++ 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 spec/features/places/searching_a_place_spec.rb diff --git a/Gemfile.lock b/Gemfile.lock index 7e3b4aa92..fef7b8258 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,6 +458,3 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) - -BUNDLED WITH - 1.10.3 diff --git a/app/controllers/places_controller.rb b/app/controllers/places_controller.rb index 54ca249fd..82189cb68 100644 --- a/app/controllers/places_controller.rb +++ b/app/controllers/places_controller.rb @@ -21,9 +21,17 @@ class PlacesController < ApplicationController end def search - respond_to do |format| - format.html do - redirect_to place_path(params[:new_place]) + if params[:new_place].empty? + respond_to do |format| + format.html do + redirect_to places_path, alert: 'Please enter a valid location' + end + end + else + respond_to do |format| + format.html do + redirect_to place_path(params[:new_place]) + end end end end diff --git a/app/views/places/_search_form.html.haml b/app/views/places/_search_form.html.haml index e9f801c17..430ebd58d 100644 --- a/app/views/places/_search_form.html.haml +++ b/app/views/places/_search_form.html.haml @@ -2,5 +2,5 @@ .form-group = label_tag :new_place, "Change location:", :class => 'sr-only' = text_field_tag :new_place, '', :class => 'form-control', :placeholder => "New location..." - = submit_tag "Search", :class => 'btn btn-primary' + = submit_tag "Search", :class => 'btn btn-primary', :id => "search_button" %br/ diff --git a/spec/features/places/searching_a_place_spec.rb b/spec/features/places/searching_a_place_spec.rb new file mode 100644 index 000000000..614fe9188 --- /dev/null +++ b/spec/features/places/searching_a_place_spec.rb @@ -0,0 +1,22 @@ +require "rails_helper" + +RSpec.feature "User searches", :type => :feature do + + scenario "with a valid place" do + visit "/places" + search_with("Philippines") + assert true + end + + scenario "with a blank search string" do + visit "/places" + search_with("") + assert true + end + + def search_with(search_string) + fill_in "new_place", :with => search_string + click_button "search_button" + end + +end \ No newline at end of file From bb88041fef6c33dd3d1723d1562a964163a6e461 Mon Sep 17 00:00:00 2001 From: Cjay Billones Date: Thu, 25 Jun 2015 09:36:15 +0800 Subject: [PATCH 079/392] [Refactoring] Replace .count and .length with .size for collections Improved program efficiency (in querying in particular) by replacing .count and .length with .size for collections. Fix error in refactoring Reverted some .size into .count --- app/controllers/crops_controller.rb | 2 +- app/models/crop.rb | 6 +++--- app/models/member.rb | 2 +- app/models/notification.rb | 2 +- app/models/planting.rb | 2 +- app/models/post.rb | 2 +- app/models/seed.rb | 2 +- app/views/account_types/_form.html.haml | 2 +- app/views/accounts/_form.html.haml | 2 +- app/views/admin/orders/search.html.haml | 4 ++-- app/views/alternate_names/_form.html.haml | 2 +- app/views/comments/_form.html.haml | 2 +- app/views/crops/_form.html.haml | 2 +- app/views/crops/_popover.html.haml | 2 +- app/views/crops/_thumbnail.html.haml | 2 +- app/views/crops/index.csv.shaper | 6 +++--- app/views/forums/_form.html.haml | 2 +- app/views/forums/index.html.haml | 2 +- app/views/forums/show.html.haml | 2 +- app/views/gardens/_form.html.haml | 2 +- app/views/gardens/index.html.haml | 2 +- app/views/gardens/show.html.haml | 8 ++++---- app/views/harvests/_form.html.haml | 2 +- app/views/harvests/index.html.haml | 2 +- app/views/harvests/show.html.haml | 2 +- app/views/home/_seeds.html.haml | 2 +- app/views/members/_gardens.html.haml | 2 +- app/views/members/_stats.html.haml | 12 ++++++------ app/views/notifications/_form.html.haml | 2 +- app/views/notifications/index.html.haml | 2 +- app/views/orders/index.html.haml | 2 +- app/views/orders/show.html.haml | 2 +- app/views/photos/new.html.haml | 2 +- app/views/plant_parts/_form.html.haml | 2 +- app/views/plantings/_form.html.haml | 2 +- app/views/plantings/index.html.haml | 2 +- app/views/plantings/show.html.haml | 2 +- app/views/posts/_comments.html.haml | 2 +- app/views/posts/_form.html.haml | 2 +- app/views/posts/_single.html.haml | 2 +- app/views/posts/_summary.html.haml | 4 ++-- app/views/products/_form.html.haml | 2 +- app/views/roles/_form.html.haml | 2 +- app/views/scientific_names/_form.html.haml | 2 +- app/views/seeds/_form.html.haml | 2 +- app/views/seeds/index.html.haml | 2 +- app/views/shop/index.html.haml | 2 +- 47 files changed, 61 insertions(+), 61 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 917b72570..ffd0ed3af 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -107,7 +107,7 @@ class CropsController < ApplicationController def edit @crop = Crop.find(params[:id]) - (3 - @crop.scientific_names.length).times do + (3 - @crop.scientific_names.size).times do @crop.scientific_names.build end end diff --git a/app/models/crop.rb b/app/models/crop.rb index 6bf902c4c..2773bbe38 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -116,7 +116,7 @@ class Crop < ActiveRecord::Base end def default_scientific_name - if scientific_names.count > 0 + if scientific_names.size > 0 return scientific_names.first.scientific_name else return nil @@ -177,7 +177,7 @@ class Crop < ActiveRecord::Base def interesting? min_plantings = 3 # needs this many plantings to be interesting min_photos = 3 # needs this many photos to be interesting - return false unless photos.count >= min_photos + return false unless photos.size >= min_photos return false unless plantings_count >= min_plantings return true end @@ -208,7 +208,7 @@ class Crop < ActiveRecord::Base howmany = 12 # max number to find interesting_crops = Array.new Crop.randomized.each do |c| - break if interesting_crops.length == howmany + break if interesting_crops.size == howmany next unless c.interesting? interesting_crops.push(c) end diff --git a/app/models/member.rb b/app/models/member.rb index 6c00fb8ce..a8af799b1 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -202,7 +202,7 @@ class Member < ActiveRecord::Base howmany = 12 # max number to find interesting_members = Array.new Member.confirmed.located.recently_signed_in.each do |m| - break if interesting_members.length == howmany + break if interesting_members.size == howmany if m.interesting? interesting_members.push(m) end diff --git a/app/models/notification.rb b/app/models/notification.rb index 304b86b03..3825d7b12 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -10,7 +10,7 @@ class Notification < ActiveRecord::Base after_create :send_email def self.unread_count - self.unread.count + self.unread.size end def replace_blank_subject diff --git a/app/models/planting.rb b/app/models/planting.rb index 958ba625f..ea9faf0d0 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -102,7 +102,7 @@ class Planting < ActiveRecord::Base seen_owners = Hash.new(false) # keep track of which owners we've seen already Planting.all.each do |p| - break if interesting_plantings.count == howmany # got enough yet? + break if interesting_plantings.size == howmany # got enough yet? if require_photo next unless p.photos.present? # skip those without photos, if required end diff --git a/app/models/post.rb b/app/models/post.rb index 88c6355cc..a1174b078 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -24,7 +24,7 @@ class Post < ActiveRecord::Base end def comment_count - self.comments.count + self.comments.size end # return the timestamp of the most recent activity on this post diff --git a/app/models/seed.rb b/app/models/seed.rb index 9fa005907..c72187fc7 100644 --- a/app/models/seed.rb +++ b/app/models/seed.rb @@ -82,7 +82,7 @@ class Seed < ActiveRecord::Base interesting_seeds = Array.new Seed.tradable.each do |s| - break if interesting_seeds.length == howmany + break if interesting_seeds.size == howmany if s.interesting? interesting_seeds.push(s) end diff --git a/app/views/account_types/_form.html.haml b/app/views/account_types/_form.html.haml index 12fcda225..0863693fe 100644 --- a/app/views/account_types/_form.html.haml +++ b/app/views/account_types/_form.html.haml @@ -1,7 +1,7 @@ = form_for @account_type do |f| - if @account_type.errors.any? #error_explanation - %h2= "#{pluralize(@account_type.errors.count, "error")} prohibited this account_type from being saved:" + %h2= "#{pluralize(@account_type.errors.size, "error")} prohibited this account_type from being saved:" %ul - @account_type.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/accounts/_form.html.haml b/app/views/accounts/_form.html.haml index 6e648d622..ce9e26eeb 100644 --- a/app/views/accounts/_form.html.haml +++ b/app/views/accounts/_form.html.haml @@ -1,7 +1,7 @@ = form_for @account do |f| - if @account.errors.any? #error_explanation - %h2= "#{pluralize(@account.errors.count, "error")} prohibited this account from being saved:" + %h2= "#{pluralize(@account.errors.size, "error")} prohibited this account from being saved:" %ul - @account.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/admin/orders/search.html.haml b/app/views/admin/orders/search.html.haml index 022e97d87..d76715fa5 100644 --- a/app/views/admin/orders/search.html.haml +++ b/app/views/admin/orders/search.html.haml @@ -5,7 +5,7 @@ - unless @orders.empty? %h2 Found - = pluralize(@orders.count, "result") + = pluralize(@orders.size, "result") %table.table.table-striped %tr @@ -28,7 +28,7 @@ %td = order.referral_code %td - - if order.order_items.count > 0 + - if order.order_items.size > 0 - order.order_items.each do |o| = o.quantity x diff --git a/app/views/alternate_names/_form.html.haml b/app/views/alternate_names/_form.html.haml index 7d6f9abd5..05dbc0133 100644 --- a/app/views/alternate_names/_form.html.haml +++ b/app/views/alternate_names/_form.html.haml @@ -1,7 +1,7 @@ = form_for @alternate_name, :html => {:class => 'form-horizontal', :role => "form"} do |f| - if @alternate_name.errors.any? #error_explanation - %h2= "#{pluralize(@alternate_name.errors.count, "error")} prohibited this alternate_name from being saved:" + %h2= "#{pluralize(@alternate_name.errors.size, "error")} prohibited this alternate_name from being saved:" %ul - @alternate_name.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml index 5d13ec6b5..e284766a2 100644 --- a/app/views/comments/_form.html.haml +++ b/app/views/comments/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@comment, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @comment.errors.any? #error_explanation - %h2= "#{pluralize(@comment.errors.count, "error")} prohibited this comment from being saved:" + %h2= "#{pluralize(@comment.errors.size, "error")} prohibited this comment from being saved:" %ul - @comment.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index cd42ca758..867239c0f 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -1,7 +1,7 @@ = form_for @crop, :html => {:class => 'form-horizontal', :role => "form"} do |f| - if @crop.errors.any? #error_explanation - %h3= "#{pluralize(@crop.errors.count, "error")} prohibited this crop from being saved:" + %h3= "#{pluralize(@crop.errors.size, "error")} prohibited this crop from being saved:" %ul - @crop.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/crops/_popover.html.haml b/app/views/crops/_popover.html.haml index 0c40b6ec7..625e55297 100644 --- a/app/views/crops/_popover.html.haml +++ b/app/views/crops/_popover.html.haml @@ -1,6 +1,6 @@ %p %small - - if crop.scientific_names.count > 0 + - if crop.scientific_names.size > 0 %i = crop.scientific_names.first.scientific_name %br/ diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index 6fc8a723e..1a6562894 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -5,7 +5,7 @@ .cropinfo .cropname = link_to crop.name, crop - - if crop.scientific_names.count > 0 + - if crop.scientific_names.size > 0 .scientificname = crop.scientific_names.first.scientific_name .plantingcount diff --git a/app/views/crops/index.csv.shaper b/app/views/crops/index.csv.shaper index 9b245492f..116d1fa9b 100644 --- a/app/views/crops/index.csv.shaper +++ b/app/views/crops/index.csv.shaper @@ -49,7 +49,7 @@ csv.headers *all_headers if c.scientific_names.any? csv.cell :default_scientific_name, c.default_scientific_name - csv.cell :scientific_name_count, c.scientific_names.count + csv.cell :scientific_name_count, c.scientific_names.size end if c.parent @@ -58,8 +58,8 @@ csv.headers *all_headers end csv.cell :plantings_count, c.plantings_count || 0 - csv.cell :seeds_count, c.seeds.count - csv.cell :harvests_count, c.harvests.count + csv.cell :seeds_count, c.seeds.size + csv.cell :harvests_count, c.harvests.size # Sunniness diff --git a/app/views/forums/_form.html.haml b/app/views/forums/_form.html.haml index 8168f30cd..524e4c20e 100644 --- a/app/views/forums/_form.html.haml +++ b/app/views/forums/_form.html.haml @@ -1,7 +1,7 @@ = form_for @forum, :html => { :class => 'form-horizontal', :role => "form" } do |f| - if @forum.errors.any? #error_explanation - %h2= "#{pluralize(@forum.errors.count, "error")} prohibited this forum from being saved:" + %h2= "#{pluralize(@forum.errors.size, "error")} prohibited this forum from being saved:" %ul - @forum.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/forums/index.html.haml b/app/views/forums/index.html.haml index 3737d3f6f..f838160a3 100644 --- a/app/views/forums/index.html.haml +++ b/app/views/forums/index.html.haml @@ -7,7 +7,7 @@ - @forums.each do |forum| %h2= forum %p - = pluralize(forum.posts.count, "post") + = pluralize(forum.posts.size, "post") | =link_to "Visit forum", forum | diff --git a/app/views/forums/show.html.haml b/app/views/forums/show.html.haml index de839a651..08bc3b55c 100644 --- a/app/views/forums/show.html.haml +++ b/app/views/forums/show.html.haml @@ -19,7 +19,7 @@ Posts =link_to "Post something", new_post_path(:forum_id => @forum.id), :class => 'btn btn-primary' -- if @forum.posts.count > 0 +- if @forum.posts.size > 0 =render :partial => "posts/summary", :locals => { :posts => @forum.posts } - else No posts yet. diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index f5cd7c429..1915910db 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@garden, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @garden.errors.any? #error_explanation - %h2= "#{pluralize(@garden.errors.count, "error")} prohibited this garden from being saved:" + %h2= "#{pluralize(@garden.errors.size, "error")} prohibited this garden from being saved:" %ul - @garden.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/gardens/index.html.haml b/app/views/gardens/index.html.haml index 749e76189..db4f800f5 100644 --- a/app/views/gardens/index.html.haml +++ b/app/views/gardens/index.html.haml @@ -14,7 +14,7 @@ - else = render :partial => 'shared/signin_signup', :locals => { :to => 'add a new garden' } -- if @gardens.length > 0 +- if @gardens.size > 0 %div.pagination = page_entries_info @gardens, :model => "gardens" diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 25c707fb3..0ca1f3cfb 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -29,7 +29,7 @@ :growstuff_markdown #{strip_tags @garden.description} - - if @garden.photos.count > 0 or (can? :edit, @garden and can? :create, Photo) + - if @garden.photos.size > 0 or (can? :edit, @garden and can? :create, Photo) .row %h2 Photos @@ -47,14 +47,14 @@ %h3 What's planted here? - - if @garden.plantings.current.count > 0 + - if @garden.plantings.current.size > 0 - @garden.plantings.current.each do |p| = render :partial => "plantings/thumbnail", :locals => { :planting => p } - else %p Nothing is currently planted here. - - if @garden.plantings.finished.count > 0 + - if @garden.plantings.finished.size > 0 %h3 Previously planted in this garden - @garden.plantings.finished.each do |p| = render :partial => "plantings/thumbnail", :locals => { :planting => p } @@ -82,7 +82,7 @@ - else = link_to "#{othergarden}", garden_path(othergarden) - - if @garden.owner.gardens.inactive.count > 0 + - if @garden.owner.gardens.inactive.size > 0 %h4= "Inactive gardens" %ul - @garden.owner.gardens.inactive.each do |othergarden| diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 806bf8701..4aae2540e 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@harvest, :html => {:class => "form-horizontal", :role => :form}) do |f| - if @harvest.errors.any? #error_explanation - %h2= "#{pluralize(@harvest.errors.count, "error")} prohibited this harvest from being saved:" + %h2= "#{pluralize(@harvest.errors.size, "error")} prohibited this harvest from being saved:" %ul - @harvest.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index f50129c9a..82281a3af 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -22,7 +22,7 @@ = page_entries_info @harvests, :model => "harvests" = will_paginate @harvests -- if @harvests.length > 0 +- if @harvests.size > 0 %table.table.table-striped %tr diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index 1cbd0d38e..4673c7e13 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -35,7 +35,7 @@ :growstuff_markdown #{ @harvest.description != "" ? @harvest.description : "No description given." } -- if @harvest.photos.count > 0 or (can? :edit, @harvest and can? :create, Photo) +- if @harvest.photos.size > 0 or (can? :edit, @harvest and can? :create, Photo) %h2 Pictures %ul.thumbnails diff --git a/app/views/home/_seeds.html.haml b/app/views/home/_seeds.html.haml index 817af347c..ce786b7bd 100644 --- a/app/views/home/_seeds.html.haml +++ b/app/views/home/_seeds.html.haml @@ -4,7 +4,7 @@ %h2= t('.title') - cache cache_key_for(Seed) do - - if seeds.length > 0 + - if seeds.size > 0 %table.table.table-striped %tr diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 38831922c..cca8ca5b1 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -19,7 +19,7 @@ :growstuff_markdown #{ strip_tags g.description } - - if g.photos.count > 0 or (can? :edit, g and can? :create, Photo) + - if g.photos.size > 0 or (can? :edit, g and can? :create, Photo) .row %h2 Photos diff --git a/app/views/members/_stats.html.haml b/app/views/members/_stats.html.haml index b6e52873d..4b9cce87d 100644 --- a/app/views/members/_stats.html.haml +++ b/app/views/members/_stats.html.haml @@ -2,34 +2,34 @@ %ul %li - - if member.plantings.count > 0 + - if member.plantings.size > 0 = link_to pluralize(member.plantings.size, "planting"), plantings_by_owner_path(:owner => member) - else 0 plantings %li - - if member.harvests.count > 0 + - if member.harvests.size > 0 = link_to pluralize(member.harvests.size, "harvest"), harvests_by_owner_path(:owner => member) - else 0 harvests %li - - if member.seeds.count > 0 + - if member.seeds.size > 0 = link_to pluralize(member.seeds.size, "seeds"), seeds_by_owner_path(:owner => member) - else 0 seeds %li - - if member.posts.count > 0 + - if member.posts.size > 0 = link_to pluralize(member.posts.size, "post"), posts_by_author_path(:author => member) - else 0 posts %li - - if member.followed.count > 0 + - if member.followed.size > 0 = link_to pluralize(member.followed.size, "follow"), member_follows_path(member) - else 0 following %li - - if member.followers.count > 0 + - if member.followers.size > 0 = link_to pluralize(member.followers.size, "follower"), member_followers_path(member) - else 0 followers diff --git a/app/views/notifications/_form.html.haml b/app/views/notifications/_form.html.haml index 91115b15a..6e73c7444 100644 --- a/app/views/notifications/_form.html.haml +++ b/app/views/notifications/_form.html.haml @@ -1,7 +1,7 @@ = form_for @notification do |f| - if @notification.errors.any? #error_explanation - %h2= "#{pluralize(@post.errors.count, "error")} prohibited this message from being sent:" + %h2= "#{pluralize(@post.errors.size, "error")} prohibited this message from being sent:" %ul - @notification.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/notifications/index.html.haml b/app/views/notifications/index.html.haml index 1c7ec4489..d5b373606 100644 --- a/app/views/notifications/index.html.haml +++ b/app/views/notifications/index.html.haml @@ -1,6 +1,6 @@ - content_for :title, "Inbox" -- if @notifications.length > 0 +- if @notifications.size > 0 %table.table.table-striped %tr %th From diff --git a/app/views/orders/index.html.haml b/app/views/orders/index.html.haml index e48b38c3c..f05b2f756 100644 --- a/app/views/orders/index.html.haml +++ b/app/views/orders/index.html.haml @@ -28,7 +28,7 @@ - else In progress %td - - if order.order_items.count > 0 + - if order.order_items.size > 0 - order.order_items.each do |o| = o.quantity x diff --git a/app/views/orders/show.html.haml b/app/views/orders/show.html.haml index dbc635d4e..29bd0f2bc 100644 --- a/app/views/orders/show.html.haml +++ b/app/views/orders/show.html.haml @@ -61,7 +61,7 @@ - if @order.errors.any? .alert #error_explanation - %h3= "#{pluralize(@order.errors.count, "error")} stopped you from checking out:" + %h3= "#{pluralize(@order.errors.size, "error")} stopped you from checking out:" %ul - @order.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/photos/new.html.haml b/app/views/photos/new.html.haml index 6b4e589b0..802281b99 100644 --- a/app/views/photos/new.html.haml +++ b/app/views/photos/new.html.haml @@ -10,7 +10,7 @@ - if @sets and @current_set %h2= @sets.key(@current_set) - - if @sets and @sets.length > 0 + - if @sets and @sets.size > 0 %p = form_tag(new_photo_path, :method => :get, :class => 'form-inline') do = label_tag :set, "Choose a photo album:", :class => 'control-label' diff --git a/app/views/plant_parts/_form.html.haml b/app/views/plant_parts/_form.html.haml index 16bf0268d..fca6c3af3 100644 --- a/app/views/plant_parts/_form.html.haml +++ b/app/views/plant_parts/_form.html.haml @@ -1,7 +1,7 @@ = form_for @plant_part do |f| - if @plant_part.errors.any? #error_explanation - %h2= "#{pluralize(@plant_part.errors.count, "error")} prohibited this plant_part from being saved:" + %h2= "#{pluralize(@plant_part.errors.size, "error")} prohibited this plant_part from being saved:" %ul - @plant_part.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index 9c166449a..b16fc2391 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@planting, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @planting.errors.any? #error_explanation - %h2= "#{pluralize(@planting.errors.count, "error")} prohibited this planting from being saved:" + %h2= "#{pluralize(@planting.errors.size, "error")} prohibited this planting from being saved:" %ul - @planting.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 1d27df4e8..25b52ee2d 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -18,7 +18,7 @@ = page_entries_info @plantings, :model => "plantings" = will_paginate @plantings -- if @plantings.length > 0 +- if @plantings.size > 0 %table.table.table-striped %tr diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 72819f7ac..93cc2a910 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -58,7 +58,7 @@ :growstuff_markdown #{ @planting.description != "" ? @planting.description : "No description given." } -- if @planting.photos.count > 0 or (can? :edit, @planting and can? :create, Photo) +- if @planting.photos.size > 0 or (can? :edit, @planting and can? :create, Photo) %h2 Pictures .row diff --git a/app/views/posts/_comments.html.haml b/app/views/posts/_comments.html.haml index bf565debc..78375ab00 100644 --- a/app/views/posts/_comments.html.haml +++ b/app/views/posts/_comments.html.haml @@ -1,7 +1,7 @@ %a{:name => "comments"} - if post.comments %h2 - =pluralize(post.comments.length, "comment") + =pluralize(post.comments.size, "comment") - post.comments.post_order.each do |c| = render :partial => "comments/single", :locals => { :comment => c } diff --git a/app/views/posts/_form.html.haml b/app/views/posts/_form.html.haml index bbb3fd352..a23a5742a 100644 --- a/app/views/posts/_form.html.haml +++ b/app/views/posts/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@post, :html => {:role => "form"}) do |f| - if @post.errors.any? #error_explanation - %h2= "#{pluralize(@post.errors.count, "error")} prohibited this post from being saved:" + %h2= "#{pluralize(@post.errors.size, "error")} prohibited this post from being saved:" %ul - @post.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/posts/_single.html.haml b/app/views/posts/_single.html.haml index 8f5cc5507..e6f7ae0f3 100644 --- a/app/views/posts/_single.html.haml +++ b/app/views/posts/_single.html.haml @@ -24,7 +24,7 @@ - unless defined?(hide_comments) .post-comments %ul.list-inline - %li.first= link_to pluralize(post.comments.count, "comment"), + %li.first= link_to pluralize(post.comments.size, "comment"), post_path(post, :anchor => 'comments') -if can? :create, Comment %li= link_to "Reply", new_comment_path(:post_id => post.id) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index f04dd2fb0..65fdeb567 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -1,5 +1,5 @@ - howmany ||= 100 -- if posts.length > 0 +- if posts.size > 0 %table.table.table-striped %tr %th Subject @@ -18,4 +18,4 @@ = distance_of_time_in_words(post.recent_activity, Time.zone.now) ago %td.hidden-xs - = post.comments.count.to_s + = post.comments.size.to_s diff --git a/app/views/products/_form.html.haml b/app/views/products/_form.html.haml index f09bce0d8..78908001a 100644 --- a/app/views/products/_form.html.haml +++ b/app/views/products/_form.html.haml @@ -1,7 +1,7 @@ = form_for @product do |f| - if @product.errors.any? #error_explanation - %h2= "#{pluralize(@product.errors.count, "error")} prohibited this product from being saved:" + %h2= "#{pluralize(@product.errors.size, "error")} prohibited this product from being saved:" %ul - @product.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/roles/_form.html.haml b/app/views/roles/_form.html.haml index 954a2f6a0..0d307d999 100644 --- a/app/views/roles/_form.html.haml +++ b/app/views/roles/_form.html.haml @@ -1,7 +1,7 @@ = form_for @role do |f| - if @role.errors.any? #error_explanation - %h2= "#{pluralize(@role.errors.count, "error")} prohibited this role from being saved:" + %h2= "#{pluralize(@role.errors.size, "error")} prohibited this role from being saved:" %ul - @role.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/scientific_names/_form.html.haml b/app/views/scientific_names/_form.html.haml index e8d08978a..c29d371bf 100644 --- a/app/views/scientific_names/_form.html.haml +++ b/app/views/scientific_names/_form.html.haml @@ -1,7 +1,7 @@ = form_for @scientific_name, :html => {:class => 'form-horizontal', :role => "form"} do |f| - if @scientific_name.errors.any? #error_explanation - %h2= "#{pluralize(@scientific_name.errors.count, "error")} prohibited this scientific_name from being saved:" + %h2= "#{pluralize(@scientific_name.errors.size, "error")} prohibited this scientific_name from being saved:" %ul - @scientific_name.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index 4d80d8726..c40a08697 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -1,7 +1,7 @@ = form_for(@seed, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @seed.errors.any? #error_explanation - %h2= "#{pluralize(@seed.errors.count, "error")} prohibited this seed from being saved:" + %h2= "#{pluralize(@seed.errors.size, "error")} prohibited this seed from being saved:" %ul - @seed.errors.full_messages.each do |msg| %li= msg diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index c9e981651..9ce88690f 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -22,7 +22,7 @@ = page_entries_info @seeds, :model => "seeds" = will_paginate @seeds -- if @seeds.length > 0 +- if @seeds.size > 0 %table.table.table-striped %tr diff --git a/app/views/shop/index.html.haml b/app/views/shop/index.html.haml index d2064828e..a31f71655 100644 --- a/app/views/shop/index.html.haml +++ b/app/views/shop/index.html.haml @@ -26,7 +26,7 @@ = render "shared/account_status" -- elsif @order and @order.order_items.count > 0 +- elsif @order and @order.order_items.size > 0 %h2 Your current order %p From 9bd7448ae6951a0061e3fa82144627aef5863d62 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 26 Jun 2015 09:17:08 +0800 Subject: [PATCH 080/392] Added the feature test for searching places --- CONTRIBUTORS.md | 1 + config/initializers/geocoder.rb | 13 +++++++++++++ spec/features/places/searching_a_place_spec.rb | 13 +++++++++---- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 45b24943e..9e5d488e4 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -57,3 +57,4 @@ submit the change with your pull request. - Jake Yesbeck / [yez](https://github.com/yez) - Mauricio Gonzalez / [mauricio-gonzalez](https://github.com/mauricio-gonzalez) - Andrey Bazhutkin / [andrba](https://github.com/andrba) +- Gabriel Sandoval / [gabrielsandoval](https://github.com/gabrielsandoval) diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index 16de69ec0..d2758b957 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -15,3 +15,16 @@ if Geocoder.config.lookup != :test Geocoder.configure(:lookup => :nominatim) end +Geocoder::Lookup::Test.add_stub( + "Philippines", [ + { + 'latitude' => 12.7503486, + 'longitude' => 122.7312101, + 'address' => 'Manila, Mnl, Philippines', + 'state' => 'Manila', + 'state_code' => 'Mnl', + 'country' => 'Philippines', + 'country_code' => 'PH' + } + ] +) \ No newline at end of file diff --git a/spec/features/places/searching_a_place_spec.rb b/spec/features/places/searching_a_place_spec.rb index 614fe9188..6812e6413 100644 --- a/spec/features/places/searching_a_place_spec.rb +++ b/spec/features/places/searching_a_place_spec.rb @@ -3,15 +3,20 @@ require "rails_helper" RSpec.feature "User searches", :type => :feature do scenario "with a valid place" do - visit "/places" + visit places_path search_with("Philippines") - assert true + expect(page).to have_content "members near Philippines" + expect(page).to have_button "search_button" + page.has_content?('placesmap') + expect(page).to have_content "Nearby members" end scenario "with a blank search string" do - visit "/places" + visit places_path search_with("") - assert true + expect(page).to have_content "Please enter a valid location" + expect(page).to have_button "search_button" + page.has_content?('placesmap') end def search_with(search_string) From 44b260b1e8c9c1766223bc3fcf1d19a4312bc9f8 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 25 May 2015 12:56:40 +1000 Subject: [PATCH 081/392] Currency refactoring in specs. --- .../{application_helper.rb => application_helper_spec.rb} | 2 +- spec/views/shop/index_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename spec/helpers/{application_helper.rb => application_helper_spec.rb} (79%) diff --git a/spec/helpers/application_helper.rb b/spec/helpers/application_helper_spec.rb similarity index 79% rename from spec/helpers/application_helper.rb rename to spec/helpers/application_helper_spec.rb index 9a39e59a7..67d05fc3e 100644 --- a/spec/helpers/application_helper.rb +++ b/spec/helpers/application_helper_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe ApplicationHelper do it "formats prices" do price_in_dollars(999).should eq '9.99' - price_with_currency(999).should eq '9.99 AUD' + price_with_currency(999).should eq '9.99 %s' % Growstuff::Application.config.currency end it "parses dates" do diff --git a/spec/views/shop/index_spec.rb b/spec/views/shop/index_spec.rb index cf4baae91..f6a4131ce 100644 --- a/spec/views/shop/index_spec.rb +++ b/spec/views/shop/index_spec.rb @@ -35,8 +35,8 @@ describe 'shop/index.html.haml', :type => "view" do assert_select("h2", :text => @product1.name) end - it 'shows prices in AUD' do - rendered.should have_content '9.99 AUD' + it 'shows prices in configured currency' do + rendered.should have_content '9.99 %s' % Growstuff::Application.config.currency end it 'should contain an exchange rate link' do @@ -45,7 +45,7 @@ describe 'shop/index.html.haml', :type => "view" do end it 'shows recommended price for products that have it' do - rendered.should have_content '12.00 AUD' + rendered.should have_content '12.00 %s' % Growstuff::Application.config.currency end it 'should contain an exchange rate link for recommended price' do From 429e54733d4ac2277124328d85e049ac66f58b31 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 1 Jul 2015 10:57:28 +0800 Subject: [PATCH 082/392] Moved the geocoder stub to ./cofig/environments/test.rb --- config/environments/test.rb | 14 ++++++++++++++ config/initializers/geocoder.rb | 16 +--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/config/environments/test.rb b/config/environments/test.rb index 8d99b4e84..c5c05f8d5 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -67,6 +67,20 @@ Geocoder::Lookup::Test.add_stub( ] ) +Geocoder::Lookup::Test.add_stub( + "Philippines", [ + { + 'latitude' => 12.7503486, + 'longitude' => 122.7312101, + 'address' => 'Manila, Mnl, Philippines', + 'state' => 'Manila', + 'state_code' => 'Mnl', + 'country' => 'Philippines', + 'country_code' => 'PH' + } + ] +) + Geocoder::Lookup::Test.add_stub( "Greenwich, UK", [ { diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index d2758b957..0d221664e 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -13,18 +13,4 @@ Geocoder.configure( # Reported as https://github.com/alexreisner/geocoder/issues/509 if Geocoder.config.lookup != :test Geocoder.configure(:lookup => :nominatim) -end - -Geocoder::Lookup::Test.add_stub( - "Philippines", [ - { - 'latitude' => 12.7503486, - 'longitude' => 122.7312101, - 'address' => 'Manila, Mnl, Philippines', - 'state' => 'Manila', - 'state_code' => 'Mnl', - 'country' => 'Philippines', - 'country_code' => 'PH' - } - ] -) \ No newline at end of file +end \ No newline at end of file From 6c72345d266a15ab7a6e73fa27c989448f3d4356 Mon Sep 17 00:00:00 2001 From: Cjay Billones Date: Thu, 2 Jul 2015 11:57:45 +0800 Subject: [PATCH 083/392] Fix test --- spec/models/crop_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index bf894b921..7423a4fd2 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -73,6 +73,7 @@ describe Crop do @crop = FactoryGirl.create(:tomato) @crop.default_scientific_name.should eq nil @sn = FactoryGirl.create(:solanum_lycopersicum, :crop => @crop) + @crop.reload @crop.default_scientific_name.should eq @sn.scientific_name end From b868364e9614fc6f4a30a7d2764104c59bdab506 Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:50:30 +0800 Subject: [PATCH 084/392] Fix merge conflict in contributors --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9e5d488e4..35050b88e 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -58,3 +58,4 @@ submit the change with your pull request. - Mauricio Gonzalez / [mauricio-gonzalez](https://github.com/mauricio-gonzalez) - Andrey Bazhutkin / [andrba](https://github.com/andrba) - Gabriel Sandoval / [gabrielsandoval](https://github.com/gabrielsandoval) +- Cjay Billones / [CjayBillones](https://github.com/CjayBillones) From 34e61082b933694bd283e893af2ce8ff0798ae08 Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:51:05 +0800 Subject: [PATCH 085/392] Add config/application.yml in gitignore Included config/application.yml in gitignore since it contains personal configuration of developer. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c9e7b8acd..6370fea4b 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ Pathogen: custom_plan.rb zeus.json .bundle +config/application.yml From 10cb6c18aad94520685637af2acb601c7c8f418a Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:52:11 +0800 Subject: [PATCH 086/392] Show last login date on member profile --- app/views/members/_account.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index 68dfbd591..2e56e4342 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -9,3 +9,7 @@ = member.account_type account +%p + %strong Last Login: + = member.last_sign_in_at + From 2528d8af8a65d687925ea575dc20fb9bb342ec31 Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:53:18 +0800 Subject: [PATCH 087/392] Show edited date/time on posts/comments --- app/views/comments/_single.html.haml | 6 +++--- app/views/posts/_single.html.haml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/comments/_single.html.haml b/app/views/comments/_single.html.haml index ae9c503af..af6c328e5 100644 --- a/app/views/comments/_single.html.haml +++ b/app/views/comments/_single.html.haml @@ -5,10 +5,10 @@ = render :partial => "members/avatar", :locals => { :member => comment.author } .col-md-11 .comment-meta - Posted by + = (comment.created_at == comment.updated_at) ? 'Posted by' : 'Edited by' = link_to comment.author.login_name, member_path(comment.author) - at - = comment.created_at + on + = (comment.created_at == comment.updated_at) ? comment.created_at : comment.updated_at .comment-body :growstuff_markdown diff --git a/app/views/posts/_single.html.haml b/app/views/posts/_single.html.haml index e6f7ae0f3..44750ceac 100644 --- a/app/views/posts/_single.html.haml +++ b/app/views/posts/_single.html.haml @@ -9,13 +9,13 @@ .post-meta %p - Posted by + = (post.created_at == post.updated_at) ? 'Posted by' : 'Edited by' = link_to post.author.login_name, member_path(post.author) - if post.forum in = link_to post.forum, post.forum - at - = post.created_at + on + = (post.created_at == post.updated_at) ? post.created_at : post.updated_at .post-body :growstuff_markdown From a73d4920629167faf360ad6eaa70dfde9185683c Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:53:54 +0800 Subject: [PATCH 088/392] Add tests for comment --- .../comments/commenting_a_comment_spec.rb | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 spec/features/comments/commenting_a_comment_spec.rb diff --git a/spec/features/comments/commenting_a_comment_spec.rb b/spec/features/comments/commenting_a_comment_spec.rb new file mode 100644 index 000000000..e5c83475d --- /dev/null +++ b/spec/features/comments/commenting_a_comment_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +feature 'Commenting on a post' do + let(:member) { FactoryGirl.create(:member) } + let(:post) { FactoryGirl.create(:post, :author => member) } + + background do + login_as(member) + visit new_comment_path(:post_id => post.id) + end + + scenario "creating a comment" do + fill_in "comment_body", :with => "This is a sample test for comment" + click_button "Post comment" + expect(page).to have_content "Comment was successfully created" + expect(page).to have_content "Commented by" + end + + context "editing a comment" do + let(:existing_comment) { FactoryGirl.create(:comment, :post => post, :author => member) } + + background do + visit edit_comment_path(existing_comment) + end + + scenario "saving edit" do + fill_in "comment_body", :with => "Testing edit for comment" + click_button "Post comment" + expect(page).to have_content "Comment was successfully updated" + expect(page).to have_content "Edited by" + end + end + +end From 3fb9283ca755bba8c87a80da63d540ee8d0d62ce Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 18:54:17 +0800 Subject: [PATCH 089/392] Add tests for posts --- spec/features/posts/posting_a_post_spec.rb | 34 ++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 spec/features/posts/posting_a_post_spec.rb diff --git a/spec/features/posts/posting_a_post_spec.rb b/spec/features/posts/posting_a_post_spec.rb new file mode 100644 index 000000000..dabda1586 --- /dev/null +++ b/spec/features/posts/posting_a_post_spec.rb @@ -0,0 +1,34 @@ +require 'rails_helper' + +feature 'Post a post' do + let(:member) { FactoryGirl.create(:member) } + + background do + login_as(member) + visit new_post_path + end + + scenario "creating a post" do + fill_in "post_subject", :with => "Testing" + fill_in "post_body", :with => "This is a sample test" + click_button "Post" + expect(page).to have_content "Post was successfully created" + expect(page).to have_content "Posted by" + end + + context "editing a post" do + let(:existing_post) { FactoryGirl.create(:post, :author => member)} + + background do + visit edit_post_path(existing_post) + end + + scenario "saving edit" do + fill_in "post_subject", :with => "Testing Edit" + click_button "Post" + expect(page).to have_content "Post was successfully updated" + expect(page).to have_content "Edited by" + end + end + +end \ No newline at end of file From 64cf71ab4ff67af3c2500f629b40e7a9f3f55dbe Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 2 Jul 2015 19:01:32 +0800 Subject: [PATCH 090/392] Fix test for comments --- spec/features/comments/commenting_a_comment_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/comments/commenting_a_comment_spec.rb b/spec/features/comments/commenting_a_comment_spec.rb index e5c83475d..e4f2fed21 100644 --- a/spec/features/comments/commenting_a_comment_spec.rb +++ b/spec/features/comments/commenting_a_comment_spec.rb @@ -13,7 +13,7 @@ feature 'Commenting on a post' do fill_in "comment_body", :with => "This is a sample test for comment" click_button "Post comment" expect(page).to have_content "Comment was successfully created" - expect(page).to have_content "Commented by" + expect(page).to have_content "Posted by" end context "editing a comment" do From 3a9077050e91f633f87d9a9a8c45b82569e7d627 Mon Sep 17 00:00:00 2001 From: Maccath Date: Sun, 5 Apr 2015 07:36:38 +0000 Subject: [PATCH 091/392] Add placeholder to harvest screen's plant part select box. --- app/views/harvests/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 4aae2540e..21de8e5b6 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -11,7 +11,7 @@ .col-md-4 = auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop .col-md-4 - = collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id }, { :class => 'form-control' }) + = collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id, :include_blank => 'e.g. fruit' }, { :class => 'form-control' }) %span.help-block.col-md-8 Can't find what you're looking for? = link_to "Request new crops.", new_crop_path From 9304e44c08743a357d7fdf36cc61ffa5034d04e4 Mon Sep 17 00:00:00 2001 From: Katy Ereira Date: Sun, 5 Apr 2015 08:47:00 +0100 Subject: [PATCH 092/392] Add Maccath tnd CjayBillones to contributors list --- CONTRIBUTORS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 9e5d488e4..de96fc4f8 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -58,3 +58,5 @@ submit the change with your pull request. - Mauricio Gonzalez / [mauricio-gonzalez](https://github.com/mauricio-gonzalez) - Andrey Bazhutkin / [andrba](https://github.com/andrba) - Gabriel Sandoval / [gabrielsandoval](https://github.com/gabrielsandoval) +- Cjay Billones / [CjayBillones](https://github.com/CjayBillones) +- Katy Ereira / [maccath](https://github.com/maccath) From e94cbcef02073401443c5168aac4c0075350a626 Mon Sep 17 00:00:00 2001 From: Cjay Billones Date: Mon, 6 Jul 2015 10:56:31 +0800 Subject: [PATCH 093/392] Refactor spec Refactor spec by changing before(:each) into let --- spec/features/admin/account_types_spec.rb | 11 ++++------ spec/features/admin/forums_spec.rb | 11 ++++------ spec/features/admin/products.rb | 3 ++- spec/features/cms_spec.rb | 22 +++++-------------- spec/features/crops/alternate_name_spec.rb | 4 ++-- spec/features/crops/request_new_crop_spec.rb | 8 +++++-- .../harvests/harvesting_a_crop_spec.rb | 2 +- spec/features/photos/show_photo_spec.rb | 2 +- .../plantings/planting_a_crop_spec.rb | 2 +- spec/features/scientific_name_spec.rb | 2 +- spec/features/seeds/adding_seeds_spec.rb | 2 +- spec/features/seeds/misc_seeds_spec.rb | 14 +++++------- 12 files changed, 35 insertions(+), 48 deletions(-) diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index b56144344..01c0040d5 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -2,13 +2,10 @@ require 'rails_helper' feature "account types" do context "admin user" do - before(:each) do - @member = FactoryGirl.create(:admin_member) - visit root_path - click_link 'Sign in' - fill_in 'Login', :with => @member.login_name - fill_in 'Password', :with => @member.password - click_button 'Sign in' + let(:member) { FactoryGirl.create(:admin_member) } + + background do + login_as member end scenario "navigating to account type admin" do diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index e9f8a43f9..98c30d6c7 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -2,13 +2,10 @@ require 'rails_helper' feature "forums" do context "admin user" do - before(:each) do - @member = FactoryGirl.create(:admin_member) - visit root_path - click_link 'Sign in' - fill_in 'Login', :with => @member.login_name - fill_in 'Password', :with => @member.password - click_button 'Sign in' + let(:member) { FactoryGirl.create(:admin_member) } + + background do + login_as member end scenario "navigating to forum admin" do diff --git a/spec/features/admin/products.rb b/spec/features/admin/products.rb index 2e85ead60..e24632cd0 100644 --- a/spec/features/admin/products.rb +++ b/spec/features/admin/products.rb @@ -3,8 +3,9 @@ require 'rails_helper' feature "products" do context "admin user" do let(:member) { FactoryGirl.create(:admin_member) } + background do - login_as(member) + login_as member end scenario "navigating to product admin" do diff --git a/spec/features/cms_spec.rb b/spec/features/cms_spec.rb index fb3f2ca93..3e10faa6b 100644 --- a/spec/features/cms_spec.rb +++ b/spec/features/cms_spec.rb @@ -1,10 +1,9 @@ -require 'spec_helper' +require 'rails_helper' feature "cms admin" do - before(:each) do - @member = FactoryGirl.create(:member) - @admin_member = FactoryGirl.create(:admin_member) - end + + let(:member) { FactoryGirl.create(:member) } + let(:admin_member) { FactoryGirl.create(:admin_member) } scenario "can't view CMS admin if not signed in" do visit comfy_admin_cms_path @@ -14,23 +13,14 @@ feature "cms admin" do scenario "can't view CMS admin if not an admin member" do # sign in as an ordinary member - visit root_path - click_link 'navbar-signin' - fill_in 'Login', :with => @member.email - fill_in 'Password', :with => @member.password - click_button 'Sign in' + login_as member visit comfy_admin_cms_path current_path.should == root_path page.should have_content("Please sign in as an admin user") end scenario "admin members can view CMS admin area" do - visit root_path - # now we sign in as an admin member - click_link 'navbar-signin' - fill_in 'Login', :with => @admin_member.email - fill_in 'Password', :with => @admin_member.password - click_button 'Sign in' + login_as admin_member visit comfy_admin_cms_path current_path.should match /#{comfy_admin_cms_path}/ # match any CMS admin page end diff --git a/spec/features/crops/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb index 348cc3279..44bd40c38 100644 --- a/spec/features/crops/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -19,8 +19,8 @@ feature "Alternate names" do let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } let(:member){crop_wranglers.first} - before :each do - login_as(member) + background do + login_as member end scenario "Crop wranglers can edit alternate names" do diff --git a/spec/features/crops/request_new_crop_spec.rb b/spec/features/crops/request_new_crop_spec.rb index afe03a0a1..de91cca7e 100644 --- a/spec/features/crops/request_new_crop_spec.rb +++ b/spec/features/crops/request_new_crop_spec.rb @@ -7,7 +7,9 @@ feature "Requesting a new crop" do let(:member) { FactoryGirl.create(:member) } let!(:wrangler) { FactoryGirl.create(:crop_wrangling_member) } - before { login_as member } + background do + login_as member + end scenario "Submit request" do visit new_crop_path @@ -25,7 +27,9 @@ feature "Requesting a new crop" do let!(:crop) { FactoryGirl.create(:crop_request) } let!(:already_approved) { FactoryGirl.create(:crop) } - before { login_as wrangler } + background do + login_as wrangler + end scenario "Approve a request" do visit edit_crop_path(crop) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index c1148cf4b..8f4cc6e1b 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -5,7 +5,7 @@ feature "Harvesting a crop", :js => true do let!(:maize) { FactoryGirl.create(:maize) } background do - login_as(member) + login_as member visit new_harvest_path sync_elasticsearch([maize]) end diff --git a/spec/features/photos/show_photo_spec.rb b/spec/features/photos/show_photo_spec.rb index aa02af988..0bef51587 100644 --- a/spec/features/photos/show_photo_spec.rb +++ b/spec/features/photos/show_photo_spec.rb @@ -8,7 +8,7 @@ feature "show photo page" do let (:member) { FactoryGirl.create(:member) } background do - login_as(member) + login_as member end context "linked to planting" do diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 7001ad400..1becf895d 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -7,7 +7,7 @@ feature "Planting a crop", :js => true do let!(:planting) { FactoryGirl.create(:planting, garden: garden, planted_at: Date.parse("2013-3-10")) } background do - login_as(member) + login_as member visit new_planting_path sync_elasticsearch([maize]) end diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index f8b93ce29..af5cc7f2f 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -20,7 +20,7 @@ feature "Scientific names" do let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } let(:member){crop_wranglers.first} - before :each do + background do login_as(member) end diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index b14622d47..8fa146724 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -5,7 +5,7 @@ feature "Seeds", :js => true do let!(:maize) { FactoryGirl.create(:maize) } background do - login_as(member) + login_as member visit new_seed_path sync_elasticsearch([maize]) end diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 1e434a754..7fc4e32d6 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -2,14 +2,12 @@ require 'rails_helper' feature "seeds" do context "signed in user" do - before(:each) do - @crop = FactoryGirl.create(:crop) - @member = FactoryGirl.create(:member) - visit root_path - click_link 'Sign in' - fill_in 'Login', :with => @member.login_name - fill_in 'Password', :with => @member.password - click_button 'Sign in' + + let(:member) { @member = FactoryGirl.create(:member) } + let(:crop) { FactoryGirl.create(:crop) } + + background do + login_as member end scenario "button on index to edit seed" do From 29a8628c42369d3af3f94761b5264f4e9a9e1177 Mon Sep 17 00:00:00 2001 From: Cjay Billones Date: Tue, 7 Jul 2015 07:38:06 +0800 Subject: [PATCH 094/392] Refactor spec/helpers Change before(:each) into let in spec/helpers --- spec/helpers/notifications_helper_spec.rb | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index b233246ab..5c3c7e1a2 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -3,12 +3,10 @@ require 'rails_helper' describe NotificationsHelper do describe "reply_link" do - before(:each) do - @member = FactoryGirl.create(:member) - end + let(:member) { FactoryGirl.create(:member) } it "replies to PMs with PMs" do - notification = FactoryGirl.create(:notification, :recipient_id => @member.id, :post_id => nil) + notification = FactoryGirl.create(:notification, :recipient_id => member.id, :post_id => nil) subject = "Re: " + notification.subject link = helper.reply_link(notification) @@ -17,7 +15,7 @@ describe NotificationsHelper do end it "replies to post comments with post comments" do - notification = FactoryGirl.create(:notification, :recipient_id => @member.id) + notification = FactoryGirl.create(:notification, :recipient_id => member.id) link = helper.reply_link(notification) link.should_not be_nil From 372a7f080d8d2ba0dad25a08b145406f7f0d67d7 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 26 Jun 2015 06:54:49 +0800 Subject: [PATCH 095/392] Added the days before maturity feature #678 --- app/controllers/plantings_controller.rb | 11 +++ app/models/planting.rb | 15 +++ .../plantings/_planting_progress.html.haml | 17 ++++ app/views/plantings/index.html.haml | 91 ++++++++++++------- app/views/plantings/show.html.haml | 10 ++ ...5_add_days_before_maturity_to_plantings.rb | 5 + 6 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 app/views/plantings/_planting_progress.html.haml create mode 100644 db/migrate/20150625224805_add_days_before_maturity_to_plantings.rb diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index 9fdefc388..0baf1de36 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -67,6 +67,7 @@ class PlantingsController < ApplicationController def create params[:planted_at] = parse_date(params[:planted_at]) @planting = Planting.new(planting_params) + @planting.days_before_maturity = update_days_before_maturity(@planting, planting_params[:crop_id]) @planting.owner = current_member respond_to do |format| @@ -87,6 +88,8 @@ class PlantingsController < ApplicationController @planting = Planting.find(params[:id]) params[:planted_at] = parse_date(params[:planted_at]) + @planting.days_before_maturity = update_days_before_maturity(@planting, planting_params[:crop_id]) + respond_to do |format| if @planting.update(planting_params) format.html { redirect_to @planting, notice: 'Planting was successfully updated.' } @@ -119,4 +122,12 @@ class PlantingsController < ApplicationController :quantity, :sunniness, :planted_from, :owner_id, :finished, :finished_at) end + + def update_days_before_maturity(planting, crop_id) + if planting.finished_at.nil? + planting.calculate_days_before_maturity(crop_id) + else + (planting.finished_at - planting.planted_at).to_i + end + end end diff --git a/app/models/planting.rb b/app/models/planting.rb index ea9faf0d0..abf2ec1e2 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -94,6 +94,21 @@ class Planting < ActiveRecord::Base return photos.present? end + def calculate_days_before_maturity(crop) + p_crop = Planting.where(:crop_id => crop) + differences = p_crop.collect do |p| + if p.finished and !p.finished_at.nil? + (p.finished_at - p.planted_at).to_i + end + end + + if differences.compact.empty? + average = nil + else + average = differences.compact.sum/differences.compact.length + end + end + # return a list of interesting plantings, for the homepage etc. # we can't do this via a scope (as far as we know) so sadly we have to # do it this way. diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml new file mode 100644 index 000000000..0b23c0066 --- /dev/null +++ b/app/views/plantings/_planting_progress.html.haml @@ -0,0 +1,17 @@ +- if DateTime.now.to_date < planting.planted_at + = "Progress: #{percent=0}% - " + = "not planted yet" + .progress + .progress-bar.progress-bar-warning{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} +- elsif planting.days_before_maturity.nil? + = "Progress: #{percent=0}% - " + = "Days before maturity unknown" + .progress + .progress-bar.progress-bar-danger{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} +- else + - if (percent = (((DateTime.now - planting.planted_at)/planting.days_before_maturity*100).to_i)) >= 100 + - percent = 100 + + = "Progress: #{percent}" + "%" + .progress + .progress-bar.progress-bar-success{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "#{percent}", :role => "progressbar", :style => "width: #{percent}%"} \ No newline at end of file diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 25b52ee2d..f4b2556a4 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -22,40 +22,69 @@ %table.table.table-striped %tr - - unless @owner - %th Owner - %th Crop - %th Garden - %th Quantity - %th Planted on - %th Finished - %th Sun/shade? - %th Planted from - %th - - - @plantings.each do |planting| + %th # + %th Photo + %th{:colspan => "3"} Planting details + + - @plantings.each.with_index do |planting, index| %tr - - unless @owner - %td= link_to planting.owner.login_name, planting.owner - %td= link_to planting.crop.name, planting.crop - %td= link_to planting.garden.name, planting.garden - %td= planting.quantity - %td= planting.planted_at + %td= "##{index+1}" + %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting %td - - if planting.finished and planting.finished_at - = planting.finished_at - - elsif planting.finished - Yes (no date specified) - %td= planting.sunniness - %td= planting.planted_from + %ul{:style => "list-style-type:none"} + %li Owner : + %li Garden : + %li Planted on : + %li Finished on : + %li Sun/shade? : + %li Planted from : %td - = link_to 'Details', planting, :class => 'btn btn-default btn-xs' - - if can? :edit, planting - =link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - = link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - - if can? :destroy, planting - =link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %ul{:style => "list-style-type:none"} + %li= link_to planting.owner.login_name, planting.owner + %li= link_to planting.garden.name, planting.garden + %li= planting.planted_at + - if planting.finished and planting.finished_at? + %li= planting.finished_at + - elsif planting.finished + %li= "Yes (no date specified)" + - else + %li= "(no date specified)" + - if planting.sunniness? + %li= planting.sunniness + - else + %li= "n/a" + %li= planting.planted_from + %td + %ul{:style => "list-style-type:none"} + %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' + - if can? :edit, planting + %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + - if can? :destroy, planting + %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %tr + %td + %td + %ul{:style => "list-style-type:none"} + %li + Crop name: + =link_to planting.crop.name, planting.crop + - if planting.finished and !planting.finished_at.nil? + - if ((p = planting.finished_at - DateTime.now).to_i) <= 0 + %li= "Days until maturity: 0" + - else + %li= "Days until maturity: #{p.to_i}" + + - elsif planting.days_before_maturity.nil? + %li= "Days until maturity: unknown" + - else + - if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 + %li= "Days until maturity: 0" + - else + %li= "Days until maturity: #{p.to_i}" + + %td{:colspan => "3"} + %ul{:style => "list-style-type:none"} + %li= render 'planting_progress', planting: planting %div.pagination = page_entries_info @plantings, :model => "plantings" diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 93cc2a910..73a1cbd72 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -38,6 +38,16 @@ = @planting.finished_at - else Yes (no date specified) + %p + %b Days until maturity: + - if @planting.finished and @planting.finished_at? + = "#{(@planting.finished_at - DateTime.now).to_i}" + - elsif @planting.days_before_maturity.nil? + = "unknown" + - else + = "#{((@planting.planted_at + @planting.days_before_maturity) - DateTime.now).to_i}" + %p + %b= render 'planting_progress', planting: @planting diff --git a/db/migrate/20150625224805_add_days_before_maturity_to_plantings.rb b/db/migrate/20150625224805_add_days_before_maturity_to_plantings.rb new file mode 100644 index 000000000..0ddf5acb5 --- /dev/null +++ b/db/migrate/20150625224805_add_days_before_maturity_to_plantings.rb @@ -0,0 +1,5 @@ +class AddDaysBeforeMaturityToPlantings < ActiveRecord::Migration + def change + add_column :plantings, :days_before_maturity, :integer + end +end From 3181c97a2a8e04ddc1319c07942f5eee0ac6d4cc Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 26 Jun 2015 11:22:57 +0800 Subject: [PATCH 096/392] Added the mark as finished button on the index page. --- app/views/plantings/index.html.haml | 2 ++ db/schema.rb | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index f4b2556a4..e6f386a15 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -59,6 +59,8 @@ %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + - if ! planting.finished + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' %tr diff --git a/db/schema.rb b/db/schema.rb index 7f8c479ce..be45fa333 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150209105410) do +ActiveRecord::Schema.define(version: 20150625224805) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -380,8 +380,8 @@ ActiveRecord::Schema.define(version: 20150209105410) do end create_table "plantings", force: true do |t| - t.integer "garden_id", null: false - t.integer "crop_id", null: false + t.integer "garden_id", null: false + t.integer "crop_id", null: false t.date "planted_at" t.integer "quantity" t.text "description" @@ -391,8 +391,9 @@ ActiveRecord::Schema.define(version: 20150209105410) do t.string "sunniness" t.string "planted_from" t.integer "owner_id" - t.boolean "finished", default: false + t.boolean "finished", default: false t.date "finished_at" + t.integer "days_before_maturity" end add_index "plantings", ["slug"], name: "index_plantings_on_slug", unique: true, using: :btree From 4ca4d6b030ed110f030b556c1d08d5c52f41e4f8 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 1 Jul 2015 09:35:13 +0800 Subject: [PATCH 097/392] Fixed error where progress bars do not change upon update --- app/controllers/plantings_controller.rb | 7 +++---- app/models/planting.rb | 8 ++++---- app/views/plantings/index.html.haml | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index 0baf1de36..bba983b6c 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -67,11 +67,11 @@ class PlantingsController < ApplicationController def create params[:planted_at] = parse_date(params[:planted_at]) @planting = Planting.new(planting_params) - @planting.days_before_maturity = update_days_before_maturity(@planting, planting_params[:crop_id]) @planting.owner = current_member respond_to do |format| if @planting.save + @planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id])) format.html { redirect_to @planting, notice: 'Planting was successfully created.' } format.json { render json: @planting, status: :created, location: @planting } expire_fragment("homepage_stats") @@ -88,10 +88,9 @@ class PlantingsController < ApplicationController @planting = Planting.find(params[:id]) params[:planted_at] = parse_date(params[:planted_at]) - @planting.days_before_maturity = update_days_before_maturity(@planting, planting_params[:crop_id]) - respond_to do |format| if @planting.update(planting_params) + @planting.update_attribute(:days_before_maturity, update_days_before_maturity(@planting, planting_params[:crop_id])) format.html { redirect_to @planting, notice: 'Planting was successfully updated.' } format.json { head :no_content } else @@ -125,7 +124,7 @@ class PlantingsController < ApplicationController def update_days_before_maturity(planting, crop_id) if planting.finished_at.nil? - planting.calculate_days_before_maturity(crop_id) + planting.calculate_days_before_maturity(planting, crop_id) else (planting.finished_at - planting.planted_at).to_i end diff --git a/app/models/planting.rb b/app/models/planting.rb index abf2ec1e2..f06ccf9ac 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -94,8 +94,8 @@ class Planting < ActiveRecord::Base return photos.present? end - def calculate_days_before_maturity(crop) - p_crop = Planting.where(:crop_id => crop) + def calculate_days_before_maturity(planting, crop) + p_crop = Planting.where(:crop_id => crop).where.not(:id => planting) differences = p_crop.collect do |p| if p.finished and !p.finished_at.nil? (p.finished_at - p.planted_at).to_i @@ -103,9 +103,9 @@ class Planting < ActiveRecord::Base end if differences.compact.empty? - average = nil + nil else - average = differences.compact.sum/differences.compact.length + differences.compact.sum/differences.compact.length end end diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index e6f386a15..0b6c3d7f0 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -59,8 +59,8 @@ %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' + - if ! planting.finished + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' %tr From b01385a1e48ca6cc374c4b21ee8c92a308382a02 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 1 Jul 2015 12:00:31 +0800 Subject: [PATCH 098/392] Added some tests on the days before maturity feature --- .../plantings/planting_a_crop_spec.rb | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 1becf895d..7be31f033 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -27,6 +27,25 @@ feature "Planting a crop", :js => true do end expect(page).to have_content "Planting was successfully created" + expect(page).to have_content "Progress: 0% - Days before maturity unknown" + end + + scenario "Creating a new planting with known days before maturity" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-06-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + check "finished" + fill_in "Finished date", :with => "2015-06-25" + fill_in "Tell us more about it", :with => "It's rad." + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" end scenario "Planting from crop page" do @@ -49,6 +68,17 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Planting was successfully updated" end + scenario "Editing a planting to fill in the finished date" do + visit planting_path(planting) + expect(page).to have_content "Progress: 0% - Days before maturity unknown" + click_link "Edit" + check "finished" + fill_in "Finished date", :with => "2015-06-25" + click_button "Save" + expect(page).to have_content "Planting was successfully updated" + expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" + end + scenario "Marking a planting as finished" do fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" @@ -94,6 +124,7 @@ feature "Planting a crop", :js => true do end expect(page).to have_content "Planting was successfully created" expect(page).to have_content "Finished: Yes (no date specified)" + expect(page).to have_content "Progress: 0% - Days before maturity unknown" end describe "Marking a planting as finished from the show page" do From f13a66391cf1d32e242ee19685f324066c5c0782 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 1 Jul 2015 13:13:30 +0800 Subject: [PATCH 099/392] Fixed errors where progress bars does not show 100% when a planting is marked as finished. --- app/views/plantings/_planting_progress.html.haml | 13 +++++++------ app/views/plantings/index.html.haml | 14 +++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index 0b23c0066..4c40724a1 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -1,17 +1,18 @@ - if DateTime.now.to_date < planting.planted_at - = "Progress: #{percent=0}% - " - = "not planted yet" + = "Progress: 0% - not planted yet" .progress .progress-bar.progress-bar-warning{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} +- elsif planting.finished? + = "Progress: 100%" + .progress + .progress-bar.progress-bar-success{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100", :role => "progressbar", :style => "width: 100%"} - elsif planting.days_before_maturity.nil? - = "Progress: #{percent=0}% - " - = "Days before maturity unknown" + = "Progress: 0% - Days before maturity unknown" .progress .progress-bar.progress-bar-danger{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} - else - if (percent = (((DateTime.now - planting.planted_at)/planting.days_before_maturity*100).to_i)) >= 100 - percent = 100 - - = "Progress: #{percent}" + "%" + = "Progress: #{percent}%" .progress .progress-bar.progress-bar-success{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "#{percent}", :role => "progressbar", :style => "width: #{percent}%"} \ No newline at end of file diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 0b6c3d7f0..3e86f5395 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -70,19 +70,19 @@ %li Crop name: =link_to planting.crop.name, planting.crop - - if planting.finished and !planting.finished_at.nil? + - if planting.finished? + %li= "Days until maturity: 0" + - elsif !planting.finished_at.nil? - if ((p = planting.finished_at - DateTime.now).to_i) <= 0 - %li= "Days until maturity: 0" - - else - %li= "Days until maturity: #{p.to_i}" + p = 0 + %li= "Days until maturity: #{p.to_i}" - elsif planting.days_before_maturity.nil? %li= "Days until maturity: unknown" - else - if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 - %li= "Days until maturity: 0" - - else - %li= "Days until maturity: #{p.to_i}" + p = 0 + %li= "Days until maturity: #{p.to_i}" %td{:colspan => "3"} %ul{:style => "list-style-type:none"} From 516274b2b7e685895adeae9fdace091e58ca7bf7 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 2 Jul 2015 09:43:37 +0800 Subject: [PATCH 100/392] Added feature more feature tests on plantings creation for progress bars' status --- app/views/plantings/index.html.haml | 4 +- app/views/plantings/show.html.haml | 20 +++- .../plantings/planting_a_crop_spec.rb | 109 +++++++++++++++--- 3 files changed, 110 insertions(+), 23 deletions(-) diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 3e86f5395..2ea21ca45 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -74,14 +74,14 @@ %li= "Days until maturity: 0" - elsif !planting.finished_at.nil? - if ((p = planting.finished_at - DateTime.now).to_i) <= 0 - p = 0 + - p = 0 %li= "Days until maturity: #{p.to_i}" - elsif planting.days_before_maturity.nil? %li= "Days until maturity: unknown" - else - if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 - p = 0 + - p = 0 %li= "Days until maturity: #{p.to_i}" %td{:colspan => "3"} diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 73a1cbd72..ff7099b42 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -40,17 +40,25 @@ Yes (no date specified) %p %b Days until maturity: - - if @planting.finished and @planting.finished_at? - = "#{(@planting.finished_at - DateTime.now).to_i}" + - if @planting.finished? + %b + = " 0" + - elsif !@planting.finished_at.nil? + - if ((p = @planting.finished_at - DateTime.now).to_i) <= 0 + - p = 0 + %b + = " #{p.to_i}" - elsif @planting.days_before_maturity.nil? - = "unknown" + %b + = " unknown" - else - = "#{((@planting.planted_at + @planting.days_before_maturity) - DateTime.now).to_i}" + - if ((p = (@planting.planted_at + @planting.days_before_maturity) - DateTime.now).to_i) <= 0 + - p = 0 + %b + = " #{p.to_i}" %p %b= render 'planting_progress', planting: @planting - - - if can? :edit, @planting or can? :destroy, @planting %p - if can? :edit, @planting diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 7be31f033..0a6663b30 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -30,22 +30,101 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Progress: 0% - Days before maturity unknown" end - scenario "Creating a new planting with known days before maturity" do - fill_autocomplete "crop", :with => "mai" - select_from_autocomplete "maize" - within "form#new_planting" do - fill_in "When", :with => "2015-06-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - check "finished" - fill_in "Finished date", :with => "2015-06-25" - fill_in "Tell us more about it", :with => "It's rad." - click_button "Save" + describe "Progress bar status on planting creation" do + before(:each) do + DateTime.stub(:now){DateTime.new(2015, 10, 20, 10, 34)} + login_as(member) + visit new_planting_path + sync_elasticsearch([maize]) end - expect(page).to have_content "Planting was successfully created" - expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" + it "should show that it is not planted yet" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-12-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to have_content "Progress: 0% - not planted yet" + end + + it "should show that days before maturity is unknown" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-9-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to have_content "Progress: 0% - Days before maturity unknown" + expect(page).to have_content "Days until maturity: unknown" + end + + it "should show that planting is in progress" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-10-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + fill_in "Finished date", :with => "2015-10-30" + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to_not have_content "Progress: 0% - not planted yet" + expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" + end + + it "should show that planting is 100% complete (no date specified)" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-10-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + check "Mark as finished" + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to have_content "Progress: 100%" + expect(page).to have_content "Yes (no date specified)" + expect(page).to have_content "Days until maturity: 0" + end + + it "should show that planting is 100% complete (date specified)" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-10-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "semi-shade", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + fill_in "Finished date", :with => "2015-10-19" + click_button "Save" + end + + expect(page).to have_content "Planting was successfully created" + expect(page).to have_content "Progress: 100%" + expect(page).to have_content "Days until maturity: 0" + end end scenario "Planting from crop page" do @@ -124,7 +203,7 @@ feature "Planting a crop", :js => true do end expect(page).to have_content "Planting was successfully created" expect(page).to have_content "Finished: Yes (no date specified)" - expect(page).to have_content "Progress: 0% - Days before maturity unknown" + expect(page).to have_content "Progress: 100%" end describe "Marking a planting as finished from the show page" do From 8d5367be9ab69624e569272fd108e9db0c0b829d Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 3 Jul 2015 10:00:04 +0800 Subject: [PATCH 101/392] Refactored code and replaced the plantings/tumbnail view. --- app/helpers/plantings_helper.rb | 57 ++++++++++++ app/views/gardens/show.html.haml | 8 +- app/views/members/_gardens.html.haml | 3 +- .../plantings/_planting_progress.html.haml | 12 +-- app/views/plantings/_progress_bar.html.haml | 2 + app/views/plantings/_thumbnail.html.haml | 87 +++++++++---------- app/views/plantings/index.html.haml | 69 +-------------- spec/features/gardens_spec.rb | 1 - .../plantings/_thumbnail.html.haml_spec.rb | 86 +++++++++--------- 9 files changed, 154 insertions(+), 171 deletions(-) create mode 100644 app/helpers/plantings_helper.rb create mode 100644 app/views/plantings/_progress_bar.html.haml diff --git a/app/helpers/plantings_helper.rb b/app/helpers/plantings_helper.rb new file mode 100644 index 000000000..60cee45a1 --- /dev/null +++ b/app/helpers/plantings_helper.rb @@ -0,0 +1,57 @@ +module PlantingsHelper + def display (notification) + if notification.post + # comment on the post in question + new_comment_url(:post_id => notification.post.id) + else + # by default, reply link sends a PM in return + reply_notification_url(notification) + end + end + + def display_days_before_maturity(planting) + if planting.finished? + 0 + elsif !planting.finished_at.nil? + if ((p = planting.finished_at - DateTime.now).to_i) <= 0 + 0 + else + p.to_i + end + elsif planting.days_before_maturity.nil? + "unknown" + else + if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 + 0 + else + p.to_i + end + end + end + + def display_finished(planting) + if !planting.finished_at.nil? + planting.finished_at + elsif planting.finished + "Yes (no date specified)" + else + "(no date specified)" + end + end + + def display_sunniness(planting) + if !planting.sunniness.blank? + planting.sunniness + else + "n/a" + end + end + + def display_planted_from(planting) + if !planting.planted_from.blank? + planting.planted_from + else + "n/a" + end + end +end \ No newline at end of file diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 0ca1f3cfb..85a8baae9 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -48,17 +48,15 @@ What's planted here? - if @garden.plantings.current.size > 0 - - @garden.plantings.current.each do |p| - = render :partial => "plantings/thumbnail", :locals => { :planting => p } + = render :partial => "plantings/thumbnail", :locals => { :plantings => @garden.plantings.current} - else %p Nothing is currently planted here. - if @garden.plantings.finished.size > 0 %h3 Previously planted in this garden - - @garden.plantings.finished.each do |p| - = render :partial => "plantings/thumbnail", :locals => { :planting => p } - + = render :partial => "plantings/thumbnail", :locals => { :plantings => @garden.plantings.finished} + .col-md-3 %h4 About this garden %p diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index cca8ca5b1..4147fa74f 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -34,8 +34,7 @@ = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' %h3 What's planted here? - - g.featured_plantings.each do |p| - = render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true } + = render :partial => "plantings/thumbnail", :locals => { :plantings => g.featured_plantings} %p = link_to "More about this garden...", url_for(g) diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index 4c40724a1..86ba5d1a5 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -1,18 +1,14 @@ - if DateTime.now.to_date < planting.planted_at = "Progress: 0% - not planted yet" - .progress - .progress-bar.progress-bar-warning{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} + = render partial: "plantings/progress_bar", locals: {status: "warning", progress: "100%"} - elsif planting.finished? = "Progress: 100%" - .progress - .progress-bar.progress-bar-success{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100", :role => "progressbar", :style => "width: 100%"} + = render partial: "plantings/progress_bar", locals: {status: "success", progress: "100%"} - elsif planting.days_before_maturity.nil? = "Progress: 0% - Days before maturity unknown" - .progress - .progress-bar.progress-bar-danger{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "100%", :role => "progressbar", :style => "width: 100%"} + = render partial: "plantings/progress_bar", locals: {status: "danger", progress: "100%"} - else - if (percent = (((DateTime.now - planting.planted_at)/planting.days_before_maturity*100).to_i)) >= 100 - percent = 100 = "Progress: #{percent}%" - .progress - .progress-bar.progress-bar-success{"aria-valuemax" => "planting.days_before_maturity", "aria-valuemin" => "0", "aria-valuenow" => "#{percent}", :role => "progressbar", :style => "width: #{percent}%"} \ No newline at end of file + = render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{percent}%"} \ No newline at end of file diff --git a/app/views/plantings/_progress_bar.html.haml b/app/views/plantings/_progress_bar.html.haml new file mode 100644 index 000000000..4b13c3338 --- /dev/null +++ b/app/views/plantings/_progress_bar.html.haml @@ -0,0 +1,2 @@ +.progress + %div{:class => "progress-bar progress-bar-#{status}", :role => "progressbar", :style => "width: #{progress}"} diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index f1b67c2cb..156be0234 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,47 +1,46 @@ -.well - .row - .col-md-3 - = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img'), planting - - .col-md-9 - %h4 - - if defined?(title) && title == 'owner' - = link_to planting.owner, planting.owner - - else - = link_to planting.crop.name, planting - - %p - Planted - - if planting.planted_at - = planting.planted_at - in - = link_to planting.location, planting.garden - - %p - - if planting.quantity - Quantity: - = planting.quantity - - else -   - - - if planting.description && ! defined?(hide_description) - %div - :growstuff_markdown - #{ planting.description } - - - if planting.finished - %p - Finished: - - if planting.finished_at - = planting.finished_at - - else - Yes (no date specified) - - - if can? :edit, planting or can? :destroy, planting - %p +%table.table.table-striped + %tr + %th # + %th Photo + %th{:colspan => "3"} Planting details + - plantings.each.with_index do |planting, index| + %tr + %td= "##{index+1}" + %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting + %td + %ul{:style => "list-style-type:none"} + %li Owner : + %li Garden : + %li Planted on : + %li Finished on : + %li Sun/shade? : + %li Planted from : + %td + %ul{:style => "list-style-type:none"} + %li= link_to planting.owner.login_name, planting.owner + %li= link_to planting.garden.name, planting.garden + %li= planting.planted_at + %li= "#{display_finished(planting)}" + %li= "#{display_sunniness(planting)}" + %li= "#{display_planted_from(planting)}" + %td + %ul{:style => "list-style-type:none"} + %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting - =link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - if ! planting.finished - = link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - if can? :destroy, planting - =link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + %tr + %td + %td + %ul{:style => "list-style-type:none"} + %li + Crop name: + =link_to planting.crop.name, planting.crop + %li= "Days until maturity: #{display_days_before_maturity(planting)}" + + %td{:colspan => "3"} + %ul{:style => "list-style-type:none"} + %li= render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 2ea21ca45..ca0db97f5 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -19,74 +19,7 @@ = will_paginate @plantings - if @plantings.size > 0 - - %table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "3"} Planting details - - - @plantings.each.with_index do |planting, index| - %tr - %td= "##{index+1}" - %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - %td - %ul{:style => "list-style-type:none"} - %li Owner : - %li Garden : - %li Planted on : - %li Finished on : - %li Sun/shade? : - %li Planted from : - %td - %ul{:style => "list-style-type:none"} - %li= link_to planting.owner.login_name, planting.owner - %li= link_to planting.garden.name, planting.garden - %li= planting.planted_at - - if planting.finished and planting.finished_at? - %li= planting.finished_at - - elsif planting.finished - %li= "Yes (no date specified)" - - else - %li= "(no date specified)" - - if planting.sunniness? - %li= planting.sunniness - - else - %li= "n/a" - %li= planting.planted_from - %td - %ul{:style => "list-style-type:none"} - %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - - if can? :edit, planting - %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - - if can? :destroy, planting - %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - %tr - %td - %td - %ul{:style => "list-style-type:none"} - %li - Crop name: - =link_to planting.crop.name, planting.crop - - if planting.finished? - %li= "Days until maturity: 0" - - elsif !planting.finished_at.nil? - - if ((p = planting.finished_at - DateTime.now).to_i) <= 0 - - p = 0 - %li= "Days until maturity: #{p.to_i}" - - - elsif planting.days_before_maturity.nil? - %li= "Days until maturity: unknown" - - else - - if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 - - p = 0 - %li= "Days until maturity: #{p.to_i}" - - %td{:colspan => "3"} - %ul{:style => "list-style-type:none"} - %li= render 'planting_progress', planting: planting + = render partial: "plantings/thumbnail", locals: {:plantings => @plantings} %div.pagination = page_entries_info @plantings, :model => "plantings" diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 31626d06f..889fdd220 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -69,7 +69,6 @@ feature "Planting a crop", :js => true do describe "Making a planting inactive from garden show" do let(:path) { garden_path(garden) } let(:link_text) { "Mark as finished" } - it_behaves_like "append date" end diff --git a/spec/views/plantings/_thumbnail.html.haml_spec.rb b/spec/views/plantings/_thumbnail.html.haml_spec.rb index 279dfda56..09404b485 100644 --- a/spec/views/plantings/_thumbnail.html.haml_spec.rb +++ b/spec/views/plantings/_thumbnail.html.haml_spec.rb @@ -14,56 +14,56 @@ -require 'rails_helper' +# require 'rails_helper' -describe "plantings/_thumbnail" do - before(:each) do - controller.stub(:current_user) { nil } - @member = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @member) - @crop = FactoryGirl.create(:tomato) +# describe "plantings/_thumbnail" do +# before(:each) do +# controller.stub(:current_user) { nil } +# @member = FactoryGirl.create(:member) +# @garden = FactoryGirl.create(:garden, :owner => @member) +# @crop = FactoryGirl.create(:tomato) - @planting = FactoryGirl.create(:planting, - :garden => @garden, - :crop => @crop - ) - end +# @planting = FactoryGirl.create(:planting, +# :garden => @garden, +# :crop => @crop +# ) +# end - context "simple view" do - before(:each) do - render :partial => "thumbnail", :locals => { - :planting => @planting, - } - end +# context "simple view" do +# before(:each) do +# render :partial => "thumbnail", :locals => { +# :planting => @planting, +# } +# end - it "renders the quantity planted" do - rendered.should have_content "33" - end +# it "renders the quantity planted" do +# rendered.should have_content "33" +# end - it "renders the date planted" do - rendered.should have_content @planting.planted_at.to_s(:default) - end +# it "renders the date planted" do +# rendered.should have_content @planting.planted_at.to_s(:default) +# end - it "shows the name of the crop" do - rendered.should have_content @crop.name - end +# it "shows the name of the crop" do +# rendered.should have_content @crop.name +# end - it "shows the description by default" do - rendered.should have_content "This is a" - end - end +# it "shows the description by default" do +# rendered.should have_content "This is a" +# end +# end - context "with complicated args" do - before(:each) do - render :partial => "thumbnail", :locals => { - :planting => @planting, - :hide_description => true - } - end +# context "with complicated args" do +# before(:each) do +# render :partial => "thumbnail", :locals => { +# :planting => @planting, +# :hide_description => true +# } +# end - it "hides the description if asked" do - rendered.should_not have_content "This is a" - end - end +# it "hides the description if asked" do +# rendered.should_not have_content "This is a" +# end +# end -end +# end From e638acd2deadd59637cc837a4da315ce2621641d Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 3 Jul 2015 11:14:25 +0800 Subject: [PATCH 102/392] Refactored further on plantings/show page --- app/helpers/plantings_helper.rb | 28 ++++-------- app/views/plantings/_thumbnail.html.haml | 14 +++--- app/views/plantings/show.html.haml | 58 +++++++++--------------- 3 files changed, 38 insertions(+), 62 deletions(-) diff --git a/app/helpers/plantings_helper.rb b/app/helpers/plantings_helper.rb index 60cee45a1..179062318 100644 --- a/app/helpers/plantings_helper.rb +++ b/app/helpers/plantings_helper.rb @@ -13,19 +13,11 @@ module PlantingsHelper if planting.finished? 0 elsif !planting.finished_at.nil? - if ((p = planting.finished_at - DateTime.now).to_i) <= 0 - 0 - else - p.to_i - end + ((p = planting.finished_at - DateTime.now).to_i) <= 0 ? 0 : p.to_i elsif planting.days_before_maturity.nil? "unknown" else - if ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i) <= 0 - 0 - else - p.to_i - end + ((p = (planting.planted_at + planting.days_before_maturity) - DateTime.now).to_i <= 0) ? 0 : p.to_i end end @@ -40,18 +32,14 @@ module PlantingsHelper end def display_sunniness(planting) - if !planting.sunniness.blank? - planting.sunniness - else - "n/a" - end + !planting.sunniness.blank? ? planting.sunniness : "not specified" end def display_planted_from(planting) - if !planting.planted_from.blank? - planting.planted_from - else - "n/a" - end + !planting.planted_from.blank? ? planting.planted_from : "not specified" + end + + def display_planting_quantity(planting) + !planting.quantity.blank? ? planting.quantity : "not specified" end end \ No newline at end of file diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 156be0234..a7f53e4f7 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -9,17 +9,19 @@ %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting %td %ul{:style => "list-style-type:none"} - %li Owner : - %li Garden : - %li Planted on : - %li Finished on : - %li Sun/shade? : - %li Planted from : + %li Owner: + %li Garden: + %li Planted on: + %li Quantity: + %li Finished on: + %li Sun/shade?: + %li Planted from: %td %ul{:style => "list-style-type:none"} %li= link_to planting.owner.login_name, planting.owner %li= link_to planting.garden.name, planting.garden %li= planting.planted_at + %li= "#{display_planting_quantity(planting)}" %li= "#{display_finished(planting)}" %li= "#{display_sunniness(planting)}" %li= "#{display_planted_from(planting)}" diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index ff7099b42..127507104 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -8,7 +8,7 @@ — = link_to "view all #{@planting.owner}'s plantings", plantings_by_owner_path(:owner => @planting.owner.slug) %p - %b Planted: + %b Planted on: = @planting.planted_at ? @planting.planted_at : "not specified" %p @@ -18,44 +18,30 @@ - if ! @planting.owner.location.blank? = "(#{@planting.owner.location})" %p - %b Quantity: - = @planting.quantity.blank? ? "not specified" : @planting.quantity - - - if ! @planting.planted_from.blank? + %b + = "Quantity: " + = "#{display_planting_quantity(@planting)}" + + - if !@planting.planted_from.blank? %p - %b Planted from: - = @planting.planted_from - - - if ! @planting.sunniness.blank? + %b + = "Planted from: " + = "#{display_planted_from(@planting)}" + + - if !@planting.sunniness.blank? %p - %b Sun or shade? - = @planting.sunniness - - - if @planting.finished - %p - %b Finished: - - if @planting.finished_at - = @planting.finished_at - - else - Yes (no date specified) + %b + = "Sun or shade?: " + = "#{display_sunniness(@planting)}" %p - %b Days until maturity: - - if @planting.finished? - %b - = " 0" - - elsif !@planting.finished_at.nil? - - if ((p = @planting.finished_at - DateTime.now).to_i) <= 0 - - p = 0 - %b - = " #{p.to_i}" - - elsif @planting.days_before_maturity.nil? - %b - = " unknown" - - else - - if ((p = (@planting.planted_at + @planting.days_before_maturity) - DateTime.now).to_i) <= 0 - - p = 0 - %b - = " #{p.to_i}" + %b + = "Days until maturity: " + = "#{display_days_before_maturity(@planting)}" + %p + %b + = "Finished: " + = "#{display_finished(@planting)}" + %p %b= render 'planting_progress', planting: @planting From 0a2d0d499c8f21930414edd71746837f984700c1 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 3 Jul 2015 11:42:20 +0800 Subject: [PATCH 103/392] Removed unneeded methods on the plantings helper --- app/helpers/plantings_helper.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/helpers/plantings_helper.rb b/app/helpers/plantings_helper.rb index 179062318..1eb220481 100644 --- a/app/helpers/plantings_helper.rb +++ b/app/helpers/plantings_helper.rb @@ -1,13 +1,4 @@ module PlantingsHelper - def display (notification) - if notification.post - # comment on the post in question - new_comment_url(:post_id => notification.post.id) - else - # by default, reply link sends a PM in return - reply_notification_url(notification) - end - end def display_days_before_maturity(planting) if planting.finished? From b599818512b2c5a9c29c15f2581e50ee93cca3a3 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Sat, 4 Jul 2015 19:18:26 +0800 Subject: [PATCH 104/392] Delete _thumbnail.html.haml_spec.rb --- .../plantings/_thumbnail.html.haml_spec.rb | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 spec/views/plantings/_thumbnail.html.haml_spec.rb diff --git a/spec/views/plantings/_thumbnail.html.haml_spec.rb b/spec/views/plantings/_thumbnail.html.haml_spec.rb deleted file mode 100644 index 09404b485..000000000 --- a/spec/views/plantings/_thumbnail.html.haml_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -# require 'rails_helper' - -# describe "plantings/_thumbnail" do -# before(:each) do -# controller.stub(:current_user) { nil } -# @member = FactoryGirl.create(:member) -# @garden = FactoryGirl.create(:garden, :owner => @member) -# @crop = FactoryGirl.create(:tomato) - -# @planting = FactoryGirl.create(:planting, -# :garden => @garden, -# :crop => @crop -# ) -# end - -# context "simple view" do -# before(:each) do -# render :partial => "thumbnail", :locals => { -# :planting => @planting, -# } -# end - -# it "renders the quantity planted" do -# rendered.should have_content "33" -# end - -# it "renders the date planted" do -# rendered.should have_content @planting.planted_at.to_s(:default) -# end - -# it "shows the name of the crop" do -# rendered.should have_content @crop.name -# end - -# it "shows the description by default" do -# rendered.should have_content "This is a" -# end -# end - -# context "with complicated args" do -# before(:each) do -# render :partial => "thumbnail", :locals => { -# :planting => @planting, -# :hide_description => true -# } -# end - -# it "hides the description if asked" do -# rendered.should_not have_content "This is a" -# end -# end - -# end From 755a60447fb4d8b01ceeb8d98c296a4dfe164fde Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 7 Jul 2015 08:19:13 +0800 Subject: [PATCH 105/392] Made the plantings/_thumbnail partial to contain only a single object. --- app/views/gardens/show.html.haml | 23 +++++-- app/views/members/_gardens.html.haml | 9 ++- app/views/plantings/_thumbnail.html.haml | 86 +++++++++++------------- app/views/plantings/index.html.haml | 8 ++- 4 files changed, 71 insertions(+), 55 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 85a8baae9..f6b38a7e8 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -43,19 +43,28 @@ %p{:style => 'text-align: center; padding-top: 50px'} = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' - - %h3 - What's planted here? - + %h3 What's planted here? - if @garden.plantings.current.size > 0 - = render :partial => "plantings/thumbnail", :locals => { :plantings => @garden.plantings.current} + %table.table.table-striped + %tr + %th # + %th Photo + %th{:colspan => "3"} Planting details + - @garden.plantings.current.each.with_index do |planting_current, index_current| + = render partial: "plantings/thumbnail", locals: {:planting => planting_current, :index => index_current} - else %p Nothing is currently planted here. + %h3 Previously planted in this garden - if @garden.plantings.finished.size > 0 - %h3 Previously planted in this garden - = render :partial => "plantings/thumbnail", :locals => { :plantings => @garden.plantings.finished} + %table.table.table-striped + %tr + %th # + %th Photo + %th{:colspan => "3"} Planting details + - @garden.plantings.finished.each.with_index do |planting_finished, index_finished| + = render partial: "plantings/thumbnail", locals: {:planting => planting_finished, :index => index_finished} .col-md-3 %h4 About this garden diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 4147fa74f..8c3f572b0 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -34,7 +34,14 @@ = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' %h3 What's planted here? - = render :partial => "plantings/thumbnail", :locals => { :plantings => g.featured_plantings} + - if g.featured_plantings.size > 0 + %table.table.table-striped + %tr + %th # + %th Photo + %th{:colspan => "3"} Planting details + - g.featured_plantings.each.with_index do |planting, index| + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} %p = link_to "More about this garden...", url_for(g) diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index a7f53e4f7..a3615c6ec 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,48 +1,42 @@ -%table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "3"} Planting details - - plantings.each.with_index do |planting, index| +%tr + %td= "##{index+1}" + %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting + %td + %ul{:style => "list-style-type:none"} + %li Owner: + %li Garden: + %li Planted on: + %li Quantity: + %li Finished on: + %li Sun/shade?: + %li Planted from: + %td + %ul{:style => "list-style-type:none"} + %li= link_to planting.owner.login_name, planting.owner + %li= link_to planting.garden.name, planting.garden + %li= planting.planted_at + %li= "#{display_planting_quantity(planting)}" + %li= "#{display_finished(planting)}" + %li= "#{display_sunniness(planting)}" + %li= "#{display_planted_from(planting)}" + %td + %ul{:style => "list-style-type:none"} + %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' + - if can? :edit, planting + %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + - if ! planting.finished + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' + - if can? :destroy, planting + %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' %tr - %td= "##{index+1}" - %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - %td - %ul{:style => "list-style-type:none"} - %li Owner: - %li Garden: - %li Planted on: - %li Quantity: - %li Finished on: - %li Sun/shade?: - %li Planted from: - %td - %ul{:style => "list-style-type:none"} - %li= link_to planting.owner.login_name, planting.owner - %li= link_to planting.garden.name, planting.garden - %li= planting.planted_at - %li= "#{display_planting_quantity(planting)}" - %li= "#{display_finished(planting)}" - %li= "#{display_sunniness(planting)}" - %li= "#{display_planted_from(planting)}" - %td - %ul{:style => "list-style-type:none"} - %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - - if can? :edit, planting - %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - - if can? :destroy, planting - %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - %tr - %td - %td - %ul{:style => "list-style-type:none"} - %li - Crop name: - =link_to planting.crop.name, planting.crop - %li= "Days until maturity: #{display_days_before_maturity(planting)}" + %td + %td + %ul{:style => "list-style-type:none"} + %li + Crop name: + =link_to planting.crop.name, planting.crop + %li= "Days until maturity: #{display_days_before_maturity(planting)}" - %td{:colspan => "3"} - %ul{:style => "list-style-type:none"} - %li= render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file + %td{:colspan => "3"} + %ul{:style => "list-style-type:none"} + %li= render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index ca0db97f5..461ebf43b 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -19,7 +19,13 @@ = will_paginate @plantings - if @plantings.size > 0 - = render partial: "plantings/thumbnail", locals: {:plantings => @plantings} + %table.table.table-striped + %tr + %th # + %th Photo + %th{:colspan => "3"} Planting details + - @plantings.each.with_index do |planting, index| + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} %div.pagination = page_entries_info @plantings, :model => "plantings" From 92db75b3d8876d2ed2156bf84d6e1201b81dbb73 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 7 Jul 2015 08:34:03 +0800 Subject: [PATCH 106/392] Converted the ul's in the plantings thumbnail partial to definition lists --- app/views/gardens/show.html.haml | 4 +-- app/views/members/_gardens.html.haml | 2 +- app/views/plantings/_thumbnail.html.haml | 42 +++++++++++------------- app/views/plantings/index.html.haml | 2 +- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index f6b38a7e8..e91183381 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -49,7 +49,7 @@ %tr %th # %th Photo - %th{:colspan => "3"} Planting details + %th{:colspan => "2"} Planting details - @garden.plantings.current.each.with_index do |planting_current, index_current| = render partial: "plantings/thumbnail", locals: {:planting => planting_current, :index => index_current} - else @@ -62,7 +62,7 @@ %tr %th # %th Photo - %th{:colspan => "3"} Planting details + %th{:colspan => "2"} Planting details - @garden.plantings.finished.each.with_index do |planting_finished, index_finished| = render partial: "plantings/thumbnail", locals: {:planting => planting_finished, :index => index_finished} diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 8c3f572b0..f84124db9 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -39,7 +39,7 @@ %tr %th # %th Photo - %th{:colspan => "3"} Planting details + %th{:colspan => "2"} Planting details - g.featured_plantings.each.with_index do |planting, index| = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index a3615c6ec..423a24355 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -2,23 +2,21 @@ %td= "##{index+1}" %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting %td - %ul{:style => "list-style-type:none"} - %li Owner: - %li Garden: - %li Planted on: - %li Quantity: - %li Finished on: - %li Sun/shade?: - %li Planted from: - %td - %ul{:style => "list-style-type:none"} - %li= link_to planting.owner.login_name, planting.owner - %li= link_to planting.garden.name, planting.garden - %li= planting.planted_at - %li= "#{display_planting_quantity(planting)}" - %li= "#{display_finished(planting)}" - %li= "#{display_sunniness(planting)}" - %li= "#{display_planted_from(planting)}" + %dl.dl-horizontal + %dt Owner: + %dd= link_to planting.owner.login_name, planting.owner + %dt Garden: + %dd= link_to planting.garden.name, planting.garden + %dt Planted on: + %dd= planting.planted_at + %dt Quantity: + %dd= "#{display_planting_quantity(planting)}" + %dt Finished on: + %dd= "#{display_finished(planting)}" + %dt Sun/shade?: + %dd= "#{display_sunniness(planting)}" + %dt Planted from: + %dd= "#{display_planted_from(planting)}" %td %ul{:style => "list-style-type:none"} %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' @@ -31,11 +29,11 @@ %tr %td %td - %ul{:style => "list-style-type:none"} - %li - Crop name: - =link_to planting.crop.name, planting.crop - %li= "Days until maturity: #{display_days_before_maturity(planting)}" + %dl.dl-horizontal + %dt Crop name: + %dd= link_to planting.crop.name, planting.crop + %dt Days until maturity: + %dd= "#{display_days_before_maturity(planting)}" %td{:colspan => "3"} %ul{:style => "list-style-type:none"} diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 461ebf43b..5623aeca4 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -23,7 +23,7 @@ %tr %th # %th Photo - %th{:colspan => "3"} Planting details + %th{:colspan => "2"} Planting details - @plantings.each.with_index do |planting, index| = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} From e138b3e8ab5b28285695605d2f761d8701ea4a00 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 7 Jul 2015 10:08:50 +0800 Subject: [PATCH 107/392] Converted html tables to CSS classes --- app/views/gardens/show.html.haml | 28 +++++++++++++-------- app/views/members/_gardens.html.haml | 14 +++++++---- app/views/plantings/_thumbnail.html.haml | 32 +++++++++++++----------- app/views/plantings/index.html.haml | 17 +++++++------ 4 files changed, 55 insertions(+), 36 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index e91183381..cef4c95f8 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -45,11 +45,15 @@ %h3 What's planted here? - if @garden.plantings.current.size > 0 - %table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "2"} Planting details + .container + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 - @garden.plantings.current.each.with_index do |planting_current, index_current| = render partial: "plantings/thumbnail", locals: {:planting => planting_current, :index => index_current} - else @@ -58,11 +62,15 @@ %h3 Previously planted in this garden - if @garden.plantings.finished.size > 0 - %table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "2"} Planting details + .container + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 - @garden.plantings.finished.each.with_index do |planting_finished, index_finished| = render partial: "plantings/thumbnail", locals: {:planting => planting_finished, :index => index_finished} diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index f84124db9..7f5d4de2b 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -35,11 +35,15 @@ %h3 What's planted here? - if g.featured_plantings.size > 0 - %table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "2"} Planting details + .container + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 - g.featured_plantings.each.with_index do |planting, index| = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 423a24355..2cebfcbd7 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,7 +1,9 @@ -%tr - %td= "##{index+1}" - %td= link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - %td +.row + .col-md-1 + = "##{index+1}" + .col-md-3 + = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting + .col-md-6 %dl.dl-horizontal %dt Owner: %dd= link_to planting.owner.login_name, planting.owner @@ -17,7 +19,7 @@ %dd= "#{display_sunniness(planting)}" %dt Planted from: %dd= "#{display_planted_from(planting)}" - %td + .col-md-2 %ul{:style => "list-style-type:none"} %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting @@ -26,15 +28,17 @@ %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - %tr - %td - %td - %dl.dl-horizontal - %dt Crop name: - %dd= link_to planting.crop.name, planting.crop - %dt Days until maturity: - %dd= "#{display_days_before_maturity(planting)}" +.row + .col-md-1 + .col-md-3 + %ul{:style => "list-style-type:none"} + %li + %b Crop name: + = link_to planting.crop.name, planting.crop + %li + %b Days until maturity: + = "#{display_days_before_maturity(planting)}" - %td{:colspan => "3"} + .col-md-8 %ul{:style => "list-style-type:none"} %li= render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 5623aeca4..aa01c9129 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -19,13 +19,16 @@ = will_paginate @plantings - if @plantings.size > 0 - %table.table.table-striped - %tr - %th # - %th Photo - %th{:colspan => "2"} Planting details - - @plantings.each.with_index do |planting, index| - = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 + - @plantings.each.with_index do |planting, index| + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} %div.pagination = page_entries_info @plantings, :model => "plantings" From 7607daa83a1cbdb10ed33c2d99a96c21d9d03f17 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 8 Jul 2015 08:04:18 +0800 Subject: [PATCH 108/392] Added feature and test for request #549 --- app/helpers/crops_helper.rb | 17 ++++++++++++ app/views/crops/show.html.haml | 4 ++- spec/features/crops/crop_detail_page_spec.rb | 27 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/helpers/crops_helper.rb diff --git a/app/helpers/crops_helper.rb b/app/helpers/crops_helper.rb new file mode 100644 index 000000000..530df6b15 --- /dev/null +++ b/app/helpers/crops_helper.rb @@ -0,0 +1,17 @@ +module CropsHelper + def display_seed_availability(member, crop) + total_quantity = 0 + member.seeds.each do |seed| + if seed.crop.name == crop.name + total_quantity = total_quantity + seed.quantity + end + end + + if (total_quantity != 0) + "You have #{pluralize(total_quantity, "seed")} of this crop." + else + "You don't have any seeds of this crop." + end + + end +end \ No newline at end of file diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index 57efa60a5..c32fc12c8 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -13,7 +13,9 @@ - if can? :create, Seed = link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-default' - + - if member_signed_in? + = display_seed_availability(@current_member, @crop) + = link_to "View your seeds", seeds_by_owner_path(:owner => current_member.slug) .row .col-md-9 diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 1d26f0825..a7654904b 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'pry' feature "crop detail page" do @@ -143,4 +144,30 @@ feature "crop detail page" do end end + + context "seed quantity for a crop" do + let(:member) { FactoryGirl.create(:member) } + let(:seed) { FactoryGirl.create(:seed, :crop => crop, :quantity => 20, :owner => member)} + + scenario "User not signed in" do + visit crop_path(seed.crop) + expect(page).to_not have_content "You have 20 seeds of this crop" + expect(page).to_not have_content "You don't have any seeds of this crop" + expect(page).to_not have_link "View your seeds" + end + + scenario "User signed in" do + login_as(member) + visit crop_path(seed.crop) + expect(page).to have_content "You have 20 seeds of this crop." + expect(page).to have_link "View your seeds" + end + + scenario "click link to your owned seeds" do + login_as(member) + visit crop_path(seed.crop) + click_link "View your seeds" + current_path.should == seeds_by_owner_path(:owner => member.slug) + end + end end From c746c6d6d7b5ae8dbdc19ad43bfe7832f97ddf0c Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 8 Jul 2015 08:35:45 +0800 Subject: [PATCH 109/392] Added feature and test for request #549 --- spec/features/crops/crop_detail_page_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index a7654904b..d8738929f 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,5 +1,4 @@ require 'rails_helper' -require 'pry' feature "crop detail page" do From 8c1d88b663b291eb3653d0b6d49b63e032207705 Mon Sep 17 00:00:00 2001 From: Jace Monje Date: Wed, 8 Jul 2015 12:07:37 +0800 Subject: [PATCH 110/392] added the admin/wrangler role check on member profile page --- app/views/members/_account.html.haml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index 2e56e4342..4898e88ea 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -13,3 +13,10 @@ %strong Last Login: = member.last_sign_in_at +%p + %strong Member Roles: + %br + - if member.has_role? :admin + Administrator + - if member.has_role? :crop_wrangler + Crop Wrangler From c6c84925284f0da450b6ee9be0494b1de4be627a Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 9 Jul 2015 01:59:34 +0800 Subject: [PATCH 111/392] Fix changes in spec/support --- spec/support/controller_macros.rb | 4 +++- spec/support/elasticsearch_helpers.rb | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/support/controller_macros.rb b/spec/support/controller_macros.rb index eb5be2dd4..2e8162705 100644 --- a/spec/support/controller_macros.rb +++ b/spec/support/controller_macros.rb @@ -1,9 +1,11 @@ # Taken unashamedly from https://github.com/plataformatec/devise/wiki/How-To%3a-Controllers-and-Views-tests-with-Rails-3-%28and-rspec%29 module ControllerMacros def login_member(member_factory=:member) + + let(:member) { member = FactoryGirl.create(member_factory || :member) } + before(:each) do @request.env["devise.mapping"] = Devise.mappings[:member] - member = FactoryGirl.create(member_factory || :member) sign_in member end end diff --git a/spec/support/elasticsearch_helpers.rb b/spec/support/elasticsearch_helpers.rb index 0d89eb33b..94cf447ff 100644 --- a/spec/support/elasticsearch_helpers.rb +++ b/spec/support/elasticsearch_helpers.rb @@ -10,7 +10,7 @@ end RSpec.configure do |config| config.include ElasticsearchHelpers - config.before(:each) do + config.before(:all) do if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" Crop.__elasticsearch__.create_index! force: true end From c5684989418170f9189df4d9b3d16b78df92e3b1 Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 9 Jul 2015 02:21:10 +0800 Subject: [PATCH 112/392] Refactor spec/models - Changed before(:each) into let - Changed :admin_ability and :cw_ability into :ability --- spec/models/ability_spec.rb | 239 ++++++++++++++-------------- spec/models/account_spec.rb | 23 ++- spec/models/comment_spec.rb | 14 +- spec/models/crop_spec.rb | 142 ++++++++--------- spec/models/forum_spec.rb | 23 ++- spec/models/garden_spec.rb | 169 ++++++++++---------- spec/models/harvest_spec.rb | 45 +++--- spec/models/member_spec.rb | 177 ++++++++++---------- spec/models/notification_spec.rb | 33 ++-- spec/models/order_item_spec.rb | 19 ++- spec/models/planting_spec.rb | 59 ++++--- spec/models/post_spec.rb | 33 ++-- spec/models/scientific_name_spec.rb | 16 +- spec/models/seed_spec.rb | 10 +- 14 files changed, 499 insertions(+), 503 deletions(-) diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 87d8a3b1d..7c3f895c2 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -2,36 +2,37 @@ require 'rails_helper' require 'cancan/matchers' describe Ability do - before(:each) do - @member = FactoryGirl.create(:member) - @ability = Ability.new(@member) - end + + let(:member) { FactoryGirl.create(:member) } + let(:ability) { Ability.new(member) } context "notifications" do + + let(:notification) { FactoryGirl.create(:notification, :recipient => member) } + it 'member can view their own notifications' do - @notification = FactoryGirl.create(:notification, :recipient => @member) - @ability.should be_able_to(:read, @notification) + ability.should be_able_to(:read, notification) end it "member can't view someone else's notifications" do - @notification = FactoryGirl.create(:notification, + notification = FactoryGirl.create(:notification, :recipient => FactoryGirl.create(:member) ) - @ability.should_not be_able_to(:read, @notification) + ability.should_not be_able_to(:read, notification) end it "member can't send messages to themself" do - @ability.should_not be_able_to(:create, + ability.should_not be_able_to(:create, FactoryGirl.create(:notification, - :recipient => @member, - :sender => @member + :recipient => member, + :sender => member ) ) end it "member can send messages to someone else" do - @ability.should be_able_to(:create, + ability.should be_able_to(:create, FactoryGirl.create(:notification, :recipient => FactoryGirl.create(:member), - :sender => @member + :sender => member ) ) end @@ -39,245 +40,248 @@ describe Ability do context "crop wrangling" do - before(:each) do - @crop = FactoryGirl.create(:crop) - end + let(:crop) { FactoryGirl.create(:crop) } context "standard member" do it "can't manage crops" do - @ability.should_not be_able_to(:update, @crop) - @ability.should_not be_able_to(:destroy, @crop) + ability.should_not be_able_to(:update, crop) + ability.should_not be_able_to(:destroy, crop) end it "can request crops" do - @ability.should be_able_to(:create, Crop) + ability.should be_able_to(:create, Crop) end it "can read crops" do - @ability.should be_able_to(:read, @crop) + ability.should be_able_to(:read, crop) end end context "crop wrangler" do + + let(:role) { FactoryGirl.create(:crop_wrangler) } + before(:each) do - @role = FactoryGirl.create(:crop_wrangler) - @member.roles << @role - @cw_ability = Ability.new(@member) + member.roles << role end + let(:ability) { Ability.new(member) } + it "has crop_wrangler role" do - @member.has_role?(:crop_wrangler).should be true + member.has_role?(:crop_wrangler).should be true end it "can create crops" do - @cw_ability.should be_able_to(:create, Crop) + ability.should be_able_to(:create, Crop) end it "can update crops" do - @cw_ability.should be_able_to(:update, @crop) + ability.should be_able_to(:update, crop) end it "can destroy crops" do - @cw_ability.should be_able_to(:destroy, @crop) + ability.should be_able_to(:destroy, crop) end end end context "products" do - before(:each) do - @product = FactoryGirl.create(:product) - end + let(:product) { FactoryGirl.create(:product) } context "standard member" do it "can't read or manage products" do - @ability.should_not be_able_to(:read, @product) - @ability.should_not be_able_to(:create, Product) - @ability.should_not be_able_to(:update, @product) - @ability.should_not be_able_to(:destroy, @product) + ability.should_not be_able_to(:read, product) + ability.should_not be_able_to(:create, Product) + ability.should_not be_able_to(:update, product) + ability.should_not be_able_to(:destroy, product) end end context "admin" do - before(:each) do - @role = FactoryGirl.create(:admin) - @member.roles << @role - @admin_ability = Ability.new(@member) + + let(:role) { FactoryGirl.create(:admin) } + + before do + member.roles << role end + let(:ability) { Ability.new(member) } + it "has admin role" do - @member.has_role?(:admin).should be true + member.has_role?(:admin).should be true end it "can read products" do - @admin_ability.should be_able_to(:read, @product) + ability.should be_able_to(:read, product) end it "can create products" do - @admin_ability.should be_able_to(:create, Product) + ability.should be_able_to(:create, Product) end it "can update products" do - @admin_ability.should be_able_to(:update, @product) + ability.should be_able_to(:update, product) end it "can destroy products" do - @admin_ability.should be_able_to(:destroy, @product) + ability.should be_able_to(:destroy, product) end end end context "orders" do - before(:each) do - @order = FactoryGirl.create(:order, :member => @member) - @strangers_order = FactoryGirl.create(:order, - :member => FactoryGirl.create(:member)) - @completed_order = FactoryGirl.create(:completed_order, - :member => @member) - - @order_item = FactoryGirl.create(:order_item, :order => @order) - @strangers_order_item = FactoryGirl.create(:order_item, - :order => @strangers_order) - @completed_order_item = FactoryGirl.create(:order_item, - :order => @completed_order) - end + let(:order) { FactoryGirl.create(:order, :member => member) } + let(:strangers_order) { FactoryGirl.create(:order, + :member => FactoryGirl.create(:member)) } + let(:completed_order) { FactoryGirl.create(:completed_order, + :member => member) } + let(:order_item) { FactoryGirl.create(:order_item, :order => order) } + let(:strangers_order_item) { FactoryGirl.create(:order_item, + :order => strangers_order) } + let(:completed_order_item) { FactoryGirl.create(:order_item, + :order => completed_order) } context "standard member" do it "can read their own orders" do - @ability.should be_able_to(:read, @order) - @ability.should be_able_to(:read, @completed_order) + ability.should be_able_to(:read, order) + ability.should be_able_to(:read, completed_order) end it "can't read other people's orders" do - @ability.should_not be_able_to(:read, @strangers_order) + ability.should_not be_able_to(:read, strangers_order) end it "can create a new order" do - @ability.should be_able_to(:create, Order) + ability.should be_able_to(:create, Order) end it "can complete their own current order" do - @ability.should be_able_to(:complete, @order) + ability.should be_able_to(:complete, order) end it "can't complete someone else's order" do - @ability.should_not be_able_to(:complete, @strangers_order) + ability.should_not be_able_to(:complete, strangers_order) end it "can't complete a completed order" do - @ability.should_not be_able_to(:complete, @completed_order) + ability.should_not be_able_to(:complete, completed_order) end it "can delete a current order" do - @ability.should be_able_to(:destroy, @order) + ability.should be_able_to(:destroy, order) end it "can't delete someone else's order" do - @ability.should_not be_able_to(:destroy, @strangers_order) + ability.should_not be_able_to(:destroy, strangers_order) end it "can't delete a completed order" do - @ability.should_not be_able_to(:destroy, @completed_order) + ability.should_not be_able_to(:destroy, completed_order) end it "can't read their own order items" do - @ability.should_not be_able_to(:read, @order_item) - @ability.should_not be_able_to(:read, @completed_order_item) + ability.should_not be_able_to(:read, order_item) + ability.should_not be_able_to(:read, completed_order_item) end it "can't read other people's order items" do - @ability.should_not be_able_to(:read, @strangers_order_item) + ability.should_not be_able_to(:read, strangers_order_item) end it "can create a new order item" do - @ability.should be_able_to(:create, OrderItem) + ability.should be_able_to(:create, OrderItem) end it "can't update their own order items" do - @ability.should_not be_able_to(:update, @order_item) + ability.should_not be_able_to(:update, order_item) end it "can't update other people's order items" do - @ability.should_not be_able_to(:update, @strangers_order_item) + ability.should_not be_able_to(:update, strangers_order_item) end it "can't updated items in completed orders" do - @ability.should_not be_able_to(:update, @completed_order_item) + ability.should_not be_able_to(:update, completed_order_item) end it "can't delete their own order item" do - @ability.should_not be_able_to(:destroy, @order_item) + ability.should_not be_able_to(:destroy, order_item) end it "can't delete someone else's order item" do - @ability.should_not be_able_to(:destroy, @strangers_order_item) + ability.should_not be_able_to(:destroy, strangers_order_item) end it "can't delete items from completed orders" do - @ability.should_not be_able_to(:destroy, @completed_order_item) + ability.should_not be_able_to(:destroy, completed_order_item) end end context "admin" do - before(:each) do - @role = FactoryGirl.create(:admin) - @member.roles << @role - @admin_ability = Ability.new(@member) + + let(:role) { FactoryGirl.create(:admin) } + + before do + member.roles << role end + let(:ability) { Ability.new(member) } + it "has admin role" do - @member.has_role?(:admin).should be true + member.has_role?(:admin).should be true end it "can read orders" do - @admin_ability.should be_able_to(:read, @order) + ability.should be_able_to(:read, order) end it "cannot create orders" do - @admin_ability.should_not be_able_to(:create, @order) + ability.should_not be_able_to(:create, order) end it "cannot complete orders" do - @admin_ability.should_not be_able_to(:complete, @order) + ability.should_not be_able_to(:complete, order) end it "cannot delete orders" do - @admin_ability.should_not be_able_to(:destroy, @order) + ability.should_not be_able_to(:destroy, order) end end end context 'account details' do - before(:each) do - @account = @member.account - end + + let(:account) { member.account } context 'ordinary member' do it "can't read account details" do - @ability.should_not be_able_to(:read, @account) + ability.should_not be_able_to(:read, account) end it "can't manage account details" do - @ability.should_not be_able_to(:create, Account) - @ability.should_not be_able_to(:update, @account) - @ability.should_not be_able_to(:destroy, @account) + ability.should_not be_able_to(:create, Account) + ability.should_not be_able_to(:update, account) + ability.should_not be_able_to(:destroy, account) end end context 'admin' do - before(:each) do - @role = FactoryGirl.create(:admin) - @member.roles << @role - @admin_ability = Ability.new(@member) + let(:role) { FactoryGirl.create(:admin) } + + before do + member.roles << role end + let(:ability) { Ability.new(member) } + it "can read account details" do - @admin_ability.should be_able_to(:read, @account) + ability.should be_able_to(:read, account) end it "can manage account details" do - @admin_ability.should be_able_to(:create, Account) - @admin_ability.should be_able_to(:update, @account) - @admin_ability.should be_able_to(:destroy, @account) + ability.should be_able_to(:create, Account) + ability.should be_able_to(:update, account) + ability.should be_able_to(:destroy, account) end end @@ -285,44 +289,45 @@ describe Ability do end context 'plant parts' do - before(:each) do - @plant_part = FactoryGirl.create(:plant_part) - end + + let(:plant_part) { FactoryGirl.create(:plant_part) } context 'ordinary member' do it "can read plant parts" do - @ability.should be_able_to(:read, @plant_part) + ability.should be_able_to(:read, plant_part) end it "can't manage plant parts" do - @ability.should_not be_able_to(:create, PlantPart) - @ability.should_not be_able_to(:update, @plant_part) - @ability.should_not be_able_to(:destroy, @plant_part) + ability.should_not be_able_to(:create, PlantPart) + ability.should_not be_able_to(:update, plant_part) + ability.should_not be_able_to(:destroy, plant_part) end end context 'admin' do - before(:each) do - @role = FactoryGirl.create(:admin) - @member.roles << @role - @admin_ability = Ability.new(@member) + let(:role) { FactoryGirl.create(:admin) } + + before do + member.roles << role end + let(:ability) { Ability.new(member) } + it "can read plant_part details" do - @admin_ability.should be_able_to(:read, @plant_part) + ability.should be_able_to(:read, plant_part) end it "can manage plant_part details" do - @admin_ability.should be_able_to(:create, PlantPart) - @admin_ability.should be_able_to(:update, @plant_part) + ability.should be_able_to(:create, PlantPart) + ability.should be_able_to(:update, plant_part) end it "can delete an unused plant part" do - @admin_ability.should be_able_to(:destroy, @plant_part) + ability.should be_able_to(:destroy, plant_part) end it "can't delete a plant part that has harvests" do - @harvest = FactoryGirl.create(:harvest, :plant_part => @plant_part) - @admin_ability.should_not be_able_to(:destroy, @plant_part) + @harvest = FactoryGirl.create(:harvest, :plant_part => plant_part) + ability.should_not be_able_to(:destroy, plant_part) end end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index b1765ccc0..2a41ed983 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1,30 +1,29 @@ require 'rails_helper' describe Account do - before(:each) do - @member = FactoryGirl.create(:member) - end + + let(:member) { FactoryGirl.create(:member) } it "auto-creates an account detail record when a member is created" do - @member.account.should be_an_instance_of Account + member.account.should be_an_instance_of Account end it "won't let you create two account details for the same member" do - @details = Account.new(:member_id => @member.id) + @details = Account.new(:member_id => member.id) @details.should_not be_valid end it "formats the 'paid until' date nicely" do - @member.account.account_type = FactoryGirl.create(:account_type) - @member.account.paid_until_string.should eq nil + member.account.account_type = FactoryGirl.create(:account_type) + member.account.paid_until_string.should eq nil - @member.account.account_type = FactoryGirl.create(:permanent_paid_account_type) - @member.account.paid_until_string.should eq "forever" + member.account.account_type = FactoryGirl.create(:permanent_paid_account_type) + member.account.paid_until_string.should eq "forever" - @member.account.account_type = FactoryGirl.create(:paid_account_type) + member.account.account_type = FactoryGirl.create(:paid_account_type) @time = Time.zone.now - @member.account.paid_until = @time - @member.account.paid_until_string.should eq @time.to_s + member.account.paid_until = @time + member.account.paid_until_string.should eq @time.to_s end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index d54cd5606..9fbf1ca1e 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -3,23 +3,21 @@ require 'rails_helper' describe Comment do context "basic" do - before(:each) do - @comment = FactoryGirl.create(:comment) - end + + let(:comment) { FactoryGirl.create(:comment) } it "belongs to a post" do - @comment.post.should be_an_instance_of Post + comment.post.should be_an_instance_of Post end it "belongs to an author" do - @comment.author.should be_an_instance_of Member + comment.author.should be_an_instance_of Member end end context "notifications" do - before(:each) do - @comment = FactoryGirl.create(:comment) - end + + let(:comment) { FactoryGirl.create(:comment) } it "sends a notification when a comment is posted" do expect { diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 7423a4fd2..724567626 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -3,42 +3,40 @@ require 'rails_helper' describe Crop do context 'all fields present' do - before(:each) do - @crop = FactoryGirl.create(:tomato) - end + let(:crop) { FactoryGirl.create(:tomato) } it 'should save a basic crop' do - @crop.save.should be(true) + crop.save.should be(true) end it 'should be fetchable from the database' do - @crop.save + crop.save @crop2 = Crop.find_by_name('tomato') @crop2.en_wikipedia_url.should == "http://en.wikipedia.org/wiki/Tomato" @crop2.slug.should == "tomato" end it 'should stringify as the system name' do - @crop.save - @crop.to_s.should == 'tomato' - "#{@crop}".should == 'tomato' + crop.save + crop.to_s.should == 'tomato' + "#{crop}".should == 'tomato' end it 'has a creator' do - @crop.save - @crop.creator.should be_an_instance_of Member + crop.save + crop.creator.should be_an_instance_of Member end end context 'invalid data' do it 'should not save a crop without a system name' do - @crop = FactoryGirl.build(:crop, :name => nil) - expect { @crop.save }.to raise_error ActiveRecord::StatementInvalid + crop = FactoryGirl.build(:crop, :name => nil) + expect { crop.save }.to raise_error ActiveRecord::StatementInvalid end end context 'ordering' do - before(:each) do + before do @uppercase = FactoryGirl.create(:uppercasecrop, :created_at => 1.minute.ago) @lowercase = FactoryGirl.create(:lowercasecrop, :created_at => 2.days.ago) end @@ -53,18 +51,20 @@ describe Crop do end context 'popularity' do - before (:each) do - @tomato = FactoryGirl.create(:tomato) - @maize = FactoryGirl.create(:maize) - @cucumber = FactoryGirl.create(:crop, :name => 'cucumber') - FactoryGirl.create_list(:planting, 10, :crop => @maize) - FactoryGirl.create_list(:planting, 3, :crop => @tomato) + + let(:tomato) { FactoryGirl.create(:tomato) } + let(:maize) { FactoryGirl.create(:maize) } + let(:cucumber) { FactoryGirl.create(:crop, :name => 'cucumber') } + + before do + FactoryGirl.create_list(:planting, 10, :crop => maize) + FactoryGirl.create_list(:planting, 3, :crop => tomato) end it "sorts by most plantings" do - Crop.popular.first.should eq @maize - FactoryGirl.create_list(:planting, 10, :crop => @tomato) - Crop.popular.first.should eq @tomato + Crop.popular.first.should eq maize + FactoryGirl.create_list(:planting, 10, :crop => tomato) + Crop.popular.first.should eq tomato end end @@ -118,70 +118,67 @@ describe Crop do end context 'sunniness' do - before(:each) do - @crop = FactoryGirl.create(:tomato) - end + + let(:crop) { FactoryGirl.create(:tomato) } it 'returns a hash of sunniness values' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => @crop) - planting4 = FactoryGirl.create(:shady_planting, :crop => @crop) - @crop.sunniness.should be_an_instance_of Hash + planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) + planting4 = FactoryGirl.create(:shady_planting, :crop => crop) + crop.sunniness.should be_an_instance_of Hash end it 'counts each sunniness value' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => @crop) - planting4 = FactoryGirl.create(:shady_planting, :crop => @crop) - @crop.sunniness.should == { 'sun' => 2, 'shade' => 1, 'semi-shade' => 1 } + planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) + planting4 = FactoryGirl.create(:shady_planting, :crop => crop) + crop.sunniness.should == { 'sun' => 2, 'shade' => 1, 'semi-shade' => 1 } end it 'ignores unused sunniness values' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => @crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => @crop) - @crop.sunniness.should == { 'sun' => 2, 'semi-shade' => 1 } + planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) + planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) + crop.sunniness.should == { 'sun' => 2, 'semi-shade' => 1 } end end context 'planted_from' do - before(:each) do - @crop = FactoryGirl.create(:tomato) - end + + let(:crop) { FactoryGirl.create(:tomato) } it 'returns a hash of sunniness values' do - planting1 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => @crop) - planting4 = FactoryGirl.create(:cutting_planting, :crop => @crop) - @crop.planted_from.should be_an_instance_of Hash + planting1 = FactoryGirl.create(:seed_planting, :crop => crop) + planting2 = FactoryGirl.create(:seed_planting, :crop => crop) + planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) + planting4 = FactoryGirl.create(:cutting_planting, :crop => crop) + crop.planted_from.should be_an_instance_of Hash end it 'counts each planted_from value' do - planting1 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => @crop) - planting4 = FactoryGirl.create(:cutting_planting, :crop => @crop) - @crop.planted_from.should == { 'seed' => 2, 'seedling' => 1, 'cutting' => 1 } + planting1 = FactoryGirl.create(:seed_planting, :crop => crop) + planting2 = FactoryGirl.create(:seed_planting, :crop => crop) + planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) + planting4 = FactoryGirl.create(:cutting_planting, :crop => crop) + crop.planted_from.should == { 'seed' => 2, 'seedling' => 1, 'cutting' => 1 } end it 'ignores unused planted_from values' do - planting1 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => @crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => @crop) - @crop.planted_from.should == { 'seed' => 2, 'seedling' => 1 } + planting1 = FactoryGirl.create(:seed_planting, :crop => crop) + planting2 = FactoryGirl.create(:seed_planting, :crop => crop) + planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) + crop.planted_from.should == { 'seed' => 2, 'seedling' => 1 } end end context 'popular plant parts' do - before(:each) do - @crop = FactoryGirl.create(:tomato) - end + + let(:crop) { FactoryGirl.create(:tomato) } it 'returns a hash of plant_part values' do - @crop.popular_plant_parts.should be_an_instance_of Hash + crop.popular_plant_parts.should be_an_instance_of Hash end it 'counts each plant_part value' do @@ -190,22 +187,22 @@ describe Crop do @root = FactoryGirl.create(:plant_part) @bulb = FactoryGirl.create(:plant_part) @harvest1 = FactoryGirl.create(:harvest, - :crop => @crop, + :crop => crop, :plant_part => @fruit ) @harvest2 = FactoryGirl.create(:harvest, - :crop => @crop, + :crop => crop, :plant_part => @fruit ) @harvest3 = FactoryGirl.create(:harvest, - :crop => @crop, + :crop => crop, :plant_part => @seed ) @harvest4 = FactoryGirl.create(:harvest, - :crop => @crop, + :crop => crop, :plant_part => @root ) - @crop.popular_plant_parts.should == { @fruit => 2, @seed => 1, @root => 1 } + crop.popular_plant_parts.should == { @fruit => 2, @seed => 1, @root => 1 } end end @@ -327,21 +324,24 @@ describe Crop do end context "search" do - before :each do - @mushroom = FactoryGirl.create(:crop, :name => 'mushroom') - sync_elasticsearch([@mushroom]) + + let(:mushroom) { FactoryGirl.create(:crop, :name => 'mushroom') } + + before do + sync_elasticsearch([mushroom]) end + it "finds exact matches" do - Crop.search('mushroom').should eq [@mushroom] + Crop.search('mushroom').should eq [mushroom] end it "finds approximate matches" do - Crop.search('mush').should eq [@mushroom] + Crop.search('mush').should eq [mushroom] end it "doesn't find non-matches" do Crop.search('mush').should_not include @crop end it "searches case insensitively" do - Crop.search('mUsH').should include @mushroom + Crop.search('mUsH').should include mushroom end it "doesn't find 'rejected' crop" do @rejected_crop = FactoryGirl.create(:rejected_crop, :name => 'tomato') diff --git a/spec/models/forum_spec.rb b/spec/models/forum_spec.rb index 9769882c6..dfebfa356 100644 --- a/spec/models/forum_spec.rb +++ b/spec/models/forum_spec.rb @@ -1,32 +1,31 @@ require 'rails_helper' describe Forum do - before(:each) do - @forum = FactoryGirl.create(:forum) - end + + let(:forum) { FactoryGirl.create(:forum) } it "belongs to an owner" do - @forum.owner.should be_an_instance_of Member + forum.owner.should be_an_instance_of Member end it "stringifies nicely" do - "#{@forum}".should eq @forum.name + "#{forum}".should eq forum.name end it 'has a slug' do - @forum.slug.should eq 'permaculture' + forum.slug.should eq 'permaculture' end it "has many posts" do - @post1 = FactoryGirl.create(:forum_post, :forum => @forum) - @post2 = FactoryGirl.create(:forum_post, :forum => @forum) - @forum.posts.length.should == 2 + @post1 = FactoryGirl.create(:forum_post, :forum => forum) + @post2 = FactoryGirl.create(:forum_post, :forum => forum) + forum.posts.length.should == 2 end it "orders posts in reverse chron order" do - @post1 = FactoryGirl.create(:forum_post, :forum => @forum, :created_at => 2.days.ago) - @post2 = FactoryGirl.create(:forum_post, :forum => @forum, :created_at => 1.day.ago) - @forum.posts.first.should eq @post2 + @post1 = FactoryGirl.create(:forum_post, :forum => forum, :created_at => 2.days.ago) + @post2 = FactoryGirl.create(:forum_post, :forum => forum, :created_at => 1.day.ago) + forum.posts.first.should eq @post2 end end diff --git a/spec/models/garden_spec.rb b/spec/models/garden_spec.rb index 7a6590596..6eebba460 100644 --- a/spec/models/garden_spec.rb +++ b/spec/models/garden_spec.rb @@ -1,80 +1,78 @@ require 'rails_helper' describe Garden do - before :each do - @owner = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @owner) - end + + let(:owner) { FactoryGirl.create(:member) } + let(:garden) { FactoryGirl.create(:garden, :owner => owner) } it "should have a slug" do - @garden.slug.should match(/member\d+-springfield-community-garden/) + garden.slug.should match(/member\d+-springfield-community-garden/) end it "should have a description" do - @garden.description.should == "This is a **totally** cool garden" + garden.description.should == "This is a **totally** cool garden" end it "doesn't allow a nil name" do - @garden = FactoryGirl.build(:garden, :name => nil) - @garden.should_not be_valid + garden = FactoryGirl.build(:garden, :name => nil) + garden.should_not be_valid end it "doesn't allow a blank name" do - @garden = FactoryGirl.build(:garden, :name => "") - @garden.should_not be_valid + garden = FactoryGirl.build(:garden, :name => "") + garden.should_not be_valid end it "doesn't allow a name with only spaces" do - @garden = FactoryGirl.build(:garden, :name => " ") - @garden.should_not be_valid + garden = FactoryGirl.build(:garden, :name => " ") + garden.should_not be_valid end it "should have an owner" do - @garden.owner.should be_an_instance_of Member + garden.owner.should be_an_instance_of Member end it "should stringify as its name" do - @garden.to_s.should == @garden.name + garden.to_s.should == garden.name end context "featured plantings" do - before :each do - @tomato = FactoryGirl.create(:tomato) - @maize = FactoryGirl.create(:maize) - @chard = FactoryGirl.create(:chard) - @apple = FactoryGirl.create(:apple) - @pear = FactoryGirl.create(:pear) - @walnut = FactoryGirl.create(:walnut) - end + + let(:tomato) { FactoryGirl.create(:tomato) } + let(:maize) { FactoryGirl.create(:maize) } + let(:chard) { FactoryGirl.create(:chard) } + let(:apple) { FactoryGirl.create(:apple) } + let(:pear) { FactoryGirl.create(:pear) } + let(:walnut) { FactoryGirl.create(:walnut) } it "should fetch < 4 featured plantings if insufficient exist" do - @p1 = FactoryGirl.create(:planting, :crop => @tomato, :garden => @garden) - @p2 = FactoryGirl.create(:planting, :crop => @maize, :garden => @garden) + @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) + @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) - @garden.featured_plantings.should eq [@p2, @p1] + garden.featured_plantings.should eq [@p2, @p1] end it "should fetch most recent 4 featured plantings" do - @p1 = FactoryGirl.create(:planting, :crop => @tomato, :garden => @garden) - @p2 = FactoryGirl.create(:planting, :crop => @maize, :garden => @garden) - @p3 = FactoryGirl.create(:planting, :crop => @chard, :garden => @garden) - @p4 = FactoryGirl.create(:planting, :crop => @apple, :garden => @garden) - @p5 = FactoryGirl.create(:planting, :crop => @walnut, :garden => @garden) + @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) + @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) + @p3 = FactoryGirl.create(:planting, :crop => chard, :garden => garden) + @p4 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) + @p5 = FactoryGirl.create(:planting, :crop => walnut, :garden => garden) - @garden.featured_plantings.should eq [@p5, @p4, @p3, @p2] + garden.featured_plantings.should eq [@p5, @p4, @p3, @p2] end it "should skip repeated plantings" do - @p1 = FactoryGirl.create(:planting, :crop => @tomato, :garden => @garden) - @p2 = FactoryGirl.create(:planting, :crop => @maize, :garden => @garden) - @p3 = FactoryGirl.create(:planting, :crop => @chard, :garden => @garden) - @p4 = FactoryGirl.create(:planting, :crop => @apple, :garden => @garden) - @p5 = FactoryGirl.create(:planting, :crop => @walnut, :garden => @garden) - @p6 = FactoryGirl.create(:planting, :crop => @apple, :garden => @garden) - @p7 = FactoryGirl.create(:planting, :crop => @pear, :garden => @garden) + @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) + @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) + @p3 = FactoryGirl.create(:planting, :crop => chard, :garden => garden) + @p4 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) + @p5 = FactoryGirl.create(:planting, :crop => walnut, :garden => garden) + @p6 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) + @p7 = FactoryGirl.create(:planting, :crop => pear, :garden => garden) - @garden.featured_plantings.should eq [@p7, @p6, @p5, @p3] + garden.featured_plantings.should eq [@p7, @p6, @p5, @p3] end end @@ -87,86 +85,85 @@ describe Garden do end it "destroys plantings when deleted" do - @garden = FactoryGirl.create(:garden, :owner => @owner) - @planting1 = FactoryGirl.create(:planting, :garden => @garden) - @planting2 = FactoryGirl.create(:planting, :garden => @garden) - @garden.plantings.length.should == 2 + garden = FactoryGirl.create(:garden, :owner => owner) + @planting1 = FactoryGirl.create(:planting, :garden => garden) + @planting2 = FactoryGirl.create(:planting, :garden => garden) + garden.plantings.length.should == 2 all = Planting.count - @garden.destroy + garden.destroy Planting.count.should == all - 2 end context 'area' do it 'allows numeric area' do - @garden = FactoryGirl.build(:garden, :area => 33) - @garden.should be_valid + garden = FactoryGirl.build(:garden, :area => 33) + garden.should be_valid end it "doesn't allow negative area" do - @garden = FactoryGirl.build(:garden, :area => -5) - @garden.should_not be_valid + garden = FactoryGirl.build(:garden, :area => -5) + garden.should_not be_valid end it 'allows decimal quantities' do - @garden = FactoryGirl.build(:garden, :area => 3.3) - @garden.should be_valid + garden = FactoryGirl.build(:garden, :area => 3.3) + garden.should be_valid end it 'allows blank quantities' do - @garden = FactoryGirl.build(:garden, :area => '') - @garden.should be_valid + garden = FactoryGirl.build(:garden, :area => '') + garden.should be_valid end it 'allows nil quantities' do - @garden = FactoryGirl.build(:garden, :area => nil) - @garden.should be_valid + garden = FactoryGirl.build(:garden, :area => nil) + garden.should be_valid end it 'cleans up zero quantities' do - @garden = FactoryGirl.build(:garden, :area => 0) - @garden.area.should == 0 + garden = FactoryGirl.build(:garden, :area => 0) + garden.area.should == 0 end it "doesn't allow non-numeric quantities" do - @garden = FactoryGirl.build(:garden, :area => "99a") - @garden.should_not be_valid + garden = FactoryGirl.build(:garden, :area => "99a") + garden.should_not be_valid end end context 'units' do Garden::AREA_UNITS_VALUES.values.push(nil, '').each do |s| it "#{s} should be a valid unit" do - @garden = FactoryGirl.build(:garden, :area_unit => s) - @garden.should be_valid + garden = FactoryGirl.build(:garden, :area_unit => s) + garden.should be_valid end end it 'should refuse invalid unit values' do - @garden = FactoryGirl.build(:garden, :area_unit => 'not valid') - @garden.should_not be_valid - @garden.errors[:area_unit].should include("not valid is not a valid area unit") + garden = FactoryGirl.build(:garden, :area_unit => 'not valid') + garden.should_not be_valid + garden.errors[:area_unit].should include("not valid is not a valid area unit") end it 'sets area unit to blank if area is blank' do - @garden = FactoryGirl.build(:garden, :area => '', :area_unit => 'acre') - @garden.should be_valid - @garden.area_unit.should eq nil + garden = FactoryGirl.build(:garden, :area => '', :area_unit => 'acre') + garden.should be_valid + garden.area_unit.should eq nil end end context 'active scopes' do - before(:each) do - @active = FactoryGirl.create(:garden) - @inactive = FactoryGirl.create(:inactive_garden) - end + + let(:active) { FactoryGirl.create(:garden) } + let(:inactive) { FactoryGirl.create(:inactive_garden) } it 'includes active garden in active scope' do - Garden.active.should include @active - Garden.active.should_not include @inactive + Garden.active.should include active + Garden.active.should_not include inactive end it 'includes inactive garden in inactive scope' do - Garden.inactive.should include @inactive - Garden.inactive.should_not include @active + Garden.inactive.should include inactive + Garden.inactive.should_not include active end end @@ -207,30 +204,32 @@ describe Garden do end context 'photos' do - before(:each) do - @garden = FactoryGirl.create(:garden) - @photo = FactoryGirl.create(:photo) - @garden.photos << @photo + + let(:garden) { FactoryGirl.create(:garden) } + let(:photo) { FactoryGirl.create(:photo) } + + before do + garden.photos << photo end it 'has a photo' do - @garden.photos.first.should eq @photo + garden.photos.first.should eq photo end it 'deletes association with photos when photo is deleted' do - @photo.destroy - @garden.reload - @garden.photos.should be_empty + photo.destroy + garden.reload + garden.photos.should be_empty end it 'has a default photo' do - @garden.default_photo.should eq @photo + garden.default_photo.should eq photo end it 'chooses the most recent photo' do @photo2 = FactoryGirl.create(:photo) - @garden.photos << @photo2 - @garden.default_photo.should eq @photo2 + garden.photos << @photo2 + garden.default_photo.should eq @photo2 end end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index cd6d5f1ef..f8e2c4f5a 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -147,12 +147,11 @@ describe Harvest do end context "stringification" do - before :each do - @crop = FactoryGirl.create(:crop, :name => "apricot") - end + + let(:crop) { FactoryGirl.create(:crop, :name => "apricot") } it "apricots" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => nil, :unit => nil, :weight_quantity => nil, @@ -162,7 +161,7 @@ describe Harvest do end it "1 individual apricot" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 1, :unit => 'individual', :weight_quantity => nil, @@ -172,7 +171,7 @@ describe Harvest do end it "10 individual apricots" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 10, :unit => 'individual', :weight_quantity => nil, @@ -182,7 +181,7 @@ describe Harvest do end it "1 bushel of apricots" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 1, :unit => 'bushel', :weight_quantity => nil, @@ -192,7 +191,7 @@ describe Harvest do end it "1.5 bushels of apricots" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 1.5, :unit => 'bushel', :weight_quantity => nil, @@ -202,7 +201,7 @@ describe Harvest do end it "10 bushels of apricots" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 10, :unit => 'bushel', :weight_quantity => nil, @@ -212,7 +211,7 @@ describe Harvest do end it "apricots weighing 1.2 kg" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => nil, :unit => nil, :weight_quantity => 1.2, @@ -222,7 +221,7 @@ describe Harvest do end it "10 bushels of apricots weighing 100 kg" do - @h = FactoryGirl.create(:harvest, :crop => @crop, + @h = FactoryGirl.create(:harvest, :crop => crop, :quantity => 10, :unit => 'bushel', :weight_quantity => 100, @@ -233,30 +232,32 @@ describe Harvest do end context 'photos' do - before(:each) do - @harvest = FactoryGirl.create(:harvest) - @photo = FactoryGirl.create(:photo) - @harvest.photos << @photo + + let(:harvest) { FactoryGirl.create(:harvest) } + let(:photo) { FactoryGirl.create(:photo) } + + before do + harvest.photos << photo end it 'has a photo' do - @harvest.photos.first.should eq @photo + harvest.photos.first.should eq photo end it 'deletes association with photos when photo is deleted' do - @photo.destroy - @harvest.reload - @harvest.photos.should be_empty + photo.destroy + harvest.reload + harvest.photos.should be_empty end it 'has a default photo' do - @harvest.default_photo.should eq @photo + harvest.default_photo.should eq photo end it 'chooses the most recent photo' do @photo2 = FactoryGirl.create(:photo) - @harvest.photos << @photo2 - @harvest.default_photo.should eq @photo2 + harvest.photos << @photo2 + harvest.default_photo.should eq @photo2 end end end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 9b0481298..b91584953 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -3,105 +3,103 @@ require 'rails_helper' describe 'member' do context 'valid member' do - before(:each) do - @member = FactoryGirl.create(:member) - end + + let(:member) { FactoryGirl.create(:member) } it 'should be fetchable from the database' do - @member2 = Member.find(@member.id) + @member2 = Member.find(member.id) @member2.should be_an_instance_of Member @member2.login_name.should match(/member\d+/) @member2.encrypted_password.should_not be_nil end it 'should have a friendly slug' do - @member.slug.should match(/member\d+/) + member.slug.should match(/member\d+/) end it 'has a bio' do - @member.bio = 'I love seeds' - @member.bio.should eq 'I love seeds' + member.bio = 'I love seeds' + member.bio.should eq 'I love seeds' end it 'should have a default garden' do - @member.gardens.count.should == 1 + member.gardens.count.should == 1 end it 'should have a accounts entry' do - @member.account.should be_an_instance_of Account + member.account.should be_an_instance_of Account end it "should have a default-type account by default" do - @member.account.account_type.name.should eq Growstuff::Application.config.default_account_type - @member.is_paid?.should be(false) + member.account.account_type.name.should eq Growstuff::Application.config.default_account_type + member.is_paid?.should be(false) end it "doesn't show email by default" do - @member.show_email.should be(false) + member.show_email.should be(false) end it 'should stringify as the login_name' do - @member.to_s.should match(/member\d+/) - "#{@member}".should match(/member\d+/) + member.to_s.should match(/member\d+/) + "#{member}".should match(/member\d+/) end it 'should be able to fetch posts' do - @post = FactoryGirl.create(:post, :author => @member) - @member.posts.should eq [@post] + @post = FactoryGirl.create(:post, :author => member) + member.posts.should eq [@post] end it 'should be able to fetch gardens' do - @member.gardens.first.name.should eq "Garden" + member.gardens.first.name.should eq "Garden" end it 'has many plantings' do - @planting = FactoryGirl.create(:planting, :owner => @member) - @member.plantings.size.should eq 1 + @planting = FactoryGirl.create(:planting, :owner => member) + member.plantings.size.should eq 1 end it "has many comments" do - @comment1 = FactoryGirl.create(:comment, :author => @member) - @comment2 = FactoryGirl.create(:comment, :author => @member) - @member.comments.length.should == 2 + @comment1 = FactoryGirl.create(:comment, :author => member) + @comment2 = FactoryGirl.create(:comment, :author => member) + member.comments.length.should == 2 end it "has many forums" do - @forum1 = FactoryGirl.create(:forum, :owner => @member) - @forum2 = FactoryGirl.create(:forum, :owner => @member) - @member.forums.length.should == 2 + @forum1 = FactoryGirl.create(:forum, :owner => member) + @forum2 = FactoryGirl.create(:forum, :owner => member) + member.forums.length.should == 2 end it 'has location and lat/long fields' do - @member.update_attributes(:location => 'Greenwich, UK') - @member.location.should eq 'Greenwich, UK' - @member.latitude.round(2).should eq 51.48 - @member.longitude.round(2).should eq 0.00 + member.update_attributes(:location => 'Greenwich, UK') + member.location.should eq 'Greenwich, UK' + member.latitude.round(2).should eq 51.48 + member.longitude.round(2).should eq 0.00 end it 'empties the lat/long if location removed' do - @member.update_attributes(:location => 'Greenwich, UK') - @member.update_attributes(:location => '') - @member.location.should eq '' - @member.latitude.should be_nil - @member.longitude.should be_nil + member.update_attributes(:location => 'Greenwich, UK') + member.update_attributes(:location => '') + member.location.should eq '' + member.latitude.should be_nil + member.longitude.should be_nil end it 'fails gracefully for unfound locations' do - @member.update_attributes(:location => 'Tatooine') - @member.location.should eq 'Tatooine' - @member.latitude.should be_nil - @member.longitude.should be_nil + member.update_attributes(:location => 'Tatooine') + member.location.should eq 'Tatooine' + member.latitude.should be_nil + member.longitude.should be_nil end end context 'no TOS agreement' do - before(:each) do - @member = FactoryGirl.build(:no_tos_member) - end + + let(:member) { FactoryGirl.build(:no_tos_member) } it "should refuse to save a member who hasn't agreed to the TOS" do - @member.save.should_not be(true) + member.save.should_not be(true) end end @@ -190,15 +188,17 @@ describe 'member' do end context 'roles' do - before(:each) do - @member = FactoryGirl.create(:member) - @role = FactoryGirl.create(:role) - @member.roles << @role + + let(:member) { FactoryGirl.create(:member) } + let(:role) { FactoryGirl.create(:role) } + + before do + member.roles << role end it 'has a role' do - @member.roles.first.should eq @role - @member.has_role?(:moderator).should eq true + member.roles.first.should eq role + member.has_role?(:moderator).should eq true end it 'sets up roles in factories' do @@ -209,8 +209,8 @@ describe 'member' do it 'converts role names properly' do # need to make sure spaces get turned to underscores @role = FactoryGirl.create(:role, :name => "a b c") - @member.roles << @role - @member.has_role?(:a_b_c).should eq true + member.roles << @role + member.has_role?(:a_b_c).should eq true end end @@ -303,73 +303,71 @@ describe 'member' do end context "paid accounts" do - before(:each) do - @member = FactoryGirl.create(:member) - end + + let(:member) { FactoryGirl.create(:member) } it "recognises a permanent paid account" do @account_type = FactoryGirl.create(:account_type, :is_paid => true, :is_permanent_paid => true) - @member.account.account_type = @account_type - @member.is_paid?.should be(true) + member.account.account_type = @account_type + member.is_paid?.should be(true) end it "recognises a current paid account" do @account_type = FactoryGirl.create(:account_type, :is_paid => true, :is_permanent_paid => false) - @member.account.account_type = @account_type - @member.account.paid_until = Time.zone.now + 1.month - @member.is_paid?.should be(true) + member.account.account_type = @account_type + member.account.paid_until = Time.zone.now + 1.month + member.is_paid?.should be(true) end it "recognises an expired paid account" do @account_type = FactoryGirl.create(:account_type, :is_paid => true, :is_permanent_paid => false) - @member.account.account_type = @account_type - @member.account.paid_until = Time.zone.now - 1.minute - @member.is_paid?.should be(false) + member.account.account_type = @account_type + member.account.paid_until = Time.zone.now - 1.minute + member.is_paid?.should be(false) end it "recognises a free account" do @account_type = FactoryGirl.create(:account_type, :is_paid => false, :is_permanent_paid => false) - @member.account.account_type = @account_type - @member.is_paid?.should be(false) + member.account.account_type = @account_type + member.is_paid?.should be(false) end it "recognises a free account even with paid_until set" do @account_type = FactoryGirl.create(:account_type, :is_paid => false, :is_permanent_paid => false) - @member.account.account_type = @account_type - @member.account.paid_until = Time.zone.now + 1.month - @member.is_paid?.should be(false) + member.account.account_type = @account_type + member.account.paid_until = Time.zone.now + 1.month + member.is_paid?.should be(false) end end context "update account" do - before(:each) do - @product = FactoryGirl.create(:product, - :paid_months => 3 - ) - @member = FactoryGirl.create(:member) - end + + let(:product) { FactoryGirl.create(:product, + :paid_months => 3 + )} + let(:member) { FactoryGirl.create(:member) } it "sets account_type" do - @member.update_account_after_purchase(@product) - @member.account.account_type.should eq @product.account_type + member.update_account_after_purchase(product) + member.account.account_type.should eq product.account_type end it "sets paid_until" do - @member.account.paid_until = nil # blank for now, as if never paid before - @member.update_account_after_purchase(@product) + member.account.paid_until = nil # blank for now, as if never paid before + member.update_account_after_purchase(product) # stringify to avoid millisecond problems... - @member.account.paid_until.to_s.should eq (Time.zone.now + 3.months).to_s + member.account.paid_until.to_s.should eq (Time.zone.now + 3.months).to_s # and again to make sure it works for currently paid accounts - @member.update_account_after_purchase(@product) - @member.account.paid_until.to_s.should eq (Time.zone.now + 3.months + 3.months).to_s + member.update_account_after_purchase(product) + member.account.paid_until.to_s.should eq (Time.zone.now + 3.months + 3.months).to_s end end @@ -382,30 +380,33 @@ describe 'member' do end context 'member who followed another member' do - before(:each) do - @member1 = FactoryGirl.create(:member) - @member2 = FactoryGirl.create(:member) - @member3 = FactoryGirl.create(:member) - @follow = @member1.follows.create(:follower_id => @member1.id, :followed_id => @member2.id) + + + let(:member1) { FactoryGirl.create(:member) } + let(:member2) { FactoryGirl.create(:member) } + let(:member3) { FactoryGirl.create(:member) } + + before do + @follow = member1.follows.create(:follower_id => member1.id, :followed_id => member2.id) end context 'already_following' do it 'detects that member is already following a member' do - expect(@member1.already_following?(@member2)).to eq true + expect(member1.already_following?(member2)).to eq true end it 'detects that member is not already following a member' do - expect(@member1.already_following?(@member3)).to eq false + expect(member1.already_following?(member3)).to eq false end end context 'get_follow' do it 'gets the correct follow for a followed member' do - expect(@member1.get_follow(@member2).id).to eq @follow.id + expect(member1.get_follow(member2).id).to eq @follow.id end it 'returns nil for a member that is not followed' do - expect(@member1.get_follow(@member3)).to be_nil + expect(member1.get_follow(member3)).to be_nil end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index 27924ebed..d14f731d1 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -1,32 +1,31 @@ require 'rails_helper' describe Notification do - before(:each) do - @notification = FactoryGirl.create(:notification) - end + + let(:notification) { FactoryGirl.create(:notification) } it "belongs to a post" do - @notification.post.should be_an_instance_of Post + notification.post.should be_an_instance_of Post end it "belongs to a recipient" do - @notification.recipient.should be_an_instance_of Member + notification.recipient.should be_an_instance_of Member end it "belongs to a sender" do - @notification.sender.should be_an_instance_of Member + notification.sender.should be_an_instance_of Member end it "has a scope for unread" do - Notification.unread.should eq [@notification] + Notification.unread.should eq [notification] @n2 = FactoryGirl.create(:notification, :read => true) - Notification.unread.should eq [@notification] + Notification.unread.should eq [notification] @n3 = FactoryGirl.create(:notification, :read => false) - Notification.unread.should eq [@n3, @notification] + Notification.unread.should eq [@n3, notification] end it "counts unread" do - @who = @notification.recipient + @who = notification.recipient @n2 = FactoryGirl.create(:notification, :recipient => @who, :read => false) @who.notifications.unread_count.should eq 2 end @@ -38,9 +37,9 @@ describe Notification do end it "doesn't send email to people who don't want it" do - @notification = FactoryGirl.create(:no_email_notification) - @notification.send_email - ActionMailer::Base.deliveries.last.to.should_not == [@notification.recipient.email] + notification = FactoryGirl.create(:no_email_notification) + notification.send_email + ActionMailer::Base.deliveries.last.to.should_not == [notification.recipient.email] end it "sends email on creation" do @@ -49,13 +48,13 @@ describe Notification do end it "replaces missing subjects with (no subject)" do - @notification = FactoryGirl.create(:notification, :subject => nil) - @notification.subject.should == "(no subject)" + notification = FactoryGirl.create(:notification, :subject => nil) + notification.subject.should == "(no subject)" end it "replaces whitespace-only subjects with (no subject)" do - @notification = FactoryGirl.create(:notification, :subject => " ") - @notification.subject.should == "(no subject)" + notification = FactoryGirl.create(:notification, :subject => " ") + notification.subject.should == "(no subject)" end end diff --git a/spec/models/order_item_spec.rb b/spec/models/order_item_spec.rb index 20c0be94f..bd3b8f195 100644 --- a/spec/models/order_item_spec.rb +++ b/spec/models/order_item_spec.rb @@ -1,27 +1,26 @@ require 'rails_helper' describe OrderItem do - before(:each) do - @order_item = FactoryGirl.create(:order_item) - end + + let(:order_item) { FactoryGirl.create(:order_item) } it "has an order and a product" do - @order_item.order.should be_an_instance_of Order - @order_item.product.should be_an_instance_of Product + order_item.order.should be_an_instance_of Order + order_item.product.should be_an_instance_of Product end it "validates price > product.min_price" do @product = FactoryGirl.create(:product) - @order_item = FactoryGirl.build(:order_item, :price => @product.min_price - 1) - @order_item.should_not be_valid + order_item = FactoryGirl.build(:order_item, :price => @product.min_price - 1) + order_item.should_not be_valid end it "doesn't let you add two items to an order" do @product = FactoryGirl.create(:product) @order = FactoryGirl.create(:order) - @order_item = FactoryGirl.build(:order_item, :order => @order) - @order_item.should be_valid - @order_item.save + order_item = FactoryGirl.build(:order_item, :order => @order) + order_item.should be_valid + order_item.save @order_item2 = FactoryGirl.build(:order_item, :order => @order) @order_item2.should_not be_valid end diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index fba4fabe1..16bb8b613 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -2,26 +2,24 @@ require 'rails_helper' describe Planting do - before(:each) do - @crop = FactoryGirl.create(:tomato) - @garden_owner = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @garden_owner) - @planting = FactoryGirl.create(:planting, - :crop => @crop, :garden => @garden) - end + let(:crop) { FactoryGirl.create(:tomato) } + let(:garden_owner) { FactoryGirl.create(:member) } + let(:garden) { FactoryGirl.create(:garden, :owner => garden_owner) } + let(:planting) { FactoryGirl.create(:planting, + :crop => crop, :garden => garden)} it 'has an owner' do - @planting.owner.should be_an_instance_of Member + planting.owner.should be_an_instance_of Member end it "owner isn't necessarily the garden owner" do # a new owner should be created automatically by FactoryGirl # note that formerly, the planting belonged to an owner through the garden - @planting.owner.should_not eq @garden_owner + planting.owner.should_not eq garden_owner end it "generates a location" do - @planting.location.should eq "#{@garden_owner.login_name}'s #{@garden.name}" + planting.location.should eq "#{garden_owner.login_name}'s #{garden.name}" end it "sorts plantings in descending order of creation" do @@ -31,7 +29,7 @@ describe Planting do end it "should have a slug" do - @planting.slug.should match /^member\d+-springfield-community-garden-tomato$/ + planting.slug.should match /^member\d+-springfield-community-garden-tomato$/ end it 'should sort in reverse creation order' do @@ -41,16 +39,16 @@ describe Planting do context 'delegation' do it 'system name' do - @planting.crop_name.should eq @planting.crop.name + planting.crop_name.should eq planting.crop.name end it 'wikipedia url' do - @planting.crop_en_wikipedia_url.should eq @planting.crop.en_wikipedia_url + planting.crop_en_wikipedia_url.should eq planting.crop.en_wikipedia_url end it 'default scientific name' do - @planting.crop_default_scientific_name.should eq @planting.crop.default_scientific_name + planting.crop_default_scientific_name.should eq planting.crop.default_scientific_name end it 'plantings count' do - @planting.crop_plantings_count.should eq @planting.crop.plantings_count + planting.crop_plantings_count.should eq planting.crop.plantings_count end end @@ -79,12 +77,11 @@ describe Planting do end context 'sunniness' do - before(:each) do - @planting = FactoryGirl.create(:sunny_planting) - end + + let(:planting) { FactoryGirl.create(:sunny_planting) } it 'should have a sunniness value' do - @planting.sunniness.should eq 'sun' + planting.sunniness.should eq 'sun' end it 'all three valid sunniness values should work' do @@ -126,30 +123,32 @@ describe Planting do # we decided that all the tests for the planting/photo association would # be done on this side, not on the photos side context 'photos' do - before(:each) do - @planting = FactoryGirl.create(:planting) - @photo = FactoryGirl.create(:photo) - @planting.photos << @photo + + let(:planting) { FactoryGirl.create(:planting) } + let(:photo) { FactoryGirl.create(:photo) } + + before do + planting.photos << photo end it 'has a photo' do - @planting.photos.first.should eq @photo + planting.photos.first.should eq photo end it 'deletes association with photos when photo is deleted' do - @photo.destroy - @planting.reload - @planting.photos.should be_empty + photo.destroy + planting.reload + planting.photos.should be_empty end it 'has a default photo' do - @planting.default_photo.should eq @photo + planting.default_photo.should eq photo end it 'chooses the most recent photo' do @photo2 = FactoryGirl.create(:photo) - @planting.photos << @photo2 - @planting.default_photo.should eq @photo2 + planting.photos << @photo2 + planting.default_photo.should eq @photo2 end end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index adce855d2..cb9324d3f 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -1,43 +1,42 @@ require 'rails_helper' describe Post do - before(:each) do - @member = FactoryGirl.create(:member) - end + + let(:member) { FactoryGirl.create(:member) } it "should be sorted in reverse order" do FactoryGirl.create(:post, :subject => 'first entry', - :author => @member, + :author => member, :created_at => 2.days.ago ) FactoryGirl.create(:post, :subject => 'second entry', - :author => @member, + :author => member, :created_at => 1.day.ago ) Post.first.subject.should == "second entry" end it "should have a slug" do - @post = FactoryGirl.create(:post, :author => @member) + @post = FactoryGirl.create(:post, :author => member) @time = @post.created_at @datestr = @time.strftime("%Y%m%d") # 2 digit day and month, full-length years # Counting digits using Math.log is not precise enough! @datestr.length.should == 4 + @time.year.to_s.size - @post.slug.should == "#{@member.login_name}-#{@datestr}-a-post" + @post.slug.should == "#{member.login_name}-#{@datestr}-a-post" end it "has many comments" do - @post = FactoryGirl.create(:post, :author => @member) + @post = FactoryGirl.create(:post, :author => member) @comment1 = FactoryGirl.create(:comment, :post => @post) @comment2 = FactoryGirl.create(:comment, :post => @post) @post.comments.length.should == 2 end it "destroys comments when deleted" do - @post = FactoryGirl.create(:post, :author => @member) + @post = FactoryGirl.create(:post, :author => member) @comment1 = FactoryGirl.create(:comment, :post => @post) @comment2 = FactoryGirl.create(:comment, :post => @post) @post.comments.length.should == 2 @@ -67,19 +66,21 @@ describe Post do end context "recent activity" do - before(:each) do + + before do Time.stub(:now => Time.now) - @post = FactoryGirl.create(:post, :created_at => 1.day.ago) end + + let(:post) { FactoryGirl.create(:post, :created_at => 1.day.ago) } it "sets recent activity to post time" do - @post.recent_activity.to_i.should eq @post.created_at.to_i + post.recent_activity.to_i.should eq post.created_at.to_i end it "sets recent activity to comment time" do - @comment = FactoryGirl.create(:comment, :post => @post, + @comment = FactoryGirl.create(:comment, :post => post, :created_at => 1.hour.ago) - @post.recent_activity.to_i.should eq @comment.created_at.to_i + post.recent_activity.to_i.should eq @comment.created_at.to_i end it "shiny new post is recently active" do @@ -90,8 +91,8 @@ describe Post do it "new comment on old post is recently active" do # now comment on an older post - @comment2 = FactoryGirl.create(:comment, :post => @post, :created_at => 1.second.ago) - Post.recently_active.first.should eq @post + @comment2 = FactoryGirl.create(:comment, :post => post, :created_at => 1.second.ago) + Post.recently_active.first.should eq post end end diff --git a/spec/models/scientific_name_spec.rb b/spec/models/scientific_name_spec.rb index 020f1cc0d..e506acccf 100644 --- a/spec/models/scientific_name_spec.rb +++ b/spec/models/scientific_name_spec.rb @@ -3,30 +3,28 @@ require 'rails_helper' describe ScientificName do context 'all fields present' do - before(:each) do - @sn = FactoryGirl.create(:zea_mays) - end + let(:sn) { FactoryGirl.create(:zea_mays) } it 'should save a basic scientific name' do - @sn.save.should be(true) + sn.save.should be(true) end it 'should be fetchable from the database' do - @sn.save + sn.save @sn2 = ScientificName.find_by_scientific_name('Zea mays') @sn2.crop.name.should == 'maize' end it 'has a creator' do - @sn.save - @sn.creator.should be_an_instance_of Member + sn.save + sn.creator.should be_an_instance_of Member end end context 'invalid data' do it 'should not save a scientific name without a name' do - @sn = ScientificName.new - expect { @sn.save }.to raise_error ActiveRecord::StatementInvalid + sn = ScientificName.new + expect { sn.save }.to raise_error ActiveRecord::StatementInvalid end end end diff --git a/spec/models/seed_spec.rb b/spec/models/seed_spec.rb index 747dbee71..58ae56ea7 100644 --- a/spec/models/seed_spec.rb +++ b/spec/models/seed_spec.rb @@ -2,17 +2,15 @@ require 'rails_helper' describe Seed do - before(:each) do - @seed = FactoryGirl.build(:seed) - end + let(:seed) { FactoryGirl.build(:seed) } it 'should save a basic seed' do - @seed.save.should be(true) + seed.save.should be(true) end it "should have a slug" do - @seed.save - @seed.slug.should match(/member\d+-magic-bean/) + seed.save + seed.slug.should match(/member\d+-magic-bean/) end context 'quantity' do From 23dbfea05aeb5a163e08672f9fc16d309b199515 Mon Sep 17 00:00:00 2001 From: Cjay Date: Thu, 9 Jul 2015 07:06:21 +0800 Subject: [PATCH 113/392] Fix spec/models/ability_spec.rb - Changed notification into a variable scope - Removed let(:cw_ability) and let(:admin_ability) and just used ability --- spec/models/ability_spec.rb | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 7c3f895c2..6a054083b 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -8,9 +8,8 @@ describe Ability do context "notifications" do - let(:notification) { FactoryGirl.create(:notification, :recipient => member) } - it 'member can view their own notifications' do + notification = FactoryGirl.create(:notification, :recipient => member) ability.should be_able_to(:read, notification) end @@ -65,8 +64,6 @@ describe Ability do member.roles << role end - let(:ability) { Ability.new(member) } - it "has crop_wrangler role" do member.has_role?(:crop_wrangler).should be true end @@ -105,8 +102,6 @@ describe Ability do member.roles << role end - let(:ability) { Ability.new(member) } - it "has admin role" do member.has_role?(:admin).should be true end @@ -225,8 +220,6 @@ describe Ability do member.roles << role end - let(:ability) { Ability.new(member) } - it "has admin role" do member.has_role?(:admin).should be true end @@ -273,8 +266,6 @@ describe Ability do member.roles << role end - let(:ability) { Ability.new(member) } - it "can read account details" do ability.should be_able_to(:read, account) end @@ -311,8 +302,6 @@ describe Ability do member.roles << role end - let(:ability) { Ability.new(member) } - it "can read plant_part details" do ability.should be_able_to(:read, plant_part) end From b9a29115a2db865cb6cac09a8e0a6d35f237e933 Mon Sep 17 00:00:00 2001 From: Jace Monje Date: Thu, 9 Jul 2015 07:14:49 +0800 Subject: [PATCH 114/392] new navbar --- app/views/layouts/_header.html.haml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 80ba2637b..ac324ab91 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -10,8 +10,14 @@ %span.icon-bar %a.navbar-brand(href=root_path) = image_tag("growstuff-brand.png", :size => "200x50", :alt => ENV['GROWSTUFF_SITE_NAME']) + = form_tag crops_search_path, :method => :get, :id => 'navbar-search', :class => 'navbar-form pull-right' do + .input + = label_tag :term, "Search crop database:", :class => 'sr-only' + = text_field_tag 'term', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops' + = submit_tag "Search", :class => 'btn sr-only' + .navbar-collapse.collapse#navbar-collapse - %ul.nav.navbar-nav + %ul.nav.navbar-nav.pull-right %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => crops_path} Crops @@ -30,7 +36,7 @@ %li= link_to "Browse Members", members_path %li= link_to "Posts", posts_path %li= link_to "Forums", forums_path - + %li= link_to "Support Growstuff", shop_path - if member_signed_in? %li.dropdown< @@ -38,7 +44,7 @@ - if current_member.notifications.unread_count > 0 Your Stuff (#{current_member.notifications.unread_count}) - else - Your Stuff + #{current_member.login_name} %b.caret %ul.dropdown-menu %li= link_to "Profile", member_path(current_member) @@ -59,7 +65,6 @@ %li= link_to "Crop Wrangling", wrangle_crops_path - if current_member.has_role?(:admin) %li= link_to "Admin", admin_path - %li= link_to "Support Growstuff", shop_path %li= link_to "Sign out", destroy_member_session_path, :method => :delete @@ -68,11 +73,6 @@ %li= link_to 'Sign in', new_member_session_path, :id => 'navbar-signin' %li= link_to 'Sign up', new_member_registration_path, :id => 'navbar-signup' - = form_tag crops_search_path, :method => :get, :id => 'navbar-search', :class => 'navbar-form pull-right' do - .input - = label_tag :term, "Search crop database:", :class => 'sr-only' - = text_field_tag 'term', nil, :class => 'search-query input-medium form-control', :placeholder => 'Search crops' - = submit_tag "Search", :class => 'btn sr-only' - # anchor tag for accessibility link to skip the navigation menu %a{:name => 'skipnav'} From 7232f4614c6e191b5a7557de5eb9d514aed7d560 Mon Sep 17 00:00:00 2001 From: Jace Monje Date: Thu, 9 Jul 2015 07:30:47 +0800 Subject: [PATCH 115/392] refactored tests fixed tests --- spec/features/following_spec.rb | 2 +- spec/views/layouts/_header_spec.rb | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/features/following_spec.rb b/spec/features/following_spec.rb index 891a38b02..31eb771ac 100644 --- a/spec/features/following_spec.rb +++ b/spec/features/following_spec.rb @@ -80,7 +80,7 @@ feature "follows", :js => true do visit member_follows_path(member) expect(page).not_to have_content "#{other_member.login_name}" visit member_followers_path(other_member) - expect(page).not_to have_content "#{member.login_name}" + expect(page).to have_content "#{current_member.login_name}" end end diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index 30ea0c7ef..c7fabfc13 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -1,13 +1,13 @@ ## DEPRECATION NOTICE: Do not add new tests to this file! ## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. ## -## If you submit a pull request containing new view or controller tests, it will not be +## If you submit a pull request containing new view or controller tests, it will not be ## merged. @@ -76,9 +76,9 @@ describe 'layouts/_header.html.haml', :type => "view" do render end - context "your stuff" do - it 'should have a Your Stuff section' do - rendered.should have_content "Your Stuff" + context "login name" do + it 'should have member login name' do + rendered.should have_content "#{current_member.login_name}" end it "should show link to member's gardens" do assert_select("a[href=#{gardens_by_owner_path(:owner => @member.slug)}]", "Gardens") From d4d210447a7b27715e1dcd509007eb4207bf3e2a Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 9 Jul 2015 00:47:11 +0100 Subject: [PATCH 116/392] Set staging secret key from environment --- config/secrets.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/secrets.yml b/config/secrets.yml index 4fc7f3b37..0337fd547 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -8,10 +8,13 @@ development: secret_key_base: 'b1b67abb399261478f4721e704eb3851466daf60d9cd2b53a1839b056d641c4c1c2a476bcaf7addc6d6548926cfd32fa5a00a8de258880257ebb5a6fd86cb08f' # run 'rake secret' to generate your own - + test: secret_key_base: 'be557aa019b181f201c9906663dbf8f22efb1b70b11f78035bfeda86aa7dcfd1efb184e2ee894a0ae0dc37fe67d311f38e7731fa16d8d595f2e1ef5447bae020' # run 'rake secret' to generate your own - + +staging: + secret_key_base: <%= ENV["RAILS_SECRET_TOKEN"] %> + production: secret_key_base: <%= ENV["RAILS_SECRET_TOKEN"] %> From fa0cb55789681f209ec826562d549b855ac37db4 Mon Sep 17 00:00:00 2001 From: Jace Monje Date: Thu, 9 Jul 2015 08:01:58 +0800 Subject: [PATCH 117/392] fixed errors in tests --- spec/features/following_spec.rb | 2 +- spec/views/layouts/_header_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/following_spec.rb b/spec/features/following_spec.rb index 31eb771ac..9654bfa4c 100644 --- a/spec/features/following_spec.rb +++ b/spec/features/following_spec.rb @@ -80,7 +80,7 @@ feature "follows", :js => true do visit member_follows_path(member) expect(page).not_to have_content "#{other_member.login_name}" visit member_followers_path(other_member) - expect(page).to have_content "#{current_member.login_name}" + expect(page).to have_content "#{member.login_name}" end end diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index c7fabfc13..94930bc31 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -78,7 +78,7 @@ describe 'layouts/_header.html.haml', :type => "view" do context "login name" do it 'should have member login name' do - rendered.should have_content "#{current_member.login_name}" + rendered.should have_content "#{@member.login_name}" end it "should show link to member's gardens" do assert_select("a[href=#{gardens_by_owner_path(:owner => @member.slug)}]", "Gardens") From 28ac7ff88680abc490bf50d5861bd4a68fa3a6e7 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 9 Jul 2015 01:06:39 +0100 Subject: [PATCH 118/392] Remove one-off tasks that were run for Release 8. The ElasticSearch index task was run, but failed because we didn't have an ElasticSearch instance to run it against. --- script/deploy-tasks.sh | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index e8461294c..b225b1f6e 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -10,17 +10,5 @@ # echo "YYYY-MM-DD - do something or other" # rake growstuff:oneoff:something -echo "2014-12-01 - load lots of new crops" -rake growstuff:import_crops file=db/seeds/crops-12-mint.csv -rake growstuff:import_crops file=db/seeds/crops-13-brassicas.csv -rake growstuff:import_crops file=db/seeds/crops-14-london-workingbee.csv -rake growstuff:import_crops file=db/seeds/crops-15-squashes.csv - -echo "2014-12-01 - load alternate names for crops" -rake growstuff:oneoff:add_alternate_names - -echo "2015-01-28 - populate the harvest si_weight field" -rake growstuff:oneoff:populate_si_weight - echo "2015-01-30 - build Elasticsearch index" rake growstuff:oneoff:elasticsearch_create_index From 4e7b0cf698d60593e71fd75c7fc1222166e06ff0 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Thu, 9 Jul 2015 02:26:48 +0200 Subject: [PATCH 119/392] Remove img-rounded --- app/views/members/_avatar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index f2aaca79a..03c893f51 100644 --- a/app/views/members/_avatar.html.haml +++ b/app/views/members/_avatar.html.haml @@ -5,5 +5,5 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => '', | - :class => 'img img-responsive avatar img-rounded' ),| + :class => 'img img-responsive avatar' ),| member_path(member) From a27d273978c647e27f91b74dbc8f36462b042f54 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Thu, 9 Jul 2015 02:27:07 +0200 Subject: [PATCH 120/392] Remove 'img-rounded' --- app/views/members/_image_with_popover.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_image_with_popover.html.haml b/app/views/members/_image_with_popover.html.haml index f15674c67..fb9caddfc 100644 --- a/app/views/members/_image_with_popover.html.haml +++ b/app/views/members/_image_with_popover.html.haml @@ -5,7 +5,7 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => member.login_name, | - :class => 'img-responsive member-image img-rounded' | + :class => 'img-responsive member-image' | ), | member, | :rel => "popover", | From 1568f4b7d80c8a3ab25579c011d018e4b1d09397 Mon Sep 17 00:00:00 2001 From: Korab Hoxha Date: Thu, 9 Jul 2015 12:14:37 +0200 Subject: [PATCH 121/392] Update _avatar.html.haml --- app/views/members/_avatar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index 03c893f51..1c265ed14 100644 --- a/app/views/members/_avatar.html.haml +++ b/app/views/members/_avatar.html.haml @@ -5,5 +5,5 @@ :size => defined?(size) ? size : 150, | :default => :identicon }), | :alt => '', | - :class => 'img img-responsive avatar' ),| + :class => 'img img-responsive avatar' ), | member_path(member) From 20219e23dcb40af492ed8ced4cc1991f2bbb1572 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 9 Jul 2015 12:09:30 +0800 Subject: [PATCH 122/392] Added sunniness icons on plantings/_thumbnail and show page --- app/assets/images/sunniness_not specified.png | Bin 0 -> 7626 bytes app/assets/images/sunniness_semi-shade.png | Bin 0 -> 47082 bytes app/assets/images/sunniness_shade.png | Bin 0 -> 22816 bytes app/assets/images/sunniness_sun.png | Bin 0 -> 6257 bytes app/helpers/plantings_helper.rb | 4 ---- app/views/plantings/_thumbnail.html.haml | 5 ++++- app/views/plantings/show.html.haml | 12 +++++++----- spec/views/plantings/show.html.haml_spec.rb | 8 -------- 8 files changed, 11 insertions(+), 18 deletions(-) create mode 100644 app/assets/images/sunniness_not specified.png create mode 100644 app/assets/images/sunniness_semi-shade.png create mode 100644 app/assets/images/sunniness_shade.png create mode 100644 app/assets/images/sunniness_sun.png diff --git a/app/assets/images/sunniness_not specified.png b/app/assets/images/sunniness_not specified.png new file mode 100644 index 0000000000000000000000000000000000000000..eccba665a1464147e78bf94089642ab9a1ee3fe1 GIT binary patch literal 7626 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/sunniness_semi-shade.png b/app/assets/images/sunniness_semi-shade.png new file mode 100644 index 0000000000000000000000000000000000000000..1ec69cc5bea7e2fe973739c7417cd7795c88a3b7 GIT binary patch literal 47082 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 A8vp?RQa!e%&AqmNtW2jV% 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 literal 0 HcmV?d00001 diff --git a/app/assets/images/sunniness_sun.png b/app/assets/images/sunniness_sun.png new file mode 100644 index 0000000000000000000000000000000000000000..f1248651ab3ae508c7489bd6196238ab521a5662 GIT binary patch literal 6257 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 J0u#6J{{ZcUVy*xH literal 0 HcmV?d00001 diff --git a/app/helpers/plantings_helper.rb b/app/helpers/plantings_helper.rb index 62d96be88..fb6e2e7dc 100644 --- a/app/helpers/plantings_helper.rb +++ b/app/helpers/plantings_helper.rb @@ -22,10 +22,6 @@ module PlantingsHelper end end - def display_sunniness(planting) - !planting.sunniness.blank? ? planting.sunniness : "not specified" - end - def display_planted_from(planting) !planting.planted_from.blank? ? planting.planted_from : "not specified" end diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 2cebfcbd7..e21da7f27 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -16,7 +16,10 @@ %dt Finished on: %dd= "#{display_finished(planting)}" %dt Sun/shade?: - %dd= "#{display_sunniness(planting)}" + %dd + - sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness + = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") + = " (#{sunniness})" %dt Planted from: %dd= "#{display_planted_from(planting)}" .col-md-2 diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 127507104..b56e1f38c 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -28,11 +28,13 @@ = "Planted from: " = "#{display_planted_from(@planting)}" - - if !@planting.sunniness.blank? - %p - %b - = "Sun or shade?: " - = "#{display_sunniness(@planting)}" + %p + %b + = "Sun or shade?: " + - sunniness = @planting.sunniness.blank? ? "not specified" : @planting.sunniness + = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") + = " (#{sunniness})" + %p %b = "Days until maturity: " diff --git a/spec/views/plantings/show.html.haml_spec.rb b/spec/views/plantings/show.html.haml_spec.rb index 09fc18eed..d0eed00ac 100644 --- a/spec/views/plantings/show.html.haml_spec.rb +++ b/spec/views/plantings/show.html.haml_spec.rb @@ -44,14 +44,6 @@ describe "plantings/show" do rendered.should have_content 'Sun or shade?' rendered.should have_content 'sun' end - - it "doesn't show sunniness if blank" do - @p.sunniness = '' - @p.save - render - rendered.should_not have_content 'Sun or shade?' - rendered.should_not have_content 'sun' - end end context 'planted from' do From 0407df880bda828374d31c695dc2435a2c3d454a Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 9 Jul 2015 12:30:37 +0800 Subject: [PATCH 123/392] Added feature tests for sunniness icons for plantings page. --- .../plantings/planting_a_crop_spec.rb | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 0a6663b30..531a08b73 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -206,6 +206,41 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Progress: 100%" end + describe "Planting sunniness" do + it "should show the image sunniness_sun.png" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-10-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + select "sun", :from => "Sun or shade?" + fill_in "Tell us more about it", :with => "It's rad." + check "Mark as finished" + click_button "Save" + end + + expect(page).to have_css("img[src*='sunniness_sun.png']") + page.should have_css("img[alt=sun]") + end + + it "should show the image 'not specified.png'" do + fill_autocomplete "crop", :with => "mai" + select_from_autocomplete "maize" + within "form#new_planting" do + fill_in "When", :with => "2015-10-15" + fill_in "How many?", :with => 42 + select "cutting", :from => "Planted from:" + fill_in "Tell us more about it", :with => "It's rad." + check "Mark as finished" + click_button "Save" + end + + expect(page).to have_css("img[src*='sunniness_not specified.png']") + page.should have_css("img[alt='not specified']") + end + end + describe "Marking a planting as finished from the show page" do let(:path) { planting_path(planting) } let(:link_text) { "Mark as finished" } From f73bb81eb681c7075e895afd90b04c5362173648 Mon Sep 17 00:00:00 2001 From: gabrielsandoval Date: Thu, 9 Jul 2015 21:23:24 +0800 Subject: [PATCH 124/392] Made sunniness icons transparent --- Gemfile.lock | 3 +++ app/assets/images/sunniness_not specified.png | Bin 7626 -> 6384 bytes app/assets/images/sunniness_semi-shade.png | Bin 47082 -> 14864 bytes app/assets/images/sunniness_shade.png | Bin 22816 -> 9501 bytes app/assets/images/sunniness_sun.png | Bin 6257 -> 6019 bytes 5 files changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index fef7b8258..7e3b4aa92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,3 +458,6 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) + +BUNDLED WITH + 1.10.3 diff --git a/app/assets/images/sunniness_not specified.png b/app/assets/images/sunniness_not specified.png index eccba665a1464147e78bf94089642ab9a1ee3fe1..e4374bf2cf374b64705365365d6c04cb791a5d94 100644 GIT binary patch literal 6384 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 literal 7626 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 diff --git a/app/assets/images/sunniness_semi-shade.png b/app/assets/images/sunniness_semi-shade.png index 1ec69cc5bea7e2fe973739c7417cd7795c88a3b7..46a849b648f090177fde1b065ebea1d279cab49b 100644 GIT binary patch literal 14864 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 literal 47082 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" + + index = 2 + + $('#add-crop-row').click -> + compiled_input = $(template.split("INDEX").join(index)) + $('#someform').append(compiled_input) + console.log("Added %d", index) + index = index + 1 + + $('#remove-crop-row').click -> + if (index != 0) + index = index - 1 + tmp = 'template[' + index + ']' + element = document.getElementById(tmp) + element.remove() + console.log("Removed %s", tmp) \ No newline at end of file diff --git a/app/views/alternate_names/_form.html.haml b/app/views/alternate_names/_form.html.haml index 05dbc0133..01b99eba3 100644 --- a/app/views/alternate_names/_form.html.haml +++ b/app/views/alternate_names/_form.html.haml @@ -16,10 +16,7 @@ = f.label :crop_id, :class => 'control-label col-md-2' .col-md-8 = collection_select(:alternate_name, :crop_id, Crop.all, :id, :name, { :selected => @alternate_name.crop_id || @crop.id }, :class => 'form-control') - .form-group - = f.label :name, :class => 'control-label col-md-2' - .col-md-8 - = f.text_field :name, :class => 'form-control' + .form-group .form-actions.col-md-offset-2.col-md-8 - = f.submit 'Save', :class => 'btn btn-primary' + = f.submit 'Save', :class => 'btn btn-primary' \ No newline at end of file diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index 867239c0f..807809786 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -44,19 +44,19 @@ -# Everyone (wranglers and requesters) gets to add scientific names - %h2 Scientific names - %p You may enter up to 3 scientific names for a crop. Most crops will have only one. + %h2 + Scientific names + = button_tag "+", :id => "add-crop-row", :type => "button" + = button_tag "-", :id => "remove-crop-row", :type => "button" + + .form-group + = label_tag :alternate_names, "Alternate name 1:", :class => 'control-label col-md-2' + .col-md-8 + .form-group + = text_field_tag :name, nil, :id => 'alt_name[1]', :class => 'form-control' + %span.help-block Alternate name of crop. - = f.fields_for :scientific_names do |sn| - .form-group - = sn.label :scientific_name, "Scientific name", :class => 'control-label col-md-2' - .col-md-8 - = sn.text_field :scientific_name, :class => 'form-control' - .col-md-2 - - if sn.object && sn.object.persisted? - %label.checkbox - = sn.check_box :_destroy - = sn.label :_destroy, "Delete" + .form-group#someform -# This is used for comments from crop requesters. We need to show it -# to everyone, but we don't include it on new crops from wranglers. From 472acd0e815d3f524c52c854b95827f37de24bf0 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Mon, 13 Jul 2015 11:50:21 +0800 Subject: [PATCH 145/392] Polished UI of added forms for alternate names --- app/assets/javascripts/seeds.js.coffee | 6 +++--- app/views/crops/_form.html.haml | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/seeds.js.coffee b/app/assets/javascripts/seeds.js.coffee index b6a6aefce..8db6c0a3f 100644 --- a/app/assets/javascripts/seeds.js.coffee +++ b/app/assets/javascripts/seeds.js.coffee @@ -6,7 +6,7 @@ jQuery -> $('.add-datepicker').datepicker('format' : 'yyyy-mm-dd') $ -> - template = "
Alternate name of crop.
" + template = "
Alternate name of crop.
" index = 2 @@ -17,9 +17,9 @@ $ -> index = index + 1 $('#remove-crop-row').click -> - if (index != 0) + if (index > 2) index = index - 1 tmp = 'template[' + index + ']' element = document.getElementById(tmp) element.remove() - console.log("Removed %s", tmp) \ No newline at end of file + console.log("Removed %s", tmp) diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index 807809786..09dafa756 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -49,14 +49,14 @@ = button_tag "+", :id => "add-crop-row", :type => "button" = button_tag "-", :id => "remove-crop-row", :type => "button" - .form-group - = label_tag :alternate_names, "Alternate name 1:", :class => 'control-label col-md-2' - .col-md-8 - .form-group + .form-group#someform + .template.col-md-12 + .col-md-2 + = label_tag :alternate_names, "Alternate name 1:", :class => 'control-label' + .col-md-8 = text_field_tag :name, nil, :id => 'alt_name[1]', :class => 'form-control' %span.help-block Alternate name of crop. - - .form-group#someform + .col-md-2 -# This is used for comments from crop requesters. We need to show it -# to everyone, but we don't include it on new crops from wranglers. From 12d151b68c18801513d8071c403a6fa7f6837dc3 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Mon, 13 Jul 2015 14:00:08 +0800 Subject: [PATCH 146/392] Added multiple forms for scientific and alternate names on crop creation --- app/assets/javascripts/seeds.js.coffee | 39 ++++++++++++++++++-------- app/controllers/crops_controller.rb | 32 +++++++++++++++++---- app/models/crop.rb | 2 +- app/views/crops/_form.html.haml | 38 +++++++++++++++++-------- 4 files changed, 81 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/seeds.js.coffee b/app/assets/javascripts/seeds.js.coffee index 8db6c0a3f..339d7422b 100644 --- a/app/assets/javascripts/seeds.js.coffee +++ b/app/assets/javascripts/seeds.js.coffee @@ -6,20 +6,35 @@ jQuery -> $('.add-datepicker').datepicker('format' : 'yyyy-mm-dd') $ -> - template = "
Alternate name of crop.
" + sci_template = "
Scientific name of crop.
" - index = 2 + sci_index = $('#scientific_names .template').length + 1 - $('#add-crop-row').click -> - compiled_input = $(template.split("INDEX").join(index)) - $('#someform').append(compiled_input) - console.log("Added %d", index) - index = index + 1 + $('#add-sci_name-row').click -> + compiled_input = $(sci_template.split("INDEX").join(sci_index)) + $('#scientific_names').append(compiled_input) + sci_index = sci_index + 1 - $('#remove-crop-row').click -> - if (index > 2) - index = index - 1 - tmp = 'template[' + index + ']' + $('#remove-sci_name-row').click -> + if (sci_index > 2) + sci_index = sci_index - 1 + tmp = 'sci_template[' + sci_index + ']' element = document.getElementById(tmp) element.remove() - console.log("Removed %s", tmp) + + alt_template = "
Alternate name of crop.
" + + alt_index = $('#alternate_names .template').length + 1 + + $('#add-alt_name-row').click -> + compiled_input = $(alt_template.split("INDEX").join(alt_index)) + $('#alternate_names').append(compiled_input) + alt_index = alt_index + 1 + + $('#remove-alt_name-row').click -> + if (alt_index > 2) + alt_index = alt_index - 1 + tmp = 'alt_template[' + alt_index + ']' + element = document.getElementById(tmp) + console.log("%s",tmp) + element.remove() diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index ffd0ed3af..98d2ca6cb 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -94,9 +94,9 @@ class CropsController < ApplicationController # GET /crops/new.json def new @crop = Crop.new - 3.times do - @crop.scientific_names.build - end + @crop.alternate_names.build + @crop.scientific_names.build + respond_to do |format| format.html # new.html.haml format.json { render json: @crop } @@ -106,15 +106,15 @@ class CropsController < ApplicationController # GET /crops/1/edit def edit @crop = Crop.find(params[:id]) + @crop.alternate_names.build if @crop.alternate_names.blank? + @crop.scientific_names.build if @crop.scientific_names.blank? - (3 - @crop.scientific_names.size).times do - @crop.scientific_names.build - end end # POST /crops # POST /crops.json def create + @crop = Crop.new(crop_params) if current_member.has_role? :crop_wrangler @@ -128,6 +128,12 @@ class CropsController < ApplicationController respond_to do |format| if @crop.save + params[:alt_name].each do |index, value| + alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id) + end + params[:sci_name].each do |index, value| + sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) + end unless current_member.has_role? :crop_wrangler Role.crop_wranglers.each do |w| Notifier.new_crop_request(w, @crop).deliver! @@ -154,6 +160,20 @@ class CropsController < ApplicationController respond_to do |format| if @crop.update(crop_params) + @crop.alternate_names.each do |alt_name| + alt_name.destroy + end + params[:alt_name].each do |index, value| + alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id) + end + + @crop.scientific_names.each do |sci_name| + sci_name.destroy + end + params[:sci_name].each do |index, value| + sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) + end + if previous_status == "pending" requester = @crop.requester new_status = @crop.approval_status diff --git a/app/models/crop.rb b/app/models/crop.rb index 2773bbe38..2000ebfbb 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -7,7 +7,7 @@ class Crop < ActiveRecord::Base :allow_destroy => true, :reject_if => :all_blank - has_many :alternate_names, after_add: :update_index, after_remove: :update_index + has_many :alternate_names, after_add: :update_index, after_remove: :update_index, dependent: :destroy has_many :plantings has_many :photos, :through => :plantings has_many :seeds diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index 09dafa756..ea3a0c653 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -46,17 +46,33 @@ -# Everyone (wranglers and requesters) gets to add scientific names %h2 Scientific names - = button_tag "+", :id => "add-crop-row", :type => "button" - = button_tag "-", :id => "remove-crop-row", :type => "button" - - .form-group#someform - .template.col-md-12 - .col-md-2 - = label_tag :alternate_names, "Alternate name 1:", :class => 'control-label' - .col-md-8 - = text_field_tag :name, nil, :id => 'alt_name[1]', :class => 'form-control' - %span.help-block Alternate name of crop. - .col-md-2 + = button_tag "+", :id => "add-sci_name-row", :type => "button" + = button_tag "-", :id => "remove-sci_name-row", :type => "button" + + .form-group#scientific_names + - @crop.scientific_names.each.with_index do |sci, index| + .template.col-md-12{ :id => "sci_template[#{index+1}]" } + .col-md-2 + = label_tag :scientific_names, "Scientific name #{index+1}:", :class => 'control-label' + .col-md-8 + = text_field_tag "sci_name[#{index+1}]", sci.scientific_name, :id => "sci_name[#{index+1}]", :class => 'form-control' + %span.help-block Scientific name of crop. + .col-md-2 + + %h2 + Alternate names + = button_tag "+", :id => "add-alt_name-row", :type => "button" + = button_tag "-", :id => "remove-alt_name-row", :type => "button" + + .form-group#alternate_names + - @crop.alternate_names.each.with_index do |alt, index| + .template.col-md-12{ :id => "alt_template[#{index+1}]" } + .col-md-2 + = label_tag :alternate_names, "Alternate name #{index+1}:", :class => 'control-label' + .col-md-8 + = text_field_tag "alt_name[#{index+1}]", alt.name, :id => "alt_name[#{index+1}]", :class => 'form-control' + %span.help-block Alternate name of crop. + .col-md-2 -# This is used for comments from crop requesters. We need to show it -# to everyone, but we don't include it on new crops from wranglers. From 734b57e395d846b93844747af5c636b6f78b894d Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 14 Jul 2015 13:24:09 +0800 Subject: [PATCH 147/392] Fixed feature test errors --- app/controllers/crops_controller.rb | 25 +++++++++++--------- app/views/alternate_names/_form.html.haml | 5 ++++ spec/features/crops/crop_wranglers_spec.rb | 2 +- spec/features/crops/request_new_crop_spec.rb | 1 + spec/views/crops/edit.html.haml_spec.rb | 5 ---- spec/views/crops/new.html.haml_spec.rb | 6 ----- 6 files changed, 21 insertions(+), 23 deletions(-) diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 98d2ca6cb..8875a55c5 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -160,18 +160,21 @@ class CropsController < ApplicationController respond_to do |format| if @crop.update(crop_params) - @crop.alternate_names.each do |alt_name| - alt_name.destroy - end - params[:alt_name].each do |index, value| - alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id) - end + if !params[:alt_name].nil? + @crop.alternate_names.each do |alt_name| + alt_name.destroy + end - @crop.scientific_names.each do |sci_name| - sci_name.destroy - end - params[:sci_name].each do |index, value| - sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) + params[:alt_name].each do |index, value| + alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id) + end + + @crop.scientific_names.each do |sci_name| + sci_name.destroy + end + params[:sci_name].each do |index, value| + sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) + end end if previous_status == "pending" diff --git a/app/views/alternate_names/_form.html.haml b/app/views/alternate_names/_form.html.haml index 01b99eba3..cb33660b5 100644 --- a/app/views/alternate_names/_form.html.haml +++ b/app/views/alternate_names/_form.html.haml @@ -17,6 +17,11 @@ .col-md-8 = collection_select(:alternate_name, :crop_id, Crop.all, :id, :name, { :selected => @alternate_name.crop_id || @crop.id }, :class => 'form-control') + .form-group + = f.label :name, :class => 'control-label col-md-2' + .col-md-8 + = f.text_field :name, :class => 'form-control' + .form-group .form-actions.col-md-offset-2.col-md-8 = f.submit 'Save', :class => 'btn btn-primary' \ No newline at end of file diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index b408e53bc..06c70048d 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -45,7 +45,7 @@ feature "crop wranglers" do click_link 'Add Crop' fill_in 'Name', with: "aubergine" fill_in 'Wikipedia URL', with: "http://en.wikipedia.org/wiki/Maize" - fill_in 'crop_scientific_names_attributes_0_scientific_name', with: "planticus maximus" + fill_in 'sci_name[1]', with: "planticus maximus" click_on 'Save' expect(page).to have_content 'Crop was successfully created' expect(page).to have_content 'planticus maximus' diff --git a/spec/features/crops/request_new_crop_spec.rb b/spec/features/crops/request_new_crop_spec.rb index de91cca7e..ba36f90d6 100644 --- a/spec/features/crops/request_new_crop_spec.rb +++ b/spec/features/crops/request_new_crop_spec.rb @@ -34,6 +34,7 @@ feature "Requesting a new crop" do scenario "Approve a request" do visit edit_crop_path(crop) select "approved", from: "Approval status" + save_and_open_page click_button "Save" expect(page).to have_content "En wikipedia url is not a valid English Wikipedia URL" fill_in "Wikipedia URL", with: "http://en.wikipedia.org/wiki/Aung_San_Suu_Kyi" diff --git a/spec/views/crops/edit.html.haml_spec.rb b/spec/views/crops/edit.html.haml_spec.rb index 9942a10f8..9d1af86db 100644 --- a/spec/views/crops/edit.html.haml_spec.rb +++ b/spec/views/crops/edit.html.haml_spec.rb @@ -40,9 +40,4 @@ describe "crops/edit" do end end - it "shows three fields for scientific_name" do - assert_select "input#crop_scientific_names_attributes_0_scientific_name", :count => 1 - assert_select "input#crop_scientific_names_attributes_1_scientific_name", :count => 1 - assert_select "input#crop_scientific_names_attributes_2_scientific_name", :count => 1 - end end diff --git a/spec/views/crops/new.html.haml_spec.rb b/spec/views/crops/new.html.haml_spec.rb index 9375019ad..3ca69f456 100644 --- a/spec/views/crops/new.html.haml_spec.rb +++ b/spec/views/crops/new.html.haml_spec.rb @@ -42,10 +42,4 @@ describe "crops/new" do assert_select "a[href^=http://wiki.growstuff.org]", "crop wrangling guide" end - it "shows three fields for scientific_name" do - assert_select "input#crop_scientific_names_attributes_0_scientific_name", :count => 1 - assert_select "input#crop_scientific_names_attributes_1_scientific_name", :count => 1 - assert_select "input#crop_scientific_names_attributes_2_scientific_name", :count => 1 - end - end From a581b759a3e804721ae51d02a4fb29caca5d31b0 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 14 Jul 2015 15:07:43 +0800 Subject: [PATCH 148/392] Added tests for creating crops with multiple scientific and alternate names --- app/controllers/crops_controller.rb | 4 +-- app/views/crops/_form.html.haml | 6 ++-- spec/features/crops/creating_a_crop_spec.rb | 36 +++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 spec/features/crops/creating_a_crop_spec.rb diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 8875a55c5..25cfee941 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -129,10 +129,10 @@ class CropsController < ApplicationController respond_to do |format| if @crop.save params[:alt_name].each do |index, value| - alt_name = @crop.alternate_names.create(name: value, creator_id: current_member.id) + @crop.alternate_names.create(name: value, creator_id: current_member.id) end params[:sci_name].each do |index, value| - sci_name = @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) + @crop.scientific_names.create(scientific_name: value, creator_id: current_member.id) end unless current_member.has_role? :crop_wrangler Role.crop_wranglers.each do |w| diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index ea3a0c653..99fa8648e 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -17,7 +17,7 @@ -# Everyone (wranglers and requesters) sees the basic info section %h2 Basic information - .form-group + .form-group#new_crop = f.label :name, :class => 'control-label col-md-2' .col-md-8 = f.text_field :name, :class => 'form-control' @@ -30,7 +30,7 @@ .form-group = f.label :en_wikipedia_url, 'Wikipedia URL', :class => 'control-label col-md-2' .col-md-8 - = f.text_field :en_wikipedia_url, :class => 'form-control' + = f.text_field :en_wikipedia_url, :class => 'form-control', :id => "en_wikipedia_url" %span.help-block Link to the crop's page on the English language Wikipedia (required). @@ -82,7 +82,7 @@ .form-group = f.label :request_notes, 'Comments', :class => 'control-label col-md-2' .col-md-8 - = f.text_area :request_notes, :rows => 3, :class => 'form-control' + = f.text_area :request_notes, :rows => 3, :class => 'form-control', :id => 'request_notes' -# A final explanation of what's going to happen next, for crop requesters - unless can? :wrangle, @crop diff --git a/spec/features/crops/creating_a_crop_spec.rb b/spec/features/crops/creating_a_crop_spec.rb new file mode 100644 index 000000000..6c8ba8dbb --- /dev/null +++ b/spec/features/crops/creating_a_crop_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +feature "Crop - " do + let!(:crop_wrangler) { FactoryGirl.create(:crop_wrangling_member)} + let!(:member) { FactoryGirl.create(:member)} + + background do + login_as member + visit new_crop_path + end + + scenario "creating a crop with multiple scientific and alternate name", :js => true do + within "form#new_crop" do + fill_in "crop_name", with: "Philippine flower" + fill_in "en_wikipedia_url", with: "https://en.wikipedia.org/wiki/Jasminum_sambac" + click_button "add-sci_name-row" + fill_in "sci_name[1]", with: "Jasminum sambac 1" + fill_in "sci_name[2]", with: "Jasminum sambac 2" + fill_in "alt_name[1]", with: "Sampaguita" + click_button "add-alt_name-row" + click_button "add-alt_name-row" + fill_in "alt_name[2]", with: "Manol" + click_button "add-alt_name-row" + fill_in "alt_name[3]", with: "Jazmin" + fill_in "alt_name[4]", with: "Matsurika" + fill_in "request_notes", with: "This is the Philippine national flower." + click_button "Save" + end + + save_and_open_page + expect(page).to have_content "Crop was successfully requested." + expect(page).to have_content "Jasminum sambac 2" + expect(page).to have_content "Matsurika" + end + +end From 134465d023baad2f28550c741008f0571ed7c7be Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 14 Jul 2015 15:26:19 +0800 Subject: [PATCH 149/392] Fixed feature errors and removed failing deprecated tests --- spec/features/crops/crop_wranglers_spec.rb | 2 +- spec/features/crops/request_new_crop_spec.rb | 4 ++-- spec/views/crops/edit.html.haml_spec.rb | 7 ------- spec/views/crops/new.html.haml_spec.rb | 9 --------- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 06c70048d..761fb3f47 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -44,7 +44,7 @@ feature "crop wranglers" do click_link 'Crop Wrangling' click_link 'Add Crop' fill_in 'Name', with: "aubergine" - fill_in 'Wikipedia URL', with: "http://en.wikipedia.org/wiki/Maize" + fill_in 'en_wikipedia_url', with: "http://en.wikipedia.org/wiki/Maize" fill_in 'sci_name[1]', with: "planticus maximus" click_on 'Save' expect(page).to have_content 'Crop was successfully created' diff --git a/spec/features/crops/request_new_crop_spec.rb b/spec/features/crops/request_new_crop_spec.rb index ba36f90d6..c1d07810b 100644 --- a/spec/features/crops/request_new_crop_spec.rb +++ b/spec/features/crops/request_new_crop_spec.rb @@ -14,7 +14,7 @@ feature "Requesting a new crop" do scenario "Submit request" do visit new_crop_path fill_in "Name", with: "Couch potato" - fill_in "Comments", with: "Couch potatoes are real for real." + fill_in "request_notes", with: "Couch potatoes are real for real." click_button "Save" expect(page).to have_content "Crop was successfully requested." end @@ -37,7 +37,7 @@ feature "Requesting a new crop" do save_and_open_page click_button "Save" expect(page).to have_content "En wikipedia url is not a valid English Wikipedia URL" - fill_in "Wikipedia URL", with: "http://en.wikipedia.org/wiki/Aung_San_Suu_Kyi" + fill_in "en_wikipedia_url", with: "http://en.wikipedia.org/wiki/Aung_San_Suu_Kyi" click_button "Save" expect(page).to have_content "Crop was successfully updated." end diff --git a/spec/views/crops/edit.html.haml_spec.rb b/spec/views/crops/edit.html.haml_spec.rb index 9d1af86db..98957fc85 100644 --- a/spec/views/crops/edit.html.haml_spec.rb +++ b/spec/views/crops/edit.html.haml_spec.rb @@ -33,11 +33,4 @@ describe "crops/edit" do rendered.should have_content "Added by #{@crop.creator} less than a minute ago." end - it "renders the edit crop form" do - assert_select "form", :action => crops_path(@crop), :method => "post" do - assert_select "input#crop_name", :name => "crop[name]" - assert_select "input#crop_en_wikipedia_url", :name => "crop[en_wikipedia_url]" - end - end - end diff --git a/spec/views/crops/new.html.haml_spec.rb b/spec/views/crops/new.html.haml_spec.rb index 3ca69f456..3e217f7d2 100644 --- a/spec/views/crops/new.html.haml_spec.rb +++ b/spec/views/crops/new.html.haml_spec.rb @@ -29,15 +29,6 @@ describe "crops/new" do render end - it "renders new crop form" do - # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => crops_path, :method => "post" do - assert_select "input#crop_name", :name => "crop[name]" - assert_select "input#crop_en_wikipedia_url", :name => "crop[en_wikipedia_url]" - assert_select "select#crop_parent_id", :name => "crop[parent_id]" - end - end - it "shows a link to crop wrangling guidelines" do assert_select "a[href^=http://wiki.growstuff.org]", "crop wrangling guide" end From 7b3aefacd38c8a9dd8d5b122e459efe6d1586468 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 17 Jul 2015 07:55:03 +0800 Subject: [PATCH 150/392] Hidden the +/- buttons by dby default, making them visible via JavaScript code. --- app/assets/javascripts/seeds.js.coffee | 5 +++++ app/assets/stylesheets/overrides.css.less | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/app/assets/javascripts/seeds.js.coffee b/app/assets/javascripts/seeds.js.coffee index 339d7422b..500c851d9 100644 --- a/app/assets/javascripts/seeds.js.coffee +++ b/app/assets/javascripts/seeds.js.coffee @@ -4,6 +4,10 @@ jQuery -> $('.add-datepicker').datepicker('format' : 'yyyy-mm-dd') + $('#add-sci_name-row').css("display", "inline-block") + $('#remove-sci_name-row').css("display", "inline-block") + $("#add-alt_name-row").css("display", "inline-block") + $("#remove-alt_name-row").css("display", "inline-block") $ -> sci_template = "
Scientific name of crop.
" @@ -38,3 +42,4 @@ $ -> element = document.getElementById(tmp) console.log("%s",tmp) element.remove() + \ No newline at end of file diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index e31ef791e..07194ae2b 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -320,3 +320,7 @@ html, body { .hide { display: none; } + +#add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row{ + display: none; +} From 745281545aeccebd53767a25a1e44639a694ab7d Mon Sep 17 00:00:00 2001 From: Jace Monje Date: Fri, 17 Jul 2015 09:06:18 +0800 Subject: [PATCH 151/392] added test for role checking on view --- app/views/members/_account.html.haml | 6 ++++-- spec/views/members/index.html.haml_spec.rb | 23 +++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index 4898e88ea..f96a125cd 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -18,5 +18,7 @@ %br - if member.has_role? :admin Administrator - - if member.has_role? :crop_wrangler - Crop Wrangler + - if member.has_role? :crop_wrangler + Crop Wrangler + - else + Member diff --git a/spec/views/members/index.html.haml_spec.rb b/spec/views/members/index.html.haml_spec.rb index 02dda186a..5693c9f20 100644 --- a/spec/views/members/index.html.haml_spec.rb +++ b/spec/views/members/index.html.haml_spec.rb @@ -1,13 +1,13 @@ ## DEPRECATION NOTICE: Do not add new tests to this file! ## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. +## View and controller tests are deprecated in the Growstuff project. +## We no longer write new view and controller tests, but instead write +## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). +## These test the full stack, behaving as a browser, and require less complicated setup +## to run. Please feel free to delete old view/controller tests as they are reimplemented +## in feature tests. ## -## If you submit a pull request containing new view or controller tests, it will not be +## If you submit a pull request containing new view or controller tests, it will not be ## merged. @@ -38,4 +38,13 @@ describe "members/index" do rendered.should have_content @member.location end + it 'should not be admin' do + rendered.should_not have_content "Administrator" + end + + it 'should not be crop_wrangler' do + rendered.should_not have_content "Crop Wrangler" + end + + end From 7748c40ccf3f36a979e312822b2148eded5ea9d1 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 17 Jul 2015 09:16:31 +0800 Subject: [PATCH 152/392] Added jacarandang to contributors --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3d42bb043..22732495c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -62,3 +62,4 @@ submit the change with your pull request. - Katy Ereira / [maccath](https://github.com/maccath) - Gabrielle DeWitt / [gabrielle27](https://github.com/gabrielle27) - Manmeet Singh / [manmeetsingh](https://github.com/manmeetsingh) +- Jym Paul Carandang / [jacarandang](https://github.com/jacarandang) From 9c469fb217fd8ee388ed84316e300f4c9f1fec84 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:05:04 -0400 Subject: [PATCH 153/392] .gitignore additions for users of Rubymine. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6370fea4b..9d8981307 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ custom_plan.rb zeus.json .bundle config/application.yml +.idea/** \ No newline at end of file From fa8b10af58f1c3c1638280958eb9b4fd6edce1e6 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:37:54 -0400 Subject: [PATCH 154/392] New contributor! --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 22732495c..3fb5b66f6 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -63,3 +63,4 @@ submit the change with your pull request. - Gabrielle DeWitt / [gabrielle27](https://github.com/gabrielle27) - Manmeet Singh / [manmeetsingh](https://github.com/manmeetsingh) - Jym Paul Carandang / [jacarandang](https://github.com/jacarandang) +- Anthony Atkinson / [sha1sum](https://github.com/sha1sum) \ No newline at end of file From 30032f552700df48e16c76d92d61396b22c946a8 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:38:41 -0400 Subject: [PATCH 155/392] Add a red asterisk via CSS after all .form-group labels with the .required class. --- app/assets/stylesheets/overrides.css.less | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 07194ae2b..8dda75bf6 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -324,3 +324,8 @@ html, body { #add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row{ display: none; } + +.form-group.required .control-label:after { + content: " *"; + color: red; +} \ No newline at end of file From a80001ffe704414873a4121c9fcfc8a1695deba0 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:39:02 -0400 Subject: [PATCH 156/392] Schema update after migration. --- db/schema.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index be45fa333..4f21ebffd 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -406,7 +406,6 @@ ActiveRecord::Schema.define(version: 20150625224805) do t.datetime "updated_at" t.string "slug" t.integer "forum_id" - t.integer "parent_id" end add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree From fc33269f472211f99a405e90cc0c8f914d1dd48b Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:51:37 -0400 Subject: [PATCH 157/392] Reusable class for adding a 1em bottom margin to a block and .red class for red foreground color. --- app/assets/stylesheets/overrides.css.less | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 8dda75bf6..8dc88e715 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -325,7 +325,15 @@ html, body { display: none; } -.form-group.required .control-label:after { - content: " *"; +.form-group.required .control-label:before { + content: "* "; + color: red; +} + +.margin-bottom { + margin-bottom: 1em; +} + +.red { color: red; } \ No newline at end of file From 9a6c32fe6dbeeeb9410ec31a12788d34de2d9373 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:52:08 -0400 Subject: [PATCH 158/392] Planting form with required fields marked and optional fields with "optional" placeholders or select options. --- app/views/plantings/_form.html.haml | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index b16fc2391..5efd62a22 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -1,3 +1,7 @@ +.margin-bottom + %span.red * + %em denotes a required field. + = form_for(@planting, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @planting.errors.any? #error_explanation @@ -6,14 +10,14 @@ - @planting.errors.full_messages.each do |msg| %li= msg - .form-group + .form-group.required = f.label :crop, 'What did you plant?', :class => 'control-label col-md-2' .col-md-8 = auto_suggest @planting, :crop, :class => 'form-control', :default => @crop %span.help-inline Can't find what you're looking for? = link_to "Request new crops.", new_crop_path - .form-group + .form-group.required = f.label :garden_id, 'Where did you plant it?', :class => 'control-label col-md-2' .col-md-8 = collection_select(:planting, :garden_id, Garden.active.where(:owner_id => current_member), :id, :name, {:selected => @planting.garden_id || @garden.id}, {:class => 'form-control'}) @@ -21,22 +25,22 @@ = link_to "Add a garden.", new_garden_path .form-group = f.label :planted_at, 'When?', :class => 'control-label col-md-2' - .col-md-2= f.text_field :planted_at, :value => @planting.planted_at ? @planting.planted_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' + .col-md-2= f.text_field :planted_at, :value => @planting.planted_at ? @planting.planted_at.to_s(:ymd) : '', :class => 'add-datepicker form-control', :placeholder => 'optional' .form-group = f.label :quantity, 'How many?', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :quantity, :class => 'form-control' + = f.number_field :quantity, :class => 'form-control', :placeholder => 'optional' .form-group = f.label :planted_from, 'Planted from:', :class => 'control-label col-md-2' .col-md-8 - = f.select(:planted_from, Planting::PLANTED_FROM_VALUES, {:include_blank => true}, :class => 'form-control') + = f.select(:planted_from, Planting::PLANTED_FROM_VALUES, {:include_blank => 'optional'}, :class => 'form-control') .form-group = f.label :sunniness, 'Sun or shade?', :class => 'control-label col-md-2' .col-md-8 - = f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => true}, :class => 'form-control') + = f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => 'optional'}, :class => 'form-control') .form-group = f.label :description, 'Tell us more about it', :class => 'control-label col-md-2' - .col-md-8= f.text_area :description, :rows => 6, :class => 'form-control' + .col-md-8= f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' .form-group = f.label :finished, 'Mark as finished', :class => 'control-label col-md-2' .col-md-8 @@ -44,9 +48,9 @@ %span.help-block A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden. .form-group - = f.label :finished_at, 'Finished date', { :class => 'control-label col-md-2' } + = f.label :finished_at, 'Finished date', { :class => 'control-label col-md-2', :placeholder => 'optional' } .col-md-2 - = f.text_field :finished_at, :value => @planting.finished_at ? @planting.finished_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' + = f.text_field :finished_at, :value => @planting.finished_at ? @planting.finished_at.to_s(:ymd) : '', :class => 'add-datepicker form-control', :placeholder => 'optional' .form-group .form-actions.col-md-offset-2.col-md-8 = f.submit 'Save', :class => 'btn btn-primary' From a03d044049e09fbbfb6a28ea4ca1a95862925d42 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 10:59:47 -0400 Subject: [PATCH 159/392] Make a reusable helper for the "* denotes a required field" help text and change the Planting form to use the helper. --- app/helpers/application_helper.rb | 6 ++++++ app/views/plantings/_form.html.haml | 4 +--- spec/helpers/application_helper_spec.rb | 7 +++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 5e1264b4a..319a954fd 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -31,5 +31,11 @@ module ApplicationHelper "#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}" end + def required_field_help_text + asterisk = content_tag :span, '*', class: ['red'] + text = content_tag :em, 'denotes a required field' + content_tag :div, asterisk + ' '.html_safe + text, class: ['margin-bottom'] + end + end diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index 5efd62a22..1e347b35e 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -1,6 +1,4 @@ -.margin-bottom - %span.red * - %em denotes a required field. += required_field_help_text = form_for(@planting, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @planting.errors.any? diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 67d05fc3e..8d1f0e78a 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -12,4 +12,11 @@ describe ApplicationHelper do parse_date('2012-05-12').should eq Date.new(2012, 5, 12) parse_date('may 12th 2012').should eq Date.new(2012, 5, 12) end + + it "shows required field marker help text with proper formatting" do + output = required_field_help_text + expect(output).to have_selector '.margin-bottom' + expect(output).to have_selector '.red', text: '*' + expect(output).to have_selector 'em', text: 'denotes a required field' + end end From 96a007ef3be768aac1361df5fe19c64853b51d14 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 11:02:46 -0400 Subject: [PATCH 160/392] Marking required and optional fields on Harvest form. --- app/views/harvests/_form.html.haml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 21de8e5b6..0b61ae03e 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -1,3 +1,5 @@ += required_field_help_text + = form_for(@harvest, :html => {:class => "form-horizontal", :role => :form}) do |f| - if @harvest.errors.any? #error_explanation @@ -6,7 +8,7 @@ - @harvest.errors.full_messages.each do |msg| %li= msg - .form-group + .form-group.required = f.label :crop, 'What did you harvest?', :class => 'control-label col-md-2' .col-md-4 = auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop @@ -17,7 +19,7 @@ = link_to "Request new crops.", new_crop_path .form-group - = f.label :harvested_at, 'When?', :class => 'control-label col-md-2' + = f.label :harvested_at, 'When?', :class => 'control-label col-md-2', :placeholder => 'optional' .col-md-2 = f.text_field :harvested_at, :value => @harvest.harvested_at ? @harvest.harvested_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' @@ -27,20 +29,20 @@ -# Some browsers (eg Firefox for Android) assume "number" means -# "integer" unless you specify step="any": -# http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/ - = f.number_field :quantity, :class => 'input-small', :step => 'any', :class => 'form-control' + = f.number_field :quantity, :class => 'input-small', :step => 'any', :class => 'form-control', :placeholder => 'optional' .col-md-2 = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium form-control') .form-group = f.label :weight_quantity, 'Weighing (in total):', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :weight_quantity, :class => 'input-small', :step => 'any', :class => 'form-control' + = f.number_field :weight_quantity, :class => 'input-small', :step => 'any', :class => 'form-control', :placeholder => 'optional' .col-md-2 = f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') .form-group = f.label :description, 'Notes', :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control' + = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' .form-group .form-actions.col-md-offset-2.col-md-8 From 715a004b13be2ae65ee781d5ad66ace852634e2f Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 11:05:21 -0400 Subject: [PATCH 161/392] Marking required and optional fields on Seed form. Purposefully marked required those select fields which have no blank option. --- app/views/seeds/_form.html.haml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index c40a08697..ac3c26df4 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -1,3 +1,5 @@ += required_field_help_text + = form_for(@seed, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @seed.errors.any? #error_explanation @@ -6,7 +8,7 @@ - @seed.errors.full_messages.each do |msg| %li= msg - .form-group + .form-group.required = f.label :crop, 'Crop:', :class => 'control-label col-md-2' .col-md-8 = auto_suggest @seed, :crop, :class => 'form-control', :default => @crop @@ -14,7 +16,7 @@ Can't find what you're looking for? = link_to "Request new crops.", new_crop_path .form-group - = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2' + = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2', :placeholder => 'optional' .col-md-2 = f.number_field :quantity, :class => 'form-control' .form-group @@ -22,7 +24,7 @@ .col-md-2 = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '' .form-group - = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2' + = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2', :placeholder => 'optional' %fieldset .col-md-2 = f.number_field :days_until_maturity_min, :class => 'form-control' @@ -32,22 +34,22 @@ = f.number_field :days_until_maturity_max, :class => 'form-control' .col-md-1 = f.label :dummy, 'days', :class => 'control-label' - .form-group + .form-group.required = f.label :organic, 'Organic?', :class => 'control-label col-md-2' .col-md-8 = f.select(:organic, Seed::ORGANIC_VALUES, {}, :class => 'form-control', :default => 'unknown') - .form-group + .form-group.required = f.label :gmo, 'GMO?', :class => 'control-label col-md-2' .col-md-8 = f.select(:gmo, Seed::GMO_VALUES, {}, :class => 'form-control', :default => 'unknown') - .form-group + .form-group.required = f.label :heirloom, 'Heirloom?', :class => 'control-label col-md-2' .col-md-8 = f.select(:heirloom, Seed::HEIRLOOM_VALUES, {}, :class => 'form-control', :default => 'unknown') .form-group = f.label :description, 'Description:', :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control' + = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' .form-group .col-md-offset-2.col-md-8 %span.help-block @@ -56,7 +58,7 @@ list your seeds as available for trade, other members can contact you to request seeds. You can list any conditions or other information in the description, above. - .form-group + .form-group.required = f.label :tradable_to, 'Will trade:', :class => 'control-label col-md-2' .col-md-8 = f.select(:tradable_to, Seed::TRADABLE_TO_VALUES, {}, :class => 'form-control') From 4786e3e087f4a2f5265602afc570e1f5cb8542c9 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 11:07:32 -0400 Subject: [PATCH 162/392] Marking required and optional fields on Garden form. --- app/views/gardens/_form.html.haml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index 1915910db..09c3b99ef 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -1,3 +1,5 @@ += required_field_help_text + = form_for(@garden, :html => {:class => "form-horizontal", :role => "form"}) do |f| - if @garden.errors.any? #error_explanation @@ -6,7 +8,7 @@ - @garden.errors.full_messages.each do |msg| %li= msg - .form-group + .form-group.required = f.label :name, :class => 'control-label col-md-2' .col-md-8 = f.text_field :name, :class => 'form-control' @@ -14,12 +16,12 @@ .form-group = f.label :description, :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control' + = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' .form-group = f.label :location, :class => 'control-label col-md-2' .col-md-8 - = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control' + = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :placeholder => 'optional' %span.help-block If you have a location set in your profile, it will be used when you create a new garden. @@ -31,7 +33,7 @@ .form-group = f.label :area, :class => 'control-label col-md-2' .col-md-2 - = f.number_field :area, :class => 'input-small form-control' + = f.number_field :area, :class => 'input-small form-control', :placeholder => 'optional' .col-md-2 = f.select(:area_unit, Garden::AREA_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') From 044f62eae25051a60ca0c20413c12df1096db6b7 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 15:54:09 -0400 Subject: [PATCH 163/392] Rubymine .gitignore additions. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6370fea4b..9d8981307 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ custom_plan.rb zeus.json .bundle config/application.yml +.idea/** \ No newline at end of file From fad9eddbc419a317ff55271561e554419b94dc93 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 16:00:45 -0400 Subject: [PATCH 164/392] Addition of guard gem to assist in quicker testing. --- Gemfile | 2 ++ Gemfile.lock | 34 ++++++++++++++++++++++++++++++++++ Guardfile | 20 ++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 Guardfile diff --git a/Gemfile b/Gemfile index bb774b703..745ca273b 100644 --- a/Gemfile +++ b/Gemfile @@ -104,6 +104,8 @@ group :development do gem 'binding_of_caller' gem 'letter_opener' gem 'quiet_assets' + gem 'guard' + gem 'guard-rspec' end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index fef7b8258..39312a659 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -163,9 +163,11 @@ GEM railties (>= 3.0.0) faraday (0.9.1) multipart-post (>= 1.2, < 3) + ffi (1.9.10) figaro (1.0.0) thor (~> 0.14) flickraw (0.9.8) + formatador (0.2.5) friendly_id (5.0.4) activerecord (>= 4.0.0) gibbon (1.1.4) @@ -174,6 +176,20 @@ GEM gravatar-ultimate (2.0.0) activesupport (>= 2.3.14) rack + guard (2.12.8) + formatador (>= 0.2.4) + listen (>= 2.7, <= 4.0) + lumberjack (~> 1.0) + nenv (~> 0.1) + notiffany (~> 0.0) + pry (>= 0.9.12) + shellany (~> 0.0) + thor (>= 0.18.1) + guard-compat (1.2.1) + guard-rspec (4.6.2) + guard (~> 2.1) + guard-compat (~> 1.1) + rspec (>= 2.99.0, < 4.0) haml (4.1.0.beta.1) tilt haml-rails (0.6.0) @@ -233,6 +249,10 @@ GEM letter_opener (1.3.0) launchy (~> 2.2) libv8 (3.16.14.7) + listen (3.0.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + lumberjack (1.0.9) mail (2.6.3) mime-types (>= 1.16, < 3) memcachier (0.0.2) @@ -243,10 +263,14 @@ GEM multi_json (1.10.1) multi_xml (0.5.5) multipart-post (2.0.0) + nenv (0.2.0) netrc (0.10.0) newrelic_rpm (3.9.8.273) nokogiri (1.6.5) mini_portile (~> 0.6.0) + notiffany (0.0.6) + nenv (~> 0.1) + shellany (~> 0.0) oauth (0.4.7) omniauth (1.2.2) hashie (>= 1.2, < 4) @@ -307,12 +331,19 @@ GEM thor (>= 0.18.1, < 2.0) raindrops (0.13.0) rake (10.4.2) + rb-fsevent (0.9.5) + rb-inotify (0.9.5) + ffi (>= 0.5.0) ref (1.0.5) responders (1.1.2) railties (>= 3.2, < 4.2) rest-client (1.7.2) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) rspec-activemodel-mocks (1.0.1) activemodel (>= 3.0) activesupport (>= 3.0) @@ -343,6 +374,7 @@ GEM sprockets (~> 2.8, < 3.0) sprockets-rails (~> 2.0) sexp_processor (4.4.4) + shellany (0.0.1) simplecov (0.9.1) docile (~> 1.1.0) multi_json (~> 1.0) @@ -423,6 +455,8 @@ DEPENDENCIES geocoder! gibbon gravatar-ultimate + guard + guard-rspec haml haml-rails heroku-api diff --git a/Guardfile b/Guardfile new file mode 100644 index 000000000..04f2fd1f3 --- /dev/null +++ b/Guardfile @@ -0,0 +1,20 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +## Uncomment and set this to only include directories you want to watch +directories %w(app lib config spec) \ + .select { |d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist") } + +## Note: if you are using the `directories` clause above and you are not +## watching the project directory ('.'), then you will want to move +## the Guardfile to a watched dir and symlink it back, e.g. +# +# $ mkdir config +# $ mv Guardfile config/ +# $ ln -s config/Guardfile . +# +# and, you'll have to watch "config/Guardfile" instead of "Guardfile" + +guard :rspec, + cmd: 'bundle exec spring rspec --format documentation', + failed_mode: :keep \ No newline at end of file From 5a35a3da01558c183fd16a8aaba1ef9190d7e3e2 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Wed, 22 Jul 2015 19:48:41 -0400 Subject: [PATCH 165/392] Initial rendition of feature test upgrade to Ruby 2.x and Rspec 3.x syntax. --- Guardfile | 31 ++-- spec/features/admin/account_types_spec.rb | 33 ++-- spec/features/admin/forums_spec.rb | 41 +++-- .../admin/{products.rb => products_spec.rb} | 26 +-- spec/features/cms_spec.rb | 17 +- .../comments/commenting_a_comment_spec.rb | 23 ++- spec/features/crops/alternate_name_spec.rb | 20 +-- spec/features/crops/browse_crops_spec.rb | 8 +- spec/features/crops/creating_a_crop_spec.rb | 10 +- spec/features/crops/crop_detail_page_spec.rb | 53 +++--- spec/features/crops/crop_wranglers_spec.rb | 41 +++-- .../crops/crop_wrangling_button_spec.rb | 45 +++--- spec/features/crops/inflections_spec.rb | 2 - spec/features/crops/request_new_crop_spec.rb | 21 +-- spec/features/following_spec.rb | 21 +-- spec/features/gardens_spec.rb | 25 ++- .../harvests/harvesting_a_crop_spec.rb | 26 ++- spec/features/locale_spec.rb | 7 +- spec/features/member_profile_spec.rb | 57 +++---- spec/features/members_list_spec.rb | 13 +- spec/features/notifications_spec.rb | 18 ++- spec/features/photos/show_photo_spec.rb | 24 ++- .../features/places/searching_a_place_spec.rb | 103 ++++++------ spec/features/planting_reminder_spec.rb | 38 ++--- .../plantings/planting_a_crop_spec.rb | 151 +++++++++--------- spec/features/posts/posting_a_post_spec.rb | 15 +- spec/features/rss/comments_spec.rb | 6 +- spec/features/rss/crops_spec.rb | 6 +- spec/features/rss/members_spec.rb | 8 +- spec/features/rss/plantings_spec.rb | 6 +- spec/features/rss/posts_spec.rb | 6 +- spec/features/rss/seeds_spec.rb | 6 +- spec/features/scientific_name_spec.rb | 18 +-- spec/features/seeds/adding_seeds_spec.rb | 25 ++- spec/features/seeds/misc_seeds_spec.rb | 40 +++-- spec/features/shared_examples/append_date.rb | 11 +- spec/features/shared_examples/crop_suggest.rb | 27 ++-- spec/features/signin_spec.rb | 21 ++- spec/features/signout_spec.rb | 12 +- spec/features/signup_spec.rb | 11 +- spec/features/unsubscribing_spec.rb | 4 +- spec/rails_helper.rb | 3 + 42 files changed, 491 insertions(+), 588 deletions(-) rename spec/features/admin/{products.rb => products_spec.rb} (50%) diff --git a/Guardfile b/Guardfile index 04f2fd1f3..edc8164d3 100644 --- a/Guardfile +++ b/Guardfile @@ -1,20 +1,13 @@ -# A sample Guardfile -# More info at https://github.com/guard/guard#readme - -## Uncomment and set this to only include directories you want to watch -directories %w(app lib config spec) \ - .select { |d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist") } - -## Note: if you are using the `directories` clause above and you are not -## watching the project directory ('.'), then you will want to move -## the Guardfile to a watched dir and symlink it back, e.g. -# -# $ mkdir config -# $ mv Guardfile config/ -# $ ln -s config/Guardfile . -# -# and, you'll have to watch "config/Guardfile" instead of "Guardfile" - guard :rspec, - cmd: 'bundle exec spring rspec --format documentation', - failed_mode: :keep \ No newline at end of file + cmd: 'bundle exec rspec --format documentation', + failed_mode: :keep do + watch(%r{^spec/.+_spec\.rb$}) + watch(%r{^lib/(.+)\.rb$}) { |m| "spec/libs/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { "spec" } + + # Rails example + watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" } + watch(%r{^spec/support/(.+)\.rb$}) { "spec" } + watch('config/routes.rb') { "spec/routing" } +end \ No newline at end of file diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index 01c0040d5..ef0be1139 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -2,7 +2,8 @@ require 'rails_helper' feature "account types" do context "admin user" do - let(:member) { FactoryGirl.create(:admin_member) } + let(:member) { create :admin_member } + let(:account_type) { create :account_type } background do login_as member @@ -11,38 +12,36 @@ feature "account types" do scenario "navigating to account type admin" do visit root_path click_link "Admin" - current_path.should eq admin_path + expect(current_path).to eq admin_path click_link "Account types" - current_path.should eq account_types_path + expect(current_path).to eq account_types_path end scenario "adding an account type" do visit account_types_path click_link "New Account type" - current_path.should eq new_account_type_path - fill_in 'Name', :with => 'Guest' + expect(current_path).to eq new_account_type_path + fill_in 'Name', with: 'Guest' click_button 'Save' - current_path.should eq account_type_path(AccountType.last) - page.should have_content 'Account type was successfully created' + expect(current_path).to eq account_type_path(AccountType.last) + expect(page).to have_content 'Account type was successfully created' end scenario 'editing account type' do - a = FactoryGirl.create(:account_type) - visit account_type_path(a) + visit account_type_path account_type click_link 'Edit' - fill_in 'Name', :with => 'Something else' + fill_in 'Name', with: 'Something else' click_button 'Save' - current_path.should eq account_type_path(a) - page.should have_content 'Account type was successfully updated' - page.should have_content 'Something else' + expect(current_path).to eq account_type_path(account_type) + expect(page).to have_content 'Account type was successfully updated' + expect(page).to have_content 'Something else' end scenario 'deleting account type' do - a = FactoryGirl.create(:account_type) - visit account_type_path(a) + visit account_type_path account_type click_link 'Delete' - current_path.should eq account_types_path - page.should have_content 'Account type was successfully deleted' + expect(current_path).to eq account_types_path + expect(page).to have_content 'Account type was successfully deleted' end end end diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index 98c30d6c7..3fe13e087 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -1,8 +1,9 @@ require 'rails_helper' feature "forums" do - context "admin user" do - let(:member) { FactoryGirl.create(:admin_member) } + context "as an admin user" do + let(:member) { create :admin_member } + let(:forum) { create :forum } background do login_as member @@ -11,43 +12,41 @@ feature "forums" do scenario "navigating to forum admin" do visit root_path click_link "Admin" - current_path.should eq admin_path + expect(current_path).to eq admin_path within 'ul#admin_links' do click_link "Forums" end - current_path.should eq forums_path - page.should have_content "New forum" + expect(current_path).to eq forums_path + expect(page).to have_content "New forum" end scenario "adding a forum" do visit forums_path click_link "New forum" - current_path.should eq new_forum_path - fill_in 'Name', :with => 'Discussion' - fill_in 'Description', :with => "this is a new forum" + expect(current_path).to eq new_forum_path + fill_in 'Name', with: 'Discussion' + fill_in 'Description', with: "this is a new forum" click_button 'Save' - current_path.should eq forum_path(Forum.last) - page.should have_content 'Forum was successfully created' + expect(current_path).to eq forum_path(Forum.last) + expect(page).to have_content 'Forum was successfully created' end scenario 'editing forum' do - f = FactoryGirl.create(:forum) - visit forum_path(f) + visit forum_path forum click_link 'Edit' - fill_in 'Name', :with => 'Something else' + fill_in 'Name', with: 'Something else' click_button 'Save' - f.reload - current_path.should eq forum_path(f) - page.should have_content 'Forum was successfully updated' - page.should have_content 'Something else' + forum.reload + expect(current_path).to eq forum_path(forum) + expect(page).to have_content 'Forum was successfully updated' + expect(page).to have_content 'Something else' end scenario 'deleting forum' do - f = FactoryGirl.create(:forum) - visit forum_path(f) + visit forum_path forum click_link 'Delete' - current_path.should eq forums_path - page.should have_content 'Forum was successfully deleted' + expect(current_path).to eq forums_path + expect(page).to have_content 'Forum was successfully deleted' end end end diff --git a/spec/features/admin/products.rb b/spec/features/admin/products_spec.rb similarity index 50% rename from spec/features/admin/products.rb rename to spec/features/admin/products_spec.rb index e24632cd0..0fc9bdb5a 100644 --- a/spec/features/admin/products.rb +++ b/spec/features/admin/products_spec.rb @@ -2,7 +2,8 @@ require 'rails_helper' feature "products" do context "admin user" do - let(:member) { FactoryGirl.create(:admin_member) } + let(:member) { create :admin_member } + let(:product) { create :product } background do login_as member @@ -11,30 +12,29 @@ feature "products" do scenario "navigating to product admin" do visit admin_path click_link "Products" - current_path.should eq products_path + expect(current_path).to eq products_path end scenario "adding a product" do visit products_path click_link "New Product" - current_path.should eq new_product_path - fill_in 'Name', :with => 'Special offer' + expect(current_path).to eq new_product_path + fill_in 'Name', with: 'Special offer' # note that failing to fill in a mandatory field has a messy error. This is not a priority defect but should be raised at some point. - fill_in 'Minimum price', :with => '150' + fill_in 'Minimum price', with: '150' click_button 'Save' - current_path.should eq product_path(Product.last) - page.should have_content 'Product was successfully created' + expect(current_path).to eq product_path(Product.last) + expect(page).to have_content 'Product was successfully created' end scenario 'editing product' do - p = FactoryGirl.create(:product) - visit product_path(p) + visit product_path product click_link 'Edit' - fill_in 'Name', :with => 'Something else' + fill_in 'Name', with: 'Something else' click_button 'Save' - current_path.should eq product_path(p) - page.should have_content 'Product was successfully updated' - page.should have_content 'Something else' + expect(current_path).to eq product_path(product) + expect(page).to have_content 'Product was successfully updated' + expect(page).to have_content 'Something else' end scenario 'deleting product' diff --git a/spec/features/cms_spec.rb b/spec/features/cms_spec.rb index 3e10faa6b..ad10acd12 100644 --- a/spec/features/cms_spec.rb +++ b/spec/features/cms_spec.rb @@ -1,27 +1,26 @@ require 'rails_helper' feature "cms admin" do - - let(:member) { FactoryGirl.create(:member) } - let(:admin_member) { FactoryGirl.create(:admin_member) } + let(:member) { create :member } + let(:admin_member) { create :admin_member } scenario "can't view CMS admin if not signed in" do visit comfy_admin_cms_path - current_path.should == root_path - page.should have_content("Please sign in as an admin user") + expect(current_path).to eq root_path + expect(page).to have_content "Please sign in as an admin user" end scenario "can't view CMS admin if not an admin member" do # sign in as an ordinary member login_as member visit comfy_admin_cms_path - current_path.should == root_path - page.should have_content("Please sign in as an admin user") + expect(current_path).to eq root_path + expect(page).to have_content "Please sign in as an admin user" end scenario "admin members can view CMS admin area" do login_as admin_member visit comfy_admin_cms_path - current_path.should match /#{comfy_admin_cms_path}/ # match any CMS admin page + expect(current_path).to match /#{comfy_admin_cms_path}/ # match any CMS admin page end -end +end \ No newline at end of file diff --git a/spec/features/comments/commenting_a_comment_spec.rb b/spec/features/comments/commenting_a_comment_spec.rb index e4f2fed21..b39d28618 100644 --- a/spec/features/comments/commenting_a_comment_spec.rb +++ b/spec/features/comments/commenting_a_comment_spec.rb @@ -1,34 +1,33 @@ require 'rails_helper' feature 'Commenting on a post' do - let(:member) { FactoryGirl.create(:member) } - let(:post) { FactoryGirl.create(:post, :author => member) } - + let(:member) { create :member } + let(:post) { create :post, author: member } + background do - login_as(member) - visit new_comment_path(:post_id => post.id) + login_as member + visit new_comment_path post_id: post.id end scenario "creating a comment" do - fill_in "comment_body", :with => "This is a sample test for comment" + fill_in "comment_body", with: "This is a sample test for comment" click_button "Post comment" expect(page).to have_content "Comment was successfully created" expect(page).to have_content "Posted by" end context "editing a comment" do - let(:existing_comment) { FactoryGirl.create(:comment, :post => post, :author => member) } + let(:existing_comment) { create :comment, post: post, author: member } background do - visit edit_comment_path(existing_comment) + visit edit_comment_path existing_comment end scenario "saving edit" do - fill_in "comment_body", :with => "Testing edit for comment" - click_button "Post comment" + fill_in "comment_body", with: "Testing edit for comment" + click_button "Post comment" expect(page).to have_content "Comment was successfully updated" expect(page).to have_content "Edited by" end end - -end +end \ No newline at end of file diff --git a/spec/features/crops/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb index 44bd40c38..586b6622b 100644 --- a/spec/features/crops/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' feature "Alternate names" do - let!(:alternate_eggplant) { FactoryGirl.create(:alternate_eggplant) } + let!(:alternate_eggplant) { create :alternate_eggplant } let(:crop) { alternate_eggplant.crop } scenario "Display alternate names on crop page" do @@ -16,8 +16,8 @@ feature "Alternate names" do end context "User is a crop wrangler" do - let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } - let(:member){crop_wranglers.first} + let!(:crop_wranglers) { create_list :crop_wrangling_member, 3 } + let(:member) { crop_wranglers.first } background do login_as member @@ -28,7 +28,7 @@ feature "Alternate names" do expect(page.status_code).to equal 200 expect(page).to have_content "CROP WRANGLER" expect(page).to have_content alternate_eggplant.name - expect(page).to have_link "Edit", :href => edit_alternate_name_path(alternate_eggplant) + expect(page).to have_link "Edit", href: edit_alternate_name_path(alternate_eggplant) within('.alternate_names') { click_on "Edit" } expect(page.status_code).to equal 200 expect(page).to have_css "option[value='#{crop.id}'][selected=selected]" @@ -42,7 +42,7 @@ feature "Alternate names" do scenario "Crop wranglers can delete alternate names" do visit crop_path(alternate_eggplant.crop) expect(page).to have_link "Delete", - href: alternate_name_path(alternate_eggplant) + href: alternate_name_path(alternate_eggplant) within('.alternate_names') { click_on "Delete" } expect(page.status_code).to equal 200 expect(page).to_not have_content alternate_eggplant.name @@ -52,7 +52,7 @@ feature "Alternate names" do scenario "Crop wranglers can add alternate names" do visit crop_path(crop) expect(page).to have_link "Add", - href: new_alternate_name_path(crop_id: crop.id) + href: new_alternate_name_path(crop_id: crop.id) within('.alternate_names') { click_on "Add" } expect(page.status_code).to equal 200 expect(page).to have_css "option[value='#{crop.id}'][selected=selected]" @@ -70,17 +70,13 @@ feature "Alternate names" do end context "When alternate name is rejected" do - let(:rejected_crop) { FactoryGirl.create(:rejected_crop) } - let(:pending_alt_name) { FactoryGirl.create(:alternate_name, :crop => rejected_crop) } + let(:rejected_crop) { create :rejected_crop } + let(:pending_alt_name) { create :alternate_name, crop: rejected_crop } scenario "Displays crop rejection message" do visit alternate_name_path(pending_alt_name) expect(page).to have_content "This crop was rejected for the following reason: Totally fake" end - end - - end - end diff --git a/spec/features/crops/browse_crops_spec.rb b/spec/features/crops/browse_crops_spec.rb index 08e0b9247..1345d8738 100644 --- a/spec/features/crops/browse_crops_spec.rb +++ b/spec/features/crops/browse_crops_spec.rb @@ -2,10 +2,10 @@ require 'rails_helper' feature "browse crops" do - let(:tomato) { FactoryGirl.create(:tomato) } - let(:maize) { FactoryGirl.create(:maize) } - let(:pending_crop) { FactoryGirl.create(:crop_request) } - let(:rejected_crop) { FactoryGirl.create(:rejected_crop) } + let(:tomato) { create :tomato } + let(:maize) { create :maize } + let(:pending_crop) { create :crop_request } + let(:rejected_crop) { create :rejected_crop } scenario "has a form for sorting by" do visit crops_path diff --git a/spec/features/crops/creating_a_crop_spec.rb b/spec/features/crops/creating_a_crop_spec.rb index 6c8ba8dbb..d234818b8 100644 --- a/spec/features/crops/creating_a_crop_spec.rb +++ b/spec/features/crops/creating_a_crop_spec.rb @@ -1,15 +1,15 @@ require 'rails_helper' feature "Crop - " do - let!(:crop_wrangler) { FactoryGirl.create(:crop_wrangling_member)} - let!(:member) { FactoryGirl.create(:member)} + let!(:crop_wrangler) { create :crop_wrangling_member } + let!(:member) { create :member } background do login_as member visit new_crop_path end - scenario "creating a crop with multiple scientific and alternate name", :js => true do + scenario "creating a crop with multiple scientific and alternate name", :js do within "form#new_crop" do fill_in "crop_name", with: "Philippine flower" fill_in "en_wikipedia_url", with: "https://en.wikipedia.org/wiki/Jasminum_sambac" @@ -27,10 +27,8 @@ feature "Crop - " do click_button "Save" end - save_and_open_page expect(page).to have_content "Crop was successfully requested." expect(page).to have_content "Jasminum sambac 2" expect(page).to have_content "Matsurika" end - -end +end \ No newline at end of file diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index d8738929f..0ed3b3308 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,11 +1,11 @@ require 'rails_helper' feature "crop detail page" do - - let(:crop) { FactoryGirl.create(:crop) } + let(:crop) { create :crop } + + subject { visit crop_path(crop) } context "varieties" do - scenario "The crop DOES NOT have varieties" do visit crop_path(crop) @@ -16,28 +16,27 @@ feature "crop detail page" do end scenario "The crop has one variety" do - roma1 = FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) + create :crop, name: 'Roma tomato 1', parent: crop - visit crop_path(crop) + subject within ".varieties" do # It lists all 2 items (note: including the top level item.) - expect(page).to have_selector('li', text: /tomato/i, count: 2) + expect(page).to have_selector('li', text: /tomato/i, count: 2) # It DOES NOT have "Show all/less" toggle link expect(page).to have_no_selector('button', text: /Show+/i) end end context "many" do - - let!(:roma1) { FactoryGirl.create(:crop, :name => 'Roma tomato 1', :parent => crop) } - let!(:roma2) { FactoryGirl.create(:crop, :name => 'Roma tomato 2', :parent => crop) } - let!(:roma3) { FactoryGirl.create(:crop, :name => 'Roma tomato 3', :parent => crop) } - let!(:roma4) { FactoryGirl.create(:crop, :name => 'Roma tomato 4', :parent => crop) } + let!(:roma1) { create :crop, name: 'Roma tomato 1', parent: crop } + let!(:roma2) { create :crop, name: 'Roma tomato 2', parent: crop } + let!(:roma3) { create :crop, name: 'Roma tomato 3', parent: crop } + let!(:roma4) { create :crop, name: 'Roma tomato 4', parent: crop } scenario "The crop has 4 varieties" do - visit crop_path(crop) + subject within ".varieties" do # It lists all 5 items (note: including the top level item.) @@ -48,9 +47,9 @@ feature "crop detail page" do end scenario "The crop has 5 varieties, including grandchild", :js => true do - roma_child1 = FactoryGirl.create(:crop, :name => 'Roma tomato child 1', :parent => roma4) + create :crop, name: 'Roma tomato child 1', parent: roma4 - visit crop_path(crop) + subject within ".varieties" do @@ -64,7 +63,7 @@ feature "crop detail page" do expect(page).to have_no_selector('button', text: /Show less+/i) # Clik "Show all" link - page.find('button', :text => /Show all+/).click + page.find('button', text: /Show all+/).click # It lists all 6 items (note: including the top level item.) # It HAS have "Show less" toggle link but not "Show all" link @@ -75,7 +74,7 @@ feature "crop detail page" do expect(page).to have_selector('button', text: /Show less+/i) # Clik "Show less" link - page.find('button', :text => /Show less+/).click + page.find('button', text: /Show less+/).click # It lists 5 items (note: including the top level item.) # It HAS have "Show all" toggle link but not "Show less" link @@ -90,7 +89,7 @@ feature "crop detail page" do end context "signed in member" do - let(:member) { FactoryGirl.create(:member) } + let(:member) { create :member } background do login_as(member) @@ -98,27 +97,23 @@ feature "crop detail page" do context "action buttons" do - background do - visit crop_path(crop) - end + background { subject } scenario "has a link to plant the crop" do - expect(page).to have_link "Plant this", :href => new_planting_path(:crop_id => crop.id) + expect(page).to have_link "Plant this", href: new_planting_path(crop_id: crop.id) end scenario "has a link to harvest the crop" do - expect(page).to have_link "Harvest this", :href => new_harvest_path(:crop_id => crop.id) + expect(page).to have_link "Harvest this", href: new_harvest_path(crop_id: crop.id) end scenario "has a link to add seeds" do - expect(page).to have_link "Add seeds to stash", :href => new_seed_path(:crop_id => crop.id) + expect(page).to have_link "Add seeds to stash", href: new_seed_path(crop_id: crop.id) end end context "SEO" do - background do - visit crop_path(crop) - end + background { subject } scenario "has seed heading with SEO" do expect(page).to have_content "Find #{ crop.name } seeds" @@ -145,8 +140,8 @@ feature "crop detail page" do end context "seed quantity for a crop" do - let(:member) { FactoryGirl.create(:member) } - let(:seed) { FactoryGirl.create(:seed, :crop => crop, :quantity => 20, :owner => member)} + let(:member) { create :member } + let(:seed) { create :seed, crop: crop, quantity: 20, owner: member } scenario "User not signed in" do visit crop_path(seed.crop) @@ -166,7 +161,7 @@ feature "crop detail page" do login_as(member) visit crop_path(seed.crop) click_link "View your seeds" - current_path.should == seeds_by_owner_path(:owner => member.slug) + current_path.should == seeds_by_owner_path(owner: member.slug) end end end diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 761fb3f47..0e71275c2 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -2,16 +2,14 @@ require 'rails_helper' feature "crop wranglers" do context "signed in wrangler" do - let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } - let(:wrangler){crop_wranglers.first} - let!(:crops) { FactoryGirl.create_list(:crop, 2) } - let!(:requested_crop) { FactoryGirl.create(:crop_request) } - let!(:rejected_crop) { FactoryGirl.create(:rejected_crop) } + let!(:crop_wranglers) { create_list :crop_wrangling_member, 3 } + let(:wrangler) { crop_wranglers.first } + let!(:crops) { create_list :crop, 2 } + let!(:requested_crop) { create :crop_request } + let!(:rejected_crop) { create :rejected_crop } + + background { login_as wrangler } - background do - login_as(wrangler) - end - scenario "sees crop wranglers listed on the crop wrangler page" do visit root_path click_link 'Crop Wrangling' @@ -19,11 +17,11 @@ feature "crop wranglers" do within '.crop_wranglers' do expect(page).to have_content 'Crop Wranglers:' crop_wranglers.each do |crop_wrangler| - page.should have_link crop_wrangler.login_name, :href => member_path(crop_wrangler) + expect(page).to have_link crop_wrangler.login_name, href: member_path(crop_wrangler) end end end - + scenario "can see list of crops with extra detail of who created a crop" do visit root_path click_link 'Crop Wrangling' @@ -31,14 +29,14 @@ feature "crop wranglers" do expect(page).to have_content "#{crops.first.creator.login_name}" end end - + scenario "visiting a crop can see wrangler links" do visit crop_path(crops.first) expect(page).to have_content 'You are a CROP WRANGLER' expect(page).to have_link 'Edit crop' expect(page).to have_link 'Delete crop' end - + scenario "can create a new crop" do visit root_path click_link 'Crop Wrangling' @@ -62,21 +60,18 @@ feature "crop wranglers" do expect(page).to have_content "This crop was rejected for the following reason: Totally fake" end - - end - - context "signed in non-wrangler" do - let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } - let(:member) { FactoryGirl.create(:member) } - background do - login_as(member) - end + end + + context "signed in non-wrangler" do + let!(:crop_wranglers) { create_list :crop_wrangling_member, 3 } + let(:member) { create :member } + + background { login_as member } scenario "can't see wrangling page" do visit root_path expect(page).not_to have_link "Crop Wrangling" end - end end diff --git a/spec/features/crops/crop_wrangling_button_spec.rb b/spec/features/crops/crop_wrangling_button_spec.rb index 26ef46e30..ede88f003 100644 --- a/spec/features/crops/crop_wrangling_button_spec.rb +++ b/spec/features/crops/crop_wrangling_button_spec.rb @@ -1,33 +1,28 @@ require 'rails_helper' feature "crop wrangling button" do + let(:crop_wrangler) { create :crop_wrangling_member } + let(:member) { create :member } - let(:crop_wrangler) { FactoryGirl.create(:crop_wrangling_member) } - - context "crop wrangling button" do - - background do - login_as(crop_wrangler) - visit crops_path - end - - scenario "has a link to crop wrangling page" do - expect(page).to have_link "Wrangle Crops", :href => wrangle_crops_path - end - + context "crop wrangling button" do + background do + login_as crop_wrangler + visit crops_path end - let(:member) { FactoryGirl.create(:member) } - - context "crop wrangling button" do - - background do - login_as(member) - visit crops_path - end - - scenario "has no link to crop wrangling page" do - expect(page).to have_no_link "Wrangle Crops", :href => wrangle_crops_path - end + scenario "has a link to crop wrangling page" do + expect(page).to have_link "Wrangle Crops", href: wrangle_crops_path end end + + context "crop wrangling button" do + background do + login_as member + visit crops_path + end + + scenario "has no link to crop wrangling page" do + expect(page).to have_no_link "Wrangle Crops", href: wrangle_crops_path + end + end +end diff --git a/spec/features/crops/inflections_spec.rb b/spec/features/crops/inflections_spec.rb index 93c1f0e24..244945d35 100644 --- a/spec/features/crops/inflections_spec.rb +++ b/spec/features/crops/inflections_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' feature "irregular crop inflections" do - # We're just testing a couple of representative crops to # check that inflection works: you don't need to add # every crop here. @@ -9,5 +8,4 @@ feature "irregular crop inflections" do expect("kale".pluralize).to eq "kale" expect("broccoli".pluralize).to eq "broccoli" end - end diff --git a/spec/features/crops/request_new_crop_spec.rb b/spec/features/crops/request_new_crop_spec.rb index c1d07810b..3d2f76e5f 100644 --- a/spec/features/crops/request_new_crop_spec.rb +++ b/spec/features/crops/request_new_crop_spec.rb @@ -1,11 +1,9 @@ require 'rails_helper' feature "Requesting a new crop" do - context "As a regular member" do - - let(:member) { FactoryGirl.create(:member) } - let!(:wrangler) { FactoryGirl.create(:crop_wrangling_member) } + let(:member) { create :member } + let!(:wrangler) { create :crop_wrangling_member } background do login_as member @@ -18,23 +16,18 @@ feature "Requesting a new crop" do click_button "Save" expect(page).to have_content "Crop was successfully requested." end - end context "As a crop wrangler" do + let(:wrangler) { create :crop_wrangling_member } + let!(:crop) { create :crop_request } + let!(:already_approved) { create :crop } - let(:wrangler) { FactoryGirl.create(:crop_wrangling_member) } - let!(:crop) { FactoryGirl.create(:crop_request) } - let!(:already_approved) { FactoryGirl.create(:crop) } - - background do - login_as wrangler - end + background { login_as wrangler } scenario "Approve a request" do visit edit_crop_path(crop) select "approved", from: "Approval status" - save_and_open_page click_button "Save" expect(page).to have_content "En wikipedia url is not a valid English Wikipedia URL" fill_in "en_wikipedia_url", with: "http://en.wikipedia.org/wiki/Aung_San_Suu_Kyi" @@ -49,7 +42,5 @@ feature "Requesting a new crop" do click_button "Save" expect(page).to have_content "Crop was successfully updated." end - end - end diff --git a/spec/features/following_spec.rb b/spec/features/following_spec.rb index 9654bfa4c..92e0f535c 100644 --- a/spec/features/following_spec.rb +++ b/spec/features/following_spec.rb @@ -1,9 +1,8 @@ require 'rails_helper' -feature "follows", :js => true do - +feature "follows", :js do context "when signed out" do - let(:member) { FactoryGirl.create(:member) } + let(:member) { create :member } scenario "follow buttons on member profile page" do visit member_path(member) @@ -13,8 +12,8 @@ feature "follows", :js => true do end context "when signed in" do - let(:member) { FactoryGirl.create(:member) } - let(:other_member) { FactoryGirl.create(:member) } + let(:member) { create :member } + let(:other_member) { create :member } background do login_as(member) @@ -32,13 +31,13 @@ feature "follows", :js => true do end scenario "has a follow button" do - expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) + expect(page).to have_link "Follow", href: follows_path(followed_id: other_member.id) end scenario "has correct message and unfollow button" do click_link 'Follow' expect(page).to have_content "Followed #{other_member.login_name}" - expect(page).to have_link "Unfollow", :href => follow_path(member.get_follow(other_member)) + expect(page).to have_link "Unfollow", href: follow_path(member.get_follow(other_member)) end scenario "has a followed member listed in the following page" do @@ -48,9 +47,7 @@ feature "follows", :js => true do end scenario "does not die when passed an authenticity_token" do - visit member_follows_path( - member, - :params => {:authenticity_token => "Ultima ratio regum"}) + visit member_follows_path member, params: { authenticity_token: "Ultima ratio regum" } expect(page.status_code).to equal 200 end @@ -59,7 +56,7 @@ feature "follows", :js => true do click_link 'Unfollow' expect(page).to have_content "Unfollowed #{other_member.login_name}" visit member_path(other_member) # unfollowing redirects to root - expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) + expect(page).to have_link "Follow", href: follows_path(followed_id: other_member.id) end scenario "has member in following list" do @@ -82,8 +79,6 @@ feature "follows", :js => true do visit member_followers_path(other_member) expect(page).to have_content "#{member.login_name}" end - end - end end diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 889fdd220..dab444bfa 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -1,13 +1,13 @@ require 'rails_helper' feature "Planting a crop", :js => true do - let!(:garden) { FactoryGirl.create(:garden) } - let!(:planting) { FactoryGirl.create(:planting, garden: garden, planted_at: Date.parse("2013-3-10")) } - let!(:tomato) { FactoryGirl.create(:tomato) } - let!(:finished_planting) { FactoryGirl.create(:finished_planting, garden: garden, crop: tomato) } + let!(:garden) { create :garden } + let!(:planting) { create :planting, garden: garden, planted_at: Date.parse("2013-3-10") } + let!(:tomato) { create :tomato } + let!(:finished_planting) { create :finished_planting, garden: garden, crop: tomato } background do - login_as(garden.owner) + login_as garden.owner end scenario "View gardens" do @@ -30,7 +30,7 @@ feature "Planting a crop", :js => true do scenario "Create new garden" do visit new_garden_path - fill_in "Name", :with => "New garden" + fill_in "Name", with: "New garden" click_button "Save" expect(page).to have_content "Garden was successfully created" expect(page).to have_content "New garden" @@ -38,8 +38,8 @@ feature "Planting a crop", :js => true do scenario "Refuse to create new garden with negative area" do visit new_garden_path - fill_in "Name", :with => "Negative Garden" - fill_in "Area", :with => -5 + fill_in "Name", with: "Negative Garden" + fill_in "Area", with: -5 click_button "Save" expect(page).not_to have_content "Garden was successfully created" expect(page).to have_content "Area must be greater than or equal to 0" @@ -47,10 +47,10 @@ feature "Planting a crop", :js => true do scenario "Edit garden" do visit new_garden_path - fill_in "Name", :with => "New garden" + fill_in "Name", with: "New garden" click_button "Save" click_link "Edit garden" - fill_in "Name", :with => "Different name" + fill_in "Name", with: "Different name" click_button "Save" expect(page).to have_content "Garden was successfully updated" expect(page).to have_content "Different name" @@ -58,7 +58,7 @@ feature "Planting a crop", :js => true do scenario "Delete garden" do visit new_garden_path - fill_in "Name", :with => "New garden" + fill_in "Name", with: "New garden" click_button "Save" visit garden_path(Garden.last) click_link "Delete garden" @@ -67,7 +67,7 @@ feature "Planting a crop", :js => true do end describe "Making a planting inactive from garden show" do - let(:path) { garden_path(garden) } + let(:path) { garden_path garden } let(:link_text) { "Mark as finished" } it_behaves_like "append date" end @@ -76,5 +76,4 @@ feature "Planting a crop", :js => true do visit gardens_path expect(page).not_to have_content finished_planting.crop_name end - end diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 3719164e1..c1a3f2f5c 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -1,25 +1,25 @@ require 'rails_helper' -feature "Harvesting a crop", :js => true do - let(:member) { FactoryGirl.create(:member) } - let!(:maize) { FactoryGirl.create(:maize) } +feature "Harvesting a crop", :js do + let(:member) { create :member } + let!(:maize) { create :maize } background do login_as member visit new_harvest_path - sync_elasticsearch([maize]) + sync_elasticsearch [maize] end it_behaves_like "crop suggest", "harvest", "crop" - scenario "Creating a new harvest", :js => true do - fill_autocomplete "crop", :with => "mai" + scenario "Creating a new harvest" do + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_harvest" do - fill_in "When?", :with => "2014-06-15" - fill_in "How many?", :with => 42 - fill_in "Weighing (in total):", :with => 42 - fill_in "Notes", :with => "It's killer." + fill_in "When?", with: "2014-06-15" + fill_in "How many?", with: 42 + fill_in "Weighing (in total):", with: 42 + fill_in "Notes", with: "It's killer." click_button "Save" end @@ -29,7 +29,7 @@ feature "Harvesting a crop", :js => true do scenario "Clicking link to owner's profile" do visit harvests_by_owner_path(member) click_link "View #{member}'s profile >>" - current_path.should eq member_path(member) + expect(current_path).to eq member_path member end scenario "Harvesting from crop page" do @@ -45,7 +45,7 @@ feature "Harvesting a crop", :js => true do end context "Editing a harvest" do - let(:existing_harvest) { FactoryGirl.create(:harvest, :crop => maize, :owner => member) } + let(:existing_harvest) { create :harvest, crop: maize, owner: member } background do visit harvest_path(existing_harvest) @@ -59,8 +59,6 @@ feature "Harvesting a crop", :js => true do expect(page).to have_content "Harvest was successfully updated" expect(page).to have_content "maize" end - end - end diff --git a/spec/features/locale_spec.rb b/spec/features/locale_spec.rb index 36b07b5c9..308f9225f 100644 --- a/spec/features/locale_spec.rb +++ b/spec/features/locale_spec.rb @@ -2,15 +2,12 @@ require 'rails_helper' feature "Changing locales" do - after do - I18n.locale = :en - end + after { I18n.locale = :en } scenario "Locale can be set with a query param" do visit root_path expect(page).to have_content("a community of food gardeners.") - visit root_path(:locale => 'ja') + visit root_path(locale: 'ja') expect(page).to have_content("はガーデナーのコミュニティです。") end - end diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 2c7343a8d..07d90b151 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -1,18 +1,17 @@ require 'rails_helper' feature "member profile" do - context "signed out member" do - let(:member) { FactoryGirl.create(:member) } + let(:member) { create :member } scenario "basic details on member profile page" do visit member_path(member) - expect(page).to have_css("h1", :text => member.login_name) + expect(page).to have_css("h1", text: member.login_name) expect(page).to have_content member.bio expect(page).to have_content "Member since: #{member.created_at.to_s(:date)}" expect(page).to have_content "Account type: Free account" expect(page).to have_content "#{member.login_name}'s gardens" - expect(page).to have_link "More about this garden...", :href => garden_path(member.gardens.first) + expect(page).to have_link "More about this garden...", href: garden_path(member.gardens.first) end scenario "no bio" do @@ -29,9 +28,9 @@ feature "member profile" do context "location" do scenario "member has set location" do - london_member = FactoryGirl.create(:london_member) + london_member = create :london_member visit member_path(london_member) - expect(page).to have_css("h1>small", :text => london_member.location) + expect(page).to have_css("h1>small", text: london_member.location) expect(page).to have_css("#membermap") expect(page).to have_content "See other members near #{london_member.location}" end @@ -47,7 +46,7 @@ feature "member profile" do context "email privacy" do scenario "public email address" do - public_member = FactoryGirl.create(:public_member) + public_member = create :public_member visit member_path(public_member) expect(page).to have_content public_member.email end @@ -59,7 +58,7 @@ feature "member profile" do context "email privacy" do scenario "public email address" do - public_member = FactoryGirl.create(:public_member) + public_member = create :public_member visit member_path(public_member) expect(page).to have_content public_member.email end @@ -81,36 +80,35 @@ feature "member profile" do end scenario "with some activity" do - FactoryGirl.create_list(:planting, 2, :owner => member) - FactoryGirl.create_list(:harvest, 3, :owner => member) - FactoryGirl.create_list(:seed, 4, :owner => member) - FactoryGirl.create_list(:post, 5, :author => member) + create_list :planting, 2, owner: member + create_list :harvest, 3, owner: member + create_list :seed, 4, owner: member + create_list :post, 5, author: member visit member_path(member) - expect(page).to have_link "2 plantings", :href => plantings_by_owner_path(:owner => member) - expect(page).to have_link "3 harvests", :href => harvests_by_owner_path(:owner => member) - expect(page).to have_link "4 seeds", :href => seeds_by_owner_path(:owner => member) - expect(page).to have_link "5 posts", :href => posts_by_author_path(:author => member) + expect(page).to have_link "2 plantings", href: plantings_by_owner_path(owner: member) + expect(page).to have_link "3 harvests", href: harvests_by_owner_path(owner: member) + expect(page).to have_link "4 seeds", href: seeds_by_owner_path(owner: member) + expect(page).to have_link "5 posts", href: posts_by_author_path(author: member) end end scenario "twitter link" do - twitter_auth = FactoryGirl.create(:authentication, :member => member) + twitter_auth = create :authentication, member: member visit member_path(member) - expect(page).to have_link twitter_auth.name, :href => "http://twitter.com/#{twitter_auth.name}" + expect(page).to have_link twitter_auth.name, href: "http://twitter.com/#{twitter_auth.name}" end scenario "flickr link" do - flickr_auth = FactoryGirl.create(:flickr_authentication, :member => member) + flickr_auth = create :flickr_authentication, member: member visit member_path(member) - expect(page).to have_link flickr_auth.name, :href => "http://flickr.com/photos/#{flickr_auth.uid}" + expect(page).to have_link flickr_auth.name, href: "http://flickr.com/photos/#{flickr_auth.uid}" end - end context "signed in member" do - let(:member) { FactoryGirl.create(:member) } - let(:other_member) { FactoryGirl.create(:member) } + let(:member) { create :member } + let(:other_member) { create :member } background do login_as(member) @@ -122,17 +120,16 @@ feature "member profile" do end scenario "has a link to create new garden" do - expect(page).to have_link "New Garden", :href => new_garden_path + expect(page).to have_link "New Garden", href: new_garden_path end scenario "has a button to edit profile" do - expect(page).to have_link "Edit profile", :href => edit_member_registration_path + expect(page).to have_link "Edit profile", href: edit_member_registration_path end scenario "has a button to upgrade account" do - expect(page).to have_link "Upgrade account", :href => shop_path + expect(page).to have_link "Upgrade account", href: shop_path end - end context "someone else's profile page" do @@ -141,9 +138,8 @@ feature "member profile" do end scenario "has a private message button" do - expect(page).to have_link "Send message", :href => new_notification_path(:recipient_id => other_member.id) + expect(page).to have_link "Send message", href: new_notification_path(:recipient_id => other_member.id) end - end context "home page" do @@ -152,9 +148,8 @@ feature "member profile" do end scenario "does not have a button to edit profile" do - expect(page).to_not have_link "Edit profile", :href => edit_member_registration_path + expect(page).to_not have_link "Edit profile", href: edit_member_registration_path end end - end end diff --git a/spec/features/members_list_spec.rb b/spec/features/members_list_spec.rb index 68cbb6d1f..073572795 100644 --- a/spec/features/members_list_spec.rb +++ b/spec/features/members_list_spec.rb @@ -1,11 +1,10 @@ require 'rails_helper' feature "members list" do - context "list all members" do - let! (:member1) { FactoryGirl.create(:member, :login_name => "Archaeopteryx", :confirmed_at => Time.zone.parse('2013-02-10')) } - let! (:member2) { FactoryGirl.create(:member, :login_name => "Zephyrosaurus", :confirmed_at => Time.zone.parse('2014-01-11')) } - let! (:member3) { FactoryGirl.create(:member, :login_name => "Testingname", :confirmed_at => Time.zone.parse('2014-05-09')) } + let!(:member1) { create :member, login_name: "Archaeopteryx", confirmed_at: Time.zone.parse('2013-02-10') } + let!(:member2) { create :member, login_name: "Zephyrosaurus", confirmed_at: Time.zone.parse('2014-01-11') } + let!(:member3) { create :member, login_name: "Testingname", confirmed_at: Time.zone.parse('2014-05-09') } scenario "default alphabetical sort" do visit members_path @@ -26,10 +25,6 @@ feature "members list" do all_links = page.all("#maincontainer p") expect(all_links.first).to have_text member3.login_name expect(all_links.last).to have_text member1.login_name - end - - end - -end +end \ No newline at end of file diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb index 5135a1c72..ee83f5c17 100644 --- a/spec/features/notifications_spec.rb +++ b/spec/features/notifications_spec.rb @@ -1,14 +1,20 @@ require 'rails_helper' -feature "Notifications", :js => true do - let(:sender) { FactoryGirl.create(:member) } - let(:recipient) { FactoryGirl.create(:member) } - +feature "Notifications", :js do + let(:sender) { create :member } + let(:recipient) { create :member } + context "On existing notification" do - let!(:notification) { FactoryGirl.create(:notification, sender: sender, recipient: recipient, body: "Notification body", :post_id => nil) } + let!(:notification) { + create :notification, + sender: sender, + recipient: recipient, + body: "Notification body", + post_id: nil + } background do - login_as(recipient) + login_as recipient visit notification_path(notification) end diff --git a/spec/features/photos/show_photo_spec.rb b/spec/features/photos/show_photo_spec.rb index 0bef51587..238e69eda 100644 --- a/spec/features/photos/show_photo_spec.rb +++ b/spec/features/photos/show_photo_spec.rb @@ -1,48 +1,42 @@ require 'rails_helper' feature "show photo page" do - - let (:photo) { FactoryGirl.create(:photo) } + let(:photo) { create :photo } context "signed in member" do - let (:member) { FactoryGirl.create(:member) } + let(:member) { create :member } - background do - login_as member - end + background { login_as member } context "linked to planting" do - let (:planting) { FactoryGirl.create(:planting) } + let(:planting) { create :planting } scenario "shows linkback to planting" do planting.photos << photo visit photo_path(photo) - expect(page).to have_link planting, :href => planting_path(planting) + expect(page).to have_link planting, href: planting_path(planting) end end context "linked to harvest" do - let (:harvest) { FactoryGirl.create(:harvest) } + let(:harvest) { create :harvest } scenario "shows linkback to harvest" do harvest.photos << photo visit photo_path(photo) - expect(page).to have_link harvest, :href => harvest_path(harvest) + expect(page).to have_link harvest, href: harvest_path(harvest) end end context "linked to garden" do - let (:garden) { FactoryGirl.create(:garden) } + let(:garden) { create :garden } scenario "shows linkback to garden" do garden.photos << photo visit photo_path(photo) - expect(page).to have_link garden, :href => garden_path(garden) + expect(page).to have_link garden, href: garden_path(garden) end - end - end - end diff --git a/spec/features/places/searching_a_place_spec.rb b/spec/features/places/searching_a_place_spec.rb index 4f69c1321..b0c0f931a 100644 --- a/spec/features/places/searching_a_place_spec.rb +++ b/spec/features/places/searching_a_place_spec.rb @@ -1,64 +1,61 @@ require "rails_helper" -RSpec.feature "User searches", :type => :feature do - let(:member) { FactoryGirl.create(:member, location: "Philippines") } - let!(:maize) { FactoryGirl.create(:maize) } - let(:garden) { FactoryGirl.create(:garden, owner: member) } - let!(:seed1) { FactoryGirl.create(:seed, owner: member) } - let!(:planting){ FactoryGirl.create(:planting, garden: garden, owner: member, planted_at: Date.parse("2013-3-10")) } +feature "User searches" do + let(:member) { create :member, location: "Philippines" } + let!(:maize) { create :maize } + let(:garden) { create :garden, owner: member } + let!(:seed1) { create :seed, owner: member } + let!(:planting) { create :planting, garden: garden, owner: member, planted_at: Date.parse("2013-3-10") } - scenario "with a valid place" do - visit places_path - search_with("Philippines") - expect(page).to have_content "members near Philippines" - expect(page).to have_button "search_button" - page.has_content?('placesmap') - expect(page).to have_content "Nearby members" - expect(page).to_not have_content "No results found" - end + scenario "with a valid place" do + visit places_path + search_with "Philippines" + expect(page).to have_content "members near Philippines" + expect(page).to have_button "search_button" + expect(page).to have_content "Nearby members" + expect(page).to_not have_content "No results found" + end - scenario "with a blank search string" do - visit places_path - search_with("") - expect(page).to have_content "Please enter a valid location" - expect(page).to have_button "search_button" - page.has_content?('placesmap') - end + scenario "with a blank search string" do + visit places_path + search_with "" + expect(page).to have_content "Please enter a valid location" + expect(page).to have_button "search_button" + end - describe "Nearby plantings, seed, and members" do - before(:each) do - login_as(member) - visit places_path - search_with("Philippines") - end + describe "Nearby plantings, seed, and members" do + before do + login_as member + visit places_path + search_with "Philippines" + end - it "should show that there are nearby seeds, plantings, and members" do - expect(page).to have_content "Nearby members" - expect(page).to have_content "Seeds available for trade near Philippines" - expect(page).to have_content "Recent plantings near Philippines" - find_link("View all members").visible? - find_link("View all seeds").visible? - find_link("View all plantings").visible? - end + it "should show that there are nearby seeds, plantings, and members" do + expect(page).to have_content "Nearby members" + expect(page).to have_content "Seeds available for trade near Philippines" + expect(page).to have_content "Recent plantings near Philippines" + end - it "should go to members' index page" do - click_link('View all members >>') - current_path.should == members_path - end + it "should go to members' index page" do + click_link 'View all members >>' + expect(current_path).to eq members_path + end - it "should go to plantings' index page" do - click_link('View all plantings >>') - current_path.should == plantings_path - end + it "should go to plantings' index page" do + click_link 'View all plantings >>' + expect(current_path).to eq plantings_path + end - it "should go to seeds' index page" do - click_link('View all seeds >>') - current_path.should == seeds_path - end - end + it "should go to seeds' index page" do + click_link 'View all seeds >>' + expect(current_path).to eq seeds_path + end + end - def search_with(search_string) - fill_in "new_place", :with => search_string - click_button "search_button" - end + private + + def search_with(search_string) + fill_in "new_place", with: search_string + click_button "search_button" + end end \ No newline at end of file diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index 3d694c013..e90118359 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -1,8 +1,8 @@ require 'rails_helper' require 'capybara/email/rspec' -feature "Planting reminder email", :js => true do - let(:member) { FactoryGirl.create(:member) } +feature "Planting reminder email", :js do + let(:member) { create :member } let(:mail) { Notifier.planting_reminder(member) } # Unfortunately, we can't use the default url options for ActionMailer as configured in @@ -23,25 +23,16 @@ feature "Planting reminder email", :js => true do scenario "doesn't list plantings" do expect(mail).not_to have_content "most recent plantings you've told us about" end - end context "when member has some plantings" do - before :each do - @p1 = FactoryGirl.create(:planting, - :garden => member.gardens.first, - :owner => member - ) - @p2 = FactoryGirl.create(:planting, - :garden => member.gardens.first, - :owner => member - ) - end + let(:p1) { create :planting, garden: member.gardens.first, owner: member } + let(:p2) { create :planting, garden: member.gardens.first, owner: member } scenario "lists plantings" do expect(mail).to have_content "most recent plantings you've told us about" - expect(mail).to have_link @p1.to_s, planting_url(@p1) - expect(mail).to have_link @p2.to_s, planting_url(@p2) + expect(mail).to have_link p1.to_s, planting_url(p1) + expect(mail).to have_link p2.to_s, planting_url(p2) expect(mail).to have_content "keep your garden records up to date" end end @@ -54,26 +45,17 @@ feature "Planting reminder email", :js => true do scenario "doesn't list plantings" do expect(mail).not_to have_content "the last few things you harvested were" end - end context "when member has some harvests" do - before :each do - @h1 = FactoryGirl.create(:harvest, - :owner => member - ) - @h2 = FactoryGirl.create(:harvest, - :owner => member - ) - end + let(:h1) { create :harvest, owner: member } + let(:h2) { create :harvest, owner: member } scenario "lists harvests" do expect(mail).to have_content "the last few things you harvested were" - expect(mail).to have_link @h1.to_s, harvest_url(@h1) - expect(mail).to have_link @h2.to_s, harvest_url(@h2) + expect(mail).to have_link h1.to_s, harvest_url(h1) + expect(mail).to have_link h2.to_s, harvest_url(h2) expect(mail).to have_content "Harvested anything else lately?" end - end - end diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 808b70880..aec99b57a 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -1,28 +1,28 @@ require "rails_helper" -feature "Planting a crop", :js => true do - let(:member) { FactoryGirl.create(:member) } - let!(:maize) { FactoryGirl.create(:maize) } - let(:garden) { FactoryGirl.create(:garden, owner: member) } - let!(:planting) { FactoryGirl.create(:planting, garden: garden, planted_at: Date.parse("2013-3-10")) } +feature "Planting a crop", :js do + let(:member) { create :member } + let!(:maize) { create :maize } + let(:garden) { create :garden, owner: member } + let!(:planting) { create :planting, garden: garden, planted_at: Date.parse("2013-3-10") } background do login_as member visit new_planting_path - sync_elasticsearch([maize]) + sync_elasticsearch [maize] end it_behaves_like "crop suggest", "planting" scenario "Creating a new planting" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2014-06-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2014-06-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." click_button "Save" end @@ -33,26 +33,25 @@ feature "Planting a crop", :js => true do scenario "Clicking link to owner's profile" do visit plantings_by_owner_path(member) click_link "View #{member}'s profile >>" - current_path.should eq member_path(member) + expect(current_path).to eq member_path(member) end describe "Progress bar status on planting creation" do - before(:each) do - DateTime.stub(:now){DateTime.new(2015, 10, 20, 10, 34)} - login_as(member) + before do + DateTime.stub(:now) { DateTime.new(2015, 10, 20, 10, 34) } + login_as member visit new_planting_path - sync_elasticsearch([maize]) end it "should show that it is not planted yet" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-12-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2015-12-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." click_button "Save" end @@ -61,14 +60,14 @@ feature "Planting a crop", :js => true do end it "should show that days before maturity is unknown" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-9-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2015-9-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." click_button "Save" end @@ -78,15 +77,15 @@ feature "Planting a crop", :js => true do end it "should show that planting is in progress" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-10-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." - fill_in "Finished date", :with => "2015-10-30" + fill_in "When", with: "2015-10-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." + fill_in "Finished date", with: "2015-10-30" click_button "Save" end @@ -96,14 +95,14 @@ feature "Planting a crop", :js => true do end it "should show that planting is 100% complete (no date specified)" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-10-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2015-10-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." check "Mark as finished" click_button "Save" end @@ -115,15 +114,15 @@ feature "Planting a crop", :js => true do end it "should show that planting is 100% complete (date specified)" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-10-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "semi-shade", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." - fill_in "Finished date", :with => "2015-10-19" + fill_in "When", with: "2015-10-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "semi-shade", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." + fill_in "Finished date", with: "2015-10-19" click_button "Save" end @@ -144,11 +143,11 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Planting was successfully created" expect(page).to have_content "maize" end - + scenario "Editing a planting to add details" do visit planting_path(planting) click_link "Edit" - fill_in "Tell us more about it", :with => "Some extra notes" + fill_in "Tell us more about it", with: "Some extra notes" click_button "Save" expect(page).to have_content "Planting was successfully updated" end @@ -158,37 +157,37 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Progress: 0% - Days before maturity unknown" click_link "Edit" check "finished" - fill_in "Finished date", :with => "2015-06-25" + fill_in "Finished date", with: "2015-06-25" click_button "Save" expect(page).to have_content "Planting was successfully updated" expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" end scenario "Marking a planting as finished" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When?", :with => "2014-07-01" + fill_in "When?", with: "2014-07-01" check "Mark as finished" - fill_in "Finished date", :with => "2014-08-30" + fill_in "Finished date", with: "2014-08-30" # Trigger click instead of using Capybara"s uncheck # because a date selection widget is overlapping # the checkbox preventing interaction. - page.find("#planting_finished").trigger("click") + find("#planting_finished").trigger 'click' end # Javascript removes the finished at date when the # planting is marked unfinished. - expect(page.find("#planting_finished_at").value).to eq("") + expect(find("#planting_finished_at").value).to eq("") within "form#new_planting" do - page.find("#planting_finished").trigger("click") + find("#planting_finished").trigger 'click' end # The finished at date was cached in Javascript in # case the user clicks unfinished accidentally. - expect(page.find("#planting_finished_at").value).to eq("2014-08-30") + expect(find("#planting_finished_at").value).to eq("2014-08-30") within "form#new_planting" do click_button "Save" @@ -201,7 +200,7 @@ feature "Planting a crop", :js => true do end scenario "Marking a planting as finished without a date" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do check "Mark as finished" @@ -214,50 +213,50 @@ feature "Planting a crop", :js => true do describe "Planting sunniness" do it "should show the image sunniness_sun.png" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-10-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - select "sun", :from => "Sun or shade?" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2015-10-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + select "sun", from: "Sun or shade?" + fill_in "Tell us more about it", with: "It's rad." check "Mark as finished" click_button "Save" end expect(page).to have_css("img[src*='sunniness_sun.png']") - page.should have_css("img[alt=sun]") + expect(page).to have_css("img[alt=sun]") end it "should show the image 'not specified.png'" do - fill_autocomplete "crop", :with => "mai" + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", :with => "2015-10-15" - fill_in "How many?", :with => 42 - select "cutting", :from => "Planted from:" - fill_in "Tell us more about it", :with => "It's rad." + fill_in "When", with: "2015-10-15" + fill_in "How many?", with: 42 + select "cutting", from: "Planted from:" + fill_in "Tell us more about it", with: "It's rad." check "Mark as finished" click_button "Save" end expect(page).to have_css("img[src*='sunniness_not specified.png']") - page.should have_css("img[alt='not specified']") + expect(page).to have_css("img[alt='not specified']") end end describe "Marking a planting as finished from the show page" do - let(:path) { planting_path(planting) } + let(:path) { planting_path(planting) } let(:link_text) { "Mark as finished" } it_behaves_like "append date" end describe "Marking a planting as finished from the list page" do - let(:path) { plantings_path } + let(:path) { plantings_path } let(:link_text) { "Mark as finished" } + it_behaves_like "append date" end - end diff --git a/spec/features/posts/posting_a_post_spec.rb b/spec/features/posts/posting_a_post_spec.rb index dabda1586..a1f32942e 100644 --- a/spec/features/posts/posting_a_post_spec.rb +++ b/spec/features/posts/posting_a_post_spec.rb @@ -1,34 +1,33 @@ require 'rails_helper' feature 'Post a post' do - let(:member) { FactoryGirl.create(:member) } + let(:member) { create :member } background do - login_as(member) + login_as member visit new_post_path end scenario "creating a post" do - fill_in "post_subject", :with => "Testing" - fill_in "post_body", :with => "This is a sample test" + fill_in "post_subject", with: "Testing" + fill_in "post_body", with: "This is a sample test" click_button "Post" expect(page).to have_content "Post was successfully created" expect(page).to have_content "Posted by" end context "editing a post" do - let(:existing_post) { FactoryGirl.create(:post, :author => member)} + let(:existing_post) { create :post, author: member } background do visit edit_post_path(existing_post) end scenario "saving edit" do - fill_in "post_subject", :with => "Testing Edit" - click_button "Post" + fill_in "post_subject", with: "Testing Edit" + click_button "Post" expect(page).to have_content "Post was successfully updated" expect(page).to have_content "Edited by" end end - end \ No newline at end of file diff --git a/spec/features/rss/comments_spec.rb b/spec/features/rss/comments_spec.rb index 3f7ce9dc8..20fb1b9d2 100644 --- a/spec/features/rss/comments_spec.rb +++ b/spec/features/rss/comments_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' feature 'Comments RSS feed' do scenario 'The index feed exists' do - visit comments_path(:format => 'rss') + visit comments_path(format: 'rss') expect(page.status_code).to equal 200 end scenario 'The index title is what we expect' do - visit comments_path(:format => 'rss') + visit comments_path(format: 'rss') expect(page).to have_content "Recent comments on all posts (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/rss/crops_spec.rb b/spec/features/rss/crops_spec.rb index 971ec1b80..bb631347d 100644 --- a/spec/features/rss/crops_spec.rb +++ b/spec/features/rss/crops_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' feature 'Crops RSS feed' do scenario 'The index feed exists' do - visit crops_path(:format => 'rss') + visit crops_path(format: 'rss') expect(page.status_code).to equal 200 end scenario 'The index title is what we expect' do - visit crops_path(:format => 'rss') + visit crops_path(format: 'rss') expect(page).to have_content "Recently added crops (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/rss/members_spec.rb b/spec/features/rss/members_spec.rb index 69abb5a25..618beb5bf 100644 --- a/spec/features/rss/members_spec.rb +++ b/spec/features/rss/members_spec.rb @@ -1,15 +1,15 @@ -require 'spec_helper' +require 'rails_helper' feature 'Members RSS feed' do - let(:member) { FactoryGirl.create(:member) } + let(:member) { create :member } scenario 'The show action exists' do - visit member_path(member, :format => 'rss') + visit member_path(member, format: 'rss') expect(page.status_code).to equal 200 end scenario 'The show action title is what we expect' do - visit member_path(member, :format => 'rss') + visit member_path(member, format: 'rss') expect(page).to have_content "#{member.login_name}'s recent posts (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/rss/plantings_spec.rb b/spec/features/rss/plantings_spec.rb index 5a0e98371..343678c1a 100644 --- a/spec/features/rss/plantings_spec.rb +++ b/spec/features/rss/plantings_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' feature 'Plantings RSS feed' do scenario 'The index feed exists' do - visit plantings_path(:format => 'rss') + visit plantings_path(format: 'rss') expect(page.status_code).to equal 200 end scenario 'The index title is what we expect' do - visit plantings_path(:format => 'rss') + visit plantings_path(format: 'rss') expect(page).to have_content "Recent plantings from #{ @owner ? @owner : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/rss/posts_spec.rb b/spec/features/rss/posts_spec.rb index 899c1427b..2eb7d4418 100644 --- a/spec/features/rss/posts_spec.rb +++ b/spec/features/rss/posts_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' feature 'Posts RSS feed' do scenario 'The index feed exists' do - visit posts_path(:format => 'rss') + visit posts_path(format: 'rss') expect(page.status_code).to equal 200 end scenario 'The index title is what we expect' do - visit posts_path(:format => 'rss') + visit posts_path(format: 'rss') expect(page).to have_content "Recent posts from #{ @author ? @author : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/rss/seeds_spec.rb b/spec/features/rss/seeds_spec.rb index e0d016939..fe490bc00 100644 --- a/spec/features/rss/seeds_spec.rb +++ b/spec/features/rss/seeds_spec.rb @@ -1,13 +1,13 @@ -require 'spec_helper' +require 'rails_helper' feature 'Seeds RSS feed' do scenario 'The index feed exists' do - visit seeds_path(:format => 'rss') + visit seeds_path(format: 'rss') expect(page.status_code).to equal 200 end scenario 'The index title is what we expect' do - visit seeds_path(:format => 'rss') + visit seeds_path(format: 'rss') expect(page).to have_content "Recent seeds from #{ @owner ? @owner : 'all members' } (#{ENV['GROWSTUFF_SITE_NAME']})" end end \ No newline at end of file diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index af5cc7f2f..9716795bf 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' feature "Scientific names" do - let!(:zea_mays) { FactoryGirl.create(:zea_mays) } + let!(:zea_mays) { create :zea_mays } let(:crop) { zea_mays.crop } scenario "Display scientific names on crop page" do @@ -17,8 +17,8 @@ feature "Scientific names" do end context "User is a crop wrangler" do - let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } - let(:member){crop_wranglers.first} + let!(:crop_wranglers) { create_list :crop_wrangling_member, 3 } + let(:member) { crop_wranglers.first } background do login_as(member) @@ -29,7 +29,7 @@ feature "Scientific names" do expect(page.status_code).to equal 200 expect(page).to have_content "CROP WRANGLER" expect(page).to have_content zea_mays.scientific_name - expect(page).to have_link "Edit", :href => edit_scientific_name_path(zea_mays) + expect(page).to have_link "Edit", href: edit_scientific_name_path(zea_mays) within('.scientific_names') { click_on "Edit" } expect(page.status_code).to equal 200 expect(page).to have_css "option[value='#{crop.id}'][selected=selected]" @@ -42,7 +42,7 @@ feature "Scientific names" do scenario "Crop wranglers can delete scientific names" do visit crop_path(zea_mays.crop) expect(page).to have_link "Delete", - href: scientific_name_path(zea_mays) + href: scientific_name_path(zea_mays) within('.scientific_names') { click_on "Delete" } expect(page.status_code).to equal 200 expect(page).to_not have_content zea_mays.scientific_name @@ -52,7 +52,7 @@ feature "Scientific names" do scenario "Crop wranglers can add scientific names" do visit crop_path(crop) expect(page).to have_link "Add", - href: new_scientific_name_path(crop_id: crop.id) + href: new_scientific_name_path(crop_id: crop.id) within('.scientific_names') { click_on "Add" } expect(page.status_code).to equal 200 expect(page).to have_css "option[value='#{crop.id}'][selected=selected]" @@ -67,12 +67,12 @@ feature "Scientific names" do visit scientific_name_path(zea_mays) expect(page.status_code).to equal 200 expect(page).to have_link zea_mays.crop.name, - href: crop_path(zea_mays.crop) + href: crop_path(zea_mays.crop) end context "When scientific name is pending" do - let(:pending_crop) { FactoryGirl.create(:crop_request) } - let(:pending_sci_name) { FactoryGirl.create(:scientific_name, :crop => pending_crop) } + let(:pending_crop) { create :crop_request } + let(:pending_sci_name) { create :scientific_name, crop: pending_crop } scenario "Displays crop pending message" do visit scientific_name_path(pending_sci_name) diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index 8fa146724..bf580793c 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -1,29 +1,29 @@ require 'rails_helper' -feature "Seeds", :js => true do - let(:member) { FactoryGirl.create(:member) } - let!(:maize) { FactoryGirl.create(:maize) } +feature "Seeds", :js do + let(:member) { create :member } + let!(:maize) { create :maize } background do login_as member visit new_seed_path - sync_elasticsearch([maize]) + sync_elasticsearch [maize] end it_behaves_like "crop suggest", "seed", "crop" - scenario "Adding a new seed", :js => true do - fill_autocomplete "crop", :with => "mai" + scenario "Adding a new seed" do + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_seed" do - fill_in "Quantity:", :with => 42 - fill_in "Plant before:", :with => "2014-06-15" - fill_in "Days until maturity:", :with => 999 - fill_in "to", :with => 1999 + fill_in "Quantity:", with: 42 + fill_in "Plant before:", with: "2014-06-15" + fill_in "Days until maturity:", with: 999 + fill_in "to", with: 1999 select "certified organic", :from => "Organic?" select "non-certified GMO-free", :from => "GMO?" select "heirloom", :from => "Heirloom?" - fill_in "Description", :with => "It's killer." + fill_in "Description", with: "It's killer." select "internationally", :from => "Will trade:" click_button "Save" end @@ -48,5 +48,4 @@ feature "Seeds", :js => true do expect(page).to have_content "Successfully added maize seed to your stash" expect(page).to have_content "maize" end - -end +end \ No newline at end of file diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 4c02ceecf..1d01e5732 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -2,77 +2,75 @@ require 'rails_helper' feature "seeds" do context "signed in user" do - - let(:member) { @member = FactoryGirl.create(:member) } - let(:crop) { FactoryGirl.create(:crop) } + let(:member) { create :member } + let(:crop) { create :crop } background do login_as member end scenario "button on index to edit seed" do - seed = FactoryGirl.create(:seed, :owner => @member) + seed = create :seed, owner: member visit seeds_path click_link "Edit" - current_path.should eq edit_seed_path(seed) - page.should have_content 'Editing seeds' + expect(current_path).to eq edit_seed_path(seed) + expect(page).to have_content 'Editing seeds' end scenario "button on front page to add seeds" do visit root_path click_link "Add seeds" - current_path.should eq new_seed_path - page.should have_content 'Add seeds' + expect(current_path).to eq new_seed_path + expect(page).to have_content 'Add seeds' end scenario "Clicking link to owner's profile" do visit seeds_by_owner_path(member) click_link "View #{member}'s profile >>" - current_path.should eq member_path(member) + expect(current_path).to eq member_path(member) end - + # actually adding seeds is in spec/features/seeds_new_spec.rb scenario "edit seeds" do - seed = FactoryGirl.create(:seed, :owner => @member) + seed = create :seed, owner: member visit seed_path(seed) click_link 'Edit' - current_path.should eq edit_seed_path(seed) - fill_in 'Quantity:', :with => seed.quantity * 2 + expect(current_path).to eq edit_seed_path(seed) + fill_in 'Quantity:', with: seed.quantity * 2 click_button 'Save' - current_path.should eq seed_path(seed) + expect(current_path).to eq seed_path(seed) end scenario "delete seeds" do - seed = FactoryGirl.create(:seed, :owner => @member) + seed = create :seed, owner: member visit seed_path(seed) click_link 'Delete' - current_path.should eq seeds_path + expect(current_path).to eq seeds_path end scenario "view seeds with max and min days until maturity" do - seed = FactoryGirl.create(:seed, :days_until_maturity_min => 5, :days_until_maturity_max => 7) + seed = create :seed, days_until_maturity_min: 5, days_until_maturity_max: 7 visit seed_path(seed) expect(page).to have_content "Days until maturity: 5–7" end scenario "view seeds with only max days until maturity" do - seed = FactoryGirl.create(:seed, :days_until_maturity_max => 7) + seed = create :seed, days_until_maturity_max: 7 visit seed_path(seed) expect(page).to have_content "Days until maturity: 7" end scenario "view seeds with only min days until maturity" do - seed = FactoryGirl.create(:seed, :days_until_maturity_min => 5) + seed = create :seed, days_until_maturity_min: 5 visit seed_path(seed) expect(page).to have_content "Days until maturity: 5" end scenario "view seeds with neither max nor min days until maturity" do - seed = FactoryGirl.create(:seed) + seed = create :seed visit seed_path(seed) expect(page).to have_content "Days until maturity: unknown" end - end end diff --git a/spec/features/shared_examples/append_date.rb b/spec/features/shared_examples/append_date.rb index 089680ff9..310e39606 100644 --- a/spec/features/shared_examples/append_date.rb +++ b/spec/features/shared_examples/append_date.rb @@ -1,22 +1,21 @@ shared_examples "append date" do + let(:this_month) { Date.today.strftime("%B") } + let(:this_year) { Date.today.strftime("%Y") } + + background { visit path } scenario "Selecting a date with datepicker" do - this_month = Date.today.strftime("%B") - this_year = Date.today.strftime("%Y") - visit path click_link link_text within "div.datepicker" do expect(page).to have_content "#{this_month}" - page.find(".datepicker-days td.day", text: "21").click + find(".datepicker-days td.day", text: "21").click end expect(page).to have_content "Finished: #{this_month} 21, #{this_year}" end scenario "Confirming without selecting date" do - visit path click_link link_text click_link "Confirm without date" expect(page).to have_content("Finished: Yes (no date specified) ") end - end \ No newline at end of file diff --git a/spec/features/shared_examples/crop_suggest.rb b/spec/features/shared_examples/crop_suggest.rb index 5e812e683..9828a7865 100644 --- a/spec/features/shared_examples/crop_suggest.rb +++ b/spec/features/shared_examples/crop_suggest.rb @@ -1,14 +1,12 @@ require 'rails_helper' shared_examples "crop suggest" do |resource| - let!(:pea) { FactoryGirl.create(:crop, :name => 'pea') } - let!(:pear) { FactoryGirl.create(:pear) } - let!(:tomato) { FactoryGirl.create(:tomato) } - let!(:roma) { FactoryGirl.create(:roma) } + let!(:pea) { create :crop, name: 'pea' } + let!(:pear) { create :pear } + let!(:tomato) { create :tomato } + let!(:roma) { create :roma } - background do - sync_elasticsearch([pea, pear, maize, tomato]) - end + background { sync_elasticsearch [pea, pear, maize, tomato] } scenario "placeholder text in crop auto suggest field" do expect(page).to have_selector("input[placeholder='e.g. lettuce']") @@ -16,21 +14,21 @@ shared_examples "crop suggest" do |resource| scenario "typing in the crop name displays suggestions" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "pe" + fill_autocomplete "crop", with: "pe" end expect(page).to_not have_content("pear") expect(page).to_not have_content("pea") within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "pea" + fill_autocomplete "crop", with: "pea" end expect(page).to have_content("pear") expect(page).to have_content("pea") within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "pear" + fill_autocomplete "crop", with: "pear" end expect(page).to have_content("pear") @@ -38,7 +36,7 @@ shared_examples "crop suggest" do |resource| scenario "selecting crop from dropdown" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "pear" + fill_autocomplete "crop", with: "pear" end select_from_autocomplete("pear") @@ -48,7 +46,7 @@ shared_examples "crop suggest" do |resource| scenario "Typing and pausing does not affect input" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "pea" + fill_autocomplete "crop", with: "pea" end expect(page).to have_content("pear") @@ -57,7 +55,7 @@ shared_examples "crop suggest" do |resource| scenario "Searching for a crop casts a wide net on results" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "tom" + fill_autocomplete "crop", with: "tom" end expect(page).to have_content("tomato") @@ -66,11 +64,10 @@ shared_examples "crop suggest" do |resource| scenario "Submitting a crop that doesn't exist in the database produces a meaningful error" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "Ryan Gosling" + fill_autocomplete "crop", with: "Ryan Gosling" click_button "Save" end expect(page).to have_content("Crop must be present and exist in our database") end - end diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index dced5f2ac..2c268e285 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -1,9 +1,9 @@ require 'rails_helper' feature "signin" do - let(:member){FactoryGirl.create(:member)} - let(:recipient){FactoryGirl.create(:member)} - let(:notification){FactoryGirl.create(:notification)} + let(:member) { create :member } + let(:recipient) { create :member } + let(:notification) { create :notification } scenario "redirect to previous page after signin" do visit crops_path # some random page @@ -11,7 +11,7 @@ feature "signin" do fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' - current_path.should eq crops_path + expect(current_path).to eq crops_path end scenario "don't redirect to devise pages after signin" do @@ -20,34 +20,33 @@ feature "signin" do fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' - current_path.should eq root_path + expect(current_path).to eq root_path end scenario "redirect to signin page for if not authenticated to view notification" do visit notification_path(notification) - current_path.should eq new_member_session_path + expect(current_path).to eq new_member_session_path end scenario "after signin, redirect to what you were trying to do" do models = %w[plantings harvests posts photos gardens seeds] models.each do |model| visit "/#{model}/new" - current_path.should eq new_member_session_path + expect(current_path).to eq new_member_session_path fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' - current_path.should eq "/#{model}/new" + expect(current_path).to eq "/#{model}/new" click_link 'Sign out' end end scenario "after signin, redirect to new notifications page" do visit new_notification_path(recipient: recipient) - current_path.should eq new_member_session_path + expect(current_path).to eq new_member_session_path fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' - current_path.should eq new_notification_path + expect(current_path).to eq new_notification_path end - end diff --git a/spec/features/signout_spec.rb b/spec/features/signout_spec.rb index 00a389069..2d5d1a230 100644 --- a/spec/features/signout_spec.rb +++ b/spec/features/signout_spec.rb @@ -1,8 +1,8 @@ require 'rails_helper' feature "signout" do - let(:member){FactoryGirl.create(:member)} - + let(:member) { create :member } + scenario "redirect to previous page after signout" do visit crops_path # some random page click_link 'Sign in' @@ -10,20 +10,20 @@ feature "signout" do fill_in 'Password', with: member.password click_button 'Sign in' click_link 'Sign out' - current_path.should eq crops_path + expect(current_path).to eq crops_path end scenario "after signout, redirect to signin page if page needs authentication" do models = %w[plantings harvests posts photos gardens seeds] models.each do |model| visit "/#{model}/new" - current_path.should eq new_member_session_path + expect(current_path).to eq new_member_session_path fill_in 'Login', with: member.login_name fill_in 'Password', with: member.password click_button 'Sign in' - current_path.should eq "/#{model}/new" + expect(current_path).to eq "/#{model}/new" click_link 'Sign out' - current_path.should eq new_member_session_path + expect(current_path).to eq new_member_session_path end end diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb index aa4c9d65f..58b203195 100644 --- a/spec/features/signup_spec.rb +++ b/spec/features/signup_spec.rb @@ -1,7 +1,6 @@ require 'rails_helper' feature "signup" do - scenario "sign up for new account from top menubar" do visit crops_path # something other than front page, which has multiple signup links click_link 'Sign up' @@ -11,7 +10,7 @@ feature "signup" do fill_in 'Password confirmation', with: 'abc123' check 'member_tos_agreement' click_button 'Sign up' - current_path.should eq root_path + expect(current_path).to eq root_path end scenario "sign up for new account with existing username" do @@ -23,8 +22,7 @@ feature "signup" do fill_in 'Password confirmation', with: 'abc123' check 'member_tos_agreement' click_button 'Sign up' - page.has_content? 'A message with a confirmation link has been sent to your email address. Please open the link to activate your account.' - current_path.should eq root_path + expect(current_path).to eq root_path first('.signup a').click # click the 'Sign up' button in the middle of the page fill_in 'Login name', with: 'person123' fill_in 'Email', with: 'gardener@example.com' @@ -32,7 +30,6 @@ feature "signup" do fill_in 'Password confirmation', with: 'abc123' check 'member_tos_agreement' click_button 'Sign up' - page.has_content? 'Login name has already been taken' end scenario "sign up for new account without accepting TOS" do @@ -44,8 +41,6 @@ feature "signup" do fill_in 'Password confirmation', with: 'abc123' # do not check 'member_tos_agreement' click_button 'Sign up' - page.has_content? 'Tos agreement must be accepted' - current_path.should eq members_path + expect(current_path).to eq members_path end - end diff --git a/spec/features/unsubscribing_spec.rb b/spec/features/unsubscribing_spec.rb index 2c37f3101..e8242f542 100644 --- a/spec/features/unsubscribing_spec.rb +++ b/spec/features/unsubscribing_spec.rb @@ -2,8 +2,8 @@ require 'rails_helper' require 'capybara/email/rspec' feature "unsubscribe" do - let(:member) { FactoryGirl.create(:member) } - let(:notification) { FactoryGirl.create(:notification) } + let(:member) { create :member } + let(:notification) { create :notification } background do clear_emails diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 784cfba6f..2bcf1cf4c 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -82,4 +82,7 @@ RSpec.configure do |config| # see https://github.com/plataformatec/devise/wiki/How-To%3a-Controllers-and-Views-tests-with-Rails-3-%28and-rspec%29 config.include Devise::TestHelpers, :type => :controller config.extend ControllerMacros, :type => :controller + + # Allow just create(:factory) instead of needing to specify FactoryGirl.create(:factory) + config.include FactoryGirl::Syntax::Methods end From f5336bd8f8bda2343f2d381caadb12b7a1dcba89 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 8 Jul 2015 14:30:22 +0800 Subject: [PATCH 166/392] Created card based template for harvests. --- app/assets/stylesheets/overrides.css.less | 5 +++ app/views/harvests/_thumbnail.html.haml | 23 ++++++++++++++ app/views/harvests/index.html.haml | 35 +++++---------------- spec/views/harvests/index.html.haml_spec.rb | 8 ----- 4 files changed, 35 insertions(+), 36 deletions(-) create mode 100644 app/views/harvests/_thumbnail.html.haml diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 07194ae2b..fcbf458e7 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -324,3 +324,8 @@ html, body { #add-sci_name-row, #remove-sci_name-row, #add-alt_name-row, #remove-alt_name-row{ display: none; } + +.panel-footer{ + height: 80px; + overflow-y: scroll; +} diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml new file mode 100644 index 000000000..25924a40c --- /dev/null +++ b/app/views/harvests/_thumbnail.html.haml @@ -0,0 +1,23 @@ +.panel.panel-success + .panel-heading + %h3.panel-title + = link_to "#{harvest.owner.login_name}'s harvest", harvest.owner + %a.pull-right{:href => edit_harvest_path(harvest), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} + .panel-body + .row + .col-md-6 + = link_to image_tag((harvest.crop.default_photo ? harvest.crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => harvest.crop.name, :class => 'img'), harvest.crop + .col-md-6 + %dl + %dt Crop + %dd= link_to harvest.crop.name, harvest.crop + %dt Plant part + %dd= link_to harvest.plant_part, harvest.plant_part + %dt Quantity + %dd= display_quantity(harvest) + %dt Harvest date + %dd= harvest.harvested_at + .panel-footer + %dt Description + %dd= harvest.description \ No newline at end of file diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 5d35a40ae..a6ef4d312 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -23,36 +23,15 @@ %div.pagination = page_entries_info @harvests, :model => "harvests" = will_paginate @harvests - -- if @harvests.size > 0 - - %table.table.table-striped - %tr - - unless @owner - %th Owner - %th Crop - %th Plant part - %th Date - %th Quantity - %th Description - %th - +.row + - if @harvests.size > 0 - @harvests.each do |harvest| - %tr - - unless @owner - %td= link_to harvest.owner.login_name, harvest.owner - %td= link_to harvest.crop.name, harvest.crop - %td - - if harvest.plant_part - = link_to harvest.plant_part.name, harvest.plant_part - %td= harvest.harvested_at - %td= display_quantity(harvest) - %td= harvest.description - %td= link_to 'Details', harvest, :class => 'btn btn-default btn-xs' + .col-md-6 + =render :partial => 'harvests/thumbnail', :locals => {:harvest => harvest} - %div.pagination - = page_entries_info @harvests, :model => "harvests" - = will_paginate @harvests +%div.pagination + = page_entries_info @harvests, :model => "harvests" + = will_paginate @harvests %ul.list-inline %li The data on this page is available in the following formats: diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index eb5c0491b..0c2dfe5bb 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -43,14 +43,6 @@ describe "harvests/index" do render end - it "renders a list of harvests" do - render - assert_select "tr>td", :text => @member.login_name - assert_select "tr>td", :text => @tomato.name - assert_select "tr>td", :text => @maize.name - assert_select "tr>td", :text => @pp.name - end - it "provides data links" do render rendered.should have_content "The data on this page is available in the following formats:" From bbe7d967b4ac5a0f92cc5b8a9924c0c64dc55c09 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 9 Jul 2015 14:02:02 +0800 Subject: [PATCH 167/392] Changed px to em and used truncate instead of srolling for long harvest descriptions. --- app/assets/stylesheets/overrides.css.less | 3 +-- app/helpers/harvests_helper.rb | 6 ++++++ app/views/harvests/_thumbnail.html.haml | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index fcbf458e7..ccb462404 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -326,6 +326,5 @@ html, body { } .panel-footer{ - height: 80px; - overflow-y: scroll; + height: 6em; } diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index b5f335db9..1c2d5fe60 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -37,4 +37,10 @@ module HarvestsHelper end end + def display_harvest_description(harvest) + output = truncate(harvest.description, length: 120, omission: '... ') + output += link_to('[Read more]', harvest_path(harvest)) if harvest.description.size > 100 + output.html_safe + end + end diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index 25924a40c..a4bcc0044 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -20,4 +20,5 @@ %dd= harvest.harvested_at .panel-footer %dt Description - %dd= harvest.description \ No newline at end of file + %dd + = display_harvest_description(harvest) From c12791e428d23da533c20cb134ccabf363b50f1e Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 9 Jul 2015 15:27:08 +0800 Subject: [PATCH 168/392] Created card-based thumbnails for Seeds and Gardens page. --- app/helpers/gardens_helper.rb | 32 +++++++++++++ app/helpers/harvests_helper.rb | 10 ++-- app/helpers/seeds_helper.rb | 13 +++++ app/views/gardens/_thumbnail.html.haml | 27 +++++++++++ app/views/gardens/index.html.haml | 61 +++++------------------- app/views/harvests/_thumbnail.html.haml | 6 +-- app/views/seeds/_thumbnail.html.haml | 26 ++++++++++ app/views/seeds/index.html.haml | 63 +++++++------------------ 8 files changed, 137 insertions(+), 101 deletions(-) create mode 100644 app/helpers/gardens_helper.rb create mode 100644 app/helpers/seeds_helper.rb create mode 100644 app/views/gardens/_thumbnail.html.haml create mode 100644 app/views/seeds/_thumbnail.html.haml diff --git a/app/helpers/gardens_helper.rb b/app/helpers/gardens_helper.rb new file mode 100644 index 000000000..9eb40e21d --- /dev/null +++ b/app/helpers/gardens_helper.rb @@ -0,0 +1,32 @@ +module GardensHelper + + def display_garden_description(garden) + if garden.description.nil? + "no description provided." + else + output = truncate(garden.description, length: 130, omission: '... ') + output += link_to('[Read more]', garden_path(garden)) if garden.description.size > 130 + output.html_safe + end + end + + def display_garden_plantings(garden) + if garden.plantings.empty? + None + else + output = "" + garden.plantings.current.each do |p| + output = p.quantity.nil? ? "0 " : "#{p.quantity} " + output += link_to p.crop.name, p + output = output.html_safe + if p.planted_at + output += ", planted on #{p.planted_at}" + end + end + + output = truncate(output, length: 100, omission: '... ') + output += link_to('[View more plantings]', garden_path(garden)) if output.size > 100 + output.html_safe + end + end +end \ No newline at end of file diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index 1c2d5fe60..7a5848066 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -38,9 +38,13 @@ module HarvestsHelper end def display_harvest_description(harvest) - output = truncate(harvest.description, length: 120, omission: '... ') - output += link_to('[Read more]', harvest_path(harvest)) if harvest.description.size > 100 - output.html_safe + if harvest.description.nil? + "no description provided." + else + output = truncate(harvest.description, length: 130, omission: '... ') + output += link_to('[Read more]', harvest_path(harvest)) if harvest.description.size > 130 + output.html_safe + end end end diff --git a/app/helpers/seeds_helper.rb b/app/helpers/seeds_helper.rb new file mode 100644 index 000000000..728ed7215 --- /dev/null +++ b/app/helpers/seeds_helper.rb @@ -0,0 +1,13 @@ +module SeedsHelper + + def display_seed_description(seed) + if seed.description.nil? + "no description provided." + else + output = truncate(seed.description, length: 130, omission: '... ') + output += link_to('[Read more]', seed_path(seed)) if seed.description.size > 130 + output.html_safe + end + end + +end \ No newline at end of file diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml new file mode 100644 index 000000000..6c3ff48c0 --- /dev/null +++ b/app/views/gardens/_thumbnail.html.haml @@ -0,0 +1,27 @@ +.panel.panel-success + .panel-heading + %h3.panel-title + = link_to "#{garden.owner.login_name}'s garden", garden.owner + %a.pull-right{:href => edit_garden_path(garden), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} + .panel-body + .row + .col-md-4 + = link_to image_tag((garden.default_photo ? garden.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => garden.name, :class => 'img'), garden + .col-md-8 + %dl.dl-horizontal + %dt Name + %dd= link_to garden.name, garden + %dt Location + %dd= link_to garden.location, place_path(garden.location) + %dt Area + %dd= garden.area.nil? ? "not specified" : pluralize(garden.area, garden.area_unit) + %dt Active? + %dd= garden.active ? "Yes" : "No" + %dt Plantings + %dd + = display_garden_plantings(garden) + .panel-footer + %dt Description + %dd + = display_garden_description(garden) diff --git a/app/views/gardens/index.html.haml b/app/views/gardens/index.html.haml index 9fc122b36..12928b051 100644 --- a/app/views/gardens/index.html.haml +++ b/app/views/gardens/index.html.haml @@ -14,56 +14,19 @@ - else = render :partial => 'shared/signin_signup', :locals => { :to => 'add a new garden' } -- if @gardens.size > 0 - - %div.pagination - = page_entries_info @gardens, :model => "gardens" - = will_paginate @gardens - - %table.table.table-striped - %tr - - unless @owner - %th Owner - %th Garden name - %th Description - %th Location - %th Area - %th Active? - %th Plantings - %th +%div.pagination + = page_entries_info @gardens, :model => "gardens" + = will_paginate @gardens +.row + - if @gardens.size > 0 - @gardens.each do |garden| - %tr - - unless @owner - %td= link_to garden.owner.login_name, garden.owner - %td= link_to garden.name, garden - %td= garden.description - %td - - if ! garden.location.blank? - = link_to garden.location, place_path(garden.location) - %td - - if garden.area - = pluralize(garden.area, garden.area_unit) - %td= garden.active ? "Yes" : "No" - %td - - if garden.plantings.empty? - None - - else - %ul - - garden.plantings.current.each do |p| - %li - = p.quantity - = link_to p.crop.name, p - - if p.planted_at - planted on - = p.planted_at + .col-md-6 + =render :partial => 'gardens/thumbnail', :locals => {:garden => garden} + - else + %p There are no gardens to display. - %td= link_to 'Details', garden, :class => 'btn btn-default btn-xs' - - %div.pagination - = page_entries_info @gardens, :model => "gardens" - = will_paginate @gardens - -- else - %p There are no gardens to display. +%div.pagination + = page_entries_info @gardens, :model => "gardens" + = will_paginate @gardens diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index a4bcc0044..acc9bbf6c 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -6,10 +6,10 @@ %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body .row - .col-md-6 + .col-md-4 = link_to image_tag((harvest.crop.default_photo ? harvest.crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => harvest.crop.name, :class => 'img'), harvest.crop - .col-md-6 - %dl + .col-md-8 + %dl.dl-horizontal %dt Crop %dd= link_to harvest.crop.name, harvest.crop %dt Plant part diff --git a/app/views/seeds/_thumbnail.html.haml b/app/views/seeds/_thumbnail.html.haml new file mode 100644 index 000000000..0d9a29c63 --- /dev/null +++ b/app/views/seeds/_thumbnail.html.haml @@ -0,0 +1,26 @@ +.panel.panel-success + .panel-heading + %h3.panel-title + = link_to "#{seed.owner.login_name}'s seed", seed.owner + %a.pull-right{:href => edit_seed_path(seed), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} + .panel-body + .row + .col-md-4 + = link_to image_tag((seed.crop.default_photo ? seed.crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => seed.crop.name, :class => 'img'), seed.crop + .col-md-8 + %dl.dl-horizontal + %dt Crop + %dd= link_to seed.crop.name, seed.crop + %dt Plant before + %dd= seed.plant_before + %dt Quantity + %dd= seed.quantity + %dt Will trade to + %dd= seed.tradable_to + %dt From location + %dd= seed.owner.location + .panel-footer + %dt Description + %dd + = display_seed_description(seed) diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index 0554984de..800c48417 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -23,52 +23,23 @@ %div.pagination = page_entries_info @seeds, :model => "seeds" = will_paginate @seeds - -- if @seeds.size > 0 - - %table.table.table-striped - %tr - - unless @owner - %th Owner - %th Crop - %th Description - %th Quantity - %th Plant before - %th Will trade to - %th From location - %th - +.row + - if @seeds.size > 0 - @seeds.each do |seed| - %tr - - unless @owner - %td= link_to seed.owner.login_name, seed.owner - %td= link_to seed.crop.name, seed.crop - %td= seed.description - %td= seed.quantity - %td= seed.plant_before - %td= seed.tradable? ? seed.tradable_to : '' - %td - - if seed.tradable? - - if seed.owner.location.blank? - unspecified - - else - = link_to seed.owner.location, place_path(seed.owner.location) - %td - = link_to 'Details', seed, :class => 'btn btn-default btn-xs' - - if can? :edit, seed - = link_to 'Edit', edit_seed_path(seed), :class => 'btn btn-default btn-xs' + .col-md-6 + =render :partial => 'seeds/thumbnail', :locals => {:seed => seed} - %div.pagination - = page_entries_info @seeds, :model => "seeds" - = will_paginate @seeds +%div.pagination + = page_entries_info @seeds, :model => "seeds" + = will_paginate @seeds - %ul.list-inline - %li The data on this page is available in the following formats: - - if @owner - %li= link_to "CSV", seeds_by_owner_path(@owner, :format => 'csv') - %li= link_to "JSON", seeds_by_owner_path(@owner, :format => 'json') - %li= link_to "RSS", seeds_by_owner_path(@owner, :format => 'rss') - - else - %li= link_to "CSV", seeds_path(:format => 'csv') - %li= link_to "JSON", seeds_path(:format => 'json') - %li= link_to "RSS", seeds_path(:format => 'rss') +%ul.list-inline + %li The data on this page is available in the following formats: + - if @owner + %li= link_to "CSV", seeds_by_owner_path(@owner, :format => 'csv') + %li= link_to "JSON", seeds_by_owner_path(@owner, :format => 'json') + %li= link_to "RSS", seeds_by_owner_path(@owner, :format => 'rss') + - else + %li= link_to "CSV", seeds_path(:format => 'csv') + %li= link_to "JSON", seeds_path(:format => 'json') + %li= link_to "RSS", seeds_path(:format => 'rss') From 7e03ef16871257430a9ff9724508eeecab466e43 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 09:56:21 +0800 Subject: [PATCH 169/392] Fixed display of plantings on gardens thumbnail. --- app/assets/stylesheets/overrides.css.less | 4 +++ app/helpers/gardens_helper.rb | 33 +++++++++-------------- app/helpers/harvests_helper.rb | 4 +-- app/helpers/seeds_helper.rb | 4 +-- app/views/gardens/_thumbnail.html.haml | 28 ++++++++++++------- app/views/harvests/_thumbnail.html.haml | 8 +++--- app/views/seeds/_thumbnail.html.haml | 10 +++---- 7 files changed, 46 insertions(+), 45 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index ccb462404..5be07c494 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -328,3 +328,7 @@ html, body { .panel-footer{ height: 6em; } + +#gardens_panel_body{ + height: 20em; +} diff --git a/app/helpers/gardens_helper.rb b/app/helpers/gardens_helper.rb index 9eb40e21d..b4fb49d06 100644 --- a/app/helpers/gardens_helper.rb +++ b/app/helpers/gardens_helper.rb @@ -4,29 +4,22 @@ module GardensHelper if garden.description.nil? "no description provided." else - output = truncate(garden.description, length: 130, omission: '... ') - output += link_to('[Read more]', garden_path(garden)) if garden.description.size > 130 - output.html_safe + truncate(garden.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", garden_path(garden) } end end - def display_garden_plantings(garden) - if garden.plantings.empty? - None + def display_garden_plantings(plantings) + if plantings.blank? + "None" else - output = "" - garden.plantings.current.each do |p| - output = p.quantity.nil? ? "0 " : "#{p.quantity} " - output += link_to p.crop.name, p - output = output.html_safe - if p.planted_at - output += ", planted on #{p.planted_at}" - end - end - - output = truncate(output, length: 100, omission: '... ') - output += link_to('[View more plantings]', garden_path(garden)) if output.size > 100 - output.html_safe + output = "" + plantings.first(2).each do |planting| + output += "
  • " + output += planting.quantity.nil? ? "0 " : "#{planting.quantity} " + output += link_to planting.crop.name, planting.crop + output += ", planted on #{planting.planted_at}
  • " + end + output.html_safe end end -end \ No newline at end of file +end diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index 7a5848066..b4c5bead4 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -41,9 +41,7 @@ module HarvestsHelper if harvest.description.nil? "no description provided." else - output = truncate(harvest.description, length: 130, omission: '... ') - output += link_to('[Read more]', harvest_path(harvest)) if harvest.description.size > 130 - output.html_safe + truncate(harvest.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", harvest_path(harvest) } end end diff --git a/app/helpers/seeds_helper.rb b/app/helpers/seeds_helper.rb index 728ed7215..2d4f5a299 100644 --- a/app/helpers/seeds_helper.rb +++ b/app/helpers/seeds_helper.rb @@ -4,9 +4,7 @@ module SeedsHelper if seed.description.nil? "no description provided." else - output = truncate(seed.description, length: 130, omission: '... ') - output += link_to('[Read more]', seed_path(seed)) if seed.description.size > 130 - output.html_safe + truncate(seed.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", seed_path(seed) } end end diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index 6c3ff48c0..926a9a258 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -4,23 +4,31 @@ = link_to "#{garden.owner.login_name}'s garden", garden.owner %a.pull-right{:href => edit_garden_path(garden), :role => "button"} %span.glyphicon.glyphicon-pencil{:title => "Edit"} - .panel-body + .panel-body{:id => "gardens_panel_body"} .row .col-md-4 = link_to image_tag((garden.default_photo ? garden.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => garden.name, :class => 'img'), garden .col-md-8 %dl.dl-horizontal - %dt Name + %dt Name : %dd= link_to garden.name, garden - %dt Location - %dd= link_to garden.location, place_path(garden.location) - %dt Area - %dd= garden.area.nil? ? "not specified" : pluralize(garden.area, garden.area_unit) - %dt Active? - %dd= garden.active ? "Yes" : "No" - %dt Plantings + %dt Location : %dd - = display_garden_plantings(garden) + - if garden.location.blank? + not specified + - else + = link_to garden.location, place_path(garden.location) + %dt Area : + %dd= garden.area.nil? ? "not specified" : pluralize(garden.area, garden.area_unit) + %dt Active? : + %dd= garden.active ? "Yes" : "No" + .col-md-12 + %b + = "#{pluralize(garden.plantings.count, "Planting")} : " + = display_garden_plantings(garden.plantings) + - if garden.plantings.count > 2 + %br + = link_to "See more plantings >>", garden_path(garden) .panel-footer %dt Description %dd diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index acc9bbf6c..aeb6e08f2 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -10,13 +10,13 @@ = link_to image_tag((harvest.crop.default_photo ? harvest.crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => harvest.crop.name, :class => 'img'), harvest.crop .col-md-8 %dl.dl-horizontal - %dt Crop + %dt Crop : %dd= link_to harvest.crop.name, harvest.crop - %dt Plant part + %dt Plant part : %dd= link_to harvest.plant_part, harvest.plant_part - %dt Quantity + %dt Quantity : %dd= display_quantity(harvest) - %dt Harvest date + %dt Harvest date : %dd= harvest.harvested_at .panel-footer %dt Description diff --git a/app/views/seeds/_thumbnail.html.haml b/app/views/seeds/_thumbnail.html.haml index 0d9a29c63..2bfe5a02c 100644 --- a/app/views/seeds/_thumbnail.html.haml +++ b/app/views/seeds/_thumbnail.html.haml @@ -10,15 +10,15 @@ = link_to image_tag((seed.crop.default_photo ? seed.crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => seed.crop.name, :class => 'img'), seed.crop .col-md-8 %dl.dl-horizontal - %dt Crop + %dt Crop : %dd= link_to seed.crop.name, seed.crop - %dt Plant before + %dt Plant before : %dd= seed.plant_before - %dt Quantity + %dt Quantity : %dd= seed.quantity - %dt Will trade to + %dt Will trade to : %dd= seed.tradable_to - %dt From location + %dt From location : %dd= seed.owner.location .panel-footer %dt Description From a97acfb1ca5f9f557323698fc71210f0fbf07d2a Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 10:03:03 +0800 Subject: [PATCH 170/392] Fixed display of edit glyphicon based on edit priviledge. --- app/views/gardens/_thumbnail.html.haml | 5 +++-- app/views/harvests/_thumbnail.html.haml | 5 +++-- app/views/seeds/_thumbnail.html.haml | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index 926a9a258..d3a65e4dd 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -2,8 +2,9 @@ .panel-heading %h3.panel-title = link_to "#{garden.owner.login_name}'s garden", garden.owner - %a.pull-right{:href => edit_garden_path(garden), :role => "button"} - %span.glyphicon.glyphicon-pencil{:title => "Edit"} + - if can? :edit, garden + %a.pull-right{:href => edit_garden_path(garden), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body{:id => "gardens_panel_body"} .row .col-md-4 diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index aeb6e08f2..62195ac22 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -2,8 +2,9 @@ .panel-heading %h3.panel-title = link_to "#{harvest.owner.login_name}'s harvest", harvest.owner - %a.pull-right{:href => edit_harvest_path(harvest), :role => "button"} - %span.glyphicon.glyphicon-pencil{:title => "Edit"} + - if can? :edit, harvest + %a.pull-right{:href => edit_harvest_path(harvest), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body .row .col-md-4 diff --git a/app/views/seeds/_thumbnail.html.haml b/app/views/seeds/_thumbnail.html.haml index 2bfe5a02c..be710b878 100644 --- a/app/views/seeds/_thumbnail.html.haml +++ b/app/views/seeds/_thumbnail.html.haml @@ -2,8 +2,9 @@ .panel-heading %h3.panel-title = link_to "#{seed.owner.login_name}'s seed", seed.owner - %a.pull-right{:href => edit_seed_path(seed), :role => "button"} - %span.glyphicon.glyphicon-pencil{:title => "Edit"} + - if can? :edit, seed + %a.pull-right{:href => edit_seed_path(seed), :role => "button"} + %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body .row .col-md-4 From 611adc0728f05ddcec90d412e2a8a9970ecd25a8 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 10:30:26 +0800 Subject: [PATCH 171/392] Fixed test errors for seeds and garden thumbnails. --- app/views/gardens/_thumbnail.html.haml | 2 +- app/views/seeds/_thumbnail.html.haml | 2 +- spec/features/seeds/misc_seeds_spec.rb | 2 +- spec/views/gardens/index.html.haml_spec.rb | 46 --------------- spec/views/seeds/index.html.haml_spec.rb | 69 ---------------------- 5 files changed, 3 insertions(+), 118 deletions(-) delete mode 100644 spec/views/gardens/index.html.haml_spec.rb delete mode 100644 spec/views/seeds/index.html.haml_spec.rb diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index d3a65e4dd..4ad75d831 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -26,7 +26,7 @@ .col-md-12 %b = "#{pluralize(garden.plantings.count, "Planting")} : " - = display_garden_plantings(garden.plantings) + = display_garden_plantings(garden.plantings.current) - if garden.plantings.count > 2 %br = link_to "See more plantings >>", garden_path(garden) diff --git a/app/views/seeds/_thumbnail.html.haml b/app/views/seeds/_thumbnail.html.haml index be710b878..1968ec254 100644 --- a/app/views/seeds/_thumbnail.html.haml +++ b/app/views/seeds/_thumbnail.html.haml @@ -3,7 +3,7 @@ %h3.panel-title = link_to "#{seed.owner.login_name}'s seed", seed.owner - if can? :edit, seed - %a.pull-right{:href => edit_seed_path(seed), :role => "button"} + %a.pull-right{:href => edit_seed_path(seed), :role => "button", :id => "edit_seed_glyphicon"} %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body .row diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 4c02ceecf..b7a4c4541 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -13,7 +13,7 @@ feature "seeds" do scenario "button on index to edit seed" do seed = FactoryGirl.create(:seed, :owner => @member) visit seeds_path - click_link "Edit" + click_link "edit_seed_glyphicon" current_path.should eq edit_seed_path(seed) page.should have_content 'Editing seeds' end diff --git a/spec/views/gardens/index.html.haml_spec.rb b/spec/views/gardens/index.html.haml_spec.rb deleted file mode 100644 index f776d6052..000000000 --- a/spec/views/gardens/index.html.haml_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe "gardens/index" do - before(:each) do - controller.stub(:current_user) { nil } - @owner = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @owner) - @finished_planting = FactoryGirl.create(:finished_planting, :garden => @garden) - page = 1 - per_page = 2 - total_entries = 2 - gardens = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| - pager.replace([@garden, @garden]) - end - assign(:gardens, gardens) - end - - it "renders a list of gardens" do - render - # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => @garden.name, :count => 2 - assert_select "tr>td>a", :text => @garden.location, :count => 2 - assert_select "tr>td", :text => pluralize(@garden.area, @garden.area_unit), :count => 2 - end - - it "does not show finished plantings" do - render - expect(rendered).to_not have_content(@finished_planting.crop_name) - end -end diff --git a/spec/views/seeds/index.html.haml_spec.rb b/spec/views/seeds/index.html.haml_spec.rb deleted file mode 100644 index 0cf2ade0b..000000000 --- a/spec/views/seeds/index.html.haml_spec.rb +++ /dev/null @@ -1,69 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe "seeds/index" do - before(:each) do - @member = FactoryGirl.create(:member) - sign_in @member - controller.stub(:current_user) { @member } - @seed1 = FactoryGirl.create(:seed, :owner => @member) - @page = 1 - @per_page = 2 - @total_entries = 2 - seeds = WillPaginate::Collection.create(@page, @per_page, @total_entries) do |pager| - pager.replace([ @seed1, @seed1 ]) - end - assign(:seeds, seeds) - end - - it "renders a list of seeds" do - render - assert_select "tr>td", :text => @seed1.crop.name, :count => 2 - assert_select "tr>td", :text => @seed1.owner.login_name, :count => 2 - assert_select "tr>td", :text => @seed1.quantity.to_s, :count => 2 - end - - context "tradable" do - before(:each) do - @owner = FactoryGirl.create(:london_member) - @seed1 = FactoryGirl.create(:tradable_seed, :owner => @owner) - seeds = WillPaginate::Collection.create(@page, @per_page, @total_entries) do |pager| - pager.replace([ @seed1, @seed1 ]) - end - assign(:seeds, seeds) - render - end - - it "shows tradable seeds" do - assert_select "tr>td", :text => @seed1.tradable_to, :count => 2 - end - - it "shows location of seed owner" do - assert_select "tr>td", :text => @owner.location, :count => 2 - assert_select 'a', :href => place_path(@owner.location) - end - end - - it "provides data links" do - render - rendered.should have_content "The data on this page is available in the following formats:" - assert_select "a", :href => seeds_path(:format => 'csv') - assert_select "a", :href => seeds_path(:format => 'json') - assert_select "a", :href => seeds_path(:format => 'rss') - end -end From aa3cf729c8ae6e28635db3300c438251d2088e2b Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Mon, 13 Jul 2015 08:40:35 +0800 Subject: [PATCH 172/392] Added feature tests for on gardens, seeds and harvests for the card based thumbnails --- app/views/gardens/_thumbnail.html.haml | 2 +- app/views/harvests/_thumbnail.html.haml | 2 +- spec/features/gardens_spec.rb | 12 ++++++++++++ .../features/harvests/harvesting_a_crop_spec.rb | 17 ++++++++++++----- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index 4ad75d831..c622098c9 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -3,7 +3,7 @@ %h3.panel-title = link_to "#{garden.owner.login_name}'s garden", garden.owner - if can? :edit, garden - %a.pull-right{:href => edit_garden_path(garden), :role => "button"} + %a.pull-right{:href => edit_garden_path(garden), :role => "button", :id => "edit_garden_glyphicon"} %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body{:id => "gardens_panel_body"} .row diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index 62195ac22..fbf482079 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -3,7 +3,7 @@ %h3.panel-title = link_to "#{harvest.owner.login_name}'s harvest", harvest.owner - if can? :edit, harvest - %a.pull-right{:href => edit_harvest_path(harvest), :role => "button"} + %a.pull-right{:href => edit_harvest_path(harvest), :role => "button", :id => "edit_harvest_glyphicon"} %span.glyphicon.glyphicon-pencil{:title => "Edit"} .panel-body .row diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 889fdd220..2d21a94ca 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -45,6 +45,18 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Area must be greater than or equal to 0" end + context "Clicking edit from the index page" do + + background do + visit gardens_path + end + + scenario "button on index to edit garden" do + first(".panel-title").click_link("edit_garden_glyphicon") + page.should have_content 'Edit garden' + end + end + scenario "Edit garden" do visit new_garden_path fill_in "Name", :with => "New garden" diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 3719164e1..0f0d25f7e 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -26,10 +26,18 @@ feature "Harvesting a crop", :js => true do expect(page).to have_content "Harvest was successfully created" end - scenario "Clicking link to owner's profile" do - visit harvests_by_owner_path(member) - click_link "View #{member}'s profile >>" - current_path.should eq member_path(member) + context "Clicking edit from the index page" do + let!(:harvest) { FactoryGirl.create(:harvest, :crop => maize, :owner => member) } + + background do + visit harvests_path + end + + scenario "button on index to edit harvest" do + click_link "edit_harvest_glyphicon" + current_path.should eq edit_harvest_path(harvest) + page.should have_content 'Editing harvest' + end end scenario "Harvesting from crop page" do @@ -63,4 +71,3 @@ feature "Harvesting a crop", :js => true do end end - From 33f28d1727bbb49d8da3e9e98cd9c66415620be4 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 10:07:10 -0400 Subject: [PATCH 173/392] Two tests required bangs on let statements in order to pass after refactoring. --- spec/features/planting_reminder_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index e90118359..10a723c90 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -26,8 +26,8 @@ feature "Planting reminder email", :js do end context "when member has some plantings" do - let(:p1) { create :planting, garden: member.gardens.first, owner: member } - let(:p2) { create :planting, garden: member.gardens.first, owner: member } + let!(:p1) { create :planting, garden: member.gardens.first, owner: member } + let!(:p2) { create :planting, garden: member.gardens.first, owner: member } scenario "lists plantings" do expect(mail).to have_content "most recent plantings you've told us about" @@ -48,8 +48,8 @@ feature "Planting reminder email", :js do end context "when member has some harvests" do - let(:h1) { create :harvest, owner: member } - let(:h2) { create :harvest, owner: member } + let!(:h1) { create :harvest, owner: member } + let!(:h2) { create :harvest, owner: member } scenario "lists harvests" do expect(mail).to have_content "the last few things you harvested were" @@ -58,4 +58,4 @@ feature "Planting reminder email", :js do expect(mail).to have_content "Harvested anything else lately?" end end -end +end \ No newline at end of file From ccde5b230b35c7b77916f0693b774404cd0e82fa Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 10:12:03 -0400 Subject: [PATCH 174/392] Comments for reasoning behind adding bangs to let statements. --- spec/features/planting_reminder_spec.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index 10a723c90..ad2173387 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -26,6 +26,8 @@ feature "Planting reminder email", :js do end context "when member has some plantings" do + # Bangs are used on the following 2 let blocks in order to ensure that the plantings are present + # in the database before the spec is run. let!(:p1) { create :planting, garden: member.gardens.first, owner: member } let!(:p2) { create :planting, garden: member.gardens.first, owner: member } @@ -48,6 +50,8 @@ feature "Planting reminder email", :js do end context "when member has some harvests" do + # Bangs are used on the following 2 let blocks in order to ensure that the plantings are present + # in the database before the spec is run. let!(:h1) { create :harvest, owner: member } let!(:h2) { create :harvest, owner: member } From 19adabc55f973d647b4bcc91fb71ffc32f92e1c9 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 11:27:17 -0400 Subject: [PATCH 175/392] Test for required and optional field display on Planting form. --- spec/features/plantings/planting_a_crop_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 808b70880..38a9e2672 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -14,6 +14,21 @@ feature "Planting a crop", :js => true do it_behaves_like "crop suggest", "planting" + it "has the required fields help text" do + expect(page).to have_content "* denotes a required field" + end + + it "displays required and optional fields properly" do + expect(page).to have_selector ".form-group.required", text: "What did you plant?" + expect(page).to have_selector ".form-group.required", text: "Where did you plant it?" + expect(page).to have_selector 'input#planting_planted_at[placeholder="optional"]' + expect(page).to have_selector 'input#planting_quantity[placeholder="optional"]' + expect(page).to have_selector 'select#planting_planted_from option', text: 'optional' + expect(page).to have_selector 'select#planting_sunniness option', text: 'optional' + expect(page).to have_selector 'textarea#planting_description[placeholder="optional"]' + expect(page).to have_selector 'input#planting_finished_at[placeholder="optional"]' + end + scenario "Creating a new planting" do fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" From efd63284360041ef155f9c15c460450e2df9000d Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 11:32:06 -0400 Subject: [PATCH 176/392] Test for required and optional field display on Harvest form. --- spec/features/harvests/harvesting_a_crop_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 3719164e1..70d914ccb 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -12,6 +12,17 @@ feature "Harvesting a crop", :js => true do it_behaves_like "crop suggest", "harvest", "crop" + it "has the required fields help text" do + expect(page).to have_content "* denotes a required field" + end + + it "displays required and optional fields properly" do + expect(page).to have_selector ".form-group.required", text: "What did you harvest?" + expect(page).to have_selector 'input#harvest_quantity[placeholder="optional"]' + expect(page).to have_selector 'input#harvest_weight_quantity[placeholder="optional"]' + expect(page).to have_selector 'textarea#harvest_description[placeholder="optional"]' + end + scenario "Creating a new harvest", :js => true do fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" From bc058b915298788ca7e9d3f34c4bbbfe818db8e6 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 11:36:40 -0400 Subject: [PATCH 177/392] Missed a few optional field placeholders on Seed form. --- app/views/seeds/_form.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index ac3c26df4..e4682c862 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -18,20 +18,20 @@ .form-group = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2', :placeholder => 'optional' .col-md-2 - = f.number_field :quantity, :class => 'form-control' + = f.number_field :quantity, :class => 'form-control', placeholder: 'optional' .form-group = f.label :plant_before, 'Plant before:', :class => 'control-label col-md-2' .col-md-2 - = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '' + = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '', placeholder: 'optional' .form-group = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2', :placeholder => 'optional' %fieldset .col-md-2 - = f.number_field :days_until_maturity_min, :class => 'form-control' + = f.number_field :days_until_maturity_min, :class => 'form-control', placeholder: 'optional' .col-md-1 = f.label :days_until_maturity_max, 'to', :class => 'control-label' .col-md-2 - = f.number_field :days_until_maturity_max, :class => 'form-control' + = f.number_field :days_until_maturity_max, :class => 'form-control', placeholder: 'optional' .col-md-1 = f.label :dummy, 'days', :class => 'control-label' .form-group.required From 69cb87fd0f5e236ee2e6bea3ed0497bff094a4b6 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 11:36:54 -0400 Subject: [PATCH 178/392] Test that required and optional fields are displaying properly on Seed form. --- spec/features/seeds/adding_seeds_spec.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index 8fa146724..d8933f594 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -12,6 +12,23 @@ feature "Seeds", :js => true do it_behaves_like "crop suggest", "seed", "crop" + it "has the required fields help text" do + expect(page).to have_content "* denotes a required field" + end + + it "displays required and optional fields properly" do + expect(page).to have_selector ".form-group.required", text: "Crop:" + expect(page).to have_selector 'input#seed_quantity[placeholder="optional"]' + expect(page).to have_selector 'input#seed_plant_before[placeholder="optional"]' + expect(page).to have_selector 'input#seed_days_until_maturity_min[placeholder="optional"]' + expect(page).to have_selector 'input#seed_days_until_maturity_max[placeholder="optional"]' + expect(page).to have_selector '.form-group.required', text: 'Organic?' + expect(page).to have_selector '.form-group.required', text: 'GMO?' + expect(page).to have_selector '.form-group.required', text: 'Heirloom?' + expect(page).to have_selector 'textarea#seed_description[placeholder="optional"]' + expect(page).to have_selector '.form-group.required', text: 'Will trade:' + end + scenario "Adding a new seed", :js => true do fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" From 5a33b2b7545233f2f8dc4b7c502f6a83f759cfcf Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Thu, 23 Jul 2015 11:42:04 -0400 Subject: [PATCH 179/392] Creating a directory for gardens under spec/features (to stay consistent with other features) and moving the creation specs from spec/gardens_spec.rb to spec/gardens/adding_gardens_spec.rb. Also added the required and optional field tests for Garden form. --- spec/features/gardens/adding_gardens_spec.rb | 37 ++++++++++++++++++++ spec/features/gardens_spec.rb | 19 +--------- 2 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 spec/features/gardens/adding_gardens_spec.rb diff --git a/spec/features/gardens/adding_gardens_spec.rb b/spec/features/gardens/adding_gardens_spec.rb new file mode 100644 index 000000000..2f2822c05 --- /dev/null +++ b/spec/features/gardens/adding_gardens_spec.rb @@ -0,0 +1,37 @@ +require 'rails_helper' + +feature "Gardens", :js do + let(:member) { FactoryGirl.create :member } + + background do + login_as member + visit new_garden_path + end + + it "has the required fields help text" do + expect(page).to have_content "* denotes a required field" + end + + it "displays required and optional fields properly" do + expect(page).to have_selector ".form-group.required", text: "Name" + expect(page).to have_selector 'textarea#garden_description[placeholder="optional"]' + expect(page).to have_selector 'input#garden_location[placeholder="optional"]' + expect(page).to have_selector 'input#garden_area[placeholder="optional"]' + end + + scenario "Create new garden" do + fill_in "Name", with: "New garden" + click_button "Save" + expect(page).to have_content "Garden was successfully created" + expect(page).to have_content "New garden" + end + + scenario "Refuse to create new garden with negative area" do + visit new_garden_path + fill_in "Name", with: "Negative Garden" + fill_in "Area", with: -5 + click_button "Save" + expect(page).not_to have_content "Garden was successfully created" + expect(page).to have_content "Area must be greater than or equal to 0" + end +end \ No newline at end of file diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 889fdd220..dfa67165c 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' feature "Planting a crop", :js => true do - let!(:garden) { FactoryGirl.create(:garden) } + let!(:garden) { FactoryGirl.create(:garden) } let!(:planting) { FactoryGirl.create(:planting, garden: garden, planted_at: Date.parse("2013-3-10")) } let!(:tomato) { FactoryGirl.create(:tomato) } let!(:finished_planting) { FactoryGirl.create(:finished_planting, garden: garden, crop: tomato) } @@ -28,23 +28,6 @@ feature "Planting a crop", :js => true do expect(page).not_to have_content "Mark as inactive" end - scenario "Create new garden" do - visit new_garden_path - fill_in "Name", :with => "New garden" - click_button "Save" - expect(page).to have_content "Garden was successfully created" - expect(page).to have_content "New garden" - end - - scenario "Refuse to create new garden with negative area" do - visit new_garden_path - fill_in "Name", :with => "Negative Garden" - fill_in "Area", :with => -5 - click_button "Save" - expect(page).not_to have_content "Garden was successfully created" - expect(page).to have_content "Area must be greater than or equal to 0" - end - scenario "Edit garden" do visit new_garden_path fill_in "Name", :with => "New garden" From b0d4f9c731e44152fc103d713f6e46f9e55d44f1 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 23 Jul 2015 13:56:07 -0400 Subject: [PATCH 180/392] switch homepage and members/ page member thumbnails to be a flexbox layout so it's more responsive. Fixes #780 --- app/assets/stylesheets/overrides.css.less | 21 ++++++++++++--- app/views/home/_members.html.haml | 6 ++--- app/views/members/_thumbnail.html.haml | 31 +++++++++++------------ app/views/members/index.html.haml | 6 ++--- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index 5be07c494..bf1943fd1 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -97,12 +97,25 @@ p.stats { font-weight: bold; } -.homepage-members { - height: 100px; +.member-cards { + display: flex; + flex: none; + flex-wrap: wrap; + justify-content: space-between; } +.member-thumbnail { + padding: .25em; -.homepage-members:nth-child(odd) { - margin-left: 0px; + div { + width: 5em; + display: inline-block; + vertical-align: top; + } + + div ~ div { + width: 15em; + padding-left: 1em; + } } #placesmap, #cropmap { diff --git a/app/views/home/_members.html.haml b/app/views/home/_members.html.haml index cca5829d6..aea526c21 100644 --- a/app/views/home/_members.html.haml +++ b/app/views/home/_members.html.haml @@ -2,12 +2,12 @@ .hidden-xs - members = Member.interesting.first(6) - if members.present? + %section %h2= t('.title') - .row + .member-cards - members.each do |m| - .col-md-4.homepage-members - = render :partial => "members/thumbnail", :locals => { :member => m } + = render :partial => "members/thumbnail", :locals => { :member => m } %p.text-right = link_to "#{t('.view_all')} »", members_path diff --git a/app/views/members/_thumbnail.html.haml b/app/views/members/_thumbnail.html.haml index c90faba8a..5f0f9c58d 100644 --- a/app/views/members/_thumbnail.html.haml +++ b/app/views/members/_thumbnail.html.haml @@ -1,17 +1,16 @@ - cache member do - .row - .member-thumbnail - .col-md-3 - = render :partial => "members/image_with_popover", :locals => { :member => member } - .col-md-9 - %p - = link_to member.login_name, member - - if ! member.location.blank? - %small - %br/ - %i= member.location - - if ! member.plantings.empty? - %small - %br/ - Recently planted: - != member.plantings.first(3).map{|p| link_to p.crop_name, p }.join(", ") + .member-thumbnail.panel + %div + = render :partial => "members/image_with_popover", :locals => { :member => member } + %div + %p + = link_to member.login_name, member + - if ! member.location.blank? + %small + %br/ + %i= member.location + - if ! member.plantings.empty? + %small + %br/ + Recently planted: + != member.plantings.first(3).map{|p| link_to p.crop_name, p }.join(", ") diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index 36ba70887..0fa659ede 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -10,11 +10,9 @@ = page_entries_info @members, :model => "members" = will_paginate @members -.row +.member-cards - @members.each do |m| - .col-md-4.three-across - .thumbnail - = render :partial => "members/thumbnail", :locals => { :member => m } + = render :partial => "members/thumbnail", :locals => { :member => m } %div.pagination = page_entries_info @members, :model => "members" From e3738ca0c67ef6808d207b2c4ebcabcf2161e39f Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 23 Jul 2015 13:56:23 -0400 Subject: [PATCH 181/392] whitespace tab/space correction --- app/helpers/gardens_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/gardens_helper.rb b/app/helpers/gardens_helper.rb index b4fb49d06..dfd0a2582 100644 --- a/app/helpers/gardens_helper.rb +++ b/app/helpers/gardens_helper.rb @@ -1,7 +1,7 @@ module GardensHelper def display_garden_description(garden) - if garden.description.nil? + if garden.description.nil? "no description provided." else truncate(garden.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", garden_path(garden) } From 9e2e93b5449bbf2712c395ee0d5305ac65ee4996 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 23 Jul 2015 21:57:22 +0100 Subject: [PATCH 182/392] Remove the last few .shoulds from spec/features --- spec/features/crops/crop_detail_page_spec.rb | 2 +- spec/features/gardens_spec.rb | 6 +++--- spec/features/harvests/harvesting_a_crop_spec.rb | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 0ed3b3308..e0232793d 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -161,7 +161,7 @@ feature "crop detail page" do login_as(member) visit crop_path(seed.crop) click_link "View your seeds" - current_path.should == seeds_by_owner_path(owner: member.slug) + expect(current_path).to eq seeds_by_owner_path(owner: member.slug) end end end diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 813140062..8ae4aa1da 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -46,14 +46,14 @@ feature "Planting a crop", :js => true do end context "Clicking edit from the index page" do - + background do visit gardens_path end - + scenario "button on index to edit garden" do first(".panel-title").click_link("edit_garden_glyphicon") - page.should have_content 'Edit garden' + expect(page).to have_content 'Edit garden' end end diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 8d7a2d26f..7d61cf68c 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -35,8 +35,8 @@ feature "Harvesting a crop", :js do scenario "button on index to edit harvest" do click_link "edit_harvest_glyphicon" - current_path.should eq edit_harvest_path(harvest) - page.should have_content 'Editing harvest' + expect(current_path).to eq edit_harvest_path(harvest) + expect(page).to have_content 'Editing harvest' end end From 48649d19868152610c4e2603b8128c91627e6553 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 23 Jul 2015 22:00:06 +0100 Subject: [PATCH 183/392] Clarify comment on an order-dependent feature test --- spec/features/planting_reminder_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index ad2173387..2891b690e 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -27,7 +27,7 @@ feature "Planting reminder email", :js do context "when member has some plantings" do # Bangs are used on the following 2 let blocks in order to ensure that the plantings are present - # in the database before the spec is run. + # in the database before the email is generated: otherwise, they won't be present in the email. let!(:p1) { create :planting, garden: member.gardens.first, owner: member } let!(:p2) { create :planting, garden: member.gardens.first, owner: member } @@ -62,4 +62,4 @@ feature "Planting reminder email", :js do expect(mail).to have_content "Harvested anything else lately?" end end -end \ No newline at end of file +end From 96b0198d4130a2b02045db7d805ffdb5325632ff Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 23 Jul 2015 23:05:39 +0100 Subject: [PATCH 184/392] Replace remaining calls to count() with size() The couple that aren't removed are required: for instance, there's a Crop.count method, but no Crop.size method. --- app/views/gardens/_thumbnail.html.haml | 4 ++-- app/views/home/_stats.html.haml | 4 ++-- spec/controllers/photos_controller_spec.rb | 4 ++-- spec/models/member_spec.rb | 6 +++--- spec/models/photo_spec.rb | 12 ++++++------ .../activemerchant-1.33.0/lib/support/ssl_verify.rb | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index c622098c9..bd3fc7eb1 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -25,9 +25,9 @@ %dd= garden.active ? "Yes" : "No" .col-md-12 %b - = "#{pluralize(garden.plantings.count, "Planting")} : " + = "#{pluralize(garden.plantings.size, "Planting")} : " = display_garden_plantings(garden.plantings.current) - - if garden.plantings.count > 2 + - if garden.plantings.size > 2 %br = link_to "See more plantings >>", garden_path(garden) .panel-footer diff --git a/app/views/home/_stats.html.haml b/app/views/home/_stats.html.haml index e13f74719..53ffd2492 100644 --- a/app/views/home/_stats.html.haml +++ b/app/views/home/_stats.html.haml @@ -1,7 +1,7 @@ - cache("homepage_stats") do %p.stats - = t('.message_html', { member: link_to(t('.member_linktext', count: Member.confirmed.count.to_i), members_path), - number_crops: link_to(t('.number_crops_linktext', count: Crop.count.to_i), crops_path), + = t('.message_html', { member: link_to(t('.member_linktext', count: Member.confirmed.size.to_i), members_path), + number_crops: link_to(t('.number_crops_linktext', count: Crop.count.to_i), crops_path), number_plantings: link_to(t('.number_plantings_linktext', count: Planting.count.to_i), plantings_path), number_gardens: link_to(t('.number_gardens_linktext', count: Garden.count.to_i), gardens_path) }) diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 286b23b64..603959b46 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -115,7 +115,7 @@ describe PhotosController do post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, :type => "planting", :id => planting.id } - Photo.last.plantings.count.should eq 1 + Photo.last.plantings.size.should eq 1 end it "attaches the photo to a harvest" do @@ -140,7 +140,7 @@ describe PhotosController do post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, :type => "harvest", :id => harvest.id } - Photo.last.harvests.count.should eq 1 + Photo.last.harvests.size.should eq 1 end end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index b91584953..66ea5a597 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -23,7 +23,7 @@ describe 'member' do end it 'should have a default garden' do - member.gardens.count.should == 1 + member.gardens.size.should == 1 end it 'should have a accounts entry' do @@ -221,12 +221,12 @@ describe 'member' do end it 'sees confirmed members' do - Member.confirmed.count.should == 2 + Member.confirmed.size.should == 2 end it 'ignores unconfirmed members' do @member3 = FactoryGirl.create(:unconfirmed_member) - Member.confirmed.count.should == 2 + Member.confirmed.size.should == 2 end end diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index 650f0f57c..36a9eb068 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -11,19 +11,19 @@ describe Photo do context "adds photos" do it 'to a planting' do planting.photos << photo - expect(planting.photos.count).to eq 1 + expect(planting.photos.size).to eq 1 expect(planting.photos.first).to eq photo end it 'to a harvest' do harvest.photos << photo - expect(harvest.photos.count).to eq 1 + expect(harvest.photos.size).to eq 1 expect(harvest.photos.first).to eq photo end it 'to a garden' do garden.photos << photo - expect(garden.photos.count).to eq 1 + expect(garden.photos.size).to eq 1 expect(garden.photos.first).to eq photo end end @@ -32,19 +32,19 @@ describe Photo do it 'from a planting' do planting.photos << photo photo.destroy - expect(planting.photos.count).to eq 0 + expect(planting.photos.size).to eq 0 end it 'from a harvest' do harvest.photos << photo photo.destroy - expect(harvest.photos.count).to eq 0 + expect(harvest.photos.size).to eq 0 end it 'from a garden' do garden.photos << photo photo.destroy - expect(garden.photos.count).to eq 0 + expect(garden.photos.size).to eq 0 end it "automatically if unused" do diff --git a/vendor/gems/activemerchant-1.33.0/lib/support/ssl_verify.rb b/vendor/gems/activemerchant-1.33.0/lib/support/ssl_verify.rb index 1ba28878a..ccb6650d5 100644 --- a/vendor/gems/activemerchant-1.33.0/lib/support/ssl_verify.rb +++ b/vendor/gems/activemerchant-1.33.0/lib/support/ssl_verify.rb @@ -10,7 +10,7 @@ class SSLVerify def test_gateways success, failed, missing, errored, disabled = [], [], [], [], [] - puts "Verifying #{@gateways.count} SSL certificates\n\n" + puts "Verifying #{@gateways.size} SSL certificates\n\n" @gateways.each do |g| if !g.live_url From f29c0ad08520ede88b2de2306729dcc6fafa6cdc Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 23 Jul 2015 23:21:55 +0100 Subject: [PATCH 185/392] Replace .length calls with .size --- app/models/planting.rb | 2 +- spec/models/crop_spec.rb | 6 +++--- spec/models/forum_spec.rb | 2 +- spec/models/garden_spec.rb | 2 +- spec/models/member_spec.rb | 4 ++-- spec/models/planting_spec.rb | 2 +- spec/models/post_spec.rb | 6 +++--- spec/models/seed_spec.rb | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index f06ccf9ac..900156b2a 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -105,7 +105,7 @@ class Planting < ActiveRecord::Base if differences.compact.empty? nil else - differences.compact.sum/differences.compact.length + differences.compact.sum/differences.compact.size end end diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 724567626..90e02c5fc 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -232,7 +232,7 @@ describe Crop do Crop.interesting.should include @crop1 Crop.interesting.should include @crop2 - Crop.interesting.length.should == 2 + Crop.interesting.size.should == 2 end it 'ignores crops without plantings' do @@ -254,7 +254,7 @@ describe Crop do Crop.interesting.should include @crop1 Crop.interesting.should_not include @crop2 - Crop.interesting.length.should == 1 + Crop.interesting.size.should == 1 end @@ -280,7 +280,7 @@ describe Crop do Crop.interesting.should include @crop1 Crop.interesting.should_not include @crop2 - Crop.interesting.length.should == 1 + Crop.interesting.size.should == 1 end end diff --git a/spec/models/forum_spec.rb b/spec/models/forum_spec.rb index dfebfa356..7c26c8f4b 100644 --- a/spec/models/forum_spec.rb +++ b/spec/models/forum_spec.rb @@ -19,7 +19,7 @@ describe Forum do it "has many posts" do @post1 = FactoryGirl.create(:forum_post, :forum => forum) @post2 = FactoryGirl.create(:forum_post, :forum => forum) - forum.posts.length.should == 2 + forum.posts.size.should == 2 end it "orders posts in reverse chron order" do diff --git a/spec/models/garden_spec.rb b/spec/models/garden_spec.rb index 6eebba460..ab52e2fac 100644 --- a/spec/models/garden_spec.rb +++ b/spec/models/garden_spec.rb @@ -88,7 +88,7 @@ describe Garden do garden = FactoryGirl.create(:garden, :owner => owner) @planting1 = FactoryGirl.create(:planting, :garden => garden) @planting2 = FactoryGirl.create(:planting, :garden => garden) - garden.plantings.length.should == 2 + garden.plantings.size.should == 2 all = Planting.count garden.destroy Planting.count.should == all - 2 diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 66ea5a597..93760a904 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -61,13 +61,13 @@ describe 'member' do it "has many comments" do @comment1 = FactoryGirl.create(:comment, :author => member) @comment2 = FactoryGirl.create(:comment, :author => member) - member.comments.length.should == 2 + member.comments.size.should == 2 end it "has many forums" do @forum1 = FactoryGirl.create(:forum, :owner => member) @forum2 = FactoryGirl.create(:forum, :owner => member) - member.forums.length.should == 2 + member.forums.size.should == 2 end it 'has location and lat/long fields' do diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 16bb8b613..659636c5e 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -229,7 +229,7 @@ describe Planting do context "with howmany argument" do it "only returns the number asked for" do @plantings = FactoryGirl.create_list(:planting, 10) - Planting.interesting(3, false).length.should eq 3 + Planting.interesting(3, false).size.should eq 3 end end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index cb9324d3f..c56a5b301 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -24,7 +24,7 @@ describe Post do @datestr = @time.strftime("%Y%m%d") # 2 digit day and month, full-length years # Counting digits using Math.log is not precise enough! - @datestr.length.should == 4 + @time.year.to_s.size + @datestr.size.should == 4 + @time.year.to_s.size @post.slug.should == "#{member.login_name}-#{@datestr}-a-post" end @@ -32,14 +32,14 @@ describe Post do @post = FactoryGirl.create(:post, :author => member) @comment1 = FactoryGirl.create(:comment, :post => @post) @comment2 = FactoryGirl.create(:comment, :post => @post) - @post.comments.length.should == 2 + @post.comments.size.should == 2 end it "destroys comments when deleted" do @post = FactoryGirl.create(:post, :author => member) @comment1 = FactoryGirl.create(:comment, :post => @post) @comment2 = FactoryGirl.create(:comment, :post => @post) - @post.comments.length.should == 2 + @post.comments.size.should == 2 all = Comment.count @post.destroy Comment.count.should == all - 2 diff --git a/spec/models/seed_spec.rb b/spec/models/seed_spec.rb index 58ae56ea7..65008adcc 100644 --- a/spec/models/seed_spec.rb +++ b/spec/models/seed_spec.rb @@ -146,7 +146,7 @@ describe Seed do Seed.interesting.should_not include @seed2 Seed.interesting.should_not include @seed3 Seed.interesting.should_not include @seed4 - Seed.interesting.length.should == 1 + Seed.interesting.size.should == 1 end end From 40b5a47aae4162ad813e89a40e38160a357fa83c Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 23 Jul 2015 23:22:45 +0100 Subject: [PATCH 186/392] Remove trailing whitespace --- app/assets/javascripts/finish_planting.js.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/finish_planting.js.coffee b/app/assets/javascripts/finish_planting.js.coffee index b8139b7fe..f52409a66 100644 --- a/app/assets/javascripts/finish_planting.js.coffee +++ b/app/assets/javascripts/finish_planting.js.coffee @@ -9,11 +9,11 @@ jQuery -> finished = $('#planting_finished_at') if @checked if previousValue.length - date = previousValue + date = previousValue finished.val(date) else finished.trigger('focus') else previousValue = finished.val() finished.val('') - ) \ No newline at end of file + ) From f970fc4db27628a8107ebcbba0e6063b977e27d8 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 24 Jul 2015 11:09:22 +0100 Subject: [PATCH 187/392] Fix another whitespace problem. --- app/helpers/gardens_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/gardens_helper.rb b/app/helpers/gardens_helper.rb index dfd0a2582..57f0c7bc6 100644 --- a/app/helpers/gardens_helper.rb +++ b/app/helpers/gardens_helper.rb @@ -2,7 +2,7 @@ module GardensHelper def display_garden_description(garden) if garden.description.nil? - "no description provided." + "no description provided." else truncate(garden.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", garden_path(garden) } end From 91a128ae7eb8b2ba400e7c4efd5520acf499cf6e Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 24 Jul 2015 15:09:54 +0100 Subject: [PATCH 188/392] Check existence of secret token before using it. People were forgetting to create config/environment.yml, which meant that RAILS_SECRET_TOKEN wasn't being set, which meant that all tests involving notifications failed. Unfortunately, the resulting wall of error messages (https://gist.github.com/sha1sum/5debae6b700ff8fc0c76) did not make the root cause remotely clear, leading to much confusion and head-scratching all round. This commit checks for the existence of RAILS_SECRET_TOKEN and fails with an informative error message if it's missing. --- app/mailers/notifier.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index a37d65d67..5ffb862d6 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -2,12 +2,19 @@ class Notifier < ActionMailer::Base include NotificationsHelper default from: "Growstuff " + def verifier() + if ENV['RAILS_SECRET_TOKEN'] + return ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) + else + raise "RAILS_SECRET_TOKEN environment variable not set - have you created config/application.yml?" + end + end + def notify(notification) @notification = notification @reply_link = reply_link(@notification) # Encrypting - verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) @signed_message = verifier.generate ({ member_id: @notification.recipient.id, type: :send_notification_email }) mail(:to => @notification.recipient.email, @@ -21,7 +28,6 @@ class Notifier < ActionMailer::Base @harvests = @member.harvests.first(5) # Encrypting - verifier = ActiveSupport::MessageVerifier.new(ENV['RAILS_SECRET_TOKEN']) @signed_message = verifier.generate ({ member_id: @member.id, type: :send_planting_reminder }) if @member.send_planting_reminder From cbb50df8d04a414699f06eb190a25e40b53b85dd Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Sat, 25 Jul 2015 13:18:30 -0400 Subject: [PATCH 189/392] Resolved #562 - Pagination of notifications. --- Gemfile | 3 +++ Gemfile.lock | 8 ++++++++ app/controllers/notifications_controller.rb | 2 +- app/views/notifications/index.html.haml | 2 ++ spec/features/notifications_spec.rb | 21 +++++++++++++++++++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index bb774b703..ffd1da341 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,9 @@ gem 'ruby-units' # for unit conversion gem 'comfortable_mexican_sofa', '~> 1.12.0' # content management system +gem 'kaminari' # pagination +gem 'bootstrap-kaminari-views' # bootstrap views for kaminari + # vendored activemerchant for testing- needed for bogus paypal # gateway monkeypatch gem 'activemerchant', '1.33.0', diff --git a/Gemfile.lock b/Gemfile.lock index fef7b8258..261a40185 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -64,6 +64,9 @@ GEM bonsai-elasticsearch-rails (0.0.4) bootstrap-datepicker-rails (1.3.0.2) railties (>= 3.0) + bootstrap-kaminari-views (0.0.5) + kaminari (>= 0.13) + rails (>= 3.1) bootstrap-sass (3.3.3) autoprefixer-rails (>= 5.0.0.1) sass (>= 3.2.19) @@ -216,6 +219,9 @@ GEM railties (>= 3.2) sprockets-rails json (1.8.2) + kaminari (0.16.3) + actionpack (>= 3.0.0) + activesupport (>= 3.0.0) kgio (2.9.2) kramdown (1.5.0) launchy (2.4.3) @@ -402,6 +408,7 @@ DEPENDENCIES bluecloth bonsai-elasticsearch-rails bootstrap-datepicker-rails + bootstrap-kaminari-views bundler (>= 1.1.5) byebug cancancan (~> 1.9) @@ -430,6 +437,7 @@ DEPENDENCIES jquery-rails jquery-ui-rails (~> 5.0.2) js-routes + kaminari leaflet-markercluster-rails leaflet-rails less (~> 2.5.0) diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 4608d3f99..f1934ded3 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -5,7 +5,7 @@ class NotificationsController < ApplicationController # GET /notifications def index - @notifications = Notification.where(recipient_id: current_member) + @notifications = Notification.where(recipient_id: current_member).page(params[:page]) respond_to do |format| format.html # index.html.erb diff --git a/app/views/notifications/index.html.haml b/app/views/notifications/index.html.haml index d5b373606..e5352ad26 100644 --- a/app/views/notifications/index.html.haml +++ b/app/views/notifications/index.html.haml @@ -1,6 +1,7 @@ - content_for :title, "Inbox" - if @notifications.size > 0 + = paginate @notifications, theme: 'twitter-bootstrap-3' %table.table.table-striped %tr %th From @@ -28,5 +29,6 @@ %strong= n.created_at %td = link_to 'Delete', n, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + = paginate @notifications, theme: 'twitter-bootstrap-3' - else You have no messages. diff --git a/spec/features/notifications_spec.rb b/spec/features/notifications_spec.rb index 5135a1c72..bb1be5907 100644 --- a/spec/features/notifications_spec.rb +++ b/spec/features/notifications_spec.rb @@ -22,4 +22,25 @@ feature "Notifications", :js => true do expect(page).to have_content "Message was successfully sent" end end + + describe 'pagination' do + before do + 34.times { FactoryGirl.create :notification, recipient: recipient } + login_as recipient + visit notifications_path + end + + it 'has page navigation' do + expect(page).to have_selector 'a[rel="next"]' + end + + it 'paginates at 30 notifications per page' do + expect(page).to have_selector 'tr', count: 31 + end + + it 'navigates pages' do + first('a[rel="next"]').click + expect(page).to have_selector 'tr', count: 5 + end + end end \ No newline at end of file From 9d62c012f1088f3d6417092ecd33f3c4ea613f8f Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Sat, 25 Jul 2015 13:34:16 -0400 Subject: [PATCH 190/392] Resolves #617 - Open Service graphic link in footer --- app/views/layouts/_footer.html.haml | 3 +++ spec/features/footer_spec.rb | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index 946f45529..75e93f27f 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -7,3 +7,6 @@ != cms_snippet_content(:footer2) .col-md-4#footer3 != cms_snippet_content(:footer3) + %div(style="float: right;") + %a(href="http://opendefinition.org/ossd/") + %img(src="http://assets.okfn.org/images/ok_buttons/os_80x15_blue.png" alt="") diff --git a/spec/features/footer_spec.rb b/spec/features/footer_spec.rb index 400b153a4..6c0c7cead 100644 --- a/spec/features/footer_spec.rb +++ b/spec/features/footer_spec.rb @@ -2,11 +2,16 @@ require 'rails_helper' feature "footer" do + before { visit root_path } + scenario "footer is on home page" do - visit root_path expect(page).to have_css 'footer' end + it 'has the Open Service link and graphic' do + expect(page).to have_selector 'a[href="http://opendefinition.org/ossd/"]' + end + # NB: not testing specific content in the footer since I'm going to put them # in the CMS and they'll be variable. end From 362f7a78b179f6f10a4ffd39d51528cd0553a784 Mon Sep 17 00:00:00 2001 From: twconquest Date: Tue, 28 Jul 2015 19:33:05 +0000 Subject: [PATCH 191/392] Add feature test for showing roles --- app/views/members/_account.html.haml | 4 ++-- spec/features/member_profile_spec.rb | 12 ++++++++++++ spec/views/members/index.html.haml_spec.rb | 9 --------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/app/views/members/_account.html.haml b/app/views/members/_account.html.haml index f96a125cd..ae8333067 100644 --- a/app/views/members/_account.html.haml +++ b/app/views/members/_account.html.haml @@ -18,7 +18,7 @@ %br - if member.has_role? :admin Administrator - - if member.has_role? :crop_wrangler - Crop Wrangler + - if member.has_role? :crop_wrangler + Crop Wrangler - else Member diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 2c7343a8d..a5240c5b6 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -111,11 +111,23 @@ feature "member profile" do context "signed in member" do let(:member) { FactoryGirl.create(:member) } let(:other_member) { FactoryGirl.create(:member) } + let(:admin_member) { FactoryGirl.create(:admin_member) } + let(:crop_wrangler) { FactoryGirl.create(:crop_wrangling_member) } background do login_as(member) end + scenario "admin user's page" do + visit member_path(admin_member) + expect(page).to have_text "Admin" + end + + scenario "crop wrangler's page" do + visit member_path(crop_wrangler) + expect(page).to have_text "Crop Wrangler" + end + context "your own profile page" do background do visit member_path(member) diff --git a/spec/views/members/index.html.haml_spec.rb b/spec/views/members/index.html.haml_spec.rb index 5693c9f20..3c864d415 100644 --- a/spec/views/members/index.html.haml_spec.rb +++ b/spec/views/members/index.html.haml_spec.rb @@ -38,13 +38,4 @@ describe "members/index" do rendered.should have_content @member.location end - it 'should not be admin' do - rendered.should_not have_content "Administrator" - end - - it 'should not be crop_wrangler' do - rendered.should_not have_content "Crop Wrangler" - end - - end From e7d2ae2c409c3324cd8851042cdc434c2d752c23 Mon Sep 17 00:00:00 2001 From: twconquest Date: Tue, 28 Jul 2015 19:50:35 +0000 Subject: [PATCH 192/392] Add myself to CONTRIBUTORS.md --- CONTRIBUTORS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3fb5b66f6..11f85d3b3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -63,4 +63,5 @@ submit the change with your pull request. - Gabrielle DeWitt / [gabrielle27](https://github.com/gabrielle27) - Manmeet Singh / [manmeetsingh](https://github.com/manmeetsingh) - Jym Paul Carandang / [jacarandang](https://github.com/jacarandang) -- Anthony Atkinson / [sha1sum](https://github.com/sha1sum) \ No newline at end of file +- Anthony Atkinson / [sha1sum](https://github.com/sha1sum) +- Terence Conquest / [twconquest](https://github.com/twconquest) \ No newline at end of file From 29f3cc323881ddee59600a3d9b6b0a8d0a2f3b58 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Sat, 1 Aug 2015 11:39:51 -0400 Subject: [PATCH 193/392] Updating new test additions and edits to features/harvests with Rspec3 Ruby2 syntax. --- spec/features/harvests/harvesting_a_crop_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 1508feaa5..802f67a4d 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -23,8 +23,8 @@ feature "Harvesting a crop", :js do expect(page).to have_selector 'textarea#harvest_description[placeholder="optional"]' end - scenario "Creating a new harvest", :js => true do - fill_autocomplete "crop", :with => "mai" + scenario "Creating a new harvest", :js do + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_harvest" do fill_in "When?", with: "2014-06-15" @@ -38,7 +38,7 @@ feature "Harvesting a crop", :js do end context "Clicking edit from the index page" do - let!(:harvest) { FactoryGirl.create(:harvest, :crop => maize, :owner => member) } + let!(:harvest) { create :harvest, crop: maize, owner: member } background do visit harvests_path From 919c25ca674d3f90155409ab77a43d66223867f7 Mon Sep 17 00:00:00 2001 From: Anthony Atkinson Date: Sat, 1 Aug 2015 11:58:13 -0400 Subject: [PATCH 194/392] Fixing notifications index view spec to be compatible with new Kaminari pagination. --- spec/views/notifications/index.html.haml_spec.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/views/notifications/index.html.haml_spec.rb b/spec/views/notifications/index.html.haml_spec.rb index 04ecdd176..362037cce 100644 --- a/spec/views/notifications/index.html.haml_spec.rb +++ b/spec/views/notifications/index.html.haml_spec.rb @@ -26,10 +26,11 @@ describe "notifications/index" do before(:each) do @notification = FactoryGirl.create(:notification, :sender => @member, :recipient => @member) - assign(:notifications, [ @notification, @notification ]) + assign(:notifications, Kaminari.paginate_array([ @notification, @notification ]).page(1)) render end + it "renders a list of notifications" do assert_select "table" assert_select "tr>td", :text => @notification.sender.to_s, :count => 2 @@ -45,7 +46,7 @@ describe "notifications/index" do it "shows (no subject)" do @notification = FactoryGirl.create(:notification, :sender => @member, :recipient => @member, :subject => nil) - assign(:notifications, [@notification]) + assign(:notifications, Kaminari.paginate_array([@notification]).page(1)) render rendered.should have_content "(no subject)" end @@ -55,7 +56,7 @@ describe "notifications/index" do it "shows (no subject)" do @notification = FactoryGirl.create(:notification, :sender => @member, :recipient => @member, :subject => " ") - assign(:notifications, [@notification]) + assign(:notifications, Kaminari.paginate_array([@notification]).page(1)) render rendered.should have_content "(no subject)" end From 43fe29f113f1cec09334c2b8d90c14c9b6458181 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 09:18:32 +0000 Subject: [PATCH 195/392] Fixing relative caching of post summary on homepage, fixed #789 --- app/views/posts/_summary.html.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 65fdeb567..9a2a479e1 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -15,7 +15,8 @@ %td.hidden-xs =link_to post.author, post.author %td - = distance_of_time_in_words(post.recent_activity, Time.zone.now) - ago + = post.recent_activity.to_date.to_formatted_s(:short) + // once the site gets more active, can change this to include time as well + // can't make it relative (distance_time as it's cached %td.hidden-xs = post.comments.size.to_s From 6f95f1fecf17e4c9fbed9cb1449a3cac424d8708 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 09:20:06 +0000 Subject: [PATCH 196/392] Clarifying comment --- app/views/posts/_summary.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 9a2a479e1..59a58dd47 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -17,6 +17,6 @@ %td = post.recent_activity.to_date.to_formatted_s(:short) // once the site gets more active, can change this to include time as well - // can't make it relative (distance_time as it's cached + // can't make it relative (distance_of_time_in_words) as it's cached %td.hidden-xs = post.comments.size.to_s From 0681fac4069a223e04aa1eaad6f9704dffddab62 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 09:51:14 +0000 Subject: [PATCH 197/392] Correcting view test for posts --- spec/views/forums/index.html.haml_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index 93d7090a9..9e7ef6f7e 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -45,7 +45,7 @@ describe "forums/index" do it "displays posts" do assert_select "table" rendered.should have_content @post.subject - rendered.should have_content "less than a minute ago" + rendered.should have_content Date.today.to_s(:short) end it "displays comment count" do From de981689fcf9c1ae7fb1edbda52caf334666d8fe Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 10:56:46 +0000 Subject: [PATCH 198/392] Revert "Merge pull request #775 from pozorvlak/speed_up_homepage" This reverts commit fa50ff47bb105cd9bd18a67d0c77109d19d65bc8, reversing changes made to 5b19d236d002cb13f511c06f6f31a55a4153e4b7. Once fixed, please read https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.html carefully to get it back in properly. --- app/models/crop.rb | 27 +++++++++++++++++++++------ app/models/planting.rb | 26 +++++++++++++++++--------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index af8aad4a4..2000ebfbb 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -29,12 +29,6 @@ class Crop < ActiveRecord::Base scope :pending_approval, -> { where(:approval_status => "pending") } scope :approved, -> { where(:approval_status => "approved") } scope :rejected, -> { where(:approval_status => "rejected") } - # Crops with enough plantings and photos - # ActiveRecord wizardry copied from - # http://stackoverflow.com/questions/13226913/how-do-i-select-all-records-with-more-than-n-child-records - scope :has_plantings, ->(min_plantings) { select("crops.*").joins(:plantings).group("crops.id").having("count(crops.id) >= ?", min_plantings) } - scope :has_photos, ->(min_photos) { select("crops.*").joins(:photos).group("crops.id").having("count(crops.id) >= ?", min_photos) } - scope :interesting, -> { has_plantings(3).has_photos(3).randomized.limit(12) } ## Wikipedia urls are only necessary when approving a crop validates :en_wikipedia_url, @@ -180,6 +174,14 @@ class Crop < ActiveRecord::Base return popular_plant_parts end + def interesting? + min_plantings = 3 # needs this many plantings to be interesting + min_photos = 3 # needs this many photos to be interesting + return false unless photos.size >= min_photos + return false unless plantings_count >= min_plantings + return true + end + def pending? approval_status == "pending" end @@ -200,6 +202,19 @@ class Crop < ActiveRecord::Base [ "already in database", "not edible", "not enough information", "other" ] end + # Crop.interesting + # returns a list of interesting crops, for use on the homepage etc + def Crop.interesting + howmany = 12 # max number to find + interesting_crops = Array.new + Crop.randomized.each do |c| + break if interesting_crops.size == howmany + next unless c.interesting? + interesting_crops.push(c) + end + return interesting_crops + end + # Crop.create_from_csv(row) # used by db/seeds.rb and rake growstuff:import_crops # CSV fields: diff --git a/app/models/planting.rb b/app/models/planting.rb index 2ce05f6e7..900156b2a 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -90,6 +90,10 @@ class Planting < ActiveRecord::Base return photos.first end + def interesting? + return photos.present? + end + def calculate_days_before_maturity(planting, crop) p_crop = Planting.where(:crop_id => crop).where.not(:id => planting) differences = p_crop.collect do |p| @@ -109,15 +113,19 @@ class Planting < ActiveRecord::Base # we can't do this via a scope (as far as we know) so sadly we have to # do it this way. def Planting.interesting(howmany=12, require_photo=true) - if require_photo then - candidates = Planting.joins(:photos).uniq - else - candidates = Planting + interesting_plantings = Array.new + seen_owners = Hash.new(false) # keep track of which owners we've seen already + + Planting.all.each do |p| + break if interesting_plantings.size == howmany # got enough yet? + if require_photo + next unless p.photos.present? # skip those without photos, if required + end + next if seen_owners[p.owner] # skip if we already have one from this owner + seen_owners[p.owner] = true # we've seen this owner + interesting_plantings.push(p) end - # Find the most recent acceptable planting for each member - most_recent_ids = candidates.select("max(plantings.id)") - .unscope(:order) - .group("plantings.owner_id") - return candidates.where(id: most_recent_ids).limit(howmany) + + return interesting_plantings end end From 1ec188c79348ad0ce875f06d64e002ea873ab8c7 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 12:36:21 +0100 Subject: [PATCH 199/392] Revert "Fixing relative caching of post summary on homepage, fixed #789" --- app/views/posts/_summary.html.haml | 5 ++--- spec/views/forums/index.html.haml_spec.rb | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 59a58dd47..65fdeb567 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -15,8 +15,7 @@ %td.hidden-xs =link_to post.author, post.author %td - = post.recent_activity.to_date.to_formatted_s(:short) - // once the site gets more active, can change this to include time as well - // can't make it relative (distance_of_time_in_words) as it's cached + = distance_of_time_in_words(post.recent_activity, Time.zone.now) + ago %td.hidden-xs = post.comments.size.to_s diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index 9e7ef6f7e..93d7090a9 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -45,7 +45,7 @@ describe "forums/index" do it "displays posts" do assert_select "table" rendered.should have_content @post.subject - rendered.should have_content Date.today.to_s(:short) + rendered.should have_content "less than a minute ago" end it "displays comment count" do From 5a12b47c7cdd653ce369080eb947df4ceec396fb Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 12:37:59 +0100 Subject: [PATCH 200/392] Revert "Revert "Fixing relative caching of post summary on homepage, fixed #789"" --- app/views/posts/_summary.html.haml | 5 +++-- spec/views/forums/index.html.haml_spec.rb | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 65fdeb567..59a58dd47 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -15,7 +15,8 @@ %td.hidden-xs =link_to post.author, post.author %td - = distance_of_time_in_words(post.recent_activity, Time.zone.now) - ago + = post.recent_activity.to_date.to_formatted_s(:short) + // once the site gets more active, can change this to include time as well + // can't make it relative (distance_of_time_in_words) as it's cached %td.hidden-xs = post.comments.size.to_s diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index 93d7090a9..9e7ef6f7e 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -45,7 +45,7 @@ describe "forums/index" do it "displays posts" do assert_select "table" rendered.should have_content @post.subject - rendered.should have_content "less than a minute ago" + rendered.should have_content Date.today.to_s(:short) end it "displays comment count" do From 44b8500fa81888998db5ed3d3eb7166c30f9fe9a Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 12:12:29 +0000 Subject: [PATCH 201/392] Fix issue #788 with uncaught nil --- app/views/plantings/_planting_progress.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index 86ba5d1a5..eea698c82 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -1,4 +1,4 @@ -- if DateTime.now.to_date < planting.planted_at +- if (planting.planted_at.nil? || DateTime.now.to_date < planting.planted_at) = "Progress: 0% - not planted yet" = render partial: "plantings/progress_bar", locals: {status: "warning", progress: "100%"} - elsif planting.finished? From 17c5fd61a3aa88196584122c4583724fe4faef58 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 12:23:00 +0000 Subject: [PATCH 202/392] Fix #677 by adding organic/GMO/heirloom to CSV and RSS --- app/views/seeds/index.csv.shaper | 6 ++++++ app/views/seeds/index.rss.haml | 3 +++ 2 files changed, 9 insertions(+) diff --git a/app/views/seeds/index.csv.shaper b/app/views/seeds/index.csv.shaper index 818e68909..68f5664d3 100644 --- a/app/views/seeds/index.csv.shaper +++ b/app/views/seeds/index.csv.shaper @@ -11,6 +11,9 @@ csv.headers :id, :latitude, :longitude, :description, + :organic, + :gmo, + :heirloom, :date_added, :last_modified, :license @@ -37,6 +40,9 @@ csv.headers :id, csv.cell :longitude, s.owner.longitude csv.cell :description + csv.cell :organic + csv.cell :gmo + csv.cell :heirloom csv.cell :date_added, s.created_at.to_s(:db) csv.cell :last_modified, s.updated_at.to_s(:db) diff --git a/app/views/seeds/index.rss.haml b/app/views/seeds/index.rss.haml index 30cec02af..c35bc0d74 100644 --- a/app/views/seeds/index.rss.haml +++ b/app/views/seeds/index.rss.haml @@ -12,6 +12,9 @@ :escaped

    Quantity: #{seed.quantity ? seed.quantity : 'unknown' }

    Plant before: #{seed.plant_before ? seed.plant_before : 'unknown' }

    +

    Organic? #{seed.organic}

    +

    GMO? #{seed.gmo}

    +

    Heirloom? #{seed.heirloom}

    - if seed.tradable? :escaped

    Will trade #{seed.tradable_to} from #{seed.owner.location ? seed.owner.location : 'unknown location'}

    From f61e2438e81dd95c71edfa14c9555674ddb9cde6 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 10 Aug 2015 16:08:09 +0930 Subject: [PATCH 203/392] Style checkbox for 'remember me' and allow it to be clickable (minor usability/mobile UI annoyance) --- app/views/devise/sessions/new.html.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 51d7b6845..1930d2043 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -15,9 +15,10 @@ - if devise_mapping.rememberable? .form-group - .col-md-8.col-md-offset-2 - = f.check_box :remember_me - Remember me + .col-md-8.col-md-offset-2.checkbox + label + = f.check_box :remember_me + Remember me .form-group .form-actions.col-md-8.col-md-offset-2 From b788cb44efd6bdab2d15fa31c7c6e3557c0d4c63 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 11 Aug 2015 10:23:50 +0930 Subject: [PATCH 204/392] Remember that we're working in haml, not slim. --- app/views/devise/sessions/new.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 1930d2043..4fdef08be 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -16,7 +16,7 @@ - if devise_mapping.rememberable? .form-group .col-md-8.col-md-offset-2.checkbox - label + %label = f.check_box :remember_me Remember me From 7b30c4237b429854d37c1867a9f12c7329e90626 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 11 Aug 2015 10:28:07 +0930 Subject: [PATCH 205/392] Name: activesupport Version: 4.1.9 Advisory: CVE-2015-3227 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/bahr2JLnxvk Title: Possible Denial of Service attack in Active Support Solution: upgrade to >= 4.2.2, ~> 4.1.11, ~> 3.2.22 Name: activesupport Version: 4.1.9 Advisory: CVE-2015-3226 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/ruby-security-ann/7VlB_pck3hU Title: XSS Vulnerability in ActiveSupport::JSON.encode Solution: upgrade to >= 4.2.2, ~> 4.1.11 --- Gemfile | 2 +- Gemfile.lock | 68 ++++++++++++++++++++++++++-------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Gemfile b/Gemfile index 0cd47ce40..8a26f1058 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' ruby '2.1.5' -gem 'rails', '4.1.9' +gem 'rails', '4.1.11' gem 'bundler', '>=1.1.5' diff --git a/Gemfile.lock b/Gemfile.lock index a0d524eac..e9a80a0a4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,29 +20,29 @@ PATH GEM remote: https://rubygems.org/ specs: - actionmailer (4.1.9) - actionpack (= 4.1.9) - actionview (= 4.1.9) + actionmailer (4.1.11) + actionpack (= 4.1.11) + actionview (= 4.1.11) mail (~> 2.5, >= 2.5.4) - actionpack (4.1.9) - actionview (= 4.1.9) - activesupport (= 4.1.9) + actionpack (4.1.11) + actionview (= 4.1.11) + activesupport (= 4.1.11) rack (~> 1.5.2) rack-test (~> 0.6.2) - actionview (4.1.9) - activesupport (= 4.1.9) + actionview (4.1.11) + activesupport (= 4.1.11) builder (~> 3.1) erubis (~> 2.7.0) active_link_to (1.0.2) actionpack - activemodel (4.1.9) - activesupport (= 4.1.9) + activemodel (4.1.11) + activesupport (= 4.1.11) builder (~> 3.1) - activerecord (4.1.9) - activemodel (= 4.1.9) - activesupport (= 4.1.9) + activerecord (4.1.11) + activemodel (= 4.1.11) + activesupport (= 4.1.11) arel (~> 5.0.0) - activesupport (4.1.9) + activesupport (4.1.11) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -234,7 +234,7 @@ GEM js-routes (0.9.9) railties (>= 3.2) sprockets-rails - json (1.8.2) + json (1.8.3) kaminari (0.16.3) actionpack (>= 3.0.0) activesupport (>= 3.0.0) @@ -263,10 +263,10 @@ GEM mime-types (>= 1.16, < 3) memcachier (0.0.2) method_source (0.8.2) - mime-types (2.4.3) + mime-types (2.6.1) mini_portile (0.6.1) - minitest (5.5.1) - multi_json (1.10.1) + minitest (5.8.0) + multi_json (1.11.2) multi_xml (0.5.5) multipart-post (2.0.0) nenv (0.2.0) @@ -309,18 +309,18 @@ GEM slop (~> 3.4) quiet_assets (1.1.0) railties (>= 3.1, < 5.0) - rack (1.5.2) + rack (1.5.5) rack-test (0.6.3) rack (>= 1.0) - rails (4.1.9) - actionmailer (= 4.1.9) - actionpack (= 4.1.9) - actionview (= 4.1.9) - activemodel (= 4.1.9) - activerecord (= 4.1.9) - activesupport (= 4.1.9) + rails (4.1.11) + actionmailer (= 4.1.11) + actionpack (= 4.1.11) + actionview (= 4.1.11) + activemodel (= 4.1.11) + activerecord (= 4.1.11) + activesupport (= 4.1.11) bundler (>= 1.3.0, < 2.0) - railties (= 4.1.9) + railties (= 4.1.11) sprockets-rails (~> 2.0) rails-i18n (4.0.3) i18n (~> 0.6) @@ -330,9 +330,9 @@ GEM rails_stdout_logging rails_serve_static_assets (0.0.2) rails_stdout_logging (0.0.3) - railties (4.1.9) - actionpack (= 4.1.9) - activesupport (= 4.1.9) + railties (4.1.11) + actionpack (= 4.1.11) + activesupport (= 4.1.11) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.13.0) @@ -387,12 +387,12 @@ GEM simplecov-html (~> 0.8.0) simplecov-html (0.8.0) slop (3.6.0) - sprockets (2.12.3) + sprockets (2.12.4) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.2.2) + sprockets-rails (2.3.2) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) @@ -404,7 +404,7 @@ GEM ref thor (0.19.1) thread (0.1.4) - thread_safe (0.3.4) + thread_safe (0.3.5) tilt (1.4.1) tins (1.3.3) tzinfo (1.2.2) @@ -488,7 +488,7 @@ DEPENDENCIES poltergeist (~> 1.6) pry quiet_assets - rails (= 4.1.9) + rails (= 4.1.11) rails_12factor rake (>= 10.0.0) rspec-activemodel-mocks From e765387e22e8e128cf8a13e972c975fe48fe2e95 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 11 Aug 2015 10:31:43 +0930 Subject: [PATCH 206/392] Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3fb5b66f6..066d267cd 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -63,4 +63,5 @@ submit the change with your pull request. - Gabrielle DeWitt / [gabrielle27](https://github.com/gabrielle27) - Manmeet Singh / [manmeetsingh](https://github.com/manmeetsingh) - Jym Paul Carandang / [jacarandang](https://github.com/jacarandang) -- Anthony Atkinson / [sha1sum](https://github.com/sha1sum) \ No newline at end of file +- Anthony Atkinson / [sha1sum](https://github.com/sha1sum) +- Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX) From 367e298d4870e7453b4f5140ab086789495552b3 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 11 Aug 2015 13:44:17 +0930 Subject: [PATCH 207/392] Fix clickable area for checkboxes in registration --- app/views/devise/registrations/new.html.haml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 268fc3e45..f15142bb0 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -26,15 +26,17 @@ .col-md-8= f.password_field :password_confirmation, :class => 'form-control' .form-group - .col-md-offset-2.col-md-8 - = f.check_box :tos_agreement - I agree to the - = succeed "." do - = link_to 'Terms of Service', url_for(:action => 'tos', :controller => '/policy') + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :tos_agreement + I agree to the + = succeed "." do + = link_to 'Terms of Service', url_for(:action => 'tos', :controller => '/policy') .form-group - .col-md-offset-2.col-md-8 - = f.check_box :newsletter, :checked => true - Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :newsletter, :checked => true + Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter .help-inline = render :partial => 'newsletter_blurb' From 97cf1347d5e2d9cd9cd22a9fc032aa6b07f3c710 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 11 Aug 2015 13:45:47 +0930 Subject: [PATCH 208/392] Fix clickable area for checkboxes in email editing --- .../registrations/_edit_email.html.haml | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/app/views/devise/registrations/_edit_email.html.haml b/app/views/devise/registrations/_edit_email.html.haml index 1ea863e2a..a44fbc3c8 100644 --- a/app/views/devise/registrations/_edit_email.html.haml +++ b/app/views/devise/registrations/_edit_email.html.haml @@ -9,24 +9,28 @@ %span.help-block If you change your email address you will have to reconfirm. .form-group - .col-md-offset-2.col-md-8 - = f.check_box :show_email - Show email publicly on your profile page. + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :show_email + Show email publicly on your profile page. .form-group - .col-md-offset-2.col-md-8 - = f.check_box :send_notification_email - Receive emailed copies of Inbox notifications (eg. private messages). + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :send_notification_email + Receive emailed copies of Inbox notifications (eg. private messages). .form-group - .col-md-offset-2.col-md-8 - = f.check_box :send_planting_reminder - Receive regular reminders to track your planting and harvesting. + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :send_planting_reminder + Receive regular reminders to track your planting and harvesting. .form-group - .col-md-offset-2.col-md-8 - = f.check_box :newsletter - Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter + .col-md-offset-2.col-md-8.checkbox + %label + = f.check_box :newsletter + Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} newsletter .help-block = render :partial => 'newsletter_blurb' From 00ae4ed49fb6c286f77de31a694c33752cbd780e Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 12 Aug 2015 16:23:48 +0930 Subject: [PATCH 209/392] Name: paperclip Version: 4.2.1 Advisory: CVE-2015-2963 Criticality: Medium URL: https://robots.thoughtbot.com/paperclip-security-release Title: Paperclip Gem for Ruby vulnerable to content type spoofing Solution: upgrade to >= 4.2.2 --- Gemfile.lock | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e9a80a0a4..1598f2ed9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,7 +89,7 @@ GEM climate_control (0.0.3) activesupport (>= 3.0) cliver (0.3.2) - cocaine (0.5.5) + cocaine (0.5.7) climate_control (>= 0.0.3, < 1.0) codemirror-rails (4.8) railties (>= 3.0, < 5) @@ -264,6 +264,7 @@ GEM memcachier (0.0.2) method_source (0.8.2) mime-types (2.6.1) + mimemagic (0.3.0) mini_portile (0.6.1) minitest (5.8.0) multi_json (1.11.2) @@ -290,11 +291,12 @@ GEM multi_json (~> 1.3) omniauth-oauth (~> 1.0) orm_adapter (0.5.0) - paperclip (4.2.1) - activemodel (>= 3.0.0) - activesupport (>= 3.0.0) - cocaine (~> 0.5.3) + paperclip (4.3.0) + activemodel (>= 3.2.0) + activesupport (>= 3.2.0) + cocaine (~> 0.5.5) mime-types + mimemagic (= 0.3.0) pg (0.17.1) plupload-rails (1.2.1) rails (>= 3.1) From 7c7c66348c4d97c10ee3fd6692893c7fe2bef0b8 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 12 Aug 2015 16:57:58 +0930 Subject: [PATCH 210/392] Name: rest-client Version: 1.7.2 Advisory: CVE-2015-3448 Criticality: Unknown URL: http://www.osvdb.org/show/osvdb/117461 Title: Rest-Client Gem for Ruby logs password information in plaintext Solution: upgrade to >= 1.7.3 Name: rest-client Version: 1.7.2 Advisory: CVE-2015-1820 Criticality: Unknown URL: https://github.com/rest-client/rest-client/issues/369 Title: rubygem-rest-client: session fixation vulnerability via Set-Cookie headers in 30x redirection responses Solution: upgrade to >= 1.8.0 --- Gemfile.lock | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1598f2ed9..1fa1bc703 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -139,6 +139,8 @@ GEM warden (~> 1.2.3) diff-lcs (1.2.5) docile (1.1.5) + domain_name (0.5.24) + unf (>= 0.0.5, < 1.0.0) easy_translate (0.5.0) json thread @@ -213,6 +215,8 @@ GEM haml (>= 4.0.0.rc.1) hpricot (~> 0.8.6) ruby_parser (~> 3.1.1) + http-cookie (1.0.2) + domain_name (~> 0.5) httparty (0.13.3) json (~> 1.8) multi_xml (>= 0.5.2) @@ -271,7 +275,7 @@ GEM multi_xml (0.5.5) multipart-post (2.0.0) nenv (0.2.0) - netrc (0.10.0) + netrc (0.10.3) newrelic_rpm (3.9.8.273) nokogiri (1.6.5) mini_portile (~> 0.6.0) @@ -345,7 +349,8 @@ GEM ref (1.0.5) responders (1.1.2) railties (>= 3.2, < 4.2) - rest-client (1.7.2) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) rspec (3.1.0) @@ -414,6 +419,9 @@ GEM uglifier (2.5.3) execjs (>= 0.3.0) json (>= 1.8.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) unicorn (4.8.3) kgio (~> 2.6) rack From cafd49c143300c84a14030a02f90180e6df8b8e1 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 12 Aug 2015 16:59:14 +0930 Subject: [PATCH 211/392] Name: jquery-rails Version: 3.1.2 Advisory: CVE-2015-1840 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/ruby-security-ann/XIZPbobuwaY Title: CSRF Vulnerability in jquery-ujs and jquery-rails Solution: upgrade to >= 4.0.4, ~> 3.1.3 --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1fa1bc703..b68e62dbe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -230,7 +230,7 @@ GEM slop (>= 3.5.0) term-ansicolor terminal-table - jquery-rails (3.1.2) + jquery-rails (3.1.3) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.3) From a5e7a8d3157390c3b4d90578e181ae42ff45d6e1 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 09:58:55 +0000 Subject: [PATCH 212/392] Cache crop thumbnails --- app/views/crops/_thumbnail.html.haml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index 1a6562894..1b0302688 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -1,13 +1,14 @@ -.thumbnail - .crop-thumbnail - - if crop - = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop - .cropinfo - .cropname - = link_to crop.name, crop - - if crop.scientific_names.size > 0 - .scientificname - = crop.scientific_names.first.scientific_name - .plantingcount - Planted - = pluralize(crop.plantings.size, "time") +- cache cache_key_for(Crop) do + .thumbnail + .crop-thumbnail + - if crop + = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop + .cropinfo + .cropname + = link_to crop.name, crop + - if crop.scientific_names.size > 0 + .scientificname + = crop.scientific_names.first.scientific_name + .plantingcount + Planted + = pluralize(crop.plantings.size, "time") From 1df0c36e726f92439286b8f8a1de1cd0a7e7c2b5 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 6 Aug 2015 15:58:18 +0000 Subject: [PATCH 213/392] Keying the cache correctly --- app/views/crops/_thumbnail.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index 1b0302688..770f1bfc7 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -1,7 +1,7 @@ -- cache cache_key_for(Crop) do - .thumbnail - .crop-thumbnail - - if crop +.thumbnail + .crop-thumbnail + - if crop + - cache cache_key_for(crop) do = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop .cropinfo .cropname From e784ec9b33c7e064d9adfdd7ca6f831841bcdc67 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 11:45:18 +0000 Subject: [PATCH 214/392] Making it trigger the crop thumbnail cache properly --- 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 770f1bfc7..32cbbce9a 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -1,7 +1,7 @@ .thumbnail .crop-thumbnail - if crop - - cache cache_key_for(crop) do + - cache cache_key_for(Crop, crop.id) do = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img'), crop .cropinfo .cropname From e8266480e592d83f58ee3af60fe7fbcba9f70292 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:17:41 +0000 Subject: [PATCH 215/392] Adding bootstrap-accessibility plugin --- app/assets/javascripts/bootstrap-accessibility.min.js | 4 ++++ app/assets/stylesheets/bootstrap-accessibility.css | 1 + 2 files changed, 5 insertions(+) create mode 100644 app/assets/javascripts/bootstrap-accessibility.min.js create mode 100644 app/assets/stylesheets/bootstrap-accessibility.css diff --git a/app/assets/javascripts/bootstrap-accessibility.min.js b/app/assets/javascripts/bootstrap-accessibility.min.js new file mode 100644 index 000000000..8e5a2ef61 --- /dev/null +++ b/app/assets/javascripts/bootstrap-accessibility.min.js @@ -0,0 +1,4 @@ +/*! bootstrap-accessibility-plugin - v1.0.4 - 2015-07-27 +* https://github.com/paypal/bootstrap-accessibility-plugin +* Copyright (c) 2015 PayPal Accessibility Team; Licensed BSD */ +!function($){"use strict";var uniqueId=function(prefix){return(prefix||"ui-id")+"-"+Math.floor(1e3*Math.random()+1)},focusable=function(element,isTabIndexNotNaN){var map,mapName,img,nodeName=element.nodeName.toLowerCase();return"area"===nodeName?(map=element.parentNode,mapName=map.name,element.href&&mapName&&"map"===map.nodeName.toLowerCase()?(img=$("img[usemap='#"+mapName+"']")[0],!!img&&visible(img)):!1):(/input|select|textarea|button|object/.test(nodeName)?!element.disabled:"a"===nodeName?element.href||isTabIndexNotNaN:isTabIndexNotNaN)&&visible(element)},visible=function(element){return $.expr.filters.visible(element)&&!$(element).parents().addBack().filter(function(){return"hidden"===$.css(this,"visibility")}).length};$.extend($.expr[":"],{data:$.expr.createPseudo?$.expr.createPseudo(function(dataName){return function(elem){return!!$.data(elem,dataName)}}):function(elem,i,match){return!!$.data(elem,match[3])},focusable:function(element){return focusable(element,!isNaN($.attr(element,"tabindex")))},tabbable:function(element){var tabIndex=$.attr(element,"tabindex"),isTabIndexNaN=isNaN(tabIndex);return(isTabIndexNaN||tabIndex>=0)&&focusable(element,!isTabIndexNaN)}}),$(".modal-dialog").attr({role:"document"});var modalhide=$.fn.modal.Constructor.prototype.hide;$.fn.modal.Constructor.prototype.hide=function(){var modalOpener=this.$element.parent().find('[data-target="#'+this.$element.attr("id")+'"]');modalhide.apply(this,arguments),modalOpener.focus(),$(document).off("keydown.bs.modal")};var modalfocus=$.fn.modal.Constructor.prototype.enforceFocus;$.fn.modal.Constructor.prototype.enforceFocus=function(){var focEls=this.$element.find(":tabbable"),lastEl=focEls[focEls.length-1];$(document).on("keydown.bs.modal",$.proxy(function(ev){!this.$element.has(ev.target).length&&ev.shiftKey&&9===ev.keyCode&&(lastEl.focus(),ev.preventDefault())},this)),modalfocus.apply(this,arguments)};var $par,firstItem,toggle="[data-toggle=dropdown]",focusDelay=200,menus=$(toggle).parent().find("ul").attr("role","menu"),lis=menus.find("li").attr("role","presentation");lis.find("a").attr({role:"menuitem",tabIndex:"-1"}),$(toggle).attr({"aria-haspopup":"true","aria-expanded":"false"}),$(toggle).parent().on("shown.bs.dropdown",function(e){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","true"),$toggle.on("keydown.bs.dropdown",$.proxy(function(ev){setTimeout(function(){firstItem=$(".dropdown-menu [role=menuitem]:visible",$par)[0];try{firstItem.focus()}catch(ex){}},focusDelay)},this))}),$(toggle).parent().on("hidden.bs.dropdown",function(e){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","false")}),$(document).on("focusout.dropdown.data-api",".dropdown-menu",function(e){var $this=$(this),that=this;setTimeout(function(){$.contains(that,document.activeElement)||($this.parent().removeClass("open"),$this.parent().find("[data-toggle=dropdown]").attr("aria-expanded","false"))},150)}).on("keydown.bs.dropdown.data-api",toggle+", [role=menu]",$.fn.dropdown.Constructor.prototype.keydown);var $tablist=$(".nav-tabs, .nav-pills"),$lis=$tablist.children("li"),$tabs=$tablist.find('[data-toggle="tab"], [data-toggle="pill"]');$tabs&&($tablist.attr("role","tablist"),$lis.attr("role","presentation"),$tabs.attr("role","tab")),$tabs.each(function(index){var tabpanel=$($(this).attr("href")),tab=$(this),tabid=tab.attr("id")||uniqueId("ui-tab");tab.attr("id",tabid),tab.parent().hasClass("active")?(tab.attr({tabIndex:"0","aria-selected":"true","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"0","aria-hidden":"false","aria-labelledby":tabid})):(tab.attr({tabIndex:"-1","aria-selected":"false","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"-1","aria-hidden":"true","aria-labelledby":tabid}))}),$.fn.tab.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$ul=$this.closest("ul[role=tablist] "),k=e.which||e.keyCode;if($this=$(this),/(37|38|39|40)/.test(k)){$items=$ul.find("[role=tab]:visible"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0);var nextTab=$items.eq(index);"tab"===nextTab.attr("role")&&nextTab.tab("show").focus(),e.preventDefault(),e.stopPropagation()}},$(document).on("keydown.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',$.fn.tab.Constructor.prototype.keydown);var tabactivate=$.fn.tab.Constructor.prototype.activate;$.fn.tab.Constructor.prototype.activate=function(element,container,callback){var $active=container.find("> .active");$active.find("[data-toggle=tab], [data-toggle=pill]").attr({tabIndex:"-1","aria-selected":!1}),$active.filter(".tab-pane").attr({"aria-hidden":!0,tabIndex:"-1"}),tabactivate.apply(this,arguments),element.addClass("active"),element.find("[data-toggle=tab], [data-toggle=pill]").attr({tabIndex:"0","aria-selected":!0}),element.filter(".tab-pane").attr({"aria-hidden":!1,tabIndex:"0"})};var $colltabs=$('[data-toggle="collapse"]');$colltabs.each(function(index){var colltab=$(this),collpanel=$(colltab.attr("data-target")?colltab.attr("data-target"):colltab.attr("href")),parent=colltab.attr("data-parent"),collparent=parent&&$(parent),collid=colltab.attr("id")||uniqueId("ui-collapse");colltab.attr("id",collid),collparent&&(colltab.attr({role:"tab","aria-selected":"false","aria-expanded":"false"}),$(collparent).find("div:not(.collapse,.panel-body), h4").attr("role","presentation"),collparent.attr({role:"tablist","aria-multiselectable":"true"}),collpanel.hasClass("in")?(colltab.attr({"aria-controls":collpanel.attr("id"),"aria-selected":"true","aria-expanded":"true",tabindex:"0"}),collpanel.attr({role:"tabpanel",tabindex:"0","aria-labelledby":collid,"aria-hidden":"false"})):(colltab.attr({"aria-controls":collpanel.attr("id"),tabindex:"-1"}),collpanel.attr({role:"tabpanel",tabindex:"-1","aria-labelledby":collid,"aria-hidden":"true"})))});var collToggle=$.fn.collapse.Constructor.prototype.toggle;$.fn.collapse.Constructor.prototype.toggle=function(){var href,prevTab=this.$parent&&this.$parent.find('[aria-expanded="true"]');if(prevTab){var curTab,prevPanel=prevTab.attr("data-target")||(href=prevTab.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),$prevPanel=$(prevPanel),$curPanel=this.$element;this.$parent;this.$parent&&(curTab=this.$parent.find('[data-toggle=collapse][href="#'+this.$element.attr("id")+'"]')),collToggle.apply(this,arguments),$.support.transition&&this.$element.one($.support.transition.end,function(){prevTab.attr({"aria-selected":"false","aria-expanded":"false",tabIndex:"-1"}),$prevPanel.attr({"aria-hidden":"true",tabIndex:"-1"}),curTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:"0"}),$curPanel.hasClass("in")?$curPanel.attr({"aria-hidden":"false",tabIndex:"0"}):(curTab.attr({"aria-selected":"false","aria-expanded":"false"}),$curPanel.attr({"aria-hidden":"true",tabIndex:"-1"}))})}else collToggle.apply(this,arguments)},$.fn.collapse.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$tablist=$this.closest("div[role=tablist] "),k=e.which||e.keyCode;$this=$(this),/(32|37|38|39|40)/.test(k)&&(32==k&&$this.click(),$items=$tablist.find("[role=tab]"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0),$items.eq(index).focus(),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.collapse.data-api",'[data-toggle="collapse"]',$.fn.collapse.Constructor.prototype.keydown),$(".carousel").each(function(index){var $this=$(this),prev=$this.find('[data-slide="prev"]'),next=$this.find('[data-slide="next"]'),$options=$this.find(".item"),$listbox=$options.parent();$this.attr({"data-interval":"false","data-wrap":"false"}),$listbox.attr("role","listbox"),$options.attr("role","option");var spanPrev=document.createElement("span");spanPrev.setAttribute("class","sr-only"),spanPrev.innerHTML="Previous";var spanNext=document.createElement("span");spanNext.setAttribute("class","sr-only"),spanNext.innerHTML="Next",prev.attr("role","button"),next.attr("role","button"),prev.append(spanPrev),next.append(spanNext),$options.each(function(){var item=$(this);item.hasClass("active")?item.attr({"aria-selected":"true",tabindex:"0"}):item.attr({"aria-selected":"false",tabindex:"-1"})})});var slideCarousel=$.fn.carousel.Constructor.prototype.slide;$.fn.carousel.Constructor.prototype.slide=function(type,next){var $active=this.$element.find(".item.active"),$next=next||$active[type]();slideCarousel.apply(this,arguments),$active.one("bsTransitionEnd",function(){$active.attr({"aria-selected":!1,tabIndex:"-1"}),$next.attr({"aria-selected":!0,tabIndex:"0"})})};var $this;$.fn.carousel.Constructor.prototype.keydown=function(e){$this=$this||$(this),this instanceof Node&&($this=$(this));var index,$ul=$this.closest("div[role=listbox]"),$items=$ul.find("[role=option]"),$parent=$ul.parent(),k=e.which||e.keyCode;/(37|38|39|40)/.test(k)&&(index=$items.index($items.filter(".active")),(37==k||38==k)&&(index--,0>index?index=$items.length-1:($parent.carousel("prev"),setTimeout(function(){$items[index].focus()},150))),(39==k||40==k)&&(index++,index==$items.length?index=0:($parent.carousel("next"),setTimeout(function(){$items[index].focus()},150))),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.carousel.data-api","div[role=option]",$.fn.carousel.Constructor.prototype.keydown)}(jQuery); diff --git a/app/assets/stylesheets/bootstrap-accessibility.css b/app/assets/stylesheets/bootstrap-accessibility.css new file mode 100644 index 000000000..b7de73ef0 --- /dev/null +++ b/app/assets/stylesheets/bootstrap-accessibility.css @@ -0,0 +1 @@ +.btn:focus{outline:dotted 2px #000}div.active:focus{outline:dotted 1px #000}a:focus{outline:dotted 1px #000}.close:hover,.close:focus{outline:dotted 1px #000}.nav>li>a:hover,.nav>li>a:focus{outline:dotted 1px #000}.carousel-inner>.item{position:absolute;top:-999999em;display:block;-moz-transition:ease-in-out 0.6s left;-o-transition:ease-in-out 0.6s left;-webkit-transition:ease-in-out 0.6s left;transition:ease-in-out 0.6s left}.carousel-inner>.active{top:0}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{position:relative}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.alert-success{color:#2d4821}.alert-info{color:#214c62}.alert-warning{color:#6c4a00;background-color:#f9f1c6}.alert-danger{color:#d2322d}.alert-danger:hover{color:#a82824} From b6dfeb980c923cf0d97cedf4fceeab19814ac5b7 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:56:36 +0000 Subject: [PATCH 216/392] i18n example --- app/views/layouts/_header.html.haml | 2 +- config/locales/en.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index ac324ab91..30e549f3b 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -1,5 +1,5 @@ .sr-only - =link_to "Skip navigation menu", "#skipnav" + =link_to t(".skip"), "#skipnav" .navbar.navbar-default.navbar-fixed-top(role="navigation") .container .navbar-header diff --git a/config/locales/en.yml b/config/locales/en.yml index 84f8cf9e0..66d1e4892 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -15,6 +15,8 @@ en: all: "Not authorized to %{action} %{subject}." layouts: + header: + skip: "Skip navigation menu" footer: about: "About" our_values: "Our Values" From fd3e69c9abde8f2c6a1dcd63adb6791fca127a1a Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:57:13 +0000 Subject: [PATCH 217/392] Removing footer translation as it's now in the CMS --- config/locales/en.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 66d1e4892..643975551 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -17,18 +17,6 @@ en: layouts: header: skip: "Skip navigation menu" - footer: - about: "About" - our_values: "Our Values" - open_source: "Open Source" - growstuff_team: "Growstuff Team" - get_involved: "Get Involved" - terms_of_service: "Terms of Service" - privacy_policy: "Privacy Policy" - data_use_policy: "Data Use Policy" - community_guidelines: "Community Guidelines" - support_: "Support" # for some reason 'support' seems to be a reserved word - contact: "Contact" home: blurb: From 5cac8743f84b370b0f3554b06baf8ebea8f368ea Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 13 Aug 2015 15:06:56 +1000 Subject: [PATCH 218/392] Upgrade to ruby 2.1.6 for CVE-2015-1855: Ruby OpenSSL Hostname Verification --- .ruby-version | 2 +- .travis.yml | 2 +- Gemfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index cd57a8b95..399088bf4 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.5 +2.1.6 diff --git a/.travis.yml b/.travis.yml index 8b8d9a6b0..04a6dabec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ env: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" bundler_args: "--without development production staging" rvm: -- 2.1.5 +- 2.1.6 before_script: - psql -c 'create database growstuff_test;' -U postgres script: diff --git a/Gemfile b/Gemfile index 8a26f1058..0f712add6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.1.5' +ruby '2.1.6' gem 'rails', '4.1.11' From c2e4686a23d04cd3af3899d962e445206b80a215 Mon Sep 17 00:00:00 2001 From: twconquest Date: Mon, 17 Aug 2015 18:29:00 +0000 Subject: [PATCH 219/392] Add negative tests for roles on profiles --- spec/features/member_profile_spec.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 67cb4dd31..c65adb385 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -126,6 +126,12 @@ feature "member profile" do expect(page).to have_text "Crop Wrangler" end + scenario "ordinary user's page" do + visit member_path(other_member) + expect(page).to_not have_text "Crop Wrangler" + expect(page).to_not have_text "Admin" + end + context "your own profile page" do background do visit member_path(member) From 65e07523764d599cfd5e273340b58b019ccd078d Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 20 Aug 2015 13:07:25 +0000 Subject: [PATCH 220/392] RSS feeds don't need JS --- spec/features/rss/comments_spec.rb | 2 +- spec/features/rss/crops_spec.rb | 2 +- spec/features/rss/members_spec.rb | 2 +- spec/features/rss/plantings_spec.rb | 2 +- spec/features/rss/posts_spec.rb | 2 +- spec/features/rss/seeds_spec.rb | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/features/rss/comments_spec.rb b/spec/features/rss/comments_spec.rb index 1887c890a..f053a7e26 100644 --- a/spec/features/rss/comments_spec.rb +++ b/spec/features/rss/comments_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Comments RSS feed', :js => true do +feature 'Comments RSS feed' do scenario 'The index feed exists' do visit comments_path(format: 'rss') expect(page.status_code).to equal 200 diff --git a/spec/features/rss/crops_spec.rb b/spec/features/rss/crops_spec.rb index 691f7f218..ef45af20b 100644 --- a/spec/features/rss/crops_spec.rb +++ b/spec/features/rss/crops_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Crops RSS feed', :js => true do +feature 'Crops RSS feed' do scenario 'The index feed exists' do visit crops_path(format: 'rss') expect(page.status_code).to equal 200 diff --git a/spec/features/rss/members_spec.rb b/spec/features/rss/members_spec.rb index 38d105eca..3849f9d80 100644 --- a/spec/features/rss/members_spec.rb +++ b/spec/features/rss/members_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Members RSS feed', :js => true do +feature 'Members RSS feed' do let(:member) { create :member } scenario 'The show action exists' do diff --git a/spec/features/rss/plantings_spec.rb b/spec/features/rss/plantings_spec.rb index e307438f1..effad2969 100644 --- a/spec/features/rss/plantings_spec.rb +++ b/spec/features/rss/plantings_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Plantings RSS feed', :js => true do +feature 'Plantings RSS feed' do scenario 'The index feed exists' do visit plantings_path(format: 'rss') expect(page.status_code).to equal 200 diff --git a/spec/features/rss/posts_spec.rb b/spec/features/rss/posts_spec.rb index d580076e5..2d900ebe4 100644 --- a/spec/features/rss/posts_spec.rb +++ b/spec/features/rss/posts_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Posts RSS feed', :js => true do +feature 'Posts RSS feed' do scenario 'The index feed exists' do visit posts_path(format: 'rss') expect(page.status_code).to equal 200 diff --git a/spec/features/rss/seeds_spec.rb b/spec/features/rss/seeds_spec.rb index 593dc47c3..7e5320655 100644 --- a/spec/features/rss/seeds_spec.rb +++ b/spec/features/rss/seeds_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature 'Seeds RSS feed', :js => true do +feature 'Seeds RSS feed' do scenario 'The index feed exists' do visit seeds_path(format: 'rss') expect(page.status_code).to equal 200 From d65ab59d3583f2b15d06a861ea0604a7077683b3 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 20 Aug 2015 13:36:13 +0000 Subject: [PATCH 221/392] Adding ids to navbar so PhantomJS can find them --- app/views/layouts/_header.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 30e549f3b..f5f22ecac 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -18,7 +18,7 @@ .navbar-collapse.collapse#navbar-collapse %ul.nav.navbar-nav.pull-right - %li.dropdown< + %li.dropdown#crops-menu< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => crops_path} Crops %b.caret @@ -27,7 +27,7 @@ %li= link_to "Seeds", seeds_path %li= link_to "Plantings", plantings_path %li= link_to "Harvests", harvests_path - %li.dropdown< + %li.dropdown#community-menu< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => members_path} Community %b.caret @@ -39,7 +39,7 @@ %li= link_to "Support Growstuff", shop_path - if member_signed_in? - %li.dropdown< + %li.dropdown#yourstuff-menu< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => root_path} - if current_member.notifications.unread_count > 0 Your Stuff (#{current_member.notifications.unread_count}) From b9ce3d4fe614866a29f3223e60bb9082397925f6 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 20 Aug 2015 13:59:37 +0000 Subject: [PATCH 222/392] Revert "Adding ids to navbar so PhantomJS can find them" Not needed - test issue was caused by wrong link text This reverts commit d65ab59d3583f2b15d06a861ea0604a7077683b3. --- app/views/layouts/_header.html.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index f5f22ecac..30e549f3b 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -18,7 +18,7 @@ .navbar-collapse.collapse#navbar-collapse %ul.nav.navbar-nav.pull-right - %li.dropdown#crops-menu< + %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => crops_path} Crops %b.caret @@ -27,7 +27,7 @@ %li= link_to "Seeds", seeds_path %li= link_to "Plantings", plantings_path %li= link_to "Harvests", harvests_path - %li.dropdown#community-menu< + %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => members_path} Community %b.caret @@ -39,7 +39,7 @@ %li= link_to "Support Growstuff", shop_path - if member_signed_in? - %li.dropdown#yourstuff-menu< + %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => root_path} - if current_member.notifications.unread_count > 0 Your Stuff (#{current_member.notifications.unread_count}) From 0e98f84da72df733fff2868386122277e275b370 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 20 Aug 2015 14:06:21 +0000 Subject: [PATCH 223/392] Fixing admin tests where you need to click on navmenu with JS --- spec/features/admin/account_types_spec.rb | 9 +++++++++ spec/features/admin/forums_spec.rb | 14 +++++++++++++- spec/features/crops/crop_wranglers_spec.rb | 11 ++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index 27b2f8dfc..197eba092 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -10,6 +10,15 @@ feature "account types", :js => true do end scenario "navigating to account type admin" do + visit root_path + click_link member.login_name + click_link "Admin" + expect(current_path).to eq admin_path + click_link "Account types" + expect(current_path).to eq account_types_path + end + + scenario "navigating to account type admin without js", :js => false do visit root_path click_link "Admin" expect(current_path).to eq admin_path diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index 0e9e6b8d5..5e9627114 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -9,7 +9,7 @@ feature "forums", :js => true do login_as member end - scenario "navigating to forum admin" do + scenario "navigating to forum admin without js", :js => false do visit root_path click_link "Admin" expect(current_path).to eq admin_path @@ -20,6 +20,18 @@ feature "forums", :js => true do expect(page).to have_content "New forum" end + scenario "navigating to forum admin with js" do + visit root_path + click_link member.login_name + click_link "Admin" + expect(current_path).to eq admin_path + within 'ul#admin_links' do + click_link "Forums" + end + expect(current_path).to eq forums_path + expect(page).to have_content "New forum" + end + scenario "adding a forum" do visit forums_path click_link "New forum" diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 19e260064..8bbb51941 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -12,6 +12,7 @@ feature "crop wranglers", :js => true do scenario "sees crop wranglers listed on the crop wrangler page" do visit root_path + click_link member.login_name click_link 'Crop Wrangling' within '.crop_wranglers' do @@ -24,6 +25,7 @@ feature "crop wranglers", :js => true do scenario "can see list of crops with extra detail of who created a crop" do visit root_path + click_link member.login_name click_link 'Crop Wrangling' within '#recently-added-crops' do expect(page).to have_content "#{crops.first.creator.login_name}" @@ -39,6 +41,7 @@ feature "crop wranglers", :js => true do scenario "can create a new crop" do visit root_path + click_link member.login_name click_link 'Crop Wrangling' click_link 'Add Crop' fill_in 'Name', with: "aubergine" @@ -69,9 +72,15 @@ feature "crop wranglers", :js => true do background { login_as member } - scenario "can't see wrangling page" do + scenario "can't see wrangling page without js", :js => false do visit root_path expect(page).not_to have_link "Crop Wrangling" end + + scenario "can't see wrangling page with js" do + visit root_path + click_link member.login_name + expect(page).not_to have_link "Crop Wrangling" + end end end From b87194336fd97cf918a0976cd72343fbc7992d29 Mon Sep 17 00:00:00 2001 From: Cesy Date: Thu, 20 Aug 2015 14:16:39 +0000 Subject: [PATCH 224/392] Wrangler has different name in tests, fixing failing test --- spec/features/crops/crop_wranglers_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index 8bbb51941..cbb410ab4 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -12,7 +12,7 @@ feature "crop wranglers", :js => true do scenario "sees crop wranglers listed on the crop wrangler page" do visit root_path - click_link member.login_name + click_link wrangler.login_name click_link 'Crop Wrangling' within '.crop_wranglers' do @@ -25,7 +25,7 @@ feature "crop wranglers", :js => true do scenario "can see list of crops with extra detail of who created a crop" do visit root_path - click_link member.login_name + click_link wrangler.login_name click_link 'Crop Wrangling' within '#recently-added-crops' do expect(page).to have_content "#{crops.first.creator.login_name}" @@ -41,7 +41,7 @@ feature "crop wranglers", :js => true do scenario "can create a new crop" do visit root_path - click_link member.login_name + click_link wrangler.login_name click_link 'Crop Wrangling' click_link 'Add Crop' fill_in 'Name', with: "aubergine" From 2882e3d1a5f7704eca5fe29033f38d6b0569a1a2 Mon Sep 17 00:00:00 2001 From: twconquest Date: Fri, 21 Aug 2015 19:27:05 +0000 Subject: [PATCH 225/392] Correct Gibbon list id to point to correct list --- app/models/member.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/member.rb b/app/models/member.rb index a8af799b1..c82ab2458 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -239,7 +239,7 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.subscribe({ - :id => Gibbon::API.api_key, + :id => config.newsletter_list_id, :email => { :email => email }, :merge_vars => { :login_name => login_name }, :double_optin => false # they already confirmed their email with us @@ -250,7 +250,7 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.unsubscribe({ - :id => ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'], + :id => config.newsletter_list_id, :email => { :email => email } }) end From db876ff10742c22e5329df8c66d9e3c99526d9be Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 24 Aug 2015 16:38:00 +0930 Subject: [PATCH 226/392] #733 Add the correct RDFa prefix --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 66b78017a..f708434f1 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -1,5 +1,5 @@ !!! 5 -%html(lang="en") +%html(lang="en" prefix="og: http://ogp.me/ns#") = render :partial => "layouts/meta" %body = render :partial => "layouts/header" From 3258a6754c2a22dc703d4a552eee980a4d087e5a Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 24 Aug 2015 16:46:42 +0930 Subject: [PATCH 227/392] #733 Render only one image, and do it with a full URL --- app/views/layouts/_meta.html.haml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/views/layouts/_meta.html.haml b/app/views/layouts/_meta.html.haml index fecf8dff9..2671cd34f 100644 --- a/app/views/layouts/_meta.html.haml +++ b/app/views/layouts/_meta.html.haml @@ -1,8 +1,7 @@ %head - - + - if (content_for?(:member_rss_login_name) && content_for(:member_rss_slug)) From e3c52b1a56f30b1a4dfaf300d3f7005af883858f Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 24 Aug 2015 16:56:35 +0930 Subject: [PATCH 228/392] #733 Render as a 'website' --- app/views/layouts/_meta.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/layouts/_meta.html.haml b/app/views/layouts/_meta.html.haml index 2671cd34f..1032821ef 100644 --- a/app/views/layouts/_meta.html.haml +++ b/app/views/layouts/_meta.html.haml @@ -2,7 +2,10 @@ - + + + + - if (content_for?(:member_rss_login_name) && content_for(:member_rss_slug)) = auto_discovery_link_tag(:rss, { :controller => "/members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "#{ ENV['GROWSTUFF_SITE_NAME'] }- #{yield(:member_rss_login_name)}'s posts" }) From 6d97a060c384d025aeeb33cfa6ab028814f417de Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 25 Aug 2015 00:32:06 +0930 Subject: [PATCH 229/392] #509 Add support for a non gravatar profile image. Assumed to be the same dimensions as a gravatar pic --- db/schema.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 4f21ebffd..67e96bd37 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150625224805) do +ActiveRecord::Schema.define(version: 20150824145414) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -306,6 +306,7 @@ ActiveRecord::Schema.define(version: 20150625224805) do t.integer "plantings_count" t.boolean "newsletter" t.boolean "send_planting_reminder", default: true + t.string "preferred_avatar_uri" end add_index "members", ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true, using: :btree From 859cf7f2152b81ef4bb175df1fbc0490e85fae63 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 25 Aug 2015 00:32:17 +0930 Subject: [PATCH 230/392] #509 Add support for a non gravatar profile image. Assumed to be the same dimensions as a gravatar pic --- app/helpers/application_helper.rb | 13 +++++++++++++ app/views/members/_avatar.html.haml | 6 +----- .../20150824145414_add_member_preferred_image.rb | 5 +++++ 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20150824145414_add_member_preferred_image.rb diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 319a954fd..d8470392d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -37,5 +37,18 @@ module ApplicationHelper content_tag :div, asterisk + ' '.html_safe + text, class: ['margin-bottom'] end + # + # Returns an image uri for a given member. + # + # Falls back to Gravatar + # + def avatar_uri(member, size = 150) + return member.preferred_avatar_uri if member.preferred_avatar_uri.present? + + Gravatar.new(member.email).image_url({ + :size => size, + :default => :identicon + }) + end end diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index 1c265ed14..3089dc4be 100644 --- a/app/views/members/_avatar.html.haml +++ b/app/views/members/_avatar.html.haml @@ -1,9 +1,5 @@ = link_to | - image_tag( | - Gravatar.new(member.email).image_url( | - options = { | - :size => defined?(size) ? size : 150, | - :default => :identicon }), | + image_tag(avatar_uri(member, 150), | :alt => '', | :class => 'img img-responsive avatar' ), | member_path(member) diff --git a/db/migrate/20150824145414_add_member_preferred_image.rb b/db/migrate/20150824145414_add_member_preferred_image.rb new file mode 100644 index 000000000..dc24bd5a0 --- /dev/null +++ b/db/migrate/20150824145414_add_member_preferred_image.rb @@ -0,0 +1,5 @@ +class AddMemberPreferredImage < ActiveRecord::Migration + def change + add_column :members, :preferred_avatar_uri, :string + end +end From 1187719e7b5f596277dcc891275547fd5cae5432 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 25 Aug 2015 00:51:13 +0930 Subject: [PATCH 231/392] #509 Add some basic test coverage --- spec/helpers/application_helper_spec.rb | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 8d1f0e78a..8a8755750 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -19,4 +19,28 @@ describe ApplicationHelper do expect(output).to have_selector '.red', text: '*' expect(output).to have_selector 'em', text: 'denotes a required field' end + + describe '#avatar_uri' do + context 'with a normal user' do + before :each do + @member = FactoryGirl.build(:member, email: 'example@example.com', preferred_avatar_uri: nil) + end + it 'should render a gravatar uri' do + expect(avatar_uri(@member)).to eq 'https://s.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=150' + end + + it 'should render a gravatar uri for a given size' do + expect(avatar_uri(@member, 456)).to eq 'https://s.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=456' + end + end + + context 'with a user who specified a preferred avatar uri' do + before :each do + @member = FactoryGirl.build(:member, email: 'example@example.com', preferred_avatar_uri: 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg') + end + it 'should render a the specified uri' do + expect(avatar_uri(@member)).to eq 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg' + end + end + end end From cad361ed7a0b5e78522f2b4ccfaf24e28be17c0a Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 25 Aug 2015 00:57:39 +0930 Subject: [PATCH 232/392] #509 Update expectations, they were slightly different to what the test tool claimed they would be. --- spec/helpers/application_helper_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 8a8755750..057f68e58 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -26,11 +26,11 @@ describe ApplicationHelper do @member = FactoryGirl.build(:member, email: 'example@example.com', preferred_avatar_uri: nil) end it 'should render a gravatar uri' do - expect(avatar_uri(@member)).to eq 'https://s.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=150' + expect(avatar_uri(@member)).to eq 'http://www.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?size=150&default=identicon' end it 'should render a gravatar uri for a given size' do - expect(avatar_uri(@member, 456)).to eq 'https://s.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?s=456' + expect(avatar_uri(@member, 456)).to eq 'http://www.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?size=456&default=identicon' end end From e84aaeb56d561c70052b73357657c43fc33a3039 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 26 Aug 2015 10:33:12 +0930 Subject: [PATCH 233/392] #509 Refactor the rendering of image_with_popover as well (size is *never* defined, so have defaulted it explicitly to 150) --- app/views/members/_image_with_popover.html.haml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/views/members/_image_with_popover.html.haml b/app/views/members/_image_with_popover.html.haml index fb9caddfc..965ac4f47 100644 --- a/app/views/members/_image_with_popover.html.haml +++ b/app/views/members/_image_with_popover.html.haml @@ -1,9 +1,6 @@ = link_to | image_tag( | - Gravatar.new(member.email).image_url( | - options = { | - :size => defined?(size) ? size : 150, | - :default => :identicon }), | + avatar_uri(member, 150), | :alt => member.login_name, | :class => 'img-responsive member-image' | ), | From c87a5f2d6b0bfcdeea22211fa581e294baccc7b4 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 27 Aug 2015 14:32:37 +0930 Subject: [PATCH 234/392] Fix #819 by removing the popover behaviour for a standard avatar; and putting the stats onto the card. --- .../members/_image_with_popover.html.haml | 12 ------------ app/views/members/_popover.html.haml | 15 --------------- app/views/members/_thumbnail.html.haml | 18 +++++++++++++++--- 3 files changed, 15 insertions(+), 30 deletions(-) delete mode 100644 app/views/members/_image_with_popover.html.haml delete mode 100644 app/views/members/_popover.html.haml diff --git a/app/views/members/_image_with_popover.html.haml b/app/views/members/_image_with_popover.html.haml deleted file mode 100644 index 965ac4f47..000000000 --- a/app/views/members/_image_with_popover.html.haml +++ /dev/null @@ -1,12 +0,0 @@ -= link_to | - image_tag( | - avatar_uri(member, 150), | - :alt => member.login_name, | - :class => 'img-responsive member-image' | - ), | - member, | - :rel => "popover", | - 'data-trigger' => 'hover', | - 'data-title' => member.login_name, | - 'data-content' => "#{ render :partial => 'members/popover', :locals => { :member => member } }", | - 'data-html' => true diff --git a/app/views/members/_popover.html.haml b/app/views/members/_popover.html.haml deleted file mode 100644 index 24122c560..000000000 --- a/app/views/members/_popover.html.haml +++ /dev/null @@ -1,15 +0,0 @@ -%small - %p - - if member.location - %i - = member.location - %p - Joined - = distance_of_time_in_words(member.created_at, Time.zone.now) - ago. - %p - = pluralize(member.gardens.size, "garden") - %br/ - = pluralize(member.plantings.size, "planting") - %br/ - = pluralize(member.seeds.size, "seed") diff --git a/app/views/members/_thumbnail.html.haml b/app/views/members/_thumbnail.html.haml index 5f0f9c58d..604081a73 100644 --- a/app/views/members/_thumbnail.html.haml +++ b/app/views/members/_thumbnail.html.haml @@ -1,16 +1,28 @@ - cache member do .member-thumbnail.panel %div - = render :partial => "members/image_with_popover", :locals => { :member => member } + = render :partial => "members/avatar", :locals => { :member => member } %div %p = link_to member.login_name, member - - if ! member.location.blank? + - if !member.location.blank? %small %br/ %i= member.location - - if ! member.plantings.empty? + - if !member.plantings.empty? %small %br/ Recently planted: != member.plantings.first(3).map{|p| link_to p.crop_name, p }.join(", ") + %p + %small + Joined + = distance_of_time_in_words(member.created_at, Time.zone.now) + ago. + %p + %small + = pluralize(member.gardens.size, "garden") + %br/ + = pluralize(member.plantings.size, "planting") + %br/ + = pluralize(member.seeds.size, "seed") From a0cdf3a8b22a0acc161bf954b6f1f2609f300502 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 27 Aug 2015 15:12:05 +0930 Subject: [PATCH 235/392] Fix #818 by removing the .thumbnail around the button. Also rearrange some of the headings (sizing) and controls (add new garden) to be more clearly not a tab. --- app/views/members/_gardens.html.haml | 39 ++++++++++++++++++---------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index ddee17d3a..7733e298d 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -7,31 +7,42 @@ - first_garden = false = link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab' - if current_member == member - %li= link_to 'New Garden', new_garden_path - .tab-content + %li.navbar-right + = link_to new_garden_path, class: 'btn' do + Add New Garden + .tab-content{style: "padding-top: 1em"} - first_garden = true - member.gardens.each do |g| %div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"} - first_garden = false - %div + .container :growstuff_markdown #{ strip_tags g.description } + - unless g.description + .row + %p No description available yet. + + - if can? :edit, g + %p + Why not + = link_to 'tell us more.', edit_garden_path(g) + - if g.photos.size > 0 or (can? :edit, g and can? :create, Photo) .row - %h2 Photos - - %ul.thumbnails - - g.photos.each do |p| - .col-md-2.six-across - = render :partial => 'photos/thumbnail', :locals => { :photo => p } - - if can? :create, Photo and can? :edit, g - .col-md-2 - .thumbnail(style='height: 220px') - %p{:style => 'text-align: center; padding-top: 50px'} - = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' + %h3 Photos + %p= pluralize(g.photos.length, "photo") + .row + %ul.thumbnails + - g.photos.each do |p| + .col-md-2.six-across + = render :partial => 'photos/thumbnail', :locals => { :photo => p } + .row + - if can? :create, Photo and can? :edit, g + %p + = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' %h3 What's planted here? .row From ff00b2c985a2ec9b00e71df95e242e3c509592a0 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 27 Aug 2015 15:25:16 +0930 Subject: [PATCH 236/392] Fix #818 and layout of show garden page --- app/views/gardens/show.html.haml | 49 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 526074e4a..4e666f8d5 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -2,7 +2,6 @@ .row .col-md-9 - - if can? :edit, @garden or can? :delete, @garden %p.btn-group - if can? :edit, @garden @@ -28,33 +27,41 @@ %div :growstuff_markdown #{strip_tags @garden.description} + - unless @garden.description + .row-fluid + %p No description available yet. + + - if can? :edit, @garden + %p + Why not + = link_to 'tell us more.', edit_garden_path(@garden) - if @garden.photos.size > 0 or (can? :edit, @garden and can? :create, Photo) - .row - %h2 Photos - - %ul.thumbnails - - @garden.photos.each do |p| - .col-md-2.six-across - = render :partial => 'photos/thumbnail', :locals => { :photo => p } + .row-fluid + %h3 Photos + %p= pluralize(@garden.photos.length, "photo") + .row-fluid + %ul.thumbnails + - @garden.photos.each do |p| + .col-md-2.six-across + = render :partial => 'photos/thumbnail', :locals => { :photo => p } + .row-fluid - if can? :create, Photo and can? :edit, @garden - .col-md-2 - .thumbnail(style='height: 220px') - %p{:style => 'text-align: center; padding-top: 50px'} - = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' + %p + = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' - %h3 What's planted here? - - if @garden.plantings.current.size > 0 - .row + .row-fluid + %h3 What's planted here? + - if @garden.plantings.current.size > 0 - @garden.plantings.current.each.with_index do |planting_current, index_current| = render partial: "plantings/thumbnail", locals: {:planting => planting_current} - - else - %p - Nothing is currently planted here. + - else + %p + Nothing is currently planted here. - %h3 Previously planted in this garden - - if @garden.plantings.finished.size > 0 - .row + .row-fluid + %h3 Previously planted in this garden + - if @garden.plantings.finished.size > 0 - @garden.plantings.finished.each.with_index do |planting_finished| = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} From 631747e9191ae1fe9317017752189d7f205e3857 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 27 Aug 2015 15:26:40 +0930 Subject: [PATCH 237/392] Add a trailing sentence. --- app/views/gardens/show.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 4e666f8d5..0900eac40 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -64,7 +64,9 @@ - if @garden.plantings.finished.size > 0 - @garden.plantings.finished.each.with_index do |planting_finished| = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} - + - else + %p + Nothing has been planted here. .col-md-3 %h4 About this garden %p From fbb442dfeead2bc465f713cb2622504c0f8aa0c2 Mon Sep 17 00:00:00 2001 From: Cesy Date: Fri, 28 Aug 2015 13:00:38 +0000 Subject: [PATCH 238/392] Adding commentary to test for clarification of non-JS version --- spec/features/admin/account_types_spec.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index 197eba092..71d763377 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -9,8 +9,9 @@ feature "account types", :js => true do login_as member end - scenario "navigating to account type admin" do + scenario "navigating to account type admin with JavaScript on" do visit root_path + # Extra click for the expandable login menu click_link member.login_name click_link "Admin" expect(current_path).to eq admin_path @@ -18,8 +19,9 @@ feature "account types", :js => true do expect(current_path).to eq account_types_path end - scenario "navigating to account type admin without js", :js => false do + scenario "navigating to account type admin without JavaScript - Accessility version", :js => false do visit root_path + # Extra link not needed as menu is already expanded click_link "Admin" expect(current_path).to eq admin_path click_link "Account types" From f3579167790eb1377d53f851d72a11e6466abc45 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 29 Aug 2015 07:49:55 +0930 Subject: [PATCH 239/392] For more accurate specs, explicitly target the login-name container --- app/views/members/_thumbnail.html.haml | 2 +- spec/features/members_list_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/members/_thumbnail.html.haml b/app/views/members/_thumbnail.html.haml index 604081a73..04d92cfc3 100644 --- a/app/views/members/_thumbnail.html.haml +++ b/app/views/members/_thumbnail.html.haml @@ -3,7 +3,7 @@ %div = render :partial => "members/avatar", :locals => { :member => member } %div - %p + %p.login-name = link_to member.login_name, member - if !member.location.blank? %small diff --git a/spec/features/members_list_spec.rb b/spec/features/members_list_spec.rb index 073572795..a7857bafd 100644 --- a/spec/features/members_list_spec.rb +++ b/spec/features/members_list_spec.rb @@ -11,7 +11,7 @@ feature "members list" do expect(page).to have_css "#sort" expect(page).to have_selector "form" click_button('Show') - all_links = page.all("#maincontainer p") + all_links = page.all("#maincontainer p.login-name") expect(all_links.first).to have_text member1.login_name expect(all_links.last).to have_text member2.login_name end @@ -22,7 +22,7 @@ feature "members list" do expect(page).to have_selector "form" select("recently", :from => 'sort') click_button('Show') - all_links = page.all("#maincontainer p") + all_links = page.all("#maincontainer p.login-name") expect(all_links.first).to have_text member3.login_name expect(all_links.last).to have_text member1.login_name end From ff779b6679fb66c42c64971e4e659af8f14ce8ac Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 29 Aug 2015 07:51:53 +0930 Subject: [PATCH 240/392] Trial rendering as comma separated --- app/views/members/_thumbnail.html.haml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/views/members/_thumbnail.html.haml b/app/views/members/_thumbnail.html.haml index 04d92cfc3..a55c34e50 100644 --- a/app/views/members/_thumbnail.html.haml +++ b/app/views/members/_thumbnail.html.haml @@ -21,8 +21,4 @@ ago. %p %small - = pluralize(member.gardens.size, "garden") - %br/ - = pluralize(member.plantings.size, "planting") - %br/ - = pluralize(member.seeds.size, "seed") + = [pluralize(member.gardens.size, "garden"), pluralize(member.plantings.size, "planting"), pluralize(member.seeds.size, "seed")].join(", ") From 85f7ca4058d5337af4e5f2c1a2ed1d4625ce113b Mon Sep 17 00:00:00 2001 From: Jim Stallings Date: Sat, 29 Aug 2015 18:39:38 -0400 Subject: [PATCH 241/392] GS-658 - internationalize drop down links and page titles --- app/views/crops/index.html.haml | 4 +- app/views/forums/index.html.haml | 2 +- app/views/harvests/index.html.haml | 2 +- app/views/layouts/_header.html.haml | 42 +++++++++---------- app/views/members/index.html.haml | 2 +- app/views/places/index.html.haml | 2 +- app/views/plantings/index.html.haml | 2 +- app/views/posts/index.html.haml | 2 +- app/views/seeds/index.html.haml | 2 +- app/views/shop/index.html.haml | 2 +- config/locales/en.yml | 65 +++++++++++++++++++++++++++++ 11 files changed, 96 insertions(+), 31 deletions(-) diff --git a/app/views/crops/index.html.haml b/app/views/crops/index.html.haml index d1be6fa49..9c50b029c 100644 --- a/app/views/crops/index.html.haml +++ b/app/views/crops/index.html.haml @@ -1,5 +1,5 @@ -- content_for :title, "Browse crops" -- content_for :subtitle, "#{@crops.size} total" +- content_for :title, t('.title') +- content_for :subtitle, t('.subtitle', crops_size: @crops.size) - if can? :wrangle, Crop = link_to 'Wrangle Crops', wrangle_crops_path, :class => 'btn btn-primary' diff --git a/app/views/forums/index.html.haml b/app/views/forums/index.html.haml index f838160a3..25649f937 100644 --- a/app/views/forums/index.html.haml +++ b/app/views/forums/index.html.haml @@ -1,4 +1,4 @@ -- content_for :title, "Forums" +- content_for :title, t('.title') - if can? :create, Forum %p diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index a6ef4d312..a99097d81 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -1,4 +1,4 @@ -- content_for :title, @owner ? "#{@owner}'s harvests" : @crop ? "Everyone's #{@crop.name} harvests" : "Everyone's harvests" +- content_for :title, @owner ? t('.title.owner_harvests', owner: @owner) : @crop ? t('.title.crop_harvests', crop: @crop.name) : t('.title.default') - if @owner = link_to "View #{@owner}'s profile >>", member_path(@owner) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index 30e549f3b..ddc9c6af2 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -23,48 +23,48 @@ Crops %b.caret %ul.dropdown-menu - %li= link_to "Browse Crops", crops_path - %li= link_to "Seeds", seeds_path - %li= link_to "Plantings", plantings_path - %li= link_to "Harvests", harvests_path + %li= link_to t('.browse_crops'), crops_path + %li= link_to t('.seeds'), seeds_path + %li= link_to t('.plantings'), plantings_path + %li= link_to t('.harvests'), harvests_path %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => members_path} Community %b.caret %ul.dropdown-menu - %li= link_to "Community Map", places_path - %li= link_to "Browse Members", members_path - %li= link_to "Posts", posts_path - %li= link_to "Forums", forums_path - %li= link_to "Support Growstuff", shop_path + %li= link_to t('.community_map'), places_path + %li= link_to t('.browse_members'), members_path + %li= link_to t('.posts'), posts_path + %li= link_to t('.forums'), forums_path + %li= link_to t('.support_growstuff'), shop_path - if member_signed_in? %li.dropdown< %a.dropdown-toggle{'data-toggle' => 'dropdown', :href => root_path} - if current_member.notifications.unread_count > 0 - Your Stuff (#{current_member.notifications.unread_count}) + = t('.your_stuff', unread_count: current_member.notifications.unread_count) - else #{current_member.login_name} %b.caret %ul.dropdown-menu - %li= link_to "Profile", member_path(current_member) - %li= link_to "Gardens", gardens_by_owner_path(:owner => current_member.slug) - %li= link_to "Plantings", plantings_by_owner_path(:owner => current_member.slug) - %li= link_to "Harvests", harvests_by_owner_path(:owner => current_member.slug) - %li= link_to "Seeds", seeds_by_owner_path(:owner => current_member.slug) - %li= link_to "Posts", posts_by_author_path(:author => current_member.slug) - %li= link_to "Account", orders_path + %li= link_to t('.profile'), member_path(current_member) + %li= link_to t('.gardens'), gardens_by_owner_path(:owner => current_member.slug) + %li= link_to t('.plantings'), plantings_by_owner_path(:owner => current_member.slug) + %li= link_to t('.harvest'), harvests_by_owner_path(:owner => current_member.slug) + %li= link_to t('.seeds'), seeds_by_owner_path(:owner => current_member.slug) + %li= link_to t('.posts'), posts_by_author_path(:author => current_member.slug) + %li= link_to t('.account'), orders_path %li - if current_member.notifications.unread_count > 0 - = link_to("Inbox (#{current_member.notifications.unread_count})", notifications_path) + = link_to(t('.inbox_unread', unread_count: current_member.notifications.unread_count), notifications_path) - else - = link_to("Inbox", notifications_path) + = link_to(t('.inbox'), notifications_path) - if current_member.has_role?(:crop_wrangler) || current_member.has_role?(:admin) %li{:class => 'divider', :role => 'presentation'} - if current_member.has_role?(:crop_wrangler) - %li= link_to "Crop Wrangling", wrangle_crops_path + %li= link_to t('.crop_wrangling'), wrangle_crops_path - if current_member.has_role?(:admin) - %li= link_to "Admin", admin_path + %li= link_to t('.admin'), admin_path %li= link_to "Sign out", destroy_member_session_path, :method => :delete diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index 0fa659ede..705d69594 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -1,4 +1,4 @@ -= content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} members" += content_for :title, t(".title", site_name: "#{ENV['GROWSTUFF_SITE_NAME']}") = form_tag(members_path, :method => :get, :class => 'form-inline', :role => 'form') do .form-group diff --git a/app/views/places/index.html.haml b/app/views/places/index.html.haml index a81dd6ba8..fe3264375 100644 --- a/app/views/places/index.html.haml +++ b/app/views/places/index.html.haml @@ -1,4 +1,4 @@ --content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} Community Map" +-content_for :title, t(".title", site_name: "#{ENV['GROWSTUFF_SITE_NAME']}") = render partial: 'search_form' %div#placesmap diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 5563ffbfc..d048a0e89 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -1,4 +1,4 @@ -- content_for :title, @owner ? "#{@owner}'s plantings" : @crop ? "Everyone's #{@crop.name} plantings" : "Everyone's plantings" +- content_for :title, @owner ? t('.title.owner_plantings', owner: @owner) : @crop ? t('.title.crop_plantings', crop: @crop.name) : t('.title.default') - if @owner = link_to "View #{@owner}'s profile >>", member_path(@owner) diff --git a/app/views/posts/index.html.haml b/app/views/posts/index.html.haml index 930dbdf84..4a5846f55 100644 --- a/app/views/posts/index.html.haml +++ b/app/views/posts/index.html.haml @@ -1,4 +1,4 @@ -- content_for :title, @author ? "#{@author}'s posts" : "Everyone's posts" +- content_for :title, @author ? t('.title.author_posts', author: @author) : t('.title.default') %p - if can? :create, Post diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index 800c48417..9bd5cde84 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -1,4 +1,4 @@ -- content_for :title, @owner ? "#{@owner}'s seeds" : @crop ? "Everyone's #{@crop.name} seeds" : "Everyone's seeds" +- content_for :title, @owner ? t('.title.owner_seeds', owner: @owner) : @crop ? t('.title.crop_seeds', crop: @crop.name) : t('.title.default') - if @owner = link_to "View #{@owner}'s profile >>", member_path(@owner) diff --git a/app/views/shop/index.html.haml b/app/views/shop/index.html.haml index a31f71655..da7008d69 100644 --- a/app/views/shop/index.html.haml +++ b/app/views/shop/index.html.haml @@ -1,4 +1,4 @@ --content_for :title, 'Shop' +-content_for :title, t('.title') %p Growstuff relies on your support to build and run this open source diff --git a/config/locales/en.yml b/config/locales/en.yml index 643975551..1551c4eb6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -17,6 +17,71 @@ en: layouts: header: skip: "Skip navigation menu" + browse_crops: "Browse Crops" + seeds: "Seeds" + plantings: "Plantings" + harvests: "Harvests" + community_map: "Community Map" + browse_members: "Browse Members" + posts: "Posts" + forums: "Forums" + support_growstuff: "Support Growstuff" + profile: "Profile" + gardens: "Gardens" + account: "Account" + inbox_unread: "Inbox (%{unread_count})" + inbox: "Inbox" + crop_wrangling: "Crop Wrangling" + admin: "Admin" + your_stuff: "Your Stuff (%{unread_count})" + + crops: + index: + title: "Browse Crops" + subtitle: "%{crops_size} total" + + seeds: + index: + title: + default: "Everyone's seeds" + crop_seeds: "Everyone's %{crop} seeds" + owner_seeds: "%{owner} seeds" + + plantings: + index: + title: + default: "Everyone's plantings" + crop_plantings: "Everyone's %{crop} plantings" + owner_plantings: "%{owner} plantings" + + harvests: + index: + title: + default: "Everyone's harvests" + crop_harvests: "Everyone's %{crop} harvests" + owner_harvests: "%{owner} harvests" + + places: + index: + title: "%{site_name} Community Map" + + members: + index: + title: "%{site_name} members" + + posts: + index: + title: + default: "Everyone's posts" + author_posts: "%{author} posts" + + shop: + index: + title: "Shop" + + forums: + index: + title: "Forums" home: blurb: From b8b511e74781226412251783b00c3e28e0ee6461 Mon Sep 17 00:00:00 2001 From: Jim Stallings Date: Sun, 30 Aug 2015 11:02:47 -0400 Subject: [PATCH 242/392] GS-658 - use yaml anchor for duplicate values --- config/locales/en.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 1551c4eb6..8d77afdc8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -17,14 +17,14 @@ en: layouts: header: skip: "Skip navigation menu" - browse_crops: "Browse Crops" + browse_crops: &browse_crops "Browse Crops" seeds: "Seeds" plantings: "Plantings" harvests: "Harvests" community_map: "Community Map" browse_members: "Browse Members" posts: "Posts" - forums: "Forums" + forums: &forums "Forums" support_growstuff: "Support Growstuff" profile: "Profile" gardens: "Gardens" @@ -37,7 +37,7 @@ en: crops: index: - title: "Browse Crops" + title: *browse_crops subtitle: "%{crops_size} total" seeds: @@ -81,7 +81,7 @@ en: forums: index: - title: "Forums" + title: *forums home: blurb: From 3e8f017ad02d70ba0f491115d41a93e50cd8f7e4 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Fri, 4 Sep 2015 12:50:38 +1000 Subject: [PATCH 243/392] Modify markdown to render quick links to members using [name](member) or @name : Feature #504 --- lib/haml/filters/growstuff_markdown.rb | 28 ++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index dba081e44..bda3f078d 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -3,6 +3,8 @@ require 'bluecloth' module Haml::Filters module GrowstuffMarkdown CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/ + MEMBER_REGEX = /\[([^\[\]]+?)\]\(member\)/ + MEMBER_AT_REGEX = /\@([^\[ \n]+)/ include Haml::Filters::Base def render(text) @@ -20,6 +22,32 @@ module Haml::Filters end end + # turn [jane](member) into [jane](http://growstuff.org/members/jane) + expanded = expanded.gsub(MEMBER_REGEX) do |m| + member_str = $1 + # find crop case-insensitively + member = Member.where('lower(login_name) = ?', member_str.downcase).first + if member + url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + "[#{member_str}](#{url})" + else + member_str + end + end + + # turn @jane into [@jane](http://growstuff.org/members/jane) + expanded = expanded.gsub(MEMBER_AT_REGEX) do |m| + member_str = $1 + # find crop case-insensitively + member = Member.where('lower(login_name) = ?', member_str.downcase).first + if member + url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + "[#{"@"+member_str}](#{url})" + else + member_str + end + end + return BlueCloth.new(expanded).to_html end From b74d89c4823568e541f3515224a8e90cf1a8bc52 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Fri, 4 Sep 2015 13:23:10 +1000 Subject: [PATCH 244/392] Tests for member quicklinks and @member links --- .../haml/filters/growstuff_markdown_spec.rb | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index 8abe8aee4..731038b79 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -15,6 +15,20 @@ def output_link(crop, name=nil) end end +def input_member_link(name) + return "[#{name}](member)" +end + +def output_member_link(member, name=nil) + url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + if name + return "
    #{name}" + else + return "#{member.login_name}" + end +end + + describe 'Haml::Filters::Growstuff_Markdown' do it 'is registered as the handler for :growstuff_markdown' do Haml::Filters::defined['growstuff_markdown'].should == @@ -60,4 +74,27 @@ describe 'Haml::Filters::Growstuff_Markdown' do rendered.should match "test" end + it 'converts quick member links' do + @member = FactoryGirl.create(:member) + rendered = Haml::Filters::GrowstuffMarkdown.render(input_member_link(@member.login_name)) + rendered.should match /#{output_member_link(@member)}/ + end + + it "doesn't convert nonexistent members" do + rendered = Haml::Filters::GrowstuffMarkdown.render(input_member_link("not a member")) + rendered.should match /not a member/ + end + + it 'converts @ member links' do + @member = FactoryGirl.create(:member) + rendered = Haml::Filters::GrowstuffMarkdown.render("@#{@member.login_name}") + rendered.should match /#{output_member_link(@member, "@#{@member.login_name}")}/ + end + + it "doesn't convert nonexistent @ members" do + rendered = Haml::Filters::GrowstuffMarkdown.render("@not-a-member") + rendered.should match /@not-a-member/ + end + + end From aacf7b1f0951685a054ba049e3dae6740d3205b9 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Fri, 4 Sep 2015 13:31:03 +1000 Subject: [PATCH 245/392] Modify regex to include @ in the group --- lib/haml/filters/growstuff_markdown.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index bda3f078d..ae2d09144 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -4,7 +4,7 @@ module Haml::Filters module GrowstuffMarkdown CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/ MEMBER_REGEX = /\[([^\[\]]+?)\]\(member\)/ - MEMBER_AT_REGEX = /\@([^\[ \n]+)/ + MEMBER_AT_REGEX = /(\@[^\[ \n]+)/ include Haml::Filters::Base def render(text) @@ -39,10 +39,10 @@ module Haml::Filters expanded = expanded.gsub(MEMBER_AT_REGEX) do |m| member_str = $1 # find crop case-insensitively - member = Member.where('lower(login_name) = ?', member_str.downcase).first + member = Member.where('lower(login_name) = ?', member_str[1..-1].downcase).first if member url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) - "[#{"@"+member_str}](#{url})" + "[#{member_str}](#{url})" else member_str end From 0adb24fa4d6a0069b3416b3804d9dca2d293147e Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Sun, 6 Sep 2015 09:10:18 +1000 Subject: [PATCH 246/392] Add quick member link help to markdown help --- app/views/shared/_markdown_help.html.haml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/views/shared/_markdown_help.html.haml b/app/views/shared/_markdown_help.html.haml index 41aaa1a31..28505a083 100644 --- a/app/views/shared/_markdown_help.html.haml +++ b/app/views/shared/_markdown_help.html.haml @@ -5,3 +5,5 @@ to format your text. For instance, *italic*, **bold**, or a link [like this](http://to.some.site.com/). %br/ Quick crop links: [sweet potato](crop). +%br/ +Quick member links: @Username or [Username](member). From f36e9d726edec45239950a381823bc5013dcb4bd Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Sun, 6 Sep 2015 14:35:35 +1000 Subject: [PATCH 247/392] Change @ regex to match alphanumeric or _ and modify test string --- lib/haml/filters/growstuff_markdown.rb | 2 +- spec/lib/haml/filters/growstuff_markdown_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index ae2d09144..5fcb9eaf6 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -4,7 +4,7 @@ module Haml::Filters module GrowstuffMarkdown CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/ MEMBER_REGEX = /\[([^\[\]]+?)\]\(member\)/ - MEMBER_AT_REGEX = /(\@[^\[ \n]+)/ + MEMBER_AT_REGEX = /(\@\w+)/ include Haml::Filters::Base def render(text) diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index 731038b79..e3b655221 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -87,7 +87,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do it 'converts @ member links' do @member = FactoryGirl.create(:member) - rendered = Haml::Filters::GrowstuffMarkdown.render("@#{@member.login_name}") + rendered = Haml::Filters::GrowstuffMarkdown.render("Hey @#{@member.login_name}! What's up") rendered.should match /#{output_member_link(@member, "@#{@member.login_name}")}/ end From 7ef1eb58528892dec67649cf8ac4c0a7ada3ea10 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Sun, 6 Sep 2015 09:13:15 +1000 Subject: [PATCH 248/392] Create a notification to all members mentioned in a post : Feature #505 --- app/models/post.rb | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/models/post.rb b/app/models/post.rb index a1174b078..3a1b372af 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -10,6 +10,32 @@ class Post < ActiveRecord::Base # also has_many notifications, but kinda meaningless to get at them # from this direction, so we won't set up an association for now. + after_create do + recipients = Array.new + sender = self.author.id + self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |m| + # find member case-insensitively and add to list of recipients + member = Member.where('lower(login_name) = ?', $1.downcase).first + recipients << member if member and not recipients.include?(member) + end + self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_AT_REGEX) do |m| + # find member case-insensitively and add to list of recipients + member = Member.where('lower(login_name) = ?', $1[1..-1].downcase).first + recipients << member if member and not recipients.include?(member) + end + # don't send notifications to yourself + recipients.map{ |r| r.id }.each do |recipient| + if recipient != sender + Notification.create( + :recipient_id => recipient, + :sender_id => sender, + :subject => "#{self.author} mentioned you in their post #{self.subject}", + :body => self.body, + ) + end + end + end + default_scope { order("created_at desc") } validates :subject, From 1908f670d9a83a3dcb7243dbb9f59d186330dd1d Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Sun, 6 Sep 2015 14:30:53 +1000 Subject: [PATCH 249/392] Tests for feature #505 : Notifying members when mentioned --- spec/models/post_spec.rb | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index c56a5b301..61eb24bc1 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -96,6 +96,38 @@ describe Post do end end + context "notifications" do + let(:member2) { FactoryGirl.create(:member) } + + it "sends a notification when a member is mentioned" do + expect { + FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name) + }.to change(Notification, :count).by(1) + end + + it "sets the notification field" do + @p = FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name) + @n = Notification.first + @n.sender.should eq member + @n.recipient.should eq member2 + @n.subject.should match /mentioned you in their post/ + @n.body.should eq @p.body + end + + it "sends notifications to all members mentioned" do + @member3 = FactoryGirl.create(:member) + expect { + FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name << " & @" << @member3.login_name) + }.to change(Notification, :count).by(2) + end + + it "doesn't send notifications if you mention yourself" do + expect { + FactoryGirl.create(:post, :author => member, :body => "@" << member.login_name) + }.to change(Notification, :count).by(0) + end + end + context "crop-post association" do let!(:tomato) { FactoryGirl.create(:tomato) } let!(:maize) { FactoryGirl.create(:maize) } From 7afd38a1ee7d923f020266082be88936bf34da47 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Sun, 6 Sep 2015 04:17:39 -0400 Subject: [PATCH 250/392] Fix #721 : Escape quick crop link in markdown Lookahead in markdown to verify \ is not present Test for escaping crop link --- lib/haml/filters/growstuff_markdown.rb | 2 +- spec/lib/haml/filters/growstuff_markdown_spec.rb | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index dba081e44..ef1ad7615 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -2,7 +2,7 @@ require 'bluecloth' module Haml::Filters module GrowstuffMarkdown - CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/ + CROP_REGEX = /(? Date: Sun, 6 Sep 2015 05:41:25 -0400 Subject: [PATCH 251/392] Escape member links for [name](member) and @name using backslash Change regex to lookforward When escaping \@name remove \ --- lib/haml/filters/growstuff_markdown.rb | 11 +++++++---- spec/lib/haml/filters/growstuff_markdown_spec.rb | 12 ++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index 5fcb9eaf6..55e9df6f5 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -3,8 +3,9 @@ require 'bluecloth' module Haml::Filters module GrowstuffMarkdown CROP_REGEX = /\[([^\[\]]+?)\]\(crop\)/ - MEMBER_REGEX = /\[([^\[\]]+?)\]\(member\)/ - MEMBER_AT_REGEX = /(\@\w+)/ + MEMBER_REGEX = /(? true) @@ -38,7 +39,7 @@ module Haml::Filters # turn @jane into [@jane](http://growstuff.org/members/jane) expanded = expanded.gsub(MEMBER_AT_REGEX) do |m| member_str = $1 - # find crop case-insensitively + # find member case-insensitively member = Member.where('lower(login_name) = ?', member_str[1..-1].downcase).first if member url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) @@ -48,6 +49,8 @@ module Haml::Filters end end + expanded = expanded.gsub(MEMBER_ESCAPE_AT_REGEX, "") + return BlueCloth.new(expanded).to_html end diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index e3b655221..73946ff00 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -85,6 +85,13 @@ describe 'Haml::Filters::Growstuff_Markdown' do rendered.should match /not a member/ end + it "doesn't convert escaped members" do + @member = FactoryGirl.create(:member) + rendered = Haml::Filters::GrowstuffMarkdown.render("\\" << input_member_link(@member.login_name)) + rendered.should match /\[#{@member.login_name}\]\(member\)/ + end + + it 'converts @ member links' do @member = FactoryGirl.create(:member) rendered = Haml::Filters::GrowstuffMarkdown.render("Hey @#{@member.login_name}! What's up") @@ -96,5 +103,10 @@ describe 'Haml::Filters::Growstuff_Markdown' do rendered.should match /@not-a-member/ end + it "doesn't convert escaped @ members" do + @member = FactoryGirl.create(:member) + rendered = Haml::Filters::GrowstuffMarkdown.render("Hey \\@#{@member.login_name}! What's up") + rendered.should match /Hey @#{@member.login_name}!/ + end end From 9e7a80cb86dbca7760c1b982cccb12a1534c3a31 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Mon, 7 Sep 2015 04:01:20 -0400 Subject: [PATCH 252/392] Fix bug #827 : Error in generating csv file for plantings with owner filter --- app/controllers/plantings_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index bba983b6c..543981170 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -20,7 +20,7 @@ class PlantingsController < ApplicationController format.json { render json: @plantings } format.rss { render :layout => false } #index.rss.builder format.csv do - specifics = (@owner ? "#{@owner.name}-" : @crop ? "#{@crop.name}-" : nil) + specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil) @filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv" render :csv => @plantings end From 342323e5668615625fc55464c1f714556ae493c3 Mon Sep 17 00:00:00 2001 From: Savant Krishna Date: Mon, 7 Sep 2015 20:05:24 -0400 Subject: [PATCH 253/392] Add test for trying to quicklink non-existent @ member --- spec/lib/haml/filters/growstuff_markdown_spec.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index 73946ff00..94c60b88e 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -98,11 +98,19 @@ describe 'Haml::Filters::Growstuff_Markdown' do rendered.should match /#{output_member_link(@member, "@#{@member.login_name}")}/ end - it "doesn't convert nonexistent @ members" do + it "doesn't convert invalid @ members" do rendered = Haml::Filters::GrowstuffMarkdown.render("@not-a-member") rendered.should match /@not-a-member/ end + it "doesn't convert nonexistent @ members" do + @member = FactoryGirl.create(:member) + @member_name = @member.login_name + @member.destroy + rendered = Haml::Filters::GrowstuffMarkdown.render("Hey @#{@member_name}") + rendered.should match /Hey @#{@member_name}/ + end + it "doesn't convert escaped @ members" do @member = FactoryGirl.create(:member) rendered = Haml::Filters::GrowstuffMarkdown.render("Hey \\@#{@member.login_name}! What's up") From b2f37551965bb40d61866aa5cbd051f6c1b424f8 Mon Sep 17 00:00:00 2001 From: twconquest Date: Wed, 9 Sep 2015 19:48:35 +0000 Subject: [PATCH 254/392] Additional config fix to point to correct list id --- app/models/member.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/member.rb b/app/models/member.rb index c82ab2458..2f60b53dd 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -239,7 +239,7 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.subscribe({ - :id => config.newsletter_list_id, + :id => Growstuff::Application.config.newsletter_list_id, :email => { :email => email }, :merge_vars => { :login_name => login_name }, :double_optin => false # they already confirmed their email with us @@ -250,7 +250,7 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.unsubscribe({ - :id => config.newsletter_list_id, + :id => Growstuff::Application.config.newsletter_list_id, :email => { :email => email } }) end From be87d2861ab1748b6c137da2865790e3b86c3c28 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 15 Sep 2015 10:27:36 +0930 Subject: [PATCH 255/392] Upgrade database cleaner gem, so that https://github.com/DatabaseCleaner/database_cleaner/pull/364 is available to us. --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 0f712add6..2c9f22aff 100644 --- a/Gemfile +++ b/Gemfile @@ -116,7 +116,7 @@ group :development, :test do gem 'rspec-rails', '~> 3.1.0' # unit testing framework gem 'rspec-activemodel-mocks' gem 'byebug' # debugging - gem 'database_cleaner', '~> 1.3.0' + gem 'database_cleaner', '~> 1.5.0' gem 'webrat' # provides HTML matchers for view tests gem 'factory_girl_rails', '~> 4.5.0' # for creating test data gem 'coveralls', require: false # coverage analysis diff --git a/Gemfile.lock b/Gemfile.lock index b68e62dbe..e84088ff7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -127,7 +127,7 @@ GEM csv_shaper (1.1.1) activesupport (>= 3.0.0) dalli (2.7.2) - database_cleaner (1.3.0) + database_cleaner (1.5.0) debug_inspector (0.0.2) debugger-linecache (1.2.0) devise (3.4.1) @@ -461,7 +461,7 @@ DEPENDENCIES coveralls csv_shaper dalli - database_cleaner (~> 1.3.0) + database_cleaner (~> 1.5.0) devise (~> 3.4.1) elasticsearch-model elasticsearch-rails From a49f359f9ecf38547600d82906409777bac38fb6 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 15 Sep 2015 10:40:41 +0930 Subject: [PATCH 256/392] Fix minor typo in specs --- spec/models/crop_spec.rb | 2 +- spec/models/plant_part_spec.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 90e02c5fc..c79944c61 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -309,7 +309,7 @@ describe Crop do @maize.plant_parts.should include @pp2 end - it "doesn't dupliate plant_parts" do + it "doesn't duplicate plant_parts" do @maize = FactoryGirl.create(:maize) @pp1 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, diff --git a/spec/models/plant_part_spec.rb b/spec/models/plant_part_spec.rb index f8dc1f290..30e118af8 100644 --- a/spec/models/plant_part_spec.rb +++ b/spec/models/plant_part_spec.rb @@ -22,7 +22,7 @@ describe PlantPart do @pp1.crops.should include @maize end - it "doesn't dupliate crops" do + it "doesn't duplicate crops" do @maize = FactoryGirl.create(:maize) @pp1 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, From 83929cc8eef29a092cc30bead9afcde462410b90 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 15 Sep 2015 11:28:30 +0930 Subject: [PATCH 257/392] Add the ability to run feature tests via selenium if you configure it, or run specs with GROWSTUFF_CAPYBARA_DRIVER=selenium bundle exec rake spec:features/ --- Gemfile | 1 + Gemfile.lock | 10 ++++++++++ spec/rails_helper.rb | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/Gemfile b/Gemfile index 0f712add6..759b1703d 100644 --- a/Gemfile +++ b/Gemfile @@ -124,6 +124,7 @@ group :development, :test do gem 'capybara-email' # integration tests for email gem 'poltergeist', '~> 1.6' # for headless JS testing gem 'i18n-tasks' # adds tests for finding missing and unused translations + gem 'selenium-webdriver' end group :travis do diff --git a/Gemfile.lock b/Gemfile.lock index b68e62dbe..54f97ae9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -86,6 +86,8 @@ GEM capybara-email (2.4.0) capybara (~> 2.4) mail + childprocess (0.5.6) + ffi (~> 1.0, >= 1.0.11) climate_control (0.0.3) activesupport (>= 3.0) cliver (0.3.2) @@ -380,12 +382,18 @@ GEM ruby-units (1.4.5) ruby_parser (3.1.3) sexp_processor (~> 4.1) + rubyzip (1.1.7) sass (3.2.19) sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) sass (~> 3.2.2) sprockets (~> 2.8, < 3.0) sprockets-rails (~> 2.0) + selenium-webdriver (2.47.1) + childprocess (~> 0.5) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0) sexp_processor (4.4.4) shellany (0.0.1) simplecov (0.9.1) @@ -432,6 +440,7 @@ GEM nokogiri (>= 1.2.0) rack (>= 1.0) rack-test (>= 0.5.3) + websocket (1.2.2) websocket-driver (0.5.4) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) @@ -505,6 +514,7 @@ DEPENDENCIES rspec-rails (~> 3.1.0) ruby-units sass-rails (~> 4.0.4) + selenium-webdriver therubyracer (~> 0.12) uglifier (~> 2.5.3) unicorn diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 2bcf1cf4c..4d8a72a98 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -23,7 +23,15 @@ end require 'capybara' require 'capybara/poltergeist' + Capybara.javascript_driver = :poltergeist +if ENV['GROWSTUFF_CAPYBARA_DRIVER'].present? + case ENV['GROWSTUFF_CAPYBARA_DRIVER'] + when 'selenium' + require 'selenium-webdriver' + end + Capybara.javascript_driver = ENV['GROWSTUFF_CAPYBARA_DRIVER'].to_sym +end Capybara.app_host = 'http://localhost' Capybara.server_port = 8081 From 78a65f26c6e8f6e4ff3c83a6ea989beb00681d27 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 16 Sep 2015 14:16:42 +0930 Subject: [PATCH 258/392] Add configuration into example file --- config/application.yml.example | 1 + 1 file changed, 1 insertion(+) diff --git a/config/application.yml.example b/config/application.yml.example index 03e8afe2c..309ac509a 100644 --- a/config/application.yml.example +++ b/config/application.yml.example @@ -78,6 +78,7 @@ GROWSTUFF_ELASTICSEARCH: "false" test: GROWSTUFF_SITE_NAME: Growstuff (test) + GROWSTUFF_CAPYBARA_DRIVER: poltergeist # Note: there is no good way to deploy settings from Figaro to # Travis-CI. If you need env vars set there in order for tests to pass, From 48829dba3ce23b83248f0d405f4155169aaeb066 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 22 Sep 2015 11:14:50 +0930 Subject: [PATCH 259/392] Bump to ruby 2.1.7 for CVE-2015-3900 Request hijacking vulnerability in RubyGems 2.4.6 and earlier; and others - https://www.ruby-lang.org/en/news/2015/08/18/ruby-2-1-7-released/ --- .ruby-version | 2 +- .travis.yml | 2 +- Gemfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index 399088bf4..04b10b4f1 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.6 +2.1.7 diff --git a/.travis.yml b/.travis.yml index 04a6dabec..35ab43fdc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ env: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" bundler_args: "--without development production staging" rvm: -- 2.1.6 +- 2.1.7 before_script: - psql -c 'create database growstuff_test;' -U postgres script: diff --git a/Gemfile b/Gemfile index 759b1703d..9c12d955f 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.1.6' +ruby '2.1.7' gem 'rails', '4.1.11' From 8caea57c472abaec8358a46cc100ec8e3dd4137a Mon Sep 17 00:00:00 2001 From: gustavor-souza Date: Tue, 29 Sep 2015 22:40:13 -0300 Subject: [PATCH 260/392] Fixing a spec timezone problem. --- spec/views/forums/index.html.haml_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index 9e7ef6f7e..07da3cf4f 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -45,7 +45,7 @@ describe "forums/index" do it "displays posts" do assert_select "table" rendered.should have_content @post.subject - rendered.should have_content Date.today.to_s(:short) + rendered.should have_content Time.zone.today.to_s(:short) end it "displays comment count" do From e35b15c8682ebb9d37e00128a3c05044164eeb70 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 21:02:54 +1030 Subject: [PATCH 261/392] Only render an edit control if the permission exists --- app/views/scientific_names/show.html.haml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/views/scientific_names/show.html.haml b/app/views/scientific_names/show.html.haml index 1c0a76357..dffbdffc3 100644 --- a/app/views/scientific_names/show.html.haml +++ b/app/views/scientific_names/show.html.haml @@ -9,6 +9,8 @@ %b Crop: = link_to @scientific_name.crop, @scientific_name.crop -= link_to 'Edit', edit_scientific_name_path(@scientific_name), :class => 'btn btn-default btn-xs' -\| + +- if can? :edit, @scientific_name + = link_to 'Edit', edit_scientific_name_path(@scientific_name), :class => 'btn btn-default btn-xs' + \| = link_to 'Back', scientific_names_path From 9fa72fa5f7979d43dcc256996dfbbace7bf726d2 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 21:02:02 +1030 Subject: [PATCH 262/392] Only render a pipe if there are multiple options like edit rights available --- app/views/alternate_names/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/alternate_names/show.html.haml b/app/views/alternate_names/show.html.haml index 06012457b..fc2b7b335 100644 --- a/app/views/alternate_names/show.html.haml +++ b/app/views/alternate_names/show.html.haml @@ -11,5 +11,5 @@ - if can? :edit, @alternate_name = link_to 'Edit', edit_alternate_name_path(@alternate_name), :class => 'btn btn-default btn-xs' -\| + \| = link_to 'Back', alternate_names_path From 32af1b28a80d0a63622b0a808ac0ebd748142089 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 22:03:59 +1030 Subject: [PATCH 263/392] Update the expectations: an edit link is visible to crop wranglers (which used to be an expectation about the id appearing in a link) --- spec/views/scientific_names/show.html.haml_spec.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/spec/views/scientific_names/show.html.haml_spec.rb b/spec/views/scientific_names/show.html.haml_spec.rb index c16fbe444..d3db043e8 100644 --- a/spec/views/scientific_names/show.html.haml_spec.rb +++ b/spec/views/scientific_names/show.html.haml_spec.rb @@ -28,6 +28,18 @@ describe "scientific_names/show" do render # Run the generator again with the --webrat flag if you want to use webrat matchers rendered.should match(/Zea mays/) - rendered.should match(@scientific_name.id.to_s) + end + + context 'signed in' do + + before :each do + @wrangler = FactoryGirl.create(:crop_wrangling_member) + sign_in @wrangler + render + end + + it 'should have an edit button' do + rendered.should have_content 'Edit' + end end end From bfffaab77fc0c2f3c47ca94e2b9d551d86ce33ba Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 22:26:36 +1030 Subject: [PATCH 264/392] Have to stub the controller load_and_authorize_resource behaviour, as these tests aren't run in that context. --- spec/views/scientific_names/show.html.haml_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/views/scientific_names/show.html.haml_spec.rb b/spec/views/scientific_names/show.html.haml_spec.rb index d3db043e8..a36646658 100644 --- a/spec/views/scientific_names/show.html.haml_spec.rb +++ b/spec/views/scientific_names/show.html.haml_spec.rb @@ -35,6 +35,7 @@ describe "scientific_names/show" do before :each do @wrangler = FactoryGirl.create(:crop_wrangling_member) sign_in @wrangler + controller.stub(:current_user) { @wrangler } render end From f23cb78dcbf5a72340f09bd09e0d8384e7d0309b Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 22:59:44 +1030 Subject: [PATCH 265/392] #840 Eager load photos, which are used in the .interesting? call; so we don't have to do a photos.size call on every single crop. --- app/models/crop.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 2000ebfbb..fe593fe37 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -207,7 +207,7 @@ class Crop < ActiveRecord::Base def Crop.interesting howmany = 12 # max number to find interesting_crops = Array.new - Crop.randomized.each do |c| + Crop.includes(:photos).randomized.each do |c| break if interesting_crops.size == howmany next unless c.interesting? interesting_crops.push(c) From b57cb581dd900f1a4ece59bfb0dba326740dd5f4 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:05:56 +1030 Subject: [PATCH 266/392] #840 Eager load photos --- app/models/planting.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index 900156b2a..14e9017cb 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -116,7 +116,7 @@ class Planting < ActiveRecord::Base interesting_plantings = Array.new seen_owners = Hash.new(false) # keep track of which owners we've seen already - Planting.all.each do |p| + Planting.includes(:photos).each do |p| break if interesting_plantings.size == howmany # got enough yet? if require_photo next unless p.photos.present? # skip those without photos, if required From 049886459a482372121a1ee072a38458c49bf872 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:13:31 +1030 Subject: [PATCH 267/392] Name: nokogiri Version: 1.6.5 Advisory: CVE-2015-1819 Criticality: Unknown URL: https://github.com/sparklemotion/nokogiri/issues/1374 Title: Nokogiri gem contains several vulnerabilities in libxml2 and libxslt Solution: upgrade to ~> 1.6.6.4, >= 1.6.7.rc4 Name: nokogiri Version: 1.6.5 Advisory: CVE-2015-7499 Criticality: Medium URL: https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM Title: Nokogiri gem contains a heap-based buffer overflow vulnerability in libxml2 Solution: upgrade to >= 1.6.7.2 Name: nokogiri Version: 1.6.5 Advisory: CVE-2015-5312 Criticality: High URL: https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s Title: Nokogiri gem contains several vulnerabilities in libxml2 Solution: upgrade to >= 1.6.7.1 --- Gemfile.lock | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8a6ac680d..a0193fad7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -271,7 +271,7 @@ GEM method_source (0.8.2) mime-types (2.6.1) mimemagic (0.3.0) - mini_portile (0.6.1) + mini_portile2 (2.0.0) minitest (5.8.0) multi_json (1.11.2) multi_xml (0.5.5) @@ -279,8 +279,8 @@ GEM nenv (0.2.0) netrc (0.10.3) newrelic_rpm (3.9.8.273) - nokogiri (1.6.5) - mini_portile (~> 0.6.0) + nokogiri (1.6.7.2) + mini_portile2 (~> 2.0.0.rc2) notiffany (0.0.6) nenv (~> 0.1) shellany (~> 0.0) @@ -520,3 +520,6 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) + +BUNDLED WITH + 1.11.2 From a76d2a3eb039070a5725659f6d886de819283cb8 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:16:21 +1030 Subject: [PATCH 268/392] Name: devise Version: 3.4.1 Advisory: CVE-2015-8314 Criticality: Unknown URL: http://blog.plataformatec.com.br/2016/01/improve-remember-me-cookie-expiration-in-devise/ Title: Devise Gem for Ruby Unauthorized Access Using Remember Me Cookie Solution: upgrade to >= 3.5.4 --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a0193fad7..5821aba4d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -53,7 +53,7 @@ GEM autoprefixer-rails (5.1.1) execjs json - bcrypt (3.1.9) + bcrypt (3.1.11) better_errors (2.0.0) coderay (>= 1.0.0) erubis (>= 2.6.6) @@ -272,7 +272,7 @@ GEM mime-types (2.6.1) mimemagic (0.3.0) mini_portile2 (2.0.0) - minitest (5.8.0) + minitest (5.8.4) multi_json (1.11.2) multi_xml (0.5.5) multipart-post (2.0.0) @@ -344,7 +344,7 @@ GEM rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.13.0) - rake (10.4.2) + rake (11.1.2) rb-fsevent (0.9.5) rb-inotify (0.9.5) ffi (>= 0.5.0) @@ -434,7 +434,7 @@ GEM kgio (~> 2.6) rack raindrops (~> 0.7) - warden (1.2.3) + warden (1.2.6) rack (>= 1.0) webrat (0.7.3) nokogiri (>= 1.2.0) From a10f6e4783d9a9c6d75c35490b5a6a641f2bf33b Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:17:55 +1030 Subject: [PATCH 269/392] Name: actionpack Version: 4.1.11 Advisory: CVE-2015-7581 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/dthJ5wL69JE Title: Object leak vulnerability for wildcard controller routes in Action Pack Solution: upgrade to >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14 Name: actionpack Version: 4.1.11 Advisory: CVE-2016-0751 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/9oLY_FCzvoc Title: Possible Object Leak and Denial of Service attack in Action Pack Solution: upgrade to ~> 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14, ~> 3.2.22.1 Name: actionpack Version: 4.1.11 Advisory: CVE-2015-7576 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/ANv0HDHEC3k Title: Timing attack vulnerability in basic authentication in Action Controller. Solution: upgrade to ~> 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14, ~> 3.2.22.1 Name: actionpack Version: 4.1.11 Advisory: CVE-2016-2098 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/ly-IH-fxr_Q Title: Possible remote code execution vulnerability in Action Pack Solution: upgrade to ~> 3.2.22.2, >= 4.2.5.2, ~> 4.2.5, >= 4.1.14.2, ~> 4.1.14 Name: actionview Version: 4.1.11 Advisory: CVE-2016-2097 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/ddY6HgqB2z4 Title: Possible Information Leak Vulnerability in Action View Solution: upgrade to ~> 3.2.22.2, >= 4.1.14.2, ~> 4.1.14 Name: actionview Version: 4.1.11 Advisory: CVE-2016-0752 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/335P1DcLG00 Title: Possible Information Leak Vulnerability in Action View Solution: upgrade to ~> 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14, ~> 3.2.22.1 Name: activemodel Version: 4.1.11 Advisory: CVE-2016-0753 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/6jQVC1geukQ Title: Possible Input Validation Circumvention in Active Model Solution: upgrade to ~> 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14 Name: activerecord Version: 4.1.11 Advisory: CVE-2015-7577 Criticality: Unknown URL: https://groups.google.com/forum/#!topic/rubyonrails-security/cawsWcQ6c8g Title: Nested attributes rejection proc bypass in Active Record Solution: upgrade to ~> 5.0.0.beta1.1, >= 4.2.5.1, ~> 4.2.5, >= 4.1.14.1, ~> 4.1.14, ~> 3.2.22.1 --- Gemfile.lock | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5821aba4d..33e1e89bd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,29 +20,29 @@ PATH GEM remote: https://rubygems.org/ specs: - actionmailer (4.1.11) - actionpack (= 4.1.11) - actionview (= 4.1.11) + actionmailer (4.1.15) + actionpack (= 4.1.15) + actionview (= 4.1.15) mail (~> 2.5, >= 2.5.4) - actionpack (4.1.11) - actionview (= 4.1.11) - activesupport (= 4.1.11) + actionpack (4.1.15) + actionview (= 4.1.15) + activesupport (= 4.1.15) rack (~> 1.5.2) rack-test (~> 0.6.2) - actionview (4.1.11) - activesupport (= 4.1.11) + actionview (4.1.15) + activesupport (= 4.1.15) builder (~> 3.1) erubis (~> 2.7.0) active_link_to (1.0.2) actionpack - activemodel (4.1.11) - activesupport (= 4.1.11) + activemodel (4.1.15) + activesupport (= 4.1.15) builder (~> 3.1) - activerecord (4.1.11) - activemodel (= 4.1.11) - activesupport (= 4.1.11) + activerecord (4.1.15) + activemodel (= 4.1.15) + activesupport (= 4.1.15) arel (~> 5.0.0) - activesupport (4.1.11) + activesupport (4.1.15) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -265,11 +265,11 @@ GEM rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) lumberjack (1.0.9) - mail (2.6.3) - mime-types (>= 1.16, < 3) + mail (2.6.4) + mime-types (>= 1.16, < 4) memcachier (0.0.2) method_source (0.8.2) - mime-types (2.6.1) + mime-types (2.99.1) mimemagic (0.3.0) mini_portile2 (2.0.0) minitest (5.8.4) @@ -320,15 +320,15 @@ GEM rack (1.5.5) rack-test (0.6.3) rack (>= 1.0) - rails (4.1.11) - actionmailer (= 4.1.11) - actionpack (= 4.1.11) - actionview (= 4.1.11) - activemodel (= 4.1.11) - activerecord (= 4.1.11) - activesupport (= 4.1.11) + rails (4.1.15) + actionmailer (= 4.1.15) + actionpack (= 4.1.15) + actionview (= 4.1.15) + activemodel (= 4.1.15) + activerecord (= 4.1.15) + activesupport (= 4.1.15) bundler (>= 1.3.0, < 2.0) - railties (= 4.1.11) + railties (= 4.1.15) sprockets-rails (~> 2.0) rails-i18n (4.0.3) i18n (~> 0.6) @@ -338,9 +338,9 @@ GEM rails_stdout_logging rails_serve_static_assets (0.0.2) rails_stdout_logging (0.0.3) - railties (4.1.11) - actionpack (= 4.1.11) - activesupport (= 4.1.11) + railties (4.1.15) + actionpack (= 4.1.15) + activesupport (= 4.1.15) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.13.0) @@ -407,7 +407,7 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.3.2) + sprockets-rails (2.3.3) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) @@ -507,7 +507,7 @@ DEPENDENCIES poltergeist (~> 1.6) pry quiet_assets - rails (= 4.1.11) + rails (~> 4.1.11) rails_12factor rake (>= 10.0.0) rspec-activemodel-mocks From c1fde41f1fe5fff7193322f2bab1c3c0a552a4a3 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:23:56 +1030 Subject: [PATCH 270/392] Name: devise Version: 3.4.1 Advisory: CVE-2015-8314 Criticality: Unknown URL: http://blog.plataformatec.com.br/2016/01/improve-remember-me-cookie-expiration-in-devise/ Title: Devise Gem for Ruby Unauthorized Access Using Remember Me Cookie Solution: upgrade to >= 3.5.4 --- Gemfile | 4 ++-- Gemfile.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 4108dc32f..8b382daa7 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,7 @@ source 'https://rubygems.org' ruby '2.1.7' -gem 'rails', '4.1.11' +gem 'rails', '~> 4.1.11' gem 'bundler', '>=1.1.5' @@ -61,7 +61,7 @@ gem 'bluecloth' gem 'will_paginate', '~> 3.0' # user signup/login/etc -gem 'devise', '~> 3.4.1' +gem 'devise', '~> 3.5.0' # nicely formatted URLs gem 'friendly_id', '~> 5.0.4' diff --git a/Gemfile.lock b/Gemfile.lock index 33e1e89bd..b7069318c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,7 +132,7 @@ GEM database_cleaner (1.5.0) debug_inspector (0.0.2) debugger-linecache (1.2.0) - devise (3.4.1) + devise (3.5.6) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) @@ -471,7 +471,7 @@ DEPENDENCIES csv_shaper dalli database_cleaner (~> 1.5.0) - devise (~> 3.4.1) + devise (~> 3.5.0) elasticsearch-model elasticsearch-rails factory_girl_rails (~> 4.5.0) From 03ae327e306202b5c26fba0b6fcf8eca1fe09e49 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:27:15 +1030 Subject: [PATCH 271/392] Name: uglifier Version: 2.5.3 Advisory: 126747 Criticality: Unknown URL: https://github.com/mishoo/UglifyJS2/issues/751 Title: uglifier incorrectly handles non-boolean comparisons during minification Solution: upgrade to >= 2.7.2 --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b7069318c..d17579c88 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -162,7 +162,7 @@ GEM multi_json erubis (2.7.0) excon (0.43.0) - execjs (2.2.2) + execjs (2.6.0) factory_girl (4.5.0) activesupport (>= 3.0.0) factory_girl_rails (4.5.0) @@ -424,7 +424,7 @@ GEM tins (1.3.3) tzinfo (1.2.2) thread_safe (~> 0.1) - uglifier (2.5.3) + uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) unf (0.1.4) @@ -516,7 +516,7 @@ DEPENDENCIES sass-rails (~> 4.0.4) selenium-webdriver therubyracer (~> 0.12) - uglifier (~> 2.5.3) + uglifier (~> 2.7.2) unicorn webrat will_paginate (~> 3.0) From 66bb130a1a14d1cc47a4ea2b78747f8998ea045b Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:33:34 +1030 Subject: [PATCH 272/392] Fix CVE-2015-7551 (https://www.ruby-lang.org/en/news/2015/12/16/unsafe-tainted-string-usage-in-fiddle-and-dl-cve-2015-7551/) --- .travis.yml | 2 +- Gemfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 35ab43fdc..52c876cc6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ env: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" bundler_args: "--without development production staging" rvm: -- 2.1.7 +- 2.1.8 before_script: - psql -c 'create database growstuff_test;' -U postgres script: diff --git a/Gemfile b/Gemfile index 4108dc32f..965d84579 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.1.7' +ruby '2.1.8' gem 'rails', '4.1.11' From 6905cd410ddf821763945adf703c26d688ee962e Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:38:25 +1030 Subject: [PATCH 273/392] Bump to current ruby 2.2.*, as there's an end of life for 2.1.* https://www.ruby-lang.org/en/news/2016/02/24/support-plan-of-ruby-2-0-0-and-2-1/ --- .travis.yml | 2 +- Gemfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 52c876cc6..52e7662f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ env: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" bundler_args: "--without development production staging" rvm: -- 2.1.8 +- 2.2.4 before_script: - psql -c 'create database growstuff_test;' -U postgres script: diff --git a/Gemfile b/Gemfile index 965d84579..2de2fefca 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.1.8' +ruby '2.2.4' gem 'rails', '4.1.11' From 4e7e82c8a8aecb4fd4c3d5ee32a8da02b68fb9a1 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:39:05 +1030 Subject: [PATCH 274/392] Fix CVE-2015-7551 (https://www.ruby-lang.org/en/news/2015/12/16/unsafe-tainted-string-usage-in-fiddle-and-dl-cve-2015-7551/) --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 04b10b4f1..ebf14b469 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.7 +2.1.8 From b0adec20e73b03b18ca348965bc0765df17bc2c2 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:40:17 +1030 Subject: [PATCH 275/392] Fix CVE-2015-7551 (https://www.ruby-lang.org/en/news/2015/12/16/unsafe-tainted-string-usage-in-fiddle-and-dl-cve-2015-7551/) --- .ruby-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ruby-version b/.ruby-version index 04b10b4f1..530cdd91a 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.7 +2.2.4 From 3748f954c52314266bb5b9aaa072e3d989f5b529 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 28 Mar 2016 23:54:29 +1030 Subject: [PATCH 276/392] Name: uglifier Version: 2.5.3 Advisory: 126747 Criticality: Unknown URL: https://github.com/mishoo/UglifyJS2/issues/751 Title: uglifier incorrectly handles non-boolean comparisons during minification Solution: upgrade to >= 2.7.2 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 8b382daa7..f2f722b19 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ gem 'less-rails', '~> 2.5.0' # CSS framework gem 'less-rails-bootstrap', '~> 3.2.0' -gem 'uglifier', '~> 2.5.3' # JavaScript compressor +gem 'uglifier', '~> 2.7.2' # JavaScript compressor gem 'jquery-rails' gem 'jquery-ui-rails', '~> 5.0.2' From df952a1779a99a9d8bdf7f10cf9162f4a9a964ec Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 29 Mar 2016 00:00:07 +1030 Subject: [PATCH 277/392] Bump rspec to fix https://github.com/rspec/rspec-rails/issues/1532 --- Gemfile | 2 +- Gemfile.lock | 41 +++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Gemfile b/Gemfile index f2f722b19..46874457f 100644 --- a/Gemfile +++ b/Gemfile @@ -113,7 +113,7 @@ end group :development, :test do gem 'haml-rails' # HTML templating language - gem 'rspec-rails', '~> 3.1.0' # unit testing framework + gem 'rspec-rails', '~> 3.4.0' # unit testing framework gem 'rspec-activemodel-mocks' gem 'byebug' # debugging gem 'database_cleaner', '~> 1.5.0' diff --git a/Gemfile.lock b/Gemfile.lock index d17579c88..6143e8f3c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -355,30 +355,31 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) - rspec (3.1.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) + rspec (3.4.0) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) rspec-activemodel-mocks (1.0.1) activemodel (>= 3.0) activesupport (>= 3.0) rspec-mocks (>= 2.99, < 4.0) - rspec-core (3.1.7) - rspec-support (~> 3.1.0) - rspec-expectations (3.1.2) + rspec-core (3.4.4) + rspec-support (~> 3.4.0) + rspec-expectations (3.4.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.1.0) - rspec-mocks (3.1.3) - rspec-support (~> 3.1.0) - rspec-rails (3.1.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - railties (>= 3.0) - rspec-core (~> 3.1.0) - rspec-expectations (~> 3.1.0) - rspec-mocks (~> 3.1.0) - rspec-support (~> 3.1.0) - rspec-support (3.1.2) + rspec-support (~> 3.4.0) + rspec-mocks (3.4.1) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.4.0) + rspec-rails (3.4.2) + actionpack (>= 3.0, < 4.3) + activesupport (>= 3.0, < 4.3) + railties (>= 3.0, < 4.3) + rspec-core (~> 3.4.0) + rspec-expectations (~> 3.4.0) + rspec-mocks (~> 3.4.0) + rspec-support (~> 3.4.0) + rspec-support (3.4.1) ruby-units (1.4.5) ruby_parser (3.1.3) sexp_processor (~> 4.1) @@ -511,7 +512,7 @@ DEPENDENCIES rails_12factor rake (>= 10.0.0) rspec-activemodel-mocks - rspec-rails (~> 3.1.0) + rspec-rails (~> 3.4.0) ruby-units sass-rails (~> 4.0.4) selenium-webdriver From 668f6d3a2b99de386bbe00e91a07b052dd594650 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 29 Mar 2016 00:43:14 +1030 Subject: [PATCH 278/392] Fix 'app/views/harvests/_form.html.haml:39: warning: duplicated key at line 39 ignored: :class' --- app/views/harvests/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 0b61ae03e..5908b829e 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -36,7 +36,7 @@ .form-group = f.label :weight_quantity, 'Weighing (in total):', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :weight_quantity, :class => 'input-small', :step => 'any', :class => 'form-control', :placeholder => 'optional' + = f.number_field :weight_quantity, :class => 'input-small form-control', :step => 'any', :placeholder => 'optional' .col-md-2 = f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') .form-group From d9f04d1fa9b870bb755a155e8aa72f3fb6820b51 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sun, 3 Apr 2016 00:02:15 +1030 Subject: [PATCH 279/392] Fixes #853 --- app/views/harvests/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 0b61ae03e..67dbda1e0 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -13,7 +13,7 @@ .col-md-4 = auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop .col-md-4 - = collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id, :include_blank => 'e.g. fruit' }, { :class => 'form-control' }) + = collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id }, { :class => 'form-control', :prompt => 'e.g. fruit', :required => "required" }) %span.help-block.col-md-8 Can't find what you're looking for? = link_to "Request new crops.", new_crop_path From 99a3be08eb0473062f172c66f0762ad50615cdcc Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sun, 3 Apr 2016 00:05:55 +1030 Subject: [PATCH 280/392] Fixes #853 --- app/models/harvest.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 4339a30fa..7bbd2b6ee 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -24,6 +24,8 @@ class Harvest < ActiveRecord::Base validates :crop, :presence => {:message => "must be present and exist in our database"} + validates :plant_part, :presence => {:message => "must be present and exist in our database"} + validates :quantity, :numericality => { :only_integer => false, From de8bcc38d367c697a8c4755691f51708ff8cab03 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sun, 3 Apr 2016 00:13:38 +1030 Subject: [PATCH 281/392] #857 Add length validations to models --- app/models/garden.rb | 6 +++++- app/models/notification.rb | 2 ++ app/models/post.rb | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/garden.rb b/app/models/garden.rb index 0514f2a96..15bbaa9de 100644 --- a/app/models/garden.rb +++ b/app/models/garden.rb @@ -28,10 +28,14 @@ class Garden < ActiveRecord::Base scope :active, -> { where(:active => true) } scope :inactive, -> { where(:active => false) } + validates :location, + :length => { :maximum => 255 } + validates :name, :format => { :with => /\S/ - } + }, + :length => { :maximum => 255 } validates :area, :numericality => { diff --git a/app/models/notification.rb b/app/models/notification.rb index 3825d7b12..01f157df9 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -3,6 +3,8 @@ class Notification < ActiveRecord::Base belongs_to :recipient, :class_name => 'Member' belongs_to :post + validates :subject, :length => { :maximum => 255 } + default_scope { order('created_at DESC') } scope :unread, -> { where(:read => false) } diff --git a/app/models/post.rb b/app/models/post.rb index 3a1b372af..6aaf8b72d 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -41,7 +41,9 @@ class Post < ActiveRecord::Base validates :subject, :format => { :with => /\S/ - } + }, + :length => { :maximum => 255 } + def author_date_subject # slugs are created before created_at is set From a9330f2d77a4c9634fd6ea38006036e8ffc0ce13 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sun, 3 Apr 2016 00:15:45 +1030 Subject: [PATCH 282/392] #857 Add length validations to UI --- app/views/gardens/_form.html.haml | 4 ++-- app/views/notifications/_form.html.haml | 2 +- app/views/posts/_form.html.haml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index 09c3b99ef..74b33249d 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -11,7 +11,7 @@ .form-group.required = f.label :name, :class => 'control-label col-md-2' .col-md-8 - = f.text_field :name, :class => 'form-control' + = f.text_field :name, :class => 'form-control', :maxlength => 255, :required => "required" .form-group = f.label :description, :class => 'control-label col-md-2' @@ -21,7 +21,7 @@ .form-group = f.label :location, :class => 'control-label col-md-2' .col-md-8 - = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :placeholder => 'optional' + = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :placeholder => 'optional', :maxlength => 255 %span.help-block If you have a location set in your profile, it will be used when you create a new garden. diff --git a/app/views/notifications/_form.html.haml b/app/views/notifications/_form.html.haml index 6e73c7444..094be410d 100644 --- a/app/views/notifications/_form.html.haml +++ b/app/views/notifications/_form.html.haml @@ -13,7 +13,7 @@ To: = link_to @recipient, @recipient = label_tag :notification, "Subject:" - = f.text_field :subject, :value => @subject, :class => 'form-control' + = f.text_field :subject, :value => @subject, :class => 'form-control', :maxlength => 255 = label_tag :body, "Type your message here:" = f.text_area :body, :rows => 12, :class => 'form-control' %span.help-block diff --git a/app/views/posts/_form.html.haml b/app/views/posts/_form.html.haml index 1ef7efb51..607b76bd8 100644 --- a/app/views/posts/_form.html.haml +++ b/app/views/posts/_form.html.haml @@ -8,7 +8,7 @@ .form-group = label_tag :post, "Subject", :class => 'control-label' - = f.text_field :subject, :class => 'form-control', :autofocus => 'autofocus' + = f.text_field :subject, :class => 'form-control', :autofocus => 'autofocus', :maxlength => 255 .form-group - if @post.forum || @forum From a800630b0101753caf1002619c1a770a15e6a5e1 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 09:43:45 +0930 Subject: [PATCH 283/392] Ensure we choose a plant part --- spec/features/harvests/harvesting_a_crop_spec.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 802f67a4d..6316b7d70 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -26,7 +26,9 @@ feature "Harvesting a crop", :js do scenario "Creating a new harvest", :js do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" + within "form#new_harvest" do + select "whole plant", from: '#harvest_plant_part_id' fill_in "When?", with: "2014-06-15" fill_in "How many?", with: 42 fill_in "Weighing (in total):", with: 42 From aa2a761a58469ad9dc4edbb2a0be6818401b6da7 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 09:46:29 +0930 Subject: [PATCH 284/392] Ensure we choose a plant part --- spec/features/harvests/harvesting_a_crop_spec.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 6316b7d70..94ea55390 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -63,6 +63,7 @@ feature "Harvesting a crop", :js do visit crop_path(maize) click_link "Harvest this" within "form#new_harvest" do + select "whole plant", from: '#harvest_plant_part_id' expect(page).to have_selector "input[value='maize']" click_button "Save" end From c3a883de16c8b5a4de17903df2ac1134737ee071 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 09:47:53 +0930 Subject: [PATCH 285/392] Ensure we choose a plant part --- spec/controllers/harvests_controller_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb index f8f87042a..b1e6312cd 100644 --- a/spec/controllers/harvests_controller_spec.rb +++ b/spec/controllers/harvests_controller_spec.rb @@ -23,7 +23,8 @@ describe HarvestsController do def valid_attributes { :owner_id => subject.current_member.id, - :crop_id => FactoryGirl.create(:crop).id + :crop_id => FactoryGirl.create(:crop).id, + :plant_part_id => FactoryGirl.create(:plant_part).id } end From a7f9e113d6d64450d763c130eb13e84fd972bf47 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 09:59:06 +0930 Subject: [PATCH 286/392] Target the name attribute --- spec/features/harvests/harvesting_a_crop_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 94ea55390..7ea134ad4 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -28,7 +28,7 @@ feature "Harvesting a crop", :js do select_from_autocomplete "maize" within "form#new_harvest" do - select "whole plant", from: '#harvest_plant_part_id' + select "whole plant", from: 'harvest[plant_part_id]' fill_in "When?", with: "2014-06-15" fill_in "How many?", with: 42 fill_in "Weighing (in total):", with: 42 @@ -63,7 +63,7 @@ feature "Harvesting a crop", :js do visit crop_path(maize) click_link "Harvest this" within "form#new_harvest" do - select "whole plant", from: '#harvest_plant_part_id' + select "whole plant", from: 'harvest[plant_part_id]' expect(page).to have_selector "input[value='maize']" click_button "Save" end From da588b7fdb79f95b8c5a282b7f330480b59a49e0 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 10:08:21 +0930 Subject: [PATCH 287/392] Create the plant part instead of assuming it's seeded --- spec/features/harvests/harvesting_a_crop_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 7ea134ad4..100bcc98f 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -3,6 +3,7 @@ require 'rails_helper' feature "Harvesting a crop", :js do let(:member) { create :member } let!(:maize) { create :maize } + let!(:plant_part) { create :plant_part } background do login_as member @@ -28,7 +29,7 @@ feature "Harvesting a crop", :js do select_from_autocomplete "maize" within "form#new_harvest" do - select "whole plant", from: 'harvest[plant_part_id]' + select plant_part.name, from: 'harvest[plant_part_id]' fill_in "When?", with: "2014-06-15" fill_in "How many?", with: 42 fill_in "Weighing (in total):", with: 42 @@ -63,7 +64,7 @@ feature "Harvesting a crop", :js do visit crop_path(maize) click_link "Harvest this" within "form#new_harvest" do - select "whole plant", from: 'harvest[plant_part_id]' + select plant_part.name, from: 'harvest[plant_part_id]' expect(page).to have_selector "input[value='maize']" click_button "Save" end From a3ad9189b19682024333ba842f3058858fc645b9 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 7 Apr 2016 10:41:35 +0930 Subject: [PATCH 288/392] Fix WARNING: Using the `raise_error` matcher without providing a specific error or message risks false positives, since `raise_error` will match when Ruby raises a `NoMethodError`, `NameError` or `ArgumentError`, potentially allowing the expectation to pass without even executing the method you are intending to call. Actual error raised was #. Instead consider providing a specific error class or message. This message can be supressed by setting: `RSpec::Expectations.configuration.warn_about_potential_false_positives = false`. Called from /home/travis/build/Growstuff/growstuff/spec/controllers/member_controller_spec.rb:65:in `block (3 levels) in '. --- spec/controllers/member_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/member_controller_spec.rb b/spec/controllers/member_controller_spec.rb index 55231ead8..4bd1f6826 100644 --- a/spec/controllers/member_controller_spec.rb +++ b/spec/controllers/member_controller_spec.rb @@ -62,12 +62,12 @@ describe MembersController do end it "doesn't show completely nonsense members" do - lambda { get :show, {:id => 9999} }.should raise_error + lambda { get :show, {:id => 9999} }.should raise_error(ActiveRecord::RecordNotFound) end it "doesn't show unconfirmed members" do @member2 = FactoryGirl.create(:unconfirmed_member) - lambda { get :show, {:id => @member2.id} }.should raise_error + lambda { get :show, {:id => @member2.id} }.should raise_error(ActiveRecord::RecordNotFound) end end From e8d7ed0c2d36d335af990bd10492527a2b6f0b8f Mon Sep 17 00:00:00 2001 From: hcbviolet Date: Fri, 8 Apr 2016 17:34:58 -0700 Subject: [PATCH 289/392] Edit display_harvest_description method for no description --- app/helpers/harvests_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index b4c5bead4..16371b4e9 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -38,8 +38,8 @@ module HarvestsHelper end def display_harvest_description(harvest) - if harvest.description.nil? - "no description provided." + if harvest.description.empty? + "No description provided." else truncate(harvest.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", harvest_path(harvest) } end From 7bb7a18b66ee0886af0764956b4469ae14d6c0f7 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 9 Apr 2016 21:45:13 +0930 Subject: [PATCH 290/392] Fixes #850 Refactors percentage grown to model, stops rendering progress bars in situations it doesn't make sense. Adds specs. --- app/models/planting.rb | 20 +++++++++ .../plantings/_planting_progress.html.haml | 12 ++---- app/views/plantings/_thumbnail.html.haml | 2 +- spec/models/planting_spec.rb | 42 +++++++++++++++++++ 4 files changed, 67 insertions(+), 9 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index 900156b2a..2e9e22149 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -109,6 +109,26 @@ class Planting < ActiveRecord::Base end end + def planted?(current_date = DateTime.now) + planted_at.present? && current_date.to_date >= planted_at + end + + def percentage_grown(current_date = DateTime.now) + return nil unless days_before_maturity && planted?(current_date) + + return 0 if current_date < planted_at + return 100 if days > days_before_maturity + + days = current_date - planted_at + percent = (days/days_before_maturity*100).to_i + + if percent >= 100 + percent = 100 + end + + percent + end + # return a list of interesting plantings, for the homepage etc. # we can't do this via a scope (as far as we know) so sadly we have to # do it this way. diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index eea698c82..57cdaeaf6 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -1,14 +1,10 @@ -- if (planting.planted_at.nil? || DateTime.now.to_date < planting.planted_at) +- unless planting.planted? = "Progress: 0% - not planted yet" - = render partial: "plantings/progress_bar", locals: {status: "warning", progress: "100%"} - elsif planting.finished? = "Progress: 100%" = render partial: "plantings/progress_bar", locals: {status: "success", progress: "100%"} - elsif planting.days_before_maturity.nil? - = "Progress: 0% - Days before maturity unknown" - = render partial: "plantings/progress_bar", locals: {status: "danger", progress: "100%"} + = "Progress: Not calculated, days before maturity unknown" - else - - if (percent = (((DateTime.now - planting.planted_at)/planting.days_before_maturity*100).to_i)) >= 100 - - percent = 100 - = "Progress: #{percent}%" - = render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{percent}%"} \ No newline at end of file + = "Progress: #{planting.percentage_grown}%" + = render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{planting.percentage_grown}%"} \ No newline at end of file diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 9790cb127..fbc859963 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -38,4 +38,4 @@ %dd= "#{display_days_before_maturity(planting)}" .col-xs-9.col-md-8 - = render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file + = render partial: 'plantings/planting_progress', locals: {planting: planting} \ No newline at end of file diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 659636c5e..1575c9320 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -37,6 +37,48 @@ describe Planting do Planting.first.should eq @planting2 end + describe '#planted?' do + it "should be false for future plantings" + it "should be false for never planted" + it "should be false for future plantings" + end + + describe '#percentage_grown' do + it 'should not be more than 100%' do + @planting = FactoryGirl.build(:planting, days_before_maturity: 1, planted_at: 1.day.ago) + + now_later_than_planting = 2.days.from_now + + @planting.percentage_grown(now_later_than_planting).should be 100 + end + + it 'should not be less than 0%' do + @planting = FactoryGirl.build(:planting, days_before_maturity: 1, planted_at: 1.day.ago) + + now_earlier_than_planting = 2.days.ago + + @planting.percentage_grown(now_earlier_than_planting).should be 0 + end + + it 'should reflect the current growth' do + @planting = FactoryGirl.build(:planting, days_before_maturity: 10, planted_at: 4.days.ago) + + @planting.percentage_grown.should be 40 + end + + it 'should not be calculated for unplanted plantings' do + @planting = FactoryGirl.build(:planting, planted_at: nil) + + @planting.planted?.should be false + @planting.percentage_grown.should be nil + end + it 'should not be calculated for plantings with an unknown days before maturity' do + @planting = FactoryGirl.build(:planting, days_before_maturity: nil) + + @planting.percentage_grown.should be nil + end + end + context 'delegation' do it 'system name' do planting.crop_name.should eq planting.crop.name From 69fb98146b296bdc6cec5a0070c355a1e167001d Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 9 Apr 2016 22:01:05 +0930 Subject: [PATCH 291/392] Adjust logic --- app/views/plantings/_planting_progress.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index 57cdaeaf6..7fe6d52f7 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -1,4 +1,4 @@ -- unless planting.planted? +- if !planting.planted? = "Progress: 0% - not planted yet" - elsif planting.finished? = "Progress: 100%" From 5cfa051d75e54ddfd3c56021b876d1a85784c369 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 9 Apr 2016 22:43:17 +0930 Subject: [PATCH 292/392] Update expectations --- spec/features/plantings/planting_a_crop_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 753bbe457..06b4480ea 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -42,7 +42,7 @@ feature "Planting a crop", :js do end expect(page).to have_content "Planting was successfully created" - expect(page).to have_content "Progress: 0% - Days before maturity unknown" + expect(page).to have_content "Progress: Not calculated, days before maturity unknown" end scenario "Clicking link to owner's profile" do @@ -87,7 +87,7 @@ feature "Planting a crop", :js do end expect(page).to have_content "Planting was successfully created" - expect(page).to have_content "Progress: 0% - Days before maturity unknown" + expect(page).to have_content "Progress: Not calculated, days before maturity unknown" expect(page).to have_content "Days until maturity: unknown" end @@ -106,7 +106,7 @@ feature "Planting a crop", :js do expect(page).to have_content "Planting was successfully created" expect(page).to_not have_content "Progress: 0% - not planted yet" - expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" + expect(page).to_not have_content "Progress: Not calculated, days before maturity unknown" end it "should show that planting is 100% complete (no date specified)" do @@ -169,13 +169,13 @@ feature "Planting a crop", :js do scenario "Editing a planting to fill in the finished date" do visit planting_path(planting) - expect(page).to have_content "Progress: 0% - Days before maturity unknown" + expect(page).to have_content "Progress: Not calculated, days before maturity unknown" click_link "Edit" check "finished" fill_in "Finished date", with: "2015-06-25" click_button "Save" expect(page).to have_content "Planting was successfully updated" - expect(page).to_not have_content "Progress: 0% - Days before maturity unknown" + expect(page).to_not have_content "Progress: Not calculated, days before maturity unknown" end scenario "Marking a planting as finished" do From 3644a8124f4ddfae4383d3dff005a327ff2a3e50 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 9 Apr 2016 22:54:03 +0930 Subject: [PATCH 293/392] Tweak specs, implementation properly --- app/models/planting.rb | 8 ++++---- spec/models/planting_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index 2e9e22149..b9566c62b 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -109,17 +109,17 @@ class Planting < ActiveRecord::Base end end - def planted?(current_date = DateTime.now) + def planted?(current_date = Date.today) planted_at.present? && current_date.to_date >= planted_at end - def percentage_grown(current_date = DateTime.now) + def percentage_grown(current_date = Date.today) return nil unless days_before_maturity && planted?(current_date) + days = (current_date.to_date - planted_at.to_date).to_i + return 0 if current_date < planted_at return 100 if days > days_before_maturity - - days = current_date - planted_at percent = (days/days_before_maturity*100).to_i if percent >= 100 diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 1575c9320..90b4da713 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -57,13 +57,13 @@ describe Planting do now_earlier_than_planting = 2.days.ago - @planting.percentage_grown(now_earlier_than_planting).should be 0 + @planting.percentage_grown(now_earlier_than_planting).should be nil end it 'should reflect the current growth' do @planting = FactoryGirl.build(:planting, days_before_maturity: 10, planted_at: 4.days.ago) - @planting.percentage_grown.should be 40 + @planting.percentage_grown(Date.today).should be 40 end it 'should not be calculated for unplanted plantings' do From 82553d6e0a42273918f5681959d1eb070e666475 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 11 Apr 2016 09:29:06 +0930 Subject: [PATCH 294/392] Avoid time travel in favour of calculating a number of past/future dates --- .../plantings/planting_a_crop_spec.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 06b4480ea..fc255d313 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -53,16 +53,19 @@ feature "Planting a crop", :js do describe "Progress bar status on planting creation" do before do - DateTime.stub(:now) { DateTime.new(2015, 10, 20, 10, 34) } login_as member visit new_planting_path + + @a_past_date = 15.days.ago.strftime("%Y-%m-%d") + @right_now = Date.today.strftime("%Y-%m-%d") + @a_future_date = 1.years.from_now.strftime("%Y-%m-%d") end it "should show that it is not planted yet" do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", with: "2015-12-15" + fill_in "When", with: @a_future_date fill_in "How many?", with: 42 select "cutting", from: "Planted from:" select "semi-shade", from: "Sun or shade?" @@ -78,7 +81,7 @@ feature "Planting a crop", :js do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", with: "2015-9-15" + fill_in "When", with: @a_past_date fill_in "How many?", with: 42 select "cutting", from: "Planted from:" select "semi-shade", from: "Sun or shade?" @@ -95,12 +98,12 @@ feature "Planting a crop", :js do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", with: "2015-10-15" + fill_in "When", with: @right_now fill_in "How many?", with: 42 select "cutting", from: "Planted from:" select "semi-shade", from: "Sun or shade?" fill_in "Tell us more about it", with: "It's rad." - fill_in "Finished date", with: "2015-10-30" + fill_in "Finished date", with: @a_future_date click_button "Save" end @@ -113,7 +116,7 @@ feature "Planting a crop", :js do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", with: "2015-10-15" + fill_in "When", with: @right_now fill_in "How many?", with: 42 select "cutting", from: "Planted from:" select "semi-shade", from: "Sun or shade?" @@ -132,12 +135,12 @@ feature "Planting a crop", :js do fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_planting" do - fill_in "When", with: "2015-10-15" + fill_in "When", with: @a_past_date fill_in "How many?", with: 42 select "cutting", from: "Planted from:" select "semi-shade", from: "Sun or shade?" fill_in "Tell us more about it", with: "It's rad." - fill_in "Finished date", with: "2015-10-19" + fill_in "Finished date", with: @right_now click_button "Save" end From e3c689ba6b943164406365e0dc9f6837989a0fc9 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 11 Apr 2016 09:51:52 +0930 Subject: [PATCH 295/392] Fixes #851 Correct the link to be specific to the author --- app/views/posts/index.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.html.haml b/app/views/posts/index.html.haml index 4a5846f55..8cc176f9a 100644 --- a/app/views/posts/index.html.haml +++ b/app/views/posts/index.html.haml @@ -30,11 +30,11 @@ - if @author Subscribe to = succeed "." do - = link_to "#{@author}'s posts RSS feed", posts_path(:format => 'rss') + = link_to "#{@author}'s posts RSS feed", posts_by_author_path(format: 'rss', author: @author) - else Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} - = link_to "posts RSS feed", posts_path(:format => 'rss') + = link_to "posts RSS feed", posts_by_author(:format => 'rss') or = succeed "." do = link_to "comments RSS feed", comments_path(:format => 'rss') From 3ff3ffa4573858bf4481c5f11532ae7e0b10b372 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 11 Apr 2016 09:55:03 +0930 Subject: [PATCH 296/392] Don't update that link, geesh. Need more coffee! --- app/views/posts/index.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/index.html.haml b/app/views/posts/index.html.haml index 8cc176f9a..9eee54694 100644 --- a/app/views/posts/index.html.haml +++ b/app/views/posts/index.html.haml @@ -34,7 +34,7 @@ - else Subscribe to the #{ENV['GROWSTUFF_SITE_NAME']} - = link_to "posts RSS feed", posts_by_author(:format => 'rss') + = link_to "posts RSS feed", posts_path(:format => 'rss') or = succeed "." do = link_to "comments RSS feed", comments_path(:format => 'rss') From 12ad16a05a5bf6ba1ed9af003d2ea74693f772d5 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Wed, 13 Apr 2016 08:41:05 +0930 Subject: [PATCH 297/392] Newlines --- spec/models/planting_spec.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 90b4da713..dfccd8352 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -72,6 +72,7 @@ describe Planting do @planting.planted?.should be false @planting.percentage_grown.should be nil end + it 'should not be calculated for plantings with an unknown days before maturity' do @planting = FactoryGirl.build(:planting, days_before_maturity: nil) @@ -83,12 +84,15 @@ describe Planting do it 'system name' do planting.crop_name.should eq planting.crop.name end + it 'wikipedia url' do planting.crop_en_wikipedia_url.should eq planting.crop.en_wikipedia_url end + it 'default scientific name' do planting.crop_default_scientific_name.should eq planting.crop.default_scientific_name end + it 'plantings count' do planting.crop_plantings_count.should eq planting.crop.plantings_count end @@ -309,13 +313,11 @@ describe Planting do @f = FactoryGirl.build(:planting, :planted_at => '2013-01-01', :finished_at => nil) @f.should be_valid end + it 'allows just the finished date' do @f = FactoryGirl.build(:planting, :finished_at => '2013-01-01', :planted_at => nil) @f.should be_valid end - end - end - -end +end \ No newline at end of file From cf0a6466996e3dd9ee04d37cf3f56f869228cecd Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 14 Apr 2016 09:59:36 +0930 Subject: [PATCH 298/392] Add EOF newlines --- app/views/plantings/_planting_progress.html.haml | 2 +- app/views/plantings/_thumbnail.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/plantings/_planting_progress.html.haml b/app/views/plantings/_planting_progress.html.haml index 7fe6d52f7..a9c851709 100644 --- a/app/views/plantings/_planting_progress.html.haml +++ b/app/views/plantings/_planting_progress.html.haml @@ -7,4 +7,4 @@ = "Progress: Not calculated, days before maturity unknown" - else = "Progress: #{planting.percentage_grown}%" - = render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{planting.percentage_grown}%"} \ No newline at end of file + = render partial: "plantings/progress_bar", locals: {status: "success", progress: "#{planting.percentage_grown}%"} diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index fbc859963..df62f7a9c 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -38,4 +38,4 @@ %dd= "#{display_days_before_maturity(planting)}" .col-xs-9.col-md-8 - = render partial: 'plantings/planting_progress', locals: {planting: planting} \ No newline at end of file + = render partial: 'plantings/planting_progress', locals: {planting: planting} From 02615dc5226602493f46cb756a023651ad9a2a73 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 17 May 2016 13:33:12 +0930 Subject: [PATCH 299/392] $ bundle update selenium-webdriver guard guard-rspec rails factory_girl pg simplecov coveralls newrelic_rpm better_errors minitest --- Gemfile.lock | 85 +++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 6143e8f3c..f02e334e1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,7 +54,7 @@ GEM execjs json bcrypt (3.1.11) - better_errors (2.0.0) + better_errors (2.1.1) coderay (>= 1.0.0) erubis (>= 2.6.6) rack (>= 0.9.0) @@ -86,7 +86,7 @@ GEM capybara-email (2.4.0) capybara (~> 2.4) mail - childprocess (0.5.6) + childprocess (0.5.9) ffi (~> 1.0, >= 1.0.11) climate_control (0.0.3) activesupport (>= 3.0) @@ -95,7 +95,7 @@ GEM climate_control (>= 0.0.3, < 1.0) codemirror-rails (4.8) railties (>= 3.0, < 5) - coderay (1.1.0) + coderay (1.1.1) coffee-rails (4.1.0) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.0) @@ -120,12 +120,12 @@ GEM rails-i18n (>= 4.0.0) sass-rails (>= 4.0.3) commonjs (0.2.7) - coveralls (0.7.1) - multi_json (~> 1.3) - rest-client - simplecov (>= 0.7) - term-ansicolor - thor + coveralls (0.8.13) + json (~> 1.8) + simplecov (~> 0.11.0) + term-ansicolor (~> 1.3) + thor (~> 0.19.1) + tins (~> 1.6.0) csv_shaper (1.1.1) activesupport (>= 3.0.0) dalli (2.7.2) @@ -141,8 +141,6 @@ GEM warden (~> 1.2.3) diff-lcs (1.2.5) docile (1.1.5) - domain_name (0.5.24) - unf (>= 0.0.5, < 1.0.0) easy_translate (0.5.0) json thread @@ -183,7 +181,7 @@ GEM gravatar-ultimate (2.0.0) activesupport (>= 2.3.14) rack - guard (2.12.8) + guard (2.13.0) formatador (>= 0.2.4) listen (>= 2.7, <= 4.0) lumberjack (~> 1.0) @@ -193,7 +191,7 @@ GEM shellany (~> 0.0) thor (>= 0.18.1) guard-compat (1.2.1) - guard-rspec (4.6.2) + guard-rspec (4.6.5) guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) @@ -217,8 +215,6 @@ GEM haml (>= 4.0.0.rc.1) hpricot (~> 0.8.6) ruby_parser (~> 3.1.1) - http-cookie (1.0.2) - domain_name (~> 0.5) httparty (0.13.3) json (~> 1.8) multi_xml (>= 0.5.2) @@ -261,27 +257,29 @@ GEM letter_opener (1.3.0) launchy (~> 2.2) libv8 (3.16.14.7) - listen (3.0.2) - rb-fsevent (>= 0.9.3) - rb-inotify (>= 0.9) - lumberjack (1.0.9) + listen (3.1.4) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + lumberjack (1.0.10) mail (2.6.4) mime-types (>= 1.16, < 4) memcachier (0.0.2) method_source (0.8.2) - mime-types (2.99.1) + mime-types (3.0) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0221) mimemagic (0.3.0) mini_portile2 (2.0.0) - minitest (5.8.4) - multi_json (1.11.2) + minitest (5.9.0) + multi_json (1.12.0) multi_xml (0.5.5) multipart-post (2.0.0) - nenv (0.2.0) - netrc (0.10.3) - newrelic_rpm (3.9.8.273) + nenv (0.3.0) + newrelic_rpm (3.15.2.317) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) - notiffany (0.0.6) + notiffany (0.0.8) nenv (~> 0.1) shellany (~> 0.0) oauth (0.4.7) @@ -303,7 +301,7 @@ GEM cocaine (~> 0.5.5) mime-types mimemagic (= 0.3.0) - pg (0.17.1) + pg (0.18.4) plupload-rails (1.2.1) rails (>= 3.1) poltergeist (1.6.0) @@ -311,7 +309,7 @@ GEM cliver (~> 0.3.1) multi_json (~> 1.0) websocket-driver (>= 0.2.0) - pry (0.10.1) + pry (0.10.3) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) @@ -345,16 +343,12 @@ GEM thor (>= 0.18.1, < 2.0) raindrops (0.13.0) rake (11.1.2) - rb-fsevent (0.9.5) - rb-inotify (0.9.5) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) ffi (>= 0.5.0) ref (1.0.5) responders (1.1.2) railties (>= 3.2, < 4.2) - rest-client (1.8.0) - http-cookie (>= 1.0.2, < 2.0) - mime-types (>= 1.16, < 3.0) - netrc (~> 0.7) rspec (3.4.0) rspec-core (~> 3.4.0) rspec-expectations (~> 3.4.0) @@ -381,27 +375,27 @@ GEM rspec-support (~> 3.4.0) rspec-support (3.4.1) ruby-units (1.4.5) + ruby_dep (1.3.1) ruby_parser (3.1.3) sexp_processor (~> 4.1) - rubyzip (1.1.7) + rubyzip (1.2.0) sass (3.2.19) sass-rails (4.0.5) railties (>= 4.0.0, < 5.0) sass (~> 3.2.2) sprockets (~> 2.8, < 3.0) sprockets-rails (~> 2.0) - selenium-webdriver (2.47.1) + selenium-webdriver (2.53.0) childprocess (~> 0.5) - multi_json (~> 1.0) rubyzip (~> 1.0) websocket (~> 1.0) sexp_processor (4.4.4) shellany (0.0.1) - simplecov (0.9.1) + simplecov (0.11.2) docile (~> 1.1.0) - multi_json (~> 1.0) - simplecov-html (~> 0.8.0) - simplecov-html (0.8.0) + json (~> 1.8) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.0) slop (3.6.0) sprockets (2.12.4) hike (~> 1.2) @@ -412,7 +406,7 @@ GEM actionpack (>= 3.0) activesupport (>= 3.0) sprockets (>= 2.8, < 4.0) - term-ansicolor (1.3.0) + term-ansicolor (1.3.2) tins (~> 1.0) terminal-table (1.4.5) therubyracer (0.12.1) @@ -422,15 +416,12 @@ GEM thread (0.1.4) thread_safe (0.3.5) tilt (1.4.1) - tins (1.3.3) + tins (1.6.0) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.7.1) unicorn (4.8.3) kgio (~> 2.6) rack @@ -441,7 +432,7 @@ GEM nokogiri (>= 1.2.0) rack (>= 1.0) rack-test (>= 0.5.3) - websocket (1.2.2) + websocket (1.2.3) websocket-driver (0.5.4) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) From fafb421a51fe7e8bf94bf460060f0ee7a4da9bc2 Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Tue, 17 May 2016 13:47:33 -0400 Subject: [PATCH 300/392] Add code climate to README Our code climate score is *abysmal*, but now that I've been using it in my job for a few months, I have some ideas how to improve it. It's all about clean code (check out the book of that name from your local library) and readability. So let's add the grade to the README, and I'll figure out how to set it up so that Code Climate is run on pull requests automatically (telling us whether things are going to get better or worse with every PR). --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index f3cfb101b..18eeb2baa 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.org/Growstuff/growstuff.png)](https://travis-ci.org/Growstuff/growstuff) [![Coverage Status](https://coveralls.io/repos/Growstuff/growstuff/badge.png)](https://coveralls.io/r/Growstuff/growstuff) +[![Code Climate](https://codeclimate.com/github/Growstuff/growstuff/badges/gpa.svg)](https://codeclimate.com/github/Growstuff/growstuff) Welcome to the Growstuff project. From 1442a9106ca92bb3b0630fc526759fd1b4ec8b9c Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Tue, 17 May 2016 13:58:55 -0400 Subject: [PATCH 301/392] add code climate / travis gem --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index c4f090a8a..1ad0d8c14 100644 --- a/Gemfile +++ b/Gemfile @@ -125,6 +125,7 @@ group :development, :test do gem 'poltergeist', '~> 1.6' # for headless JS testing gem 'i18n-tasks' # adds tests for finding missing and unused translations gem 'selenium-webdriver' + gem "codeclimate-test-reporter", group: :test, require: nil end group :travis do From 925027f7f062d8c22504675ac1cea5b675b9abbd Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Tue, 17 May 2016 14:02:42 -0400 Subject: [PATCH 302/392] add code climate test reporter --- spec/spec_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 191e049ee..8c7b0b9fe 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -14,6 +14,8 @@ # users commonly want. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +require "codeclimate-test-reporter" +CodeClimate::TestReporter.start RSpec.configure do |config| # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest From 4a341bb7ab69e64a5630969b29d32d61a77a3744 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 19 May 2016 13:33:36 +0100 Subject: [PATCH 303/392] Install *all* gems in CI Previously we were only installing the gems needed for testing. This caused our CI to miss an incompatibility problem with a gem that was only needed for another environment: https://github.com/Growstuff/growstuff/pull/878#discussion_r63745751 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 52c876cc6..42fb140d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ env: - GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' GROWSTUFF_ELASTICSEARCH='false' global: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" -bundler_args: "--without development production staging" rvm: - 2.1.8 before_script: From 79db3c4c1dbe89b14c0e801aa7f6ec441d264461 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 19 May 2016 14:40:24 +0100 Subject: [PATCH 304/392] Fix "duplicated key: :class" warning in HAML code The warning was app/views/harvests/_form.html.haml:32: warning: duplicated key at line 32 ignored: :class We were specifying two `:class` attributes on an HTML tag; I've combined them into one. --- app/views/harvests/_form.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 67dbda1e0..40305a04a 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -29,7 +29,7 @@ -# Some browsers (eg Firefox for Android) assume "number" means -# "integer" unless you specify step="any": -# http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/ - = f.number_field :quantity, :class => 'input-small', :step => 'any', :class => 'form-control', :placeholder => 'optional' + = f.number_field :quantity, :class => 'input-small form-control', :step => 'any', :placeholder => 'optional' .col-md-2 = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium form-control') From 4b4e0cf69ac3216efe2d2f990c5668e39faefa27 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 14 Apr 2016 10:06:02 +0930 Subject: [PATCH 305/392] $ rubocop --only HashSyntax --auto-correct 483 files inspected, 2018 offenses detected, 2018 offenses corrected --- app/controllers/admin/orders_controller.rb | 2 +- app/controllers/alternate_names_controller.rb | 2 +- app/controllers/application_controller.rb | 2 +- app/controllers/authentications_controller.rb | 12 +- app/controllers/comments_controller.rb | 8 +- app/controllers/crops_controller.rb | 34 ++--- app/controllers/follows_controller.rb | 4 +- app/controllers/gardens_controller.rb | 8 +- app/controllers/harvests_controller.rb | 6 +- app/controllers/members_controller.rb | 20 +-- app/controllers/order_items_controller.rb | 2 +- app/controllers/orders_controller.rb | 22 +-- app/controllers/photos_controller.rb | 4 +- app/controllers/places_controller.rb | 4 +- app/controllers/plantings_controller.rb | 14 +- app/controllers/posts_controller.rb | 14 +- app/controllers/registrations_controller.rb | 2 +- .../scientific_names_controller.rb | 2 +- app/controllers/seeds_controller.rb | 12 +- app/helpers/application_helper.rb | 6 +- app/helpers/harvests_helper.rb | 8 +- app/helpers/notifications_helper.rb | 2 +- app/mailers/notifier.rb | 14 +- app/models/ability.rb | 62 ++++---- app/models/account.rb | 4 +- app/models/alternate_name.rb | 2 +- app/models/comment.rb | 12 +- app/models/crop.rb | 58 ++++---- app/models/follow.rb | 10 +- app/models/forum.rb | 2 +- app/models/garden.rb | 34 ++--- app/models/harvest.rb | 40 ++--- app/models/member.rb | 94 ++++++------ app/models/notification.rb | 8 +- app/models/order.rb | 16 +- app/models/order_item.rb | 2 +- app/models/photo.rb | 16 +- app/models/plant_part.rb | 4 +- app/models/planting.rb | 42 +++--- app/models/post.rb | 18 +-- app/models/product.rb | 8 +- app/models/scientific_name.rb | 2 +- app/models/seed.rb | 62 ++++---- config/application.rb | 8 +- config/database.yml | 3 +- config/environments/development.rb | 18 +-- config/environments/production.rb | 20 +-- config/environments/staging.rb | 20 +-- config/environments/test.rb | 4 +- .../initializers/comfortable_mexican_sofa.rb | 2 +- config/initializers/geocoder.rb | 8 +- config/routes.rb | 12 +- .../20120903092956_devise_create_users.rb | 16 +- ...003190731_require_system_name_for_crops.rb | 4 +- db/migrate/20121105032913_create_gardens.rb | 4 +- .../20121107012827_create_scientific_names.rb | 4 +- db/migrate/20121108105440_create_updates.rb | 6 +- db/migrate/20121219022554_create_plantings.rb | 4 +- ...30208034248_require_fields_for_comments.rb | 12 +- .../20130212123628_create_notifications.rb | 2 +- db/migrate/20130213014511_create_forums.rb | 6 +- db/migrate/20130214024117_create_roles.rb | 2 +- .../20130214034838_add_members_roles_table.rb | 2 +- .../20130222060730_default_read_to_false.rb | 4 +- ...20130327120024_add_send_email_to_member.rb | 2 +- .../20130404174459_create_authentications.rb | 4 +- ...130409103549_make_post_subject_non_null.rb | 2 +- db/migrate/20130507105357_create_products.rb | 6 +- db/migrate/20130507110411_create_orders.rb | 2 +- ...0130507113915_add_orders_products_table.rb | 2 +- db/migrate/20130508104506_create_photos.rb | 8 +- .../20130509123711_add_metadata_to_photos.rb | 6 +- .../20130517015920_create_account_details.rb | 2 +- ...0130517234458_require_account_type_name.rb | 4 +- ...130531110729_add_photos_plantings_table.rb | 2 +- db/migrate/20130715110134_create_seeds.rb | 4 +- db/migrate/20130917053547_create_harvests.rb | 4 +- .../20131025104228_add_fields_to_gardens.rb | 2 +- ...8075753_default_plantings_count_to_zero.rb | 4 +- ...20140829230600_add_finished_to_planting.rb | 2 +- ...0140905001730_add_harvests_photos_table.rb | 2 +- .../20140928044231_add_crops_posts_table.rb | 2 +- ...13_add_send_planting_reminder_to_member.rb | 2 +- .../20141018111015_create_alternate_names.rb | 6 +- .../20150124110540_add_properties_to_seeds.rb | 6 +- ...20150127043022_add_gardens_photos_table.rb | 2 +- db/migrate/20150201052245_create_cms.rb | 100 ++++++------- db/seeds.rb | 78 +++++----- lib/haml/filters/growstuff_markdown.rb | 6 +- lib/tasks/growstuff.rake | 90 ++++++------ lib/tasks/hooks.rake | 2 +- lib/tasks/testing.rake | 2 +- script/heroku_maintenance.rb | 2 +- .../admin/orders_controller_spec.rb | 4 +- .../authentications_controller_spec.rb | 2 +- spec/controllers/comments_controller_spec.rb | 20 +-- spec/controllers/crops_controller_spec.rb | 8 +- spec/controllers/gardens_controller_spec.rb | 2 +- spec/controllers/harvests_controller_spec.rb | 44 +++--- spec/controllers/member_controller_spec.rb | 22 +-- .../notifications_controller_spec.rb | 20 +-- .../order_items_controller_spec.rb | 36 ++--- spec/controllers/orders_controller_spec.rb | 16 +- spec/controllers/photos_controller_spec.rb | 116 +++++++-------- spec/controllers/places_controller_spec.rb | 6 +- spec/controllers/plantings_controller_spec.rb | 20 +-- spec/controllers/posts_controller_spec.rb | 6 +- spec/controllers/products_controller_spec.rb | 6 +- .../registrations_controller_spec.rb | 4 +- .../scientific_names_controller_spec.rb | 4 +- spec/controllers/seeds_controller_spec.rb | 2 +- spec/controllers/shop_controller_spec.rb | 2 +- spec/features/admin/account_types_spec.rb | 4 +- spec/features/admin/forums_spec.rb | 4 +- spec/features/crops/alternate_name_spec.rb | 2 +- spec/features/crops/crop_detail_page_spec.rb | 4 +- spec/features/crops/crop_wranglers_spec.rb | 4 +- spec/features/footer_spec.rb | 2 +- spec/features/gardens_spec.rb | 2 +- spec/features/locale_spec.rb | 2 +- spec/features/member_profile_spec.rb | 4 +- spec/features/members_list_spec.rb | 2 +- spec/features/scientific_name_spec.rb | 2 +- spec/features/seeds/adding_seeds_spec.rb | 12 +- spec/features/seeds/misc_seeds_spec.rb | 2 +- spec/features/shared_examples/crop_suggest.rb | 2 +- spec/features/signin_spec.rb | 2 +- spec/features/signup_spec.rb | 2 +- spec/helpers/harvests_helper_spec.rb | 46 +++--- spec/helpers/notifications_helper_spec.rb | 6 +- spec/helpers/plantings_helper_spec.rb | 38 ++--- .../haml/filters/growstuff_markdown_spec.rb | 6 +- spec/models/ability_spec.rb | 26 ++-- spec/models/account_spec.rb | 2 +- spec/models/alternate_name_spec.rb | 6 +- spec/models/comment_spec.rb | 10 +- spec/models/crop_spec.rb | 138 +++++++++--------- spec/models/follow_spec.rb | 8 +- spec/models/forum_spec.rb | 8 +- spec/models/garden_spec.rb | 70 ++++----- spec/models/harvest_spec.rb | 128 ++++++++-------- spec/models/member_spec.rb | 64 ++++---- spec/models/notification_spec.rb | 10 +- spec/models/order_item_spec.rb | 6 +- spec/models/order_spec.rb | 58 ++++---- spec/models/photo_spec.rb | 2 +- spec/models/plant_part_spec.rb | 16 +- spec/models/planting_spec.rb | 43 +++--- spec/models/post_spec.rb | 56 +++---- spec/models/seed_spec.rb | 36 ++--- spec/rails_helper.rb | 4 +- spec/routing/account_types_routing_spec.rb | 8 +- spec/routing/authentications_routing_spec.rb | 2 +- spec/routing/comments_routing_spec.rb | 8 +- spec/routing/crops_routing_spec.rb | 8 +- spec/routing/follows_routing_spec.rb | 2 +- spec/routing/forums_routing_spec.rb | 8 +- spec/routing/gardens_routing_spec.rb | 8 +- spec/routing/harvests_routing_spec.rb | 8 +- spec/routing/notifications_routing_spec.rb | 8 +- spec/routing/order_items_routing_spec.rb | 8 +- spec/routing/orders_routing_spec.rb | 8 +- spec/routing/photos_routing_spec.rb | 8 +- spec/routing/plant_parts_routing_spec.rb | 8 +- spec/routing/plantings_routing_spec.rb | 8 +- spec/routing/products_routing_spec.rb | 8 +- spec/routing/roles_routing_spec.rb | 8 +- spec/routing/scientific_names_routing_spec.rb | 8 +- spec/routing/seeds_routing_spec.rb | 8 +- spec/routing/updates_routing_spec.rb | 8 +- spec/support/database_cleaner.rb | 2 +- spec/support/devise.rb | 4 +- spec/support/feature_helpers.rb | 4 +- spec/views/about/contact_spec.rb | 2 +- .../account_types/edit.html.haml_spec.rb | 14 +- .../account_types/index.html.haml_spec.rb | 2 +- .../views/account_types/new.html.haml_spec.rb | 14 +- .../account_types/show.html.haml_spec.rb | 6 +- spec/views/accounts/edit.html.haml_spec.rb | 6 +- spec/views/accounts/index.html.haml_spec.rb | 2 +- spec/views/accounts/new.html.haml_spec.rb | 6 +- spec/views/admin/index_spec.rb | 10 +- spec/views/admin/newsletter_spec.rb | 2 +- spec/views/admin/orders/index_spec.rb | 4 +- spec/views/comments/edit.html.haml_spec.rb | 4 +- spec/views/comments/index.html.haml_spec.rb | 4 +- spec/views/comments/index.rss.haml_spec.rb | 4 +- spec/views/comments/new.html.haml_spec.rb | 6 +- spec/views/crops/_grown_for.html.haml_spec.rb | 8 +- .../crops/_planting_advice.html.haml_spec.rb | 34 ++--- spec/views/crops/_popover.html.haml_spec.rb | 6 +- spec/views/crops/hierarchy.html.haml_spec.rb | 4 +- spec/views/crops/index.html.haml_spec.rb | 12 +- spec/views/crops/wrangle.html.haml_spec.rb | 6 +- spec/views/devise/confirmations/new_spec.rb | 2 +- .../mailer/confirmation_instructions_spec.rb | 2 +- .../reset_password_instructions_spec.rb | 2 +- .../devise/mailer/unlock_instructions_spec.rb | 2 +- spec/views/devise/registrations/edit_spec.rb | 18 +-- spec/views/devise/registrations/new_spec.rb | 2 +- spec/views/devise/sessions/new_spec.rb | 2 +- spec/views/devise/shared/_links_spec.rb | 18 +-- spec/views/devise/unlocks/new_spec.rb | 2 +- spec/views/forums/edit.html.haml_spec.rb | 14 +- spec/views/forums/index.html.haml_spec.rb | 8 +- spec/views/forums/new.html.haml_spec.rb | 8 +- spec/views/forums/show.html.haml_spec.rb | 4 +- spec/views/gardens/edit.html.haml_spec.rb | 16 +- spec/views/gardens/new.html.haml_spec.rb | 16 +- spec/views/gardens/show.html.haml_spec.rb | 4 +- spec/views/harvests/edit.html.haml_spec.rb | 18 +-- spec/views/harvests/index.html.haml_spec.rb | 14 +- spec/views/harvests/new.html.haml_spec.rb | 18 +-- spec/views/harvests/show.html.haml_spec.rb | 2 +- spec/views/home/_blurb.html.haml_spec.rb | 6 +- spec/views/home/_crops.html.haml_spec.rb | 12 +- spec/views/home/_members.html.haml_spec.rb | 4 +- spec/views/home/_seeds.html.haml_spec.rb | 10 +- spec/views/home/_stats.html.haml_spec.rb | 2 +- spec/views/home/index_spec.rb | 6 +- spec/views/layouts/_header_spec.rb | 14 +- spec/views/layouts/_meta_spec.rb | 8 +- spec/views/layouts/application_spec.rb | 4 +- .../views/members/_location.html.haml_spec.rb | 6 +- spec/views/members/index.html.haml_spec.rb | 2 +- spec/views/members/show.rss.haml_spec.rb | 6 +- .../notifications/index.html.haml_spec.rb | 14 +- .../views/notifications/new.html.haml_spec.rb | 14 +- .../notifications/show.html.haml_spec.rb | 2 +- spec/views/notifier/notify.html.haml_spec.rb | 8 +- spec/views/orders/index.html.haml_spec.rb | 8 +- spec/views/orders/show.html.haml_spec.rb | 24 +-- spec/views/photos/edit.html.haml_spec.rb | 8 +- spec/views/photos/index.html.haml_spec.rb | 4 +- spec/views/photos/new.html.haml_spec.rb | 2 +- spec/views/photos/show.html.haml_spec.rb | 10 +- .../places/_map_attribution.html.haml_spec.rb | 12 +- spec/views/places/show.html.haml_spec.rb | 2 +- spec/views/plant_parts/edit.html.haml_spec.rb | 6 +- .../views/plant_parts/index.html.haml_spec.rb | 2 +- spec/views/plant_parts/new.html.haml_spec.rb | 6 +- spec/views/plant_parts/show.html.haml_spec.rb | 4 +- spec/views/plantings/_form.html.haml_spec.rb | 8 +- spec/views/plantings/edit.html.haml_spec.rb | 24 +-- spec/views/plantings/index.html.haml_spec.rb | 32 ++-- spec/views/plantings/new.html.haml_spec.rb | 28 ++-- spec/views/plantings/show.html.haml_spec.rb | 8 +- spec/views/policy/community_spec.rb | 2 +- spec/views/policy/tos_spec.rb | 2 +- spec/views/posts/_single.html.haml_spec.rb | 22 +-- spec/views/posts/edit.html.haml_spec.rb | 12 +- spec/views/posts/index.html.haml_spec.rb | 16 +- spec/views/posts/index.rss.haml_spec.rb | 6 +- spec/views/posts/new.html.haml_spec.rb | 10 +- spec/views/posts/show.html.haml_spec.rb | 34 ++--- spec/views/posts/show.rss.haml_spec.rb | 4 +- spec/views/products/edit.html.haml_spec.rb | 16 +- spec/views/products/index.html.haml_spec.rb | 6 +- spec/views/products/new.html.haml_spec.rb | 20 +-- spec/views/roles/edit.html.haml_spec.rb | 10 +- spec/views/roles/index.html.haml_spec.rb | 12 +- spec/views/roles/new.html.haml_spec.rb | 10 +- spec/views/roles/show.html.haml_spec.rb | 4 +- .../scientific_names/edit.html.haml_spec.rb | 6 +- .../scientific_names/index.html.haml_spec.rb | 4 +- .../scientific_names/new.html.haml_spec.rb | 6 +- spec/views/seeds/edit.html.haml_spec.rb | 18 +-- spec/views/seeds/new.html.haml_spec.rb | 22 +-- spec/views/seeds/show.html.haml_spec.rb | 8 +- spec/views/shop/index_spec.rb | 8 +- spec/views/support/index_spec.rb | 2 +- 271 files changed, 1719 insertions(+), 1721 deletions(-) diff --git a/app/controllers/admin/orders_controller.rb b/app/controllers/admin/orders_controller.rb index e39ddc48a..c092ba7f2 100644 --- a/app/controllers/admin/orders_controller.rb +++ b/app/controllers/admin/orders_controller.rb @@ -8,7 +8,7 @@ class Admin::OrdersController < ApplicationController def search authorize! :manage, :all - @orders = Order.search({:by => params[:search_by], :for => params[:search_text]}) + @orders = Order.search({by: params[:search_by], for: params[:search_text]}) if @orders.empty? flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}" diff --git a/app/controllers/alternate_names_controller.rb b/app/controllers/alternate_names_controller.rb index f75f8e442..35bd6f289 100644 --- a/app/controllers/alternate_names_controller.rb +++ b/app/controllers/alternate_names_controller.rb @@ -1,5 +1,5 @@ class AlternateNamesController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /alternate_names diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bb1d276a5..0c30ee1e1 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -35,7 +35,7 @@ class ApplicationController < ActionController::Base # CanCan error handling rescue_from CanCan::AccessDenied do |exception| - redirect_to request.referer || root_url, :alert => exception.message + redirect_to request.referer || root_url, alert: exception.message end def set_locale diff --git a/app/controllers/authentications_controller.rb b/app/controllers/authentications_controller.rb index 9a873bebb..7a6ddf724 100644 --- a/app/controllers/authentications_controller.rb +++ b/app/controllers/authentications_controller.rb @@ -20,14 +20,14 @@ class AuthenticationsController < ApplicationController @authentication = current_member.authentications .create_with( - :name => name, - :token => auth['credentials']['token'], - :secret => auth['credentials']['secret'] + name: name, + token: auth['credentials']['token'], + secret: auth['credentials']['secret'] ) .find_or_create_by( - :provider => auth['provider'], - :uid => auth['uid'], - :name => name) + provider: auth['provider'], + uid: auth['uid'], + name: name) flash[:notice] = "Authentication successful." else diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 0caac18ed..1fdc8d70b 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -1,16 +1,16 @@ class CommentsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /comments # GET /comments.json def index - @comments = Comment.paginate(:page => params[:page]) + @comments = Comment.paginate(page: params[:page]) respond_to do |format| format.html # index.html.erb format.json { render json: @comments } - format.rss { render :layout => false } + format.rss { render layout: false } end end @@ -39,7 +39,7 @@ class CommentsController < ApplicationController end else redirect_to request.referer || root_url, - :alert => "Can't post a comment on a non-existent post" + alert: "Can't post a comment on a non-existent post" end end diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index 25cfee941..6182e354c 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -1,9 +1,9 @@ require 'will_paginate/array' class CropsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :hierarchy, :search, :show] + before_filter :authenticate_member!, except: [:index, :hierarchy, :search, :show] load_and_authorize_resource - skip_authorize_resource :only => [:hierarchy, :search] + skip_authorize_resource only: [:hierarchy, :search] # GET /crops # GET /crops.json @@ -11,25 +11,25 @@ class CropsController < ApplicationController @sort = params[:sort] if @sort == 'alpha' # alphabetical order - @crops = Crop.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.approved.paginate(:page => params[:page]) + @crops = Crop.includes(:scientific_names, {plantings: :photos}) + @paginated_crops = @crops.approved.paginate(page: params[:page]) else # default to sorting by popularity - @crops = Crop.popular.includes(:scientific_names, {:plantings => :photos}) - @paginated_crops = @crops.approved.paginate(:page => params[:page]) + @crops = Crop.popular.includes(:scientific_names, {plantings: :photos}) + @paginated_crops = @crops.approved.paginate(page: params[:page]) end respond_to do |format| format.html - format.json { render :json => @crops } + format.json { render json: @crops } format.rss do @crops = Crop.recent.includes(:scientific_names, :creator) - render :rss => @crops + render rss: @crops end format.csv do @filename = "Growstuff-Crops-#{Time.zone.now.to_s(:number)}.csv" @crops = Crop.includes(:scientific_names, :plantings, :seeds, :creator) - render :csv => @crops + render csv: @crops end end end @@ -46,7 +46,7 @@ class CropsController < ApplicationController @crops = Crop.recent end - @crops = @crops.paginate(:page => params[:page]) + @crops = @crops.paginate(page: params[:page]) @crop_wranglers = Role.crop_wranglers respond_to do |format| @@ -66,25 +66,25 @@ class CropsController < ApplicationController def search @term = params[:term] @matches = Crop.search(@term) - @paginated_matches = @matches.paginate(:page => params[:page]) + @paginated_matches = @matches.paginate(page: params[:page]) respond_to do |format| format.html - format.json { render :json => @matches } + format.json { render json: @matches } end end # GET /crops/1 # GET /crops/1.json def show - @crop = Crop.includes(:scientific_names, {:plantings => :photos}).find(params[:id]) - @posts = @crop.posts.paginate(:page => params[:page]) + @crop = Crop.includes(:scientific_names, {plantings: :photos}).find(params[:id]) + @posts = @crop.posts.paginate(page: params[:page]) respond_to do |format| format.html # show.html.haml format.json do - render :json => @crop.to_json(:include => { - :plantings => { :include => { :owner => { :only => [:id, :login_name, :location, :latitude, :longitude] }}} + render json: @crop.to_json(include: { + plantings: { include: { owner: { only: [:id, :login_name, :location, :latitude, :longitude] }}} }) end end @@ -207,6 +207,6 @@ class CropsController < ApplicationController private def crop_params - params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :approval_status, :request_notes, :reason_for_rejection, :rejection_notes, :scientific_names_attributes => [:scientific_name, :_destroy, :id]) + params.require(:crop).permit(:en_wikipedia_url, :name, :parent_id, :creator_id, :approval_status, :request_notes, :reason_for_rejection, :rejection_notes, scientific_names_attributes: [:scientific_name, :_destroy, :id]) end end diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index b5a0b48ab..2e2e5ec48 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -1,12 +1,12 @@ class FollowsController < ApplicationController before_filter :authenticate_member! load_and_authorize_resource - skip_load_resource :only => :create + skip_load_resource only: :create # POST /follows def create - @follow = current_member.follows.build(:followed_id => follow_params[:followed_id]) + @follow = current_member.follows.build(followed_id: follow_params[:followed_id]) if @follow.save flash[:notice] = "Followed #{ @follow.followed.login_name }" diff --git a/app/controllers/gardens_controller.rb b/app/controllers/gardens_controller.rb index f2ce6103a..68bb919c4 100644 --- a/app/controllers/gardens_controller.rb +++ b/app/controllers/gardens_controller.rb @@ -1,15 +1,15 @@ class GardensController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /gardens # GET /gardens.json def index - @gardens = Garden.paginate(:page => params[:page]) + @gardens = Garden.paginate(page: params[:page]) @owner = Member.find_by_slug(params[:owner]) if @owner - @gardens = @owner.gardens.paginate(:page => params[:page]) + @gardens = @owner.gardens.paginate(page: params[:page]) end respond_to do |format| @@ -87,7 +87,7 @@ class GardensController < ApplicationController expire_fragment("homepage_stats") respond_to do |format| - format.html { redirect_to gardens_by_owner_path(:owner => @garden.owner), notice: 'Garden was successfully deleted.' } + format.html { redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.' } format.json { head :no_content } end end diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index 4bc3a5d90..55f652a61 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -1,5 +1,5 @@ class HarvestsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource @@ -17,12 +17,12 @@ class HarvestsController < ApplicationController end respond_to do |format| - format.html { @harvests = @harvests.paginate(:page => params[:page]) } + format.html { @harvests = @harvests.paginate(page: params[:page]) } format.json { render json: @harvests } format.csv do specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil) @filename = "Growstuff-#{specifics}Harvests-#{Time.zone.now.to_s(:number)}.csv" - render :csv => @harvests + render csv: @harvests end end end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 013ae44de..7d8c892bb 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -1,21 +1,21 @@ class MembersController < ApplicationController load_and_authorize_resource - skip_authorize_resource :only => [:nearby, :unsubscribe] + skip_authorize_resource only: [:nearby, :unsubscribe] - after_action :expire_cache_fragments, :only => :create + after_action :expire_cache_fragments, only: :create def index @sort = params[:sort] if @sort == 'recently_joined' - @members = Member.confirmed.recently_joined.paginate(:page => params[:page]) + @members = Member.confirmed.recently_joined.paginate(page: params[:page]) else - @members = Member.confirmed.paginate(:page => params[:page]) + @members = Member.confirmed.paginate(page: params[:page]) end respond_to do |format| format.html # index.html.haml - format.json { render :json => @members.to_json(:only => [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) } + format.json { render json: @members.to_json(only: [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) } end end @@ -31,22 +31,22 @@ class MembersController < ApplicationController respond_to do |format| format.html # show.html.haml - format.json { render :json => @member.to_json(:only => [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) } + format.json { render json: @member.to_json(only: [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) } format.rss { render( - :layout => false, - :locals => { :member => @member } + layout: false, + locals: { member: @member } )} end end def view_follows @member = Member.confirmed.find(params[:login_name]) - @follows = @member.followed.paginate(:page => params[:page]) + @follows = @member.followed.paginate(page: params[:page]) end def view_followers @member = Member.confirmed.find(params[:login_name]) - @followers = @member.followers.paginate(:page => params[:page]) + @followers = @member.followers.paginate(page: params[:page]) end EMAIL_TYPE_STRING = { diff --git a/app/controllers/order_items_controller.rb b/app/controllers/order_items_controller.rb index 37a7e7b74..7781913d4 100644 --- a/app/controllers/order_items_controller.rb +++ b/app/controllers/order_items_controller.rb @@ -8,7 +8,7 @@ class OrderItemsController < ApplicationController params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents end @order_item = OrderItem.new(order_item_params) - @order_item.order = current_member.current_order || Order.create(:member_id => current_member.id) + @order_item.order = current_member.current_order || Order.create(member_id: current_member.id) respond_to do |format| if @order_item.save diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index 3cc4caa9c..82bb337f9 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -34,15 +34,15 @@ class OrdersController < ApplicationController @order = Order.find(params[:id]) respond_to do |format| - if @order.update_attributes(:referral_code => params[:referral_code]) + if @order.update_attributes(referral_code: params[:referral_code]) response = EXPRESS_GATEWAY.setup_purchase( @order.total, - :items => @order.activemerchant_items, - :currency => Growstuff::Application.config.currency, - :no_shipping => true, - :ip => request.remote_ip, - :return_url => complete_order_url, - :cancel_return_url => shop_url + items: @order.activemerchant_items, + currency: Growstuff::Application.config.currency, + no_shipping: true, + ip: request.remote_ip, + return_url: complete_order_url, + cancel_return_url: shop_url ) format.html { redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token) } else @@ -58,10 +58,10 @@ class OrdersController < ApplicationController if (params[:token] && params['PayerID']) purchase = EXPRESS_GATEWAY.purchase( @order.total, - :currency => Growstuff::Application.config.currency, - :ip => request.remote_ip, - :payer_id => params['PayerID'], - :token => params[:token] + currency: Growstuff::Application.config.currency, + ip: request.remote_ip, + payer_id: params['PayerID'], + token: params[:token] ) if purchase.success? @order.completed_at = Time.zone.now diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 9f39aa7ab..8130ef4e1 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -1,11 +1,11 @@ class PhotosController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /photos # GET /photos.json def index - @photos = Photo.paginate(:page => params[:page]) + @photos = Photo.paginate(page: params[:page]) respond_to do |format| format.html # index.html.erb diff --git a/app/controllers/places_controller.rb b/app/controllers/places_controller.rb index 82189cb68..13c0bd05c 100644 --- a/app/controllers/places_controller.rb +++ b/app/controllers/places_controller.rb @@ -5,7 +5,7 @@ class PlacesController < ApplicationController respond_to do |format| format.html # json response is whatever we want to map here - format.json { render :json => Member.located.to_json(:only => [:id, :login_name, :slug, :location, :latitude, :longitude]) } + format.json { render json: Member.located.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) } end end @@ -16,7 +16,7 @@ class PlacesController < ApplicationController @nearby_members = Member.nearest_to(params[:place]) respond_to do |format| format.html # show.html.haml - format.json { render :json => @nearby_members.to_json(:only => [:id, :login_name, :slug, :location, :latitude, :longitude]) } + format.json { render json: @nearby_members.to_json(only: [:id, :login_name, :slug, :location, :latitude, :longitude]) } end end diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index 543981170..276024309 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -1,5 +1,5 @@ class PlantingsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /plantings @@ -8,21 +8,21 @@ class PlantingsController < ApplicationController @owner = Member.find_by_slug(params[:owner]) @crop = Crop.find_by_slug(params[:crop]) if @owner - @plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page]) + @plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page]) elsif @crop - @plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page]) + @plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page]) else - @plantings = Planting.includes(:owner, :crop, :garden).paginate(:page => params[:page]) + @plantings = Planting.includes(:owner, :crop, :garden).paginate(page: params[:page]) end respond_to do |format| - format.html { @plantings = @plantings.paginate(:page => params[:page]) } + format.html { @plantings = @plantings.paginate(page: params[:page]) } format.json { render json: @plantings } - format.rss { render :layout => false } #index.rss.builder + format.rss { render layout: false } #index.rss.builder format.csv do specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil) @filename = "Growstuff-#{specifics}Plantings-#{Time.zone.now.to_s(:number)}.csv" - render :csv => @plantings + render csv: @plantings end end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index ceb4730cc..e30ea1f7f 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -1,5 +1,5 @@ class PostsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /posts @@ -8,29 +8,29 @@ class PostsController < ApplicationController def index @author = Member.find_by_slug(params[:author]) if @author - @posts = @author.posts.includes(:author, { :comments => :author }).paginate(:page => params[:page]) + @posts = @author.posts.includes(:author, { comments: :author }).paginate(page: params[:page]) else - @posts = Post.includes(:author, { :comments => :author }).paginate(:page => params[:page]) + @posts = Post.includes(:author, { comments: :author }).paginate(page: params[:page]) end respond_to do |format| format.html # index.html.haml format.json { render json: @posts } - format.rss { render :layout => false } #index.rss.builder + format.rss { render layout: false } #index.rss.builder end end # GET /posts/1 # GET /posts/1.json def show - @post = Post.includes(:author, { :comments => :author }).find(params[:id]) + @post = Post.includes(:author, { comments: :author }).find(params[:id]) respond_to do |format| format.html # show.html.haml format.json { render json: @post } format.rss { render( - :layout => false, - :locals => { :post => @post } + layout: false, + locals: { post: @post } )} end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index c4883bd4d..d0ab917b0 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -28,7 +28,7 @@ class RegistrationsController < Devise::RegistrationsController if successfully_updated set_flash_message :notice, :updated # Sign in the member bypassing validation in case their password changed - sign_in @member, :bypass => true + sign_in @member, bypass: true redirect_to edit_member_registration_path else render "edit" diff --git a/app/controllers/scientific_names_controller.rb b/app/controllers/scientific_names_controller.rb index 511a96279..cc7723b0b 100644 --- a/app/controllers/scientific_names_controller.rb +++ b/app/controllers/scientific_names_controller.rb @@ -1,5 +1,5 @@ class ScientificNamesController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /scientific_names diff --git a/app/controllers/seeds_controller.rb b/app/controllers/seeds_controller.rb index a2e79afaf..70f3936a1 100644 --- a/app/controllers/seeds_controller.rb +++ b/app/controllers/seeds_controller.rb @@ -1,5 +1,5 @@ class SeedsController < ApplicationController - before_filter :authenticate_member!, :except => [:index, :show] + before_filter :authenticate_member!, except: [:index, :show] load_and_authorize_resource # GET /seeds @@ -8,17 +8,17 @@ class SeedsController < ApplicationController @owner = Member.find_by_slug(params[:owner]) @crop = Crop.find_by_slug(params[:crop]) if @owner - @seeds = @owner.seeds.includes(:owner, :crop).paginate(:page => params[:page]) + @seeds = @owner.seeds.includes(:owner, :crop).paginate(page: params[:page]) elsif @crop - @seeds = @crop.seeds.includes(:owner, :crop).paginate(:page => params[:page]) + @seeds = @crop.seeds.includes(:owner, :crop).paginate(page: params[:page]) else - @seeds = Seed.includes(:owner, :crop).paginate(:page => params[:page]) + @seeds = Seed.includes(:owner, :crop).paginate(page: params[:page]) end respond_to do |format| format.html # index.html.erb format.json { render json: @seeds } - format.rss { render :layout => false } #index.rss.builder + format.rss { render layout: false } #index.rss.builder format.csv do if @owner @filename = "Growstuff-#{@owner}-Seeds-#{Time.zone.now.to_s(:number)}.csv" @@ -27,7 +27,7 @@ class SeedsController < ApplicationController @filename = "Growstuff-Seeds-#{Time.zone.now.to_s(:number)}.csv" @seeds = Seed.includes(:owner, :crop) end - render :csv => @seeds + render csv: @seeds end end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index d8470392d..8c0a0c937 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -21,7 +21,7 @@ module ApplicationHelper link = "http://www.wolframalpha.com/input/?i=#{pid}+#{currency}" return link_to "(convert)", link, - :target => "_blank" + target: "_blank" end # Produces a cache key for uniquely identifying cached fragments. @@ -46,8 +46,8 @@ module ApplicationHelper return member.preferred_avatar_uri if member.preferred_avatar_uri.present? Gravatar.new(member.email).image_url({ - :size => size, - :default => :identicon + size: size, + default: :identicon }) end end diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index 16371b4e9..3055db065 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -18,11 +18,11 @@ module HarvestsHelper def display_human_quantity(harvest) if ! harvest.quantity.blank? && harvest.quantity > 0 if harvest.unit == 'individual' # just the number - number_to_human(harvest.quantity, :strip_insignificant_zeros => true) + number_to_human(harvest.quantity, strip_insignificant_zeros: true) elsif ! harvest.unit.blank? # pluralize anything else - return pluralize(number_to_human(harvest.quantity, :strip_insignificant_zeros => true), harvest.unit) + return pluralize(number_to_human(harvest.quantity, strip_insignificant_zeros: true), harvest.unit) else - return "#{number_to_human(harvest.quantity, :strip_insignificant_zeros => true)} #{harvest.unit}" + return "#{number_to_human(harvest.quantity, strip_insignificant_zeros: true)} #{harvest.unit}" end else return nil @@ -31,7 +31,7 @@ module HarvestsHelper def display_weight(harvest) if ! harvest.weight_quantity.blank? && harvest.weight_quantity > 0 - return "#{number_to_human(harvest.weight_quantity, :strip_insignificant_zeros => true)} #{harvest.weight_unit}" + return "#{number_to_human(harvest.weight_quantity, strip_insignificant_zeros: true)} #{harvest.weight_unit}" else return nil end diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb index cef59c9c8..bb3695851 100644 --- a/app/helpers/notifications_helper.rb +++ b/app/helpers/notifications_helper.rb @@ -2,7 +2,7 @@ module NotificationsHelper def reply_link(notification) if notification.post # comment on the post in question - new_comment_url(:post_id => notification.post.id) + new_comment_url(post_id: notification.post.id) else # by default, reply link sends a PM in return reply_notification_url(notification) diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 5ffb862d6..e7f1a9e8b 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -17,8 +17,8 @@ class Notifier < ActionMailer::Base # Encrypting @signed_message = verifier.generate ({ member_id: @notification.recipient.id, type: :send_notification_email }) - mail(:to => @notification.recipient.email, - :subject => @notification.subject) + mail(to: @notification.recipient.email, + subject: @notification.subject) end def planting_reminder(member) @@ -31,24 +31,24 @@ class Notifier < ActionMailer::Base @signed_message = verifier.generate ({ member_id: @member.id, type: :send_planting_reminder }) if @member.send_planting_reminder - mail(:to => @member.email, - :subject => "What have you planted lately?") + mail(to: @member.email, + subject: "What have you planted lately?") end end def new_crop_request(member, request) @member, @request = member, request - mail(:to => @member.email, :subject => "#{@request.requester.login_name} has requested #{@request.name} as a new crop") + mail(to: @member.email, subject: "#{@request.requester.login_name} has requested #{@request.name} as a new crop") end def crop_request_approved(member, crop) @member, @crop = member, crop - mail(:to => @member.email, :subject => "#{crop.name.capitalize} has been approved") + mail(to: @member.email, subject: "#{crop.name.capitalize} has been approved") end def crop_request_rejected(member, crop) @member, @crop = member, crop - mail(:to => @member.email, :subject => "#{crop.name.capitalize} has been rejected") + mail(to: @member.email, subject: "#{crop.name.capitalize} has been rejected") end end diff --git a/app/models/ability.rb b/app/models/ability.rb index 6ec3aea25..96b4ea69e 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -24,7 +24,7 @@ class Ability # nobody should be able to view unapproved crops unless they # are wranglers or admins cannot :read, Crop - can :read, Crop, :approval_status => "approved" + can :read, Crop, approval_status: "approved" # scientific names should only be viewable if associated crop is approved cannot :read, ScientificName can :read, ScientificName do |sn| @@ -38,15 +38,15 @@ class Ability if member # members can see even rejected or pending crops if they requested it - can :read, Crop, :requester_id => member.id + can :read, Crop, requester_id: member.id # managing your own user settings - can :update, Member, :id => member.id + can :update, Member, id: member.id # can read/delete notifications that were sent to them - can :read, Notification, :recipient_id => member.id - can :destroy, Notification, :recipient_id => member.id - can :reply, Notification, :recipient_id => member.id + can :read, Notification, recipient_id: member.id + can :destroy, Notification, recipient_id: member.id + can :reply, Notification, recipient_id: member.id # can send a private message to anyone but themselves # note: sadly, we can't test for this from the view, but it works # for the model/controller @@ -68,58 +68,58 @@ class Ability # can create & destroy their own authentications against other sites. can :create, Authentication - can :destroy, Authentication, :member_id => member.id + can :destroy, Authentication, member_id: member.id # anyone can create a post, or comment on a post, # but only the author can edit/destroy it. can :create, Post - can :update, Post, :author_id => member.id - can :destroy, Post, :author_id => member.id + can :update, Post, author_id: member.id + can :destroy, Post, author_id: member.id can :create, Comment - can :update, Comment, :author_id => member.id - can :destroy, Comment, :author_id => member.id + can :update, Comment, author_id: member.id + can :destroy, Comment, author_id: member.id # same deal for gardens and plantings can :create, Garden - can :update, Garden, :owner_id => member.id - can :destroy, Garden, :owner_id => member.id + can :update, Garden, owner_id: member.id + can :destroy, Garden, owner_id: member.id can :create, Planting - can :update, Planting, :garden => { :owner_id => member.id } - can :destroy, Planting, :garden => { :owner_id => member.id } + can :update, Planting, garden: { owner_id: member.id } + can :destroy, Planting, garden: { owner_id: member.id } can :create, Harvest - can :update, Harvest, :owner_id => member.id - can :destroy, Harvest, :owner_id => member.id + can :update, Harvest, owner_id: member.id + can :destroy, Harvest, owner_id: member.id can :create, Photo - can :update, Photo, :owner_id => member.id - can :destroy, Photo, :owner_id => member.id + can :update, Photo, owner_id: member.id + can :destroy, Photo, owner_id: member.id can :create, Seed - can :update, Seed, :owner_id => member.id - can :destroy, Seed, :owner_id => member.id + can :update, Seed, owner_id: member.id + can :destroy, Seed, owner_id: member.id # orders/shop/etc can :create, Order - can :read, Order, :member_id => member.id - can :complete, Order, :member_id => member.id, :completed_at => nil - can :checkout, Order, :member_id => member.id, :completed_at => nil - can :cancel, Order, :member_id => member.id, :completed_at => nil - can :destroy, Order, :member_id => member.id, :completed_at => nil + can :read, Order, member_id: member.id + can :complete, Order, member_id: member.id, completed_at: nil + can :checkout, Order, member_id: member.id, completed_at: nil + can :cancel, Order, member_id: member.id, completed_at: nil + can :destroy, Order, member_id: member.id, completed_at: nil can :create, OrderItem # for now, let's not let people mess with individual order items - cannot :read, OrderItem, :order => { :member_id => member.id } - cannot :update, OrderItem, :order => { :member_id => member.id, :completed_at => nil } - cannot :destroy, OrderItem, :order => { :member_id => member.id, :completed_at => nil } + cannot :read, OrderItem, order: { member_id: member.id } + cannot :update, OrderItem, order: { member_id: member.id, completed_at: nil } + cannot :destroy, OrderItem, order: { member_id: member.id, completed_at: nil } # following/unfollowing permissions can :create, Follow - cannot :create, Follow, :followed_id => member.id # can't follow yourself + cannot :create, Follow, followed_id: member.id # can't follow yourself can :destroy, Follow - cannot :destroy, Follow, :followed_id => member.id # can't unfollow yourself + cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself if member.has_role? :admin diff --git a/app/models/account.rb b/app/models/account.rb index 547fc57bf..bfbf60e5d 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -2,8 +2,8 @@ class Account < ActiveRecord::Base belongs_to :member belongs_to :account_type - validates :member_id, :uniqueness => { - :message => 'already has account details associated with it' + validates :member_id, uniqueness: { + message: 'already has account details associated with it' } before_create do |account| diff --git a/app/models/alternate_name.rb b/app/models/alternate_name.rb index 857adf7ec..30923bfac 100644 --- a/app/models/alternate_name.rb +++ b/app/models/alternate_name.rb @@ -1,5 +1,5 @@ class AlternateName < ActiveRecord::Base after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" } belongs_to :crop - belongs_to :creator, :class_name => 'Member' + belongs_to :creator, class_name: 'Member' end diff --git a/app/models/comment.rb b/app/models/comment.rb index f7da18842..e649eb2b4 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,5 +1,5 @@ class Comment < ActiveRecord::Base - belongs_to :author, :class_name => 'Member' + belongs_to :author, class_name: 'Member' belongs_to :post default_scope { order("created_at DESC") } @@ -11,11 +11,11 @@ class Comment < ActiveRecord::Base # don't send notifications to yourself if recipient != sender Notification.create( - :recipient_id => recipient, - :sender_id => sender, - :subject => "#{self.author} commented on #{self.post.subject}", - :body => self.body, - :post_id => self.post.id + recipient_id: recipient, + sender_id: sender, + subject: "#{self.author} commented on #{self.post.subject}", + body: self.body, + post_id: self.post.id ) end end diff --git a/app/models/crop.rb b/app/models/crop.rb index fe593fe37..ec7dc7d0d 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -4,42 +4,42 @@ class Crop < ActiveRecord::Base has_many :scientific_names, after_add: :update_index, after_remove: :update_index accepts_nested_attributes_for :scientific_names, - :allow_destroy => true, - :reject_if => :all_blank + allow_destroy: true, + reject_if: :all_blank has_many :alternate_names, after_add: :update_index, after_remove: :update_index, dependent: :destroy has_many :plantings - has_many :photos, :through => :plantings + has_many :photos, through: :plantings has_many :seeds has_many :harvests - has_many :plant_parts, -> { uniq }, :through => :harvests - belongs_to :creator, :class_name => 'Member' - belongs_to :requester, :class_name => 'Member' + has_many :plant_parts, -> { uniq }, through: :harvests + belongs_to :creator, class_name: 'Member' + belongs_to :requester, class_name: 'Member' - belongs_to :parent, :class_name => 'Crop' - has_many :varieties, :class_name => 'Crop', :foreign_key => 'parent_id' + belongs_to :parent, class_name: 'Crop' + has_many :varieties, class_name: 'Crop', foreign_key: 'parent_id' has_and_belongs_to_many :posts before_destroy {|crop| crop.posts.clear} default_scope { order("lower(name) asc") } - scope :recent, -> { where(:approval_status => "approved").reorder("created_at desc") } - scope :toplevel, -> { where(:approval_status => "approved", :parent_id => nil) } - scope :popular, -> { where(:approval_status => "approved").reorder("plantings_count desc, lower(name) asc") } - scope :randomized, -> { where(:approval_status => "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql - scope :pending_approval, -> { where(:approval_status => "pending") } - scope :approved, -> { where(:approval_status => "approved") } - scope :rejected, -> { where(:approval_status => "rejected") } + scope :recent, -> { where(approval_status: "approved").reorder("created_at desc") } + scope :toplevel, -> { where(approval_status: "approved", parent_id: nil) } + scope :popular, -> { where(approval_status: "approved").reorder("plantings_count desc, lower(name) asc") } + scope :randomized, -> { where(approval_status: "approved").reorder('random()') } # ok on sqlite and psql, but not on mysql + scope :pending_approval, -> { where(approval_status: "pending") } + scope :approved, -> { where(approval_status: "approved") } + scope :rejected, -> { where(approval_status: "rejected") } ## Wikipedia urls are only necessary when approving a crop validates :en_wikipedia_url, - :format => { - :with => /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/, - :message => 'is not a valid English Wikipedia URL' + format: { + with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/, + message: 'is not a valid English Wikipedia URL' }, - :if => :approved? + if: :approved? ## Reasons are only necessary when rejecting - validates :reason_for_rejection, :presence => true, :if => :rejected? + validates :reason_for_rejection, presence: true, if: :rejected? ## This validation addresses a race condition validate :approval_status_cannot_be_changed_again @@ -231,14 +231,14 @@ class Crop < ActiveRecord::Base crop = Crop.find_or_create_by(name: name) crop.update_attributes( - :en_wikipedia_url => en_wikipedia_url, - :creator_id => cropbot.id + en_wikipedia_url: en_wikipedia_url, + creator_id: cropbot.id ) if parent parent = Crop.find_by_name(parent) if parent - crop.update_attributes(:parent_id => parent.id) + crop.update_attributes(parent_id: parent.id) else logger.warn("Warning: parent crop #{parent} not found") end @@ -264,13 +264,13 @@ class Crop < ActiveRecord::Base raise "cropbot account not found: run rake db:seed" unless cropbot names_to_add.each do |n| - if self.scientific_names.exists?(:scientific_name => n) + if self.scientific_names.exists?(scientific_name: n) logger.warn("Warning: skipping duplicate scientific name #{n} for #{self}") else self.scientific_names.create( - :scientific_name => n, - :creator_id => cropbot.id + scientific_name: n, + creator_id: cropbot.id ) end end @@ -286,12 +286,12 @@ class Crop < ActiveRecord::Base names_to_add = alternate_names.split(%r{,\s*}) names_to_add.each do |n| - if self.alternate_names.exists?(:name => n) + if self.alternate_names.exists?(name: n) logger.warn("Warning: skipping duplicate alternate name #{n} for #{self}") else self.alternate_names.create( - :name => n, - :creator_id => cropbot.id + name: n, + creator_id: cropbot.id ) end end diff --git a/app/models/follow.rb b/app/models/follow.rb index d7028c8ed..997352ebf 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,14 +1,14 @@ class Follow < ActiveRecord::Base belongs_to :follower, class_name: "Member" belongs_to :followed, class_name: "Member" - validates :follower_id, uniqueness: { :scope => :followed_id } + validates :follower_id, uniqueness: { scope: :followed_id } after_create do Notification.create( - :recipient_id => self.followed_id, - :sender_id => self.follower_id, - :subject => "#{self.follower.login_name} is now following you", - :body => "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. " + recipient_id: self.followed_id, + sender_id: self.follower_id, + subject: "#{self.follower.login_name} is now following you", + body: "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. " ) end diff --git a/app/models/forum.rb b/app/models/forum.rb index fd4a79509..0e2e2615d 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -3,7 +3,7 @@ class Forum < ActiveRecord::Base friendly_id :name, use: [:slugged, :finders] has_many :posts - belongs_to :owner, :class_name => "Member" + belongs_to :owner, class_name: "Member" def to_s return name diff --git a/app/models/garden.rb b/app/models/garden.rb index 15bbaa9de..448d7d60e 100644 --- a/app/models/garden.rb +++ b/app/models/garden.rb @@ -3,9 +3,9 @@ class Garden < ActiveRecord::Base extend FriendlyId friendly_id :garden_slug, use: [:slugged, :finders] - belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id' - has_many :plantings, -> { order(created_at: :desc) }, :dependent => :destroy - has_many :crops, :through => :plantings + belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id' + has_many :plantings, -> { order(created_at: :desc) }, dependent: :destroy + has_many :crops, through: :plantings has_and_belongs_to_many :photos @@ -25,23 +25,23 @@ class Garden < ActiveRecord::Base after_save :mark_inactive_garden_plantings_as_finished default_scope { order("lower(name) asc") } - scope :active, -> { where(:active => true) } - scope :inactive, -> { where(:active => false) } + scope :active, -> { where(active: true) } + scope :inactive, -> { where(active: false) } validates :location, - :length => { :maximum => 255 } + length: { maximum: 255 } validates :name, - :format => { - :with => /\S/ + format: { + with: /\S/ }, - :length => { :maximum => 255 } + length: { maximum: 255 } validates :area, - :numericality => { - :only_integer => false, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: false, + greater_than_or_equal_to: 0 }, + allow_nil: true AREA_UNITS_VALUES = { "square metres" => "square metre", @@ -49,10 +49,10 @@ class Garden < ActiveRecord::Base "hectares" => "hectare", "acres" => "acre" } - validates :area_unit, :inclusion => { :in => AREA_UNITS_VALUES.values, - :message => "%{value} is not a valid area unit" }, - :allow_nil => true, - :allow_blank => true + validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values, + message: "%{value} is not a valid area unit" }, + allow_nil: true, + allow_blank: true after_validation :cleanup_area diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 7bbd2b6ee..e648bec39 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -4,7 +4,7 @@ class Harvest < ActiveRecord::Base friendly_id :harvest_slug, use: [:slugged, :finders] belongs_to :crop - belongs_to :owner, :class_name => 'Member' + belongs_to :owner, class_name: 'Member' belongs_to :plant_part has_and_belongs_to_many :photos @@ -20,17 +20,17 @@ class Harvest < ActiveRecord::Base default_scope { order('created_at DESC') } - validates :crop, :approved => true + validates :crop, approved: true - validates :crop, :presence => {:message => "must be present and exist in our database"} + validates :crop, presence: {message: "must be present and exist in our database"} - validates :plant_part, :presence => {:message => "must be present and exist in our database"} + validates :plant_part, presence: {message: "must be present and exist in our database"} validates :quantity, - :numericality => { - :only_integer => false, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: false, + greater_than_or_equal_to: 0 }, + allow_nil: true UNITS_VALUES = { "individual" => "individual", @@ -44,24 +44,24 @@ class Harvest < ActiveRecord::Base "baskets" => "basket", "bushels" => "bushel" } - validates :unit, :inclusion => { :in => UNITS_VALUES.values, - :message => "%{value} is not a valid unit" }, - :allow_nil => true, - :allow_blank => true + validates :unit, inclusion: { in: UNITS_VALUES.values, + message: "%{value} is not a valid unit" }, + allow_nil: true, + allow_blank: true validates :weight_quantity, - :numericality => { :only_integer => false }, - :allow_nil => true + numericality: { only_integer: false }, + allow_nil: true WEIGHT_UNITS_VALUES = { "kg" => "kg", "lb" => "lb", "oz" => "oz" } - validates :weight_unit, :inclusion => { :in => WEIGHT_UNITS_VALUES.values, - :message => "%{value} is not a valid unit" }, - :allow_nil => true, - :allow_blank => true + validates :weight_unit, inclusion: { in: WEIGHT_UNITS_VALUES.values, + message: "%{value} is not a valid unit" }, + allow_nil: true, + allow_blank: true after_validation :cleanup_quantities @@ -104,7 +104,7 @@ class Harvest < ActiveRecord::Base # 2 buckets of apricots, weighing 10kg string = '' if self.quantity - string += "#{number_to_human(self.quantity.to_s, :strip_insignificant_zeros => true)} " + string += "#{number_to_human(self.quantity.to_s, strip_insignificant_zeros: true)} " if self.unit == 'individual' string += 'individual ' else @@ -125,7 +125,7 @@ class Harvest < ActiveRecord::Base end if self.weight_quantity - string += " weighing #{number_to_human(self.weight_quantity, :strip_insignificant_zeros => true)} #{self.weight_unit}" + string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)} #{self.weight_unit}" end return string diff --git a/app/models/member.rb b/app/models/member.rb index a8af799b1..28a0d6f10 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -4,26 +4,26 @@ class Member < ActiveRecord::Base friendly_id :login_name, use: [:slugged, :finders] - has_many :posts, :foreign_key => 'author_id' - has_many :comments, :foreign_key => 'author_id' - has_many :forums, :foreign_key => 'owner_id' + has_many :posts, foreign_key: 'author_id' + has_many :comments, foreign_key: 'author_id' + has_many :forums, foreign_key: 'owner_id' - has_many :gardens, :foreign_key => 'owner_id' - has_many :plantings, :foreign_key => 'owner_id' + has_many :gardens, foreign_key: 'owner_id' + has_many :plantings, foreign_key: 'owner_id' - has_many :seeds, :foreign_key => 'owner_id' - has_many :harvests, :foreign_key => 'owner_id' + has_many :seeds, foreign_key: 'owner_id' + has_many :harvests, foreign_key: 'owner_id' has_and_belongs_to_many :roles - has_many :notifications, :foreign_key => 'recipient_id' - has_many :sent_notifications, :foreign_key => 'sender_id' + has_many :notifications, foreign_key: 'recipient_id' + has_many :sent_notifications, foreign_key: 'sender_id' has_many :authentications has_many :orders has_one :account - has_one :account_type, :through => :account + has_one :account_type, through: :account has_many :photos @@ -33,13 +33,13 @@ class Member < ActiveRecord::Base scope :located, -> { where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") } scope :recently_signed_in, -> { reorder('updated_at DESC') } scope :recently_joined, -> { reorder("confirmed_at desc") } - scope :wants_newsletter, -> { where(:newsletter => true) } + scope :wants_newsletter, -> { where(newsletter: true) } - has_many :follows, :class_name => "Follow", :foreign_key => "follower_id" - has_many :followed, :through => :follows + has_many :follows, class_name: "Follow", foreign_key: "follower_id" + has_many :followed, through: :follows - has_many :inverse_follows, :class_name => "Follow", :foreign_key => "followed_id" - has_many :followers, :through => :inverse_follows, :source => :follower + has_many :inverse_follows, class_name: "Follow", foreign_key: "followed_id" + has_many :followers, through: :inverse_follows, source: :follower # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, @@ -58,34 +58,34 @@ class Member < ActiveRecord::Base attr_accessor :login # Requires acceptance of the Terms of Service - validates_acceptance_of :tos_agreement, :allow_nil => false, - :accept => true + validates_acceptance_of :tos_agreement, allow_nil: false, + accept: true validates :login_name, - :length => { - :minimum => 2, - :maximum => 25, - :message => "should be between 2 and 25 characters long" + length: { + minimum: 2, + maximum: 25, + message: "should be between 2 and 25 characters long" }, - :exclusion => { - :in => %w(growstuff admin moderator staff nearby), - :message => "name is reserved" + exclusion: { + in: %w(growstuff admin moderator staff nearby), + message: "name is reserved" }, - :format => { - :with => /\A\w+\z/, - :message => "may only include letters, numbers, or underscores" + format: { + with: /\A\w+\z/, + message: "may only include letters, numbers, or underscores" }, - :uniqueness => { - :case_sensitive => false + uniqueness: { + case_sensitive: false } # Give each new member a default garden - after_create {|member| Garden.create(:name => "Garden", :owner_id => member.id) } + after_create {|member| Garden.create(name: "Garden", owner_id: member.id) } # and an account record (for paid accounts etc) # we use find_or_create to avoid accidentally creating a second one, # which can happen sometimes especially with FactoryGirl associations - after_create {|member| Account.find_or_create_by(:member_id => member.id) } + after_create {|member| Account.find_or_create_by(member_id: member.id) } after_save :update_newsletter_subscription @@ -93,7 +93,7 @@ class Member < ActiveRecord::Base def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if login = conditions.delete(:login) - where(conditions).where(["lower(login_name) = :value OR lower(email) = :value", { :value => login.downcase }]).first + where(conditions).where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }]).first else where(conditions).first end @@ -108,7 +108,7 @@ class Member < ActiveRecord::Base end def current_order - orders.where(:completed_at => nil).first + orders.where(completed_at: nil).first end # when purchasing a product that gives you a paid account, this method @@ -163,15 +163,15 @@ class Member < ActiveRecord::Base result = false if set result = flickr.photosets.getPhotos( - :photoset_id => set, - :page => page_num, - :per_page => 30 + photoset_id: set, + page: page_num, + per_page: 30 ) else result = flickr.people.getPhotos( - :user_id => 'me', - :page => page_num, - :per_page => 30 + user_id: 'me', + page: page_num, + per_page: 30 ) end if result @@ -239,10 +239,10 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.subscribe({ - :id => Gibbon::API.api_key, - :email => { :email => email }, - :merge_vars => { :login_name => login_name }, - :double_optin => false # they already confirmed their email with us + id: Gibbon::API.api_key, + email: { email: email }, + merge_vars: { login_name: login_name }, + double_optin: false # they already confirmed their email with us }) end @@ -250,17 +250,17 @@ class Member < ActiveRecord::Base return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.unsubscribe({ - :id => ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'], - :email => { :email => email } + id: ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'], + email: { email: email } }) end def already_following?(member) - self.follows.exists?(:followed_id => member.id) + self.follows.exists?(followed_id: member.id) end def get_follow(member) - self.follows.where(:followed_id => member.id).first if already_following?(member) + self.follows.where(followed_id: member.id).first if already_following?(member) end end diff --git a/app/models/notification.rb b/app/models/notification.rb index 01f157df9..0668167f4 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,12 +1,12 @@ class Notification < ActiveRecord::Base - belongs_to :sender, :class_name => 'Member' - belongs_to :recipient, :class_name => 'Member' + belongs_to :sender, class_name: 'Member' + belongs_to :recipient, class_name: 'Member' belongs_to :post - validates :subject, :length => { :maximum => 255 } + validates :subject, length: { maximum: 255 } default_scope { order('created_at DESC') } - scope :unread, -> { where(:read => false) } + scope :unread, -> { where(read: false) } before_create :replace_blank_subject after_create :send_email diff --git a/app/models/order.rb b/app/models/order.rb index e9f97034f..f3a4eaafb 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -1,13 +1,13 @@ class Order < ActiveRecord::Base belongs_to :member - has_many :order_items, :dependent => :destroy + has_many :order_items, dependent: :destroy default_scope { order('created_at DESC') } - validates :referral_code, :format => { - :with => /\A[a-zA-Z0-9 ]*\z/, - :message => "may only include letters and numbers" + validates :referral_code, format: { + with: /\A[a-zA-Z0-9 ]*\z/, + message: "may only include letters and numbers" } before_save :standardize_referral_code @@ -27,9 +27,9 @@ class Order < ActiveRecord::Base items = [] order_items.each do |i| items.push({ - :name => i.product.name, - :quantity => i.quantity, - :amount => i.price + name: i.product.name, + quantity: i.quantity, + amount: i.price }) end return items @@ -87,7 +87,7 @@ class Order < ActiveRecord::Base end when "referral_code" # coerce to uppercase - return Order.where(:referral_code => args[:for].upcase) + return Order.where(referral_code: args[:for].upcase) end end return [] diff --git a/app/models/order_item.rb b/app/models/order_item.rb index 159876dd5..da26f3a42 100644 --- a/app/models/order_item.rb +++ b/app/models/order_item.rb @@ -4,7 +4,7 @@ class OrderItem < ActiveRecord::Base validate :price_must_be_greater_than_minimum - validates_uniqueness_of :order_id, :message => "may only have one item." + validates_uniqueness_of :order_id, message: "may only have one item." def price_must_be_greater_than_minimum @product = Product.find(product_id) diff --git a/app/models/photo.rb b/app/models/photo.rb index 54cc94de3..1abef6047 100644 --- a/app/models/photo.rb +++ b/app/models/photo.rb @@ -1,5 +1,5 @@ class Photo < ActiveRecord::Base - belongs_to :owner, :class_name => 'Member' + belongs_to :owner, class_name: 'Member' has_and_belongs_to_many :plantings has_and_belongs_to_many :harvests @@ -23,16 +23,16 @@ class Photo < ActiveRecord::Base # for easier stubbing and testing. def flickr_metadata flickr = owner.flickr - info = flickr.photos.getInfo(:photo_id => flickr_photo_id) + info = flickr.photos.getInfo(photo_id: flickr_photo_id) licenses = flickr.photos.licenses.getInfo() license = licenses.find { |l| l.id == info.license } return { - :title => info.title || "Untitled", - :license_name => license.name, - :license_url => license.url, - :thumbnail_url => FlickRaw.url_q(info), - :fullsize_url => FlickRaw.url_z(info), - :link_url => FlickRaw.url_photopage(info) + title: info.title || "Untitled", + license_name: license.name, + license_url: license.url, + thumbnail_url: FlickRaw.url_q(info), + fullsize_url: FlickRaw.url_z(info), + link_url: FlickRaw.url_photopage(info) } end diff --git a/app/models/plant_part.rb b/app/models/plant_part.rb index 33d2292fa..652bc894b 100644 --- a/app/models/plant_part.rb +++ b/app/models/plant_part.rb @@ -1,9 +1,9 @@ class PlantPart < ActiveRecord::Base extend FriendlyId - friendly_id :name, :use => [:slugged, :finders] + friendly_id :name, use: [:slugged, :finders] has_many :harvests - has_many :crops, -> { uniq }, :through => :harvests + has_many :crops, -> { uniq }, through: :harvests def to_s return name diff --git a/app/models/planting.rb b/app/models/planting.rb index 7ccfe5572..02028f909 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -3,8 +3,8 @@ class Planting < ActiveRecord::Base friendly_id :planting_slug, use: [:slugged, :finders] belongs_to :garden - belongs_to :owner, :class_name => 'Member', :counter_cache => true - belongs_to :crop, :counter_cache => true + belongs_to :owner, class_name: 'Member', counter_cache: true + belongs_to :crop, counter_cache: true has_and_belongs_to_many :photos @@ -18,33 +18,33 @@ class Planting < ActiveRecord::Base end default_scope { order("created_at desc") } - scope :finished, -> { where(:finished => true) } - scope :current, -> { where(:finished => false) } + scope :finished, -> { where(finished: true) } + scope :current, -> { where(finished: false) } delegate :name, :en_wikipedia_url, :default_scientific_name, :plantings_count, - :to => :crop, - :prefix => true + to: :crop, + prefix: true default_scope { order("created_at desc") } - validates :crop, :approved => true + validates :crop, approved: true - validates :crop, :presence => {:message => "must be present and exist in our database"} + validates :crop, presence: {message: "must be present and exist in our database"} validates :quantity, - :numericality => { - :only_integer => true, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: true, + greater_than_or_equal_to: 0 }, + allow_nil: true SUNNINESS_VALUES = %w(sun semi-shade shade) - validates :sunniness, :inclusion => { :in => SUNNINESS_VALUES, - :message => "%{value} is not a valid sunniness value" }, - :allow_nil => true, - :allow_blank => true + validates :sunniness, inclusion: { in: SUNNINESS_VALUES, + message: "%{value} is not a valid sunniness value" }, + allow_nil: true, + allow_blank: true PLANTED_FROM_VALUES = [ 'seed', @@ -59,10 +59,10 @@ class Planting < ActiveRecord::Base 'graft', 'layering' ] - validates :planted_from, :inclusion => { :in => PLANTED_FROM_VALUES, - :message => "%{value} is not a valid planting method" }, - :allow_nil => true, - :allow_blank => true + validates :planted_from, inclusion: { in: PLANTED_FROM_VALUES, + message: "%{value} is not a valid planting method" }, + allow_nil: true, + allow_blank: true validate :finished_must_be_after_planted @@ -95,7 +95,7 @@ class Planting < ActiveRecord::Base end def calculate_days_before_maturity(planting, crop) - p_crop = Planting.where(:crop_id => crop).where.not(:id => planting) + p_crop = Planting.where(crop_id: crop).where.not(id: planting) differences = p_crop.collect do |p| if p.finished and !p.finished_at.nil? (p.finished_at - p.planted_at).to_i diff --git a/app/models/post.rb b/app/models/post.rb index 6aaf8b72d..a6852bbb4 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,9 +1,9 @@ class Post < ActiveRecord::Base extend FriendlyId friendly_id :author_date_subject, use: [:slugged, :finders] - belongs_to :author, :class_name => 'Member' + belongs_to :author, class_name: 'Member' belongs_to :forum - has_many :comments, :dependent => :destroy + has_many :comments, dependent: :destroy has_and_belongs_to_many :crops before_destroy {|post| post.crops.clear} after_save :update_crops_posts_association @@ -27,10 +27,10 @@ class Post < ActiveRecord::Base recipients.map{ |r| r.id }.each do |recipient| if recipient != sender Notification.create( - :recipient_id => recipient, - :sender_id => sender, - :subject => "#{self.author} mentioned you in their post #{self.subject}", - :body => self.body, + recipient_id: recipient, + sender_id: sender, + subject: "#{self.author} mentioned you in their post #{self.subject}", + body: self.body, ) end end @@ -39,10 +39,10 @@ class Post < ActiveRecord::Base default_scope { order("created_at desc") } validates :subject, - :format => { - :with => /\S/ + format: { + with: /\S/ }, - :length => { :maximum => 255 } + length: { maximum: 255 } def author_date_subject diff --git a/app/models/product.rb b/app/models/product.rb index 68d483665..942e2603b 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -3,10 +3,10 @@ class Product < ActiveRecord::Base belongs_to :account_type validates :paid_months, - :numericality => { - :only_integer => true, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: true, + greater_than_or_equal_to: 0 }, + allow_nil: true def to_s name diff --git a/app/models/scientific_name.rb b/app/models/scientific_name.rb index aec8f1091..2df6aa5e7 100644 --- a/app/models/scientific_name.rb +++ b/app/models/scientific_name.rb @@ -1,5 +1,5 @@ class ScientificName < ActiveRecord::Base after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop && ENV['GROWSTUFF_ELASTICSEARCH'] == "true" } belongs_to :crop - belongs_to :creator, :class_name => 'Member' + belongs_to :creator, class_name: 'Member' end diff --git a/app/models/seed.rb b/app/models/seed.rb index c72187fc7..b05528680 100644 --- a/app/models/seed.rb +++ b/app/models/seed.rb @@ -3,62 +3,62 @@ class Seed < ActiveRecord::Base friendly_id :seed_slug, use: [:slugged, :finders] belongs_to :crop - belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id' + belongs_to :owner, class_name: 'Member', foreign_key: 'owner_id' default_scope { order("created_at desc") } - validates :crop, :approved => true + validates :crop, approved: true - validates :crop, :presence => {:message => "must be present and exist in our database"} + validates :crop, presence: {message: "must be present and exist in our database"} validates :quantity, - :numericality => { - :only_integer => true, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: true, + greater_than_or_equal_to: 0 }, + allow_nil: true validates :days_until_maturity_min, - :numericality => { - :only_integer => true, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: true, + greater_than_or_equal_to: 0 }, + allow_nil: true validates :days_until_maturity_max, - :numericality => { - :only_integer => true, - :greater_than_or_equal_to => 0 }, - :allow_nil => true + numericality: { + only_integer: true, + greater_than_or_equal_to: 0 }, + allow_nil: true scope :tradable, -> { where("tradable_to != 'nowhere'") } TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally) - validates :tradable_to, :inclusion => { :in => TRADABLE_TO_VALUES, - :message => "You may only trade seed nowhere, locally, nationally, or internationally" }, - :allow_nil => false, - :allow_blank => false + validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES, + message: "You may only trade seed nowhere, locally, nationally, or internationally" }, + allow_nil: false, + allow_blank: false ORGANIC_VALUES = [ 'certified organic', 'non-certified organic', 'conventional/non-organic', 'unknown'] - validates :organic, :inclusion => { :in => ORGANIC_VALUES, - :message => "You must say whether the seeds are organic or not, or that you don't know" }, - :allow_nil => false, - :allow_blank => false + validates :organic, inclusion: { in: ORGANIC_VALUES, + message: "You must say whether the seeds are organic or not, or that you don't know" }, + allow_nil: false, + allow_blank: false GMO_VALUES = [ 'certified GMO-free', 'non-certified GMO-free', 'GMO', 'unknown'] - validates :gmo, :inclusion => { :in => GMO_VALUES, - :message => "You must say whether the seeds are genetically modified or not, or that you don't know" }, - :allow_nil => false, - :allow_blank => false + validates :gmo, inclusion: { in: GMO_VALUES, + message: "You must say whether the seeds are genetically modified or not, or that you don't know" }, + allow_nil: false, + allow_blank: false HEIRLOOM_VALUES = %w(heirloom hybrid unknown) - validates :heirloom, :inclusion => { :in => HEIRLOOM_VALUES, - :message => "You must say whether the seeds are heirloom, hybrid, or unknown" }, - :allow_nil => false, - :allow_blank => false + validates :heirloom, inclusion: { in: HEIRLOOM_VALUES, + message: "You must say whether the seeds are heirloom, hybrid, or unknown" }, + allow_nil: false, + allow_blank: false def tradable? if self.tradable_to == 'nowhere' diff --git a/config/application.rb b/config/application.rb index 113d0bc66..facb29787 100644 --- a/config/application.rb +++ b/config/application.rb @@ -5,7 +5,7 @@ require 'openssl' if defined?(Bundler) # If you precompile assets before deploying to production, use this line - Bundler.require(*Rails.groups(:assets => %w(development test))) + Bundler.require(*Rails.groups(assets: %w(development test))) # If you want your assets lazily compiled in production, use this line # Bundler.require(:default, :assets, Rails.env) end @@ -84,9 +84,9 @@ module Growstuff config.action_mailer.delivery_method = :sendmail config.action_mailer.sendmail_settings = { - :location => '/usr/sbin/sendmail', - :arguments => '-i -t', - :openssl_verify_mode => 'none' + location: '/usr/sbin/sendmail', + arguments: '-i -t', + openssl_verify_mode: 'none' } # Growstuff-specific configuration variables diff --git a/config/database.yml b/config/database.yml index 6aeb5d961..eb75b3791 100644 --- a/config/database.yml +++ b/config/database.yml @@ -3,13 +3,14 @@ development: database: growstuff_dev host: localhost user: postgres - password: password + password: postgres test: adapter: postgresql database: growstuff_test host: localhost user: postgres + password: postgres production: adapter: postgresql diff --git a/config/environments/development.rb b/config/environments/development.rb index 282071cda..700771c10 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -44,15 +44,15 @@ Growstuff::Application.configure do # config.action_view.raise_on_missing_translations = true # Growstuff config - config.action_mailer.default_url_options = { :host => 'localhost:8080' } + config.action_mailer.default_url_options = { host: 'localhost:8080' } config.action_mailer.delivery_method = :letter_opener config.action_mailer.smtp_settings = { - :port => '587', - :address => 'smtp.mandrillapp.com', - :user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'], - :password => ENV['GROWSTUFF_MANDRILL_APIKEY'], - :authentication => :login + port: '587', + address: 'smtp.mandrillapp.com', + user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'], + password: ENV['GROWSTUFF_MANDRILL_APIKEY'], + authentication: :login } config.host = 'localhost:8080' @@ -65,9 +65,9 @@ Growstuff::Application.configure do config.after_initialize do ActiveMerchant::Billing::Base.mode = :test paypal_options = { - :login => ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy', - :password => ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy', - :signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy' + login: ENV['GROWSTUFF_PAYPAL_USERNAME'] || 'dummy', + password: ENV['GROWSTUFF_PAYPAL_PASSWORD'] || 'dummy', + signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] || 'dummy' } ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) diff --git a/config/environments/production.rb b/config/environments/production.rb index 2410617fb..3b61a9255 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -67,15 +67,15 @@ Growstuff::Application.configure do config.active_record.dump_schema_after_migration = false # Growstuff configuration - config.action_mailer.default_url_options = { :host => 'growstuff.org' } + config.action_mailer.default_url_options = { host: 'growstuff.org' } config.action_mailer.smtp_settings = { - :port => '587', - :address => 'smtp.mandrillapp.com', - :user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'], - :password => ENV['GROWSTUFF_MANDRILL_APIKEY'], - :domain => 'heroku.com', - :authentication => :plain + port: '587', + address: 'smtp.mandrillapp.com', + user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'], + password: ENV['GROWSTUFF_MANDRILL_APIKEY'], + domain: 'heroku.com', + authentication: :plain } config.action_mailer.delivery_method = :smtp @@ -93,9 +93,9 @@ Growstuff::Application.configure do config.after_initialize do ActiveMerchant::Billing::Base.mode = :production paypal_options = { - :login => ENV['GROWSTUFF_PAYPAL_USERNAME'], - :password => ENV['GROWSTUFF_PAYPAL_PASSWORD'], - :signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE'] + login: ENV['GROWSTUFF_PAYPAL_USERNAME'], + password: ENV['GROWSTUFF_PAYPAL_PASSWORD'], + signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] } ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 4b69b498c..e9702cad0 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -69,15 +69,15 @@ Growstuff::Application.configure do config.active_record.dump_schema_after_migration = false # Growstuff configuration - config.action_mailer.default_url_options = { :host => 'staging.growstuff.org' } + config.action_mailer.default_url_options = { host: 'staging.growstuff.org' } config.action_mailer.smtp_settings = { - :port => '587', - :address => 'smtp.mandrillapp.com', - :user_name => ENV['GROWSTUFF_MANDRILL_USERNAME'], - :password => ENV['GROWSTUFF_MANDRILL_APIKEY'], - :domain => 'heroku.com', - :authentication => :plain + port: '587', + address: 'smtp.mandrillapp.com', + user_name: ENV['GROWSTUFF_MANDRILL_USERNAME'], + password: ENV['GROWSTUFF_MANDRILL_APIKEY'], + domain: 'heroku.com', + authentication: :plain } config.action_mailer.delivery_method = :smtp @@ -91,9 +91,9 @@ Growstuff::Application.configure do config.after_initialize do ActiveMerchant::Billing::Base.mode = :test paypal_options = { - :login => ENV['GROWSTUFF_PAYPAL_USERNAME'], - :password => ENV['GROWSTUFF_PAYPAL_PASSWORD'], - :signature => ENV['GROWSTUFF_PAYPAL_SIGNATURE'] + login: ENV['GROWSTUFF_PAYPAL_USERNAME'], + password: ENV['GROWSTUFF_PAYPAL_PASSWORD'], + signature: ENV['GROWSTUFF_PAYPAL_SIGNATURE'] } ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) diff --git a/config/environments/test.rb b/config/environments/test.rb index c5c05f8d5..61eba7adc 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -40,7 +40,7 @@ Growstuff::Application.configure do # config.action_view.raise_on_missing_translations = true # Growstuff config - config.action_mailer.default_url_options = { :host => 'localhost:8080' } + config.action_mailer.default_url_options = { host: 'localhost:8080' } Growstuff::Application.configure do config.host = 'test.example.com' @@ -56,7 +56,7 @@ Growstuff::Application.configure do end -Geocoder.configure(:lookup => :test) +Geocoder.configure(lookup: :test) Geocoder::Lookup::Test.add_stub( "Amundsen-Scott Base, Antarctica", [ diff --git a/config/initializers/comfortable_mexican_sofa.rb b/config/initializers/comfortable_mexican_sofa.rb index fe6e80ace..fc5025933 100644 --- a/config/initializers/comfortable_mexican_sofa.rb +++ b/config/initializers/comfortable_mexican_sofa.rb @@ -97,7 +97,7 @@ end module CmsDeviseAuth def authenticate unless current_member && current_member.has_role?(:admin) - redirect_to root_path, :alert => 'Permission denied. Please sign in as an admin user to use the CMS admin area.' + redirect_to root_path, alert: 'Permission denied. Please sign in as an admin user to use the CMS admin area.' end end end diff --git a/config/initializers/geocoder.rb b/config/initializers/geocoder.rb index 0d221664e..9c52ced91 100644 --- a/config/initializers/geocoder.rb +++ b/config/initializers/geocoder.rb @@ -1,9 +1,9 @@ require 'geocodable' Geocoder.configure( - :units => :km, - :timeout => 10, - :http_headers => { + units: :km, + timeout: 10, + http_headers: { "User-Agent" => "#{Growstuff::Application.config.user_agent} #{Growstuff::Application.config.user_agent_email}", "From" => Growstuff::Application.config.user_agent_email @@ -12,5 +12,5 @@ Geocoder.configure( # This configuration takes precedence over environment/test.rb # Reported as https://github.com/alexreisner/geocoder/issues/509 if Geocoder.config.lookup != :test - Geocoder.configure(:lookup => :nominatim) + Geocoder.configure(lookup: :nominatim) end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 1aa7e772a..9980edadd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,7 +4,7 @@ Growstuff::Application.routes.draw do resources :plant_parts - devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" } + devise_for :members, controllers: { registrations: "registrations", passwords: "passwords" } devise_scope :member do get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member' end @@ -13,7 +13,7 @@ Growstuff::Application.routes.draw do resources :photos - resources :authentications, :only => [:create, :destroy] + resources :authentications, only: [:create, :destroy] resources :plantings get '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner' @@ -48,7 +48,7 @@ Growstuff::Application.routes.draw do get 'reply', on: :member end - resources :follows, :only => [:create, :destroy] + resources :follows, only: [:create, :destroy] get '/members/:login_name/follows' => 'members#view_follows', :as => 'member_follows' get '/members/:login_name/followers' => 'members#view_followers', :as => 'member_followers' @@ -69,7 +69,7 @@ Growstuff::Application.routes.draw do resources :products get "home/index" - root :to => 'home#index' + root to: 'home#index' get 'auth/:provider/callback' => 'authentications#create' @@ -85,7 +85,7 @@ Growstuff::Application.routes.draw do get '/shop' => 'shop#index' get '/shop/:action' => 'shop#:action' - comfy_route :cms_admin, :path => '/admin/cms' + comfy_route :cms_admin, path: '/admin/cms' get '/admin/orders' => 'admin/orders#index' get '/admin/orders/:action' => 'admin/orders#:action' get '/admin' => 'admin#index' @@ -93,6 +93,6 @@ Growstuff::Application.routes.draw do get '/admin/:action' => 'admin#:action' # CMS stuff -- must remain LAST - comfy_route :cms, :path => '/', :sitemap => false + comfy_route :cms, path: '/', sitemap: false end diff --git a/db/migrate/20120903092956_devise_create_users.rb b/db/migrate/20120903092956_devise_create_users.rb index 2dd95591c..cb9c47966 100644 --- a/db/migrate/20120903092956_devise_create_users.rb +++ b/db/migrate/20120903092956_devise_create_users.rb @@ -2,8 +2,8 @@ class DeviseCreateUsers < ActiveRecord::Migration def change create_table(:users) do |t| ## Database authenticatable - t.string :email, :null => false, :default => "" - t.string :encrypted_password, :null => false, :default => "" + t.string :email, null: false, default: "" + t.string :encrypted_password, null: false, default: "" ## Recoverable t.string :reset_password_token @@ -13,7 +13,7 @@ class DeviseCreateUsers < ActiveRecord::Migration t.datetime :remember_created_at ## Trackable - t.integer :sign_in_count, :default => 0 + t.integer :sign_in_count, default: 0 t.datetime :current_sign_in_at t.datetime :last_sign_in_at t.string :current_sign_in_ip @@ -26,7 +26,7 @@ class DeviseCreateUsers < ActiveRecord::Migration t.string :unconfirmed_email # Only if using reconfirmable ## Lockable - t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts + t.integer :failed_attempts, default: 0 # Only if lock strategy is :failed_attempts t.string :unlock_token # Only if unlock strategy is :email or :both t.datetime :locked_at @@ -37,10 +37,10 @@ class DeviseCreateUsers < ActiveRecord::Migration t.timestamps end - add_index :users, :email, :unique => true - add_index :users, :reset_password_token, :unique => true - add_index :users, :confirmation_token, :unique => true - add_index :users, :unlock_token, :unique => true + add_index :users, :email, unique: true + add_index :users, :reset_password_token, unique: true + add_index :users, :confirmation_token, unique: true + add_index :users, :unlock_token, unique: true # add_index :users, :authentication_token, :unique => true end end diff --git a/db/migrate/20121003190731_require_system_name_for_crops.rb b/db/migrate/20121003190731_require_system_name_for_crops.rb index 47a46ec26..f4536c18b 100644 --- a/db/migrate/20121003190731_require_system_name_for_crops.rb +++ b/db/migrate/20121003190731_require_system_name_for_crops.rb @@ -2,13 +2,13 @@ class RequireSystemNameForCrops < ActiveRecord::Migration def up change_table :crops do |t| t.index :system_name - t.change :system_name, :string, :null => false + t.change :system_name, :string, null: false end end def down change_table :crops do |t| - t.change :system_name, :string, :null => true + t.change :system_name, :string, null: true t.remove_index :system_name end end diff --git a/db/migrate/20121105032913_create_gardens.rb b/db/migrate/20121105032913_create_gardens.rb index eaa7715d6..373179c26 100644 --- a/db/migrate/20121105032913_create_gardens.rb +++ b/db/migrate/20121105032913_create_gardens.rb @@ -1,9 +1,9 @@ class CreateGardens < ActiveRecord::Migration def change create_table :gardens do |t| - t.string :name, :null => false + t.string :name, null: false t.integer :user_id - t.string :slug, :null => false + t.string :slug, null: false t.timestamps end diff --git a/db/migrate/20121107012827_create_scientific_names.rb b/db/migrate/20121107012827_create_scientific_names.rb index 4651a5b91..36140e27a 100644 --- a/db/migrate/20121107012827_create_scientific_names.rb +++ b/db/migrate/20121107012827_create_scientific_names.rb @@ -1,8 +1,8 @@ class CreateScientificNames < ActiveRecord::Migration def change create_table :scientific_names do |t| - t.string :scientific_name, :null => false - t.integer :crop_id, :null => false + t.string :scientific_name, null: false + t.integer :crop_id, null: false t.timestamps end diff --git a/db/migrate/20121108105440_create_updates.rb b/db/migrate/20121108105440_create_updates.rb index fa96f17a5..a2b29ed03 100644 --- a/db/migrate/20121108105440_create_updates.rb +++ b/db/migrate/20121108105440_create_updates.rb @@ -1,9 +1,9 @@ class CreateUpdates < ActiveRecord::Migration def change create_table :updates do |t| - t.integer :user_id, :null => false - t.string :subject, :null => false - t.text :body, :null => false + t.integer :user_id, null: false + t.string :subject, null: false + t.text :body, null: false t.timestamps end diff --git a/db/migrate/20121219022554_create_plantings.rb b/db/migrate/20121219022554_create_plantings.rb index 2c50a7813..7fe96782e 100644 --- a/db/migrate/20121219022554_create_plantings.rb +++ b/db/migrate/20121219022554_create_plantings.rb @@ -1,8 +1,8 @@ class CreatePlantings < ActiveRecord::Migration def change create_table :plantings do |t| - t.integer :garden_id, :null => false - t.integer :crop_id, :null => false + t.integer :garden_id, null: false + t.integer :crop_id, null: false t.datetime :planted_at t.integer :quantity t.text :description diff --git a/db/migrate/20130208034248_require_fields_for_comments.rb b/db/migrate/20130208034248_require_fields_for_comments.rb index c1adea261..ecb17f302 100644 --- a/db/migrate/20130208034248_require_fields_for_comments.rb +++ b/db/migrate/20130208034248_require_fields_for_comments.rb @@ -1,17 +1,17 @@ class RequireFieldsForComments < ActiveRecord::Migration def up change_table :comments do |t| - t.change :post_id, :integer, :null => false - t.change :author_id, :integer, :null => false - t.change :body, :text, :null => false + t.change :post_id, :integer, null: false + t.change :author_id, :integer, null: false + t.change :body, :text, null: false end end def down change_table :comments do |t| - t.change :post_id, :integer, :null => true - t.change :author_id, :integer, :null => true - t.change :body, :text, :null => true + t.change :post_id, :integer, null: true + t.change :author_id, :integer, null: true + t.change :body, :text, null: true end end end diff --git a/db/migrate/20130212123628_create_notifications.rb b/db/migrate/20130212123628_create_notifications.rb index 0bb5e1bec..03ca126a8 100644 --- a/db/migrate/20130212123628_create_notifications.rb +++ b/db/migrate/20130212123628_create_notifications.rb @@ -2,7 +2,7 @@ class CreateNotifications < ActiveRecord::Migration def change create_table :notifications do |t| t.integer :from_id - t.integer :to_id, :null => false + t.integer :to_id, null: false t.string :subject t.text :body t.boolean :read diff --git a/db/migrate/20130213014511_create_forums.rb b/db/migrate/20130213014511_create_forums.rb index 6388876e6..1969b09dc 100644 --- a/db/migrate/20130213014511_create_forums.rb +++ b/db/migrate/20130213014511_create_forums.rb @@ -1,9 +1,9 @@ class CreateForums < ActiveRecord::Migration def change create_table :forums do |t| - t.string :name, :null => false - t.text :description, :null => false - t.integer :owner_id, :null => false + t.string :name, null: false + t.text :description, null: false + t.integer :owner_id, null: false t.timestamps end diff --git a/db/migrate/20130214024117_create_roles.rb b/db/migrate/20130214024117_create_roles.rb index 8ccaf5ca6..8797691d5 100644 --- a/db/migrate/20130214024117_create_roles.rb +++ b/db/migrate/20130214024117_create_roles.rb @@ -1,7 +1,7 @@ class CreateRoles < ActiveRecord::Migration def change create_table :roles do |t| - t.string :name, :null => false + t.string :name, null: false t.text :description t.timestamps diff --git a/db/migrate/20130214034838_add_members_roles_table.rb b/db/migrate/20130214034838_add_members_roles_table.rb index a8044ebc8..9e84fd37d 100644 --- a/db/migrate/20130214034838_add_members_roles_table.rb +++ b/db/migrate/20130214034838_add_members_roles_table.rb @@ -1,6 +1,6 @@ class AddMembersRolesTable < ActiveRecord::Migration def change - create_table :members_roles, :id => false do |t| + create_table :members_roles, id: false do |t| t.integer :member_id t.integer :role_id end diff --git a/db/migrate/20130222060730_default_read_to_false.rb b/db/migrate/20130222060730_default_read_to_false.rb index b7250b8c6..efe6d4b61 100644 --- a/db/migrate/20130222060730_default_read_to_false.rb +++ b/db/migrate/20130222060730_default_read_to_false.rb @@ -1,13 +1,13 @@ class DefaultReadToFalse < ActiveRecord::Migration def up change_table :notifications do |t| - t.change :read, :boolean, :default => false + t.change :read, :boolean, default: false end end def down change_table :notifications do |t| - t.change :read, :boolean, :default => nil + t.change :read, :boolean, default: nil end end end diff --git a/db/migrate/20130327120024_add_send_email_to_member.rb b/db/migrate/20130327120024_add_send_email_to_member.rb index b52c5fdb2..b83dd9e03 100644 --- a/db/migrate/20130327120024_add_send_email_to_member.rb +++ b/db/migrate/20130327120024_add_send_email_to_member.rb @@ -1,5 +1,5 @@ class AddSendEmailToMember < ActiveRecord::Migration def change - add_column :members, :send_notification_email, :boolean, :default => true + add_column :members, :send_notification_email, :boolean, default: true end end diff --git a/db/migrate/20130404174459_create_authentications.rb b/db/migrate/20130404174459_create_authentications.rb index 3acdf6080..aeeb109da 100644 --- a/db/migrate/20130404174459_create_authentications.rb +++ b/db/migrate/20130404174459_create_authentications.rb @@ -1,8 +1,8 @@ class CreateAuthentications < ActiveRecord::Migration def change create_table :authentications do |t| - t.integer :member_id, :null => false - t.string :provider, :null => false + t.integer :member_id, null: false + t.string :provider, null: false t.string :uid t.string :token t.string :secret diff --git a/db/migrate/20130409103549_make_post_subject_non_null.rb b/db/migrate/20130409103549_make_post_subject_non_null.rb index 0a7f8db34..877bd048f 100644 --- a/db/migrate/20130409103549_make_post_subject_non_null.rb +++ b/db/migrate/20130409103549_make_post_subject_non_null.rb @@ -1,3 +1,3 @@ class MakePostSubjectNonNull < ActiveRecord::Migration - change_column :posts, :subject, :string, :null => false + change_column :posts, :subject, :string, null: false end diff --git a/db/migrate/20130507105357_create_products.rb b/db/migrate/20130507105357_create_products.rb index 0ad9b1063..8e8901293 100644 --- a/db/migrate/20130507105357_create_products.rb +++ b/db/migrate/20130507105357_create_products.rb @@ -1,9 +1,9 @@ class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| - t.string :name, :null => false - t.string :description, :null => false - t.decimal :min_price, :null => false + t.string :name, null: false + t.string :description, null: false + t.decimal :min_price, null: false t.timestamps end diff --git a/db/migrate/20130507110411_create_orders.rb b/db/migrate/20130507110411_create_orders.rb index 0aed92dfb..7cde95ad2 100644 --- a/db/migrate/20130507110411_create_orders.rb +++ b/db/migrate/20130507110411_create_orders.rb @@ -1,7 +1,7 @@ class CreateOrders < ActiveRecord::Migration def change create_table :orders do |t| - t.string :member_id, :null => false + t.string :member_id, null: false t.timestamps end diff --git a/db/migrate/20130507113915_add_orders_products_table.rb b/db/migrate/20130507113915_add_orders_products_table.rb index 92af21427..8666e01ab 100644 --- a/db/migrate/20130507113915_add_orders_products_table.rb +++ b/db/migrate/20130507113915_add_orders_products_table.rb @@ -1,6 +1,6 @@ class AddOrdersProductsTable < ActiveRecord::Migration def change - create_table :orders_products, :id => false do |t| + create_table :orders_products, id: false do |t| t.integer :order_id t.integer :product_id end diff --git a/db/migrate/20130508104506_create_photos.rb b/db/migrate/20130508104506_create_photos.rb index f7c56188d..f6c908529 100644 --- a/db/migrate/20130508104506_create_photos.rb +++ b/db/migrate/20130508104506_create_photos.rb @@ -1,10 +1,10 @@ class CreatePhotos < ActiveRecord::Migration def change create_table :photos do |t| - t.integer :owner_id, :null => false - t.integer :flickr_photo_id, :null => false - t.string :thumbnail_url, :null => false - t.string :fullsize_url, :null => false + t.integer :owner_id, null: false + t.integer :flickr_photo_id, null: false + t.string :thumbnail_url, null: false + t.string :fullsize_url, null: false t.timestamps end diff --git a/db/migrate/20130509123711_add_metadata_to_photos.rb b/db/migrate/20130509123711_add_metadata_to_photos.rb index 9e73a6272..cb76a901a 100644 --- a/db/migrate/20130509123711_add_metadata_to_photos.rb +++ b/db/migrate/20130509123711_add_metadata_to_photos.rb @@ -5,9 +5,9 @@ class AddMetadataToPhotos < ActiveRecord::Migration t.string :license_name t.string :license_url t.string :link_url - t.change :title, :string, :null => false - t.change :license_name, :string, :null => false - t.change :link_url, :string, :null => false + t.change :title, :string, null: false + t.change :license_name, :string, null: false + t.change :link_url, :string, null: false end end diff --git a/db/migrate/20130517015920_create_account_details.rb b/db/migrate/20130517015920_create_account_details.rb index 8eb899fd5..99f4c4eb8 100644 --- a/db/migrate/20130517015920_create_account_details.rb +++ b/db/migrate/20130517015920_create_account_details.rb @@ -1,7 +1,7 @@ class CreateAccountDetails < ActiveRecord::Migration def change create_table :account_details do |t| - t.integer :member_id, :null => false + t.integer :member_id, null: false t.integer :account_type_id t.datetime :paid_until diff --git a/db/migrate/20130517234458_require_account_type_name.rb b/db/migrate/20130517234458_require_account_type_name.rb index c4bdfa69a..6e745cb4b 100644 --- a/db/migrate/20130517234458_require_account_type_name.rb +++ b/db/migrate/20130517234458_require_account_type_name.rb @@ -1,9 +1,9 @@ class RequireAccountTypeName < ActiveRecord::Migration def up - change_column :account_types, :name, :string, :null => false + change_column :account_types, :name, :string, null: false end def down - change_column :account_types, :name, :string, :null => true + change_column :account_types, :name, :string, null: true end end diff --git a/db/migrate/20130531110729_add_photos_plantings_table.rb b/db/migrate/20130531110729_add_photos_plantings_table.rb index 07040ed93..ab08ff0d1 100644 --- a/db/migrate/20130531110729_add_photos_plantings_table.rb +++ b/db/migrate/20130531110729_add_photos_plantings_table.rb @@ -1,6 +1,6 @@ class AddPhotosPlantingsTable < ActiveRecord::Migration def change - create_table :photos_plantings, :id => false do |t| + create_table :photos_plantings, id: false do |t| t.integer :photo_id t.integer :planting_id end diff --git a/db/migrate/20130715110134_create_seeds.rb b/db/migrate/20130715110134_create_seeds.rb index 1d0d49225..d5ece87ec 100644 --- a/db/migrate/20130715110134_create_seeds.rb +++ b/db/migrate/20130715110134_create_seeds.rb @@ -1,8 +1,8 @@ class CreateSeeds < ActiveRecord::Migration def change create_table :seeds do |t| - t.integer :owner_id, :null => false - t.integer :crop_id, :null => false + t.integer :owner_id, null: false + t.integer :crop_id, null: false t.text :description t.integer :quantity t.date :use_by diff --git a/db/migrate/20130917053547_create_harvests.rb b/db/migrate/20130917053547_create_harvests.rb index e7b7db6b4..8a808ac1a 100644 --- a/db/migrate/20130917053547_create_harvests.rb +++ b/db/migrate/20130917053547_create_harvests.rb @@ -1,8 +1,8 @@ class CreateHarvests < ActiveRecord::Migration def change create_table :harvests do |t| - t.integer :crop_id, :null => false - t.integer :owner_id, :null => false + t.integer :crop_id, null: false + t.integer :owner_id, null: false t.date :harvested_at t.decimal :quantity t.string :units diff --git a/db/migrate/20131025104228_add_fields_to_gardens.rb b/db/migrate/20131025104228_add_fields_to_gardens.rb index 24b73c966..2c3983507 100644 --- a/db/migrate/20131025104228_add_fields_to_gardens.rb +++ b/db/migrate/20131025104228_add_fields_to_gardens.rb @@ -1,6 +1,6 @@ class AddFieldsToGardens < ActiveRecord::Migration def change - add_column :gardens, :active, :boolean, :default => true + add_column :gardens, :active, :boolean, default: true add_column :gardens, :location, :string add_column :gardens, :latitude, :float add_column :gardens, :longitude, :float diff --git a/db/migrate/20140718075753_default_plantings_count_to_zero.rb b/db/migrate/20140718075753_default_plantings_count_to_zero.rb index 608821fbc..ce8d0d075 100644 --- a/db/migrate/20140718075753_default_plantings_count_to_zero.rb +++ b/db/migrate/20140718075753_default_plantings_count_to_zero.rb @@ -1,9 +1,9 @@ class DefaultPlantingsCountToZero < ActiveRecord::Migration def up - change_column :crops, :plantings_count, :integer, :default => 0 + change_column :crops, :plantings_count, :integer, default: 0 end def down - change_column :crops, :plantings_count, :integer, :default => nil + change_column :crops, :plantings_count, :integer, default: nil end end diff --git a/db/migrate/20140829230600_add_finished_to_planting.rb b/db/migrate/20140829230600_add_finished_to_planting.rb index 8be30756a..f8cb41663 100644 --- a/db/migrate/20140829230600_add_finished_to_planting.rb +++ b/db/migrate/20140829230600_add_finished_to_planting.rb @@ -1,6 +1,6 @@ class AddFinishedToPlanting < ActiveRecord::Migration def change - add_column :plantings, :finished, :boolean, :default => false + add_column :plantings, :finished, :boolean, default: false add_column :plantings, :finished_at, :date end end diff --git a/db/migrate/20140905001730_add_harvests_photos_table.rb b/db/migrate/20140905001730_add_harvests_photos_table.rb index edacd061b..fb9c73a37 100644 --- a/db/migrate/20140905001730_add_harvests_photos_table.rb +++ b/db/migrate/20140905001730_add_harvests_photos_table.rb @@ -1,6 +1,6 @@ class AddHarvestsPhotosTable < ActiveRecord::Migration def change - create_table :harvests_photos, :id => false do |t| + create_table :harvests_photos, id: false do |t| t.integer :photo_id t.integer :harvest_id end diff --git a/db/migrate/20140928044231_add_crops_posts_table.rb b/db/migrate/20140928044231_add_crops_posts_table.rb index a8c06927b..6f200c3d8 100644 --- a/db/migrate/20140928044231_add_crops_posts_table.rb +++ b/db/migrate/20140928044231_add_crops_posts_table.rb @@ -1,6 +1,6 @@ class AddCropsPostsTable < ActiveRecord::Migration def change - create_table :crops_posts, :id => false do |t| + create_table :crops_posts, id: false do |t| t.integer :crop_id t.integer :post_id end diff --git a/db/migrate/20140928085713_add_send_planting_reminder_to_member.rb b/db/migrate/20140928085713_add_send_planting_reminder_to_member.rb index e6a5ec214..67c7184d7 100644 --- a/db/migrate/20140928085713_add_send_planting_reminder_to_member.rb +++ b/db/migrate/20140928085713_add_send_planting_reminder_to_member.rb @@ -1,5 +1,5 @@ class AddSendPlantingReminderToMember < ActiveRecord::Migration def change - add_column :members, :send_planting_reminder, :boolean, :default => true + add_column :members, :send_planting_reminder, :boolean, default: true end end diff --git a/db/migrate/20141018111015_create_alternate_names.rb b/db/migrate/20141018111015_create_alternate_names.rb index 8a63471c8..7364fceb0 100644 --- a/db/migrate/20141018111015_create_alternate_names.rb +++ b/db/migrate/20141018111015_create_alternate_names.rb @@ -1,9 +1,9 @@ class CreateAlternateNames < ActiveRecord::Migration def change create_table :alternate_names do |t| - t.string :name, :null => false - t.integer :crop_id, :null => false - t.integer :creator_id, :null => false + t.string :name, null: false + t.integer :crop_id, null: false + t.integer :creator_id, null: false t.timestamps end diff --git a/db/migrate/20150124110540_add_properties_to_seeds.rb b/db/migrate/20150124110540_add_properties_to_seeds.rb index e2fa64fe7..7d60735fd 100644 --- a/db/migrate/20150124110540_add_properties_to_seeds.rb +++ b/db/migrate/20150124110540_add_properties_to_seeds.rb @@ -2,8 +2,8 @@ class AddPropertiesToSeeds < ActiveRecord::Migration def change add_column :seeds, :days_until_maturity_min, :integer add_column :seeds, :days_until_maturity_max, :integer - add_column :seeds, :organic, :text, :default => 'unknown' - add_column :seeds, :gmo, :text, :default => 'unknown' - add_column :seeds, :heirloom, :text, :default => 'unknown' + add_column :seeds, :organic, :text, default: 'unknown' + add_column :seeds, :gmo, :text, default: 'unknown' + add_column :seeds, :heirloom, :text, default: 'unknown' end end diff --git a/db/migrate/20150127043022_add_gardens_photos_table.rb b/db/migrate/20150127043022_add_gardens_photos_table.rb index c0cfd76fc..7e8f8bd81 100644 --- a/db/migrate/20150127043022_add_gardens_photos_table.rb +++ b/db/migrate/20150127043022_add_gardens_photos_table.rb @@ -1,6 +1,6 @@ class AddGardensPhotosTable < ActiveRecord::Migration def change - create_table :gardens_photos, :id => false do |t| + create_table :gardens_photos, id: false do |t| t.integer :photo_id t.integer :garden_id end diff --git a/db/migrate/20150201052245_create_cms.rb b/db/migrate/20150201052245_create_cms.rb index 9e999488f..0a29e2b6d 100644 --- a/db/migrate/20150201052245_create_cms.rb +++ b/db/migrate/20150201052245_create_cms.rb @@ -6,52 +6,52 @@ class CreateCms < ActiveRecord::Migration when 'PostgreSQL' { } else - { :limit => 16777215 } + { limit: 16777215 } end # -- Sites -------------------------------------------------------------- create_table :comfy_cms_sites do |t| - t.string :label, :null => false - t.string :identifier, :null => false - t.string :hostname, :null => false + t.string :label, null: false + t.string :identifier, null: false + t.string :hostname, null: false t.string :path - t.string :locale, :null => false, :default => 'en' - t.boolean :is_mirrored, :null => false, :default => false + t.string :locale, null: false, default: 'en' + t.boolean :is_mirrored, null: false, default: false end add_index :comfy_cms_sites, :hostname add_index :comfy_cms_sites, :is_mirrored # -- Layouts ------------------------------------------------------------ create_table :comfy_cms_layouts do |t| - t.integer :site_id, :null => false + t.integer :site_id, null: false t.integer :parent_id t.string :app_layout - t.string :label, :null => false - t.string :identifier, :null => false + t.string :label, null: false + t.string :identifier, null: false t.text :content, text_limit t.text :css, text_limit t.text :js, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false + t.integer :position, null: false, default: 0 + t.boolean :is_shared, null: false, default: false t.timestamps end add_index :comfy_cms_layouts, [:parent_id, :position] - add_index :comfy_cms_layouts, [:site_id, :identifier], :unique => true + add_index :comfy_cms_layouts, [:site_id, :identifier], unique: true # -- Pages -------------------------------------------------------------- create_table :comfy_cms_pages do |t| - t.integer :site_id, :null => false + t.integer :site_id, null: false t.integer :layout_id t.integer :parent_id t.integer :target_page_id - t.string :label, :null => false + t.string :label, null: false t.string :slug - t.string :full_path, :null => false + t.string :full_path, null: false t.text :content_cache, text_limit - t.integer :position, :null => false, :default => 0 - t.integer :children_count, :null => false, :default => 0 - t.boolean :is_published, :null => false, :default => true - t.boolean :is_shared, :null => false, :default => false + t.integer :position, null: false, default: 0 + t.integer :children_count, null: false, default: 0 + t.boolean :is_published, null: false, default: true + t.boolean :is_shared, null: false, default: false t.timestamps end add_index :comfy_cms_pages, [:site_id, :full_path] @@ -59,9 +59,9 @@ class CreateCms < ActiveRecord::Migration # -- Page Blocks -------------------------------------------------------- create_table :comfy_cms_blocks do |t| - t.string :identifier, :null => false + t.string :identifier, null: false t.text :content, text_limit - t.references :blockable, :polymorphic => true + t.references :blockable, polymorphic: true t.timestamps end add_index :comfy_cms_blocks, [:identifier] @@ -69,27 +69,27 @@ class CreateCms < ActiveRecord::Migration # -- Snippets ----------------------------------------------------------- create_table :comfy_cms_snippets do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :identifier, :null => false + t.integer :site_id, null: false + t.string :label, null: false + t.string :identifier, null: false t.text :content, text_limit - t.integer :position, :null => false, :default => 0 - t.boolean :is_shared, :null => false, :default => false + t.integer :position, null: false, default: 0 + t.boolean :is_shared, null: false, default: false t.timestamps end - add_index :comfy_cms_snippets, [:site_id, :identifier], :unique => true + add_index :comfy_cms_snippets, [:site_id, :identifier], unique: true add_index :comfy_cms_snippets, [:site_id, :position] # -- Files -------------------------------------------------------------- create_table :comfy_cms_files do |t| - t.integer :site_id, :null => false + t.integer :site_id, null: false t.integer :block_id - t.string :label, :null => false - t.string :file_file_name, :null => false - t.string :file_content_type, :null => false - t.integer :file_file_size, :null => false - t.string :description, :limit => 2048 - t.integer :position, :null => false, :default => 0 + t.string :label, null: false + t.string :file_file_name, null: false + t.string :file_content_type, null: false + t.integer :file_file_size, null: false + t.string :description, limit: 2048 + t.integer :position, null: false, default: 0 t.timestamps end add_index :comfy_cms_files, [:site_id, :label] @@ -98,31 +98,31 @@ class CreateCms < ActiveRecord::Migration add_index :comfy_cms_files, [:site_id, :block_id] # -- Revisions ----------------------------------------------------------- - create_table :comfy_cms_revisions, :force => true do |t| - t.string :record_type, :null => false - t.integer :record_id, :null => false + create_table :comfy_cms_revisions, force: true do |t| + t.string :record_type, null: false + t.integer :record_id, null: false t.text :data, text_limit t.datetime :created_at end add_index :comfy_cms_revisions, [:record_type, :record_id, :created_at], - :name => 'index_cms_revisions_on_rtype_and_rid_and_created_at' + name: 'index_cms_revisions_on_rtype_and_rid_and_created_at' # -- Categories --------------------------------------------------------- - create_table :comfy_cms_categories, :force => true do |t| - t.integer :site_id, :null => false - t.string :label, :null => false - t.string :categorized_type, :null => false + create_table :comfy_cms_categories, force: true do |t| + t.integer :site_id, null: false + t.string :label, null: false + t.string :categorized_type, null: false end - add_index :comfy_cms_categories, [:site_id, :categorized_type, :label], :unique => true, - :name => 'index_cms_categories_on_site_id_and_cat_type_and_label' + add_index :comfy_cms_categories, [:site_id, :categorized_type, :label], unique: true, + name: 'index_cms_categories_on_site_id_and_cat_type_and_label' - create_table :comfy_cms_categorizations, :force => true do |t| - t.integer :category_id, :null => false - t.string :categorized_type, :null => false - t.integer :categorized_id, :null => false + create_table :comfy_cms_categorizations, force: true do |t| + t.integer :category_id, null: false + t.string :categorized_type, null: false + t.integer :categorized_id, null: false end - add_index :comfy_cms_categorizations, [:category_id, :categorized_type, :categorized_id], :unique => true, - :name => 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id' + add_index :comfy_cms_categorizations, [:category_id, :categorized_type, :categorized_id], unique: true, + name: 'index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id' end def self.down diff --git a/db/seeds.rb b/db/seeds.rb index 37fb28204..f1b8d67cb 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -39,22 +39,22 @@ end def load_roles puts "Creating admin role..." - @admin = Role.create(:name => 'Admin') + @admin = Role.create(name: 'Admin') puts "Creating crop wrangler role..." - @wrangler = Role.create(:name => 'Crop Wrangler') + @wrangler = Role.create(name: 'Crop Wrangler') end def load_basic_account_types puts "Adding 'free' and 'staff' account types..." AccountType.create!( - :name => "Free", - :is_paid => false, - :is_permanent_paid => false + name: "Free", + is_paid: false, + is_permanent_paid: false ) AccountType.create!( - :name => "Staff", - :is_paid => true, - :is_permanent_paid => true + name: "Staff", + is_paid: true, + is_permanent_paid: true ) end @@ -75,10 +75,10 @@ def load_test_users (1..member_size).each do |i| @user = Member.new( - :login_name => "test#{i}", - :email => "test#{i}@example.com", - :password => "password#{i}", - :tos_agreement => true + login_name: "test#{i}", + email: "test#{i}@example.com", + password: "password#{i}", + tos_agreement: true ) @user.skip_confirmation! @user.save! @@ -112,20 +112,20 @@ end def load_admin_users puts "Adding admin and crop wrangler members..." @admin_user = Member.new( - :login_name => "admin1", - :email => "admin1@example.com", - :password => "password1", - :tos_agreement => true + login_name: "admin1", + email: "admin1@example.com", + password: "password1", + tos_agreement: true ) @admin_user.skip_confirmation! @admin_user.roles << @admin @admin_user.save! @wrangler_user = Member.new( - :login_name => "wrangler1", - :email => "wrangler1@example.com", - :password => "password1", - :tos_agreement => true + login_name: "wrangler1", + email: "wrangler1@example.com", + password: "password1", + tos_agreement: true ) @wrangler_user.skip_confirmation! @wrangler_user.roles << @wrangler @@ -134,10 +134,10 @@ end def create_cropbot @cropbot_user = Member.new( - :login_name => "cropbot", - :email => Growstuff::Application.config.bot_email, - :password => SecureRandom.urlsafe_base64(64), - :tos_agreement => true + login_name: "cropbot", + email: Growstuff::Application.config.bot_email, + password: SecureRandom.urlsafe_base64(64), + tos_agreement: true ) @cropbot_user.skip_confirmation! @cropbot_user.roles << @wrangler @@ -149,31 +149,31 @@ end def load_paid_account_types puts "Adding 'paid' and 'seed' account types..." @paid_account = AccountType.create!( - :name => "Paid", - :is_paid => true, - :is_permanent_paid => false + name: "Paid", + is_paid: true, + is_permanent_paid: false ) @seed_account = AccountType.create!( - :name => "Seed", - :is_paid => true, - :is_permanent_paid => true + name: "Seed", + is_paid: true, + is_permanent_paid: true ) end def load_products puts "Adding products..." Product.create!( - :name => "Annual subscription", - :description => "Paid account, 1 year", - :min_price => 3000, - :account_type_id => @paid_account.id, - :paid_months => 12 + name: "Annual subscription", + description: "Paid account, 1 year", + min_price: 3000, + account_type_id: @paid_account.id, + paid_months: 12 ) Product.create!( - :name => "Seed account", - :description => "Paid account, in perpetuity", - :min_price => 15000, - :account_type_id => @seed_account.id, + name: "Seed account", + description: "Paid account, in perpetuity", + min_price: 15000, + account_type_id: @seed_account.id, ) end diff --git a/lib/haml/filters/growstuff_markdown.rb b/lib/haml/filters/growstuff_markdown.rb index 6711461e0..bb665e810 100644 --- a/lib/haml/filters/growstuff_markdown.rb +++ b/lib/haml/filters/growstuff_markdown.rb @@ -16,7 +16,7 @@ module Haml::Filters # find crop case-insensitively crop = Crop.where('lower(name) = ?', crop_str.downcase).first if crop - url = Rails.application.routes.url_helpers.crop_url(crop, :host => Growstuff::Application.config.host) + url = Rails.application.routes.url_helpers.crop_url(crop, host: Growstuff::Application.config.host) "[#{crop_str}](#{url})" else crop_str @@ -29,7 +29,7 @@ module Haml::Filters # find member case-insensitively member = Member.where('lower(login_name) = ?', member_str.downcase).first if member - url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + url = Rails.application.routes.url_helpers.member_url(member, only_path: true) "[#{member_str}](#{url})" else member_str @@ -42,7 +42,7 @@ module Haml::Filters # find member case-insensitively member = Member.where('lower(login_name) = ?', member_str[1..-1].downcase).first if member - url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + url = Rails.application.routes.url_helpers.member_url(member, only_path: true) "[#{member_str}](#{url})" else member_str diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index bfb7b8642..58372327a 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -3,7 +3,7 @@ namespace :growstuff do desc "Add an admin user, by name" # usage: rake growstuff:admin_user name=skud - task :admin_user => :environment do + task admin_user: :environment do member = Member.find_by_login_name(ENV['name']) or raise "Usage: rake growstuff:admin_user name=whoever (login name is case-sensitive)" admin = Role.find('admin') member.roles << admin @@ -12,7 +12,7 @@ namespace :growstuff do desc "Add a crop wrangler user, by name" # usage: rake growstuff:cropwrangler_user name=skud - task :cropwrangler_user => :environment do + task cropwrangler_user: :environment do member = Member.find_by_login_name(ENV['name']) or raise "Usage: rake growstuff:cropwrangler_user name=whoever (login name is case-sensitive)" cw = Role.find('crop-wrangler') member.roles << cw @@ -21,7 +21,7 @@ namespace :growstuff do desc "Upload crops from a CSV file" # usage: rake growstuff:import_crops file=filename.csv - task :import_crops => :environment do + task import_crops: :environment do require 'csv' @file = ENV['file'] or raise "Usage: rake growstuff:import_crops file=file.csv" @@ -38,7 +38,7 @@ namespace :growstuff do desc "Send planting reminder email" # usage: rake growstuff:send_planting_reminder - task :send_planting_reminder => :environment do + task send_planting_reminder: :environment do # Heroku scheduler only lets us run things daily, so this checks # whether it's the right day to actually do the deed. # Note that Heroku scheduler runs on UTC. @@ -56,7 +56,7 @@ namespace :growstuff do desc "Depopulate Null Island" # this fixes up anyone who has erroneously wound up with a 0,0 lat/long - task :depopulate_null_island => :environment do + task depopulate_null_island: :environment do Member.find_each do |m| if m.location and (m.latitude == nil and m.longitude == nil) m.geocode @@ -69,7 +69,7 @@ namespace :growstuff do namespace :oneoff do desc "May 2013: replace any empty notification subjects with (no subject)" - task :empty_subjects => :environment do + task empty_subjects: :environment do # this is inefficient as it checks every Notification, but the # site is small and there aren't many of them, so it shouldn't matter @@ -81,7 +81,7 @@ namespace :growstuff do end desc "May 2013: replace any empty garden names with Garden" - task :empty_garden_names => :environment do + task empty_garden_names: :environment do # this is inefficient as it checks every Garden, but the # site is small and there aren't many of them, so it shouldn't matter @@ -96,48 +96,48 @@ namespace :growstuff do desc "June 2013: create account types and products." - task :setup_shop => :environment do + task setup_shop: :environment do puts "Adding account types..." AccountType.find_or_create_by( - :name => "Free", - :is_paid => false, - :is_permanent_paid => false + name: "Free", + is_paid: false, + is_permanent_paid: false ) @paid_account = AccountType.find_or_create_by( - :name => "Paid", - :is_paid => true, - :is_permanent_paid => false + name: "Paid", + is_paid: true, + is_permanent_paid: false ) @seed_account = AccountType.find_or_create_by( - :name => "Seed", - :is_paid => true, - :is_permanent_paid => true + name: "Seed", + is_paid: true, + is_permanent_paid: true ) @staff_account = AccountType.find_or_create_by( - :name => "Staff", - :is_paid => true, - :is_permanent_paid => true + name: "Staff", + is_paid: true, + is_permanent_paid: true ) puts "Adding products..." Product.find_or_create_by( - :name => "Annual subscription", - :description => "An annual subscription gives you access to paid account features for one year. Does not auto-renew.", - :min_price => 3000, - :account_type_id => @paid_account.id, - :paid_months => 12 + name: "Annual subscription", + description: "An annual subscription gives you access to paid account features for one year. Does not auto-renew.", + min_price: 3000, + account_type_id: @paid_account.id, + paid_months: 12 ) Product.find_or_create_by( - :name => "Seed account", - :description => "A seed account helps Growstuff grow in its early days. It gives you all the features of a paid account, in perpetuity. This account type never expires.", - :min_price => 15000, - :account_type_id => @seed_account.id, + name: "Seed account", + description: "A seed account helps Growstuff grow in its early days. It gives you all the features of a paid account, in perpetuity. This account type never expires.", + min_price: 15000, + account_type_id: @seed_account.id, ) puts "Giving each member an account record..." Member.all.each do |m| unless m.account - Account.create(:member_id => m.id) + Account.create(member_id: m.id) end end @@ -152,7 +152,7 @@ namespace :growstuff do end desc "June 2013: replace nil account_types with free accounts" - task :nil_account_type => :environment do + task nil_account_type: :environment do free = AccountType.find_by_name("Free") raise "Free account type not found: run rake growstuff:oneoff:setup_shop"\ @@ -166,7 +166,7 @@ namespace :growstuff do end desc "July 2013: replace nil seed.tradable_to with nowhere" - task :tradable_to_nowhere => :environment do + task tradable_to_nowhere: :environment do Seed.all.each do |s| unless s.tradable_to @@ -177,7 +177,7 @@ namespace :growstuff do end desc "August 2013: set up plantings_count cache on crop" - task :reset_crop_plantings_count => :environment do + task reset_crop_plantings_count: :environment do Crop.find_each do |c| Crop.reset_counters c.id, :plantings @@ -185,7 +185,7 @@ namespace :growstuff do end desc "August 2013: set default creator on existing crops" - task :set_default_crop_creator => :environment do + task set_default_crop_creator: :environment do cropbot = Member.find_by_login_name("cropbot") raise "cropbot not found: create cropbot member on site or run rake db:seed" unless cropbot @@ -207,7 +207,7 @@ namespace :growstuff do end desc "August 2013: set planting owner" - task :set_planting_owner => :environment do + task set_planting_owner: :environment do Planting.find_each do |p| p.owner = p.garden.owner p.save @@ -215,14 +215,14 @@ namespace :growstuff do end desc "August 2013: initialize member planting counter" - task :initialize_member_planting_count => :environment do + task initialize_member_planting_count: :environment do Member.find_each do |m| Member.reset_counters m.id, :plantings end end desc "October 2013: set garden locations to member locations" - task :initialize_garden_locations => :environment do + task initialize_garden_locations: :environment do Member.located.find_each do |m| m.gardens.each do |g| if g.location.blank? @@ -236,7 +236,7 @@ namespace :growstuff do end desc "October 2013: import initial plant parts" - task :import_plant_parts => :environment do + task import_plant_parts: :environment do plant_parts = [ 'fruit', 'flower', @@ -257,7 +257,7 @@ namespace :growstuff do end desc "July 2014: set planting_count to 0 by default, not nil" - task :zero_plantings_count => :environment do + task zero_plantings_count: :environment do Crop.find_each do |c| if c.plantings_count.nil? c.plantings_count = 0 @@ -267,7 +267,7 @@ namespace :growstuff do end desc "August 2014: fix ping to pint in database" - task :ping_to_pint => :environment do + task ping_to_pint: :environment do Harvest.find_each do |h| if h.unit == "ping" h.unit = "pint" @@ -277,21 +277,21 @@ namespace :growstuff do end desc "October 2014: remove unused photos" - task :remove_unused_photos => :environment do + task remove_unused_photos: :environment do Photo.find_each do |p| p.destroy_if_unused end end desc "October 2014: generate crops_posts records for existing posts" - task :generate_crops_posts_records => :environment do + task generate_crops_posts_records: :environment do Post.find_each do |p| p.save end end desc "October 2014: add alternate names for crops" - task :add_alternate_names => :environment do + task add_alternate_names: :environment do require 'csv' file = "db/seeds/alternate_names_201410.csv" puts "Loading alternate names from #{file}..." @@ -316,7 +316,7 @@ namespace :growstuff do end desc "January 2015: fill in si_weight column" - task :populate_si_weight => :environment do + task populate_si_weight: :environment do Harvest.find_each do |h| h.set_si_weight h.save @@ -324,7 +324,7 @@ namespace :growstuff do end desc "January 2015: build Elasticsearch index" - task :elasticsearch_create_index => :environment do + task elasticsearch_create_index: :environment do Crop.__elasticsearch__.create_index! force: true Crop.import end diff --git a/lib/tasks/hooks.rake b/lib/tasks/hooks.rake index 036032414..93d599831 100644 --- a/lib/tasks/hooks.rake +++ b/lib/tasks/hooks.rake @@ -1,5 +1,5 @@ desc "Install git hooks" task :hooks do FileUtils.symlink '../../script/pre-commit.sh', '.git/hooks/pre-commit', - :force => true + force: true end diff --git a/lib/tasks/testing.rake b/lib/tasks/testing.rake index 1f7f000ef..a7908d590 100644 --- a/lib/tasks/testing.rake +++ b/lib/tasks/testing.rake @@ -2,7 +2,7 @@ require 'rake' begin require 'rspec/core/rake_task' task(:spec).clear - RSpec::Core::RakeTask.new(:spec => 'db:test:prepare') do |t| + RSpec::Core::RakeTask.new(spec: 'db:test:prepare') do |t| t.verbose = false end rescue LoadError diff --git a/script/heroku_maintenance.rb b/script/heroku_maintenance.rb index cf23b398f..4fd898148 100755 --- a/script/heroku_maintenance.rb +++ b/script/heroku_maintenance.rb @@ -3,7 +3,7 @@ require 'heroku-api' require 'yaml' -heroku = Heroku::API.new(:api_key => ENV['HEROKU_API_KEY']) +heroku = Heroku::API.new(api_key: ENV['HEROKU_API_KEY']) branch = ENV['TRAVIS_BRANCH'] travis_config = YAML.load_file('.travis.yml') if travis_config['deploy']['app'].has_key? branch diff --git a/spec/controllers/admin/orders_controller_spec.rb b/spec/controllers/admin/orders_controller_spec.rb index aa79e2895..28fe0203a 100644 --- a/spec/controllers/admin/orders_controller_spec.rb +++ b/spec/controllers/admin/orders_controller_spec.rb @@ -24,13 +24,13 @@ describe Admin::OrdersController do describe "GET search" do it "assigns @orders" do order = FactoryGirl.create(:order) - get :search, {:search_by => 'order_id', :search_text => order.id} + get :search, {search_by: 'order_id', search_text: order.id} assigns(:orders).should eq([order]) end it "sets an error message if nothing found" do order = FactoryGirl.create(:order) - get :search, {:search_by => 'order_id', :search_text => 'foo'} + get :search, {search_by: 'order_id', search_text: 'foo'} flash[:alert].should match /Couldn't find order with/ end end diff --git a/spec/controllers/authentications_controller_spec.rb b/spec/controllers/authentications_controller_spec.rb index 9365ed782..e3dd39447 100644 --- a/spec/controllers/authentications_controller_spec.rb +++ b/spec/controllers/authentications_controller_spec.rb @@ -22,7 +22,7 @@ describe AuthenticationsController do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_member) { @member } - @auth = FactoryGirl.create(:authentication, :member => @member) + @auth = FactoryGirl.create(:authentication, member: @member) request.env['omniauth.auth'] = { 'provider' => 'foo', 'uid' => 'bar', diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index cac37fe7e..3e60a642b 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -26,12 +26,12 @@ describe CommentsController do def valid_attributes @post = FactoryGirl.create(:post) - { :post_id => @post.id, :author_id => @member.id, :body => "some text" } + { post_id: @post.id, author_id: @member.id, body: "some text" } end describe "GET RSS feed" do it "returns an RSS feed" do - get :index, :format => "rss" + get :index, format: "rss" response.should be_success response.should render_template("comments/index") response.content_type.should eq("application/rss+xml") @@ -41,14 +41,14 @@ describe CommentsController do describe "GET new" do it "picks up post from params" do post = FactoryGirl.create(:post) - get :new, {:post_id => post.id} + get :new, {post_id: post.id} assigns(:post).should eq(post) end it "assigns the old comments as @comments" do post = FactoryGirl.create(:post) - old_comment = FactoryGirl.create(:comment, :post => post) - get :new, {:post_id => post.id} + old_comment = FactoryGirl.create(:comment, post: post) + get :new, {post_id: post.id} assigns(:comments).should eq [old_comment] end @@ -61,9 +61,9 @@ describe CommentsController do describe "GET edit" do it "assigns previous comments as @comments" do post = FactoryGirl.create(:post) - old_comment = FactoryGirl.create(:comment, :post => post) - comment = FactoryGirl.create(:comment, :post => post, :author => @member) - get :edit, {:id => comment.to_param} + old_comment = FactoryGirl.create(:comment, post: post) + comment = FactoryGirl.create(:comment, post: post, author: @member) + get :edit, {id: comment.to_param} assigns(:comments).should eq([comment, old_comment]) end end @@ -72,7 +72,7 @@ describe CommentsController do describe "with valid params" do it "redirects to the comment's post" do comment = Comment.create! valid_attributes - put :update, {:id => comment.to_param, :comment => valid_attributes} + put :update, {id: comment.to_param, comment: valid_attributes} response.should redirect_to(comment.post) end end @@ -82,7 +82,7 @@ describe CommentsController do it "redirects to the post the comment was on" do comment = Comment.create! valid_attributes post = comment.post - delete :destroy, {:id => comment.to_param} + delete :destroy, {id: comment.to_param} response.should redirect_to(post) end end diff --git a/spec/controllers/crops_controller_spec.rb b/spec/controllers/crops_controller_spec.rb index b9b6d44ba..894858057 100644 --- a/spec/controllers/crops_controller_spec.rb +++ b/spec/controllers/crops_controller_spec.rb @@ -22,9 +22,9 @@ describe CropsController do def valid_attributes { - :name => "Tomato", - :en_wikipedia_url => 'http://en.wikipedia.org/wiki/Tomato', - :approval_status => 'approved' + name: "Tomato", + en_wikipedia_url: 'http://en.wikipedia.org/wiki/Tomato', + approval_status: 'approved' } end @@ -55,7 +55,7 @@ describe CropsController do describe "GET RSS feed" do it "returns an RSS feed" do - get :index, :format => "rss" + get :index, format: "rss" response.should be_success response.should render_template("crops/index") response.content_type.should eq("application/rss+xml") diff --git a/spec/controllers/gardens_controller_spec.rb b/spec/controllers/gardens_controller_spec.rb index 5905c8200..4e9d0fc1c 100644 --- a/spec/controllers/gardens_controller_spec.rb +++ b/spec/controllers/gardens_controller_spec.rb @@ -22,7 +22,7 @@ describe GardensController do def valid_attributes member = FactoryGirl.create(:member) - {:name => 'My Garden', :owner_id => member.id } + {name: 'My Garden', owner_id: member.id } end end diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb index b1e6312cd..80822c564 100644 --- a/spec/controllers/harvests_controller_spec.rb +++ b/spec/controllers/harvests_controller_spec.rb @@ -22,9 +22,9 @@ describe HarvestsController do def valid_attributes { - :owner_id => subject.current_member.id, - :crop_id => FactoryGirl.create(:crop).id, - :plant_part_id => FactoryGirl.create(:plant_part).id + owner_id: subject.current_member.id, + crop_id: FactoryGirl.create(:crop).id, + plant_part_id: FactoryGirl.create(:plant_part).id } end @@ -34,8 +34,8 @@ describe HarvestsController do @member2 = FactoryGirl.create(:member) @tomato = FactoryGirl.create(:tomato) @maize = FactoryGirl.create(:maize) - @harvest1 = FactoryGirl.create(:harvest, :owner_id => @member1.id, :crop_id => @tomato.id) - @harvest2 = FactoryGirl.create(:harvest, :owner_id => @member2.id, :crop_id => @maize.id) + @harvest1 = FactoryGirl.create(:harvest, owner_id: @member1.id, crop_id: @tomato.id) + @harvest2 = FactoryGirl.create(:harvest, owner_id: @member2.id, crop_id: @maize.id) end it "assigns all harvests as @harvests" do @@ -44,19 +44,19 @@ describe HarvestsController do end it "picks up owner from params and shows owner's harvests only" do - get :index, {:owner => @member1.slug} + get :index, {owner: @member1.slug} assigns(:owner).should eq @member1 assigns(:harvests).should eq [@harvest1] end it "picks up crop from params and shows the harvests for the crop only" do - get :index, {:crop => @maize.name} + get :index, {crop: @maize.name} assigns(:crop).should eq @maize assigns(:harvests).should eq [@harvest2] end it "generates a csv" do - get :index, {:format => "csv"} + get :index, {format: "csv"} response.status.should eq 200 end end @@ -64,7 +64,7 @@ describe HarvestsController do describe "GET show" do it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - get :show, {:id => harvest.to_param} + get :show, {id: harvest.to_param} assigns(:harvest).should eq(harvest) end end @@ -79,7 +79,7 @@ describe HarvestsController do describe "GET edit" do it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - get :edit, {:id => harvest.to_param} + get :edit, {id: harvest.to_param} assigns(:harvest).should eq(harvest) end end @@ -88,18 +88,18 @@ describe HarvestsController do describe "with valid params" do it "creates a new Harvest" do expect { - post :create, {:harvest => valid_attributes} + post :create, {harvest: valid_attributes} }.to change(Harvest, :count).by(1) end it "assigns a newly created harvest as @harvest" do - post :create, {:harvest => valid_attributes} + post :create, {harvest: valid_attributes} assigns(:harvest).should be_a(Harvest) assigns(:harvest).should be_persisted end it "redirects to the created harvest" do - post :create, {:harvest => valid_attributes} + post :create, {harvest: valid_attributes} response.should redirect_to(Harvest.last) end end @@ -108,14 +108,14 @@ describe HarvestsController do it "assigns a newly created but unsaved harvest as @harvest" do # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - post :create, {:harvest => { "crop_id" => "invalid value" }} + post :create, {harvest: { "crop_id" => "invalid value" }} assigns(:harvest).should be_a_new(Harvest) end it "re-renders the 'new' template" do # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - post :create, {:harvest => { "crop_id" => "invalid value" }} + post :create, {harvest: { "crop_id" => "invalid value" }} response.should render_template("new") end end @@ -130,18 +130,18 @@ describe HarvestsController do # receives the :update message with whatever params are # submitted in the request. Harvest.any_instance.should_receive(:update).with({ "crop_id" => "1" }) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "1" }} + put :update, {id: harvest.to_param, harvest: { "crop_id" => "1" }} end it "assigns the requested harvest as @harvest" do harvest = Harvest.create! valid_attributes - put :update, {:id => harvest.to_param, :harvest => valid_attributes} + put :update, {id: harvest.to_param, harvest: valid_attributes} assigns(:harvest).should eq(harvest) end it "redirects to the harvest" do harvest = Harvest.create! valid_attributes - put :update, {:id => harvest.to_param, :harvest => valid_attributes} + put :update, {id: harvest.to_param, harvest: valid_attributes} response.should redirect_to(harvest) end end @@ -151,7 +151,7 @@ describe HarvestsController do harvest = Harvest.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }} + put :update, {id: harvest.to_param, harvest: { "crop_id" => "invalid value" }} assigns(:harvest).should eq(harvest) end @@ -159,7 +159,7 @@ describe HarvestsController do harvest = Harvest.create! valid_attributes # Trigger the behavior that occurs when invalid params are submitted Harvest.any_instance.stub(:save).and_return(false) - put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "invalid value" }} + put :update, {id: harvest.to_param, harvest: { "crop_id" => "invalid value" }} response.should render_template("edit") end end @@ -169,13 +169,13 @@ describe HarvestsController do it "destroys the requested harvest" do harvest = Harvest.create! valid_attributes expect { - delete :destroy, {:id => harvest.to_param} + delete :destroy, {id: harvest.to_param} }.to change(Harvest, :count).by(-1) end it "redirects to the harvests list" do harvest = Harvest.create! valid_attributes - delete :destroy, {:id => harvest.to_param} + delete :destroy, {id: harvest.to_param} response.should redirect_to(harvests_url) end end diff --git a/spec/controllers/member_controller_spec.rb b/spec/controllers/member_controller_spec.rb index 4bd1f6826..be178341e 100644 --- a/spec/controllers/member_controller_spec.rb +++ b/spec/controllers/member_controller_spec.rb @@ -20,9 +20,9 @@ describe MembersController do before :each do @member = FactoryGirl.create(:member) - @posts = [ FactoryGirl.create(:post, :author => @member) ] - @twitter_auth = FactoryGirl.create(:authentication, :member => @member) - @flickr_auth = FactoryGirl.create(:flickr_authentication, :member => @member) + @posts = [ FactoryGirl.create(:post, author: @member) ] + @twitter_auth = FactoryGirl.create(:authentication, member: @member) + @flickr_auth = FactoryGirl.create(:flickr_authentication, member: @member) end describe "GET index" do @@ -34,7 +34,7 @@ describe MembersController do describe "GET JSON index" do it "provides JSON for members" do - get :index, :format => 'json' + get :index, format: 'json' response.should be_success end end @@ -42,39 +42,39 @@ describe MembersController do describe "GET show" do it "provides JSON for member profile" do - get :show, { :id => @member.id , :format => 'json' } + get :show, { id: @member.id , format: 'json' } response.should be_success end it "assigns @posts with the member's posts" do - get :show, {:id => @member.id} + get :show, {id: @member.id} assigns(:posts).should eq(@posts) end it "assigns @twitter_auth" do - get :show, {:id => @member.id} + get :show, {id: @member.id} assigns(:twitter_auth).should eq(@twitter_auth) end it "assigns @flickr_auth" do - get :show, {:id => @member.id} + get :show, {id: @member.id} assigns(:flickr_auth).should eq(@flickr_auth) end it "doesn't show completely nonsense members" do - lambda { get :show, {:id => 9999} }.should raise_error(ActiveRecord::RecordNotFound) + lambda { get :show, {id: 9999} }.should raise_error(ActiveRecord::RecordNotFound) end it "doesn't show unconfirmed members" do @member2 = FactoryGirl.create(:unconfirmed_member) - lambda { get :show, {:id => @member2.id} }.should raise_error(ActiveRecord::RecordNotFound) + lambda { get :show, {id: @member2.id} }.should raise_error(ActiveRecord::RecordNotFound) end end describe "GET member's RSS feed" do it "returns an RSS feed" do - get :show, { :id => @member.to_param, :format => "rss" } + get :show, { id: @member.to_param, format: "rss" } response.should be_success response.should render_template("members/show") response.content_type.should eq("application/rss+xml") diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 55bf1d72d..1b70d0f33 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -47,7 +47,7 @@ describe NotificationsController do describe "GET index" do it "assigns all notifications as @notifications" do - notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) + notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id) get :index, {} assigns(:notifications).should eq([notification]) end @@ -55,24 +55,24 @@ describe NotificationsController do describe "GET show" do it "assigns the requested notification as @notification" do - notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) - get :show, {:id => notification.to_param} + notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id) + get :show, {id: notification.to_param} assigns(:notification).should eq(notification) end it "assigns the reply link for a post comment" do - notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) + notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id) - get :show, {:id => notification.to_param} + get :show, {id: notification.to_param} assigns(:reply_link).should_not be_nil assigns(:reply_link).should eq new_comment_url( - :post_id => notification.post.id + post_id: notification.post.id ) end it "marks notifications as read" do - notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) - get :show, {:id => notification.to_param} + notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id) + get :show, {id: notification.to_param} # we need to fetch it from the db again, can't test against the old one n = Notification.find(notification.id) n.read.should eq true @@ -82,7 +82,7 @@ describe NotificationsController do describe "GET new" do it "assigns a recipient" do @recipient = FactoryGirl.create(:member) - get :new, {:recipient_id => @recipient.id } + get :new, {recipient_id: @recipient.id } assigns(:recipient).should be_an_instance_of(Member) end end @@ -91,7 +91,7 @@ describe NotificationsController do describe "with valid params" do it "redirects to the recipient's profile" do @recipient = FactoryGirl.create(:member) - post :create, { :notification => { :recipient_id => @recipient.id, :subject => 'foo' } } + post :create, { notification: { recipient_id: @recipient.id, subject: 'foo' } } response.should redirect_to(notifications_path) end end diff --git a/spec/controllers/order_items_controller_spec.rb b/spec/controllers/order_items_controller_spec.rb index 5188b5127..f081c85b7 100644 --- a/spec/controllers/order_items_controller_spec.rb +++ b/spec/controllers/order_items_controller_spec.rb @@ -24,22 +24,22 @@ describe OrderItemsController do @member = FactoryGirl.create(:member) sign_in @member @product = FactoryGirl.create(:product) - @order = FactoryGirl.create(:order, :member => @member) + @order = FactoryGirl.create(:order, member: @member) @order_item = FactoryGirl.create(:order_item, - :order => @order, - :product => @product, - :price => @product.min_price + order: @order, + product: @product, + price: @product.min_price ) end describe "POST create" do it "redirects to order" do - @order = FactoryGirl.create(:order, :member => @member) - post :create, {:order_item => { - :order_id => @order.id, - :product_id => @product.id, - :price => @product.min_price + @order = FactoryGirl.create(:order, member: @member) + post :create, {order_item: { + order_id: @order.id, + product_id: @product.id, + price: @product.min_price }} response.should redirect_to(OrderItem.last.order) end @@ -49,9 +49,9 @@ describe OrderItemsController do sign_in @member @product = FactoryGirl.create(:product) expect { - post :create, {:order_item => { - :product_id => @product.id, - :price => @product.min_price + post :create, {order_item: { + product_id: @product.id, + price: @product.min_price }} }.to change(Order, :count).by(1) OrderItem.last.order.should be_an_instance_of Order @@ -59,13 +59,13 @@ describe OrderItemsController do describe "with non-int price" do it "converts 3.33 to 333 cents" do - @order = FactoryGirl.create(:order, :member => @member) - @product = FactoryGirl.create(:product, :min_price => 1) + @order = FactoryGirl.create(:order, member: @member) + @product = FactoryGirl.create(:product, min_price: 1) expect { - post :create, {:order_item => { - :order_id => @order.id, - :product_id => @product.id, - :price => 3.33 + post :create, {order_item: { + order_id: @order.id, + product_id: @product.id, + price: 3.33 }} }.to change(OrderItem, :count).by(1) OrderItem.last.price.should eq 333 diff --git a/spec/controllers/orders_controller_spec.rb b/spec/controllers/orders_controller_spec.rb index c884bdca9..81e74a5b5 100644 --- a/spec/controllers/orders_controller_spec.rb +++ b/spec/controllers/orders_controller_spec.rb @@ -32,8 +32,8 @@ describe OrdersController do it 'sets the referral_code' do member = FactoryGirl.create(:member) sign_in member - order = Order.create!(:member_id => member.id) - get :checkout, {:id => order.to_param, :referral_code => 'FOOBAR'} + order = Order.create!(member_id: member.id) + get :checkout, {id: order.to_param, referral_code: 'FOOBAR'} order.reload order.referral_code.should eq 'FOOBAR' end @@ -41,8 +41,8 @@ describe OrdersController do it "redirects to Paypal" do member = FactoryGirl.create(:member) sign_in member - order = Order.create!(:member_id => member.id) - get :checkout, {:id => order.to_param} + order = Order.create!(member_id: member.id) + get :checkout, {id: order.to_param} response.status.should eq 302 response.redirect_url.should match /paypal\.com/ end @@ -52,8 +52,8 @@ describe OrdersController do it "assigns the requested order as @order" do member = FactoryGirl.create(:member) sign_in member - order = Order.create!(:member_id => member.id) - get :complete, {:id => order.to_param} + order = Order.create!(member_id: member.id) + get :complete, {id: order.to_param} assigns(:order).should eq(order) end end @@ -62,8 +62,8 @@ describe OrdersController do it "redirects to the shop" do member = FactoryGirl.create(:member) sign_in member - order = Order.create!(:member_id => member.id) - delete :destroy, {:id => order.id} + order = Order.create!(member_id: member.id) + delete :destroy, {id: order.id} response.should redirect_to(shop_url) end end diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 603959b46..e73ba5317 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -47,31 +47,31 @@ describe PhotosController do end it "assigns the flickr auth as @flickr_auth" do - @auth = FactoryGirl.create(:flickr_authentication, :member => @member) + @auth = FactoryGirl.create(:flickr_authentication, member: @member) get :new, {} assigns(:flickr_auth).should be_an_instance_of(Authentication) end it "assigns a planting id" do - get :new, { :type => "planting", :id => 5 } + get :new, { type: "planting", id: 5 } assigns(:id).should eq "5" assigns(:type).should eq "planting" end it "assigns a harvest id" do - get :new, { :type => "harvest", :id => 5 } + get :new, { type: "harvest", id: 5 } assigns(:id).should eq "5" assigns(:type).should eq "harvest" end it "assigns a garden id" do - get :new, { :type => "garden", :id => 5 } + get :new, { type: "garden", id: 5 } assigns(:id).should eq "5" assigns(:type).should eq "garden" end it "assigns the current set as @current_set" do - get :new, { :set => 'foo' } + get :new, { set: 'foo' } assigns(:current_set).should eq "foo" end @@ -80,12 +80,12 @@ describe PhotosController do describe "POST create" do before(:each) do Photo.any_instance.stub(:flickr_metadata).and_return( { - :title => "A Heartbreaking work of staggering genius", - :license_name => "CC-BY", - :license_url => "http://example.com/aybpl", - :thumbnail_url => "http://example.com/thumb.jpg", - :fullsize_url => "http://example.com/full.jpg", - :link_url => "http://example.com" + title: "A Heartbreaking work of staggering genius", + license_name: "CC-BY", + license_url: "http://example.com/aybpl", + thumbnail_url: "http://example.com/thumb.jpg", + fullsize_url: "http://example.com/full.jpg", + link_url: "http://example.com" }) end @@ -94,52 +94,52 @@ describe PhotosController do it "attaches the photo to a planting" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - garden = FactoryGirl.create(:garden, :owner => member) - planting = FactoryGirl.create(:planting, :garden => garden, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "planting", - :id => planting.id } + garden = FactoryGirl.create(:garden, owner: member) + planting = FactoryGirl.create(:planting, garden: garden, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "planting", + id: planting.id } Photo.last.plantings.first.should eq planting end it "doesn't attach a photo to a planting twice" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - garden = FactoryGirl.create(:garden, :owner => member) - planting = FactoryGirl.create(:planting, :garden => garden, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "planting", - :id => planting.id } - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "planting", - :id => planting.id } + garden = FactoryGirl.create(:garden, owner: member) + planting = FactoryGirl.create(:planting, garden: garden, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "planting", + id: planting.id } + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "planting", + id: planting.id } Photo.last.plantings.size.should eq 1 end it "attaches the photo to a harvest" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - harvest = FactoryGirl.create(:harvest, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "harvest", - :id => harvest.id } + harvest = FactoryGirl.create(:harvest, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "harvest", + id: harvest.id } Photo.last.harvests.first.should eq harvest end it "doesn't attach a photo to a harvest twice" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - harvest = FactoryGirl.create(:harvest, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "harvest", - :id => harvest.id } - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "harvest", - :id => harvest.id } + harvest = FactoryGirl.create(:harvest, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "harvest", + id: harvest.id } + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "harvest", + id: harvest.id } Photo.last.harvests.size.should eq 1 end end @@ -147,10 +147,10 @@ describe PhotosController do describe "for the second time" do it "does not add a photo twice" do expect { - post :create, {:photo => { :flickr_photo_id => 1 } } + post :create, {photo: { flickr_photo_id: 1 } } }.to change(Photo, :count).by(1) expect { - post :create, {:photo => { :flickr_photo_id => 1 } } + post :create, {photo: { flickr_photo_id: 1 } } }.to change(Photo, :count).by(0) end end @@ -159,23 +159,23 @@ describe PhotosController do it "creates the planting/photo link" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - garden = FactoryGirl.create(:garden, :owner => member) - planting = FactoryGirl.create(:planting, :garden => garden, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "planting", - :id => planting.id } + garden = FactoryGirl.create(:garden, owner: member) + planting = FactoryGirl.create(:planting, garden: garden, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "planting", + id: planting.id } Photo.last.plantings.first.should eq planting end it "creates the harvest/photo link" do member = FactoryGirl.create(:member) controller.stub(:current_member) { member } - harvest = FactoryGirl.create(:harvest, :owner => member) - photo = FactoryGirl.create(:photo, :owner => member) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "harvest", - :id => harvest.id } + harvest = FactoryGirl.create(:harvest, owner: member) + photo = FactoryGirl.create(:photo, owner: member) + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "harvest", + id: harvest.id } Photo.last.harvests.first.should eq harvest end end @@ -185,9 +185,9 @@ describe PhotosController do # members will be auto-created, and different planting = FactoryGirl.create(:planting) photo = FactoryGirl.create(:photo) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "planting", - :id => planting.id } + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "planting", + id: planting.id } Photo.last.plantings.first.should_not eq planting end @@ -195,9 +195,9 @@ describe PhotosController do # members will be auto-created, and different harvest = FactoryGirl.create(:harvest) photo = FactoryGirl.create(:photo) - post :create, {:photo => { :flickr_photo_id => photo.flickr_photo_id }, - :type => "harvest", - :id => harvest.id } + post :create, {photo: { flickr_photo_id: photo.flickr_photo_id }, + type: "harvest", + id: harvest.id } Photo.last.harvests.first.should_not eq harvest end end diff --git a/spec/controllers/places_controller_spec.rb b/spec/controllers/places_controller_spec.rb index 1f6da6ed0..4c8c34d3c 100644 --- a/spec/controllers/places_controller_spec.rb +++ b/spec/controllers/places_controller_spec.rb @@ -28,12 +28,12 @@ describe PlacesController do end it "assigns place name" do - get :show, { :place => @member_london.location } + get :show, { place: @member_london.location } assigns(:place).should eq @member_london.location end it "assigns nearby members" do - get :show, { :place => @member_london.location } + get :show, { place: @member_london.location } assigns(:nearby_members).should eq [@member_london, @member_south_pole] end @@ -41,7 +41,7 @@ describe PlacesController do describe "GET search" do it "redirects to the new place" do - get :search, { :new_place => "foo" } + get :search, { new_place: "foo" } response.should redirect_to place_path("foo") end end diff --git a/spec/controllers/plantings_controller_spec.rb b/spec/controllers/plantings_controller_spec.rb index 2e6b2e366..68514b634 100644 --- a/spec/controllers/plantings_controller_spec.rb +++ b/spec/controllers/plantings_controller_spec.rb @@ -22,8 +22,8 @@ describe PlantingsController do def valid_attributes { - :garden_id => FactoryGirl.create(:garden, :owner => subject.current_member).id, - :crop_id => FactoryGirl.create(:crop).id + garden_id: FactoryGirl.create(:garden, owner: subject.current_member).id, + crop_id: FactoryGirl.create(:crop).id } end @@ -33,8 +33,8 @@ describe PlantingsController do @member2 = FactoryGirl.create(:member) @tomato = FactoryGirl.create(:tomato) @maize = FactoryGirl.create(:maize) - @planting1 = FactoryGirl.create(:planting, :crop => @tomato, :owner => @member1) - @planting2 = FactoryGirl.create(:planting, :crop => @maize, :owner => @member2) + @planting1 = FactoryGirl.create(:planting, crop: @tomato, owner: @member1) + @planting2 = FactoryGirl.create(:planting, crop: @maize, owner: @member2) end it "assigns all plantings as @plantings" do @@ -43,13 +43,13 @@ describe PlantingsController do end it "picks up owner from params and shows owner's plantings only" do - get :index, {:owner => @member1.slug} + get :index, {owner: @member1.slug} assigns(:owner).should eq @member1 assigns(:plantings).should eq [@planting1] end it "picks up crop from params and shows the plantings for the crop only" do - get :index, {:crop => @maize.name} + get :index, {crop: @maize.name} assigns(:crop).should eq @maize assigns(:plantings).should eq [@planting2] end @@ -59,7 +59,7 @@ describe PlantingsController do it "picks up crop from params" do crop = FactoryGirl.create(:crop) - get :new, {:crop_id => crop.id} + get :new, {crop_id: crop.id} assigns(:crop).should eq(crop) end @@ -70,8 +70,8 @@ describe PlantingsController do it "picks up garden from params" do member = FactoryGirl.create(:member) - garden = FactoryGirl.create(:garden, :owner => member) - get :new, {:garden_id => garden.id} + garden = FactoryGirl.create(:garden, owner: member) + get :new, {garden_id: garden.id} assigns(:garden).should eq(garden) end @@ -86,7 +86,7 @@ describe PlantingsController do end it "sets the owner automatically" do - post :create, { :planting => valid_attributes } + post :create, { planting: valid_attributes } assigns(:planting).owner.should eq subject.current_member end diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index b11434a98..b53a67f40 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -22,12 +22,12 @@ describe PostsController do def valid_attributes member = FactoryGirl.create(:member) - { :author_id => member.id, :subject => "blah", :body => "blah blah" } + { author_id: member.id, subject: "blah", body: "blah blah" } end describe "GET RSS feed" do it "returns an RSS feed" do - get :index, :format => "rss" + get :index, format: "rss" response.should be_success response.should render_template("posts/index") response.content_type.should eq("application/rss+xml") @@ -37,7 +37,7 @@ describe PostsController do describe "GET RSS feed for individual post" do it "returns an RSS feed" do post = Post.create! valid_attributes - get :show, { :format => "rss", :id => post.slug } + get :show, { format: "rss", id: post.slug } response.should be_success response.should render_template("posts/show") response.content_type.should eq("application/rss+xml") diff --git a/spec/controllers/products_controller_spec.rb b/spec/controllers/products_controller_spec.rb index 84875191d..f8ca75083 100644 --- a/spec/controllers/products_controller_spec.rb +++ b/spec/controllers/products_controller_spec.rb @@ -22,9 +22,9 @@ describe ProductsController do def valid_attributes { - :name => "product name", - :description => 'some description', - :min_price => 9.99 + name: "product name", + description: 'some description', + min_price: 9.99 } end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 028356209..ac9990254 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -32,13 +32,13 @@ describe RegistrationsController do end it "picks up the twitter auth" do - @auth = FactoryGirl.create(:authentication, :member => @member) + @auth = FactoryGirl.create(:authentication, member: @member) get :edit assigns(:twitter_auth).should eq @auth end it "picks up the flickr auth" do - @auth = FactoryGirl.create(:flickr_authentication, :member => @member) + @auth = FactoryGirl.create(:flickr_authentication, member: @member) get :edit assigns(:flickr_auth).should eq @auth end diff --git a/spec/controllers/scientific_names_controller_spec.rb b/spec/controllers/scientific_names_controller_spec.rb index 47f3ff29c..ab40494fb 100644 --- a/spec/controllers/scientific_names_controller_spec.rb +++ b/spec/controllers/scientific_names_controller_spec.rb @@ -25,12 +25,12 @@ describe ScientificNamesController do end def valid_attributes - { :scientific_name => 'Solanum lycopersicum', :crop_id => @crop.id } + { scientific_name: 'Solanum lycopersicum', crop_id: @crop.id } end describe "GET new" do it "assigns crop if specified" do - get :new, { :crop_id => 1 } + get :new, { crop_id: 1 } assigns(:crop).should be_an_instance_of Crop end diff --git a/spec/controllers/seeds_controller_spec.rb b/spec/controllers/seeds_controller_spec.rb index 97016cf31..bfb880477 100644 --- a/spec/controllers/seeds_controller_spec.rb +++ b/spec/controllers/seeds_controller_spec.rb @@ -20,7 +20,7 @@ describe SeedsController do describe "GET index" do it "picks up owner from params" do owner = FactoryGirl.create(:member) - get :index, {:owner => owner.slug} + get :index, {owner: owner.slug} assigns(:owner).should eq(owner) end end diff --git a/spec/controllers/shop_controller_spec.rb b/spec/controllers/shop_controller_spec.rb index 51bb36437..a02d4fbad 100644 --- a/spec/controllers/shop_controller_spec.rb +++ b/spec/controllers/shop_controller_spec.rb @@ -42,7 +42,7 @@ describe ShopController do it "assigns @order as current_order if there is one" do @member = FactoryGirl.create(:member) sign_in @member - @order = FactoryGirl.create(:order, :member => @member) + @order = FactoryGirl.create(:order, member: @member) get :index, {} assigns(:order).should eq @order end diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index 71d763377..dac241586 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "account types", :js => true do +feature "account types", js: true do context "admin user" do let(:member) { create :admin_member } let(:account_type) { create :account_type } @@ -19,7 +19,7 @@ feature "account types", :js => true do expect(current_path).to eq account_types_path end - scenario "navigating to account type admin without JavaScript - Accessility version", :js => false do + scenario "navigating to account type admin without JavaScript - Accessility version", js: false do visit root_path # Extra link not needed as menu is already expanded click_link "Admin" diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index 5e9627114..a385289a6 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "forums", :js => true do +feature "forums", js: true do context "as an admin user" do let(:member) { create :admin_member } let(:forum) { create :forum } @@ -9,7 +9,7 @@ feature "forums", :js => true do login_as member end - scenario "navigating to forum admin without js", :js => false do + scenario "navigating to forum admin without js", js: false do visit root_path click_link "Admin" expect(current_path).to eq admin_path diff --git a/spec/features/crops/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb index ce7984638..de8843708 100644 --- a/spec/features/crops/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Alternate names", :js => true do +feature "Alternate names", js: true do let!(:alternate_eggplant) { create :alternate_eggplant } let(:crop) { alternate_eggplant.crop } diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 88c7ed7ad..865925bce 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "crop detail page", :js => true do +feature "crop detail page", js: true do let(:crop) { create :crop } subject { visit crop_path(crop) } @@ -46,7 +46,7 @@ feature "crop detail page", :js => true do end end - scenario "The crop has 5 varieties, including grandchild", :js => true do + scenario "The crop has 5 varieties, including grandchild", js: true do create :crop, name: 'Roma tomato child 1', parent: roma4 subject diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb index cbb410ab4..620034fb2 100644 --- a/spec/features/crops/crop_wranglers_spec.rb +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "crop wranglers", :js => true do +feature "crop wranglers", js: true do context "signed in wrangler" do let!(:crop_wranglers) { create_list :crop_wrangling_member, 3 } let(:wrangler) { crop_wranglers.first } @@ -72,7 +72,7 @@ feature "crop wranglers", :js => true do background { login_as member } - scenario "can't see wrangling page without js", :js => false do + scenario "can't see wrangling page without js", js: false do visit root_path expect(page).not_to have_link "Crop Wrangling" end diff --git a/spec/features/footer_spec.rb b/spec/features/footer_spec.rb index 47fb42631..8a2c21bbd 100644 --- a/spec/features/footer_spec.rb +++ b/spec/features/footer_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "footer", :js => true do +feature "footer", js: true do before { visit root_path } diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 8ae4aa1da..90f2f9ed7 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Planting a crop", :js => true do +feature "Planting a crop", js: true do let!(:garden) { create :garden } let!(:planting) { create :planting, garden: garden, planted_at: Date.parse("2013-3-10") } let!(:tomato) { create :tomato } diff --git a/spec/features/locale_spec.rb b/spec/features/locale_spec.rb index 6d8502cdf..74cf208be 100644 --- a/spec/features/locale_spec.rb +++ b/spec/features/locale_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Changing locales", :js => true do +feature "Changing locales", js: true do after { I18n.locale = :en } diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index c336dfa94..cfa0753ba 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "member profile", :js => true do +feature "member profile", js: true do context "signed out member" do let(:member) { create :member } @@ -157,7 +157,7 @@ feature "member profile", :js => true do end scenario "has a private message button" do - expect(page).to have_link "Send message", href: new_notification_path(:recipient_id => other_member.id) + expect(page).to have_link "Send message", href: new_notification_path(recipient_id: other_member.id) end end diff --git a/spec/features/members_list_spec.rb b/spec/features/members_list_spec.rb index a7857bafd..99e15820a 100644 --- a/spec/features/members_list_spec.rb +++ b/spec/features/members_list_spec.rb @@ -20,7 +20,7 @@ feature "members list" do visit members_path expect(page).to have_css "#sort" expect(page).to have_selector "form" - select("recently", :from => 'sort') + select("recently", from: 'sort') click_button('Show') all_links = page.all("#maincontainer p.login-name") expect(all_links.first).to have_text member3.login_name diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index 7966ad2ee..c5b621e10 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "Scientific names", :js => true do +feature "Scientific names", js: true do let!(:zea_mays) { create :zea_mays } let(:crop) { zea_mays.crop } diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index e1e1db2df..f3c463b17 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -29,19 +29,19 @@ feature "Seeds", :js do expect(page).to have_selector '.form-group.required', text: 'Will trade:' end - scenario "Adding a new seed", :js => true do - fill_autocomplete "crop", :with => "mai" + scenario "Adding a new seed", js: true do + fill_autocomplete "crop", with: "mai" select_from_autocomplete "maize" within "form#new_seed" do fill_in "Quantity:", with: 42 fill_in "Plant before:", with: "2014-06-15" fill_in "Days until maturity:", with: 999 fill_in "to", with: 1999 - select "certified organic", :from => "Organic?" - select "non-certified GMO-free", :from => "GMO?" - select "heirloom", :from => "Heirloom?" + select "certified organic", from: "Organic?" + select "non-certified GMO-free", from: "GMO?" + select "heirloom", from: "Heirloom?" fill_in "Description", with: "It's killer." - select "internationally", :from => "Will trade:" + select "internationally", from: "Will trade:" click_button "Save" end diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 4c238a691..1db053a80 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "seeds", :js => true do +feature "seeds", js: true do context "signed in user" do let(:member) { create :member } let(:crop) { create :crop } diff --git a/spec/features/shared_examples/crop_suggest.rb b/spec/features/shared_examples/crop_suggest.rb index 9828a7865..8f45c1e96 100644 --- a/spec/features/shared_examples/crop_suggest.rb +++ b/spec/features/shared_examples/crop_suggest.rb @@ -41,7 +41,7 @@ shared_examples "crop suggest" do |resource| select_from_autocomplete("pear") - expect(page).to have_selector("input##{resource}_crop_id[value='#{pear.id}']", :visible => false) + expect(page).to have_selector("input##{resource}_crop_id[value='#{pear.id}']", visible: false) end scenario "Typing and pausing does not affect input" do diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index 4b9220a11..693a8ec6b 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' -feature "signin", :js => true do +feature "signin", js: true do let(:member) { create :member } let(:recipient) { create :member } let(:notification) { create :notification } diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb index 1160f9efb..f35ddd0c9 100644 --- a/spec/features/signup_spec.rb +++ b/spec/features/signup_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -feature "signup", :js => true do +feature "signup", js: true do scenario "sign up for new account from top menubar" do visit crops_path # something other than front page, which has multiple signup links diff --git a/spec/helpers/harvests_helper_spec.rb b/spec/helpers/harvests_helper_spec.rb index 7bc516162..c65d8b36e 100644 --- a/spec/helpers/harvests_helper_spec.rb +++ b/spec/helpers/harvests_helper_spec.rb @@ -5,8 +5,8 @@ describe HarvestsHelper do it "blank" do harvest = FactoryGirl.create(:harvest, - :quantity => nil, - :weight_quantity => nil + quantity: nil, + weight_quantity: nil ) result = helper.display_quantity(harvest) result.should eq 'not specified' @@ -14,9 +14,9 @@ describe HarvestsHelper do it '3 individual' do harvest = FactoryGirl.create(:harvest, - :quantity => 3, - :unit => 'individual', - :weight_quantity => nil + quantity: 3, + unit: 'individual', + weight_quantity: nil ) result = helper.display_quantity(harvest) result.should eq '3' @@ -24,9 +24,9 @@ describe HarvestsHelper do it '1 bunch' do harvest = FactoryGirl.create(:harvest, - :quantity => 1, - :unit => 'bunch', - :weight_quantity => nil + quantity: 1, + unit: 'bunch', + weight_quantity: nil ) result = helper.display_quantity(harvest) result.should eq '1 bunch' @@ -34,9 +34,9 @@ describe HarvestsHelper do it '3 bunches' do harvest = FactoryGirl.create(:harvest, - :quantity => 3, - :unit => 'bunch', - :weight_quantity => nil + quantity: 3, + unit: 'bunch', + weight_quantity: nil ) result = helper.display_quantity(harvest) result.should eq '3 bunches' @@ -44,10 +44,10 @@ describe HarvestsHelper do it '3 kg' do harvest = FactoryGirl.create(:harvest, - :quantity => nil, - :unit => nil, - :weight_quantity => 3, - :weight_unit => 'kg' + quantity: nil, + unit: nil, + weight_quantity: 3, + weight_unit: 'kg' ) result = helper.display_quantity(harvest) result.should eq '3 kg' @@ -55,10 +55,10 @@ describe HarvestsHelper do it '3 individual weighing 3 kg' do harvest = FactoryGirl.create(:harvest, - :quantity => 3, - :unit => 'individual', - :weight_quantity => 3, - :weight_unit => 'kg' + quantity: 3, + unit: 'individual', + weight_quantity: 3, + weight_unit: 'kg' ) result = helper.display_quantity(harvest) result.should eq '3, weighing 3 kg' @@ -66,10 +66,10 @@ describe HarvestsHelper do it '3 bunches weighing 3 kg' do harvest = FactoryGirl.create(:harvest, - :quantity => 3, - :unit => 'bunch', - :weight_quantity => 3, - :weight_unit => 'kg' + quantity: 3, + unit: 'bunch', + weight_quantity: 3, + weight_unit: 'kg' ) result = helper.display_quantity(harvest) result.should eq '3 bunches, weighing 3 kg' diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 5c3c7e1a2..109bf0c87 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -6,7 +6,7 @@ describe NotificationsHelper do let(:member) { FactoryGirl.create(:member) } it "replies to PMs with PMs" do - notification = FactoryGirl.create(:notification, :recipient_id => member.id, :post_id => nil) + notification = FactoryGirl.create(:notification, recipient_id: member.id, post_id: nil) subject = "Re: " + notification.subject link = helper.reply_link(notification) @@ -15,12 +15,12 @@ describe NotificationsHelper do end it "replies to post comments with post comments" do - notification = FactoryGirl.create(:notification, :recipient_id => member.id) + notification = FactoryGirl.create(:notification, recipient_id: member.id) link = helper.reply_link(notification) link.should_not be_nil link.should eq new_comment_url( - :post_id => notification.post.id + post_id: notification.post.id ) end diff --git a/spec/helpers/plantings_helper_spec.rb b/spec/helpers/plantings_helper_spec.rb index 4cb2c63a7..ae8c78c78 100644 --- a/spec/helpers/plantings_helper_spec.rb +++ b/spec/helpers/plantings_helper_spec.rb @@ -3,13 +3,13 @@ require 'rails_helper' describe PlantingsHelper do describe "display_planting" do - let!(:member) { FactoryGirl.build(:member, :login_name => 'crop_lady') } + let!(:member) { FactoryGirl.build(:member, login_name: 'crop_lady') } it "does not have a quantity nor a planted from value provided" do planting = FactoryGirl.build(:planting, - :quantity => nil, - :planted_from => '', - :owner => member + quantity: nil, + planted_from: '', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady." @@ -17,9 +17,9 @@ describe PlantingsHelper do it "does not have a quantity provided" do planting = FactoryGirl.build(:planting, - :quantity => nil, - :planted_from => 'seed', - :owner => member + quantity: nil, + planted_from: 'seed', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady planted seeds." @@ -28,9 +28,9 @@ describe PlantingsHelper do context "when quantity is greater than 1" do it "does not have a planted from value provided" do planting = FactoryGirl.build(:planting, - :quantity => 10, - :planted_from => '', - :owner => member + quantity: 10, + planted_from: '', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady planted 10 units." @@ -38,9 +38,9 @@ describe PlantingsHelper do it "does have a planted from value provided" do planting = FactoryGirl.build(:planting, - :quantity => 5, - :planted_from => 'seed', - :owner => member + quantity: 5, + planted_from: 'seed', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady planted 5 seeds." @@ -50,9 +50,9 @@ describe PlantingsHelper do context "when quantity is 1" do it "does not have a planted from value provided" do planting = FactoryGirl.build(:planting, - :quantity => 1, - :planted_from => '', - :owner => member + quantity: 1, + planted_from: '', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady planted 1 unit." @@ -60,9 +60,9 @@ describe PlantingsHelper do it "does have a planted from value provided" do planting = FactoryGirl.build(:planting, - :quantity => 1, - :planted_from => 'seed', - :owner => member + quantity: 1, + planted_from: 'seed', + owner: member ) result = helper.display_planting(planting) expect(result).to eq "crop_lady planted 1 seed." diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index 979b3f305..2aba8fb89 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -7,7 +7,7 @@ def input_link(name) end def output_link(crop, name=nil) - url = Rails.application.routes.url_helpers.crop_url(crop, :host => Growstuff::Application.config.host) + url = Rails.application.routes.url_helpers.crop_url(crop, host: Growstuff::Application.config.host) if name return "#{name}" else @@ -20,7 +20,7 @@ def input_member_link(name) end def output_member_link(member, name=nil) - url = Rails.application.routes.url_helpers.member_url(member, :only_path => true) + url = Rails.application.routes.url_helpers.member_url(member, only_path: true) if name return "#{name}" else @@ -67,7 +67,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do end it "finds crops case insensitively" do - @crop = FactoryGirl.create(:crop, :name => 'tomato') + @crop = FactoryGirl.create(:crop, name: 'tomato') rendered = Haml::Filters::GrowstuffMarkdown.render(input_link('ToMaTo')) rendered.should match /#{output_link(@crop, 'ToMaTo')}/ end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 6a054083b..f31f7f845 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -9,29 +9,29 @@ describe Ability do context "notifications" do it 'member can view their own notifications' do - notification = FactoryGirl.create(:notification, :recipient => member) + notification = FactoryGirl.create(:notification, recipient: member) ability.should be_able_to(:read, notification) end it "member can't view someone else's notifications" do notification = FactoryGirl.create(:notification, - :recipient => FactoryGirl.create(:member) + recipient: FactoryGirl.create(:member) ) ability.should_not be_able_to(:read, notification) end it "member can't send messages to themself" do ability.should_not be_able_to(:create, FactoryGirl.create(:notification, - :recipient => member, - :sender => member + recipient: member, + sender: member ) ) end it "member can send messages to someone else" do ability.should be_able_to(:create, FactoryGirl.create(:notification, - :recipient => FactoryGirl.create(:member), - :sender => member + recipient: FactoryGirl.create(:member), + sender: member ) ) end @@ -123,16 +123,16 @@ describe Ability do context "orders" do - let(:order) { FactoryGirl.create(:order, :member => member) } + let(:order) { FactoryGirl.create(:order, member: member) } let(:strangers_order) { FactoryGirl.create(:order, - :member => FactoryGirl.create(:member)) } + member: FactoryGirl.create(:member)) } let(:completed_order) { FactoryGirl.create(:completed_order, - :member => member) } - let(:order_item) { FactoryGirl.create(:order_item, :order => order) } + member: member) } + let(:order_item) { FactoryGirl.create(:order_item, order: order) } let(:strangers_order_item) { FactoryGirl.create(:order_item, - :order => strangers_order) } + order: strangers_order) } let(:completed_order_item) { FactoryGirl.create(:order_item, - :order => completed_order) } + order: completed_order) } context "standard member" do it "can read their own orders" do @@ -315,7 +315,7 @@ describe Ability do end it "can't delete a plant part that has harvests" do - @harvest = FactoryGirl.create(:harvest, :plant_part => plant_part) + @harvest = FactoryGirl.create(:harvest, plant_part: plant_part) ability.should_not be_able_to(:destroy, plant_part) end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 2a41ed983..1274a825e 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -9,7 +9,7 @@ describe Account do end it "won't let you create two account details for the same member" do - @details = Account.new(:member_id => member.id) + @details = Account.new(member_id: member.id) @details.should_not be_valid end diff --git a/spec/models/alternate_name_spec.rb b/spec/models/alternate_name_spec.rb index ecbdc10eb..5e12b02de 100644 --- a/spec/models/alternate_name_spec.rb +++ b/spec/models/alternate_name_spec.rb @@ -10,9 +10,9 @@ describe AlternateName do it 'should be possible to add multiple alternate names to a crop' do crop = an.crop an2 = AlternateName.create( - :name => "really alternative tomato", - :crop_id => crop.id, - :creator_id => an.creator.id + name: "really alternative tomato", + crop_id: crop.id, + creator_id: an.creator.id ) crop.alternate_names << an2 expect(crop.alternate_names).to include an diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index 9fbf1ca1e..f3c94860e 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -37,9 +37,9 @@ describe Comment do it "doesn't send notifications to yourself" do @m = FactoryGirl.create(:member) - @p = FactoryGirl.create(:post, :author => @m) + @p = FactoryGirl.create(:post, author: @m) expect { - FactoryGirl.create(:comment, :post => @p, :author => @m) + FactoryGirl.create(:comment, post: @p, author: @m) }.to change(Notification, :count).by(0) end end @@ -47,9 +47,9 @@ describe Comment do context "ordering" do before(:each) do @m = FactoryGirl.create(:member) - @p = FactoryGirl.create(:post, :author => @m) - @c1 = FactoryGirl.create(:comment, :post => @p, :author => @m) - @c2 = FactoryGirl.create(:comment, :post => @p, :author => @m) + @p = FactoryGirl.create(:post, author: @m) + @c1 = FactoryGirl.create(:comment, post: @p, author: @m) + @c2 = FactoryGirl.create(:comment, post: @p, author: @m) end it 'is in DESC order by default' do diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index c79944c61..047ca0c6a 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -30,15 +30,15 @@ describe Crop do context 'invalid data' do it 'should not save a crop without a system name' do - crop = FactoryGirl.build(:crop, :name => nil) + crop = FactoryGirl.build(:crop, name: nil) expect { crop.save }.to raise_error ActiveRecord::StatementInvalid end end context 'ordering' do before do - @uppercase = FactoryGirl.create(:uppercasecrop, :created_at => 1.minute.ago) - @lowercase = FactoryGirl.create(:lowercasecrop, :created_at => 2.days.ago) + @uppercase = FactoryGirl.create(:uppercasecrop, created_at: 1.minute.ago) + @lowercase = FactoryGirl.create(:lowercasecrop, created_at: 2.days.ago) end it "should be sorted case-insensitively" do @@ -54,16 +54,16 @@ describe Crop do let(:tomato) { FactoryGirl.create(:tomato) } let(:maize) { FactoryGirl.create(:maize) } - let(:cucumber) { FactoryGirl.create(:crop, :name => 'cucumber') } + let(:cucumber) { FactoryGirl.create(:crop, name: 'cucumber') } before do - FactoryGirl.create_list(:planting, 10, :crop => maize) - FactoryGirl.create_list(:planting, 3, :crop => tomato) + FactoryGirl.create_list(:planting, 10, crop: maize) + FactoryGirl.create_list(:planting, 3, crop: tomato) end it "sorts by most plantings" do Crop.popular.first.should eq maize - FactoryGirl.create_list(:planting, 10, :crop => tomato) + FactoryGirl.create_list(:planting, 10, crop: tomato) Crop.popular.first.should eq tomato end @@ -72,7 +72,7 @@ describe Crop do it 'finds a default scientific name' do @crop = FactoryGirl.create(:tomato) @crop.default_scientific_name.should eq nil - @sn = FactoryGirl.create(:solanum_lycopersicum, :crop => @crop) + @sn = FactoryGirl.create(:solanum_lycopersicum, crop: @crop) @crop.reload @crop.default_scientific_name.should eq @sn.scientific_name end @@ -80,29 +80,29 @@ describe Crop do it 'counts plantings' do @crop = FactoryGirl.create(:tomato) @crop.plantings.size.should eq 0 - @planting = FactoryGirl.create(:planting, :crop => @crop) + @planting = FactoryGirl.create(:planting, crop: @crop) @crop.reload @crop.plantings.size.should eq 1 end it 'validates en_wikipedia_url' do - @crop = FactoryGirl.build(:tomato, :en_wikipedia_url => 'this is not valid') + @crop = FactoryGirl.build(:tomato, en_wikipedia_url: 'this is not valid') @crop.should_not be_valid - @crop = FactoryGirl.build(:tomato, :en_wikipedia_url => 'http://en.wikipedia.org/wiki/SomePage') + @crop = FactoryGirl.build(:tomato, en_wikipedia_url: 'http://en.wikipedia.org/wiki/SomePage') @crop.should be_valid end context 'varieties' do it 'has a crop hierarchy' do @tomato = FactoryGirl.create(:tomato) - @roma = FactoryGirl.create(:roma, :parent_id => @tomato.id) + @roma = FactoryGirl.create(:roma, parent_id: @tomato.id) @roma.parent.should eq @tomato @tomato.varieties.should eq [@roma] end it 'toplevel scope works' do @tomato = FactoryGirl.create(:tomato) - @roma = FactoryGirl.create(:roma, :parent_id => @tomato.id) + @roma = FactoryGirl.create(:roma, parent_id: @tomato.id) Crop.toplevel.should eq [ @tomato ] end end @@ -110,7 +110,7 @@ describe Crop do context 'photos' do it 'has a default photo' do @crop = FactoryGirl.create(:tomato) - @planting = FactoryGirl.create(:planting, :crop => @crop) + @planting = FactoryGirl.create(:planting, crop: @crop) @photo = FactoryGirl.create(:photo) @planting.photos << @photo @crop.default_photo.should be_an_instance_of Photo @@ -122,25 +122,25 @@ describe Crop do let(:crop) { FactoryGirl.create(:tomato) } it 'returns a hash of sunniness values' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) - planting4 = FactoryGirl.create(:shady_planting, :crop => crop) + planting1 = FactoryGirl.create(:sunny_planting, crop: crop) + planting2 = FactoryGirl.create(:sunny_planting, crop: crop) + planting3 = FactoryGirl.create(:semi_shady_planting, crop: crop) + planting4 = FactoryGirl.create(:shady_planting, crop: crop) crop.sunniness.should be_an_instance_of Hash end it 'counts each sunniness value' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) - planting4 = FactoryGirl.create(:shady_planting, :crop => crop) + planting1 = FactoryGirl.create(:sunny_planting, crop: crop) + planting2 = FactoryGirl.create(:sunny_planting, crop: crop) + planting3 = FactoryGirl.create(:semi_shady_planting, crop: crop) + planting4 = FactoryGirl.create(:shady_planting, crop: crop) crop.sunniness.should == { 'sun' => 2, 'shade' => 1, 'semi-shade' => 1 } end it 'ignores unused sunniness values' do - planting1 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting2 = FactoryGirl.create(:sunny_planting, :crop => crop) - planting3 = FactoryGirl.create(:semi_shady_planting, :crop => crop) + planting1 = FactoryGirl.create(:sunny_planting, crop: crop) + planting2 = FactoryGirl.create(:sunny_planting, crop: crop) + planting3 = FactoryGirl.create(:semi_shady_planting, crop: crop) crop.sunniness.should == { 'sun' => 2, 'semi-shade' => 1 } end end @@ -150,25 +150,25 @@ describe Crop do let(:crop) { FactoryGirl.create(:tomato) } it 'returns a hash of sunniness values' do - planting1 = FactoryGirl.create(:seed_planting, :crop => crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) - planting4 = FactoryGirl.create(:cutting_planting, :crop => crop) + planting1 = FactoryGirl.create(:seed_planting, crop: crop) + planting2 = FactoryGirl.create(:seed_planting, crop: crop) + planting3 = FactoryGirl.create(:seedling_planting, crop: crop) + planting4 = FactoryGirl.create(:cutting_planting, crop: crop) crop.planted_from.should be_an_instance_of Hash end it 'counts each planted_from value' do - planting1 = FactoryGirl.create(:seed_planting, :crop => crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) - planting4 = FactoryGirl.create(:cutting_planting, :crop => crop) + planting1 = FactoryGirl.create(:seed_planting, crop: crop) + planting2 = FactoryGirl.create(:seed_planting, crop: crop) + planting3 = FactoryGirl.create(:seedling_planting, crop: crop) + planting4 = FactoryGirl.create(:cutting_planting, crop: crop) crop.planted_from.should == { 'seed' => 2, 'seedling' => 1, 'cutting' => 1 } end it 'ignores unused planted_from values' do - planting1 = FactoryGirl.create(:seed_planting, :crop => crop) - planting2 = FactoryGirl.create(:seed_planting, :crop => crop) - planting3 = FactoryGirl.create(:seedling_planting, :crop => crop) + planting1 = FactoryGirl.create(:seed_planting, crop: crop) + planting2 = FactoryGirl.create(:seed_planting, crop: crop) + planting3 = FactoryGirl.create(:seedling_planting, crop: crop) crop.planted_from.should == { 'seed' => 2, 'seedling' => 1 } end end @@ -187,20 +187,20 @@ describe Crop do @root = FactoryGirl.create(:plant_part) @bulb = FactoryGirl.create(:plant_part) @harvest1 = FactoryGirl.create(:harvest, - :crop => crop, - :plant_part => @fruit + crop: crop, + plant_part: @fruit ) @harvest2 = FactoryGirl.create(:harvest, - :crop => crop, - :plant_part => @fruit + crop: crop, + plant_part: @fruit ) @harvest3 = FactoryGirl.create(:harvest, - :crop => crop, - :plant_part => @seed + crop: crop, + plant_part: @seed ) @harvest4 = FactoryGirl.create(:harvest, - :crop => crop, - :plant_part => @root + crop: crop, + plant_part: @root ) crop.popular_plant_parts.should == { @fruit => 2, @seed => 1, @root => 1 } end @@ -215,10 +215,10 @@ describe Crop do # they need 3+ plantings each to be interesting (1..3).each do - FactoryGirl.create(:planting, :crop => @crop1) + FactoryGirl.create(:planting, crop: @crop1) end (1..3).each do - FactoryGirl.create(:planting, :crop => @crop2) + FactoryGirl.create(:planting, crop: @crop2) end # crops need 3+ photos to be interesting @@ -242,7 +242,7 @@ describe Crop do # only crop1 has plantings (1..3).each do - FactoryGirl.create(:planting, :crop => @crop1) + FactoryGirl.create(:planting, crop: @crop1) end # ... and photos @@ -265,10 +265,10 @@ describe Crop do # both crops have plantings (1..3).each do - FactoryGirl.create(:planting, :crop => @crop1) + FactoryGirl.create(:planting, crop: @crop1) end (1..3).each do - FactoryGirl.create(:planting, :crop => @crop2) + FactoryGirl.create(:planting, crop: @crop2) end # but only crop1 has photos @@ -288,7 +288,7 @@ describe Crop do context "harvests" do it "has harvests" do crop = FactoryGirl.create(:crop) - harvest = FactoryGirl.create(:harvest, :crop => crop) + harvest = FactoryGirl.create(:harvest, crop: crop) crop.harvests.should eq [harvest] end end @@ -298,12 +298,12 @@ describe Crop do @pp1 = FactoryGirl.create(:plant_part) @pp2 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @h2 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp2 + crop: @maize, + plant_part: @pp2 ) @maize.plant_parts.should include @pp1 @maize.plant_parts.should include @pp2 @@ -313,19 +313,19 @@ describe Crop do @maize = FactoryGirl.create(:maize) @pp1 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @h2 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @maize.plant_parts.should eq [@pp1] end context "search" do - let(:mushroom) { FactoryGirl.create(:crop, :name => 'mushroom') } + let(:mushroom) { FactoryGirl.create(:crop, name: 'mushroom') } before do sync_elasticsearch([mushroom]) @@ -344,12 +344,12 @@ describe Crop do Crop.search('mUsH').should include mushroom end it "doesn't find 'rejected' crop" do - @rejected_crop = FactoryGirl.create(:rejected_crop, :name => 'tomato') + @rejected_crop = FactoryGirl.create(:rejected_crop, name: 'tomato') sync_elasticsearch([@rejected_crop]) Crop.search('tomato').should_not include @rejected_crop end it "doesn't find 'pending' crop" do - @crop_request = FactoryGirl.create(:crop_request, :name => 'tomato') + @crop_request = FactoryGirl.create(:crop_request, name: 'tomato') sync_elasticsearch([@crop_request]) Crop.search('tomato').should_not include @crop_request end @@ -374,12 +374,12 @@ describe Crop do end it "picks up scientific name from parent crop if available" do - parent = FactoryGirl.create(:crop, :name => 'parent crop') + parent = FactoryGirl.create(:crop, name: 'parent crop') parent.add_scientific_names_from_csv("Parentis cropis") parent.save parent.reload - tomato = FactoryGirl.create(:tomato, :parent => parent) + tomato = FactoryGirl.create(:tomato, parent: parent) expect(tomato.parent).to eq parent expect(tomato.parent.default_scientific_name).to eq "Parentis cropis" @@ -399,12 +399,12 @@ describe Crop do end it "doesn't add a duplicate scientific name from parent" do - parent = FactoryGirl.create(:crop, :name => 'parent') + parent = FactoryGirl.create(:crop, name: 'parent') parent.add_scientific_names_from_csv("Parentis cropis") parent.save parent.reload - tomato = FactoryGirl.create(:tomato, :parent => parent) + tomato = FactoryGirl.create(:tomato, parent: parent) expect(tomato.scientific_names.size).to eq 0 tomato.add_scientific_names_from_csv('') expect(tomato.scientific_names.size).to eq 1 # picks up parent SN @@ -509,7 +509,7 @@ describe Crop do end it "loads a crop with a parent" do - parent = FactoryGirl.create(:crop, :name => 'parent') + parent = FactoryGirl.create(:crop, name: 'parent') tomato_row = "tomato,http://en.wikipedia.org/wiki/Tomato,parent" CSV.parse(tomato_row) do |row| @@ -539,7 +539,7 @@ describe Crop do context "crop-post association" do let!(:tomato) { FactoryGirl.create(:tomato) } let!(:maize) { FactoryGirl.create(:maize) } - let!(:post) { FactoryGirl.create(:post, :body => "[maize](crop)[tomato](crop)[tomato](crop)") } + let!(:post) { FactoryGirl.create(:post, body: "[maize](crop)[tomato](crop)[tomato](crop)") } describe "destroying a crop" do before do @@ -557,8 +557,8 @@ describe Crop do end context "crop rejections" do - let!(:rejected_reason) { FactoryGirl.create(:crop, :name => 'tomato', :approval_status => 'rejected', :reason_for_rejection => 'not edible') } - let!(:rejected_other) { FactoryGirl.create(:crop, :name => 'tomato', :approval_status => 'rejected', :reason_for_rejection => 'other', :rejection_notes => 'blah blah blah') } + let!(:rejected_reason) { FactoryGirl.create(:crop, name: 'tomato', approval_status: 'rejected', reason_for_rejection: 'not edible') } + let!(:rejected_other) { FactoryGirl.create(:crop, name: 'tomato', approval_status: 'rejected', reason_for_rejection: 'other', rejection_notes: 'blah blah blah') } describe "rejecting a crop" do it "should give reason if a default option" do diff --git a/spec/models/follow_spec.rb b/spec/models/follow_spec.rb index 27b42de15..7bebbc7f3 100644 --- a/spec/models/follow_spec.rb +++ b/spec/models/follow_spec.rb @@ -9,13 +9,13 @@ describe Follow do it "sends a notification when a follow is created" do expect { - Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + Follow.create(follower_id: @member1.id, followed_id: @member2.id) }.to change(Notification, :count).by(1) end it "does not delete any members when follow is deleted" do expect { - follow = Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + follow = Follow.create(follower_id: @member1.id, followed_id: @member2.id) follow.destroy }.not_to change(Member, :count) end @@ -23,11 +23,11 @@ describe Follow do context "when follow is created" do before (:each) do - @follow = Follow.create(:follower_id => @member1.id, :followed_id => @member2.id) + @follow = Follow.create(follower_id: @member1.id, followed_id: @member2.id) end it "should not duplicate follows" do - expect(Follow.create(:follower_id => @member1.id, :followed_id => @member2.id)).not_to be_valid + expect(Follow.create(follower_id: @member1.id, followed_id: @member2.id)).not_to be_valid end it "should list users in following/follower collections when follow is created" do diff --git a/spec/models/forum_spec.rb b/spec/models/forum_spec.rb index 7c26c8f4b..72fafd31c 100644 --- a/spec/models/forum_spec.rb +++ b/spec/models/forum_spec.rb @@ -17,14 +17,14 @@ describe Forum do end it "has many posts" do - @post1 = FactoryGirl.create(:forum_post, :forum => forum) - @post2 = FactoryGirl.create(:forum_post, :forum => forum) + @post1 = FactoryGirl.create(:forum_post, forum: forum) + @post2 = FactoryGirl.create(:forum_post, forum: forum) forum.posts.size.should == 2 end it "orders posts in reverse chron order" do - @post1 = FactoryGirl.create(:forum_post, :forum => forum, :created_at => 2.days.ago) - @post2 = FactoryGirl.create(:forum_post, :forum => forum, :created_at => 1.day.ago) + @post1 = FactoryGirl.create(:forum_post, forum: forum, created_at: 2.days.ago) + @post2 = FactoryGirl.create(:forum_post, forum: forum, created_at: 1.day.ago) forum.posts.first.should eq @post2 end diff --git a/spec/models/garden_spec.rb b/spec/models/garden_spec.rb index ab52e2fac..1332e7287 100644 --- a/spec/models/garden_spec.rb +++ b/spec/models/garden_spec.rb @@ -3,7 +3,7 @@ require 'rails_helper' describe Garden do let(:owner) { FactoryGirl.create(:member) } - let(:garden) { FactoryGirl.create(:garden, :owner => owner) } + let(:garden) { FactoryGirl.create(:garden, owner: owner) } it "should have a slug" do garden.slug.should match(/member\d+-springfield-community-garden/) @@ -14,17 +14,17 @@ describe Garden do end it "doesn't allow a nil name" do - garden = FactoryGirl.build(:garden, :name => nil) + garden = FactoryGirl.build(:garden, name: nil) garden.should_not be_valid end it "doesn't allow a blank name" do - garden = FactoryGirl.build(:garden, :name => "") + garden = FactoryGirl.build(:garden, name: "") garden.should_not be_valid end it "doesn't allow a name with only spaces" do - garden = FactoryGirl.build(:garden, :name => " ") + garden = FactoryGirl.build(:garden, name: " ") garden.should_not be_valid end @@ -46,31 +46,31 @@ describe Garden do let(:walnut) { FactoryGirl.create(:walnut) } it "should fetch < 4 featured plantings if insufficient exist" do - @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) - @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) + @p1 = FactoryGirl.create(:planting, crop: tomato, garden: garden) + @p2 = FactoryGirl.create(:planting, crop: maize, garden: garden) garden.featured_plantings.should eq [@p2, @p1] end it "should fetch most recent 4 featured plantings" do - @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) - @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) - @p3 = FactoryGirl.create(:planting, :crop => chard, :garden => garden) - @p4 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) - @p5 = FactoryGirl.create(:planting, :crop => walnut, :garden => garden) + @p1 = FactoryGirl.create(:planting, crop: tomato, garden: garden) + @p2 = FactoryGirl.create(:planting, crop: maize, garden: garden) + @p3 = FactoryGirl.create(:planting, crop: chard, garden: garden) + @p4 = FactoryGirl.create(:planting, crop: apple, garden: garden) + @p5 = FactoryGirl.create(:planting, crop: walnut, garden: garden) garden.featured_plantings.should eq [@p5, @p4, @p3, @p2] end it "should skip repeated plantings" do - @p1 = FactoryGirl.create(:planting, :crop => tomato, :garden => garden) - @p2 = FactoryGirl.create(:planting, :crop => maize, :garden => garden) - @p3 = FactoryGirl.create(:planting, :crop => chard, :garden => garden) - @p4 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) - @p5 = FactoryGirl.create(:planting, :crop => walnut, :garden => garden) - @p6 = FactoryGirl.create(:planting, :crop => apple, :garden => garden) - @p7 = FactoryGirl.create(:planting, :crop => pear, :garden => garden) + @p1 = FactoryGirl.create(:planting, crop: tomato, garden: garden) + @p2 = FactoryGirl.create(:planting, crop: maize, garden: garden) + @p3 = FactoryGirl.create(:planting, crop: chard, garden: garden) + @p4 = FactoryGirl.create(:planting, crop: apple, garden: garden) + @p5 = FactoryGirl.create(:planting, crop: walnut, garden: garden) + @p6 = FactoryGirl.create(:planting, crop: apple, garden: garden) + @p7 = FactoryGirl.create(:planting, crop: pear, garden: garden) garden.featured_plantings.should eq [@p7, @p6, @p5, @p3] end @@ -85,9 +85,9 @@ describe Garden do end it "destroys plantings when deleted" do - garden = FactoryGirl.create(:garden, :owner => owner) - @planting1 = FactoryGirl.create(:planting, :garden => garden) - @planting2 = FactoryGirl.create(:planting, :garden => garden) + garden = FactoryGirl.create(:garden, owner: owner) + @planting1 = FactoryGirl.create(:planting, garden: garden) + @planting2 = FactoryGirl.create(:planting, garden: garden) garden.plantings.size.should == 2 all = Planting.count garden.destroy @@ -96,37 +96,37 @@ describe Garden do context 'area' do it 'allows numeric area' do - garden = FactoryGirl.build(:garden, :area => 33) + garden = FactoryGirl.build(:garden, area: 33) garden.should be_valid end it "doesn't allow negative area" do - garden = FactoryGirl.build(:garden, :area => -5) + garden = FactoryGirl.build(:garden, area: -5) garden.should_not be_valid end it 'allows decimal quantities' do - garden = FactoryGirl.build(:garden, :area => 3.3) + garden = FactoryGirl.build(:garden, area: 3.3) garden.should be_valid end it 'allows blank quantities' do - garden = FactoryGirl.build(:garden, :area => '') + garden = FactoryGirl.build(:garden, area: '') garden.should be_valid end it 'allows nil quantities' do - garden = FactoryGirl.build(:garden, :area => nil) + garden = FactoryGirl.build(:garden, area: nil) garden.should be_valid end it 'cleans up zero quantities' do - garden = FactoryGirl.build(:garden, :area => 0) + garden = FactoryGirl.build(:garden, area: 0) garden.area.should == 0 end it "doesn't allow non-numeric quantities" do - garden = FactoryGirl.build(:garden, :area => "99a") + garden = FactoryGirl.build(:garden, area: "99a") garden.should_not be_valid end end @@ -134,19 +134,19 @@ describe Garden do context 'units' do Garden::AREA_UNITS_VALUES.values.push(nil, '').each do |s| it "#{s} should be a valid unit" do - garden = FactoryGirl.build(:garden, :area_unit => s) + garden = FactoryGirl.build(:garden, area_unit: s) garden.should be_valid end end it 'should refuse invalid unit values' do - garden = FactoryGirl.build(:garden, :area_unit => 'not valid') + garden = FactoryGirl.build(:garden, area_unit: 'not valid') garden.should_not be_valid garden.errors[:area_unit].should include("not valid is not a valid area unit") end it 'sets area unit to blank if area is blank' do - garden = FactoryGirl.build(:garden, :area => '', :area_unit => 'acre') + garden = FactoryGirl.build(:garden, area: '', area_unit: 'acre') garden.should be_valid garden.area_unit.should eq nil end @@ -169,8 +169,8 @@ describe Garden do it "marks plantings as finished when garden is inactive" do garden = FactoryGirl.create(:garden) - p1 = FactoryGirl.create(:planting, :garden => garden) - p2 = FactoryGirl.create(:planting, :garden => garden) + p1 = FactoryGirl.create(:planting, garden: garden) + p2 = FactoryGirl.create(:planting, garden: garden) p1.finished.should eq false p2.finished.should eq false @@ -187,8 +187,8 @@ describe Garden do it "doesn't mark the wrong plantings as finished" do g1 = FactoryGirl.create(:garden) g2 = FactoryGirl.create(:garden) - p1 = FactoryGirl.create(:planting, :garden => g1) - p2 = FactoryGirl.create(:planting, :garden => g2) + p1 = FactoryGirl.create(:planting, garden: g1) + p2 = FactoryGirl.create(:planting, garden: g2) # mark the garden as inactive g1.active = false diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index f8e2c4f5a..583363aa2 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -14,32 +14,32 @@ describe Harvest do context 'quantity' do it 'allows numeric quantities' do - @harvest = FactoryGirl.build(:harvest, :quantity => 33) + @harvest = FactoryGirl.build(:harvest, quantity: 33) @harvest.should be_valid end it 'allows decimal quantities' do - @harvest = FactoryGirl.build(:harvest, :quantity => 3.3) + @harvest = FactoryGirl.build(:harvest, quantity: 3.3) @harvest.should be_valid end it 'allows blank quantities' do - @harvest = FactoryGirl.build(:harvest, :quantity => '') + @harvest = FactoryGirl.build(:harvest, quantity: '') @harvest.should be_valid end it 'allows nil quantities' do - @harvest = FactoryGirl.build(:harvest, :quantity => nil) + @harvest = FactoryGirl.build(:harvest, quantity: nil) @harvest.should be_valid end it 'cleans up zero quantities' do - @harvest = FactoryGirl.build(:harvest, :quantity => 0) + @harvest = FactoryGirl.build(:harvest, quantity: 0) @harvest.quantity.should == 0 end it "doesn't allow non-numeric quantities" do - @harvest = FactoryGirl.build(:harvest, :quantity => "99a") + @harvest = FactoryGirl.build(:harvest, quantity: "99a") @harvest.should_not be_valid end end @@ -47,19 +47,19 @@ describe Harvest do context 'units' do it 'all valid units should work' do ['individual','bunch','sprig','handful','litre','pint','quart','bucket','basket','bushel', nil, ''].each do |s| - @harvest = FactoryGirl.build(:harvest, :unit => s) + @harvest = FactoryGirl.build(:harvest, unit: s) @harvest.should be_valid end end it 'should refuse invalid unit values' do - @harvest = FactoryGirl.build(:harvest, :unit => 'not valid') + @harvest = FactoryGirl.build(:harvest, unit: 'not valid') @harvest.should_not be_valid @harvest.errors[:unit].should include("not valid is not a valid unit") end it 'sets unit to blank if quantity is blank' do - @harvest = FactoryGirl.build(:harvest, :quantity => '', :unit => 'individual') + @harvest = FactoryGirl.build(:harvest, quantity: '', unit: 'individual') @harvest.should be_valid @harvest.unit.should eq nil end @@ -67,32 +67,32 @@ describe Harvest do context 'weight quantity' do it 'allows numeric weight quantities' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => 33) + @harvest = FactoryGirl.build(:harvest, weight_quantity: 33) @harvest.should be_valid end it 'allows decimal weight quantities' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => 3.3) + @harvest = FactoryGirl.build(:harvest, weight_quantity: 3.3) @harvest.should be_valid end it 'allows blank weight quantities' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => '') + @harvest = FactoryGirl.build(:harvest, weight_quantity: '') @harvest.should be_valid end it 'allows nil weight quantities' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => nil) + @harvest = FactoryGirl.build(:harvest, weight_quantity: nil) @harvest.should be_valid end it 'cleans up zero quantities' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => 0) + @harvest = FactoryGirl.build(:harvest, weight_quantity: 0) @harvest.weight_quantity.should == 0 end it "doesn't allow non-numeric weight quantities" do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => "99a") + @harvest = FactoryGirl.build(:harvest, weight_quantity: "99a") @harvest.should_not be_valid end end @@ -100,19 +100,19 @@ describe Harvest do context 'weight units' do it 'all valid units should work' do ['kg', 'lb', 'oz', nil, ''].each do |s| - @harvest = FactoryGirl.build(:harvest, :weight_unit => s) + @harvest = FactoryGirl.build(:harvest, weight_unit: s) @harvest.should be_valid end end it 'should refuse invalid weight unit values' do - @harvest = FactoryGirl.build(:harvest, :weight_unit => 'not valid') + @harvest = FactoryGirl.build(:harvest, weight_unit: 'not valid') @harvest.should_not be_valid @harvest.errors[:weight_unit].should include("not valid is not a valid unit") end it 'sets weight_unit to blank if quantity is blank' do - @harvest = FactoryGirl.build(:harvest, :weight_quantity => '', :weight_unit => 'kg') + @harvest = FactoryGirl.build(:harvest, weight_quantity: '', weight_unit: 'kg') @harvest.should be_valid @harvest.weight_unit.should eq nil end @@ -120,19 +120,19 @@ describe Harvest do context "standardized weights" do it 'converts from pounds' do - @harvest = FactoryGirl.create(:harvest, :weight_quantity => 2, :weight_unit => "lb") + @harvest = FactoryGirl.create(:harvest, weight_quantity: 2, weight_unit: "lb") @harvest.should be_valid @harvest.reload.si_weight.should eq 0.907 end it 'converts from ounces' do - @harvest = FactoryGirl.create(:harvest, :weight_quantity => 16, :weight_unit => "oz") + @harvest = FactoryGirl.create(:harvest, weight_quantity: 16, weight_unit: "oz") @harvest.should be_valid @harvest.reload.si_weight.should eq 0.454 end it 'leaves kg alone' do - @harvest = FactoryGirl.create(:harvest, :weight_quantity => 2, :weight_unit => "kg") + @harvest = FactoryGirl.create(:harvest, weight_quantity: 2, weight_unit: "kg") @harvest.should be_valid @harvest.reload.si_weight.should eq 2.0 end @@ -140,92 +140,92 @@ describe Harvest do context 'ordering' do it 'lists most recent harvests first' do - @h1 = FactoryGirl.create(:harvest, :created_at => 1.day.ago) - @h2 = FactoryGirl.create(:harvest, :created_at => 1.hour.ago) + @h1 = FactoryGirl.create(:harvest, created_at: 1.day.ago) + @h2 = FactoryGirl.create(:harvest, created_at: 1.hour.ago) Harvest.all.should eq [@h2, @h1] end end context "stringification" do - let(:crop) { FactoryGirl.create(:crop, :name => "apricot") } + let(:crop) { FactoryGirl.create(:crop, name: "apricot") } it "apricots" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => nil, - :unit => nil, - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: nil, + unit: nil, + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "apricots" end it "1 individual apricot" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 1, - :unit => 'individual', - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 1, + unit: 'individual', + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "1 individual apricot" end it "10 individual apricots" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 10, - :unit => 'individual', - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 10, + unit: 'individual', + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "10 individual apricots" end it "1 bushel of apricots" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 1, - :unit => 'bushel', - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 1, + unit: 'bushel', + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "1 bushel of apricots" end it "1.5 bushels of apricots" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 1.5, - :unit => 'bushel', - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 1.5, + unit: 'bushel', + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "1.5 bushels of apricots" end it "10 bushels of apricots" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 10, - :unit => 'bushel', - :weight_quantity => nil, - :weight_unit => nil + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 10, + unit: 'bushel', + weight_quantity: nil, + weight_unit: nil ) @h.to_s.should eq "10 bushels of apricots" end it "apricots weighing 1.2 kg" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => nil, - :unit => nil, - :weight_quantity => 1.2, - :weight_unit => 'kg' + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: nil, + unit: nil, + weight_quantity: 1.2, + weight_unit: 'kg' ) @h.to_s.should eq "apricots weighing 1.2 kg" end it "10 bushels of apricots weighing 100 kg" do - @h = FactoryGirl.create(:harvest, :crop => crop, - :quantity => 10, - :unit => 'bushel', - :weight_quantity => 100, - :weight_unit => 'kg') + @h = FactoryGirl.create(:harvest, crop: crop, + quantity: 10, + unit: 'bushel', + weight_quantity: 100, + weight_unit: 'kg') @h.to_s.should eq "10 bushels of apricots weighing 100 kg" end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 93760a904..dfb413df0 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -45,7 +45,7 @@ describe 'member' do end it 'should be able to fetch posts' do - @post = FactoryGirl.create(:post, :author => member) + @post = FactoryGirl.create(:post, author: member) member.posts.should eq [@post] end @@ -54,39 +54,39 @@ describe 'member' do end it 'has many plantings' do - @planting = FactoryGirl.create(:planting, :owner => member) + @planting = FactoryGirl.create(:planting, owner: member) member.plantings.size.should eq 1 end it "has many comments" do - @comment1 = FactoryGirl.create(:comment, :author => member) - @comment2 = FactoryGirl.create(:comment, :author => member) + @comment1 = FactoryGirl.create(:comment, author: member) + @comment2 = FactoryGirl.create(:comment, author: member) member.comments.size.should == 2 end it "has many forums" do - @forum1 = FactoryGirl.create(:forum, :owner => member) - @forum2 = FactoryGirl.create(:forum, :owner => member) + @forum1 = FactoryGirl.create(:forum, owner: member) + @forum2 = FactoryGirl.create(:forum, owner: member) member.forums.size.should == 2 end it 'has location and lat/long fields' do - member.update_attributes(:location => 'Greenwich, UK') + member.update_attributes(location: 'Greenwich, UK') member.location.should eq 'Greenwich, UK' member.latitude.round(2).should eq 51.48 member.longitude.round(2).should eq 0.00 end it 'empties the lat/long if location removed' do - member.update_attributes(:location => 'Greenwich, UK') - member.update_attributes(:location => '') + member.update_attributes(location: 'Greenwich, UK') + member.update_attributes(location: '') member.location.should eq '' member.latitude.should be_nil member.longitude.should be_nil end it 'fails gracefully for unfound locations' do - member.update_attributes(:location => 'Tatooine') + member.update_attributes(location: 'Tatooine') member.location.should eq 'Tatooine' member.latitude.should be_nil member.longitude.should be_nil @@ -114,15 +114,15 @@ describe 'member' do context 'same :login_name' do it "should not allow two members with the same login_name" do - FactoryGirl.create(:member, :login_name => "bob") - member = FactoryGirl.build(:member, :login_name => "bob") + FactoryGirl.create(:member, login_name: "bob") + member = FactoryGirl.build(:member, login_name: "bob") member.should_not be_valid member.errors[:login_name].should include("has already been taken") end it "tests uniqueness case-insensitively" do - FactoryGirl.create(:member, :login_name => "bob") - member = FactoryGirl.build(:member, :login_name => "BoB") + FactoryGirl.create(:member, login_name: "bob") + member = FactoryGirl.build(:member, login_name: "BoB") member.should_not be_valid member.errors[:login_name].should include("has already been taken") end @@ -130,7 +130,7 @@ describe 'member' do context 'case sensitivity' do it 'preserves case of login name' do - member = FactoryGirl.create(:member, :login_name => "BOB") + member = FactoryGirl.create(:member, login_name: "BOB") check = Member.find('bob') check.login_name.should eq 'BOB' end @@ -138,8 +138,8 @@ describe 'member' do context 'ordering' do it "should be sorted by name" do - z = FactoryGirl.create(:member, :login_name => "Zoe") - a = FactoryGirl.create(:member, :login_name => "Anna") + z = FactoryGirl.create(:member, login_name: "Zoe") + a = FactoryGirl.create(:member, login_name: "Anna") Member.first.should == a end end @@ -208,7 +208,7 @@ describe 'member' do it 'converts role names properly' do # need to make sure spaces get turned to underscores - @role = FactoryGirl.create(:role, :name => "a b c") + @role = FactoryGirl.create(:role, name: "a b c") member.roles << @role member.has_role?(:a_b_c).should eq true end @@ -246,7 +246,7 @@ describe 'member' do @london_member = FactoryGirl.create(:london_member) @london_member.latitude = nil @london_member.longitude = nil - @london_member.save(:validate => false) + @london_member.save(validate: false) Member.located.should_not include @london_member end end @@ -273,7 +273,7 @@ describe 'member' do @member4 = FactoryGirl.create(:unconfirmed_member) [@member1, @member2, @member3, @member4].each do |m| - FactoryGirl.create(:planting, :owner => m) + FactoryGirl.create(:planting, owner: m) end @member1.updated_at = 3.days.ago @@ -289,15 +289,15 @@ describe 'member' do context 'orders' do it 'finds the current order' do @member = FactoryGirl.create(:member) - @order1 = FactoryGirl.create(:completed_order, :member => @member) - @order2 = FactoryGirl.create(:order, :member => @member) + @order1 = FactoryGirl.create(:completed_order, member: @member) + @order2 = FactoryGirl.create(:order, member: @member) @member.current_order.should eq @order2 end it "copes if there's no current order" do @member = FactoryGirl.create(:member) - @order1 = FactoryGirl.create(:completed_order, :member => @member) - @order2 = FactoryGirl.create(:completed_order, :member => @member) + @order1 = FactoryGirl.create(:completed_order, member: @member) + @order2 = FactoryGirl.create(:completed_order, member: @member) @member.current_order.should be_nil end end @@ -308,14 +308,14 @@ describe 'member' do it "recognises a permanent paid account" do @account_type = FactoryGirl.create(:account_type, - :is_paid => true, :is_permanent_paid => true) + is_paid: true, is_permanent_paid: true) member.account.account_type = @account_type member.is_paid?.should be(true) end it "recognises a current paid account" do @account_type = FactoryGirl.create(:account_type, - :is_paid => true, :is_permanent_paid => false) + is_paid: true, is_permanent_paid: false) member.account.account_type = @account_type member.account.paid_until = Time.zone.now + 1.month member.is_paid?.should be(true) @@ -323,7 +323,7 @@ describe 'member' do it "recognises an expired paid account" do @account_type = FactoryGirl.create(:account_type, - :is_paid => true, :is_permanent_paid => false) + is_paid: true, is_permanent_paid: false) member.account.account_type = @account_type member.account.paid_until = Time.zone.now - 1.minute member.is_paid?.should be(false) @@ -331,14 +331,14 @@ describe 'member' do it "recognises a free account" do @account_type = FactoryGirl.create(:account_type, - :is_paid => false, :is_permanent_paid => false) + is_paid: false, is_permanent_paid: false) member.account.account_type = @account_type member.is_paid?.should be(false) end it "recognises a free account even with paid_until set" do @account_type = FactoryGirl.create(:account_type, - :is_paid => false, :is_permanent_paid => false) + is_paid: false, is_permanent_paid: false) member.account.account_type = @account_type member.account.paid_until = Time.zone.now + 1.month member.is_paid?.should be(false) @@ -349,7 +349,7 @@ describe 'member' do context "update account" do let(:product) { FactoryGirl.create(:product, - :paid_months => 3 + paid_months: 3 )} let(:member) { FactoryGirl.create(:member) } @@ -374,7 +374,7 @@ describe 'member' do context 'harvests' do it 'has harvests' do member = FactoryGirl.create(:member) - harvest = FactoryGirl.create(:harvest, :owner => member) + harvest = FactoryGirl.create(:harvest, owner: member) member.harvests.should eq [harvest] end end @@ -387,7 +387,7 @@ describe 'member' do let(:member3) { FactoryGirl.create(:member) } before do - @follow = member1.follows.create(:follower_id => member1.id, :followed_id => member2.id) + @follow = member1.follows.create(follower_id: member1.id, followed_id: member2.id) end context 'already_following' do diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index d14f731d1..e38444d5d 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -18,15 +18,15 @@ describe Notification do it "has a scope for unread" do Notification.unread.should eq [notification] - @n2 = FactoryGirl.create(:notification, :read => true) + @n2 = FactoryGirl.create(:notification, read: true) Notification.unread.should eq [notification] - @n3 = FactoryGirl.create(:notification, :read => false) + @n3 = FactoryGirl.create(:notification, read: false) Notification.unread.should eq [@n3, notification] end it "counts unread" do @who = notification.recipient - @n2 = FactoryGirl.create(:notification, :recipient => @who, :read => false) + @n2 = FactoryGirl.create(:notification, recipient: @who, read: false) @who.notifications.unread_count.should eq 2 end @@ -48,12 +48,12 @@ describe Notification do end it "replaces missing subjects with (no subject)" do - notification = FactoryGirl.create(:notification, :subject => nil) + notification = FactoryGirl.create(:notification, subject: nil) notification.subject.should == "(no subject)" end it "replaces whitespace-only subjects with (no subject)" do - notification = FactoryGirl.create(:notification, :subject => " ") + notification = FactoryGirl.create(:notification, subject: " ") notification.subject.should == "(no subject)" end diff --git a/spec/models/order_item_spec.rb b/spec/models/order_item_spec.rb index bd3b8f195..67f86415c 100644 --- a/spec/models/order_item_spec.rb +++ b/spec/models/order_item_spec.rb @@ -11,17 +11,17 @@ describe OrderItem do it "validates price > product.min_price" do @product = FactoryGirl.create(:product) - order_item = FactoryGirl.build(:order_item, :price => @product.min_price - 1) + order_item = FactoryGirl.build(:order_item, price: @product.min_price - 1) order_item.should_not be_valid end it "doesn't let you add two items to an order" do @product = FactoryGirl.create(:product) @order = FactoryGirl.create(:order) - order_item = FactoryGirl.build(:order_item, :order => @order) + order_item = FactoryGirl.build(:order_item, order: @order) order_item.should be_valid order_item.save - @order_item2 = FactoryGirl.build(:order_item, :order => @order) + @order_item2 = FactoryGirl.build(:order_item, order: @order) @order_item2.should_not be_valid end diff --git a/spec/models/order_spec.rb b/spec/models/order_spec.rb index 50fb6f949..9291e1a3f 100644 --- a/spec/models/order_spec.rb +++ b/spec/models/order_spec.rb @@ -5,7 +5,7 @@ describe Order do @order = FactoryGirl.create(:order) @product = FactoryGirl.create(:product) @order_item = FactoryGirl.create(:order_item, - :order_id => @order.id, :product_id => @product.id) + order_id: @order.id, product_id: @product.id) end it 'has order_items' do @@ -19,14 +19,14 @@ describe Order do it 'updates the account details' do @member = FactoryGirl.create(:member) - @order = FactoryGirl.create(:order, :member => @member) - @account_type = FactoryGirl.create(:account_type, :name => 'paid') + @order = FactoryGirl.create(:order, member: @member) + @account_type = FactoryGirl.create(:account_type, name: 'paid') @product = FactoryGirl.create(:product, - :account_type => @account_type, - :paid_months => 3 + account_type: @account_type, + paid_months: 3 ) @order_item = FactoryGirl.create(:order_item, - :order_id => @order.id, :product_id => @product.id) + order_id: @order.id, product_id: @product.id) @member.account.paid_until.should be_nil @@ -38,48 +38,48 @@ describe Order do it "totals the amount due" do @member = FactoryGirl.create(:member) - @order = FactoryGirl.create(:order, :member => @member) + @order = FactoryGirl.create(:order, member: @member) @product = FactoryGirl.create(:product, - :min_price => 1000 + min_price: 1000 ) # we force an order to only have one item at present. Add more if wanted # later. @order_item1 = FactoryGirl.create(:order_item, - :order_id => @order.id, :product_id => @product.id, :price => 1111, :quantity => 1) + order_id: @order.id, product_id: @product.id, price: 1111, quantity: 1) @order.total.should eq 1111 end it "gives the correct total for quantities more than 1" do @member = FactoryGirl.create(:member) - @order = FactoryGirl.create(:order, :member => @member) + @order = FactoryGirl.create(:order, member: @member) @product = FactoryGirl.create(:product, - :min_price => 1000 + min_price: 1000 ) # we force an order to only have one item at present. Add more if wanted # later. @order_item1 = FactoryGirl.create(:order_item, - :order_id => @order.id, :product_id => @product.id, :price => 1111, :quantity => 2) + order_id: @order.id, product_id: @product.id, price: 1111, quantity: 2) @order.total.should eq 2222 end it "formats order items for activemerchant" do @member = FactoryGirl.create(:member) - @order = FactoryGirl.create(:order, :member => @member) + @order = FactoryGirl.create(:order, member: @member) @product = FactoryGirl.create(:product, - :name => 'foo', - :min_price => 1000 + name: 'foo', + min_price: 1000 ) # we force an order to only have one item at present. Add more if wanted # later. @order_item1 = FactoryGirl.create(:order_item, - :order_id => @order.id, :product_id => @product.id, :price => 1111, :quantity => 1) + order_id: @order.id, product_id: @product.id, price: 1111, quantity: 1) @order.activemerchant_items.should eq [{ - :name => 'foo', - :quantity => 1, - :amount => 1111 + name: 'foo', + quantity: 1, + amount: 1111 }] end @@ -91,12 +91,12 @@ describe Order do end it "validates referral codes" do - referred_order = FactoryGirl.build(:order, :referral_code => 'CAMP_AIGN1?') + referred_order = FactoryGirl.build(:order, referral_code: 'CAMP_AIGN1?') referred_order.should_not be_valid end it "cleans up messy referral codes" do - referred_order = FactoryGirl.create(:order, :referral_code => 'CaMpAiGn 1 ') + referred_order = FactoryGirl.create(:order, referral_code: 'CaMpAiGn 1 ') referred_order.referral_code.should eq 'CAMPAIGN1' end end @@ -104,27 +104,27 @@ describe Order do context 'search' do it 'finds orders by member' do order = FactoryGirl.create(:order) - Order.search(:by => 'member', :for => order.member.login_name).should eq [order] + Order.search(by: 'member', for: order.member.login_name).should eq [order] end it 'finds orders by order_id' do order = FactoryGirl.create(:order) - Order.search(:by => 'order_id', :for => order.id).should eq [order] + Order.search(by: 'order_id', for: order.id).should eq [order] end it 'finds orders by paypal_token' do - order = FactoryGirl.create(:order, :paypal_express_token => 'foo') - Order.search(:by => 'paypal_token', :for => 'foo').should eq [order] + order = FactoryGirl.create(:order, paypal_express_token: 'foo') + Order.search(by: 'paypal_token', for: 'foo').should eq [order] end it 'finds orders by paypal_payer_id' do - order = FactoryGirl.create(:order, :paypal_express_payer_id => 'bar') - Order.search(:by => 'paypal_payer_id', :for => 'bar').should eq [order] + order = FactoryGirl.create(:order, paypal_express_payer_id: 'bar') + Order.search(by: 'paypal_payer_id', for: 'bar').should eq [order] end it 'finds orders by referral_code' do - order = FactoryGirl.create(:order, :referral_code => 'baz') - Order.search(:by => 'referral_code', :for => 'baz').should eq [order] + order = FactoryGirl.create(:order, referral_code: 'baz') + Order.search(by: 'referral_code', for: 'baz').should eq [order] end end diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index 36a9eb068..bd6335be2 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -115,7 +115,7 @@ describe Photo do # which was epistemologically unsatisfactory. # So we're just going to test that the method exists. it 'exists' do - photo = Photo.new(:owner_id => 1) + photo = Photo.new(owner_id: 1) photo.should.respond_to? :flickr_metadata end end diff --git a/spec/models/plant_part_spec.rb b/spec/models/plant_part_spec.rb index 30e118af8..ef3705ef2 100644 --- a/spec/models/plant_part_spec.rb +++ b/spec/models/plant_part_spec.rb @@ -11,12 +11,12 @@ describe PlantPart do @tomato = FactoryGirl.create(:tomato) @pp1 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, - :crop => @tomato, - :plant_part => @pp1 + crop: @tomato, + plant_part: @pp1 ) @h2 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @pp1.crops.should include @tomato @pp1.crops.should include @maize @@ -26,12 +26,12 @@ describe PlantPart do @maize = FactoryGirl.create(:maize) @pp1 = FactoryGirl.create(:plant_part) @h1 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @h2 = FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp1 + crop: @maize, + plant_part: @pp1 ) @pp1.crops.should eq [@maize] end diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 9f48766be..3663f8c29 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -4,9 +4,9 @@ describe Planting do let(:crop) { FactoryGirl.create(:tomato) } let(:garden_owner) { FactoryGirl.create(:member) } - let(:garden) { FactoryGirl.create(:garden, :owner => garden_owner) } + let(:garden) { FactoryGirl.create(:garden, owner: garden_owner) } let(:planting) { FactoryGirl.create(:planting, - :crop => crop, :garden => garden)} + crop: crop, garden: garden)} it 'has an owner' do planting.owner.should be_an_instance_of Member @@ -100,24 +100,24 @@ describe Planting do context 'quantity' do it 'allows integer quantities' do - @planting = FactoryGirl.build(:planting, :quantity => 99) + @planting = FactoryGirl.build(:planting, quantity: 99) @planting.should be_valid end it "doesn't allow decimal quantities" do - @planting = FactoryGirl.build(:planting, :quantity => 99.9) + @planting = FactoryGirl.build(:planting, quantity: 99.9) @planting.should_not be_valid end it "doesn't allow non-numeric quantities" do - @planting = FactoryGirl.build(:planting, :quantity => 'foo') + @planting = FactoryGirl.build(:planting, quantity: 'foo') @planting.should_not be_valid end it "allows blank quantities" do - @planting = FactoryGirl.build(:planting, :quantity => nil) + @planting = FactoryGirl.build(:planting, quantity: nil) @planting.should be_valid - @planting = FactoryGirl.build(:planting, :quantity => '') + @planting = FactoryGirl.build(:planting, quantity: '') @planting.should be_valid end end @@ -132,13 +132,13 @@ describe Planting do it 'all three valid sunniness values should work' do ['sun', 'shade', 'semi-shade', nil, ''].each do |s| - @planting = FactoryGirl.build(:planting, :sunniness => s) + @planting = FactoryGirl.build(:planting, sunniness: s) @planting.should be_valid end end it 'should refuse invalid sunniness values' do - @planting = FactoryGirl.build(:planting, :sunniness => 'not valid') + @planting = FactoryGirl.build(:planting, sunniness: 'not valid') @planting.should_not be_valid @planting.errors[:sunniness].should include("not valid is not a valid sunniness value") end @@ -154,13 +154,13 @@ describe Planting do ['seed', 'seedling', 'cutting', 'root division', 'runner', 'bare root plant', 'advanced plant', 'graft', 'layering', 'bulb', 'root/tuber', nil, ''].each do |p| - @planting = FactoryGirl.build(:planting, :planted_from => p) + @planting = FactoryGirl.build(:planting, planted_from: p) @planting.should be_valid end end it 'should refuse invalid planted_from values' do - @planting = FactoryGirl.build(:planting, :planted_from => 'not valid') + @planting = FactoryGirl.build(:planting, planted_from: 'not valid') @planting.should_not be_valid @planting.errors[:planted_from].should include("not valid is not a valid planting method") end @@ -202,10 +202,10 @@ describe Planting do it 'picks up interesting plantings' do # plantings have members created implicitly for them # each member is different, hence these are all interesting - @planting1 = FactoryGirl.create(:planting, :created_at => 5.days.ago) - @planting2 = FactoryGirl.create(:planting, :created_at => 4.days.ago) - @planting3 = FactoryGirl.create(:planting, :created_at => 3.days.ago) - @planting4 = FactoryGirl.create(:planting, :created_at => 2.days.ago) + @planting1 = FactoryGirl.create(:planting, created_at: 5.days.ago) + @planting2 = FactoryGirl.create(:planting, created_at: 4.days.ago) + @planting3 = FactoryGirl.create(:planting, created_at: 3.days.ago) + @planting4 = FactoryGirl.create(:planting, created_at: 2.days.ago) # plantings need photos to be interesting @photo = FactoryGirl.create(:photo) @@ -238,14 +238,14 @@ describe Planting do it 'ignores plantings with the same owner' do # this planting is older - @planting1 = FactoryGirl.create(:planting, :created_at => 1.day.ago) + @planting1 = FactoryGirl.create(:planting, created_at: 1.day.ago) @planting1.photos << FactoryGirl.create(:photo) @planting1.save # this one is newer, and has the same owner, through the garden @planting2 = FactoryGirl.create(:planting, - :created_at => 1.minute.ago, - :owner_id => @planting1.owner.id + created_at: 1.minute.ago, + owner_id: @planting1.owner.id ) @planting2.photos << FactoryGirl.create(:photo) @planting2.save @@ -304,18 +304,17 @@ describe Planting do context "finished date validation" do it 'requires finished date after planting date' do - @f = FactoryGirl.build(:finished_planting, :planted_at => - '2014-01-01', :finished_at => '2013-01-01') + @f = FactoryGirl.build(:finished_planting, planted_at: '2014-01-01', finished_at: '2013-01-01') @f.should_not be_valid end it 'allows just the planted date' do - @f = FactoryGirl.build(:planting, :planted_at => '2013-01-01', :finished_at => nil) + @f = FactoryGirl.build(:planting, planted_at: '2013-01-01', finished_at: nil) @f.should be_valid end it 'allows just the finished date' do - @f = FactoryGirl.build(:planting, :finished_at => '2013-01-01', :planted_at => nil) + @f = FactoryGirl.build(:planting, finished_at: '2013-01-01', planted_at: nil) @f.should be_valid end end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 61eb24bc1..45a37c47b 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -6,20 +6,20 @@ describe Post do it "should be sorted in reverse order" do FactoryGirl.create(:post, - :subject => 'first entry', - :author => member, - :created_at => 2.days.ago + subject: 'first entry', + author: member, + created_at: 2.days.ago ) FactoryGirl.create(:post, - :subject => 'second entry', - :author => member, - :created_at => 1.day.ago + subject: 'second entry', + author: member, + created_at: 1.day.ago ) Post.first.subject.should == "second entry" end it "should have a slug" do - @post = FactoryGirl.create(:post, :author => member) + @post = FactoryGirl.create(:post, author: member) @time = @post.created_at @datestr = @time.strftime("%Y%m%d") # 2 digit day and month, full-length years @@ -29,16 +29,16 @@ describe Post do end it "has many comments" do - @post = FactoryGirl.create(:post, :author => member) - @comment1 = FactoryGirl.create(:comment, :post => @post) - @comment2 = FactoryGirl.create(:comment, :post => @post) + @post = FactoryGirl.create(:post, author: member) + @comment1 = FactoryGirl.create(:comment, post: @post) + @comment2 = FactoryGirl.create(:comment, post: @post) @post.comments.size.should == 2 end it "destroys comments when deleted" do - @post = FactoryGirl.create(:post, :author => member) - @comment1 = FactoryGirl.create(:comment, :post => @post) - @comment2 = FactoryGirl.create(:comment, :post => @post) + @post = FactoryGirl.create(:post, author: member) + @comment1 = FactoryGirl.create(:comment, post: @post) + @comment2 = FactoryGirl.create(:comment, post: @post) @post.comments.size.should == 2 all = Comment.count @post.destroy @@ -51,47 +51,47 @@ describe Post do end it "doesn't allow a nil subject" do - @post = FactoryGirl.build(:post, :subject => nil) + @post = FactoryGirl.build(:post, subject: nil) @post.should_not be_valid end it "doesn't allow a blank subject" do - @post = FactoryGirl.build(:post, :subject => "") + @post = FactoryGirl.build(:post, subject: "") @post.should_not be_valid end it "doesn't allow a subject with only spaces" do - @post = FactoryGirl.build(:post, :subject => " ") + @post = FactoryGirl.build(:post, subject: " ") @post.should_not be_valid end context "recent activity" do before do - Time.stub(:now => Time.now) + Time.stub(now: Time.now) end - let(:post) { FactoryGirl.create(:post, :created_at => 1.day.ago) } + let(:post) { FactoryGirl.create(:post, created_at: 1.day.ago) } it "sets recent activity to post time" do post.recent_activity.to_i.should eq post.created_at.to_i end it "sets recent activity to comment time" do - @comment = FactoryGirl.create(:comment, :post => post, - :created_at => 1.hour.ago) + @comment = FactoryGirl.create(:comment, post: post, + created_at: 1.hour.ago) post.recent_activity.to_i.should eq @comment.created_at.to_i end it "shiny new post is recently active" do # create a shiny new post - @post2 = FactoryGirl.create(:post, :created_at => 1.minute.ago) + @post2 = FactoryGirl.create(:post, created_at: 1.minute.ago) Post.recently_active.first.should eq @post2 end it "new comment on old post is recently active" do # now comment on an older post - @comment2 = FactoryGirl.create(:comment, :post => post, :created_at => 1.second.ago) + @comment2 = FactoryGirl.create(:comment, post: post, created_at: 1.second.ago) Post.recently_active.first.should eq post end end @@ -101,12 +101,12 @@ describe Post do it "sends a notification when a member is mentioned" do expect { - FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name) + FactoryGirl.create(:post, author: member, body: "Hey @" << member2.login_name) }.to change(Notification, :count).by(1) end it "sets the notification field" do - @p = FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name) + @p = FactoryGirl.create(:post, author: member, body: "Hey @" << member2.login_name) @n = Notification.first @n.sender.should eq member @n.recipient.should eq member2 @@ -117,13 +117,13 @@ describe Post do it "sends notifications to all members mentioned" do @member3 = FactoryGirl.create(:member) expect { - FactoryGirl.create(:post, :author => member, :body => "Hey @" << member2.login_name << " & @" << @member3.login_name) + FactoryGirl.create(:post, author: member, body: "Hey @" << member2.login_name << " & @" << @member3.login_name) }.to change(Notification, :count).by(2) end it "doesn't send notifications if you mention yourself" do expect { - FactoryGirl.create(:post, :author => member, :body => "@" << member.login_name) + FactoryGirl.create(:post, author: member, body: "@" << member.login_name) }.to change(Notification, :count).by(0) end end @@ -132,7 +132,7 @@ describe Post do let!(:tomato) { FactoryGirl.create(:tomato) } let!(:maize) { FactoryGirl.create(:maize) } let!(:chard) { FactoryGirl.create(:chard) } - let!(:post) { FactoryGirl.create(:post, :body => "[maize](crop)[tomato](crop)[tomato](crop)") } + let!(:post) { FactoryGirl.create(:post, body: "[maize](crop)[tomato](crop)[tomato](crop)") } it "should be generated" do expect(tomato.posts).to eq [post] @@ -144,7 +144,7 @@ describe Post do end it "should be updated when post was modified" do - post.update_attributes(:body => "[chard](crop)") + post.update_attributes(body: "[chard](crop)") expect(post.crops).to eq [chard] expect(chard.posts).to eq [post] diff --git a/spec/models/seed_spec.rb b/spec/models/seed_spec.rb index 65008adcc..58ae5f906 100644 --- a/spec/models/seed_spec.rb +++ b/spec/models/seed_spec.rb @@ -15,24 +15,24 @@ describe Seed do context 'quantity' do it 'allows integer quantities' do - @seed = FactoryGirl.build(:seed, :quantity => 99) + @seed = FactoryGirl.build(:seed, quantity: 99) @seed.should be_valid end it "doesn't allow decimal quantities" do - @seed = FactoryGirl.build(:seed, :quantity => 99.9) + @seed = FactoryGirl.build(:seed, quantity: 99.9) @seed.should_not be_valid end it "doesn't allow non-numeric quantities" do - @seed = FactoryGirl.build(:seed, :quantity => 'foo') + @seed = FactoryGirl.build(:seed, quantity: 'foo') @seed.should_not be_valid end it "allows blank quantities" do - @seed = FactoryGirl.build(:seed, :quantity => nil) + @seed = FactoryGirl.build(:seed, quantity: nil) @seed.should be_valid - @seed = FactoryGirl.build(:seed, :quantity => '') + @seed = FactoryGirl.build(:seed, quantity: '') @seed.should be_valid end end @@ -40,32 +40,32 @@ describe Seed do context 'tradable' do it 'all valid tradable_to values should work' do ['nowhere', 'locally', 'nationally', 'internationally'].each do |t| - @seed = FactoryGirl.build(:seed, :tradable_to => t) + @seed = FactoryGirl.build(:seed, tradable_to: t) @seed.should be_valid end end it 'should refuse invalid tradable_to values' do - @seed = FactoryGirl.build(:seed, :tradable_to => 'not valid') + @seed = FactoryGirl.build(:seed, tradable_to: 'not valid') @seed.should_not be_valid @seed.errors[:tradable_to].should include("You may only trade seed nowhere, locally, nationally, or internationally") end it 'should not allow nil or blank values' do - @seed = FactoryGirl.build(:seed, :tradable_to => nil) + @seed = FactoryGirl.build(:seed, tradable_to: nil) @seed.should_not be_valid - @seed = FactoryGirl.build(:seed, :tradable_to => '') + @seed = FactoryGirl.build(:seed, tradable_to: '') @seed.should_not be_valid end it 'tradable? gives the right answers' do - @seed = FactoryGirl.create(:seed, :tradable_to => 'nowhere') + @seed = FactoryGirl.create(:seed, tradable_to: 'nowhere') @seed.tradable?.should eq false - @seed = FactoryGirl.create(:seed, :tradable_to => 'locally') + @seed = FactoryGirl.create(:seed, tradable_to: 'locally') @seed.tradable?.should eq true - @seed = FactoryGirl.create(:seed, :tradable_to => 'nationally') + @seed = FactoryGirl.create(:seed, tradable_to: 'nationally') @seed.tradable?.should eq true - @seed = FactoryGirl.create(:seed, :tradable_to => 'internationally') + @seed = FactoryGirl.create(:seed, tradable_to: 'internationally') @seed.tradable?.should eq true end @@ -90,7 +90,7 @@ describe Seed do it 'all valid organic values should work' do ['certified organic', 'non-certified organic', 'conventional/non-organic', 'unknown'].each do |t| - @seed = FactoryGirl.build(:seed, :organic => t) + @seed = FactoryGirl.build(:seed, organic: t) @seed.should be_valid end end @@ -98,14 +98,14 @@ describe Seed do it 'all valid GMO values should work' do ['certified GMO-free', 'non-certified GMO-free', 'GMO', 'unknown'].each do |t| - @seed = FactoryGirl.build(:seed, :gmo => t) + @seed = FactoryGirl.build(:seed, gmo: t) @seed.should be_valid end end it 'all valid heirloom values should work' do %w(heirloom hybrid unknown).each do |t| - @seed = FactoryGirl.build(:seed, :heirloom => t) + @seed = FactoryGirl.build(:seed, heirloom: t) @seed.should be_valid end end @@ -137,8 +137,8 @@ describe Seed do # 2) the owner must have a location set @located_member = FactoryGirl.create(:london_member) - @seed1 = FactoryGirl.create(:tradable_seed, :owner => @located_member) - @seed2 = FactoryGirl.create(:seed, :owner => @located_member) + @seed1 = FactoryGirl.create(:tradable_seed, owner: @located_member) + @seed2 = FactoryGirl.create(:seed, owner: @located_member) @seed3 = FactoryGirl.create(:tradable_seed) @seed4 = FactoryGirl.create(:seed) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 4d8a72a98..a30142f36 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -88,8 +88,8 @@ RSpec.configure do |config| # controller specs require this to work with Devise # see https://github.com/plataformatec/devise/wiki/How-To%3a-Controllers-and-Views-tests-with-Rails-3-%28and-rspec%29 - config.include Devise::TestHelpers, :type => :controller - config.extend ControllerMacros, :type => :controller + config.include Devise::TestHelpers, type: :controller + config.extend ControllerMacros, type: :controller # Allow just create(:factory) instead of needing to specify FactoryGirl.create(:factory) config.include FactoryGirl::Syntax::Methods diff --git a/spec/routing/account_types_routing_spec.rb b/spec/routing/account_types_routing_spec.rb index 440c16956..83dba34a5 100644 --- a/spec/routing/account_types_routing_spec.rb +++ b/spec/routing/account_types_routing_spec.rb @@ -12,11 +12,11 @@ describe AccountTypesController do end it "routes to #show" do - get("/account_types/1").should route_to("account_types#show", :id => "1") + get("/account_types/1").should route_to("account_types#show", id: "1") end it "routes to #edit" do - get("/account_types/1/edit").should route_to("account_types#edit", :id => "1") + get("/account_types/1/edit").should route_to("account_types#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe AccountTypesController do end it "routes to #update" do - put("/account_types/1").should route_to("account_types#update", :id => "1") + put("/account_types/1").should route_to("account_types#update", id: "1") end it "routes to #destroy" do - delete("/account_types/1").should route_to("account_types#destroy", :id => "1") + delete("/account_types/1").should route_to("account_types#destroy", id: "1") end end diff --git a/spec/routing/authentications_routing_spec.rb b/spec/routing/authentications_routing_spec.rb index 5d907428f..75f86fd49 100644 --- a/spec/routing/authentications_routing_spec.rb +++ b/spec/routing/authentications_routing_spec.rb @@ -7,7 +7,7 @@ describe AuthenticationsController do end it "routes to #destroy" do - delete("/authentications/1").should route_to("authentications#destroy", :id => "1") + delete("/authentications/1").should route_to("authentications#destroy", id: "1") end end diff --git a/spec/routing/comments_routing_spec.rb b/spec/routing/comments_routing_spec.rb index 4a0fe8026..b5466af43 100644 --- a/spec/routing/comments_routing_spec.rb +++ b/spec/routing/comments_routing_spec.rb @@ -12,11 +12,11 @@ describe CommentsController do end it "routes to #show" do - get("/comments/1").should route_to("comments#show", :id => "1") + get("/comments/1").should route_to("comments#show", id: "1") end it "routes to #edit" do - get("/comments/1/edit").should route_to("comments#edit", :id => "1") + get("/comments/1/edit").should route_to("comments#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe CommentsController do end it "routes to #update" do - put("/comments/1").should route_to("comments#update", :id => "1") + put("/comments/1").should route_to("comments#update", id: "1") end it "routes to #destroy" do - delete("/comments/1").should route_to("comments#destroy", :id => "1") + delete("/comments/1").should route_to("comments#destroy", id: "1") end end diff --git a/spec/routing/crops_routing_spec.rb b/spec/routing/crops_routing_spec.rb index 1e1fe4aac..95985917f 100644 --- a/spec/routing/crops_routing_spec.rb +++ b/spec/routing/crops_routing_spec.rb @@ -12,11 +12,11 @@ describe CropsController do end it "routes to #show" do - get("/crops/1").should route_to("crops#show", :id => "1") + get("/crops/1").should route_to("crops#show", id: "1") end it "routes to #edit" do - get("/crops/1/edit").should route_to("crops#edit", :id => "1") + get("/crops/1/edit").should route_to("crops#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe CropsController do end it "routes to #update" do - put("/crops/1").should route_to("crops#update", :id => "1") + put("/crops/1").should route_to("crops#update", id: "1") end it "routes to #destroy" do - delete("/crops/1").should route_to("crops#destroy", :id => "1") + delete("/crops/1").should route_to("crops#destroy", id: "1") end end diff --git a/spec/routing/follows_routing_spec.rb b/spec/routing/follows_routing_spec.rb index d4259e024..4158502c7 100644 --- a/spec/routing/follows_routing_spec.rb +++ b/spec/routing/follows_routing_spec.rb @@ -8,7 +8,7 @@ describe FollowsController do end it "routes to #destroy" do - delete("/follows/1").should route_to("follows#destroy", :id => "1") + delete("/follows/1").should route_to("follows#destroy", id: "1") end end diff --git a/spec/routing/forums_routing_spec.rb b/spec/routing/forums_routing_spec.rb index 4bd7d6097..12730c556 100644 --- a/spec/routing/forums_routing_spec.rb +++ b/spec/routing/forums_routing_spec.rb @@ -12,11 +12,11 @@ describe ForumsController do end it "routes to #show" do - get("/forums/1").should route_to("forums#show", :id => "1") + get("/forums/1").should route_to("forums#show", id: "1") end it "routes to #edit" do - get("/forums/1/edit").should route_to("forums#edit", :id => "1") + get("/forums/1/edit").should route_to("forums#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe ForumsController do end it "routes to #update" do - put("/forums/1").should route_to("forums#update", :id => "1") + put("/forums/1").should route_to("forums#update", id: "1") end it "routes to #destroy" do - delete("/forums/1").should route_to("forums#destroy", :id => "1") + delete("/forums/1").should route_to("forums#destroy", id: "1") end end diff --git a/spec/routing/gardens_routing_spec.rb b/spec/routing/gardens_routing_spec.rb index 1c627e091..5270195ec 100644 --- a/spec/routing/gardens_routing_spec.rb +++ b/spec/routing/gardens_routing_spec.rb @@ -12,11 +12,11 @@ describe GardensController do end it "routes to #show" do - get("/gardens/1").should route_to("gardens#show", :id => "1") + get("/gardens/1").should route_to("gardens#show", id: "1") end it "routes to #edit" do - get("/gardens/1/edit").should route_to("gardens#edit", :id => "1") + get("/gardens/1/edit").should route_to("gardens#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe GardensController do end it "routes to #update" do - put("/gardens/1").should route_to("gardens#update", :id => "1") + put("/gardens/1").should route_to("gardens#update", id: "1") end it "routes to #destroy" do - delete("/gardens/1").should route_to("gardens#destroy", :id => "1") + delete("/gardens/1").should route_to("gardens#destroy", id: "1") end end diff --git a/spec/routing/harvests_routing_spec.rb b/spec/routing/harvests_routing_spec.rb index 8b34d920a..4d532bcfc 100644 --- a/spec/routing/harvests_routing_spec.rb +++ b/spec/routing/harvests_routing_spec.rb @@ -12,11 +12,11 @@ describe HarvestsController do end it "routes to #show" do - get("/harvests/1").should route_to("harvests#show", :id => "1") + get("/harvests/1").should route_to("harvests#show", id: "1") end it "routes to #edit" do - get("/harvests/1/edit").should route_to("harvests#edit", :id => "1") + get("/harvests/1/edit").should route_to("harvests#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe HarvestsController do end it "routes to #update" do - put("/harvests/1").should route_to("harvests#update", :id => "1") + put("/harvests/1").should route_to("harvests#update", id: "1") end it "routes to #destroy" do - delete("/harvests/1").should route_to("harvests#destroy", :id => "1") + delete("/harvests/1").should route_to("harvests#destroy", id: "1") end end diff --git a/spec/routing/notifications_routing_spec.rb b/spec/routing/notifications_routing_spec.rb index 35f54689f..d3c2b9f61 100644 --- a/spec/routing/notifications_routing_spec.rb +++ b/spec/routing/notifications_routing_spec.rb @@ -12,11 +12,11 @@ describe NotificationsController do end it "routes to #show" do - get("/notifications/1").should route_to("notifications#show", :id => "1") + get("/notifications/1").should route_to("notifications#show", id: "1") end it "routes to #edit" do - get("/notifications/1/edit").should route_to("notifications#edit", :id => "1") + get("/notifications/1/edit").should route_to("notifications#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe NotificationsController do end it "routes to #update" do - put("/notifications/1").should route_to("notifications#update", :id => "1") + put("/notifications/1").should route_to("notifications#update", id: "1") end it "routes to #destroy" do - delete("/notifications/1").should route_to("notifications#destroy", :id => "1") + delete("/notifications/1").should route_to("notifications#destroy", id: "1") end end diff --git a/spec/routing/order_items_routing_spec.rb b/spec/routing/order_items_routing_spec.rb index 858a873ad..6562e3a17 100644 --- a/spec/routing/order_items_routing_spec.rb +++ b/spec/routing/order_items_routing_spec.rb @@ -12,11 +12,11 @@ describe OrderItemsController do end it "routes to #show" do - get("/order_items/1").should route_to("order_items#show", :id => "1") + get("/order_items/1").should route_to("order_items#show", id: "1") end it "routes to #edit" do - get("/order_items/1/edit").should route_to("order_items#edit", :id => "1") + get("/order_items/1/edit").should route_to("order_items#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe OrderItemsController do end it "routes to #update" do - put("/order_items/1").should route_to("order_items#update", :id => "1") + put("/order_items/1").should route_to("order_items#update", id: "1") end it "routes to #destroy" do - delete("/order_items/1").should route_to("order_items#destroy", :id => "1") + delete("/order_items/1").should route_to("order_items#destroy", id: "1") end end diff --git a/spec/routing/orders_routing_spec.rb b/spec/routing/orders_routing_spec.rb index 7fc9735ee..61410745e 100644 --- a/spec/routing/orders_routing_spec.rb +++ b/spec/routing/orders_routing_spec.rb @@ -12,11 +12,11 @@ describe OrdersController do end it "routes to #show" do - get("/orders/1").should route_to("orders#show", :id => "1") + get("/orders/1").should route_to("orders#show", id: "1") end it "routes to #edit" do - get("/orders/1/edit").should route_to("orders#edit", :id => "1") + get("/orders/1/edit").should route_to("orders#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe OrdersController do end it "routes to #update" do - put("/orders/1").should route_to("orders#update", :id => "1") + put("/orders/1").should route_to("orders#update", id: "1") end it "routes to #destroy" do - delete("/orders/1").should route_to("orders#destroy", :id => "1") + delete("/orders/1").should route_to("orders#destroy", id: "1") end end diff --git a/spec/routing/photos_routing_spec.rb b/spec/routing/photos_routing_spec.rb index 5bdfeca07..fb96758c2 100644 --- a/spec/routing/photos_routing_spec.rb +++ b/spec/routing/photos_routing_spec.rb @@ -12,11 +12,11 @@ describe PhotosController do end it "routes to #show" do - get("/photos/1").should route_to("photos#show", :id => "1") + get("/photos/1").should route_to("photos#show", id: "1") end it "routes to #edit" do - get("/photos/1/edit").should route_to("photos#edit", :id => "1") + get("/photos/1/edit").should route_to("photos#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe PhotosController do end it "routes to #update" do - put("/photos/1").should route_to("photos#update", :id => "1") + put("/photos/1").should route_to("photos#update", id: "1") end it "routes to #destroy" do - delete("/photos/1").should route_to("photos#destroy", :id => "1") + delete("/photos/1").should route_to("photos#destroy", id: "1") end end diff --git a/spec/routing/plant_parts_routing_spec.rb b/spec/routing/plant_parts_routing_spec.rb index 54d02caa1..4a4137cd6 100644 --- a/spec/routing/plant_parts_routing_spec.rb +++ b/spec/routing/plant_parts_routing_spec.rb @@ -12,11 +12,11 @@ describe PlantPartsController do end it "routes to #show" do - get("/plant_parts/1").should route_to("plant_parts#show", :id => "1") + get("/plant_parts/1").should route_to("plant_parts#show", id: "1") end it "routes to #edit" do - get("/plant_parts/1/edit").should route_to("plant_parts#edit", :id => "1") + get("/plant_parts/1/edit").should route_to("plant_parts#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe PlantPartsController do end it "routes to #update" do - put("/plant_parts/1").should route_to("plant_parts#update", :id => "1") + put("/plant_parts/1").should route_to("plant_parts#update", id: "1") end it "routes to #destroy" do - delete("/plant_parts/1").should route_to("plant_parts#destroy", :id => "1") + delete("/plant_parts/1").should route_to("plant_parts#destroy", id: "1") end end diff --git a/spec/routing/plantings_routing_spec.rb b/spec/routing/plantings_routing_spec.rb index bf3e1e8b8..1be8416d4 100644 --- a/spec/routing/plantings_routing_spec.rb +++ b/spec/routing/plantings_routing_spec.rb @@ -12,11 +12,11 @@ describe PlantingsController do end it "routes to #show" do - get("/plantings/1").should route_to("plantings#show", :id => "1") + get("/plantings/1").should route_to("plantings#show", id: "1") end it "routes to #edit" do - get("/plantings/1/edit").should route_to("plantings#edit", :id => "1") + get("/plantings/1/edit").should route_to("plantings#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe PlantingsController do end it "routes to #update" do - put("/plantings/1").should route_to("plantings#update", :id => "1") + put("/plantings/1").should route_to("plantings#update", id: "1") end it "routes to #destroy" do - delete("/plantings/1").should route_to("plantings#destroy", :id => "1") + delete("/plantings/1").should route_to("plantings#destroy", id: "1") end end diff --git a/spec/routing/products_routing_spec.rb b/spec/routing/products_routing_spec.rb index a9c2fa004..189bbe59a 100644 --- a/spec/routing/products_routing_spec.rb +++ b/spec/routing/products_routing_spec.rb @@ -12,11 +12,11 @@ describe ProductsController do end it "routes to #show" do - get("/products/1").should route_to("products#show", :id => "1") + get("/products/1").should route_to("products#show", id: "1") end it "routes to #edit" do - get("/products/1/edit").should route_to("products#edit", :id => "1") + get("/products/1/edit").should route_to("products#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe ProductsController do end it "routes to #update" do - put("/products/1").should route_to("products#update", :id => "1") + put("/products/1").should route_to("products#update", id: "1") end it "routes to #destroy" do - delete("/products/1").should route_to("products#destroy", :id => "1") + delete("/products/1").should route_to("products#destroy", id: "1") end end diff --git a/spec/routing/roles_routing_spec.rb b/spec/routing/roles_routing_spec.rb index 0a7900f9d..752bd7c49 100644 --- a/spec/routing/roles_routing_spec.rb +++ b/spec/routing/roles_routing_spec.rb @@ -12,11 +12,11 @@ describe RolesController do end it "routes to #show" do - get("/roles/1").should route_to("roles#show", :id => "1") + get("/roles/1").should route_to("roles#show", id: "1") end it "routes to #edit" do - get("/roles/1/edit").should route_to("roles#edit", :id => "1") + get("/roles/1/edit").should route_to("roles#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe RolesController do end it "routes to #update" do - put("/roles/1").should route_to("roles#update", :id => "1") + put("/roles/1").should route_to("roles#update", id: "1") end it "routes to #destroy" do - delete("/roles/1").should route_to("roles#destroy", :id => "1") + delete("/roles/1").should route_to("roles#destroy", id: "1") end end diff --git a/spec/routing/scientific_names_routing_spec.rb b/spec/routing/scientific_names_routing_spec.rb index 00c049289..f5bfa780e 100644 --- a/spec/routing/scientific_names_routing_spec.rb +++ b/spec/routing/scientific_names_routing_spec.rb @@ -12,11 +12,11 @@ describe ScientificNamesController do end it "routes to #show" do - get("/scientific_names/1").should route_to("scientific_names#show", :id => "1") + get("/scientific_names/1").should route_to("scientific_names#show", id: "1") end it "routes to #edit" do - get("/scientific_names/1/edit").should route_to("scientific_names#edit", :id => "1") + get("/scientific_names/1/edit").should route_to("scientific_names#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe ScientificNamesController do end it "routes to #update" do - put("/scientific_names/1").should route_to("scientific_names#update", :id => "1") + put("/scientific_names/1").should route_to("scientific_names#update", id: "1") end it "routes to #destroy" do - delete("/scientific_names/1").should route_to("scientific_names#destroy", :id => "1") + delete("/scientific_names/1").should route_to("scientific_names#destroy", id: "1") end end diff --git a/spec/routing/seeds_routing_spec.rb b/spec/routing/seeds_routing_spec.rb index 4fe46774a..5ac7ae02c 100644 --- a/spec/routing/seeds_routing_spec.rb +++ b/spec/routing/seeds_routing_spec.rb @@ -12,11 +12,11 @@ describe SeedsController do end it "routes to #show" do - get("/seeds/1").should route_to("seeds#show", :id => "1") + get("/seeds/1").should route_to("seeds#show", id: "1") end it "routes to #edit" do - get("/seeds/1/edit").should route_to("seeds#edit", :id => "1") + get("/seeds/1/edit").should route_to("seeds#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe SeedsController do end it "routes to #update" do - put("/seeds/1").should route_to("seeds#update", :id => "1") + put("/seeds/1").should route_to("seeds#update", id: "1") end it "routes to #destroy" do - delete("/seeds/1").should route_to("seeds#destroy", :id => "1") + delete("/seeds/1").should route_to("seeds#destroy", id: "1") end end diff --git a/spec/routing/updates_routing_spec.rb b/spec/routing/updates_routing_spec.rb index 9ff2b5ccd..32be13b86 100644 --- a/spec/routing/updates_routing_spec.rb +++ b/spec/routing/updates_routing_spec.rb @@ -12,11 +12,11 @@ describe PostsController do end it "routes to #show" do - get("/posts/1").should route_to("posts#show", :id => "1") + get("/posts/1").should route_to("posts#show", id: "1") end it "routes to #edit" do - get("/posts/1/edit").should route_to("posts#edit", :id => "1") + get("/posts/1/edit").should route_to("posts#edit", id: "1") end it "routes to #create" do @@ -24,11 +24,11 @@ describe PostsController do end it "routes to #update" do - put("/posts/1").should route_to("posts#update", :id => "1") + put("/posts/1").should route_to("posts#update", id: "1") end it "routes to #destroy" do - delete("/posts/1").should route_to("posts#destroy", :id => "1") + delete("/posts/1").should route_to("posts#destroy", id: "1") end end diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb index b3e908378..051579ea7 100644 --- a/spec/support/database_cleaner.rb +++ b/spec/support/database_cleaner.rb @@ -8,7 +8,7 @@ RSpec.configure do |config| DatabaseCleaner.strategy = :transaction end - config.before(:each, :js => true) do + config.before(:each, js: true) do DatabaseCleaner.strategy = :truncation end diff --git a/spec/support/devise.rb b/spec/support/devise.rb index 5d898b4d3..5fffd6c3f 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -1,4 +1,4 @@ RSpec.configure do |config| - config.include Devise::TestHelpers, :type => :controller - config.include Devise::TestHelpers, :type => :view + config.include Devise::TestHelpers, type: :controller + config.include Devise::TestHelpers, type: :view end diff --git a/spec/support/feature_helpers.rb b/spec/support/feature_helpers.rb index 81b781d18..b4da3b755 100644 --- a/spec/support/feature_helpers.rb +++ b/spec/support/feature_helpers.rb @@ -1,7 +1,7 @@ module FeatureHelpers def fill_autocomplete(field, options={}) - fill_in field, :with => options[:with] + fill_in field, with: options[:with] page.execute_script %Q{ $('##{field}').trigger('focus'); } page.execute_script %Q{ $('##{field}').trigger('keydown'); } @@ -16,5 +16,5 @@ module FeatureHelpers end RSpec.configure do |config| - config.include FeatureHelpers, :type => :feature + config.include FeatureHelpers, type: :feature end \ No newline at end of file diff --git a/spec/views/about/contact_spec.rb b/spec/views/about/contact_spec.rb index ce5b5afec..695be51b4 100644 --- a/spec/views/about/contact_spec.rb +++ b/spec/views/about/contact_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'about/contact.html.haml', :type => "view" do +describe 'about/contact.html.haml', type: "view" do before(:each) do render end diff --git a/spec/views/account_types/edit.html.haml_spec.rb b/spec/views/account_types/edit.html.haml_spec.rb index e8aeae7c0..f8fa80cc3 100644 --- a/spec/views/account_types/edit.html.haml_spec.rb +++ b/spec/views/account_types/edit.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "account_types/edit" do before(:each) do @account_type = assign(:account_type, stub_model(AccountType, - :name => "MyString", - :is_paid => false, - :is_permanent_paid => false + name: "MyString", + is_paid: false, + is_permanent_paid: false )) end @@ -29,10 +29,10 @@ describe "account_types/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => account_types_path(@account_type), :method => "post" do - assert_select "input#account_type_name", :name => "account_type[name]" - assert_select "input#account_type_is_paid", :name => "account_type[is_paid]" - assert_select "input#account_type_is_permanent_paid", :name => "account_type[is_permanent_paid]" + assert_select "form", action: account_types_path(@account_type), method: "post" do + assert_select "input#account_type_name", name: "account_type[name]" + assert_select "input#account_type_is_paid", name: "account_type[is_paid]" + assert_select "input#account_type_is_permanent_paid", name: "account_type[is_permanent_paid]" end end end diff --git a/spec/views/account_types/index.html.haml_spec.rb b/spec/views/account_types/index.html.haml_spec.rb index aed40b2af..76a83d269 100644 --- a/spec/views/account_types/index.html.haml_spec.rb +++ b/spec/views/account_types/index.html.haml_spec.rb @@ -25,6 +25,6 @@ describe "account_types/index" do it "renders a list of account_types" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => @type.name.to_s, :count => 2 + assert_select "tr>td", text: @type.name.to_s, count: 2 end end diff --git a/spec/views/account_types/new.html.haml_spec.rb b/spec/views/account_types/new.html.haml_spec.rb index 1fd496b55..8ec9fc1ff 100644 --- a/spec/views/account_types/new.html.haml_spec.rb +++ b/spec/views/account_types/new.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "account_types/new" do before(:each) do assign(:account_type, stub_model(AccountType, - :name => "MyString", - :is_paid => false, - :is_permanent_paid => false + name: "MyString", + is_paid: false, + is_permanent_paid: false ).as_new_record) end @@ -29,10 +29,10 @@ describe "account_types/new" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => account_types_path, :method => "post" do - assert_select "input#account_type_name", :name => "account_type[name]" - assert_select "input#account_type_is_paid", :name => "account_type[is_paid]" - assert_select "input#account_type_is_permanent_paid", :name => "account_type[is_permanent_paid]" + assert_select "form", action: account_types_path, method: "post" do + assert_select "input#account_type_name", name: "account_type[name]" + assert_select "input#account_type_is_paid", name: "account_type[is_paid]" + assert_select "input#account_type_is_permanent_paid", name: "account_type[is_permanent_paid]" end end end diff --git a/spec/views/account_types/show.html.haml_spec.rb b/spec/views/account_types/show.html.haml_spec.rb index 84861f8a3..bfbd50243 100644 --- a/spec/views/account_types/show.html.haml_spec.rb +++ b/spec/views/account_types/show.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "account_types/show" do before(:each) do @account_type = assign(:account_type, stub_model(AccountType, - :name => "Name", - :is_paid => false, - :is_permanent_paid => false + name: "Name", + is_paid: false, + is_permanent_paid: false )) end diff --git a/spec/views/accounts/edit.html.haml_spec.rb b/spec/views/accounts/edit.html.haml_spec.rb index 522707304..2f265658f 100644 --- a/spec/views/accounts/edit.html.haml_spec.rb +++ b/spec/views/accounts/edit.html.haml_spec.rb @@ -26,9 +26,9 @@ describe "accounts/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => accounts_path(@account), :method => "post" do - assert_select "input#account_member_id", :name => "account[member_id]" - assert_select "input#account_account_type", :name => "account[account_type]" + assert_select "form", action: accounts_path(@account), method: "post" do + assert_select "input#account_member_id", name: "account[member_id]" + assert_select "input#account_account_type", name: "account[account_type]" end end end diff --git a/spec/views/accounts/index.html.haml_spec.rb b/spec/views/accounts/index.html.haml_spec.rb index 98802ad6d..60b2cf6f6 100644 --- a/spec/views/accounts/index.html.haml_spec.rb +++ b/spec/views/accounts/index.html.haml_spec.rb @@ -26,6 +26,6 @@ describe "accounts/index" do it "renders a list of accounts" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => @account.member_id.to_s, :count => 2 + assert_select "tr>td", text: @account.member_id.to_s, count: 2 end end diff --git a/spec/views/accounts/new.html.haml_spec.rb b/spec/views/accounts/new.html.haml_spec.rb index 2cf2dcef7..f51649226 100644 --- a/spec/views/accounts/new.html.haml_spec.rb +++ b/spec/views/accounts/new.html.haml_spec.rb @@ -26,9 +26,9 @@ describe "accounts/new" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => accounts_path, :method => "post" do - assert_select "input#account_member_id", :name => "account[member_id]" - assert_select "input#account_account_type", :name => "account[account_type]" + assert_select "form", action: accounts_path, method: "post" do + assert_select "input#account_member_id", name: "account[member_id]" + assert_select "input#account_account_type", name: "account[account_type]" end end end diff --git a/spec/views/admin/index_spec.rb b/spec/views/admin/index_spec.rb index e82f7b641..79ac5d965 100644 --- a/spec/views/admin/index_spec.rb +++ b/spec/views/admin/index_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'admin/index.html.haml', :type => "view" do +describe 'admin/index.html.haml', type: "view" do before(:each) do @member = FactoryGirl.create(:admin_member) sign_in @member @@ -25,10 +25,10 @@ describe 'admin/index.html.haml', :type => "view" do end it "includes links to manage various things" do - assert_select "a", :href => account_types_path - assert_select "a", :href => products_path - assert_select "a", :href => roles_path - assert_select "a", :href => forums_path + assert_select "a", href: account_types_path + assert_select "a", href: products_path + assert_select "a", href: roles_path + assert_select "a", href: forums_path end it "has a link to newsletter subscribers" do diff --git a/spec/views/admin/newsletter_spec.rb b/spec/views/admin/newsletter_spec.rb index 6ea4abeb0..55f02d0fa 100644 --- a/spec/views/admin/newsletter_spec.rb +++ b/spec/views/admin/newsletter_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'admin/newsletter.html.haml', :type => "view" do +describe 'admin/newsletter.html.haml', type: "view" do before(:each) do @member = FactoryGirl.create(:admin_member) sign_in @member diff --git a/spec/views/admin/orders/index_spec.rb b/spec/views/admin/orders/index_spec.rb index 00fbd811e..55d55773d 100644 --- a/spec/views/admin/orders/index_spec.rb +++ b/spec/views/admin/orders/index_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'admin/orders/index.html.haml', :type => "view" do +describe 'admin/orders/index.html.haml', type: "view" do before(:each) do @member = FactoryGirl.create(:admin_member) sign_in @member @@ -31,6 +31,6 @@ describe 'admin/orders/index.html.haml', :type => "view" do end it "lets you search by referral code" do - assert_select "option[value=referral_code]", :text => "Referral code" + assert_select "option[value=referral_code]", text: "Referral code" end end diff --git a/spec/views/comments/edit.html.haml_spec.rb b/spec/views/comments/edit.html.haml_spec.rb index a3ba59479..d6e7ccb2a 100644 --- a/spec/views/comments/edit.html.haml_spec.rb +++ b/spec/views/comments/edit.html.haml_spec.rb @@ -26,8 +26,8 @@ describe "comments/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => comments_path(@comment), :method => "post" do - assert_select "textarea#comment_body", :name => "comment[body]" + assert_select "form", action: comments_path(@comment), method: "post" do + assert_select "textarea#comment_body", name: "comment[body]" end end end diff --git a/spec/views/comments/index.html.haml_spec.rb b/spec/views/comments/index.html.haml_spec.rb index 2c237da3a..4b8cbf72f 100644 --- a/spec/views/comments/index.html.haml_spec.rb +++ b/spec/views/comments/index.html.haml_spec.rb @@ -25,7 +25,7 @@ describe "comments/index" do comments = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| pager.replace([ FactoryGirl.create(:comment), - FactoryGirl.create(:comment, :body => 'ROFL') + FactoryGirl.create(:comment, body: 'ROFL') ]) end assign(:comments, comments) @@ -39,6 +39,6 @@ describe "comments/index" do end it "contains an RSS feed link" do - assert_select "a", :href => comments_path(:format => 'rss') + assert_select "a", href: comments_path(format: 'rss') end end diff --git a/spec/views/comments/index.rss.haml_spec.rb b/spec/views/comments/index.rss.haml_spec.rb index 58c07a6c8..9c61e9f2d 100644 --- a/spec/views/comments/index.rss.haml_spec.rb +++ b/spec/views/comments/index.rss.haml_spec.rb @@ -22,8 +22,8 @@ describe 'comments/index.rss.haml' do @author = FactoryGirl.create(:member) @post = FactoryGirl.create(:post) assign(:comments, [ - FactoryGirl.create(:comment, :author => @author, :post => @post), - FactoryGirl.create(:comment, :author => @author, :post => @post) + FactoryGirl.create(:comment, author: @author, post: @post), + FactoryGirl.create(:comment, author: @author, post: @post) ]) render end diff --git a/spec/views/comments/new.html.haml_spec.rb b/spec/views/comments/new.html.haml_spec.rb index 981211c8d..d86d304cf 100644 --- a/spec/views/comments/new.html.haml_spec.rb +++ b/spec/views/comments/new.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "comments/new" do before(:each) do controller.stub(:current_user) { nil } @post = FactoryGirl.create(:post) - @comment = FactoryGirl.create(:comment, :post => @post) + @comment = FactoryGirl.create(:comment, post: @post) assign(:comment, @comment) assign(:comments, [@comment]) render @@ -39,8 +39,8 @@ describe "comments/new" do end it "renders new comment form" do - assert_select "form", :action => comments_path, :method => "post" do - assert_select "textarea#comment_body", :name => "comment[body]" + assert_select "form", action: comments_path, method: "post" do + assert_select "textarea#comment_body", name: "comment[body]" end end diff --git a/spec/views/crops/_grown_for.html.haml_spec.rb b/spec/views/crops/_grown_for.html.haml_spec.rb index d77e6ee29..10a36aff9 100644 --- a/spec/views/crops/_grown_for.html.haml_spec.rb +++ b/spec/views/crops/_grown_for.html.haml_spec.rb @@ -21,14 +21,14 @@ describe "crops/_grown_for" do @crop = FactoryGirl.create(:crop) @pp = FactoryGirl.create(:plant_part) @harvest = FactoryGirl.create(:harvest, - :crop => @crop, - :plant_part => @pp + crop: @crop, + plant_part: @pp ) end it 'shows plant parts' do - render :partial => 'crops/grown_for', :locals => { :crop => @crop } + render partial: 'crops/grown_for', locals: { crop: @crop } rendered.should have_content @pp.name - assert_select "a", :href => plant_part_path(@pp) + assert_select "a", href: plant_part_path(@pp) end end diff --git a/spec/views/crops/_planting_advice.html.haml_spec.rb b/spec/views/crops/_planting_advice.html.haml_spec.rb index c902a7827..77e7e1b38 100644 --- a/spec/views/crops/_planting_advice.html.haml_spec.rb +++ b/spec/views/crops/_planting_advice.html.haml_spec.rb @@ -20,31 +20,31 @@ describe "crops/_planting_advice" do before(:each) do @owner = FactoryGirl.create(:member) @crop = FactoryGirl.create(:crop) - @garden = FactoryGirl.create(:garden, :owner => @owner) + @garden = FactoryGirl.create(:garden, owner: @owner) @planting = FactoryGirl.create(:planting, - :garden => @garden, - :crop => @crop + garden: @garden, + crop: @crop ) end context "sunniness" do it "doesn't show sunniness if none are set" do - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant in: not known." end it "shows sunniness frequencies" do - FactoryGirl.create(:sunny_planting, :crop => @crop) - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + FactoryGirl.create(:sunny_planting, crop: @crop) + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant in:" rendered.should have_content "sun (1)" end it "shows multiple sunniness frequencies" do - FactoryGirl.create(:sunny_planting, :crop => @crop) - FactoryGirl.create(:sunny_planting, :crop => @crop) - FactoryGirl.create(:shady_planting, :crop => @crop) - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + FactoryGirl.create(:sunny_planting, crop: @crop) + FactoryGirl.create(:sunny_planting, crop: @crop) + FactoryGirl.create(:shady_planting, crop: @crop) + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant in:" rendered.should have_content "sun (2), shade (1)" end @@ -54,22 +54,22 @@ describe "crops/_planting_advice" do context "planted from" do it "doesn't show planted_from if none are set" do - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant from: not known." end it "shows planted_from frequencies" do - FactoryGirl.create(:seed_planting, :crop => @crop) - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + FactoryGirl.create(:seed_planting, crop: @crop) + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant from:" rendered.should have_content "seed (1)" end it "shows multiple planted_from frequencies" do - FactoryGirl.create(:seed_planting, :crop => @crop) - FactoryGirl.create(:seed_planting, :crop => @crop) - FactoryGirl.create(:cutting_planting, :crop => @crop) - render :partial => 'crops/planting_advice', :locals => { :crop => @crop } + FactoryGirl.create(:seed_planting, crop: @crop) + FactoryGirl.create(:seed_planting, crop: @crop) + FactoryGirl.create(:cutting_planting, crop: @crop) + render partial: 'crops/planting_advice', locals: { crop: @crop } rendered.should have_content "Plant from:" rendered.should have_content "seed (2), cutting (1)" end diff --git a/spec/views/crops/_popover.html.haml_spec.rb b/spec/views/crops/_popover.html.haml_spec.rb index a98cc6e10..3ef9660f6 100644 --- a/spec/views/crops/_popover.html.haml_spec.rb +++ b/spec/views/crops/_popover.html.haml_spec.rb @@ -19,10 +19,10 @@ require 'rails_helper' describe "crops/_popover" do before(:each) do @tomato = FactoryGirl.create(:tomato) - @sn = FactoryGirl.create(:solanum_lycopersicum, :crop => @tomato) - @planting = FactoryGirl.create(:planting, :crop => @tomato) + @sn = FactoryGirl.create(:solanum_lycopersicum, crop: @tomato) + @planting = FactoryGirl.create(:planting, crop: @tomato) @tomato.reload # to pick up latest plantings_count - render :partial => 'crops/popover', :locals => { :crop => @tomato } + render partial: 'crops/popover', locals: { crop: @tomato } end it 'has a scientific name' do diff --git a/spec/views/crops/hierarchy.html.haml_spec.rb b/spec/views/crops/hierarchy.html.haml_spec.rb index 9cef87105..32bfc4248 100644 --- a/spec/views/crops/hierarchy.html.haml_spec.rb +++ b/spec/views/crops/hierarchy.html.haml_spec.rb @@ -20,12 +20,12 @@ describe "crops/hierarchy" do before(:each) do controller.stub(:current_user) { nil } @tomato = FactoryGirl.create(:tomato) - @roma = FactoryGirl.create(:crop, :name => 'Roma tomato', :parent => @tomato) + @roma = FactoryGirl.create(:crop, name: 'Roma tomato', parent: @tomato) assign(:crops, [@tomato, @roma]) render end it "shows crop hierarchy" do - assert_select "ul>li>ul>li", :text => @roma.name + assert_select "ul>li>ul>li", text: @roma.name end end diff --git a/spec/views/crops/index.html.haml_spec.rb b/spec/views/crops/index.html.haml_spec.rb index 096f1632e..0a779241d 100644 --- a/spec/views/crops/index.html.haml_spec.rb +++ b/spec/views/crops/index.html.haml_spec.rb @@ -32,16 +32,16 @@ describe "crops/index" do end it "shows photos where available" do - @planting = FactoryGirl.create(:planting, :crop => @tomato) + @planting = FactoryGirl.create(:planting, crop: @tomato) @photo = FactoryGirl.create(:photo) @planting.photos << @photo render - assert_select "img", :src => @photo.thumbnail_url + assert_select "img", src: @photo.thumbnail_url end it "linkifies crop images" do render - assert_select "img", :src => :tomato + assert_select "img", src: :tomato end context "logged in and crop wrangler" do @@ -61,9 +61,9 @@ describe "crops/index" do it "offers data downloads" do render rendered.should have_content "The data on this page is available in the following formats:" - assert_select "a", :href => crops_path(:format => 'csv') - assert_select "a", :href => crops_path(:format => 'json') - assert_select "a", :href => crops_path(:format => 'rss') + assert_select "a", href: crops_path(format: 'csv') + assert_select "a", href: crops_path(format: 'json') + assert_select "a", href: crops_path(format: 'rss') end end end diff --git a/spec/views/crops/wrangle.html.haml_spec.rb b/spec/views/crops/wrangle.html.haml_spec.rb index c0a29b4cd..e4f41b8c8 100644 --- a/spec/views/crops/wrangle.html.haml_spec.rb +++ b/spec/views/crops/wrangle.html.haml_spec.rb @@ -40,13 +40,13 @@ describe "crops/wrangle" do it 'has a link to add a crop' do render - assert_select "a", :href => new_crop_path + assert_select "a", href: new_crop_path end it "renders a list of crops" do render - assert_select "a", :text => @maize.name - assert_select "a", :text => @tomato.name + assert_select "a", text: @maize.name + assert_select "a", text: @tomato.name end end diff --git a/spec/views/devise/confirmations/new_spec.rb b/spec/views/devise/confirmations/new_spec.rb index 1e1555db3..8d567d793 100644 --- a/spec/views/devise/confirmations/new_spec.rb +++ b/spec/views/devise/confirmations/new_spec.rb @@ -1,4 +1,4 @@ -describe 'devise/confirmations/new.html.haml', :type => "view" do +describe 'devise/confirmations/new.html.haml', type: "view" do before(:each) do @view.stub(:resource).and_return(Member.new) diff --git a/spec/views/devise/mailer/confirmation_instructions_spec.rb b/spec/views/devise/mailer/confirmation_instructions_spec.rb index d1805f2f9..6f60268e4 100644 --- a/spec/views/devise/mailer/confirmation_instructions_spec.rb +++ b/spec/views/devise/mailer/confirmation_instructions_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/mailer/confirmation_instructions.html.haml', :type => "view" do +describe 'devise/mailer/confirmation_instructions.html.haml', type: "view" do context "logged in" do before(:each) do diff --git a/spec/views/devise/mailer/reset_password_instructions_spec.rb b/spec/views/devise/mailer/reset_password_instructions_spec.rb index 28c76144f..91c46a696 100644 --- a/spec/views/devise/mailer/reset_password_instructions_spec.rb +++ b/spec/views/devise/mailer/reset_password_instructions_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/mailer/reset_password_instructions.html.haml', :type => "view" do +describe 'devise/mailer/reset_password_instructions.html.haml', type: "view" do context "logged in" do before(:each) do diff --git a/spec/views/devise/mailer/unlock_instructions_spec.rb b/spec/views/devise/mailer/unlock_instructions_spec.rb index 5112da12c..5c90260c5 100644 --- a/spec/views/devise/mailer/unlock_instructions_spec.rb +++ b/spec/views/devise/mailer/unlock_instructions_spec.rb @@ -15,7 +15,7 @@ require 'rails_helper' -describe 'devise/mailer/unlock_instructions.html.haml', :type => "view" do +describe 'devise/mailer/unlock_instructions.html.haml', type: "view" do context "logged in" do before(:each) do @resource = FactoryGirl.create(:member) diff --git a/spec/views/devise/registrations/edit_spec.rb b/spec/views/devise/registrations/edit_spec.rb index 50f44d6e7..8fb096255 100644 --- a/spec/views/devise/registrations/edit_spec.rb +++ b/spec/views/devise/registrations/edit_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/registrations/edit.html.haml', :type => "view" do +describe 'devise/registrations/edit.html.haml', type: "view" do context "logged in" do before(:each) do @@ -58,11 +58,11 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do end it "contains a gravatar icon" do - assert_select "img", :src => /gravatar\.com\/avatar/ + assert_select "img", src: /gravatar\.com\/avatar/ end it 'contains a link to gravatar.com' do - assert_select "a", :href => /gravatar\.com/ + assert_select "a", href: /gravatar\.com/ end it 'shows bio field' do @@ -84,15 +84,15 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do end context 'connected to twitter' do before(:each) do - @twitter_auth = FactoryGirl.create(:authentication, :member => @member) + @twitter_auth = FactoryGirl.create(:authentication, member: @member) render end it 'has a link to twitter profile' do - assert_select "a", :href => "http://twitter.com/#{@twitter_auth.name}" + assert_select "a", href: "http://twitter.com/#{@twitter_auth.name}" end it 'has a link to disconnect' do render - assert_select "a", :href => @twitter_auth, :text => "Disconnect" + assert_select "a", href: @twitter_auth, text: "Disconnect" end end @@ -104,15 +104,15 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do end context 'connected to flickr' do before(:each) do - @flickr_auth = FactoryGirl.create(:flickr_authentication, :member => @member) + @flickr_auth = FactoryGirl.create(:flickr_authentication, member: @member) render end it 'has a link to flickr photostream' do - assert_select "a", :href => "http://flickr.com/photos/#{@flickr_auth.uid}" + assert_select "a", href: "http://flickr.com/photos/#{@flickr_auth.uid}" end it 'has a link to disconnect' do render - assert_select "a", :href => @flickr_auth, :text => "Disconnect" + assert_select "a", href: @flickr_auth, text: "Disconnect" end end diff --git a/spec/views/devise/registrations/new_spec.rb b/spec/views/devise/registrations/new_spec.rb index 8a63d0884..5d6d8ac5a 100644 --- a/spec/views/devise/registrations/new_spec.rb +++ b/spec/views/devise/registrations/new_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/registrations/new.html.haml', :type => "view" do +describe 'devise/registrations/new.html.haml', type: "view" do context "logged in" do before(:each) do diff --git a/spec/views/devise/sessions/new_spec.rb b/spec/views/devise/sessions/new_spec.rb index 418b53d56..674e92978 100644 --- a/spec/views/devise/sessions/new_spec.rb +++ b/spec/views/devise/sessions/new_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/sessions/new.html.haml', :type => "view" do +describe 'devise/sessions/new.html.haml', type: "view" do context "logged in" do before(:each) do diff --git a/spec/views/devise/shared/_links_spec.rb b/spec/views/devise/shared/_links_spec.rb index 41f9b45ef..7e71bbc12 100644 --- a/spec/views/devise/shared/_links_spec.rb +++ b/spec/views/devise/shared/_links_spec.rb @@ -1,28 +1,26 @@ -describe 'devise/shared/_links.haml', :type => "view" do +describe 'devise/shared/_links.haml', type: "view" do def devise_mapping(register, recover, confirm, lock, oauth) dm = double("mappings") - dm.stub(:registerable? => register) - dm.stub(:recoverable? => recover) - dm.stub(:confirmable? => confirm) - dm.stub(:lockable? => lock) - dm.stub(:omniauthable? => oauth) + dm.stub(registerable?: register) + dm.stub(recoverable?: recover) + dm.stub(confirmable?: confirm) + dm.stub(lockable?: lock) + dm.stub(omniauthable?: oauth) return dm end it 'should have a sign-in link if not in sessions' do @view.stub(:controller_name).and_return("anything but sessions") @view.stub(:resource_name).and_return("member") - @view.stub(:devise_mapping => - devise_mapping(false, false, false, false, false)) + @view.stub(devise_mapping: devise_mapping(false, false, false, false, false)) render end it "shouldn't have a sign-in link if in sessions" do @view.stub(:controller_name).and_return("sessions") @view.stub(:resource_name).and_return("member") - @view.stub(:devise_mapping => - devise_mapping(false, false, false, false, false)) + @view.stub(devise_mapping: devise_mapping(false, false, false, false, false)) render end end diff --git a/spec/views/devise/unlocks/new_spec.rb b/spec/views/devise/unlocks/new_spec.rb index 4a060d78f..e145900e4 100644 --- a/spec/views/devise/unlocks/new_spec.rb +++ b/spec/views/devise/unlocks/new_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'devise/unlocks/new.html.haml', :type => "view" do +describe 'devise/unlocks/new.html.haml', type: "view" do context "logged in" do before(:each) do diff --git a/spec/views/forums/edit.html.haml_spec.rb b/spec/views/forums/edit.html.haml_spec.rb index 762a6d806..e3c874519 100644 --- a/spec/views/forums/edit.html.haml_spec.rb +++ b/spec/views/forums/edit.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "forums/edit" do before(:each) do @forum = assign(:forum, stub_model(Forum, - :name => "MyString", - :description => "MyText", - :owner_id => 1 + name: "MyString", + description: "MyText", + owner_id: 1 )) end @@ -29,10 +29,10 @@ describe "forums/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => forums_path(@forum), :method => "post" do - assert_select "input#forum_name", :name => "forum[name]" - assert_select "textarea#forum_description", :name => "forum[description]" - assert_select "select#forum_owner_id", :name => "forum[owner_id]" + assert_select "form", action: forums_path(@forum), method: "post" do + assert_select "input#forum_name", name: "forum[name]" + assert_select "textarea#forum_description", name: "forum[description]" + assert_select "select#forum_owner_id", name: "forum[owner_id]" end end end diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index 07da3cf4f..dc1bdba58 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -27,7 +27,7 @@ describe "forums/index" do it "renders a list of forums" do render - assert_select "h2", :text => @forum1.name, :count => 2 + assert_select "h2", text: @forum1.name, count: 2 end it "doesn't display posts for empty forums" do @@ -37,8 +37,8 @@ describe "forums/index" do context "posts" do before(:each) do - @post = FactoryGirl.create(:forum_post, :forum => @forum1) - @comment = FactoryGirl.create(:comment, :post => @post) + @post = FactoryGirl.create(:forum_post, forum: @forum1) + @comment = FactoryGirl.create(:comment, post: @post) render end @@ -49,7 +49,7 @@ describe "forums/index" do end it "displays comment count" do - assert_select "td", :text => "1" + assert_select "td", text: "1" end end diff --git a/spec/views/forums/new.html.haml_spec.rb b/spec/views/forums/new.html.haml_spec.rb index 5785b1b21..59988ae90 100644 --- a/spec/views/forums/new.html.haml_spec.rb +++ b/spec/views/forums/new.html.haml_spec.rb @@ -23,10 +23,10 @@ describe "forums/new" do end it "renders new forum form" do - assert_select "form", :action => forums_path, :method => "post" do - assert_select "input#forum_name", :name => "forum[name]" - assert_select "textarea#forum_description", :name => "forum[description]" - assert_select "select#forum_owner_id", :name => "forum[owner_id]" + assert_select "form", action: forums_path, method: "post" do + assert_select "input#forum_name", name: "forum[name]" + assert_select "textarea#forum_description", name: "forum[description]" + assert_select "select#forum_owner_id", name: "forum[owner_id]" end end end diff --git a/spec/views/forums/show.html.haml_spec.rb b/spec/views/forums/show.html.haml_spec.rb index 119e411f6..a012c248e 100644 --- a/spec/views/forums/show.html.haml_spec.rb +++ b/spec/views/forums/show.html.haml_spec.rb @@ -35,7 +35,7 @@ describe "forums/show" do it 'links to new post with the forum id' do render - assert_select "a[href=#{new_post_path(:forum_id => @forum.id)}]" + assert_select "a[href=#{new_post_path(forum_id: @forum.id)}]" end it 'has no posts' do @@ -44,7 +44,7 @@ describe "forums/show" do end it 'shows posts' do - @post = FactoryGirl.create(:post, :forum => @forum) + @post = FactoryGirl.create(:post, forum: @forum) render assert_select "table" rendered.should have_content @post.subject diff --git a/spec/views/gardens/edit.html.haml_spec.rb b/spec/views/gardens/edit.html.haml_spec.rb index 3900dad35..959600d77 100644 --- a/spec/views/gardens/edit.html.haml_spec.rb +++ b/spec/views/gardens/edit.html.haml_spec.rb @@ -23,7 +23,7 @@ describe "gardens/edit" do @owner = FactoryGirl.create(:member) sign_in @owner controller.stub(:current_user) { @owner } - @garden = assign(:garden, FactoryGirl.create(:garden, :owner => @owner)) + @garden = assign(:garden, FactoryGirl.create(:garden, owner: @owner)) render end @@ -31,13 +31,13 @@ describe "gardens/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => gardens_path(@garden), :method => "post" do - assert_select "input#garden_name", :name => "garden[name]" - assert_select "textarea#garden_description", :name => "garden[description]" - assert_select "input#garden_location", :name => "garden[location]" - assert_select "input#garden_area", :name => "garden[area]" - assert_select "select#garden_area_unit", :name => "garden[area_unit]" - assert_select "input#garden_active", :name => "garden[active]" + assert_select "form", action: gardens_path(@garden), method: "post" do + assert_select "input#garden_name", name: "garden[name]" + assert_select "textarea#garden_description", name: "garden[description]" + assert_select "input#garden_location", name: "garden[location]" + assert_select "input#garden_area", name: "garden[area]" + assert_select "select#garden_area_unit", name: "garden[area_unit]" + assert_select "input#garden_active", name: "garden[active]" end end end diff --git a/spec/views/gardens/new.html.haml_spec.rb b/spec/views/gardens/new.html.haml_spec.rb index 056079f89..84b689eb0 100644 --- a/spec/views/gardens/new.html.haml_spec.rb +++ b/spec/views/gardens/new.html.haml_spec.rb @@ -21,19 +21,19 @@ describe "gardens/new" do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_user) { @member } - @garden = FactoryGirl.create(:garden, :owner => @member) + @garden = FactoryGirl.create(:garden, owner: @member) assign(:garden, @garden) render end it "renders new garden form" do - assert_select "form", :action => gardens_path, :method => "post" do - assert_select "input#garden_name", :name => "garden[name]" - assert_select "textarea#garden_description", :name => "garden[description]" - assert_select "input#garden_location", :name => "garden[location]" - assert_select "input#garden_area", :name => "garden[area]" - assert_select "select#garden_area_unit", :name => "garden[area_unit]" - assert_select "input#garden_active", :name => "garden[active]" + assert_select "form", action: gardens_path, method: "post" do + assert_select "input#garden_name", name: "garden[name]" + assert_select "textarea#garden_description", name: "garden[description]" + assert_select "input#garden_location", name: "garden[location]" + assert_select "input#garden_area", name: "garden[area]" + assert_select "select#garden_area_unit", name: "garden[area_unit]" + assert_select "input#garden_active", name: "garden[active]" end end end diff --git a/spec/views/gardens/show.html.haml_spec.rb b/spec/views/gardens/show.html.haml_spec.rb index 7c4f2c143..3753e075e 100644 --- a/spec/views/gardens/show.html.haml_spec.rb +++ b/spec/views/gardens/show.html.haml_spec.rb @@ -20,8 +20,8 @@ describe "gardens/show" do before(:each) do @owner = FactoryGirl.create(:member) controller.stub(:current_user) { @owner } - @garden = FactoryGirl.create(:garden, :owner => @owner) - @planting = FactoryGirl.create(:planting, :garden => @garden) + @garden = FactoryGirl.create(:garden, owner: @owner) + @planting = FactoryGirl.create(:planting, garden: @garden) assign(:garden, @garden) render end diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index f7c175667..f318e3a79 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -23,15 +23,15 @@ describe "harvests/edit" do end it "renders new harvest form" do - assert_select "form", :action => harvests_path, :method => "post" do - assert_select "input#crop", :class => "ui-autocomplete-input" - assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" - assert_select "select#harvest_plant_part_id", :name => "harvest[plant_part_id]" - assert_select "input#harvest_quantity", :name => "harvest[quantity]" - assert_select "input#harvest_weight_quantity", :name => "harvest[quantity]" - assert_select "select#harvest_unit", :name => "harvest[unit]" - assert_select "select#harvest_weight_unit", :name => "harvest[unit]" - assert_select "textarea#harvest_description", :name => "harvest[description]" + assert_select "form", action: harvests_path, method: "post" do + assert_select "input#crop", class: "ui-autocomplete-input" + assert_select "input#harvest_crop_id", name: "harvest[crop_id]" + assert_select "select#harvest_plant_part_id", name: "harvest[plant_part_id]" + assert_select "input#harvest_quantity", name: "harvest[quantity]" + assert_select "input#harvest_weight_quantity", name: "harvest[quantity]" + assert_select "select#harvest_unit", name: "harvest[unit]" + assert_select "select#harvest_weight_unit", name: "harvest[unit]" + assert_select "textarea#harvest_description", name: "harvest[description]" end end end diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index 0c2dfe5bb..923b3fb39 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -29,13 +29,13 @@ describe "harvests/index" do harvests = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| pager.replace([ FactoryGirl.create(:harvest, - :crop => @tomato, - :owner => @member + crop: @tomato, + owner: @member ), FactoryGirl.create(:harvest, - :crop => @maize, - :plant_part => @pp, - :owner => @member + crop: @maize, + plant_part: @pp, + owner: @member ) ]) end @@ -46,8 +46,8 @@ describe "harvests/index" do it "provides data links" do render rendered.should have_content "The data on this page is available in the following formats:" - assert_select "a", :href => harvests_path(:format => 'csv') - assert_select "a", :href => harvests_path(:format => 'json') + assert_select "a", href: harvests_path(format: 'csv') + assert_select "a", href: harvests_path(format: 'json') end it "displays member's name in title" do diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 015b94dda..20a908310 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -23,16 +23,16 @@ describe "harvests/new" do end it "renders new harvest form" do - assert_select "form", :action => harvests_path, :method => "post" do - assert_select "input#crop", :class => "ui-autocomplete-input" - assert_select "input#harvest_crop_id", :name => "harvest[crop_id]" - assert_select "select#harvest_plant_part_id", :name => "harvest[plant_part_id]" + assert_select "form", action: harvests_path, method: "post" do + assert_select "input#crop", class: "ui-autocomplete-input" + assert_select "input#harvest_crop_id", name: "harvest[crop_id]" + assert_select "select#harvest_plant_part_id", name: "harvest[plant_part_id]" # some browsers interpret without a step as "integer" - assert_select "input#harvest_quantity[step=any]", :name => "harvest[quantity]" - assert_select "input#harvest_weight_quantity[step=any]", :name => "harvest[quantity]" - assert_select "select#harvest_unit", :name => "harvest[unit]" - assert_select "select#harvest_weight_unit", :name => "harvest[unit]" - assert_select "textarea#harvest_description", :name => "harvest[description]" + assert_select "input#harvest_quantity[step=any]", name: "harvest[quantity]" + assert_select "input#harvest_weight_quantity[step=any]", name: "harvest[quantity]" + assert_select "select#harvest_unit", name: "harvest[unit]" + assert_select "select#harvest_weight_unit", name: "harvest[unit]" + assert_select "textarea#harvest_description", name: "harvest[description]" end end end diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb index 56d69b608..91014941b 100644 --- a/spec/views/harvests/show.html.haml_spec.rb +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "harvests/show" do before(:each) do controller.stub(:current_user) { nil } @crop = FactoryGirl.create(:tomato) - @harvest = assign(:harvest, FactoryGirl.create(:harvest, :crop => @crop)) + @harvest = assign(:harvest, FactoryGirl.create(:harvest, crop: @crop)) render end diff --git a/spec/views/home/_blurb.html.haml_spec.rb b/spec/views/home/_blurb.html.haml_spec.rb index e61f2be63..94e7550d1 100644 --- a/spec/views/home/_blurb.html.haml_spec.rb +++ b/spec/views/home/_blurb.html.haml_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'home/_blurb.html.haml', :type => "view" do +describe 'home/_blurb.html.haml', type: "view" do context 'signed out' do before :each do controller.stub(:current_user) { nil } @@ -29,12 +29,12 @@ describe 'home/_blurb.html.haml', :type => "view" do it 'has signup section' do assert_select "div.signup" - assert_select "a", :href => new_member_registration_path + assert_select "a", href: new_member_registration_path end it 'has a link to sign in' do rendered.should have_content "Or sign in if you already have an account" - assert_select "a", :href => new_member_session_path + assert_select "a", href: new_member_session_path end end diff --git a/spec/views/home/_crops.html.haml_spec.rb b/spec/views/home/_crops.html.haml_spec.rb index c82066b57..08b0cba01 100644 --- a/spec/views/home/_crops.html.haml_spec.rb +++ b/spec/views/home/_crops.html.haml_spec.rb @@ -16,12 +16,12 @@ require 'rails_helper' -describe 'home/_crops.html.haml', :type => "view" do +describe 'home/_crops.html.haml', type: "view" do before(:each) do # we need to set up an "interesting" crop @crop = FactoryGirl.create(:crop) (1..3).each do - @planting = FactoryGirl.create(:planting, :crop => @crop) + @planting = FactoryGirl.create(:planting, crop: @crop) end @photo = FactoryGirl.create(:photo) (1..3).each do @@ -31,20 +31,20 @@ describe 'home/_crops.html.haml', :type => "view" do end it 'shows crops section' do - assert_select 'h2', :text => 'Some of our crops' + assert_select 'h2', text: 'Some of our crops' assert_select "a[href=#{crop_path(@crop)}]" end it 'shows plantings section' do - assert_select 'h2', :text => 'Recently planted' + assert_select 'h2', text: 'Recently planted' rendered.should have_content @planting.location end it 'shows recently added crops' do - assert_select 'h2', :text => 'Recently planted' + assert_select 'h2', text: 'Recently planted' end it 'includes a link to all crops' do - assert_select "a[href=#{crops_path}]", :text => /View all crops/ + assert_select "a[href=#{crops_path}]", text: /View all crops/ end end diff --git a/spec/views/home/_members.html.haml_spec.rb b/spec/views/home/_members.html.haml_spec.rb index 5bda606ed..f208c1bde 100644 --- a/spec/views/home/_members.html.haml_spec.rb +++ b/spec/views/home/_members.html.haml_spec.rb @@ -16,13 +16,13 @@ require 'rails_helper' -describe 'home/_members.html.haml', :type => "view" do +describe 'home/_members.html.haml', type: "view" do before(:each) do @member = FactoryGirl.create(:london_member) @member.updated_at = 2.days.ago assign(:members, [@member]) - @planting = FactoryGirl.create(:planting, :owner => @member) + @planting = FactoryGirl.create(:planting, owner: @member) render end diff --git a/spec/views/home/_seeds.html.haml_spec.rb b/spec/views/home/_seeds.html.haml_spec.rb index 148cc2ea0..6cbd276f7 100644 --- a/spec/views/home/_seeds.html.haml_spec.rb +++ b/spec/views/home/_seeds.html.haml_spec.rb @@ -16,10 +16,10 @@ require 'rails_helper' -describe 'home/_seeds.html.haml', :type => "view" do +describe 'home/_seeds.html.haml', type: "view" do before(:each) do @owner = FactoryGirl.create(:london_member) - @seed = FactoryGirl.create(:tradable_seed, :owner => @owner) + @seed = FactoryGirl.create(:tradable_seed, owner: @owner) render end @@ -29,10 +29,10 @@ describe 'home/_seeds.html.haml', :type => "view" do it 'lists seeds' do assert_select "table" - assert_select 'a', :href => crop_path(@seed.crop) - assert_select 'a', :href => crop_path(@seed.owner) + assert_select 'a', href: crop_path(@seed.crop) + assert_select 'a', href: crop_path(@seed.owner) assert_select 'td', @seed.tradable_to assert_select 'td', @seed.owner.location - assert_select 'a', :href => seed_path(@seed) + assert_select 'a', href: seed_path(@seed) end end diff --git a/spec/views/home/_stats.html.haml_spec.rb b/spec/views/home/_stats.html.haml_spec.rb index f1a78b62c..0eeaf66f8 100644 --- a/spec/views/home/_stats.html.haml_spec.rb +++ b/spec/views/home/_stats.html.haml_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'home/_stats.html.haml', :type => "view" do +describe 'home/_stats.html.haml', type: "view" do it 'has activity stats' do render rendered.should have_content "So far, 0 members have planted 0 crops" diff --git a/spec/views/home/index_spec.rb b/spec/views/home/index_spec.rb index 5d45dcb2d..84dd65bde 100644 --- a/spec/views/home/index_spec.rb +++ b/spec/views/home/index_spec.rb @@ -16,16 +16,16 @@ require 'rails_helper' -describe 'home/index.html.haml', :type => "view" do +describe 'home/index.html.haml', type: "view" do before(:each) do @member = FactoryGirl.create(:london_member) @member.updated_at = 2.days.ago assign(:interesting_members, [@member]) - @post = FactoryGirl.create(:post, :author => @member) + @post = FactoryGirl.create(:post, author: @member) assign(:posts, [@post]) - @planting = FactoryGirl.create(:planting, :owner => @member) + @planting = FactoryGirl.create(:planting, owner: @member) assign(:plantings, [@planting]) @crop = FactoryGirl.create(:crop) diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index 94930bc31..cd531dc71 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'layouts/_header.html.haml', :type => "view" do +describe 'layouts/_header.html.haml', type: "view" do context "when not logged in" do before(:each) do controller.stub(:current_user) { nil } @@ -24,7 +24,7 @@ describe 'layouts/_header.html.haml', :type => "view" do end it 'shows the brand logo in the navbar' do - assert_select("img[src='/assets/growstuff-brand.png']", :href => root_path) + assert_select("img[src='/assets/growstuff-brand.png']", href: root_path) end it 'should have signup/signin links' do @@ -81,16 +81,16 @@ describe 'layouts/_header.html.haml', :type => "view" do rendered.should have_content "#{@member.login_name}" end it "should show link to member's gardens" do - assert_select("a[href=#{gardens_by_owner_path(:owner => @member.slug)}]", "Gardens") + assert_select("a[href=#{gardens_by_owner_path(owner: @member.slug)}]", "Gardens") end it "should show link to member's plantings" do - assert_select("a[href=#{plantings_by_owner_path(:owner => @member.slug)}]", "Plantings") + assert_select("a[href=#{plantings_by_owner_path(owner: @member.slug)}]", "Plantings") end it "should show link to member's seeds" do - assert_select("a[href=#{seeds_by_owner_path(:owner => @member.slug)}]", "Seeds") + assert_select("a[href=#{seeds_by_owner_path(owner: @member.slug)}]", "Seeds") end it "should show link to member's posts" do - assert_select("a[href=#{posts_by_author_path(:author => @member.slug)}]", "Posts") + assert_select("a[href=#{posts_by_author_path(author: @member.slug)}]", "Posts") end end @@ -105,7 +105,7 @@ describe 'layouts/_header.html.haml', :type => "view" do context 'has notifications' do it 'should show inbox count' do - FactoryGirl.create(:notification, :recipient => @member) + FactoryGirl.create(:notification, recipient: @member) render rendered.should have_content 'Inbox (1)' end diff --git a/spec/views/layouts/_meta_spec.rb b/spec/views/layouts/_meta_spec.rb index a181a4414..8b27d7a8b 100644 --- a/spec/views/layouts/_meta_spec.rb +++ b/spec/views/layouts/_meta_spec.rb @@ -16,23 +16,23 @@ require 'rails_helper' -describe 'layouts/_meta.html.haml', :type => "view" do +describe 'layouts/_meta.html.haml', type: "view" do before(:each) do render end it 'should have a Posts RSS feed' do - posts_rss = url_for(:controller => 'posts', :format => 'rss', :only_path => false) + posts_rss = url_for(controller: 'posts', format: 'rss', only_path: false) assert_select "head>link[href=#{posts_rss}]" end it 'should have a Crops RSS feed' do - crops_rss = url_for(:controller => 'crops', :format => 'rss', :only_path => false) + crops_rss = url_for(controller: 'crops', format: 'rss', only_path: false) assert_select "head>link[href=#{crops_rss}]" end it 'should have a Plantings RSS feed' do - plantings_rss = url_for(:controller => 'plantings', :format => 'rss', :only_path => false) + plantings_rss = url_for(controller: 'plantings', format: 'rss', only_path: false) assert_select "head>link[href=#{plantings_rss}]" end diff --git a/spec/views/layouts/application_spec.rb b/spec/views/layouts/application_spec.rb index 0679af903..af710ce6f 100644 --- a/spec/views/layouts/application_spec.rb +++ b/spec/views/layouts/application_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'layouts/application.html.haml', :type => "view" do +describe 'layouts/application.html.haml', type: "view" do before(:each) do controller.stub(:current_user) { nil } end @@ -24,7 +24,7 @@ describe 'layouts/application.html.haml', :type => "view" do it 'includes the analytics code' do Growstuff::Application.config.analytics_code = '' render - assert_select "script", :text => 'alert("foo!")' + assert_select "script", text: 'alert("foo!")' rendered.should_not have_content 'script' end diff --git a/spec/views/members/_location.html.haml_spec.rb b/spec/views/members/_location.html.haml_spec.rb index 5c4b229a3..43fb66285 100644 --- a/spec/views/members/_location.html.haml_spec.rb +++ b/spec/views/members/_location.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "members/_location" do context "member with location" do before(:each) do @member = FactoryGirl.create(:london_member) - render :partial => 'members/location', :locals => { :member => @member } + render partial: 'members/location', locals: { member: @member } end it 'shows location if available' do @@ -28,14 +28,14 @@ describe "members/_location" do end it "links to the places page" do - assert_select "a", :href => place_path(@member.location) + assert_select "a", href: place_path(@member.location) end end context "member with no location" do before(:each) do @member = FactoryGirl.create(:member) - render :partial => 'members/location', :locals => { :member => @member } + render partial: 'members/location', locals: { member: @member } end it 'shows unknown location' do diff --git a/spec/views/members/index.html.haml_spec.rb b/spec/views/members/index.html.haml_spec.rb index 3c864d415..ee1537b77 100644 --- a/spec/views/members/index.html.haml_spec.rb +++ b/spec/views/members/index.html.haml_spec.rb @@ -31,7 +31,7 @@ describe "members/index" do end it "contains two gravatar icons" do - assert_select "img", :src => /gravatar\.com\/avatar/, :count => 2 + assert_select "img", src: /gravatar\.com\/avatar/, count: 2 end it 'contains member locations' do diff --git a/spec/views/members/show.rss.haml_spec.rb b/spec/views/members/show.rss.haml_spec.rb index e4aab16a7..dcfa0b7b6 100644 --- a/spec/views/members/show.rss.haml_spec.rb +++ b/spec/views/members/show.rss.haml_spec.rb @@ -16,11 +16,11 @@ require 'rails_helper' -describe 'members/show.rss.haml', :type => "view" do +describe 'members/show.rss.haml', type: "view" do before(:each) do @member = assign(:member, FactoryGirl.create(:member)) - @post1 = FactoryGirl.create(:post, :id => 1, :author => @member) - @post2 = FactoryGirl.create(:markdown_post, :id => 2, :author => @member) + @post1 = FactoryGirl.create(:post, id: 1, author: @member) + @post2 = FactoryGirl.create(:markdown_post, id: 2, author: @member) assign(:posts, [@post1, @post2]) render end diff --git a/spec/views/notifications/index.html.haml_spec.rb b/spec/views/notifications/index.html.haml_spec.rb index 362037cce..a7ec6a696 100644 --- a/spec/views/notifications/index.html.haml_spec.rb +++ b/spec/views/notifications/index.html.haml_spec.rb @@ -24,8 +24,8 @@ describe "notifications/index" do context "ordinary notifications" do before(:each) do - @notification = FactoryGirl.create(:notification, :sender => @member, - :recipient => @member) + @notification = FactoryGirl.create(:notification, sender: @member, + recipient: @member) assign(:notifications, Kaminari.paginate_array([ @notification, @notification ]).page(1)) render end @@ -33,19 +33,19 @@ describe "notifications/index" do it "renders a list of notifications" do assert_select "table" - assert_select "tr>td", :text => @notification.sender.to_s, :count => 2 - assert_select "tr>td", :text => @notification.subject, :count => 2 + assert_select "tr>td", text: @notification.sender.to_s, count: 2 + assert_select "tr>td", text: @notification.subject, count: 2 end it "links to sender's profile" do - assert_select "a", :href => member_path(@notification.sender) + assert_select "a", href: member_path(@notification.sender) end end context "no subject" do it "shows (no subject)" do @notification = FactoryGirl.create(:notification, - :sender => @member, :recipient => @member, :subject => nil) + sender: @member, recipient: @member, subject: nil) assign(:notifications, Kaminari.paginate_array([@notification]).page(1)) render rendered.should have_content "(no subject)" @@ -55,7 +55,7 @@ describe "notifications/index" do context "whitespace-only subject" do it "shows (no subject)" do @notification = FactoryGirl.create(:notification, - :sender => @member, :recipient => @member, :subject => " ") + sender: @member, recipient: @member, subject: " ") assign(:notifications, Kaminari.paginate_array([@notification]).page(1)) render rendered.should have_content "(no subject)" diff --git a/spec/views/notifications/new.html.haml_spec.rb b/spec/views/notifications/new.html.haml_spec.rb index 2ec73bca3..b2e6cd125 100644 --- a/spec/views/notifications/new.html.haml_spec.rb +++ b/spec/views/notifications/new.html.haml_spec.rb @@ -20,16 +20,16 @@ describe "notifications/new" do before(:each) do @recipient = FactoryGirl.create(:member) @sender = FactoryGirl.create(:member) - assign(:notification, FactoryGirl.create(:notification, :recipient_id => @recipient.id, :sender_id => @sender.id)) + assign(:notification, FactoryGirl.create(:notification, recipient_id: @recipient.id, sender_id: @sender.id)) sign_in @sender controller.stub(:current_user) { @sender} end it "renders new message form" do render - assert_select "form", :action => notifications_path, :method => "notification" do - assert_select "input#notification_subject", :name => "notification[subject]" - assert_select "textarea#notification_body", :name => "notification[body]" + assert_select "form", action: notifications_path, method: "notification" do + assert_select "input#notification_subject", name: "notification[subject]" + assert_select "textarea#notification_body", name: "notification[body]" end end @@ -40,18 +40,18 @@ describe "notifications/new" do it "puts the recipient in a hidden field" do render - assert_select "input#notification_recipient_id[type=hidden]", :name => "notification[recipient_id]" + assert_select "input#notification_recipient_id[type=hidden]", name: "notification[recipient_id]" end it "fills in the subject if provided" do assign(:subject, 'Foo') render - assert_select "input#notification_subject", :value => "Foo" + assert_select "input#notification_subject", value: "Foo" end it "leaves the subject empty if not provided" do render - assert_select "input#notification_subject", :value => "" + assert_select "input#notification_subject", value: "" end it "Tells you to write your message here" do diff --git a/spec/views/notifications/show.html.haml_spec.rb b/spec/views/notifications/show.html.haml_spec.rb index 4e9f27dbf..42b732ad5 100644 --- a/spec/views/notifications/show.html.haml_spec.rb +++ b/spec/views/notifications/show.html.haml_spec.rb @@ -19,7 +19,7 @@ require 'rails_helper' describe "notifications/show" do before(:each) do @member = FactoryGirl.create(:member) - @notification = FactoryGirl.create(:notification, :recipient => @member) + @notification = FactoryGirl.create(:notification, recipient: @member) assign(:notification, @notification) @reply_link = assign(:reply_link, new_notification_path) controller.stub(:current_user) { @member } diff --git a/spec/views/notifier/notify.html.haml_spec.rb b/spec/views/notifier/notify.html.haml_spec.rb index 787470805..1a4a607bc 100644 --- a/spec/views/notifier/notify.html.haml_spec.rb +++ b/spec/views/notifier/notify.html.haml_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'notifier/notify.html.haml', :type => "view" do +describe 'notifier/notify.html.haml', type: "view" do before(:each) do @notification = FactoryGirl.create(:notification) @@ -36,7 +36,7 @@ describe 'notifier/notify.html.haml', :type => "view" do end it 'should include a reply link' do - assert_select "a[href=#{@reply_link}]", :text => /Reply/ + assert_select "a[href=#{@reply_link}]", text: /Reply/ end it 'should contain a link to your inbox' do @@ -45,8 +45,8 @@ describe 'notifier/notify.html.haml', :type => "view" do it 'should have fully qualified URLs' do # lots of lovely fully qualified URLs - assert_select "a[href^=http]", { :minimum => 4 } + assert_select "a[href^=http]", { minimum: 4 } # no relative URLs starting with / - assert_select "a[href^=/]", { :count => 0 } + assert_select "a[href^=/]", { count: 0 } end end diff --git a/spec/views/orders/index.html.haml_spec.rb b/spec/views/orders/index.html.haml_spec.rb index 1ca2889e0..3efdce690 100644 --- a/spec/views/orders/index.html.haml_spec.rb +++ b/spec/views/orders/index.html.haml_spec.rb @@ -20,8 +20,8 @@ describe "orders/index" do before(:each) do @member = FactoryGirl.create(:member) sign_in @member - @order1 = FactoryGirl.create(:order, :member => @member) - @order2 = FactoryGirl.create(:completed_order, :member => @member) + @order1 = FactoryGirl.create(:order, member: @member) + @order2 = FactoryGirl.create(:completed_order, member: @member) assign(:orders, [ @order1, @order2 ]) end @@ -33,7 +33,7 @@ describe "orders/index" do it "renders a list of orders" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => @order1.id - assert_select "tr>td", :text => @order2.id + assert_select "tr>td", text: @order1.id + assert_select "tr>td", text: @order2.id end end diff --git a/spec/views/orders/show.html.haml_spec.rb b/spec/views/orders/show.html.haml_spec.rb index 3779795e6..c4a2de1cf 100644 --- a/spec/views/orders/show.html.haml_spec.rb +++ b/spec/views/orders/show.html.haml_spec.rb @@ -26,11 +26,11 @@ describe "orders/show" do context "current order" do before(:each) do - @order = assign(:order, FactoryGirl.create(:order, :member => @member)) + @order = assign(:order, FactoryGirl.create(:order, member: @member)) @order_item = FactoryGirl.create(:order_item, - :order => @order, - :quantity => 2, - :price => 9900 + order: @order, + quantity: 2, + price: 9900 ) render end @@ -40,7 +40,7 @@ describe "orders/show" do end it "shows order items in a table" do - assert_select "table>tr>th", :text => "Product" + assert_select "table>tr>th", text: "Product" end it "shows the total" do @@ -62,27 +62,27 @@ describe "orders/show" do end it "shows a delete order button" do - assert_select "a", :text => "Delete this order" + assert_select "a", text: "Delete this order" end end context "completed order" do before(:each) do - @order = assign(:order, FactoryGirl.create(:completed_order, :member => @member)) + @order = assign(:order, FactoryGirl.create(:completed_order, member: @member)) @order_item = FactoryGirl.create(:order_item, - :order => @order, - :quantity => 2, - :price => 9900 + order: @order, + quantity: 2, + price: 9900 ) render end it "doesn't show a checkout button" do - assert_select "a", :text => "Checkout", :count => 0 + assert_select "a", text: "Checkout", count: 0 end it "doesn't show delete order button" do - assert_select "a", :text => "Delete this order", :count => 0 + assert_select "a", text: "Delete this order", count: 0 end end diff --git a/spec/views/photos/edit.html.haml_spec.rb b/spec/views/photos/edit.html.haml_spec.rb index a13aea7c6..6df82b418 100644 --- a/spec/views/photos/edit.html.haml_spec.rb +++ b/spec/views/photos/edit.html.haml_spec.rb @@ -19,10 +19,10 @@ require 'rails_helper' describe "photos/edit" do before(:each) do @photo = assign(:photo, stub_model(Photo, - :owner_id => 1, - :flickr_photo_id => 1, - :thumbnail_url => "MyString", - :fullsize_url => "MyString" + owner_id: 1, + flickr_photo_id: 1, + thumbnail_url: "MyString", + fullsize_url: "MyString" )) end diff --git a/spec/views/photos/index.html.haml_spec.rb b/spec/views/photos/index.html.haml_spec.rb index 866302895..1741d9aa3 100644 --- a/spec/views/photos/index.html.haml_spec.rb +++ b/spec/views/photos/index.html.haml_spec.rb @@ -32,7 +32,7 @@ describe "photos/index" do it "renders a gallery of photos" do render - assert_select ".thumbnail", :count => 2 - assert_select "img", :count => 2 + assert_select ".thumbnail", count: 2 + assert_select "img", count: 2 end end diff --git a/spec/views/photos/new.html.haml_spec.rb b/spec/views/photos/new.html.haml_spec.rb index 3c2321aef..46489e87e 100644 --- a/spec/views/photos/new.html.haml_spec.rb +++ b/spec/views/photos/new.html.haml_spec.rb @@ -27,7 +27,7 @@ describe "photos/new" do pager.replace([]) end assign(:photos, photos) - assign(:flickr_auth, FactoryGirl.create(:flickr_authentication, :member => @member)) + assign(:flickr_auth, FactoryGirl.create(:flickr_authentication, member: @member)) end context "user has no photosets" do diff --git a/spec/views/photos/show.html.haml_spec.rb b/spec/views/photos/show.html.haml_spec.rb index 941badb66..a7e014eac 100644 --- a/spec/views/photos/show.html.haml_spec.rb +++ b/spec/views/photos/show.html.haml_spec.rb @@ -24,7 +24,7 @@ describe "photos/show" do context "CC-licensed photo" do before(:each) do - @photo = assign(:photo, FactoryGirl.create(:photo, :owner => @member)) + @photo = assign(:photo, FactoryGirl.create(:photo, owner: @member)) render end @@ -33,16 +33,16 @@ describe "photos/show" do end it "links to the owner's profile" do - assert_select "a", :href => @photo.owner + assert_select "a", href: @photo.owner end it "links to the CC license" do - assert_select "a", :href => @photo.license_url, - :text => @photo.license_name + assert_select "a", href: @photo.license_url, + text: @photo.license_name end it "shows a link to the original image" do - assert_select "a", :href => @photo.link_url, :text => "View on Flickr" + assert_select "a", href: @photo.link_url, text: "View on Flickr" end it "has a delete button" do diff --git a/spec/views/places/_map_attribution.html.haml_spec.rb b/spec/views/places/_map_attribution.html.haml_spec.rb index e2bc7e5b0..cbb305ed6 100644 --- a/spec/views/places/_map_attribution.html.haml_spec.rb +++ b/spec/views/places/_map_attribution.html.haml_spec.rb @@ -16,22 +16,22 @@ require 'rails_helper' -describe "places/_map_attribution.html.haml", :type => :view do +describe "places/_map_attribution.html.haml", type: :view do before(:each) do render end it "links to OpenStreetMap" do - assert_select "a", :href => "http://openstreetmap.org", - :text => "OpenStreetMap" + assert_select "a", href: "http://openstreetmap.org", + text: "OpenStreetMap" end it "links to the ODbL" do - assert_select "a", :href => "http://www.openstreetmap.org/copyright", - :text => "ODbL" + assert_select "a", href: "http://www.openstreetmap.org/copyright", + text: "ODbL" end it "links to CloudMade" do - assert_select "a", :href => "http://cloudmade.com", :text => "CloudMade" + assert_select "a", href: "http://cloudmade.com", text: "CloudMade" end end diff --git a/spec/views/places/show.html.haml_spec.rb b/spec/views/places/show.html.haml_spec.rb index 13884eb3b..7cfa2c16c 100644 --- a/spec/views/places/show.html.haml_spec.rb +++ b/spec/views/places/show.html.haml_spec.rb @@ -31,7 +31,7 @@ describe "places/show" do end it "shows the selected place in the textbox" do - assert_select "#new_place", :value => @place + assert_select "#new_place", value: @place end it "shows the names of nearby members" do diff --git a/spec/views/plant_parts/edit.html.haml_spec.rb b/spec/views/plant_parts/edit.html.haml_spec.rb index fc25b711b..1f92923d8 100644 --- a/spec/views/plant_parts/edit.html.haml_spec.rb +++ b/spec/views/plant_parts/edit.html.haml_spec.rb @@ -19,7 +19,7 @@ require 'rails_helper' describe "plant_parts/edit" do before(:each) do @plant_part = assign(:plant_part, stub_model(PlantPart, - :name => "MyString" + name: "MyString" )) end @@ -27,8 +27,8 @@ describe "plant_parts/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => plant_parts_path(@plant_part), :method => "post" do - assert_select "input#plant_part_name", :name => "plant_part[name]" + assert_select "form", action: plant_parts_path(@plant_part), method: "post" do + assert_select "input#plant_part_name", name: "plant_part[name]" end end end diff --git a/spec/views/plant_parts/index.html.haml_spec.rb b/spec/views/plant_parts/index.html.haml_spec.rb index 256810ac3..1fe26abba 100644 --- a/spec/views/plant_parts/index.html.haml_spec.rb +++ b/spec/views/plant_parts/index.html.haml_spec.rb @@ -26,7 +26,7 @@ describe "plant_parts/index" do it "renders a list of plant_parts" do render rendered.should have_content @pp.name - assert_select "a", :href => plant_part_path(@pp) + assert_select "a", href: plant_part_path(@pp) end end diff --git a/spec/views/plant_parts/new.html.haml_spec.rb b/spec/views/plant_parts/new.html.haml_spec.rb index 64b572ef7..213eee57a 100644 --- a/spec/views/plant_parts/new.html.haml_spec.rb +++ b/spec/views/plant_parts/new.html.haml_spec.rb @@ -19,7 +19,7 @@ require 'rails_helper' describe "plant_parts/new" do before(:each) do assign(:plant_part, stub_model(PlantPart, - :name => "MyString" + name: "MyString" ).as_new_record) end @@ -27,8 +27,8 @@ describe "plant_parts/new" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => plant_parts_path, :method => "post" do - assert_select "input#plant_part_name", :name => "plant_part[name]" + assert_select "form", action: plant_parts_path, method: "post" do + assert_select "input#plant_part_name", name: "plant_part[name]" end end end diff --git a/spec/views/plant_parts/show.html.haml_spec.rb b/spec/views/plant_parts/show.html.haml_spec.rb index fa839419f..7c23b9bb9 100644 --- a/spec/views/plant_parts/show.html.haml_spec.rb +++ b/spec/views/plant_parts/show.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "plant_parts/show" do before(:each) do controller.stub(:current_user) { nil } @pp = FactoryGirl.create(:plant_part) - @harvest = FactoryGirl.create(:harvest, :plant_part => @pp) + @harvest = FactoryGirl.create(:harvest, plant_part: @pp) assign(:plant_part, @pp) end @@ -28,7 +28,7 @@ describe "plant_parts/show" do render @pp.crops.each do |c| rendered.should have_content c.name - assert_select "a", :href => crop_path(c) + assert_select "a", href: crop_path(c) end end end diff --git a/spec/views/plantings/_form.html.haml_spec.rb b/spec/views/plantings/_form.html.haml_spec.rb index f65fd82eb..a8565dfda 100644 --- a/spec/views/plantings/_form.html.haml_spec.rb +++ b/spec/views/plantings/_form.html.haml_spec.rb @@ -20,15 +20,15 @@ describe "plantings/_form" do before(:each) do controller.stub(:current_user) { nil } @member = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @member) + @garden = FactoryGirl.create(:garden, owner: @member) @uppercase = FactoryGirl.create(:uppercasecrop) @lowercase = FactoryGirl.create(:lowercasecrop) @crop = @lowercase # needed to render the form @planting = FactoryGirl.create(:planting, - :garden => @garden, - :crop => @crop, - :planted_at => Date.new(2013, 03, 01) + garden: @garden, + crop: @crop, + planted_at: Date.new(2013, 03, 01) ) render end diff --git a/spec/views/plantings/edit.html.haml_spec.rb b/spec/views/plantings/edit.html.haml_spec.rb index f0af66587..b71b34d2a 100644 --- a/spec/views/plantings/edit.html.haml_spec.rb +++ b/spec/views/plantings/edit.html.haml_spec.rb @@ -19,8 +19,8 @@ require 'rails_helper' describe "plantings/edit" do before(:each) do @member = FactoryGirl.create(:member, - :login_name => 'right', - :email => 'right@example.com' + login_name: 'right', + email: 'right@example.com' ) # creating two crops to make sure that the correct one is selected @@ -29,11 +29,11 @@ describe "plantings/edit" do @maize = FactoryGirl.create(:maize) # and likewise for gardens - @garden = FactoryGirl.create(:garden_z, :owner => @member) - @garden2 = FactoryGirl.create(:garden_a, :owner => @member) + @garden = FactoryGirl.create(:garden_z, owner: @member) + @garden2 = FactoryGirl.create(:garden_a, owner: @member) @planting = assign(:planting, - FactoryGirl.create(:planting, :garden => @garden, :crop => @tomato) + FactoryGirl.create(:planting, garden: @garden, crop: @tomato) ) end @@ -46,16 +46,16 @@ describe "plantings/edit" do end it "renders the edit planting form" do - assert_select "form", :action => plantings_path(@planting), :method => "post" do - assert_select "input#planting_quantity", :name => "planting[quantity]" - assert_select "textarea#planting_description", :name => "planting[description]" - assert_select "select#planting_sunniness", :name => "planting[sunniness]" - assert_select "select#planting_planted_from", :name => "planting[planted_from]" + assert_select "form", action: plantings_path(@planting), method: "post" do + assert_select "input#planting_quantity", name: "planting[quantity]" + assert_select "textarea#planting_description", name: "planting[description]" + assert_select "select#planting_sunniness", name: "planting[sunniness]" + assert_select "select#planting_planted_from", name: "planting[planted_from]" end end it 'includes helpful links for crops and gardens' do - assert_select "a[href=#{new_garden_path}]", :text => "Add a garden." + assert_select "a[href=#{new_garden_path}]", text: "Add a garden." end it "chooses the right crop" do @@ -64,7 +64,7 @@ describe "plantings/edit" do it "chooses the right garden" do assert_select "select#planting_garden_id", - :html => /option selected="selected" value="#{@garden.id}"/ + html: /option selected="selected" value="#{@garden.id}"/ end end diff --git a/spec/views/plantings/index.html.haml_spec.rb b/spec/views/plantings/index.html.haml_spec.rb index 9c890caf4..928735dde 100644 --- a/spec/views/plantings/index.html.haml_spec.rb +++ b/spec/views/plantings/index.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "plantings/index" do before(:each) do controller.stub(:current_user) { nil } @member = FactoryGirl.create(:member) - @garden = FactoryGirl.create(:garden, :owner => @member) + @garden = FactoryGirl.create(:garden, owner: @member) @tomato = FactoryGirl.create(:tomato) @maize = FactoryGirl.create(:maize) page = 1 @@ -29,22 +29,22 @@ describe "plantings/index" do plantings = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| pager.replace([ FactoryGirl.create(:planting, - :garden => @garden, - :crop => @tomato, - :owner => @member + garden: @garden, + crop: @tomato, + owner: @member ), FactoryGirl.create(:planting, - :garden => @garden, - :crop => @maize, - :description => '', - :planted_at => Time.local(2013, 1, 13) + garden: @garden, + crop: @maize, + description: '', + planted_at: Time.local(2013, 1, 13) ), FactoryGirl.create(:planting, - :garden => @garden, - :crop => @tomato, - :planted_at => Time.local(2013, 1, 13), - :finished_at => Time.local(2013, 1, 20), - :finished => true + garden: @garden, + crop: @tomato, + planted_at: Time.local(2013, 1, 13), + finished_at: Time.local(2013, 1, 20), + finished: true ) ]) end @@ -70,9 +70,9 @@ describe "plantings/index" do it "provides data links" do render rendered.should have_content "The data on this page is available in the following formats:" - assert_select "a", :href => plantings_path(:format => 'csv') - assert_select "a", :href => plantings_path(:format => 'json') - assert_select "a", :href => plantings_path(:format => 'rss') + assert_select "a", href: plantings_path(format: 'csv') + assert_select "a", href: plantings_path(format: 'json') + assert_select "a", href: plantings_path(format: 'rss') end it "displays member's name in title" do diff --git a/spec/views/plantings/new.html.haml_spec.rb b/spec/views/plantings/new.html.haml_spec.rb index 0227a0f79..cd3a95445 100644 --- a/spec/views/plantings/new.html.haml_spec.rb +++ b/spec/views/plantings/new.html.haml_spec.rb @@ -22,14 +22,14 @@ describe "plantings/new" do controller.stub(:current_user) { @member } # create gardens and crops to populate dropdowns - @garden_a = FactoryGirl.create(:garden, :owner => @member) - @garden_z = FactoryGirl.create(:garden, :owner => @member) + @garden_a = FactoryGirl.create(:garden, owner: @member) + @garden_z = FactoryGirl.create(:garden, owner: @member) @crop1 = FactoryGirl.create(:tomato) @crop2 = FactoryGirl.create(:maize) assign(:planting, FactoryGirl.create(:planting, - :garden => @garden_a, - :crop => @crop2 + garden: @garden_a, + crop: @crop2 )) end @@ -44,24 +44,24 @@ describe "plantings/new" do end it "renders new planting form" do - assert_select "form", :action => plantings_path, :method => "post" do - assert_select "select#planting_garden_id", :name => "planting[garden_id]" - assert_select "input#crop", :class => "ui-autocomplete-input" - assert_select "input#planting_crop_id", :name => "planting[crop_id]" - assert_select "input#planting_quantity", :name => "planting[quantity]" - assert_select "textarea#planting_description", :name => "planting[description]" - assert_select "select#planting_sunniness", :name => "planting[sunniness]" - assert_select "select#planting_planted_from", :name => "planting[planted_from]" + assert_select "form", action: plantings_path, method: "post" do + assert_select "select#planting_garden_id", name: "planting[garden_id]" + assert_select "input#crop", class: "ui-autocomplete-input" + assert_select "input#planting_crop_id", name: "planting[crop_id]" + assert_select "input#planting_quantity", name: "planting[quantity]" + assert_select "textarea#planting_description", name: "planting[description]" + assert_select "select#planting_sunniness", name: "planting[sunniness]" + assert_select "select#planting_planted_from", name: "planting[planted_from]" end end it 'includes helpful links for crops and gardens' do - assert_select "a[href=#{new_garden_path}]", :text => "Add a garden." + assert_select "a[href=#{new_garden_path}]", text: "Add a garden." end it "selects a garden given in a param" do assert_select "select#planting_garden_id", - :html => /option selected="selected" value="#{@garden_z.id}"/ + html: /option selected="selected" value="#{@garden_z.id}"/ end end end diff --git a/spec/views/plantings/show.html.haml_spec.rb b/spec/views/plantings/show.html.haml_spec.rb index d0eed00ac..79faf1d1d 100644 --- a/spec/views/plantings/show.html.haml_spec.rb +++ b/spec/views/plantings/show.html.haml_spec.rb @@ -18,11 +18,11 @@ require 'rails_helper' describe "plantings/show" do def create_planting_for(member) - @garden = FactoryGirl.create(:garden, :owner => @member) + @garden = FactoryGirl.create(:garden, owner: @member) @crop = FactoryGirl.create(:tomato) @planting = assign(:planting, - FactoryGirl.create(:planting, :garden => @garden, :crop => @crop, - :planted_from => 'cutting') + FactoryGirl.create(:planting, garden: @garden, crop: @crop, + planted_from: 'cutting') ) end @@ -67,7 +67,7 @@ describe "plantings/show" do end it "shows photos" do - @photo = FactoryGirl.create(:photo, :owner => @member) + @photo = FactoryGirl.create(:photo, owner: @member) @p.photos << @photo render assert_select "img[src=#{@photo.thumbnail_url}]" diff --git a/spec/views/policy/community_spec.rb b/spec/views/policy/community_spec.rb index df7c828fb..a56139aad 100644 --- a/spec/views/policy/community_spec.rb +++ b/spec/views/policy/community_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'policy/community.html.haml', :type => "view" do +describe 'policy/community.html.haml', type: "view" do before(:each) do render end diff --git a/spec/views/policy/tos_spec.rb b/spec/views/policy/tos_spec.rb index 56f08e928..baac388da 100644 --- a/spec/views/policy/tos_spec.rb +++ b/spec/views/policy/tos_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'policy/tos.html.haml', :type => "view" do +describe 'policy/tos.html.haml', type: "view" do before(:each) do render end diff --git a/spec/views/posts/_single.html.haml_spec.rb b/spec/views/posts/_single.html.haml_spec.rb index 284542965..75a57b99c 100644 --- a/spec/views/posts/_single.html.haml_spec.rb +++ b/spec/views/posts/_single.html.haml_spec.rb @@ -19,7 +19,7 @@ require 'rails_helper' describe "posts/_single" do def render_post() - render :partial => "single", :locals => { :post => @post } + render partial: "single", locals: { post: @post } end before(:each) do @@ -37,7 +37,7 @@ describe "posts/_single" do end it "doesn't contain a link to new comment" do - assert_select "a[href=#{new_comment_path(:post_id => @post.id)}]", false + assert_select "a[href=#{new_comment_path(post_id: @post.id)}]", false end end @@ -50,7 +50,7 @@ describe "posts/_single" do end it "contains link to new comment" do - assert_select "a[href=#{new_comment_path(:post_id => @post.id)}]", "Reply" + assert_select "a[href=#{new_comment_path(post_id: @post.id)}]", "Reply" end it "does not contain an edit link" do @@ -63,7 +63,7 @@ describe "posts/_single" do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_user) { @member } - @post = FactoryGirl.create(:post, :author => @member) + @post = FactoryGirl.create(:post, author: @member) render_post end @@ -84,7 +84,7 @@ describe "posts/_single" do context "when there is 1 comment" do before(:each) do - @comment = FactoryGirl.create(:comment, :post => @post) + @comment = FactoryGirl.create(:comment, post: @post) render_post end @@ -95,8 +95,8 @@ describe "posts/_single" do context "when there are 2 comments" do before(:each) do - @comment = FactoryGirl.create(:comment, :post => @post) - @comment2 = FactoryGirl.create(:comment, :post => @post) + @comment = FactoryGirl.create(:comment, post: @post) + @comment2 = FactoryGirl.create(:comment, post: @post) render_post end @@ -110,9 +110,9 @@ describe "posts/_single" do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_user) { @member } - @comment = FactoryGirl.create(:comment, :post => @post) - render :partial => "single", :locals => { - :post => @post, :hide_comments => true + @comment = FactoryGirl.create(:comment, post: @post) + render partial: "single", locals: { + post: @post, hide_comments: true } end @@ -125,7 +125,7 @@ describe "posts/_single" do end it "does not contain link to new comment" do - assert_select "a[href=#{new_comment_path(:post_id => @post.id)}]", false + assert_select "a[href=#{new_comment_path(post_id: @post.id)}]", false end end diff --git a/spec/views/posts/edit.html.haml_spec.rb b/spec/views/posts/edit.html.haml_spec.rb index 12fd02c27..e0a557db6 100644 --- a/spec/views/posts/edit.html.haml_spec.rb +++ b/spec/views/posts/edit.html.haml_spec.rb @@ -20,7 +20,7 @@ describe "posts/edit" do before(:each) do controller.stub(:current_user) { nil } @author = FactoryGirl.create(:member) - @post = assign(:post, FactoryGirl.create(:post, :author => @author)) + @post = assign(:post, FactoryGirl.create(:post, author: @author)) end context "logged in" do @@ -30,9 +30,9 @@ describe "posts/edit" do end it "renders the edit post form" do - assert_select "form", :action => posts_path(@post), :method => "post" do - assert_select "input#post_subject", :name => "post[subject]" - assert_select "textarea#post_body", :name => "post[body]" + assert_select "form", action: posts_path(@post), method: "post" do + assert_select "input#post_subject", name: "post[subject]" + assert_select "textarea#post_body", name: "post[body]" end end @@ -48,8 +48,8 @@ describe "posts/edit" do before(:each) do @forum = assign(:forum, FactoryGirl.create(:forum)) assign(:post, FactoryGirl.create( :post, - :forum => @forum, - :author => @author + forum: @forum, + author: @author )) render end diff --git a/spec/views/posts/index.html.haml_spec.rb b/spec/views/posts/index.html.haml_spec.rb index 2f2f42d78..1290cc2c7 100644 --- a/spec/views/posts/index.html.haml_spec.rb +++ b/spec/views/posts/index.html.haml_spec.rb @@ -25,8 +25,8 @@ describe "posts/index" do total_entries = 2 posts = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| pager.replace([ - FactoryGirl.create(:post, :author => @author), - FactoryGirl.create(:post, :author => @author) + FactoryGirl.create(:post, author: @author), + FactoryGirl.create(:post, author: @author) ]) end assign(:posts, posts) @@ -34,18 +34,18 @@ describe "posts/index" do end it "renders a list of posts" do - assert_select "div.post", :count => 2 - assert_select "h3", :text => "A Post".to_s, :count => 2 + assert_select "div.post", count: 2 + assert_select "h3", text: "A Post".to_s, count: 2 assert_select "div.post-body", - :text => "This is some text.".to_s, :count => 2 + text: "This is some text.".to_s, count: 2 end it "contains two gravatar icons" do - assert_select "img", :src => /gravatar\.com\/avatar/, :count => 2 + assert_select "img", src: /gravatar\.com\/avatar/, count: 2 end it "contains RSS feed links for posts and comments" do - assert_select "a", :href => posts_path(:format => 'rss') - assert_select "a", :href => comments_path(:format => 'rss') + assert_select "a", href: posts_path(format: 'rss') + assert_select "a", href: comments_path(format: 'rss') end end diff --git a/spec/views/posts/index.rss.haml_spec.rb b/spec/views/posts/index.rss.haml_spec.rb index b29dae565..496311efc 100644 --- a/spec/views/posts/index.rss.haml_spec.rb +++ b/spec/views/posts/index.rss.haml_spec.rb @@ -16,12 +16,12 @@ require 'rails_helper' -describe 'posts/index.rss.haml', :type => "view" do +describe 'posts/index.rss.haml', type: "view" do before(:each) do controller.stub(:current_user) { nil } author = FactoryGirl.create(:member) - @post1 = FactoryGirl.create(:post, :id => 1, :author => author) - @post2 = FactoryGirl.create(:post, :id => 2, :author => author) + @post1 = FactoryGirl.create(:post, id: 1, author: author) + @post2 = FactoryGirl.create(:post, id: 2, author: author) assign(:posts, [@post1, @post2]) render end diff --git a/spec/views/posts/new.html.haml_spec.rb b/spec/views/posts/new.html.haml_spec.rb index 8b0da615e..e9d26ba5e 100644 --- a/spec/views/posts/new.html.haml_spec.rb +++ b/spec/views/posts/new.html.haml_spec.rb @@ -19,7 +19,7 @@ require 'rails_helper' describe "posts/new" do before(:each) do @author = FactoryGirl.create(:member) - assign(:post, FactoryGirl.create(:post, :author => @author)) + assign(:post, FactoryGirl.create(:post, author: @author)) # assign(:forum, Forum.new) sign_in @author controller.stub(:current_user) { @author } @@ -27,9 +27,9 @@ describe "posts/new" do it "renders new post form" do render - assert_select "form", :action => posts_path, :method => "post" do - assert_select "input#post_subject", :name => "post[subject]" - assert_select "textarea#post_body", :name => "post[body]" + assert_select "form", action: posts_path, method: "post" do + assert_select "input#post_subject", name: "post[subject]" + assert_select "textarea#post_body", name: "post[body]" end end @@ -51,7 +51,7 @@ describe "posts/new" do context "forum specified" do before(:each) do @forum = assign(:forum, FactoryGirl.create(:forum)) - assign(:post, FactoryGirl.create(:post, :forum => @forum)) + assign(:post, FactoryGirl.create(:post, forum: @forum)) render end diff --git a/spec/views/posts/show.html.haml_spec.rb b/spec/views/posts/show.html.haml_spec.rb index 13faf053d..e95d888b8 100644 --- a/spec/views/posts/show.html.haml_spec.rb +++ b/spec/views/posts/show.html.haml_spec.rb @@ -24,7 +24,7 @@ describe "posts/show" do it "renders the post" do @post = assign(:post, - FactoryGirl.create(:post, :author => @author)) + FactoryGirl.create(:post, author: @author)) render # show the name of the member who posted the post rendered.should match(/member\d+/) @@ -37,14 +37,14 @@ describe "posts/show" do it "should parse markdown into html" do @post = assign(:post, - FactoryGirl.create(:markdown_post, :author => @author)) + FactoryGirl.create(:markdown_post, author: @author)) render assert_select "strong", "strong" end it "shouldn't let html through in body" do @post = assign(:post, - FactoryGirl.create(:html_post, :author => @author)) + FactoryGirl.create(:html_post, author: @author)) render rendered.should match(/EVIL/) rendered.should_not match(/a href="http:\/\/evil.com"/) @@ -52,7 +52,7 @@ describe "posts/show" do it 'has an anchor to the comments' do @post = assign(:post, - FactoryGirl.create(:post, :author => @author)) + FactoryGirl.create(:post, author: @author)) render assert_select 'a[name=comments]' end @@ -60,8 +60,8 @@ describe "posts/show" do context "when there is one comment" do before(:each) do @post = assign(:post, - FactoryGirl.create(:html_post, :author => @author)) - @comment = FactoryGirl.create(:comment, :post => @post) + FactoryGirl.create(:html_post, author: @author)) + @comment = FactoryGirl.create(:comment, post: @post) @comments = @post.comments render end @@ -82,14 +82,14 @@ describe "posts/show" do context "when there is more than one comment" do before(:each) do @post = assign(:post, - FactoryGirl.create(:html_post, :author => @author)) - @comment1 = FactoryGirl.create(:comment, :post => @post, :body => "F1rst!!!", - :created_at => Date.new(2010, 5, 17)) - @comment3 = FactoryGirl.create(:comment, :post => @post, :body => "Th1rd!!!", - :created_at => Date.new(2012, 5, 17)) - @comment4 = FactoryGirl.create(:comment, :post => @post, :body => "F0urth!!!") - @comment2 = FactoryGirl.create(:comment, :post => @post, :body => "S3c0nd!!1!", - :created_at => Date.new(2011, 5, 17)) + FactoryGirl.create(:html_post, author: @author)) + @comment1 = FactoryGirl.create(:comment, post: @post, body: "F1rst!!!", + created_at: Date.new(2010, 5, 17)) + @comment3 = FactoryGirl.create(:comment, post: @post, body: "Th1rd!!!", + created_at: Date.new(2012, 5, 17)) + @comment4 = FactoryGirl.create(:comment, post: @post, body: "F0urth!!!") + @comment2 = FactoryGirl.create(:comment, post: @post, body: "S3c0nd!!1!", + created_at: Date.new(2011, 5, 17)) @comments = @post.comments render end @@ -102,7 +102,7 @@ describe "posts/show" do context "forum post" do it "shows forum name" do @post = assign(:post, - FactoryGirl.create(:forum_post, :author => @author)) + FactoryGirl.create(:forum_post, author: @author)) render rendered.should have_content "in #{@post.forum.name}" end @@ -113,12 +113,12 @@ describe "posts/show" do sign_in @author controller.stub(:current_user) { @author } @post = assign(:post, - FactoryGirl.create(:post, :author => @author)) + FactoryGirl.create(:post, author: @author)) render end it 'shows a comment button' do - assert_select "a[href=#{new_comment_path(:post_id => @post.id)}]", "Comment" + assert_select "a[href=#{new_comment_path(post_id: @post.id)}]", "Comment" end end diff --git a/spec/views/posts/show.rss.haml_spec.rb b/spec/views/posts/show.rss.haml_spec.rb index 08d6da814..abe9b81f4 100644 --- a/spec/views/posts/show.rss.haml_spec.rb +++ b/spec/views/posts/show.rss.haml_spec.rb @@ -21,8 +21,8 @@ describe 'posts/show.rss.haml' do controller.stub(:current_user) { nil } @author = FactoryGirl.create(:member) @post = FactoryGirl.create(:post) - FactoryGirl.create(:comment, :author => @author, :post => @post) - FactoryGirl.create(:comment, :author => @author, :post => @post) + FactoryGirl.create(:comment, author: @author, post: @post) + FactoryGirl.create(:comment, author: @author, post: @post) assign(:post, @post) render end diff --git a/spec/views/products/edit.html.haml_spec.rb b/spec/views/products/edit.html.haml_spec.rb index 4574064a7..107a32284 100644 --- a/spec/views/products/edit.html.haml_spec.rb +++ b/spec/views/products/edit.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "products/edit" do before(:each) do @product = assign(:product, stub_model(Product, - :name => "MyString", - :description => "MyString", - :min_price => "9.99" + name: "MyString", + description: "MyString", + min_price: "9.99" )) end @@ -29,11 +29,11 @@ describe "products/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => products_path(@product), :method => "post" do - assert_select "input#product_name", :name => "product[name]" - assert_select "textarea#product_description", :name => "product[description]" - assert_select "input#product_min_price", :name => "product[min_price]" - assert_select "input#product_recommended_price", :name => "product[recommended_price]" + assert_select "form", action: products_path(@product), method: "post" do + assert_select "input#product_name", name: "product[name]" + assert_select "textarea#product_description", name: "product[description]" + assert_select "input#product_min_price", name: "product[min_price]" + assert_select "input#product_recommended_price", name: "product[recommended_price]" end end end diff --git a/spec/views/products/index.html.haml_spec.rb b/spec/views/products/index.html.haml_spec.rb index dcd85623d..7fdaa0d20 100644 --- a/spec/views/products/index.html.haml_spec.rb +++ b/spec/views/products/index.html.haml_spec.rb @@ -25,8 +25,8 @@ describe "products/index" do it "renders a list of products" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => @product.name, :count => 2 - assert_select "tr>td", :text => @product.description, :count => 2 - assert_select "tr>td", :text => @product.min_price, :count => 2 + assert_select "tr>td", text: @product.name, count: 2 + assert_select "tr>td", text: @product.description, count: 2 + assert_select "tr>td", text: @product.min_price, count: 2 end end diff --git a/spec/views/products/new.html.haml_spec.rb b/spec/views/products/new.html.haml_spec.rb index 08986cacf..db20a5c95 100644 --- a/spec/views/products/new.html.haml_spec.rb +++ b/spec/views/products/new.html.haml_spec.rb @@ -19,9 +19,9 @@ require 'rails_helper' describe "products/new" do before(:each) do assign(:product, stub_model(Product, - :name => "MyString", - :description => "MyString", - :min_price => "9.99" + name: "MyString", + description: "MyString", + min_price: "9.99" ).as_new_record) end @@ -29,13 +29,13 @@ describe "products/new" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => products_path, :method => "post" do - assert_select "input#product_name", :name => "product[name]" - assert_select "textarea#product_description", :name => "product[description]" - assert_select "input#product_min_price", :name => "product[min_price]" - assert_select "input#product_recommended_price", :name => "product[recommended_price]" - assert_select "select#product_account_type_id", :name => "product[account_type_id]" - assert_select "input#product_paid_months", :name => "product[paid_months]" + assert_select "form", action: products_path, method: "post" do + assert_select "input#product_name", name: "product[name]" + assert_select "textarea#product_description", name: "product[description]" + assert_select "input#product_min_price", name: "product[min_price]" + assert_select "input#product_recommended_price", name: "product[recommended_price]" + assert_select "select#product_account_type_id", name: "product[account_type_id]" + assert_select "input#product_paid_months", name: "product[paid_months]" end end end diff --git a/spec/views/roles/edit.html.haml_spec.rb b/spec/views/roles/edit.html.haml_spec.rb index e4b927471..a4026f63e 100644 --- a/spec/views/roles/edit.html.haml_spec.rb +++ b/spec/views/roles/edit.html.haml_spec.rb @@ -19,8 +19,8 @@ require 'rails_helper' describe "roles/edit" do before(:each) do @role = assign(:role, stub_model(Role, - :name => "MyString", - :description => "MyText" + name: "MyString", + description: "MyText" )) end @@ -28,9 +28,9 @@ describe "roles/edit" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => roles_path(@role), :method => "post" do - assert_select "input#role_name", :name => "role[name]" - assert_select "textarea#role_description", :name => "role[description]" + assert_select "form", action: roles_path(@role), method: "post" do + assert_select "input#role_name", name: "role[name]" + assert_select "textarea#role_description", name: "role[description]" end end end diff --git a/spec/views/roles/index.html.haml_spec.rb b/spec/views/roles/index.html.haml_spec.rb index 6e821daff..fe8e40333 100644 --- a/spec/views/roles/index.html.haml_spec.rb +++ b/spec/views/roles/index.html.haml_spec.rb @@ -21,12 +21,12 @@ describe "roles/index" do controller.stub(:current_user) { nil } assign(:roles, [ stub_model(Role, - :name => "Name", - :description => "MyText" + name: "Name", + description: "MyText" ), stub_model(Role, - :name => "Name", - :description => "MyText" + name: "Name", + description: "MyText" ) ]) end @@ -34,7 +34,7 @@ describe "roles/index" do it "renders a list of roles" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "tr>td", :text => "Name".to_s, :count => 2 - assert_select "tr>td", :text => "MyText".to_s, :count => 2 + assert_select "tr>td", text: "Name".to_s, count: 2 + assert_select "tr>td", text: "MyText".to_s, count: 2 end end diff --git a/spec/views/roles/new.html.haml_spec.rb b/spec/views/roles/new.html.haml_spec.rb index 3073f7f35..01dcd4c60 100644 --- a/spec/views/roles/new.html.haml_spec.rb +++ b/spec/views/roles/new.html.haml_spec.rb @@ -19,8 +19,8 @@ require 'rails_helper' describe "roles/new" do before(:each) do assign(:role, stub_model(Role, - :name => "MyString", - :description => "MyText" + name: "MyString", + description: "MyText" ).as_new_record) end @@ -28,9 +28,9 @@ describe "roles/new" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => roles_path, :method => "post" do - assert_select "input#role_name", :name => "role[name]" - assert_select "textarea#role_description", :name => "role[description]" + assert_select "form", action: roles_path, method: "post" do + assert_select "input#role_name", name: "role[name]" + assert_select "textarea#role_description", name: "role[description]" end end end diff --git a/spec/views/roles/show.html.haml_spec.rb b/spec/views/roles/show.html.haml_spec.rb index 889535194..cc0eb506e 100644 --- a/spec/views/roles/show.html.haml_spec.rb +++ b/spec/views/roles/show.html.haml_spec.rb @@ -19,8 +19,8 @@ require 'rails_helper' describe "roles/show" do before(:each) do @role = assign(:role, stub_model(Role, - :name => "Name", - :description => "MyText" + name: "Name", + description: "MyText" )) end diff --git a/spec/views/scientific_names/edit.html.haml_spec.rb b/spec/views/scientific_names/edit.html.haml_spec.rb index f85bab335..09ff5125b 100644 --- a/spec/views/scientific_names/edit.html.haml_spec.rb +++ b/spec/views/scientific_names/edit.html.haml_spec.rb @@ -33,9 +33,9 @@ describe "scientific_names/edit" do end it "renders the edit scientific_name form" do - assert_select "form", :action => scientific_names_path(@scientific_name), :method => "post" do - assert_select "input#scientific_name_scientific_name", :name => "scientific_name[scientific_name]" - assert_select "select#scientific_name_crop_id", :name => "scientific_name[crop_id]" + assert_select "form", action: scientific_names_path(@scientific_name), method: "post" do + assert_select "input#scientific_name_scientific_name", name: "scientific_name[scientific_name]" + assert_select "select#scientific_name_crop_id", name: "scientific_name[crop_id]" end end end diff --git a/spec/views/scientific_names/index.html.haml_spec.rb b/spec/views/scientific_names/index.html.haml_spec.rb index 2fb36e99d..ea89ae101 100644 --- a/spec/views/scientific_names/index.html.haml_spec.rb +++ b/spec/views/scientific_names/index.html.haml_spec.rb @@ -27,8 +27,8 @@ describe "scientific_names/index" do it "renders a list of scientific_names" do render - assert_select "tr>td", :text => "Zea mays".to_s - assert_select "tr>td", :text => "Solanum lycopersicum".to_s + assert_select "tr>td", text: "Zea mays".to_s + assert_select "tr>td", text: "Solanum lycopersicum".to_s end it "doesn't show edit/destroy links" do diff --git a/spec/views/scientific_names/new.html.haml_spec.rb b/spec/views/scientific_names/new.html.haml_spec.rb index 2ca9f68c0..a8ad3f615 100644 --- a/spec/views/scientific_names/new.html.haml_spec.rb +++ b/spec/views/scientific_names/new.html.haml_spec.rb @@ -32,9 +32,9 @@ describe "scientific_names/new" do it "renders new scientific_name form" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => scientific_names_path, :method => "post" do - assert_select "input#scientific_name_scientific_name", :name => "scientific_name[scientific_name]" - assert_select "select#scientific_name_crop_id", :name => "scientific_name[crop_id]" + assert_select "form", action: scientific_names_path, method: "post" do + assert_select "input#scientific_name_scientific_name", name: "scientific_name[scientific_name]" + assert_select "select#scientific_name_crop_id", name: "scientific_name[crop_id]" end end diff --git a/spec/views/seeds/edit.html.haml_spec.rb b/spec/views/seeds/edit.html.haml_spec.rb index 9bdcf9447..1c9911afa 100644 --- a/spec/views/seeds/edit.html.haml_spec.rb +++ b/spec/views/seeds/edit.html.haml_spec.rb @@ -21,26 +21,26 @@ describe "seeds/edit" do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_user) { @member } - @seed = FactoryGirl.create(:seed, :owner => @member) + @seed = FactoryGirl.create(:seed, owner: @member) end it "renders the edit seed form" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select "form", :action => seeds_path(@seed), :method => "post" do - assert_select "input#crop", :class => "ui-autocomplete-input" - assert_select "input#seed_crop_id", :name => "seed[crop_id]" - assert_select "textarea#seed_description", :name => "seed[description]" - assert_select "input#seed_quantity", :name => "seed[quantity]" - assert_select "select#seed_tradable_to", :name => "seed[tradable_to]" + assert_select "form", action: seeds_path(@seed), method: "post" do + assert_select "input#crop", class: "ui-autocomplete-input" + assert_select "input#seed_crop_id", name: "seed[crop_id]" + assert_select "textarea#seed_description", name: "seed[description]" + assert_select "input#seed_quantity", name: "seed[quantity]" + assert_select "select#seed_tradable_to", name: "seed[tradable_to]" end end it "doesn't revert tradable_to to nowhere" do - @seed = FactoryGirl.create(:tradable_seed, :owner => @member) + @seed = FactoryGirl.create(:tradable_seed, owner: @member) @seed.tradable_to.should_not eq "nowhere" render - assert_select "option[selected=selected]", :text => @seed.tradable_to + assert_select "option[selected=selected]", text: @seed.tradable_to end end diff --git a/spec/views/seeds/new.html.haml_spec.rb b/spec/views/seeds/new.html.haml_spec.rb index 82bc32bd4..2f20412fa 100644 --- a/spec/views/seeds/new.html.haml_spec.rb +++ b/spec/views/seeds/new.html.haml_spec.rb @@ -21,25 +21,25 @@ describe "seeds/new" do @member = FactoryGirl.create(:member) sign_in @member controller.stub(:current_user) { @member } - @seed1 = FactoryGirl.create(:seed, :owner => @member) + @seed1 = FactoryGirl.create(:seed, owner: @member) assign(:seed, @seed1) end it "renders new seed form" do render - assert_select "form", :action => seeds_path, :method => "post" do - assert_select "input#crop", :class => "ui-autocomplete-input" - assert_select "input#seed_crop_id", :name => "seed[crop_id]" - assert_select "textarea#seed_description", :name => "seed[description]" - assert_select "input#seed_quantity", :name => "seed[quantity]" - assert_select "select#seed_tradable_to", :name => "seed[tradable_to]" + assert_select "form", action: seeds_path, method: "post" do + assert_select "input#crop", class: "ui-autocomplete-input" + assert_select "input#seed_crop_id", name: "seed[crop_id]" + assert_select "textarea#seed_description", name: "seed[description]" + assert_select "input#seed_quantity", name: "seed[quantity]" + assert_select "select#seed_tradable_to", name: "seed[tradable_to]" end end it 'reminds you to set your location' do render rendered.should have_content "Don't forget to set your location." - assert_select "a", :text => "set your location" + assert_select "a", text: "set your location" end context 'member has location' do @@ -47,19 +47,19 @@ describe "seeds/new" do @member = FactoryGirl.create(:london_member) sign_in @member controller.stub(:current_user) { @member } - @seed1 = FactoryGirl.create(:seed, :owner => @member) + @seed1 = FactoryGirl.create(:seed, owner: @member) assign(:seed, @seed1) end it 'shows the location' do render rendered.should have_content "from #{@member.location}." - assert_select 'a', :href => place_path(@member.location) + assert_select 'a', href: place_path(@member.location) end it 'links to change location' do render - assert_select "a", :text => "Change your location." + assert_select "a", text: "Change your location." end end diff --git a/spec/views/seeds/show.html.haml_spec.rb b/spec/views/seeds/show.html.haml_spec.rb index 660eadfb9..db2bae6ce 100644 --- a/spec/views/seeds/show.html.haml_spec.rb +++ b/spec/views/seeds/show.html.haml_spec.rb @@ -32,7 +32,7 @@ describe "seeds/show" do before(:each) do @owner = FactoryGirl.create(:london_member) assign(:seed, FactoryGirl.create(:tradable_seed, - :owner => @owner)) + owner: @owner)) # note current_member is not the owner of this seed @member = FactoryGirl.create(:member) sign_in @member @@ -47,7 +47,7 @@ describe "seeds/show" do it "shows location of seed owner" do render rendered.should have_content @owner.location - assert_select 'a', :href => place_path(@owner.location) + assert_select 'a', href: place_path(@owner.location) end context 'with no location' do @@ -55,7 +55,7 @@ describe "seeds/show" do @owner = FactoryGirl.create(:member) # no location sign_in @owner controller.stub(:current_user) { @owner } - assign(:seed, FactoryGirl.create(:tradable_seed, :owner => @owner)) + assign(:seed, FactoryGirl.create(:tradable_seed, owner: @owner)) end it 'says "from unspecified location"' do @@ -65,7 +65,7 @@ describe "seeds/show" do it "links to profile to set location" do render - assert_select "a[href=#{url_for(edit_member_registration_path)}]", :text => "Set Location" + assert_select "a[href=#{url_for(edit_member_registration_path)}]", text: "Set Location" end end diff --git a/spec/views/shop/index_spec.rb b/spec/views/shop/index_spec.rb index f6a4131ce..df1f74920 100644 --- a/spec/views/shop/index_spec.rb +++ b/spec/views/shop/index_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'shop/index.html.haml', :type => "view" do +describe 'shop/index.html.haml', type: "view" do before(:each) do @product1 = FactoryGirl.create(:product) @product2 = FactoryGirl.create(:product_with_recommended_price) @@ -32,7 +32,7 @@ describe 'shop/index.html.haml', :type => "view" do end it 'shows products' do - assert_select("h2", :text => @product1.name) + assert_select("h2", text: @product1.name) end it 'shows prices in configured currency' do @@ -54,11 +54,11 @@ describe 'shop/index.html.haml', :type => "view" do end it 'displays the order form' do - assert_select "form", :count => 2 + assert_select "form", count: 2 end it 'renders markdown in product descriptions' do - assert_select "em", :text => 'hurrah', :count => 2 + assert_select "em", text: 'hurrah', count: 2 end end diff --git a/spec/views/support/index_spec.rb b/spec/views/support/index_spec.rb index 5d9ce615d..3749bbf6d 100644 --- a/spec/views/support/index_spec.rb +++ b/spec/views/support/index_spec.rb @@ -16,7 +16,7 @@ require 'rails_helper' -describe 'support/index.html.haml', :type => "view" do +describe 'support/index.html.haml', type: "view" do before(:each) do render end From 5a31619b4601e899b602edf3b3d5179e76c10811 Mon Sep 17 00:00:00 2001 From: Kevin Rio Date: Sat, 22 Aug 2015 17:41:35 -0400 Subject: [PATCH 306/392] If i reply to a notification directly, it's not marked as read. #507 --- app/controllers/notifications_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index f1934ded3..57b5836ba 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -40,6 +40,8 @@ class NotificationsController < ApplicationController def reply @notification = Notification.new @sender_notification = Notification.find(params[:id]) + @sender_notification.read = true + @sender_notification.save @recipient = @sender_notification.sender @subject = @sender_notification.subject =~ /^Re: / ? @sender_notification.subject : From 18cd8f5966870fed5c5976a9f577353fe9fdc075 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 16 Apr 2016 10:55:05 +0930 Subject: [PATCH 307/392] #507 #813 Add spec --- spec/controllers/notifications_controller_spec.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 1b70d0f33..a7737dad2 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -79,6 +79,16 @@ describe NotificationsController do end end + describe "GET reply" do + it "marks notifications as read" do + notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id) + get :reply, {:id => notification.to_param} + # we need to fetch it from the db again, can't test against the old one + n = Notification.find(notification.id) + n.read.should eq true + end + end + describe "GET new" do it "assigns a recipient" do @recipient = FactoryGirl.create(:member) From 0df52b3cd88ed469199bb315f02cfda810e2ae8b Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 19 May 2016 15:20:38 -0400 Subject: [PATCH 308/392] update paperclip --- Gemfile.lock | 11 ++--------- README.md | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9e30e2832..376b6571f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -90,7 +90,7 @@ GEM climate_control (0.0.3) activesupport (>= 3.0) cliver (0.3.2) - cocaine (0.5.7) + cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) codemirror-rails (4.8) railties (>= 3.0, < 5) @@ -119,12 +119,6 @@ GEM rails-i18n (>= 4.0.0) sass-rails (>= 4.0.3) concurrent-ruby (1.0.2) - coveralls (0.7.1) - multi_json (~> 1.3) - rest-client - simplecov (>= 0.7) - term-ansicolor - thor coveralls (0.8.13) json (~> 1.8) simplecov (~> 0.11.0) @@ -255,7 +249,6 @@ GEM leaflet-rails (0.7.4) letter_opener (1.3.0) launchy (~> 2.2) - lumberjack (1.0.9) listen (3.1.4) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -294,7 +287,7 @@ GEM multi_json (~> 1.3) omniauth-oauth (~> 1.0) orm_adapter (0.5.0) - paperclip (4.3.0) + paperclip (4.3.6) activemodel (>= 3.2.0) activesupport (>= 3.2.0) cocaine (~> 0.5.5) diff --git a/README.md b/README.md index fbef661d2..cd534bcb4 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ The wiki is down right now, so here's what you need to do on Mac OS X to get set ``` gem install bundle -gem install pg -v '0.17.1' -- --with-pg-config=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config +gem install pg -v '0.18.4' -- --with-pg-config=/Applications/Postgres.app/Contents/Versions/latest/bin/pg_config bundle install ``` From 51a0a33b2a601c629b28b679ab9a3abced0c6a6f Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Sat, 21 May 2016 16:33:42 -0400 Subject: [PATCH 309/392] upgrade gems and make API change for ruby-units --- Gemfile | 2 +- Gemfile.lock | 183 +++++++++++++++++++++--------------------- app/models/harvest.rb | 2 +- 3 files changed, 93 insertions(+), 94 deletions(-) diff --git a/Gemfile b/Gemfile index e062e0fe7..bd1d38baf 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem 'unicorn' # http server gem 'pg' gem 'figaro' # for handling config via ENV variables gem 'cancancan', '~> 1.9' # for checking member privileges -gem 'gibbon' # for Mailchimp newsletter subscriptions +gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions gem 'csv_shaper' # CSV export gem 'ruby-units' # for unit conversion diff --git a/Gemfile.lock b/Gemfile.lock index 376b6571f..914398c35 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -33,7 +33,7 @@ GEM activesupport (= 4.1.15) builder (~> 3.1) erubis (~> 2.7.0) - active_link_to (1.0.2) + active_link_to (1.0.3) actionpack activemodel (4.1.15) activesupport (= 4.1.15) @@ -48,8 +48,9 @@ GEM minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) - addressable (2.3.6) + addressable (2.4.0) arel (5.0.1.20140414130214) + ast (2.2.0) autoprefixer-rails (6.3.6.1) execjs bcrypt (3.1.11) @@ -61,7 +62,7 @@ GEM debug_inspector (>= 0.0.1) bluecloth (2.2.0) bonsai-elasticsearch-rails (0.0.4) - bootstrap-datepicker-rails (1.3.0.2) + bootstrap-datepicker-rails (1.6.1.1) railties (>= 3.0) bootstrap-kaminari-views (0.0.5) kaminari (>= 0.13) @@ -69,20 +70,18 @@ GEM bootstrap-sass (3.3.6) autoprefixer-rails (>= 5.2.1) sass (>= 3.3.4) - bootstrap_form (2.2.0) + bootstrap_form (2.3.0) builder (3.2.2) - byebug (3.5.1) - columnize (~> 0.8) - debugger-linecache (~> 1.2) - slop (~> 3.6) - cancancan (1.9.2) - capybara (2.4.4) + byebug (9.0.4) + cancancan (1.14.0) + capybara (2.7.1) + addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (~> 2.0) - capybara-email (2.4.0) + capybara-email (2.5.0) capybara (~> 2.4) mail childprocess (0.5.9) @@ -92,18 +91,17 @@ GEM cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) - codemirror-rails (4.8) + codemirror-rails (5.11) railties (>= 3.0, < 5) coderay (1.1.1) - coffee-rails (4.1.0) + coffee-rails (4.1.1) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.0) - coffee-script (2.3.0) + railties (>= 4.0.0, < 5.1.x) + coffee-script (2.4.1) coffee-script-source execjs - coffee-script-source (1.8.0) - columnize (0.9.0) - comfortable_mexican_sofa (1.12.7) + coffee-script-source (1.10.0) + comfortable_mexican_sofa (1.12.9) active_link_to (>= 1.0.0) bootstrap-sass (>= 3.2.0) bootstrap_form (>= 2.2.0) @@ -125,13 +123,12 @@ GEM term-ansicolor (~> 1.3) thor (~> 0.19.1) tins (~> 1.6.0) - csv_shaper (1.1.1) + csv_shaper (1.2.0) activesupport (>= 3.0.0) - dalli (2.7.2) - database_cleaner (1.5.0) + dalli (2.7.6) + database_cleaner (1.5.3) debug_inspector (0.0.2) - debugger-linecache (1.2.0) - devise (3.5.6) + devise (3.5.10) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) @@ -144,47 +141,47 @@ GEM json thread thread_safe - elasticsearch (1.0.6) - elasticsearch-api (= 1.0.6) - elasticsearch-transport (= 1.0.6) - elasticsearch-api (1.0.6) + elasticsearch (1.0.17) + elasticsearch-api (= 1.0.17) + elasticsearch-transport (= 1.0.17) + elasticsearch-api (1.0.17) multi_json - elasticsearch-model (0.1.6) + elasticsearch-model (0.1.9) activesupport (> 3) elasticsearch (> 0.4) hashie - elasticsearch-rails (0.1.6) - elasticsearch-transport (1.0.6) + elasticsearch-rails (0.1.9) + elasticsearch-transport (1.0.17) faraday multi_json erubis (2.7.0) - excon (0.43.0) - execjs (2.6.0) + excon (0.49.0) + execjs (2.7.0) factory_girl (4.5.0) activesupport (>= 3.0.0) factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) - faraday (0.9.1) + faraday (0.9.2) multipart-post (>= 1.2, < 3) ffi (1.9.10) - figaro (1.0.0) + figaro (1.1.1) thor (~> 0.14) flickraw (0.9.8) font-awesome-sass (4.6.2) sass (>= 3.2) formatador (0.2.5) - friendly_id (5.0.4) + friendly_id (5.0.5) activerecord (>= 4.0.0) - gibbon (1.1.4) + gibbon (1.2.0) httparty - multi_json (>= 1.3.4) + multi_json (>= 1.9.0) gravatar-ultimate (2.0.0) activesupport (>= 2.3.14) rack - guard (2.13.0) + guard (2.14.0) formatador (>= 0.2.4) - listen (>= 2.7, <= 4.0) + listen (>= 2.7, < 4.0) lumberjack (~> 1.0) nenv (~> 0.1) notiffany (~> 0.0) @@ -196,60 +193,60 @@ GEM guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) - haml (4.1.0.beta.1) + haml (4.0.7) tilt - haml-rails (0.6.0) + haml-rails (0.9.0) actionpack (>= 4.0.1) activesupport (>= 4.0.1) - haml (>= 3.1, < 5.0) + haml (>= 4.0.6, < 5.0) html2haml (>= 1.0.1) railties (>= 4.0.1) - hashie (3.3.2) - heroku-api (0.3.22) - excon (~> 0.38) + hashie (3.4.4) + heroku-api (0.4.2) + excon (~> 0.45) multi_json (~> 1.8) - highline (1.6.21) - hpricot (0.8.6) - html2haml (1.0.1) + highline (1.7.8) + html2haml (2.0.0) erubis (~> 2.7.0) - haml (>= 4.0.0.rc.1) - hpricot (~> 0.8.6) - ruby_parser (~> 3.1.1) + haml (~> 4.0.0) + nokogiri (~> 1.6.0) + ruby_parser (~> 3.5) httparty (0.13.3) json (~> 1.8) multi_xml (>= 0.5.2) i18n (0.7.0) - i18n-tasks (0.7.8) - activesupport + i18n-tasks (0.9.5) + activesupport (>= 4.0.2) + ast (>= 2.1.0) easy_translate (>= 0.5.0) erubis - highline + highline (>= 1.7.3) i18n - slop (>= 3.5.0) - term-ansicolor - terminal-table - jquery-rails (3.1.3) + parser (>= 2.2.3.0) + term-ansicolor (>= 1.3.2) + terminal-table (>= 1.5.1) + jquery-rails (3.1.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (5.0.3) + jquery-ui-rails (5.0.5) railties (>= 3.2.16) - js-routes (0.9.9) + js-routes (1.2.5) railties (>= 3.2) sprockets-rails json (1.8.3) kaminari (0.16.3) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - kgio (2.9.2) - kramdown (1.5.0) + kgio (2.10.0) + kramdown (1.11.1) launchy (2.4.3) addressable (~> 2.3) leaflet-markercluster-rails (0.7.0) railties (>= 3.1) - leaflet-rails (0.7.4) - letter_opener (1.3.0) + leaflet-rails (0.7.7) + letter_opener (1.4.1) launchy (~> 2.2) - listen (3.1.4) + listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) @@ -264,28 +261,29 @@ GEM mimemagic (0.3.0) mini_portile2 (2.0.0) minitest (5.9.0) - multi_json (1.12.1) + multi_json (1.11.3) multi_xml (0.5.5) multipart-post (2.0.0) nenv (0.3.0) newrelic_rpm (3.15.2.317) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) - notiffany (0.0.8) + notiffany (0.1.0) nenv (~> 0.1) shellany (~> 0.0) - oauth (0.4.7) - omniauth (1.2.2) + oauth (0.5.1) + omniauth (1.3.1) hashie (>= 1.2, < 4) - rack (~> 1.0) - omniauth-flickr (0.0.15) + rack (>= 1.0, < 3) + omniauth-flickr (0.0.19) + multi_json (~> 1.11.0) omniauth-oauth (~> 1.0) - omniauth-oauth (1.0.1) + omniauth-oauth (1.1.0) oauth omniauth (~> 1.0) - omniauth-twitter (1.1.0) - multi_json (~> 1.3) - omniauth-oauth (~> 1.0) + omniauth-twitter (1.2.1) + json (~> 1.3) + omniauth-oauth (~> 1.1) orm_adapter (0.5.0) paperclip (4.3.6) activemodel (>= 3.2.0) @@ -293,10 +291,12 @@ GEM cocaine (~> 0.5.5) mime-types mimemagic (= 0.3.0) + parser (2.3.1.0) + ast (~> 2.2) pg (0.18.4) plupload-rails (1.2.1) rails (>= 3.1) - poltergeist (1.6.0) + poltergeist (1.9.0) capybara (~> 2.1) cliver (~> 0.3.1) multi_json (~> 1.0) @@ -320,20 +320,20 @@ GEM bundler (>= 1.3.0, < 2.0) railties (= 4.1.15) sprockets-rails (~> 2.0) - rails-i18n (4.0.3) - i18n (~> 0.6) + rails-i18n (4.0.8) + i18n (~> 0.7) railties (~> 4.0) rails_12factor (0.0.3) rails_serve_static_assets rails_stdout_logging - rails_serve_static_assets (0.0.2) - rails_stdout_logging (0.0.3) + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) railties (4.1.15) actionpack (= 4.1.15) activesupport (= 4.1.15) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - raindrops (0.13.0) + raindrops (0.16.0) rake (11.1.2) rb-fsevent (0.9.7) rb-inotify (0.9.7) @@ -344,7 +344,7 @@ GEM rspec-core (~> 3.4.0) rspec-expectations (~> 3.4.0) rspec-mocks (~> 3.4.0) - rspec-activemodel-mocks (1.0.1) + rspec-activemodel-mocks (1.0.3) activemodel (>= 3.0) activesupport (>= 3.0) rspec-mocks (>= 2.99, < 4.0) @@ -365,9 +365,9 @@ GEM rspec-mocks (~> 3.4.0) rspec-support (~> 3.4.0) rspec-support (3.4.1) - ruby-units (1.4.5) + ruby-units (2.0.0) ruby_dep (1.3.1) - ruby_parser (3.1.3) + ruby_parser (3.8.2) sexp_processor (~> 4.1) rubyzip (1.2.0) sass (3.4.22) @@ -381,7 +381,7 @@ GEM childprocess (~> 0.5) rubyzip (~> 1.0) websocket (~> 1.0) - sexp_processor (4.4.4) + sexp_processor (4.7.0) shellany (0.0.1) simplecov (0.11.2) docile (~> 1.1.0) @@ -398,9 +398,9 @@ GEM sprockets (>= 2.8, < 4.0) term-ansicolor (1.3.2) tins (~> 1.0) - terminal-table (1.4.5) + terminal-table (1.5.2) thor (0.19.1) - thread (0.1.4) + thread (0.2.2) thread_safe (0.3.5) tilt (2.0.4) tins (1.6.0) @@ -409,9 +409,8 @@ GEM uglifier (2.7.2) execjs (>= 0.3.0) json (>= 1.8.0) - unicorn (4.8.3) + unicorn (5.1.0) kgio (~> 2.6) - rack raindrops (~> 0.7) warden (1.2.6) rack (>= 1.0) @@ -420,10 +419,10 @@ GEM rack (>= 1.0) rack-test (>= 0.5.3) websocket (1.2.3) - websocket-driver (0.5.4) + websocket-driver (0.6.4) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) - will_paginate (3.0.7) + will_paginate (3.1.0) xpath (2.0.0) nokogiri (~> 1.3) @@ -460,7 +459,7 @@ DEPENDENCIES font-awesome-sass friendly_id (~> 5.0.4) geocoder! - gibbon + gibbon (~> 1.2.0) gravatar-ultimate guard guard-rspec diff --git a/app/models/harvest.rb b/app/models/harvest.rb index e648bec39..8a1fea37b 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -72,7 +72,7 @@ class Harvest < ActiveRecord::Base def set_si_weight if self.weight_unit != nil weight_string = "#{self.weight_quantity} #{self.weight_unit}" - self.si_weight = Unit(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f + self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f end end From da1375e34d08c03c56b8e66b703b665c0f64a610 Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Sun, 22 May 2016 15:50:22 +0000 Subject: [PATCH 310/392] Making database.yml locally editable --- .gitignore | 2 +- config/database.yml.example | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 config/database.yml.example diff --git a/.gitignore b/.gitignore index 9d8981307..b889a0064 100644 --- a/.gitignore +++ b/.gitignore @@ -8,10 +8,10 @@ coverage *~ *.DS_Store config/application.yml +config/database.yml credentials*.sh Pathogen: custom_plan.rb zeus.json .bundle -config/application.yml .idea/** \ No newline at end of file diff --git a/config/database.yml.example b/config/database.yml.example new file mode 100644 index 000000000..eb75b3791 --- /dev/null +++ b/config/database.yml.example @@ -0,0 +1,31 @@ +development: + adapter: postgresql + database: growstuff_dev + host: localhost + user: postgres + password: postgres + +test: + adapter: postgresql + database: growstuff_test + host: localhost + user: postgres + password: postgres + +production: + adapter: postgresql + database: growstuff_prod + pool: 5 + timeout: 5000 + username: growstuff + host: localhost + password: thisisnottherealpassword + +staging: + adapter: postgresql + database: growstuff_prod + pool: 5 + timeout: 5000 + username: growstuff + host: localhost + password: thisisnottherealpassword From 397bfd8bca21fe37a4e9a3e509487161b88ed2fa Mon Sep 17 00:00:00 2001 From: twconquest Date: Tue, 28 Jul 2015 18:55:10 +0000 Subject: [PATCH 311/392] Start removing static page references. --- app/controllers/policy_controller.rb | 2 -- app/controllers/support_controller.rb | 2 -- config/routes.rb | 6 ------ 3 files changed, 10 deletions(-) delete mode 100644 app/controllers/policy_controller.rb delete mode 100644 app/controllers/support_controller.rb diff --git a/app/controllers/policy_controller.rb b/app/controllers/policy_controller.rb deleted file mode 100644 index 91127ca5a..000000000 --- a/app/controllers/policy_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class PolicyController < ApplicationController -end diff --git a/app/controllers/support_controller.rb b/app/controllers/support_controller.rb deleted file mode 100644 index e104ae76d..000000000 --- a/app/controllers/support_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class SupportController < ApplicationController -end diff --git a/config/routes.rb b/config/routes.rb index 9980edadd..be85f961e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -73,12 +73,6 @@ Growstuff::Application.routes.draw do get 'auth/:provider/callback' => 'authentications#create' - - get '/policy/:action' => 'policy#:action' - - get '/support' => 'support#index' - get '/support/:action' => 'support#:action' - get '/about' => 'about#index' get '/about/:action' => 'about#:action' From 79734ff6036ce92013a398219c75de3bd90e8322 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 13:42:26 +0000 Subject: [PATCH 312/392] Fix #690 Removing old static files that are now in CMS --- app/views/about/contact.html.haml | 17 --- app/views/policy/api.html.haml | 45 ------ app/views/policy/community.html.haml | 31 ---- app/views/policy/privacy.html.haml | 107 -------------- app/views/policy/tos.html.haml | 156 -------------------- app/views/support/index.html.haml | 211 --------------------------- 6 files changed, 567 deletions(-) delete mode 100644 app/views/about/contact.html.haml delete mode 100644 app/views/policy/api.html.haml delete mode 100644 app/views/policy/community.html.haml delete mode 100644 app/views/policy/privacy.html.haml delete mode 100644 app/views/policy/tos.html.haml delete mode 100644 app/views/support/index.html.haml diff --git a/app/views/about/contact.html.haml b/app/views/about/contact.html.haml deleted file mode 100644 index 2398bea36..000000000 --- a/app/views/about/contact.html.haml +++ /dev/null @@ -1,17 +0,0 @@ --content_for :title, 'Contact' - -%dl - %dt General contact email - %dd= link_to 'info@growstuff.org', 'mailto:info@growstuff.org' -%dl - %dt - Support and accounts enquiries (not covered by the - =succeed ")" do - =link_to 'FAQ', url_for(:controller => '/support') - %dd= link_to 'support@growstuff.org', 'mailto:support@growstuff.org' -%dl - %dt Media/Press enquiries - %dd= link_to 'media@growstuff.org', 'mailto:media@growstuff.org' -%dl - %dt Twitter - %dd= link_to '@growstufforg', 'http://twitter.com/growstufforg' diff --git a/app/views/policy/api.html.haml b/app/views/policy/api.html.haml deleted file mode 100644 index 4dc0bbdd8..000000000 --- a/app/views/policy/api.html.haml +++ /dev/null @@ -1,45 +0,0 @@ --content_for :title, 'API and Data Use Policy' - -:markdown - We hate legalese, so we've tried to make this policy readable. If you've got any questions, feel free to [ask us](mailto:support@growstuff.org), and we'll do our best to answer. - - This API and Data Use Policy covers all websites (such as [growstuff.org](http://growstuff.org)) owned and operated by Growstuff Pty Ltd ("Growstuff", "we", "us", "our") and all associated services, collectively referred to as the Service. - - In particular, this policy covers any access to the Service via any Application Programming Interface, feeds, spidering, scraping, or any other automated or programmatic access to the Structured Data or Content available via the Service (collectively, the "API"). This policy applies to anyone who uses the API ("you", "developer"). - - ## 1. API Provided As-Is, and Subject to Change - - Growstuff provides its API on an as-is basis, as described under "Disclaimer of Warranties" in our [Terms of Service](http://growstuff.org/policy/tos). - - Growstuff's API is subject to change. We will make reasonable efforts to notify developers of changes and of the release status of any API features. You should take reasonable efforts to keep up with Growstuff technical news via our forums, mailing lists, or other channels. - - ## 2. Don't overload our servers - - You agree to limit your access to the API in such a way as to prevent excessive load on the Service. Growstuff reserves the right to restrict or rate-limit access to the API if necessary to maintain the performance of the Service. - - ## 3. Use of Growstuff Data and Content - - You agree to observe the terms of the [Creative Commons Attribution-ShareAlike (CC-BY-SA) 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US) under which our Structured Data is made available. You agree to to observe the copyright and intellectual property rights of Growstuff's members with regard to their Content posted on the Service, including but not limited to posts, comments, images, etc. - - You agree to respect any privacy settings which pertain to the Structured Data or Content you access via the API. You agree not to republish any Structured Data or Content with more permissive access than was originally intended by the member who posted it. - - Growstuff acknowledges that Structured Data and Content made available under the API may be cached or retained by third parties for any length of time. However, we request that if you are building an application using current Structured Data and Content, you will take reasonable efforts to regularly update it, including removing any Structured Data or Content that is deleted from the Service, and reflecting any changes in privacy settings that pertain to it. - - ## 4. Authentication - - Growstuff reserves the right to require authentication and/or app registration as a condition of use of the API and Data. - - If you provide users with the ability to login to Growstuff, you must do so via OAuth. You may not require users to provide their Growstuff login name and password. - - ## 5. Penalties - - If you violate the terms of this Policy, Growstuff may restrict your access to the API. - - ## 6. Changes - - We may change our API and Data Use Policy from time to time. A history of changes to this Policy is available via our public source code repository at [https://github.com/Growstuff/policy](https://github.com/Growstuff/policy). We will take reasonable steps to notify you of any substantial changes to this Policy; however, it is your responsibility to check this Policy periodically for changes. Your continued use of this site after any change in this Privacy Policy will constitute your acceptance of such change. - - ## 7. Creative Commons License - - This API and Data Use Policy is licensed under a [Creative Commons Attribution-ShareAlike (CC-BY-SA) 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). - diff --git a/app/views/policy/community.html.haml b/app/views/policy/community.html.haml deleted file mode 100644 index c6c0c8f49..000000000 --- a/app/views/policy/community.html.haml +++ /dev/null @@ -1,31 +0,0 @@ --content_for :title, 'Growstuff Community Guidelines' - -:markdown - Growstuff is a community by and for food-gardeners. Together, we are building a website where we can share our experience, knowledge, and the products of our harvest. The most important thing about Growstuff is the people. For Growstuff to thrive, we need people to add their crops, share their knowledge, and help build the site itself. - - Whatever your interest in Growstuff you are welcome here, and will be treated with respect. In particular: - - - We welcome people of any age, gender identity or expression, ethnicity, nationality, religion or absence thereof, political opinion, sexual orientation, marital status, family structure, ability or disability, appearance, subculture, or other identity or self-identification. - - - Although Growstuff is primarily focused on food gardening, we welcome all kinds of gardeners, including organic and conventional growers; those who grow their crops in fields or on balconies or in hydroponic systems; those who garden commercially or non-commercially; those who subsist on their crops and those who garden for other reasons. - - - We welcome people of all skill and experience levels, and we don't believe in being dismissive or commenting rudely just because you are new or learning. - - - Every role in our community is important, including gardeners who contribute skills, knowledge, and information to our site; coders, designers and other techies who help build it; moderators and others who help our community thrive; or any other form of participation. We believe in working together, and prioritise communication and mutual understanding. - - If you want to participate in the Growstuff community (which includes our website and any auxiliary forums such as our mailing list(s), IRC channel, etc), you need to agree to our general commitment to inclusiveness and mutual respect, as well as to the following specific policies: - - - Harassment of any Growstuff community member is forbidden. Harassment includes slurs directed at individuals or groups; unwanted sexual remarks directed at any person or group; sexually explicit comments or imagery in public spaces; stalking or other repeated, unwanted contact; or any repeated or sustained behaviour which disrupts someone else's enjoyment of the Growstuff site or community. - - - The privacy of our community members is very important. You may not disclose any member's personal details (including names by which they are known outside of Growstuff, their location, employment details, family details, outside-of-Growstuff contact details, or any other identifying or personal information) without their explicit consent. - - - Although we let you choose your own name on our site, and don't insist that you use the same name on our website as you have on the cards in your wallet, you're not allowed to create or use a pseudonymous account to mislead people, evade accountability, or otherwise cause trouble. (This is commonly known as a "sockpuppet" account.) - - If you experience or witness behaviour that goes against these community guidelines, you can report it to support@growstuff.org. We will listen carefully and take your report seriously. Once we've looked into the situation, we may take any action we deem necessary. For instance, we may issue a warning, or in serious cases we may suspend or ban people from our community. If this happens, we will always tell the person affected the reason for our action, with reference to our policy documents. - - We don't want to make these guidelines too long or legalistic, so we'll leave it there, except for one final guideline. As Bill and Ted said: *be excellent to each other*. And grow stuff. - - ## Creative Commons License - - These Community Guidelines are licensed under a [Creative Commons Attribution-ShareAlike (CC-BY-SA) 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/deed.en_US). - diff --git a/app/views/policy/privacy.html.haml b/app/views/policy/privacy.html.haml deleted file mode 100644 index 3a2fc2f5c..000000000 --- a/app/views/policy/privacy.html.haml +++ /dev/null @@ -1,107 +0,0 @@ --content_for :title, 'Privacy Policy' - -:markdown - We hate legalese, so we've tried to make this policy readable. If you've got any questions, feel free to [ask us](mailto:support@growstuff.org), and we'll do our best to answer. - - This privacy statement ("Privacy Policy") covers all websites (such as [growstuff.org](http://growstuff.org/)) owned and operated by Growstuff Pty Ltd ("Growstuff", "we", "us", "our") and all associated services, collectively referred to as "the Service". - - We use information you share with us for our internal business purposes. We do not sell your information. This notice tells you what information we collect, how we use it, and steps we take to protect and secure it. - - ## 1. Information we collect - - ### 1.1 Non-Personal Data - - Like most website operators, we collect Non-Personal Data such as browser type, language preference, referring site, and the date and time of each visitor request. - - We collect this to understand how our visitors and members use our service, and use it to make decisions about how to change and adapt the service. - - From time to time, we may release Non-Personal Data in aggregate form (for instance, by publishing trends in site usage) to explain our reasoning in making decisions. We will not release individual information, only aggregate information. - - ### 1.2 Personal Data - - Personal Data is anything which can be used to identify or contact you, such as your legal name, email address, IP address, or physical location. - - #### 1.2.1 Automatically collected Personal Data - - We automatically collect some Personal Data, such as IP address, provided by your browser and your computer whenever you visit our website. - - We collect this information for several purposes: - - * To diagnose and repair network issues with your use of the site; - * To estimate the number of users accessing the service from specific geographic regions; - * To help prevent fraud and abuse. - - #### 1.2.2 Email address - - In order to register for the service, you must give us your email address. We will use your email address to send confirmation of certain actions, such as when you change your password. We will contact you when it's necessary to complete a transaction that you've initiated, or if there's a critical or administrative issue affecting your use of the service. - - Once you have created your account, you can choose to subscribe to certain events and have notifications of those events sent to you via email. You will be able to change your mind and opt out of receiving notifications via email at any time. - - We will never sell or provide your email address to any third party for marketing purposes, or for any other reason except as set out below. - - #### 1.2.3 Optional Personal Data you provide to us - - As you use the service, you have the option to provide more Personal Data, through your profile and other activity on the site. Providing this information is strictly optional. - - You have the option to provide us with your location. You may provide this at whatever level of detail you wish, for instance you may provide your street address or your country of residence or nothing at all. We use this location to provide you with relevant content. - - Many of your activities on the Service may allow you to post Personal Data or to directly or indirectly disclose Personal Data about yourself. For instance, you may disclose Personal Data in a post or comment on the site, by uploading a picture, by linking to another website you use, or by recording your gardening activity in detail. All of these activities are optional. You should use due caution when disclosing Personal Data through your activity on the Service. - - We will show the information you provide, including any Personal Data it may contain, to others viewing the site, in accordance with the privacy options you've selected. - - The information you provide is also made available to third parties via our API and feeds, in accordance with the privacy options you've selected and subject to the terms of our API and Data Use Policy which is available at [http://growstuff.org/policy/api](http://growstuff.org/policy/api). - - Some of the information you provide is categorised as Structured Data, which is defined more fully in our [Terms of Service]([http://growstuff.org/policy/tos). We make Structured Data freely available under a Creative Commons Attribution ShareAlike (CC-BY-SA) 3.0 Unported license for use by third parties, in accordance with the privacy options you've selected. - - We may also use any Personal Data you provide, in aggregate, to make decisions about how to change and adapt the service. From time to time, we may release information in aggregate form (for instance, by publishing trends in site usage) to explain our reasoning in making decisions. We will not release individual information, only aggregate information. - - #### 1.2.4 Financial information and transactions - - You can engage in financial transactions with Growstuff to purchase a paid account. These transactions are optional. If you choose to purchase a paid account, you will be asked to provide financial information to complete the transaction. - - Credit cards: If you pay by credit card, we need you to provide your credit card number, your full name as it appears on the card, your address as it appears on the card statement, and the CVN or Card Verification Number. This information is required so we can authorize and charge your credit card. Your financial information is protected by industry-standard encryption methods. It is never stored on our servers: we pass it immediately along to our processor for the sole purpose of completing the authorized transaction. - - In all cases, Growstuff collects this personal and financial information only as necessary or appropriate for the completion of the single requested transaction. Any additional non-financial Personal Data you disclose during these transactions will be governed by the "Disclosure of Personal Data" provisions below. - - ## 2. Disclosure of Personal Data - - We disclose Personal Data, including optional personal information you have provided but which is not normally available to other site users, only to those of our employees, contractors, and volunteers who (i) need to know that information in order to operate the service and (ii) have agreed not to disclose it to others. Circumstances in which this is necessary include, but are not limited to: troubleshooting and diagnosing technical problems, investigating possible Terms of Service violations, and legal compliance issues. - - We contract with third-party vendors to provide some site features. We will only share personal information with third-party vendors to the extent that is necessary for them to provide these site features. We require our third-party vendors to provide the same level of privacy protection that we do, and they do not have the right to share or use personal information for any purpose other than for an authorized transaction. - - We may disclose Personal Data or potentially personally-identifying data when that release is required by law or by court order, or when we believe in good faith that disclosure is reasonably necessary to protect the safety or rights of us, third parties, or the public at large. - - We reserve the right to transfer your Personal Data to a third party in the event of a sale, merger, liquidation, receivership or transfer of all or substantially all of the assets of our company provided that the third party agrees to adhere to the terms of the Growstuff Privacy Policy and provided that the third party only uses your Personal Data for the purposes that you provided it to us. You will be notified in the event of any such transfer and you will be afforded an opportunity to opt-out. - - ## 3. Cookies - - A cookie is a string of information that a website stores on a visitor's computer, and that the visitor's browser provides to the website each time the visitor returns. We use cookies to help us identify and track visitors, their usage of the website, and their website access preferences. We also use cookies to govern logging into your account. - - Visitors who do not wish to have cookies placed on their computers should set their browsers to refuse cookies before using the site, with the drawback that certain features of the site may not function properly without the aid of cookies. - - ## 4. Confidentiality and security - - No data transmisson over the Internet can ever be guaranteed to be 100% secure. You use this service at your own risk. However, we will take all reasonable steps (including appropriate technical and organisational measures) to protect your Personal Data. - - Your account information is password-protected. We recommend that you choose a strong and secure password. We use industry-standard encryption to protect your password on our servers. - - If we learn of a system security breach, we will notify you electronically so you can take appropriate steps to protect yourself. - - ## 5. Deleting your information - - You can change or delete any optional information that you've provided us at any time. If you change or delete any optional information you've provided, the change will take place immediately on the Service. However, caching or references to the data, including in third party applications based on the Service, may mean that formerly available data remains available for some time. - - As part of the day to day operation of the Service, we will make regular copies of the data contained in the databases for backup purposes. These backups can potentially contain deleted data for several weeks or months. These backups will also be governed by the rules for Disclosure of Personal Data. - - ## 6. Changes - - We may change our Privacy Policy from time to time. A history of changes to this Policy is available via our public source code repository at [https://github.com/Growstuff/policy](https://github.com/Growstuff/policy). We will take reasonable steps to notify you of any substantial changes to this Policy; however, it is your responsibility to check this Policy periodically for changes. Your continued use of this site after any change in this Privacy Policy will constitute your acceptance of such change. - - ## 7. Contacting us - - If you have questions about this policy, you can contact us at [support@growstuff.org](mailto:support@growstuff.org). - - ## 8. Creative Commons - - This privacy policy is based on one developed by Automattic ([http://automattic.com/privacy/](http://automattic.com/privacy/)) and amended by Dreamwidth ([http://dreamwidth.org/legal/privacy](http://dreamwidth.org/legal/privacy)) and is licensed under a [Creative Commons Attribution-ShareAlike 2.5 License](http://creativecommons.org/licenses/by-sa/2.5/). - diff --git a/app/views/policy/tos.html.haml b/app/views/policy/tos.html.haml deleted file mode 100644 index 2cae2f57a..000000000 --- a/app/views/policy/tos.html.haml +++ /dev/null @@ -1,156 +0,0 @@ --content_for :title, 'Growstuff Terms of Service' - -:markdown - We hate legalese, so we've tried to make our Terms of Service readable. If you've got any questions, feel free to [ask us](mailto:support@growstuff.org), and we'll do our best to answer. - - Growstuff Pty Ltd ("we", "us", "our", "Growstuff") present the following terms and conditions, which govern your use of the Growstuff website at [growstuff.org](http://growstuff.org), and all content, services and products available at or through the website, which we collectively refer to as "the Service". - - To use the Service, you need to agree to these Terms of Service, along with all other policies we publish (including, but not limited to, Growstuff's Privacy Policy, API and Data Use Policy, Copyright Infringement Policy and Community Guidelines). We refer to this as "the Agreement". - - Please read this Agreement carefully before accessing or using the Service. By accessing or using any part of the Service, you agree that you are bound by the terms and conditions of this Agreement. If you do not agree to all the terms and conditions of this Agreement, then you may not access the Service. - - ## 1. Your Account - - If you create an account on the Service, you are responsible for maintaining the security of your account. You are responsible for all activities that occur under the account. You must take reasonable steps to guard the security of your account. We will not be liable for anything that happens if your account security is breached as a result of your failure to protect it. - - ## 2. Account Structure - - Growstuff currently has three types of accounts: - - * Free Accounts are available free of charge. Free accounts can access basic site functions, but do not receive access to premium features. - * Paid Accounts are available for term-based fee and receive access to a number of premium features. When your Paid Account expires, it will revert to a Free Account until you pay for it again. - * Permanent Accounts are reserved for those who have contributed significantly to the Growstuff project, at our discretion. They receive all features available to paid accounts, for as long as Growstuff continues to operate, without need for future payment. - - Payments to Growstuff, for account services or for any other purpose, are refundable or transferable solely at Growstuff's discretion. - - By using this Service, you agree to this account structure, and to Growstuff's right to change, modify, or discontinue any type of account or the features available to it at any time. - - ## 3. Content policy - - Our content policy relates to any material you may post on the Growstuff website or through the Service, which we call "Content". This includes profile information, posts and comments, information about your food growing activity, and any other material, whether text, graphics, or any other format, which you may post on Growstuff itself or link to from Growstuff. - - All Content posted to the Service in any way is the responsibility of the owner. If Content is deemed illegal by any law having jurisdiction over you, you agree that we may submit any necessary information to the proper authorities. - - We claim no ownership or control over any Content that you post to the Service. You retain any intellectual property rights to the Content you post, in accordance with applicable law. By posting Content, you represent that you have the rights to reproduce that Content (and the right to allow us to serve such Content) without violation of the rights of any third party. You agree that you will bear any liability resulting from the posting of any Content that you do not have the rights to post. - - You grant us a world-wide, royalty-free, and non-exclusive license to reproduce, modify, adapt and publish the Content, solely for the purpose of displaying, distributing and promoting the contents of your account, through any part of the Service including through our API, feeds, and external clients. - - If you delete Content, we will use reasonable efforts to remove it from the Service, but you acknowledge that caching or references to the Content may not be made immediately unavailable. - - ### 3.1 Structured Data - - There is a subset of Content which we refer to as "Structured Data". Structured Data is Content which represents simple facts, rather than creative effort. For instance, locations, dates, or the type and number of crops you have planted are Structured Data. Structured Data may be created explicitly by you or implicitly by the Website in response to your activity. - - By using the Service, you acknowledge that Structured Data will be gathered and stored by Growstuff, and that any Structured Data pertaining to you or your activity may be made available for use by third parties under a Creative Commons Attribution ShareAlike (CC-BY-SA) license. You also agree that attribution for the Structured Data under the terms of the Creative Commons license will be given to Growstuff. - - ### 3.2 Content Posted on Other Websites - - We have not reviewed, and cannot review, all of the material, including computer software, made available through the websites and webpages to which we, any user, or any provider of Content links, or that link to us. We do not have any control over those websites and webpages, and are not responsible for their contents or their use. By linking to an external website or webpage, we do not represent or imply that we endorse such website or webpage. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. We disclaim any responsibility for any harm resulting from your use of external websites and webpages, whether that link is provided by us or by any provider of Content on the Service. - - ### 3.3 How we deal with problem Content - - You agree that by using the Service, you may be exposed to Content you find offensive or objectionable. - - We do not pre-screen Content. However, you acknowledge that we have the right (but not the obligation), in our sole discretion, to remove or refuse to remove any Content from the Service. If such Content is reported to us, it will be our sole discretion as to what action, if any, should be taken. - - If any Content you have submitted is reported to us as violating this Agreement, you agree that we may call upon you to change, modify, or remove that Content, within a reasonable amount of time, as defined by us. If you do not follow this directive, we may terminate your account. - - ## 4. Member Conduct - - You agree that you will not use the Service to: - - 1. Upload, post, or otherwise transmit any Content that is harmful, threatening, abusive, hateful, invasive to the privacy and publicity rights of any person, or that violates any applicable local, state, national, or international law, including any regulation having the force of law; - 1. Upload, post, or otherwise transmit any Content that is spam, or contains unethical or unwanted commercial content designed to drive traffic to third party sites or boost the search engine rankings of third party sites, or to further unlawful acts (such as phishing) or mislead recipients as to the source of the material (such as spoofing); - 1. Maliciously impersonate any real person or entity, including but not limited to a Growstuff staff member or volunteer, or to otherwise misrepresent your affiliation with any person or entity; - 1. Upload, post or otherwise transmit any Content that you do not have a right to transmit under any law or under contractual or fiduciary relationships (such as inside information, proprietary and confidential information learned or disclosed as part of employment relationships or under nondisclosure agreements); - 1. Upload, post or otherwise transmit any Content that infringes any patent, trademark, trade secret, copyright, or other proprietary rights of any party; - 1. Interfere with or disrupt the Service or servers or networks connected to the Service, or disobey any requirements, procedures, policies or regulations of networks connected to the Service; - 1. Solicit passwords or personal identifying information for unintended, commercial or unlawful purposes from other users; - 1. Upload, post or otherwise transmit any Content that contains viruses, worms, malware, Trojan horses or other harmful or destructive content; - 1. Allow usage by others in such a way as to violate this Agreement; - 1. Make excessive or otherwise harmful automated use of the Service; - 1. Access any other person's account, or exceed the scope of the Service that you have signed up for; for example, accessing and using features you don't have a right to use. - - You agree that you will abide by the Community Guidelines, which are currently available at [http://growstuff.org/policy/community](http://growstuff.org/policy/community). - - ## 5. Volunteers - - We appreciate the service of volunteers in many aspects of Growstuff's operations. Volunteer activities include but are not limited to developing software, providing technical support, writing documentation, performing site administration duties, providing expert advice, research, technical writing, reviewing, categorizing, and other duties as necessary to support the operation of the Service. - - All volunteers are expected to be of legal age, or volunteering with the consent of a legal parent or guardian. - - By volunteering, you agree that any work created as a result of your volunteer activities shall be licensed to Growstuff on a perpetual, irrevocable, and world-wide basis, to the extent permitted by law. You agree that Growstuff may determine the basis upon which your volunteer work shall be licensed to others, including under Open Source or Creative Commons licenses that may permit the further alteration or dissemination of your work. If laws prevent such licensing, you agree never to sue Growstuff for the use of said work. - - By volunteering, you agree that you are providing your work with no expectation of pay or future consideration by Growstuff. You also agree that you have taken reasonable diligence to ensure that the work is correct, accurate, and free of defect. You agree that you will not disclose or share any proprietary or confidential information you are provided with in the course of your volunteer work. - - No user is required to volunteer, and users who do not volunteer will receive equal care, support, and attention. - - ## 6. Privacy Policy - - Your use of the Website is governed by the Privacy Policy, currently located at [http://growstuff.org/policy/privacy](http://growstuff.org/policy/privacy). - - ## 7. API and Data Use Policy - - Your use of our API and/or data is governed by our API and Data Use Policy, currently located at [http://growstuff.org/policy/api](http://growstuff.org/policy/api). - - ## 8. Copyright Infringement - - If you believe that material located on the Website violates your copyright, you may notify us in accordance with our Copyright Policy, currently located at [http://growstuff.org/policy/copyright](http://growstuff.org/policy/copyright). - - ## 9. Resale of Services - - You agree not to reproduce, duplicate, copy, sell, resell, or exploit any portion of the Service, use of the Service, or access to the Service, except as is permitted under our API and Data Use Policy, open source license pertaining to the Service's source code, or Creative Commons licenses pertaining to Content or other material posted on the Service. - - ## 10. Indemnity - - You agree to indemnify and hold harmless Growstuff Pty Ltd, its contractors, its licensors, and their respective directors, officers, employees and agents from and against any and all claims and expenses, including attorneys' fees, arising out of your use of the Service, including but not limited to out of your violation of this Agreement. - - ## 11. Termination - - Growstuff may terminate your account or otherwise restrict your use of the Service at any time if we believe you have violated this Agreement. If this occurs, you will be notified by email, and we will tell you which part of the Agreement we believe you violated. We may, at our discretion, choose to issue a warning rather than terminate your account, in which case you will also be notified by email and told which part of the Agreement we believe you violated. We will also provide you with a contact address where you may appeal our decision, however, we do not guarantee that we will change our minds. - - You agree that any termination of your access to the Service may involve removing or discarding any content you have provided. - - Paid accounts that are terminated for violations of this Agreement will only be refunded at our discretion, and only if such termination should come under our established criteria for issuing refunds. - - We may, at our sole discretion, discontinue providing the Service at any time, with or without notice. - - If you wish to terminate this Agreement, you may delete your account and cease using the Service. You agree that, upon deletion of your account, we may, but are not required to, remove any Content you have provided, at any time past the deletion of your account. - - All provisions of this Agreement which by their nature should survive termination shall survive termination, including, without limitation, ownership provisions, warranty disclaimers, indemnity and limitations of liability. - - ## 12. Changes - - We reserve the right, at our sole discretion, to modify or replace any part of this Agreement at any time. A history of changes to this Agreement is available via our public source code repository at [https://github.com/Growstuff/policy](https://github.com/Growstuff/policy). We will take reasonable steps to notify you of any substantial changes to this Agreement; however, it is your responsibility to check this Agreement periodically for changes. Your continued use of the Service following the posting of any changes to this Agreement constitutes acceptance of those changes. - - We may also, in the future, offer new features or services through the Service. Such new features and/or services shall be subject to the terms and conditions of this Agreement. - - ## 13. Disclaimer of Warranties - - This Service is provided "as is". Growstuff Pty Ltd and its suppliers and licensors hereby disclaim all warranties of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose and non-infringement. Neither Growstuff Pty Ltd nor its suppliers and licensors, makes any warranty that the Service will be error free or that access to the Service will be continuous or uninterrupted. You agree that any interruptions to the service will not qualify for reimbursement or compensation. You understand that you download from, or otherwise obtain content or services through, the Service at your own discretion and risk. - - No advice or information, whether oral or written, obtained by you in any fashion shall create any warranty not expressly stated in this Agreement. - - ## 14. Limitation of Liability - - You expressly understand and agree that in no event will Growstuff Pty Ltd or its suppliers or licensors, be liable with respect to any subject matter of this agreement under any contract, negligence, strict liability or other legal or equitable theory for: (i) any special, incidental or consequential damages; (ii) the cost of procurement or substitute products or services; (iii) interruption of use or loss or corruption of data; (iv) any statements or conduct of any third party on the service; or (v) any unauthorized access to or alterations of your Content. We shall have no liability for any failure or delay due to matters beyond our reasonable control. - - The foregoing shall not apply to the extent prohibited by applicable law. - - ## 15. General Information - - This Agreement constitutes the entire agreement between us and you concerning your use of the Service. This Agreement may only be modified by a written amendment signed by an authorized representative of Growstuff Pty Ltd, or by the posting of a revised version to this location. Except to the extent that applicable law (if any) provides otherwise, any dispute arising between you and Growstuff Pty Ltd regarding these Terms of Service and/or your use or access of the Service will be governed by the laws of the state of Victoria and the federal laws of Australia, excluding any conflict of law provisions. You agree to submit to the jurisdiction of the state and federal courts located in Melbourne, Australia for any disputes arising out of or relating to your use of the Service or your acceptance of this Agreement. - - If any part of this Agreement is held invalid or unenforceable, that part will be construed to reflect the parties' original intent, and the remaining portions will remain in full force and effect. A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, will not waive such term or condition or any subsequent breach thereof. - - The section titles in this Agreement are for convenience only and have no legal or contractual effect. - - ## 16. Reporting Violations - - To report a violation of this agreement, please email [support@growstuff.org](support@growstuff.org). - - ## 17. Creative Commons - - This Terms of Service document is based on one developed by Automattic ([http://wordpress.com/tos/](http://wordpress.com/tos/)) with amendments by Dreamwidth ([http://www.dreamwidth.org/legal/tos](http://www.dreamwidth.org/legal/tos)) and is licensed under a [Creative Commons Attribution-ShareAlike 2.5 License](http://creativecommons.org/licenses/by-sa/2.5/). - - diff --git a/app/views/support/index.html.haml b/app/views/support/index.html.haml deleted file mode 100644 index 2b64fd000..000000000 --- a/app/views/support/index.html.haml +++ /dev/null @@ -1,211 +0,0 @@ --content_for :title, 'Support - Frequently Asked Questions' - -:markdown - ## About Growstuff - - ### Who runs Growstuff? - - Growstuff is run by Alex Bayley ([Skud](/members/skud)) an open source - software developer and keen veggie gardener from Melbourne, Australia. - - ### How did Growstuff get started? - - The idea of Growstuff came out of a discussion at an open source conference in Spain in 2012. We wanted a free, open source of information about planting and growing crops, and realised the best way to do this would be to crowdsource it from gardeners around the world. - - We first set up Growstuff as an open source project in August 2012, and quietly launched it in March 2013. We are planning to have a full public launch in May 2013. - - ### Is Growstuff a non-profit? - - No, Growstuff is a for-profit business (Growstuff Pty Ltd), incorporated in Australia. The business helps provide hosting and support for the Growstuff website. However, we make our best efforts to operate as an ethical, transparent, and community-minded company. You should also know that software and aggregated data about crops and who's growing them are freely available under open licenses. You might like to read [Why Growstuff is Open Source](http://blog.growstuff.org/2013/02/20/why-growstuff-is-open-source/) to understand some of the reasoning behind that. - - ### How does Growstuff make money? - - We will offer paid subscriptions/memberships, which give you access to special features and a warm glow of knowing you're supporting a sustainable, community-focused project. - - ### Can I advertise on Growstuff? - - Sorry, we're 100% ad-free! - - If you're a member, you can post things to trade or sell in our trading post area, but we don't have and will never have banner ads or the like. We believe that supporting a website through outside advertising makes for a less pleasant experience for our members and visitors, and is not a sustainable business model. - - ### What's the status of Growstuff? Is it in beta? - - We don't much like the word "beta" or the idea it represents. - Growstuff is in a constant state of change and improvement, and we - hope we will always be adding new features and making things better - for our members. - - If you find any bugs or problems, please let us know via our support - forum. If a feature you want isn't available yet, check back soon! - - ## Membership and payments - - ### Can I use Growstuff for free? - - Absolutely! You can sign up right now for a no-cost membership and use it for as long as you want, perhaps forever. - - ### Can I get a membership for my family, school, or community group? - - Yup! Feel free to sign up as "JonesFamily" or "SmithfieldCommunity" or whatever floats your boat. - - Just keep in mind that you are responsible for anything that happens under that account, so be careful who you allow to use it. In due course, we are hoping to develop features to help community gardens share with their members/gardeners, so that they can track what's planted in the community garden without having to login as the community garden account. We'll publicise this widely when it's ready, so keep an ear to the ground. - - ### What other types of accounts are there? - - You can purchase a paid account which will give you access to special - features, and a warm glow of knowing you're supporting a - community-focused, open source project. You can see the current list - of paid account options in our [shop](/shop). - - ## Profile, settings, and privacy - - ### How do I add a picture to my profile? - - Profile pictures are provided [Gravatar](http://gravatar.com Gravatar), a service that provides "Globally Recognised Avatars", run by the people who operate the Wordpress blogging platform. - - If you have ever signed up for Gravatar in the past, using the same address as you signed up for Growstuff, you will already have a picture for your profile. - - If you have signed up for Growstuff with a different email address than your Gravatar address, you will need to add it on Gravatar. - - If you have never signed up for Gravatar before, you can create an account and upload a picture, which will appear not only on Growstuff, but on any other site which supports Gravatars and where you use the same email address. - - ### Do I have to fill in all this personal stuff? - - Your profile asks several questions about you, which you can choose to answer (or not) as you see fit. We don't require personal information like your legal name, gender, or age for tracking or demographic purposes -- one of the benefits of not having ads on our site! - - When it comes to location, it really helps if you can provide that to Growstuff because we use it to suggest things to grow. However, you can do it at whatever level of detail you're comfortable with: perhaps the name of your town, or your state or province, or even your country if the country is small enough and has a fairly consistent climate. Just choose something that is close enough to give you accurate growing advice, and vague enough to feel safe. - - You can read more about the privacy of your information in our [Privacy Policy](http://growstuff.org/policy/privacy). - - - ## Crops, gardens, and planting - - ### How can I add a new crop? - - For now, please drop a note in [Requests for new crops](http://www.growstuff.org/posts/skud-20130319-requests-for-new-crops) on our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support). - - ### Will you add non-edible plants? - - We do not currently have plans to add plants which are not edible or which are not "useful" in a food-growing or sustainability context -- these might include companions plants, green manure crops, plants used to manage pests or diseases, and the like. If you're thinking of purely ornamental plants, we probably won't be adding them anytime soon. - - However, we are hoping, in future, to support the ability for any member to plant "unofficial" plants that aren't in our crop database. - - ## Posting, commenting, and forums - - ### What formatting can I use in posts and comments? - - We use [Markdown](http://daringfireball.net/projects/markdown/syntax/) syntax, which offers a pretty wide range of options from simple emphasis (bold and italics) to links, pictures, and more. We're hoping to install a toolbar to help you generate the right syntax, but in the meantime I'm afraid all we can offer is the rather technical documentation linked above. - - ## Forthcoming features - - ### Where can I see what features are planned? - - Our software developers use a tracking tool called Pivotal Tracker, and you can see ours at [http://tracker.growstuff.org/](http://tracker.growstuff.org). This tells you what features we are currently working on and plan to work on soon. - - Pivotal Tracker's interface shows three columns of information: - - * the "Current" section shows the features (called "stories") that we're working on at the moment - * "Backlog" shows you stories that we're planning to work on in the nearish future - * "Icebox" contains stories that we've identified as things we'd like to do, but which don't have a timeframe set yet. - - ### Where can I suggest a feature I'd like to see? - - We suggest checking the [tracker](http://tracker.growstuff.org/) first (see above) to see if it's something we're already planning or talking about. Once you've done that, if it's not already planned or you have some other comments to make, you can post your suggestion in the [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support]. - - ## Developers and API - - ### Is there a Growstuff API? - - At present there is no official API, as our site is still changing so - rapidly. However, we do expose some of our data via JSON and/or RSS - feeds, and you're welcome to play with it, on the understanding that - it may change under you. You can find [API docs on our wiki](http://wiki.growstuff.org/index.php/API). - - Use of our API and data is subject to the [API and Data Use Policy](http://www.growstuff.org/policy/api). - - ### What license is your data under? - - Growstuff's data is licensed under the [Creative Commons Attribution Share-Alike license (CC-BY-SA) 3.0 Unported license](http://creativecommons.org/licenses/by-sa/3.0/). This means you can re-use it as long as you attribute it to Growstuff (by linking back to our site), and as long as your own app/site/project shares its own content or data under CC-BY-SA. - - See our [API and Data Use Policy](http://growstuff.org/policy/api) for more information. - - ## Volunteering and jobs - - ### Are you hiring? - - Sadly, no. We're a self-funded/bootstrapped company, and at present we're not even paying ourselves. - - When we are ready to hire, we will most likely look first to people we know from our community. If you want to get involved, see below. - - ### How can I volunteer to help Growstuff? - - First and foremost, by being an active member of the site -- growing crops, tracking your harvests, posting in our forums, getting to know other members -- you help build our database and our community, without which Growstuff would be completely pointless. So, thanks for that! - - Secondly, we'd love it if you could spread the word about Growstuff to your friends who grow their own food or who might like to try. You can see some tips on how to do that below. - - Growstuff's software is built with the help of volunteer developers, too. If you're a coder or would like to learn how to code, you can join us in that. All are welcome, regardless of experience. - - We also have volunteer crop wranglers, who manage our crops database, and moderators, who help keep the forums running smoothly. These are usually chosen from among our most active and helpful members. - - ### How can I get involved as a coder? - - Start by checking out our [wiki](http://wiki.growstuff.org/), code on [Github](http://github.com/Growstuff/growstuff), and [tracker](http://tracker.growstuff.org) to get an idea of how we work. - - If you want to get involved, you should join our [discussion mailing list](http://lists.growstuff.org/mailman/listinfo/discuss) and/or come hang out on our [IRC channel](http://wiki.growstuff.org/index.php/IRC), #growstuff on irc.freenode.net. - - ### My coding skills are rusty or non-existent. Can I still get involved? - - Sure! We love to mentor new coders, people who haven't coded in a while, or people who are just learning our platform (Ruby on Rails) for the first time. We work by pair programming, and can get you started on easy stories, starting with something as simple as fixing a typo or HTML tag (check the "easy" tag in our [tracker](http://tracker.growstuff.org) for some examples). - - ### How can I help spread the word about Growstuff? - - First and foremost, by telling your friends and inviting them to join and be part of it. We don't want to be spammy about it, so we'll never ask to scrape your address book or automatically post Facebook updates or tweet on your behalf. But we would really love it if you'd tell people in your own words. - - Places to spread the word online: Facebook, Twitter, and other social media; your own blog or website; gardening or sustainability forums you participate in. - - Or offline: tell friends, family and neighbours; spread the word through your local community gardens, farmers markets, or produce swaps; contact your local sustainability or Transition group; or any other place where you think food-growers might be. - - ## Terms of service, copyright, and other abuse - - ### Where can I report a violation of the Terms of Service or Community Guidelines? - - You can post in our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support) or send email to [support@growstuff.org](mailto:support@growstuff.org). - - ### What do you consider spam, and how can I report it? - - There are many kinds of spam. The most obvious is repeated, unwanted commercial advertising. Many spammers also post irrelevant, nonsensical, or low-value content to forums to try and get you to click on a link, or just to see what they can get away with. - - Please report all these kinds of spam! - - For now, because we're so new, we don't have a good spam reporting mechanism set up. However, you can drop a link in our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support) and we'll do what we can. - - ### Someone posted something I believe is copyright. Where can I report it? - - If you are the copyright owner, you can submit a complaint by following the procedure outlined in our [Copyright Infringement Policy](http://growstuff.org/policy/copyright). - - ### Is Growstuff safe for kids to use? - - As a website that's focused on growing food, we expect Growstuff to be a pretty safe and friendly environment. However, some parts of the site (such as posts made by members) may contain mature concepts, coarse language, and the like. If you don't want your kids exposed to these, we strongly suggest you supervise their use of Growstuff. We also suggest you be careful about what personal information your kids share on Growstuff. - - ## Further support - - ### Where can I find a list of known issues with the site? - - In the [Known Issues](http://www.growstuff.org/posts/skud-20130319-known-issues) post on our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support). - - ### My question's not answered here. Where can I ask for further support? - - On our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support). Please check the list of known issues before posting. - - ### Where can I post feedback/kudos? - - We love feedback! Drop us a note in our [Feedback & Support forum](http://www.growstuff.org/forums/growstuff-feedback-support). (Is there an echo in here?) - - ### How else can I contact you? - - If you need help with something that hasn't been covered here, then you can send an email to [support@growstuff.org](mailto:support@growstuff.org). - - Media/press enquiries can go to [media@growstuff.org](mailto:media@growstuff.org). - - If you have an enquiry about the site in general (eg. businessy stuff, or just want to get in touch with someone official in a non-support-like way), you can send an email to [info@growstuff.org](mailto:info@growstuff.org). - From f5b20c2f32520a99626839ff96699a86cfcafa6f Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:02:42 +0000 Subject: [PATCH 313/392] About is empty, policy won't work without the routes --- app/controllers/about_controller.rb | 2 - app/views/policy/copyright.html.haml | 91 ---------------------------- config/routes.rb | 3 - 3 files changed, 96 deletions(-) delete mode 100644 app/controllers/about_controller.rb delete mode 100644 app/views/policy/copyright.html.haml diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb deleted file mode 100644 index f1549add2..000000000 --- a/app/controllers/about_controller.rb +++ /dev/null @@ -1,2 +0,0 @@ -class AboutController < ApplicationController -end diff --git a/app/views/policy/copyright.html.haml b/app/views/policy/copyright.html.haml deleted file mode 100644 index 9f947f373..000000000 --- a/app/views/policy/copyright.html.haml +++ /dev/null @@ -1,91 +0,0 @@ --content_for :title, 'Copyright Infringement Policy' - -:markdown - We hate legalese, so we've tried to make this policy readable. If you've got any questions, feel free to [ask us](mailto:support@growstuff.org), and we'll do our best to answer. - - This Copyright Infringement Policy covers all websites (such as [growstuff.org](http://growstuff.org)) owned and operated by Growstuff Pty Ltd ("Growstuff", "we", "us", "our") and all associated services, collectively referred to as "the Service". It describes how you may report a violation of copyright on the Service. - - Growstuff respects the intellectual property of others, and we ask our users to do the same. Growstuff members are required by the [Terms of Service](http://growstuff.org/policy/tos) to ensure that they have the legal right to post content to the Service. - - Growstuff is based in Melbourne, Australia and is not subject to the provisions of the United States Digital Millennium Copyright Act (DMCA). However, we have established policy and procedures which are similar to those required by the DMCA, as we believe they constitute best practice for web services operating in Australia. - - ## 1. Notifying us of an infringement - - If you believe that a Growstuff member has infringed your intellectual property rights by posting Content to the service, you may follow these steps to notify us and ask for the removal of the Content. - - Notifications may be submitted by email to [support@growstuff.org](mailto:support@growstuff.org) or by physical mail to: - - Growstuff - Level 3, 673 Bourke Street - Melbourne VIC 3000 - AUSTRALIA - - We prefer to receive notifications by email. - - Copyright infringement notifications sent through any other mechanism or forum will not be acted upon. - - You must provide the following information: - - * Sufficient information to identify the copyrighted work being infringed. For instance, if the work is a published book, provide the title, author, and ISBN; if the work is a magazine article, provide the title, author, magazine name, and magazine issue; if the work is available on the Internet, provide the URL of the work. - * The URL of the specific page on Growstuff where your work was reproduced without permission. General descriptions or non-specific links (such as to Growstuff's homepage) cannot be acted upon. - * Your postal address, telephone number, and email address. - * A statement by you that the above information is accurate and that you are the copyright or intellectual property owner or authorized to act on the copyright or intellectual property owner's behalf. - * A physical signature or digital signature in a recognized industry-standard format such as PGP, of the copyright or intellectual property owner or the person authorized to act on their behalf. Unsigned notifications will not be processed. - - ## 2. Responding to notifications - - We will respond to copyright infringement notifications within two business days. - - If we are not provided with enough information to act on the notification, including all the items listed in the section above, we will reject the notification and notify the submitter that it cannot be acted upon. - - If the Content is not hosted on our servers (for instance, if the notification concerns an image hosted on another site which is merely displayed on or linked from our site) we will respond, notifying the submitter that the Content is not hosted by us and referring them to the hosting site. - - Provided we are able to act upon the notification, we will contact the member who posted the Content and inform them of the notification and claim of intellectual property rights. - - The member will have two business days to respond. They may respond as follows: - - * Admit that they have posted something to which they do not hold intellectual property rights. In this case, the member may delete the Content from the Service, or we may render it inaccessible. - * Submit a counter-notification, stating that they have the right to post the Content, and that they are prepared to uphold this claim in court. The process for this is outlined below. - * Respond saying that they do not believe they have infringed any intellectual property rights, but that they do not wish to formally submit a counter-notification. In this case, the member may delete the Content from the Service, or we may render the Content inaccessible. - * If the member fails to respond, we will render the Content inaccessible. - - When Content is deleted or rendered inaccessible, we will take reasonable efforts to ensure it cannot be accessed via the Service. However, caching or external references may mean that Content remains accessible for some time, including on third-party sites or applications. Third party sites and applications are not under Growstuff's control. If infringing Content has been removed or rendered inaccessible via the Service but is still available via third-party sites and applications, the copyright or intellectual property holder may contact the operators of those sites/applications to notify them of the infringement. - - ## 3. Counter-notification and restoration process - - A counter-notification is a statement that you do not believe your content infringes on another person's rights, or that your use of another person's copyrighted material falls into a protected category under law. - - By filing a counter-notification, you are indicating that you are willing to defend your use of the material in court, if the copyright owner chooses to bring a lawsuit against you for your use of the material. This may involve civil and/or criminal penalties. We strongly suggest you contact an intellectual property lawyer licensed to practice law in your jurisdiction before you do this, so that you are aware of your rights and obligations under the law. - - A counter-notification must contain the following items: - - * Your signature. Signatures may be a physical signature or a digital signature in a recognized industry-standard format such as PGP. - * The URL of the Content that has been called into question (this will have been provided in the original notification). - * A statement that you have a good faith belief that the copyright infringement notification was sent as a result of mistake or misidentification of the material. This should include any reasons why you believe your use of the material is not infringing. - * Your name, address, and telephone number. - - We will forward your counter-notification, in full, to the submitter of the original notification. They will then have 14 days to initiate legal action and notify us that they have done so. - - In the meantime, we will render the Content inaccessible. - - If, after 14 days, we have not been informed that legal proceedings have been initiated, we will restore the Content. - - If you have filed a counter-notification, you may not re-post the allegedly-infringing material until we notify you that the waiting period has expired. - - ## 4. Repeat offenses - - Members who receive three or more valid copyright infringement notices will have their accounts terminated. - - If a counter-notification is filed, or if the member has stated that they do not accept the allegation of copyright infringement but do not wish to formally file a counter-notification, the notification will not be counted toward termination. - - We also reserve the right to terminate the accounts of those who, in our opinion, misuse or abuse the copyright infringement notification process against other members. - - ## 5. Changes - - We may change our Copyright Infringement Policy from time to time. A history of changes to this Policy is available via our public source code repository at [https://github.com/Growstuff/policy](https://github.com/Growstuff/policy). We will take reasonable steps to notify you of any substantial changes to this Policy; however, it is your responsibility to check this Policy periodically for changes. Your continued use of this site after any change in this Privacy Policy will constitute your acceptance of such change. - - ## 6. Creative Commons license - - This Terms of Service document is based on one developed by Dreamwidth ([http://www.dreamwidth.org/legal/dmca](http://www.dreamwidth.org/legal/dmca)) and is licensed under a [Creative Commons Attribution-ShareAlike 2.5 License](http://creativecommons.org/licenses/by-sa/2.5/). - - diff --git a/config/routes.rb b/config/routes.rb index be85f961e..45ef094e1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -73,9 +73,6 @@ Growstuff::Application.routes.draw do get 'auth/:provider/callback' => 'authentications#create' - get '/about' => 'about#index' - get '/about/:action' => 'about#:action' - get '/shop' => 'shop#index' get '/shop/:action' => 'shop#:action' From 8c0fc54344e43326f7937e3363a04c57ea4eae42 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:29:55 +0000 Subject: [PATCH 314/392] Sorting tests related to moving to CMS --- .../confirmation_instructions.html.haml | 2 +- spec/views/about/contact_spec.rb | 28 ------------------- spec/views/policy/community_spec.rb | 28 ------------------- spec/views/policy/tos_spec.rb | 28 ------------------- 4 files changed, 1 insertion(+), 85 deletions(-) delete mode 100644 spec/views/about/contact_spec.rb delete mode 100644 spec/views/policy/community_spec.rb delete mode 100644 spec/views/policy/tos_spec.rb diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml index d910951f6..6892d9b3b 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.haml +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -25,7 +25,7 @@ %p We'd also appreciate it if you'd read our = succeed "," do - = link_to 'Community Guidelines', url_for(:controller => '/policy', :action => 'community', :only_path => false) + = link_to 'Community Guidelines', '#{root_url}/policy/community' and make sure you follow them. We want #{site_name} to be a friendly, welcoming environment for everyone, and we hope you'll help us keep it that way. diff --git a/spec/views/about/contact_spec.rb b/spec/views/about/contact_spec.rb deleted file mode 100644 index 695be51b4..000000000 --- a/spec/views/about/contact_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe 'about/contact.html.haml', type: "view" do - before(:each) do - render - end - - it 'should show support faq' do - render - rendered.should have_content 'General contact email' - end -end diff --git a/spec/views/policy/community_spec.rb b/spec/views/policy/community_spec.rb deleted file mode 100644 index a56139aad..000000000 --- a/spec/views/policy/community_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe 'policy/community.html.haml', type: "view" do - before(:each) do - render - end - - it 'should show community guidelines' do - render - rendered.should have_content 'is a community by and for food-gardeners.' - end -end diff --git a/spec/views/policy/tos_spec.rb b/spec/views/policy/tos_spec.rb deleted file mode 100644 index baac388da..000000000 --- a/spec/views/policy/tos_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe 'policy/tos.html.haml', type: "view" do - before(:each) do - render - end - - it 'should show terms of service' do - render - rendered.should have_content 'Terms of Service' - end -end From 29102e3b52c0f1d10b9cd7946e135d3b46bab1da Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:39:14 +0000 Subject: [PATCH 315/392] Cleaning up more tests --- spec/views/support/index_spec.rb | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 spec/views/support/index_spec.rb diff --git a/spec/views/support/index_spec.rb b/spec/views/support/index_spec.rb deleted file mode 100644 index 3749bbf6d..000000000 --- a/spec/views/support/index_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -## DEPRECATION NOTICE: Do not add new tests to this file! -## -## View and controller tests are deprecated in the Growstuff project. -## We no longer write new view and controller tests, but instead write -## feature tests (in spec/features) using Capybara (https://github.com/jnicklas/capybara). -## These test the full stack, behaving as a browser, and require less complicated setup -## to run. Please feel free to delete old view/controller tests as they are reimplemented -## in feature tests. -## -## If you submit a pull request containing new view or controller tests, it will not be -## merged. - - - - - -require 'rails_helper' - -describe 'support/index.html.haml', type: "view" do - before(:each) do - render - end - - it 'should show support faq' do - rendered.should have_content 'About Growstuff' - end - - it 'should not mention Courtney any more' do - rendered.should_not have_content 'Courtney' - rendered.should_not have_content 'phazel' - end -end From daa3c08706fc71ea2cd6b64a2402bc14c429f831 Mon Sep 17 00:00:00 2001 From: Cesy Date: Wed, 12 Aug 2015 14:45:53 +0000 Subject: [PATCH 316/392] Fixing broken links to pages that are now in CMS --- app/views/devise/mailer/confirmation_instructions.html.haml | 2 +- app/views/devise/registrations/new.html.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml index 6892d9b3b..f8a275dba 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.haml +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -25,7 +25,7 @@ %p We'd also appreciate it if you'd read our = succeed "," do - = link_to 'Community Guidelines', '#{root_url}/policy/community' + = link_to 'Community Guidelines', "#{root_url}/policy/community" and make sure you follow them. We want #{site_name} to be a friendly, welcoming environment for everyone, and we hope you'll help us keep it that way. diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index f15142bb0..3ec01a0ef 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -31,7 +31,7 @@ = f.check_box :tos_agreement I agree to the = succeed "." do - = link_to 'Terms of Service', url_for(:action => 'tos', :controller => '/policy') + = link_to 'Terms of Service', "#{root_url}/policy/tos" .form-group .col-md-offset-2.col-md-8.checkbox %label From 23a6722ddbe6caadeb72422022dc62b39323750e Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Sun, 22 May 2016 16:34:36 +0000 Subject: [PATCH 317/392] Precompile css and js with sass --- script/deploy-tasks.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index b225b1f6e..481f221f6 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -2,6 +2,9 @@ # tasks to run at deploy time, usually after 'rake db:migrate' +# Permanent tasks +rake assets:precompile + # When adding tasks, do so in chronological order, and note the date # when it was added. This will help us know which ones have been run # and can safely be commented out or removed. @@ -10,5 +13,7 @@ # echo "YYYY-MM-DD - do something or other" # rake growstuff:oneoff:something -echo "2015-01-30 - build Elasticsearch index" -rake growstuff:oneoff:elasticsearch_create_index +# One-off tasks + +# echo "2015-01-30 - build Elasticsearch index" +# rake growstuff:oneoff:elasticsearch_create_index From fe7d8f73f3be3c59cef46437c87a232cea780e7e Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Sun, 22 May 2016 20:49:35 -0400 Subject: [PATCH 318/392] darken navbar item text when it opens (and the background turns light) Fixes #896 --- app/assets/stylesheets/custom_bootstrap/variables.sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/stylesheets/custom_bootstrap/variables.sass b/app/assets/stylesheets/custom_bootstrap/variables.sass index 7809e1c78..3f364f862 100644 --- a/app/assets/stylesheets/custom_bootstrap/variables.sass +++ b/app/assets/stylesheets/custom_bootstrap/variables.sass @@ -42,7 +42,7 @@ $navbar-default-bg-highlight: $brown $navbar-default-color: $beige $navbar-default-link-color: darken($beige, 20%) $navbar-default-link-hover-color: $beige -$navbar-default-link-active-color: $beige +$navbar-default-link-active-color: darken($beige,80%) $navbar-default-brand-color: lighten($green, 20%) // Top nav collapse threshold From e7926b6f226accdc9bbb88599950b6eee132e907 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 10:48:49 +0930 Subject: [PATCH 319/392] Improve the styling of a planting to be more like the other card-layouts --- app/assets/stylesheets/overrides.sass | 14 +++++ app/views/plantings/_thumbnail.html.haml | 80 ++++++++++++------------ 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 41cf2b03b..5bf527c68 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -93,6 +93,20 @@ p.stats padding-left: 1em width: 15em +.planting-thumbnail + padding: .25em + + dl.planting-attributes + font-size: 85% + width: 100% + + dt + text-align: left + width: 80px + dd + padding-left: 80px + margin-left: auto + #placesmap, #cropmap height: 500px diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index df62f7a9c..0dd5c0708 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,41 +1,41 @@ -.row - .col-xs-4.col-md-2 - = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - .col-xs-4.col-md-6 - %dl.dl-horizontal - %dt Owner: - %dd= link_to planting.owner.login_name, planting.owner - %dt Garden: - %dd= link_to planting.garden.name, planting.garden - %dt Planted on: - %dd= planting.planted_at - %dt Quantity: - %dd= "#{display_planting_quantity(planting)}" - %dt Finished on: - %dd= "#{display_finished(planting)}" - %dt Sun/shade?: - %dd - - sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness - = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") - = " (#{sunniness})" - %dt Planted from: - %dd= "#{display_planted_from(planting)}" - .col-xs-4.col-md-4 - %ul{:style => "list-style-type:none"} - %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - - if can? :edit, planting - %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - - if can? :destroy, planting - %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' -.row - .col-xs-3.col-md-4 - %dl - %dt Crop name: - %dd= link_to planting.crop.name, planting.crop - %dt Days until maturity: - %dd= "#{display_days_before_maturity(planting)}" +.panel.planting-thumbnail + .row + .col-xs-4.col-md-4 + = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting + .col-xs-4.col-md-5 + %h4= link_to planting.crop.name, planting.crop + %dl.dl-horizontal.planting-attributes + %dt Owner: + %dd= link_to planting.owner.login_name, planting.owner + %dt Garden: + %dd= link_to planting.garden.name, planting.garden + %dt Planted on: + %dd= planting.planted_at + %dt Quantity: + %dd= "#{display_planting_quantity(planting)}" + %dt Finished on: + %dd= "#{display_finished(planting)}" + %dt Sun/shade?: + %dd + - sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness + = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") + = " (#{sunniness})" + %dt Planted from: + %dd= "#{display_planted_from(planting)}" + .col-xs-4.col-md-3 + %ul{:style => "list-style-type:none; text-align:right"} + %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' + - if can? :edit, planting + %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + - if ! planting.finished + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' + - if can? :destroy, planting + %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + .row + .col-xs-3.col-md-4 + %dl + %dt Days until maturity: + %dd= "#{display_days_before_maturity(planting)}" - .col-xs-9.col-md-8 - = render partial: 'plantings/planting_progress', locals: {planting: planting} + .col-xs-9.col-md-8 + = render partial: 'plantings/planting_progress', locals: {planting: planting} From 55380dab04220fd1a53b42e1e653b5925f543b73 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 10:58:09 +0930 Subject: [PATCH 320/392] Fix style regression by moving garden content properly into the container --- app/views/members/_gardens.html.haml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 7733e298d..ad40fda9a 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -44,12 +44,12 @@ %p = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' - %h3 What's planted here? - .row - - if g.featured_plantings.size > 0 - - g.featured_plantings.each.with_index do |planting| - .col-xs-12.col-lg-6 - = render partial: "plantings/thumbnail", locals: {:planting => planting} + %h3 What's planted here? + .row + - if g.featured_plantings.size > 0 + - g.featured_plantings.each.with_index do |planting| + .col-xs-12.col-lg-6 + = render partial: "plantings/thumbnail", locals: {:planting => planting} - %p - = link_to "More about this garden...", url_for(g) + %p + = link_to "More about this garden...", url_for(g) From 24956255d7bec704544dff674723e4886b95a273 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:03:23 +0930 Subject: [PATCH 321/392] Fix layout of view all plantings link --- app/views/places/show.html.haml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 75be54058..a6aa81cab 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -29,17 +29,20 @@ %h3= "Recent plantings near #{@place}" - .row - - plantings = [] - - @nearby_members.first(10).each do |member| - - member.plantings.first(5).each do |planting| - - plantings << planting - - if !plantings.blank? + + - plantings = [] + - @nearby_members.first(10).each do |member| + - member.plantings.first(5).each do |planting| + - plantings << planting + - if !plantings.blank? + .row - plantings.first(10).each.with_index do |planting, index| .col-xs-12.col-lg-6 = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + .row = link_to "View all plantings >>", plantings_path - - else + - else + .row %p No nearby plantings found - else %p No results found \ No newline at end of file From 5e8211172bb0f522abb037f4adda6caf3410285e Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:12:42 +0930 Subject: [PATCH 322/392] Only show a heading for Notes if there are notes --- app/views/plantings/show.html.haml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index b56e1f38c..983a28c6d 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -59,10 +59,11 @@ .col-md-6 = render :partial => "crops/index_card", :locals => { :crop => @planting.crop} -%h2 Notes +- if @planting.description + %h2 Notes -:growstuff_markdown - #{ @planting.description != "" ? @planting.description : "No description given." } + :growstuff_markdown + #{ @planting.description != "" ? @planting.description : "No description given." } - if @planting.photos.size > 0 or (can? :edit, @planting and can? :create, Photo) %h2 Pictures From d9ed21ba539ff0de56de5e59ba5a299e1c8c05ae Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:24:32 +0930 Subject: [PATCH 323/392] Styling the show view of a planting more like the card view (though 100% card view looks funny with the crop thumbnail floating to the right) --- app/assets/stylesheets/overrides.sass | 9 ++++ app/views/plantings/show.html.haml | 75 +++++++++++++-------------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 5bf527c68..4ee88781d 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -93,6 +93,15 @@ p.stats padding-left: 1em width: 15em +.planting + dl.planting-attributes + font-size: 85% + + dt + text-align: left + dd + margin-left: auto + .planting-thumbnail padding: .25em diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 983a28c6d..ac37c3449 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -1,51 +1,46 @@ =content_for :title, "#{@planting.crop} in #{@planting.location}" -.row +.row.planting .col-md-6 - %p - %b Owner: - = link_to @planting.owner, @planting.owner - — - = link_to "view all #{@planting.owner}'s plantings", plantings_by_owner_path(:owner => @planting.owner.slug) - %p - %b Planted on: - = @planting.planted_at ? @planting.planted_at : "not specified" + %dl.dl-horizontal.planting-attributes + %dt Owner: + %dd + = link_to @planting.owner, @planting.owner + — + = link_to "view all #{@planting.owner}'s plantings", plantings_by_owner_path(:owner => @planting.owner.slug) - %p - %b Where: - =link_to "#{@planting.owner}'s", @planting.owner - =link_to @planting.garden, @planting.garden - - if ! @planting.owner.location.blank? - = "(#{@planting.owner.location})" - %p - %b - = "Quantity: " - = "#{display_planting_quantity(@planting)}" + %dt Planted on: + %dd= @planting.planted_at ? @planting.planted_at : "not specified" + + %dt Where: + %dd + =link_to "#{@planting.owner}'s", @planting.owner + =link_to @planting.garden, @planting.garden + - if ! @planting.owner.location.blank? + = "(#{@planting.owner.location})" + + %dt Quantity: + %dd + ="#{display_planting_quantity(@planting)}" - - if !@planting.planted_from.blank? - %p - %b - = "Planted from: " - = "#{display_planted_from(@planting)}" + - if !@planting.planted_from.blank? + %dt Planted from: + %dd= "#{display_planted_from(@planting)}" - %p - %b - = "Sun or shade?: " - - sunniness = @planting.sunniness.blank? ? "not specified" : @planting.sunniness - = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") - = " (#{sunniness})" + %dt Sun or shade? + %dd + - sunniness = @planting.sunniness.blank? ? "not specified" : @planting.sunniness + = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") + = " (#{sunniness})" + + %dt Days until maturity: + %dd= "#{display_days_before_maturity(@planting)}" + + %dt Finished: + %dd= "#{display_finished(@planting)}" %p - %b - = "Days until maturity: " - = "#{display_days_before_maturity(@planting)}" - %p - %b - = "Finished: " - = "#{display_finished(@planting)}" - - %p - %b= render 'planting_progress', planting: @planting + = render 'planting_progress', planting: @planting - if can? :edit, @planting or can? :destroy, @planting %p From 7d10101c57b58833d623f8b666e5a7cc37f49bcd Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:31:29 +0930 Subject: [PATCH 324/392] For a place, talk about the community as a vaguer way of explaining 'members, seeds, plantings, etc' --- app/views/places/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 75be54058..c22094996 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -1,4 +1,4 @@ --content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} members near #{@place}" +-content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} community near #{@place}" = render partial: 'search_form' From 7872bb48e279aba46eb50fa06337bfaa1c8ad229 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:35:49 +0930 Subject: [PATCH 325/392] Fixes #872 Add more links and explain them better --- app/views/members/_map.html.haml | 2 +- app/views/plantings/show.html.haml | 5 ++++- app/views/seeds/show.html.haml | 4 ++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/views/members/_map.html.haml b/app/views/members/_map.html.haml index d98792501..b6b6c40d2 100644 --- a/app/views/members/_map.html.haml +++ b/app/views/members/_map.html.haml @@ -1,5 +1,5 @@ - if member.latitude and member.longitude %div#membermap %p - See other members near + See other members, plantings, seeds and more near = link_to member.location, place_path(member.location) diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index b56e1f38c..4c96bf461 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -58,7 +58,10 @@ .col-md-6 = render :partial => "crops/index_card", :locals => { :crop => @planting.crop} - + %p + %small + View other plantings, members and more near + = link_to @planting.owner.location, place_path(@planting.owner.location) %h2 Notes :growstuff_markdown diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index c2f3399ea..96be29a1c 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -57,3 +57,7 @@ .col-md-6 = render :partial => "crops/index_card", :locals => { :crop => @seed.crop } + %p + %small + View other seeds, members and more near + = link_to @seed.owner.location, place_path(@seed.owner.location) \ No newline at end of file From 80f826421bdd72e67182a193e07519bdb0cd83e8 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:41:42 +0930 Subject: [PATCH 326/392] Add page anchors to put you to the area you are most interested in --- app/views/gardens/_thumbnail.html.haml | 2 +- app/views/members/_location.html.haml | 2 +- app/views/members/_map.html.haml | 2 +- app/views/places/show.html.haml | 6 +++--- app/views/plantings/show.html.haml | 2 +- app/views/seeds/show.html.haml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/gardens/_thumbnail.html.haml b/app/views/gardens/_thumbnail.html.haml index bd3fc7eb1..e831dc986 100644 --- a/app/views/gardens/_thumbnail.html.haml +++ b/app/views/gardens/_thumbnail.html.haml @@ -18,7 +18,7 @@ - if garden.location.blank? not specified - else - = link_to garden.location, place_path(garden.location) + = link_to garden.location, place_path(garden.location, anchor: "gardens") %dt Area : %dd= garden.area.nil? ? "not specified" : pluralize(garden.area, garden.area_unit) %dt Active? : diff --git a/app/views/members/_location.html.haml b/app/views/members/_location.html.haml index 195897d71..a8442afe2 100644 --- a/app/views/members/_location.html.haml +++ b/app/views/members/_location.html.haml @@ -2,4 +2,4 @@ - if member.location.blank? unknown location - else - = link_to member.location, place_path(:place => member.location) + = link_to member.location, place_path(:place => member.location, anchor: "members") diff --git a/app/views/members/_map.html.haml b/app/views/members/_map.html.haml index b6b6c40d2..027f83c65 100644 --- a/app/views/members/_map.html.haml +++ b/app/views/members/_map.html.haml @@ -2,4 +2,4 @@ %div#membermap %p See other members, plantings, seeds and more near - = link_to member.location, place_path(member.location) + = link_to member.location, place_path(member.location, anchor: "members") diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index c22094996..55a61f385 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -4,7 +4,7 @@ %div#placesmap{ :style => "height:300px"} -%h3= "Nearby members" +%h3#members= "Nearby members" - if !@nearby_members.empty? .row @@ -13,7 +13,7 @@ = render :partial => "members/thumbnail", :locals => { :member => member } = link_to "View all members >>", members_path - %h3= "Seeds available for trade near #{@place}" + %h3#seeds= "Seeds available for trade near #{@place}" - crop_id = [] - @nearby_members.first(10).each do |member| - member.seeds.first(5).each do |seed| @@ -27,7 +27,7 @@ - else %p No nearby seeds found - %h3= "Recent plantings near #{@place}" + %h3#plantings= "Recent plantings near #{@place}" .row - plantings = [] diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 4c96bf461..1b9a2570e 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -61,7 +61,7 @@ %p %small View other plantings, members and more near - = link_to @planting.owner.location, place_path(@planting.owner.location) + = link_to @planting.owner.location, place_path(@planting.owner.location, anchor: "plantings") %h2 Notes :growstuff_markdown diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index 96be29a1c..e7885d115 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -60,4 +60,4 @@ %p %small View other seeds, members and more near - = link_to @seed.owner.location, place_path(@seed.owner.location) \ No newline at end of file + = link_to @seed.owner.location, place_path(@seed.owner.location, anchor: "seeds") \ No newline at end of file From 884a3aad2cf1ac8149079ae631f07ff7f55a2761 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 11:51:14 +0930 Subject: [PATCH 327/392] Check we have a location before linking to it --- app/views/places/show.html.haml | 3 ++- app/views/plantings/show.html.haml | 9 +++++---- app/views/seeds/show.html.haml | 11 ++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 55a61f385..e992c7bf9 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -27,7 +27,8 @@ - else %p No nearby seeds found - %h3#plantings= "Recent plantings near #{@place}" + #plantings + %h3= "Recent plantings near #{@place}" .row - plantings = [] diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 1b9a2570e..09fc8597d 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -58,10 +58,11 @@ .col-md-6 = render :partial => "crops/index_card", :locals => { :crop => @planting.crop} - %p - %small - View other plantings, members and more near - = link_to @planting.owner.location, place_path(@planting.owner.location, anchor: "plantings") + - if @planting.owner.location + %p + %small + View other plantings, members and more near + = link_to @planting.owner.location, place_path(@planting.owner.location, anchor: "plantings") %h2 Notes :growstuff_markdown diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index e7885d115..643445a05 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -35,7 +35,7 @@ - else (from = succeed ")" do - = link_to @seed.owner.location, place_path(@seed.owner.location) + = link_to @seed.owner.location, place_path(@seed.owner.location, anchor: "seeds") %p %b Description: @@ -57,7 +57,8 @@ .col-md-6 = render :partial => "crops/index_card", :locals => { :crop => @seed.crop } - %p - %small - View other seeds, members and more near - = link_to @seed.owner.location, place_path(@seed.owner.location, anchor: "seeds") \ No newline at end of file + - if @seed.owner.location + %p + %small + View other seeds, members and more near + = link_to @seed.owner.location, place_path(@seed.owner.location, anchor: "seeds") \ No newline at end of file From b4060b7903b17b044ada83bdd35f31284da29a20 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 12:55:50 +0930 Subject: [PATCH 328/392] Update stale test expectation --- spec/features/member_profile_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index cfa0753ba..0551e3873 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -33,14 +33,14 @@ feature "member profile", js: true do visit member_path(london_member) expect(page).to have_css("h1>small", text: london_member.location) expect(page).to have_css("#membermap") - expect(page).to have_content "See other members near #{london_member.location}" + expect(page).to have_content "See other members, plantings, seeds and more near #{london_member.location}" end scenario "member has not set location" do visit member_path(member) expect(page).not_to have_css("h1>small") expect(page).not_to have_css("#membermap") - expect(page).not_to have_content "See other members near" + expect(page).not_to have_content "See other members" end end From dc9ee18e9669bd44bbcd47c490f143b1053144cf Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 12:56:37 +0930 Subject: [PATCH 329/392] Update stale test expectation --- spec/features/places/searching_a_place_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/places/searching_a_place_spec.rb b/spec/features/places/searching_a_place_spec.rb index b0c0f931a..e8562c244 100644 --- a/spec/features/places/searching_a_place_spec.rb +++ b/spec/features/places/searching_a_place_spec.rb @@ -10,7 +10,7 @@ feature "User searches" do scenario "with a valid place" do visit places_path search_with "Philippines" - expect(page).to have_content "members near Philippines" + expect(page).to have_content "community near Philippines" expect(page).to have_button "search_button" expect(page).to have_content "Nearby members" expect(page).to_not have_content "No results found" From 5104225d114727b06b59c4e8a0410f6973810661 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 16:13:53 +0930 Subject: [PATCH 330/392] #856 Clip long text in definition lists within panels --- app/assets/stylesheets/overrides.sass | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 41cf2b03b..359dc6dcb 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -276,6 +276,11 @@ $state-success-bg: lighten($green, 50%) .panel-footer height: 6em +.panel + .dl-horizontal + text-overflow: ellipsis + overflow: hidden + #gardens_panel_body height: 20em From ab897f05f9c5410530fc987fd3cdbd68f03b3ff1 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 16:21:13 +0930 Subject: [PATCH 331/392] Use panel-body and panel-heading more effectively --- app/assets/stylesheets/overrides.sass | 2 - app/views/plantings/_thumbnail.html.haml | 82 ++++++++++++------------ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 4ee88781d..b9af04816 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -103,8 +103,6 @@ p.stats margin-left: auto .planting-thumbnail - padding: .25em - dl.planting-attributes font-size: 85% width: 100% diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 0dd5c0708..94b51862f 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,41 +1,43 @@ -.panel.planting-thumbnail - .row - .col-xs-4.col-md-4 - = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - .col-xs-4.col-md-5 - %h4= link_to planting.crop.name, planting.crop - %dl.dl-horizontal.planting-attributes - %dt Owner: - %dd= link_to planting.owner.login_name, planting.owner - %dt Garden: - %dd= link_to planting.garden.name, planting.garden - %dt Planted on: - %dd= planting.planted_at - %dt Quantity: - %dd= "#{display_planting_quantity(planting)}" - %dt Finished on: - %dd= "#{display_finished(planting)}" - %dt Sun/shade?: - %dd - - sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness - = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") - = " (#{sunniness})" - %dt Planted from: - %dd= "#{display_planted_from(planting)}" - .col-xs-4.col-md-3 - %ul{:style => "list-style-type:none; text-align:right"} - %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - - if can? :edit, planting - %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' - - if ! planting.finished - %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - - if can? :destroy, planting - %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' - .row - .col-xs-3.col-md-4 - %dl - %dt Days until maturity: - %dd= "#{display_days_before_maturity(planting)}" +.panel.panel-success.planting-thumbnail + .panel-heading + %h3.panel-title= link_to planting.crop.name, planting.crop + .panel-body + .row + .col-xs-4.col-md-4 + = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting + .col-xs-4.col-md-5 + %dl.dl-horizontal.planting-attributes + %dt Owner: + %dd= link_to planting.owner.login_name, planting.owner + %dt Garden: + %dd= link_to planting.garden.name, planting.garden + %dt Planted on: + %dd= planting.planted_at + %dt Quantity: + %dd= "#{display_planting_quantity(planting)}" + %dt Finished on: + %dd= "#{display_finished(planting)}" + %dt Sun/shade?: + %dd + - sunniness = planting.sunniness.blank? ? "not specified" : planting.sunniness + = image_tag("sunniness_#{sunniness}.png", :size => "25x25", :alt => "#{sunniness}", :title => "#{sunniness}") + = " (#{sunniness})" + %dt Planted from: + %dd= "#{display_planted_from(planting)}" + .col-xs-4.col-md-3 + %ul{:style => "list-style-type:none; text-align:right"} + %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' + - if can? :edit, planting + %li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs' + - if ! planting.finished + %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' + - if can? :destroy, planting + %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + .row + .col-xs-3.col-md-4 + %dl + %dt Days until maturity: + %dd= "#{display_days_before_maturity(planting)}" - .col-xs-9.col-md-8 - = render partial: 'plantings/planting_progress', locals: {planting: planting} + .col-xs-9.col-md-8 + = render partial: 'plantings/planting_progress', locals: {planting: planting} From 92cce5910e203bf0cd1813525d581c441fed2cca Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 23 May 2016 16:35:58 +0930 Subject: [PATCH 332/392] Improve planting card UI on mobile --- app/assets/stylesheets/overrides.sass | 21 +++++++++++---------- app/views/plantings/_thumbnail.html.haml | 11 ++++++----- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index b9af04816..4ab1e7738 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -102,17 +102,18 @@ p.stats dd margin-left: auto -.planting-thumbnail - dl.planting-attributes - font-size: 85% - width: 100% +@media (min-width: $screen-md-min) + .planting-thumbnail + dl.planting-attributes + font-size: 85% + width: 100% - dt - text-align: left - width: 80px - dd - padding-left: 80px - margin-left: auto + dt + text-align: left + width: 80px + dd + padding-left: 80px + margin-left: auto #placesmap, #cropmap height: 500px diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 94b51862f..3ae1ee084 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -3,9 +3,9 @@ %h3.panel-title= link_to planting.crop.name, planting.crop .panel-body .row - .col-xs-4.col-md-4 + .col-xs-12.col-md-4 = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - .col-xs-4.col-md-5 + .col-xs-7.col-md-5 %dl.dl-horizontal.planting-attributes %dt Owner: %dd= link_to planting.owner.login_name, planting.owner @@ -24,7 +24,7 @@ = " (#{sunniness})" %dt Planted from: %dd= "#{display_planted_from(planting)}" - .col-xs-4.col-md-3 + .col-xs-1.col-md-3 %ul{:style => "list-style-type:none; text-align:right"} %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting @@ -33,11 +33,12 @@ %li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date' - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' + .row - .col-xs-3.col-md-4 + .col-xs-12.col-md-4 %dl %dt Days until maturity: %dd= "#{display_days_before_maturity(planting)}" - .col-xs-9.col-md-8 + .col-xs-12.col-md-8 = render partial: 'plantings/planting_progress', locals: {planting: planting} From 76f152aa352e8a12a2c5f607f0380ef1e37499c2 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Mon, 23 May 2016 13:07:18 -0400 Subject: [PATCH 333/392] add Code Climate config file --- .codeclimate.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .codeclimate.yml diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 000000000..f568e4bc2 --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,36 @@ +engines: + rubocop: + enabled: true + scss-lint: + enabled: true + shellcheck: + enabled: true + eslint: + enabled: true + coffeelint: + enabled: true + brakeman: + enabled: true + bundler-audit: + enabled: true + duplication: + enabled: true + config: + languages: + - ruby + - javascript + fixme: + enabled: true +ratings: + paths: + - "**.rb" + - "**.js" + - "**.coffee" + - "**.sass" + - "**.haml" + - Gemfile.lock +exclude_paths: +- config/ +- db/ +- spec/ +- public/ From b601fe40b3952649f0ffe4b9fd9f31ea09a5a6cc Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Tue, 24 May 2016 16:55:37 -0400 Subject: [PATCH 334/392] refactor photo controller create for readability --- app/controllers/photos_controller.rb | 53 ++++++++++++++-------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 8130ef4e1..73d47ec5a 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -63,35 +63,20 @@ class PhotosController < ApplicationController @photo.owner_id = current_member.id @photo.set_flickr_metadata - # several models can have photos. we need to know what model and the id - # for the entry to attach the photo to - valid_models = ["planting", "harvest", "garden"] - if params[:type] - if valid_models.include?(params[:type]) - if params[:id] - item = params[:type].camelcase.constantize.find_by_id(params[:id]) - if item - if item.owner.id == current_member.id - # This syntax is weird, so just know that it means this: - # @photo.harvests << item unless @photo.harvests.include?(item) - # but with the correct many-to-many relationship automatically referenced - (@photo.send "#{params[:type]}s") << item unless (@photo.send "#{params[:type]}s").include?(item) - else - flash[:alert] = "You must own both the #{params[:type]} and the photo." - end - else - flash[:alert] = "Couldn't find #{params[:type]} to connect to photo." - end - else - flash[:alert] = "Missing id parameter" - end + if has_valid_key && has_item_id + item = params[:type].camelcase.constantize.find_by_id(params[:id]) + if item && member_owns_item(item) + # This syntax is weird, so just know that it means this: + # @photo.harvests << item unless @photo.harvests.include?(item) + # but with the correct many-to-many relationship automatically referenced + (@photo.send "#{params[:type]}s") << item unless (@photo.send "#{params[:type]}s").include?(item) else - flash[:alert] = "Cannot attach photos to #{params[:type]}" + flash[:alert] = "Could not find this item owned by you" end - else - flash[:alert] = "Missing type parameter" + else + flash[:alert] = "Missing or invalid type or id parameter" end - + respond_to do |format| if @photo.save format.html { redirect_to @photo, notice: 'Photo was successfully added.' } @@ -134,6 +119,22 @@ class PhotosController < ApplicationController private + def valid_models + ["planting", "harvest", "garden"] + end + + def has_valid_key + (params.key? :type) && valid_models.include?(params[:type]) + end + + def has_item_id + params.key? :id + end + + def member_owns_item(item) + item.owner.id == current_member.id + end + def photo_params params.require(:photo).permit(:flickr_photo_id, :owner_id, :title, :license_name, :license_url, :thumbnail_url, :fullsize_url, :link_url) From b5b201b6dfd55364f45cec3c9c489cba2cff9ab9 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 10:38:06 -0400 Subject: [PATCH 335/392] bundle --- Gemfile.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 914398c35..46e9c20df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -91,6 +91,8 @@ GEM cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) + codeclimate-test-reporter (0.5.0) + simplecov (>= 0.7.1, < 1.0.0) codemirror-rails (5.11) railties (>= 3.0, < 5) coderay (1.1.1) @@ -444,6 +446,7 @@ DEPENDENCIES cancancan (~> 1.9) capybara capybara-email + codeclimate-test-reporter coffee-rails (~> 4.1.0) comfortable_mexican_sofa (~> 1.12.0) coveralls From 8c2aa4844f9912696b2778d8e19da7a905eb9aff Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 15:15:09 -0400 Subject: [PATCH 336/392] use CW's case statement idea --- app/controllers/photos_controller.rb | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 73d47ec5a..fb3133588 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -63,13 +63,22 @@ class PhotosController < ApplicationController @photo.owner_id = current_member.id @photo.set_flickr_metadata - if has_valid_key && has_item_id + + collection = case params[:type] + when 'garden' + @photo.gardens + when 'planting' + @photo.plantings + when 'harvest' + @photo.harvests + else + nil + end + + if collection && has_item_id item = params[:type].camelcase.constantize.find_by_id(params[:id]) if item && member_owns_item(item) - # This syntax is weird, so just know that it means this: - # @photo.harvests << item unless @photo.harvests.include?(item) - # but with the correct many-to-many relationship automatically referenced - (@photo.send "#{params[:type]}s") << item unless (@photo.send "#{params[:type]}s").include?(item) + collection << item unless collection.include?(item) else flash[:alert] = "Could not find this item owned by you" end @@ -119,14 +128,6 @@ class PhotosController < ApplicationController private - def valid_models - ["planting", "harvest", "garden"] - end - - def has_valid_key - (params.key? :type) && valid_models.include?(params[:type]) - end - def has_item_id params.key? :id end From 58617b568588c9f3c825b70cc0f46a15662f1338 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 16:07:49 -0400 Subject: [PATCH 337/392] set background color on autocomplete dropdown. Fixes #914 --- app/assets/stylesheets/overrides.sass | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 6d0360687..d649ecb85 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -244,7 +244,8 @@ html, body // Autosuggest -.ui-autocomplete +.ui-autocomplete + background: white z-index: $zindex-tooltip // Crowdfunding campaign, Sep-Oct 2014 From 11e2e86b06d866e9b46a5b82ee1a8d002555a07f Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 16:21:17 -0400 Subject: [PATCH 338/392] make seed card heading link to seed page and add owner link. Fixes #873 --- app/views/seeds/_thumbnail.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/seeds/_thumbnail.html.haml b/app/views/seeds/_thumbnail.html.haml index 1968ec254..7bc5f6ad2 100644 --- a/app/views/seeds/_thumbnail.html.haml +++ b/app/views/seeds/_thumbnail.html.haml @@ -1,7 +1,7 @@ .panel.panel-success .panel-heading %h3.panel-title - = link_to "#{seed.owner.login_name}'s seed", seed.owner + = link_to "#{seed.owner.login_name}'s seed", seed - if can? :edit, seed %a.pull-right{:href => edit_seed_path(seed), :role => "button", :id => "edit_seed_glyphicon"} %span.glyphicon.glyphicon-pencil{:title => "Edit"} @@ -21,6 +21,8 @@ %dd= seed.tradable_to %dt From location : %dd= seed.owner.location + %dt Owner : + %dd= link_to seed.owner.login_name, seed.owner .panel-footer %dt Description %dd From 736e45aec98cc132c2a84556eee47f928ead8b3b Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 17:35:23 -0400 Subject: [PATCH 339/392] update Gemfile.lock for code climate --- Gemfile.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 914398c35..46e9c20df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -91,6 +91,8 @@ GEM cliver (0.3.2) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) + codeclimate-test-reporter (0.5.0) + simplecov (>= 0.7.1, < 1.0.0) codemirror-rails (5.11) railties (>= 3.0, < 5) coderay (1.1.1) @@ -444,6 +446,7 @@ DEPENDENCIES cancancan (~> 1.9) capybara capybara-email + codeclimate-test-reporter coffee-rails (~> 4.1.0) comfortable_mexican_sofa (~> 1.12.0) coveralls From d2276016276051593a8a5f28e647d689f8443ef4 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Wed, 25 May 2016 17:35:57 -0400 Subject: [PATCH 340/392] Add config/factory_girl.rb so that rspec doesn't fail with a confusing 'Could not find mapping for # Date: Wed, 25 May 2016 23:15:36 -0400 Subject: [PATCH 341/392] Stop hard-coding strings for pagination Use translation template to set singular/other strings for .model_name Fixes #855 --- app/views/comments/index.html.haml | 4 +-- app/views/crops/show.html.haml | 4 +-- app/views/crops/wrangle.html.haml | 4 +-- app/views/gardens/index.html.haml | 4 +-- app/views/harvests/index.html.haml | 4 +-- app/views/members/index.html.haml | 4 +-- app/views/members/view_followers.html.haml | 6 ++--- app/views/members/view_follows.html.haml | 6 ++--- app/views/photos/index.html.haml | 4 +-- app/views/photos/new.html.haml | 2 +- app/views/plantings/index.html.haml | 4 +-- app/views/posts/index.html.haml | 4 +-- app/views/seeds/index.html.haml | 4 +-- config/locales/en.yml | 29 ++++++++++++++++++++++ 14 files changed, 56 insertions(+), 27 deletions(-) diff --git a/app/views/comments/index.html.haml b/app/views/comments/index.html.haml index 540773b41..e04707fc7 100644 --- a/app/views/comments/index.html.haml +++ b/app/views/comments/index.html.haml @@ -1,7 +1,7 @@ = content_for :title, "Recent comments" %div.pagination - = page_entries_info @comments, :model => "comments" + = page_entries_info @comments = will_paginate @comments - @comments.each do |comment| @@ -11,7 +11,7 @@ = render :partial => "single", :locals => { :comment => comment } %div.pagination - = page_entries_info @comments, :model => "comments" + = page_entries_info @comments = will_paginate @comments %p diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index c32fc12c8..40c5d1812 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -54,13 +54,13 @@ = render :partial => "shared/signin_signup", :locals => { :to => "post your tips and experiences growing #{ @crop.name.pluralize }" } - else %div.pagination - = page_entries_info @posts, :model => "posts" + = page_entries_info @posts = will_paginate @posts, :params => {:anchor => "posts"} - @posts.each do |post| = render :partial => "posts/single", :locals => { :post => post, :subject => true } %div.pagination - = page_entries_info @posts, :model => "posts" + = page_entries_info @posts = will_paginate @posts, :params => {:anchor => "posts"} .col-md-3 diff --git a/app/views/crops/wrangle.html.haml b/app/views/crops/wrangle.html.haml index 3a13ec68e..4c0448b01 100644 --- a/app/views/crops/wrangle.html.haml +++ b/app/views/crops/wrangle.html.haml @@ -34,7 +34,7 @@ %div.pagination - = page_entries_info @crops, :model => "crops" + = page_entries_info @crops = will_paginate @crops %table{:class => "table table-striped", :id => @approval_status.blank? ? 'recently-added-crops' : "#{@approval_status}-crops"} @@ -64,7 +64,7 @@ ago. %div.pagination - = page_entries_info @crops, :model => "crops" + = page_entries_info @crops = will_paginate @crops diff --git a/app/views/gardens/index.html.haml b/app/views/gardens/index.html.haml index 12928b051..0323d0be1 100644 --- a/app/views/gardens/index.html.haml +++ b/app/views/gardens/index.html.haml @@ -15,7 +15,7 @@ = render :partial => 'shared/signin_signup', :locals => { :to => 'add a new garden' } %div.pagination - = page_entries_info @gardens, :model => "gardens" + = page_entries_info @gardens = will_paginate @gardens .row @@ -27,6 +27,6 @@ %p There are no gardens to display. %div.pagination - = page_entries_info @gardens, :model => "gardens" + = page_entries_info @gardens = will_paginate @gardens diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index a99097d81..f6f5fff7f 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -21,7 +21,7 @@ = render :partial => 'shared/signin_signup', :locals => { :to => 'track your harvests' } %div.pagination - = page_entries_info @harvests, :model => "harvests" + = page_entries_info @harvests = will_paginate @harvests .row - if @harvests.size > 0 @@ -30,7 +30,7 @@ =render :partial => 'harvests/thumbnail', :locals => {:harvest => harvest} %div.pagination - = page_entries_info @harvests, :model => "harvests" + = page_entries_info @harvests = will_paginate @harvests %ul.list-inline diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index 705d69594..43f3b2867 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -7,7 +7,7 @@ = submit_tag "Show", :class => 'btn btn-primary' %div.pagination - = page_entries_info @members, :model => "members" + = page_entries_info @members = will_paginate @members .member-cards @@ -15,5 +15,5 @@ = render :partial => "members/thumbnail", :locals => { :member => m } %div.pagination - = page_entries_info @members, :model => "members" + = page_entries_info @members = will_paginate @members diff --git a/app/views/members/view_followers.html.haml b/app/views/members/view_followers.html.haml index 25a10a860..6600c737c 100644 --- a/app/views/members/view_followers.html.haml +++ b/app/views/members/view_followers.html.haml @@ -1,7 +1,7 @@ - content_for :title, "#{@member.login_name}'s followers" %div.pagination - = page_entries_info @followers, :model => "members" + = page_entries_info @followers = will_paginate @followers .row @@ -12,5 +12,5 @@ = render :partial => "members/thumbnail", :locals => { :member => f } %div.pagination - = page_entries_info @followers, :model => "members" - = will_paginate @followers \ No newline at end of file + = page_entries_info @followers + = will_paginate @followers diff --git a/app/views/members/view_follows.html.haml b/app/views/members/view_follows.html.haml index 93d2695ac..cd0c522de 100644 --- a/app/views/members/view_follows.html.haml +++ b/app/views/members/view_follows.html.haml @@ -1,7 +1,7 @@ - content_for :title, "#{@member.login_name}'s follows" %div.pagination - = page_entries_info @follows, :model => "members" + = page_entries_info @follows = will_paginate @follows .row @@ -12,5 +12,5 @@ = render :partial => "members/thumbnail", :locals => { :member => f } %div.pagination - = page_entries_info @follows, :model => "members" - = will_paginate @follows \ No newline at end of file + = page_entries_info @follows + = will_paginate @follows diff --git a/app/views/photos/index.html.haml b/app/views/photos/index.html.haml index 10a14f88e..f7791cdc0 100644 --- a/app/views/photos/index.html.haml +++ b/app/views/photos/index.html.haml @@ -3,7 +3,7 @@ %p Most recent photos added to #{ENV['GROWSTUFF_SITE_NAME']}. %div.pagination - = page_entries_info @photos, :model => "photos" + = page_entries_info @photos = will_paginate @photos .row @@ -17,7 +17,7 @@ = link_to p.owner, p.owner %div.pagination - = page_entries_info @photos, :model => "photos" + = page_entries_info @photos = will_paginate @photos diff --git a/app/views/photos/new.html.haml b/app/views/photos/new.html.haml index 802281b99..6c8a525b6 100644 --- a/app/views/photos/new.html.haml +++ b/app/views/photos/new.html.haml @@ -20,7 +20,7 @@ = submit_tag "Search", :class => 'btn btn-primary' %div.pagination - = page_entries_info @photos, :model => "photos" + = page_entries_info @photos = will_paginate @photos .row diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index d048a0e89..14c319a5b 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -17,7 +17,7 @@ = render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" } %div.pagination - = page_entries_info @plantings, :model => "plantings" + = page_entries_info @plantings = will_paginate @plantings .row @@ -27,7 +27,7 @@ = render partial: "plantings/thumbnail", locals: {:planting => planting} %div.pagination - = page_entries_info @plantings, :model => "plantings" + = page_entries_info @plantings = will_paginate @plantings %ul.list-inline diff --git a/app/views/posts/index.html.haml b/app/views/posts/index.html.haml index 9eee54694..fa2156dcd 100644 --- a/app/views/posts/index.html.haml +++ b/app/views/posts/index.html.haml @@ -15,7 +15,7 @@ = render :partial => 'shared/signin_signup', :locals => { :to => 'write a post' } %div.pagination - = page_entries_info @posts, :model => "posts" + = page_entries_info @posts = will_paginate @posts - unless @posts.empty? @@ -23,7 +23,7 @@ = render :partial => "single", :locals => { :post => post, :subject => true } %div.pagination - = page_entries_info @posts, :model => "posts" + = page_entries_info @posts = will_paginate @posts %p diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index 9bd5cde84..86329147c 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -21,7 +21,7 @@ = render :partial => 'shared/signin_signup', :locals => { :to => 'add seeds to your stash' } %div.pagination - = page_entries_info @seeds, :model => "seeds" + = page_entries_info @seeds = will_paginate @seeds .row - if @seeds.size > 0 @@ -30,7 +30,7 @@ =render :partial => 'seeds/thumbnail', :locals => {:seed => seed} %div.pagination - = page_entries_info @seeds, :model => "seeds" + = page_entries_info @seeds = will_paginate @seeds %ul.list-inline diff --git a/config/locales/en.yml b/config/locales/en.yml index 8d77afdc8..27e8c5a91 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -151,3 +151,32 @@ en: post: "Post" edit_profile: "Edit profile" + activerecord: + models: + comment: + one: "comment" + other: "comments" + crop: + one: "crop" + other: "crops" + garden: + one: "garden" + other: "gardens" + harvest: + one: "harvest" + other: "harvests" + member: + one: "member" + other: "members" + photo: + one: "photo" + other: "photos" + planting: + one: "planting" + other: "plantings" + post: + one: "post" + other: "posts" + seed: + one: "seed" + other: "seeds" From dd0373a3ee1e04297a588b98c139c1b559a8e85e Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 11:51:46 -0400 Subject: [PATCH 342/392] Use standardized & translateable strings for the photo show page Fixes #876 --- app/views/photos/show.html.haml | 6 +++--- config/locales/en.yml | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml index d09464152..5d941c2ba 100644 --- a/app/views/photos/show.html.haml +++ b/app/views/photos/show.html.haml @@ -24,13 +24,13 @@ %ul - if @photo.plantings.size > 0 - @photo.plantings.each do |p| - %li= link_to p, p + %li= link_to t('.thing_by', thing: Planting.model_name.singular, owner: p.owner), p - if @photo.harvests.size > 0 - @photo.harvests.each do |h| - %li= link_to h, h + %li= link_to t('.thing_by', thing: Harvest.model_name.singular, owner: h.owner), h - if @photo.gardens.size > 0 - @photo.gardens.each do |g| - %li= link_to g, g + %li= link_to t('.thing_by', thing: Garden.model_name.singular, owner: g.owner), g .row diff --git a/config/locales/en.yml b/config/locales/en.yml index 27e8c5a91..480db0e0c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -54,6 +54,10 @@ en: crop_plantings: "Everyone's %{crop} plantings" owner_plantings: "%{owner} plantings" + photos: + show: + thing_by: "A %{thing} by %{owner}" + harvests: index: title: From 58f4ae32d07033db9cd3dbf1e3e224bcd9713401 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 12:28:58 -0400 Subject: [PATCH 343/392] test update --- spec/features/photos/show_photo_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/photos/show_photo_spec.rb b/spec/features/photos/show_photo_spec.rb index 238e69eda..bf72f5fd6 100644 --- a/spec/features/photos/show_photo_spec.rb +++ b/spec/features/photos/show_photo_spec.rb @@ -14,7 +14,7 @@ feature "show photo page" do scenario "shows linkback to planting" do planting.photos << photo visit photo_path(photo) - expect(page).to have_link planting, href: planting_path(planting) + expect(page).to have_link "A planting by #{planting.owner}", href: planting_path(planting) end end @@ -24,7 +24,7 @@ feature "show photo page" do scenario "shows linkback to harvest" do harvest.photos << photo visit photo_path(photo) - expect(page).to have_link harvest, href: harvest_path(harvest) + expect(page).to have_link "A harvest by #{harvest.owner}", href: harvest_path(harvest) end end @@ -34,7 +34,7 @@ feature "show photo page" do scenario "shows linkback to garden" do garden.photos << photo visit photo_path(photo) - expect(page).to have_link garden, href: garden_path(garden) + expect(page).to have_link "A garden by #{garden.owner}", href: garden_path(garden) end end end From 079cecc529cbd253a0ac82efea6683f3638c55be Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 16:53:46 -0400 Subject: [PATCH 344/392] Swap over to having "(Optional)" (or translation) after optional form elements rather than using placeholder text Fixes #848 --- app/views/gardens/_form.html.haml | 15 ++++++--- app/views/harvests/_form.html.haml | 16 +++++++--- app/views/plantings/_form.html.haml | 32 ++++++++++++++----- app/views/seeds/_form.html.haml | 31 +++++++++++------- config/locales/en.yml | 16 ++++++++++ spec/features/gardens/adding_gardens_spec.rb | 8 ++--- .../harvests/harvesting_a_crop_spec.rb | 6 ++-- .../plantings/planting_a_crop_spec.rb | 12 +++---- spec/features/seeds/adding_seeds_spec.rb | 10 +++--- 9 files changed, 99 insertions(+), 47 deletions(-) diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index 74b33249d..a4ec53331 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -16,15 +16,18 @@ .form-group = f.label :description, :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' + = f.text_area :description, :rows => 6, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :location, :class => 'control-label col-md-2' .col-md-8 - = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :placeholder => 'optional', :maxlength => 255 + = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :maxlength => 255 + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' %span.help-block - If you have a location set in your profile, it will be used when - you create a new garden. + = t('.location_helper') - if current_member.location.blank? =link_to "Set your location now.", edit_member_registration_path - else @@ -33,7 +36,9 @@ .form-group = f.label :area, :class => 'control-label col-md-2' .col-md-2 - = f.number_field :area, :class => 'input-small form-control', :placeholder => 'optional' + = f.number_field :area, :class => 'input-small form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .col-md-2 = f.select(:area_unit, Garden::AREA_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index 4dc28c7be..bef3e7dfa 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -19,9 +19,11 @@ = link_to "Request new crops.", new_crop_path .form-group - = f.label :harvested_at, 'When?', :class => 'control-label col-md-2', :placeholder => 'optional' + = f.label :harvested_at, 'When?', :class => 'control-label col-md-2' .col-md-2 = f.text_field :harvested_at, :value => @harvest.harvested_at ? @harvest.harvested_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :quantity, 'How many?', :class => 'control-label col-md-2' @@ -29,20 +31,26 @@ -# Some browsers (eg Firefox for Android) assume "number" means -# "integer" unless you specify step="any": -# http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/ - = f.number_field :quantity, :class => 'input-small form-control', :step => 'any', :placeholder => 'optional' + = f.number_field :quantity, :class => 'input-small form-control', :step => 'any' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .col-md-2 = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium form-control') .form-group = f.label :weight_quantity, 'Weighing (in total):', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :weight_quantity, :class => 'input-small form-control', :step => 'any', :placeholder => 'optional' + = f.number_field :weight_quantity, :class => 'input-small form-control', :step => 'any' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .col-md-2 = f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') .form-group = f.label :description, 'Notes', :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' + = f.text_area :description, :rows => 6, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group .form-actions.col-md-offset-2.col-md-8 diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index 1e347b35e..7b1b4f690 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -23,32 +23,48 @@ = link_to "Add a garden.", new_garden_path .form-group = f.label :planted_at, 'When?', :class => 'control-label col-md-2' - .col-md-2= f.text_field :planted_at, :value => @planting.planted_at ? @planting.planted_at.to_s(:ymd) : '', :class => 'add-datepicker form-control', :placeholder => 'optional' + .col-md-2 + = f.text_field :planted_at, :value => @planting.planted_at ? @planting.planted_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :quantity, 'How many?', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :quantity, :class => 'form-control', :placeholder => 'optional' + = f.number_field :quantity, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :planted_from, 'Planted from:', :class => 'control-label col-md-2' .col-md-8 - = f.select(:planted_from, Planting::PLANTED_FROM_VALUES, {:include_blank => 'optional'}, :class => 'form-control') + = f.select(:planted_from, Planting::PLANTED_FROM_VALUES, {:include_blank => ''}, :class => 'form-control') + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :sunniness, 'Sun or shade?', :class => 'control-label col-md-2' .col-md-8 - = f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => 'optional'}, :class => 'form-control') + = f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => ''}, :class => 'form-control') + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :description, 'Tell us more about it', :class => 'control-label col-md-2' - .col-md-8= f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' + .col-md-8 + = f.text_area :description, :rows => 6, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :finished, 'Mark as finished', :class => 'control-label col-md-2' .col-md-8 = f.check_box :finished - %span.help-block - A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden. + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' + = t('.finish_helper') + .form-group - = f.label :finished_at, 'Finished date', { :class => 'control-label col-md-2', :placeholder => 'optional' } + = f.label :finished_at, 'Finished date', { :class => 'control-label col-md-2' } .col-md-2 = f.text_field :finished_at, :value => @planting.finished_at ? @planting.finished_at.to_s(:ymd) : '', :class => 'add-datepicker form-control', :placeholder => 'optional' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group .form-actions.col-md-offset-2.col-md-8 = f.submit 'Save', :class => 'btn btn-primary' diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index e4682c862..82a169bd9 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -16,24 +16,33 @@ Can't find what you're looking for? = link_to "Request new crops.", new_crop_path .form-group - = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2', :placeholder => 'optional' + = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2' .col-md-2 - = f.number_field :quantity, :class => 'form-control', placeholder: 'optional' + = f.number_field :quantity, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group = f.label :plant_before, 'Plant before:', :class => 'control-label col-md-2' .col-md-2 - = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '', placeholder: 'optional' + = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group - = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2', :placeholder => 'optional' + = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2' %fieldset .col-md-2 - = f.number_field :days_until_maturity_min, :class => 'form-control', placeholder: 'optional' + = f.number_field :days_until_maturity_min, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .col-md-1 = f.label :days_until_maturity_max, 'to', :class => 'control-label' .col-md-2 - = f.number_field :days_until_maturity_max, :class => 'form-control', placeholder: 'optional' + = f.number_field :days_until_maturity_max, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .col-md-1 = f.label :dummy, 'days', :class => 'control-label' + .form-group.required = f.label :organic, 'Organic?', :class => 'control-label col-md-2' .col-md-8 @@ -49,15 +58,13 @@ .form-group = f.label :description, 'Description:', :class => 'control-label col-md-2' .col-md-8 - = f.text_area :description, :rows => 6, :class => 'form-control', :placeholder => 'optional' + = f.text_area :description, :rows => 6, :class => 'form-control' + %span.help-block.optional + = I18n.t 'optional', :scope => 'forms' .form-group .col-md-offset-2.col-md-8 %span.help-block - Are you interested in trading or swapping seeds with other - #{ENV['GROWSTUFF_SITE_NAME']} members? If you - list your seeds as available for trade, other members can - contact you to request seeds. You can list any conditions or - other information in the description, above. + = t('.trade_help', :site_name => ENV['GROWSTUFF_SITE_NAME']) .form-group.required = f.label :tradable_to, 'Will trade:', :class => 'control-label col-md-2' .col-md-8 diff --git a/config/locales/en.yml b/config/locales/en.yml index 480db0e0c..aa3d52424 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2,6 +2,8 @@ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. en: + forms: + optional: "(Optional)" unauthorized: read: notification: "You must be signed in to view notifications." @@ -40,12 +42,23 @@ en: title: *browse_crops subtitle: "%{crops_size} total" + gardens: + form: + location_helper: "If you have a location set in your profile, it will be used when + you create a new garden." + seeds: index: title: default: "Everyone's seeds" crop_seeds: "Everyone's %{crop} seeds" owner_seeds: "%{owner} seeds" + form: + trade_help: "Are you interested in trading or swapping seeds with other + %{site_name} members? If you + list your seeds as available for trade, other members can + contact you to request seeds. You can list any conditions or + other information in the description, above." plantings: index: @@ -53,6 +66,9 @@ en: default: "Everyone's plantings" crop_plantings: "Everyone's %{crop} plantings" owner_plantings: "%{owner} plantings" + form: + finish_helper: "A planting is finished when you've harvested all of the crop, or + it dies, or it's otherwise no longer growing in your garden." photos: show: diff --git a/spec/features/gardens/adding_gardens_spec.rb b/spec/features/gardens/adding_gardens_spec.rb index 2f2822c05..14e7db3cd 100644 --- a/spec/features/gardens/adding_gardens_spec.rb +++ b/spec/features/gardens/adding_gardens_spec.rb @@ -14,9 +14,9 @@ feature "Gardens", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "Name" - expect(page).to have_selector 'textarea#garden_description[placeholder="optional"]' - expect(page).to have_selector 'input#garden_location[placeholder="optional"]' - expect(page).to have_selector 'input#garden_area[placeholder="optional"]' + expect(page).to have_selector 'textarea#garden_description + .optional' + expect(page).to have_selector 'input#garden_location + .optional' + expect(page).to have_selector 'input#garden_area + .optional' end scenario "Create new garden" do @@ -34,4 +34,4 @@ feature "Gardens", :js do expect(page).not_to have_content "Garden was successfully created" expect(page).to have_content "Area must be greater than or equal to 0" end -end \ No newline at end of file +end diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 100bcc98f..c367fd5ea 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -19,9 +19,9 @@ feature "Harvesting a crop", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "What did you harvest?" - expect(page).to have_selector 'input#harvest_quantity[placeholder="optional"]' - expect(page).to have_selector 'input#harvest_weight_quantity[placeholder="optional"]' - expect(page).to have_selector 'textarea#harvest_description[placeholder="optional"]' + expect(page).to have_selector 'input#harvest_quantity + .optional' + expect(page).to have_selector 'input#harvest_weight_quantity + .optional' + expect(page).to have_selector 'textarea#harvest_description + .optional' end scenario "Creating a new harvest", :js do diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index fc255d313..3bf0813bd 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -21,12 +21,12 @@ feature "Planting a crop", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "What did you plant?" expect(page).to have_selector ".form-group.required", text: "Where did you plant it?" - expect(page).to have_selector 'input#planting_planted_at[placeholder="optional"]' - expect(page).to have_selector 'input#planting_quantity[placeholder="optional"]' - expect(page).to have_selector 'select#planting_planted_from option', text: 'optional' - expect(page).to have_selector 'select#planting_sunniness option', text: 'optional' - expect(page).to have_selector 'textarea#planting_description[placeholder="optional"]' - expect(page).to have_selector 'input#planting_finished_at[placeholder="optional"]' + expect(page).to have_selector 'input#planting_planted_at + .optional' + expect(page).to have_selector 'input#planting_quantity + .optional' + expect(page).to have_selector 'select#planting_planted_from + .optional' + expect(page).to have_selector 'select#planting_sunniness + .optional' + expect(page).to have_selector 'textarea#planting_description + .optional' + expect(page).to have_selector 'input#planting_finished_at + .optional' end scenario "Creating a new planting" do diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index f3c463b17..95387ade3 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -18,14 +18,14 @@ feature "Seeds", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "Crop:" - expect(page).to have_selector 'input#seed_quantity[placeholder="optional"]' - expect(page).to have_selector 'input#seed_plant_before[placeholder="optional"]' - expect(page).to have_selector 'input#seed_days_until_maturity_min[placeholder="optional"]' - expect(page).to have_selector 'input#seed_days_until_maturity_max[placeholder="optional"]' + expect(page).to have_selector 'input#seed_quantity + .optional' + expect(page).to have_selector 'input#seed_plant_before + .optional' + expect(page).to have_selector 'input#seed_days_until_maturity_min + .optional' + expect(page).to have_selector 'input#seed_days_until_maturity_max + .optional' expect(page).to have_selector '.form-group.required', text: 'Organic?' expect(page).to have_selector '.form-group.required', text: 'GMO?' expect(page).to have_selector '.form-group.required', text: 'Heirloom?' - expect(page).to have_selector 'textarea#seed_description[placeholder="optional"]' + expect(page).to have_selector 'textarea#seed_description + .optional' expect(page).to have_selector '.form-group.required', text: 'Will trade:' end From 8d982c7e3ea406f594dce2ba681803446da38844 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 22:39:58 -0400 Subject: [PATCH 345/392] Add capybara-screenshot to assist with feature testing --- Gemfile | 1 + Gemfile.lock | 4 ++++ spec/rails_helper.rb | 2 ++ 3 files changed, 7 insertions(+) diff --git a/Gemfile b/Gemfile index ea95528ef..d5182a1d1 100644 --- a/Gemfile +++ b/Gemfile @@ -112,6 +112,7 @@ group :development, :test do gem 'coveralls', require: false # coverage analysis gem 'capybara' # integration tests gem 'capybara-email' # integration tests for email + gem 'capybara-screenshot' # for test debugging gem 'poltergeist', '~> 1.6' # for headless JS testing gem 'i18n-tasks' # adds tests for finding missing and unused translations gem 'selenium-webdriver' diff --git a/Gemfile.lock b/Gemfile.lock index 46e9c20df..7d175309f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -84,6 +84,9 @@ GEM capybara-email (2.5.0) capybara (~> 2.4) mail + capybara-screenshot (1.0.13) + capybara (>= 1.0, < 3) + launchy childprocess (0.5.9) ffi (~> 1.0, >= 1.0.11) climate_control (0.0.3) @@ -446,6 +449,7 @@ DEPENDENCIES cancancan (~> 1.9) capybara capybara-email + capybara-screenshot codeclimate-test-reporter coffee-rails (~> 4.1.0) comfortable_mexican_sofa (~> 1.12.0) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index a30142f36..e399103ea 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -23,6 +23,8 @@ end require 'capybara' require 'capybara/poltergeist' +require 'capybara/rspec' +require 'capybara-screenshot/rspec' Capybara.javascript_driver = :poltergeist if ENV['GROWSTUFF_CAPYBARA_DRIVER'].present? From 2089866756f8c42c8c582f33ceccbeb0585df141 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 22:37:47 -0400 Subject: [PATCH 346/392] Display one line of description in harvest card, then go to ellipsis and put read more on next line Fixes #854 --- app/assets/stylesheets/overrides.sass | 5 +++ app/helpers/harvests_helper.rb | 2 +- app/views/harvests/_thumbnail.html.haml | 4 ++- spec/factories/harvests.rb | 8 +++++ spec/features/gardens_spec.rb | 1 + .../features/harvests/browse_harvests_spec.rb | 35 +++++++++++++++++++ 6 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 spec/features/harvests/browse_harvests_spec.rb diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index d649ecb85..76a074718 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -316,3 +316,8 @@ $state-success-bg: lighten($green, 50%) .red color: red + +.truncate + overflow: hidden + text-overflow: ellipsis + white-space: nowrap diff --git a/app/helpers/harvests_helper.rb b/app/helpers/harvests_helper.rb index 3055db065..b5f695a9d 100644 --- a/app/helpers/harvests_helper.rb +++ b/app/helpers/harvests_helper.rb @@ -41,7 +41,7 @@ module HarvestsHelper if harvest.description.empty? "No description provided." else - truncate(harvest.description, length: 130, separator: ' ', omission: '... ') { link_to "Read more", harvest_path(harvest) } + harvest.description end end diff --git a/app/views/harvests/_thumbnail.html.haml b/app/views/harvests/_thumbnail.html.haml index fbf482079..d21614947 100644 --- a/app/views/harvests/_thumbnail.html.haml +++ b/app/views/harvests/_thumbnail.html.haml @@ -21,5 +21,7 @@ %dd= harvest.harvested_at .panel-footer %dt Description - %dd + %dd.truncate = display_harvest_description(harvest) + = if not harvest.description.empty? + - link_to "Read more", harvest_path(harvest) diff --git a/spec/factories/harvests.rb b/spec/factories/harvests.rb index 71356388a..20a3affcd 100644 --- a/spec/factories/harvests.rb +++ b/spec/factories/harvests.rb @@ -12,4 +12,12 @@ FactoryGirl.define do weight_unit "kg" description "A lovely harvest" end + + trait :long_description do + description "This is a very long description that is so very long that it will need to be cut off" + end + + trait :no_description do + description "" + end end diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 90f2f9ed7..26b6ccdc8 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -12,6 +12,7 @@ feature "Planting a crop", js: true do scenario "View gardens" do visit gardens_path + puts page.body expect(page).to have_content "Everyone's gardens" click_link "View your gardens" expect(page).to have_content "#{garden.owner.login_name}'s gardens" diff --git a/spec/features/harvests/browse_harvests_spec.rb b/spec/features/harvests/browse_harvests_spec.rb new file mode 100644 index 000000000..0b4d07f6a --- /dev/null +++ b/spec/features/harvests/browse_harvests_spec.rb @@ -0,0 +1,35 @@ +require 'rails_helper' + +feature "browse harvests" do + let!(:member) { create :member } + + background do + login_as member + end + + feature 'blank optional fields' do + let!(:harvest) { create :harvest, :no_description } + + before (:each) do + visit harvests_path + end + + scenario 'read more' do + expect(page).not_to have_link "Read more" + end + + end + + feature "filled in optional fields" do + let!(:harvest) { create :harvest, :long_description } + + before (:each) do + visit harvests_path + end + + scenario 'read more' do + expect(page).to have_link "Read more" + end + + end +end From 03c74dae03a5e4199a435d289046bad8b94eacb2 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Thu, 26 May 2016 23:55:49 -0400 Subject: [PATCH 347/392] Capture originalText from the button that's been clicked, not from the array of all possible date-picker buttons. Fixes #906 --- app/assets/javascripts/append_date.js.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/assets/javascripts/append_date.js.coffee b/app/assets/javascripts/append_date.js.coffee index 8fc31de9d..c1be9ce47 100644 --- a/app/assets/javascripts/append_date.js.coffee +++ b/app/assets/javascripts/append_date.js.coffee @@ -10,12 +10,11 @@ jQuery -> href = el.attr('href') - originalText = el.text() - el.click (e) -> e.stopPropagation() e.preventDefault() + originalText = $(this).text() $(this).text('Confirm without date') $(this).bind('click.confirm', (e) -> From 75631da3988ed8e459f8c5246aa84a482b018b9c Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Fri, 27 May 2016 00:21:02 -0400 Subject: [PATCH 348/392] Set filename of screenshot to test name --- spec/rails_helper.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e399103ea..938d2a2a0 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -34,6 +34,11 @@ if ENV['GROWSTUFF_CAPYBARA_DRIVER'].present? end Capybara.javascript_driver = ENV['GROWSTUFF_CAPYBARA_DRIVER'].to_sym end + +Capybara::Screenshot.register_filename_prefix_formatter(:rspec) do |example| + "screenshot_#{example.description.gsub(' ', '-').gsub(/^.*\/spec\//,'')}" +end + Capybara.app_host = 'http://localhost' Capybara.server_port = 8081 From 23d21be73f01719c413e112af1695841bb341bd5 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 27 May 2016 14:04:30 +0100 Subject: [PATCH 349/392] Delete debugging `puts` statement from spec Fixes the "rspec output includes an HTML page dump" issue noted at https://github.com/Growstuff/growstuff/commit/2089866756f8c42c8c582f33ceccbeb0585df141#diff-6464240396bc745d7e89a408c200fd3aR15 --- spec/features/gardens_spec.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 26b6ccdc8..90f2f9ed7 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -12,7 +12,6 @@ feature "Planting a crop", js: true do scenario "View gardens" do visit gardens_path - puts page.body expect(page).to have_content "Everyone's gardens" click_link "View your gardens" expect(page).to have_content "#{garden.owner.login_name}'s gardens" From 10095701028b9560fb66b741a5718b447501da01 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 27 May 2016 14:46:55 +0100 Subject: [PATCH 350/392] Check href attribute of links in planting reminder To check the target of a link, you need to pass it to `has_link` as an `href` keyword argument. We were passing it as a positional argument, which meant that - it was ignored, weakening the tests - the output of rspec filled up with annoying warnings. Fixes #928. --- spec/features/crops/crop_detail_page_spec.rb | 2 +- spec/features/planting_reminder_spec.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index 865925bce..d48d60f41 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -133,7 +133,7 @@ feature "crop detail page", js: true do scenario "has a link to Wikipedia with SEO" do expect(page).to have_content "Learn more about #{ crop.name }" - expect(page).to have_link "Wikipedia (English)", crop.en_wikipedia_url + expect(page).to have_link "Wikipedia (English)", href: crop.en_wikipedia_url end end diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index 2891b690e..4cba3cb51 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -33,8 +33,8 @@ feature "Planting reminder email", :js do scenario "lists plantings" do expect(mail).to have_content "most recent plantings you've told us about" - expect(mail).to have_link p1.to_s, planting_url(p1) - expect(mail).to have_link p2.to_s, planting_url(p2) + expect(mail).to have_link p1.to_s, href: planting_url(p1) + expect(mail).to have_link p2.to_s, href: planting_url(p2) expect(mail).to have_content "keep your garden records up to date" end end @@ -57,8 +57,8 @@ feature "Planting reminder email", :js do scenario "lists harvests" do expect(mail).to have_content "the last few things you harvested were" - expect(mail).to have_link h1.to_s, harvest_url(h1) - expect(mail).to have_link h2.to_s, harvest_url(h2) + expect(mail).to have_link h1.to_s, href: harvest_url(h1) + expect(mail).to have_link h2.to_s, href: harvest_url(h2) expect(mail).to have_content "Harvested anything else lately?" end end From 13dc87f36880641b42dd10d71700af1a6d08c379 Mon Sep 17 00:00:00 2001 From: Mackenzie Morgan Date: Fri, 27 May 2016 11:26:36 -0400 Subject: [PATCH 351/392] Optional field improvements * Added custom matcher `have_optional(field id name goes here)` * Fix partial * Add tests --- app/views/gardens/_form.html.haml | 9 +++----- app/views/harvests/_form.html.haml | 12 ++++------ app/views/plantings/_form.html.haml | 22 +++++++------------ app/views/seeds/_form.html.haml | 15 +++++-------- app/views/shared/_form_optional.html.haml | 2 ++ spec/custom_matchers.rb | 7 ++++++ spec/features/gardens/adding_gardens_spec.rb | 7 +++--- .../harvests/harvesting_a_crop_spec.rb | 7 +++--- .../plantings/planting_a_crop_spec.rb | 13 ++++++----- spec/features/seeds/adding_seeds_spec.rb | 11 +++++----- 10 files changed, 50 insertions(+), 55 deletions(-) create mode 100644 app/views/shared/_form_optional.html.haml create mode 100644 spec/custom_matchers.rb diff --git a/app/views/gardens/_form.html.haml b/app/views/gardens/_form.html.haml index a4ec53331..571af8aba 100644 --- a/app/views/gardens/_form.html.haml +++ b/app/views/gardens/_form.html.haml @@ -17,15 +17,13 @@ = f.label :description, :class => 'control-label col-md-2' .col-md-8 = f.text_area :description, :rows => 6, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :location, :class => 'control-label col-md-2' .col-md-8 = f.text_field :location, :value => @garden.location || current_member.location, :class => 'form-control', :maxlength => 255 - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' %span.help-block = t('.location_helper') - if current_member.location.blank? @@ -37,8 +35,7 @@ = f.label :area, :class => 'control-label col-md-2' .col-md-2 = f.number_field :area, :class => 'input-small form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .col-md-2 = f.select(:area_unit, Garden::AREA_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') diff --git a/app/views/harvests/_form.html.haml b/app/views/harvests/_form.html.haml index bef3e7dfa..c116f757c 100644 --- a/app/views/harvests/_form.html.haml +++ b/app/views/harvests/_form.html.haml @@ -22,8 +22,7 @@ = f.label :harvested_at, 'When?', :class => 'control-label col-md-2' .col-md-2 = f.text_field :harvested_at, :value => @harvest.harvested_at ? @harvest.harvested_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :quantity, 'How many?', :class => 'control-label col-md-2' @@ -32,8 +31,7 @@ -# "integer" unless you specify step="any": -# http://blog.isotoma.com/2012/03/html5-input-typenumber-and-decimalsfloats-in-chrome/ = f.number_field :quantity, :class => 'input-small form-control', :step => 'any' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .col-md-2 = f.select(:unit, Harvest::UNITS_VALUES, {:include_blank => false}, :class => 'input-medium form-control') @@ -41,16 +39,14 @@ = f.label :weight_quantity, 'Weighing (in total):', :class => 'control-label col-md-2' .col-md-2 = f.number_field :weight_quantity, :class => 'input-small form-control', :step => 'any' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .col-md-2 = f.select(:weight_unit, Harvest::WEIGHT_UNITS_VALUES, {:include_blank => false}, :class => 'form-control') .form-group = f.label :description, 'Notes', :class => 'control-label col-md-2' .col-md-8 = f.text_area :description, :rows => 6, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group .form-actions.col-md-offset-2.col-md-8 diff --git a/app/views/plantings/_form.html.haml b/app/views/plantings/_form.html.haml index 7b1b4f690..bdbae6aa2 100644 --- a/app/views/plantings/_form.html.haml +++ b/app/views/plantings/_form.html.haml @@ -25,46 +25,40 @@ = f.label :planted_at, 'When?', :class => 'control-label col-md-2' .col-md-2 = f.text_field :planted_at, :value => @planting.planted_at ? @planting.planted_at.to_s(:ymd) : '', :class => 'add-datepicker form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :quantity, 'How many?', :class => 'control-label col-md-2' .col-md-2 = f.number_field :quantity, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :planted_from, 'Planted from:', :class => 'control-label col-md-2' .col-md-8 = f.select(:planted_from, Planting::PLANTED_FROM_VALUES, {:include_blank => ''}, :class => 'form-control') - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :sunniness, 'Sun or shade?', :class => 'control-label col-md-2' .col-md-8 = f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => ''}, :class => 'form-control') - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :description, 'Tell us more about it', :class => 'control-label col-md-2' .col-md-8 = f.text_area :description, :rows => 6, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :finished, 'Mark as finished', :class => 'control-label col-md-2' .col-md-8 = f.check_box :finished - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' + %span.help-block = t('.finish_helper') .form-group = f.label :finished_at, 'Finished date', { :class => 'control-label col-md-2' } .col-md-2 = f.text_field :finished_at, :value => @planting.finished_at ? @planting.finished_at.to_s(:ymd) : '', :class => 'add-datepicker form-control', :placeholder => 'optional' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group .form-actions.col-md-offset-2.col-md-8 = f.submit 'Save', :class => 'btn btn-primary' diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index 82a169bd9..77b4a6998 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -19,27 +19,23 @@ = f.label :quantity, 'Quantity:', :class => 'control-label col-md-2' .col-md-2 = f.number_field :quantity, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :plant_before, 'Plant before:', :class => 'control-label col-md-2' .col-md-2 = f.text_field :plant_before, :class => 'add-datepicker form-control', :value => @seed.plant_before ? @seed.plant_before.to_s(:ymd) : '' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group = f.label :days_until_maturity_min, 'Days until maturity:', :class => 'control-label col-md-2' %fieldset .col-md-2 = f.number_field :days_until_maturity_min, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .col-md-1 = f.label :days_until_maturity_max, 'to', :class => 'control-label' .col-md-2 = f.number_field :days_until_maturity_max, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .col-md-1 = f.label :dummy, 'days', :class => 'control-label' @@ -59,8 +55,7 @@ = f.label :description, 'Description:', :class => 'control-label col-md-2' .col-md-8 = f.text_area :description, :rows => 6, :class => 'form-control' - %span.help-block.optional - = I18n.t 'optional', :scope => 'forms' + = render :partial => 'shared/form_optional' .form-group .col-md-offset-2.col-md-8 %span.help-block diff --git a/app/views/shared/_form_optional.html.haml b/app/views/shared/_form_optional.html.haml new file mode 100644 index 000000000..28fe3598b --- /dev/null +++ b/app/views/shared/_form_optional.html.haml @@ -0,0 +1,2 @@ +%span.help-block.optional + = I18n.t 'optional', :scope => 'forms' diff --git a/spec/custom_matchers.rb b/spec/custom_matchers.rb new file mode 100644 index 000000000..6d52388bb --- /dev/null +++ b/spec/custom_matchers.rb @@ -0,0 +1,7 @@ +require 'rspec/expectations' + +RSpec::Matchers.define :have_optional do | expected | + match do |actual| + actual.has_selector? "#{expected} + span", text: '(Optional)' + end +end diff --git a/spec/features/gardens/adding_gardens_spec.rb b/spec/features/gardens/adding_gardens_spec.rb index 14e7db3cd..da2bd0481 100644 --- a/spec/features/gardens/adding_gardens_spec.rb +++ b/spec/features/gardens/adding_gardens_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'custom_matchers' feature "Gardens", :js do let(:member) { FactoryGirl.create :member } @@ -14,9 +15,9 @@ feature "Gardens", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "Name" - expect(page).to have_selector 'textarea#garden_description + .optional' - expect(page).to have_selector 'input#garden_location + .optional' - expect(page).to have_selector 'input#garden_area + .optional' + expect(page).to have_optional 'textarea#garden_description' + expect(page).to have_optional 'input#garden_location' + expect(page).to have_optional 'input#garden_area' end scenario "Create new garden" do diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index c367fd5ea..888e74bfb 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'custom_matchers' feature "Harvesting a crop", :js do let(:member) { create :member } @@ -19,9 +20,9 @@ feature "Harvesting a crop", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "What did you harvest?" - expect(page).to have_selector 'input#harvest_quantity + .optional' - expect(page).to have_selector 'input#harvest_weight_quantity + .optional' - expect(page).to have_selector 'textarea#harvest_description + .optional' + expect(page).to have_optional 'input#harvest_quantity' + expect(page).to have_optional 'input#harvest_weight_quantity' + expect(page).to have_optional 'textarea#harvest_description' end scenario "Creating a new harvest", :js do diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 3bf0813bd..5ecabef33 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -1,4 +1,5 @@ require "rails_helper" +require 'custom_matchers' feature "Planting a crop", :js do let(:member) { create :member } @@ -21,12 +22,12 @@ feature "Planting a crop", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "What did you plant?" expect(page).to have_selector ".form-group.required", text: "Where did you plant it?" - expect(page).to have_selector 'input#planting_planted_at + .optional' - expect(page).to have_selector 'input#planting_quantity + .optional' - expect(page).to have_selector 'select#planting_planted_from + .optional' - expect(page).to have_selector 'select#planting_sunniness + .optional' - expect(page).to have_selector 'textarea#planting_description + .optional' - expect(page).to have_selector 'input#planting_finished_at + .optional' + expect(page).to have_optional 'input#planting_planted_at' + expect(page).to have_optional 'input#planting_quantity' + expect(page).to have_optional 'select#planting_planted_from' + expect(page).to have_optional 'select#planting_sunniness' + expect(page).to have_optional 'textarea#planting_description' + expect(page).to have_optional 'input#planting_finished_at' end scenario "Creating a new planting" do diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index 95387ade3..e52a96136 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -1,4 +1,5 @@ require 'rails_helper' +require 'custom_matchers' feature "Seeds", :js do let(:member) { create :member } @@ -18,14 +19,14 @@ feature "Seeds", :js do it "displays required and optional fields properly" do expect(page).to have_selector ".form-group.required", text: "Crop:" - expect(page).to have_selector 'input#seed_quantity + .optional' - expect(page).to have_selector 'input#seed_plant_before + .optional' - expect(page).to have_selector 'input#seed_days_until_maturity_min + .optional' - expect(page).to have_selector 'input#seed_days_until_maturity_max + .optional' + expect(page).to have_optional 'input#seed_quantity' + expect(page).to have_optional 'input#seed_plant_before' + expect(page).to have_optional 'input#seed_days_until_maturity_min' + expect(page).to have_optional 'input#seed_days_until_maturity_max' expect(page).to have_selector '.form-group.required', text: 'Organic?' expect(page).to have_selector '.form-group.required', text: 'GMO?' expect(page).to have_selector '.form-group.required', text: 'Heirloom?' - expect(page).to have_selector 'textarea#seed_description + .optional' + expect(page).to have_optional 'textarea#seed_description' expect(page).to have_selector '.form-group.required', text: 'Will trade:' end From fa77f11177e80505a8b656675ef7e0fd9152e0ae Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 28 May 2016 09:21:04 +0930 Subject: [PATCH 352/392] Based on MIT licenced icon-globe (http://fontawesome.io/3.2.1/icon/globe/) --- app/assets/images/location-not-set.en.png | Bin 0 -> 22759 bytes app/assets/stylesheets/overrides.sass | 7 +++++++ app/views/members/_map.html.haml | 2 ++ 3 files changed, 9 insertions(+) create mode 100644 app/assets/images/location-not-set.en.png diff --git a/app/assets/images/location-not-set.en.png b/app/assets/images/location-not-set.en.png new file mode 100644 index 0000000000000000000000000000000000000000..6e1cde69cfa7b05d2e2730a2002539ec895c5ed7 GIT binary patch literal 22759 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 literal 0 HcmV?d00001 diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 76a074718..7bcadefd5 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -121,6 +121,13 @@ p.stats #membermap height: 250px +.location-not-set + height: 250px + width: 100% + background-image: image-url('location-not-set.en.png') + background-repeat: no-repeat + background-position: center + .member-location font-size: small font-style: italic diff --git a/app/views/members/_map.html.haml b/app/views/members/_map.html.haml index 027f83c65..43e89fa4f 100644 --- a/app/views/members/_map.html.haml +++ b/app/views/members/_map.html.haml @@ -3,3 +3,5 @@ %p See other members, plantings, seeds and more near = link_to member.location, place_path(member.location, anchor: "members") +- else + %div.location-not-set \ No newline at end of file From 3d04e7c12570d9ca374747dbd08573c0086a3f50 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Sat, 28 May 2016 09:30:54 +0930 Subject: [PATCH 353/392] Add list-inline to ensure the sidebar never conflicts with other content --- app/views/members/_stats.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/members/_stats.html.haml b/app/views/members/_stats.html.haml index 4b9cce87d..26635e2f1 100644 --- a/app/views/members/_stats.html.haml +++ b/app/views/members/_stats.html.haml @@ -1,6 +1,6 @@ %h3 Activity -%ul +%ul.list-inline %li - if member.plantings.size > 0 = link_to pluralize(member.plantings.size, "planting"), plantings_by_owner_path(:owner => member) From 3ac42deae569a713ceda76fab701073cd52e0cdf Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Sun, 29 May 2016 16:13:21 -0400 Subject: [PATCH 354/392] crop approval flash alert for wranglers upon sign in --- app/controllers/sessions_controller.rb | 9 +++++++++ config/routes.rb | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 app/controllers/sessions_controller.rb diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 000000000..99676c86f --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,9 @@ +class SessionsController < Devise::SessionsController + def create + super do |resource| + if Crop.pending_approval.present? && current_member.has_role?(:crop_wrangler) + flash[:alert] = "There are crops waiting to be wrangled." + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 45ef094e1..b8fee2796 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,12 +4,12 @@ Growstuff::Application.routes.draw do resources :plant_parts - devise_for :members, controllers: { registrations: "registrations", passwords: "passwords" } - devise_scope :member do + devise_for :members, controllers: { registrations: "registrations", passwords: "passwords", sessions: "sessions" } + devise_scope :member do get '/members/unsubscribe/:message' => 'members#unsubscribe', :as => 'unsubscribe_member' end - resources :members + resources :members resources :photos From f33367ebac5e43f428cdfdf0ac75223e8f624bc3 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Sun, 29 May 2016 18:19:15 -0500 Subject: [PATCH 355/392] align devise shared links properly on "Forgot your password" page --- app/views/devise/passwords/new.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/devise/passwords/new.html.haml b/app/views/devise/passwords/new.html.haml index b32607760..2044264c8 100644 --- a/app/views/devise/passwords/new.html.haml +++ b/app/views/devise/passwords/new.html.haml @@ -11,4 +11,6 @@ .form-actions.col-md-offset-2.col-md-8 = f.submit "Send me reset password instructions", :class => 'btn btn-primary' -= render "devise/shared/links" + .form-group + .col-md-offset-2.col-md-8 + = render "devise/shared/links" From 1344f776e404f01265a38205bd4674c1095e7380 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Sun, 29 May 2016 18:23:57 -0500 Subject: [PATCH 356/392] align devise shared links properly on "Resend confirmation instructions" page --- app/views/devise/confirmations/new.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/devise/confirmations/new.html.haml b/app/views/devise/confirmations/new.html.haml index c7ebdd604..03a021478 100644 --- a/app/views/devise/confirmations/new.html.haml +++ b/app/views/devise/confirmations/new.html.haml @@ -13,4 +13,6 @@ .form-actions.col-md-offset-2.col-md-8 = f.submit "Resend confirmation instructions", :class => 'btn btn-primary' -= render "devise/shared/links" + .form-group + .col-md-offset-2.col-md-8 + = render "devise/shared/links" From 51229031397819427aaa584389290cca19566a78 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Sun, 29 May 2016 18:25:01 -0500 Subject: [PATCH 357/392] align links on "Resend unlock instructions" page --- app/views/devise/unlocks/new.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/devise/unlocks/new.html.haml b/app/views/devise/unlocks/new.html.haml index 77d726806..1e612e9bf 100644 --- a/app/views/devise/unlocks/new.html.haml +++ b/app/views/devise/unlocks/new.html.haml @@ -11,4 +11,6 @@ .form-actions.col-md-offset-2.col-md-8 = f.submit "Resend unlock instructions", :class => 'btn btn-primary' -= render "devise/shared/links" + .form-group + .col-md-offset-2.col-md-8 + = render "devise/shared/links" From 8f05e254a2d582254970704b3cf4bc93b63cfe05 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Mon, 30 May 2016 10:06:51 +0930 Subject: [PATCH 358/392] Remove crowdfunding code --- app/assets/stylesheets/overrides.sass | 14 -------------- app/views/layouts/_crowdfunding.html.haml | 7 ------- app/views/layouts/application.html.haml | 1 - 3 files changed, 22 deletions(-) delete mode 100644 app/views/layouts/_crowdfunding.html.haml diff --git a/app/assets/stylesheets/overrides.sass b/app/assets/stylesheets/overrides.sass index 76a074718..69753ec87 100644 --- a/app/assets/stylesheets/overrides.sass +++ b/app/assets/stylesheets/overrides.sass @@ -248,20 +248,6 @@ html, body background: white z-index: $zindex-tooltip -// Crowdfunding campaign, Sep-Oct 2014 - -.crowdfunding-banner - text-align: center - font-weight: bold - background-color: lighten($green, 30%) - margin-top: 0px - margin-bottom: 5px - padding: 15px - -.crowdfunding-banner a - color: $brown - text-decoration: underline - .alert a font-weight: 800 diff --git a/app/views/layouts/_crowdfunding.html.haml b/app/views/layouts/_crowdfunding.html.haml deleted file mode 100644 index 63a27b4a8..000000000 --- a/app/views/layouts/_crowdfunding.html.haml +++ /dev/null @@ -1,7 +0,0 @@ -- daysleft = Date.new(2014, 10, 22) - Date.today # end of campaign is the 21st, this gives a number that matches what IGG uses -- if daysleft > 0 - .crowdfunding-banner - Help us share free growing information with the world. - = link_to "Support our crowdfunding campaign.", "https://www.indiegogo.com/projects/growstuff/x/6079859" - There are only #{daysleft.to_i} days left. - diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index f708434f1..a17bde125 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -3,7 +3,6 @@ = render :partial => "layouts/meta" %body = render :partial => "layouts/header" - = render :partial => "layouts/crowdfunding" #maincontainer.container .row From 2ac901c891365ead8ed3be3d911adeeb57b15111 Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Mon, 30 May 2016 09:06:09 -0400 Subject: [PATCH 359/392] feature test for issue 910 --- spec/features/signin_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index 693a8ec6b..c091e572c 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -4,6 +4,7 @@ require 'rails_helper' feature "signin", js: true do let(:member) { create :member } let(:recipient) { create :member } + let(:wrangler) { create :crop_wrangling_member } let(:notification) { create :notification } scenario "redirect to previous page after signin" do @@ -50,4 +51,14 @@ feature "signin", js: true do click_button 'Sign in' expect(current_path).to eq new_notification_path end + + scenario "after crop wrangler signs in and crops await wrangling, show alert" do + create :crop_request + visit crops_path # some random page + click_link 'Sign in' + fill_in 'Login', with: wrangler.login_name + fill_in 'Password', with: wrangler.password + click_button 'Sign in' + expect(page).to have_content("There are crops waiting to be wrangled.") + end end From 5111c2a96bac0b2b4ffa44984ae00e586e05b40c Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Tue, 31 May 2016 09:43:53 +0930 Subject: [PATCH 360/392] Add sr-only text --- app/views/members/_map.html.haml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/members/_map.html.haml b/app/views/members/_map.html.haml index 43e89fa4f..cbf32ea6e 100644 --- a/app/views/members/_map.html.haml +++ b/app/views/members/_map.html.haml @@ -4,4 +4,6 @@ See other members, plantings, seeds and more near = link_to member.location, place_path(member.location, anchor: "members") - else - %div.location-not-set \ No newline at end of file + %div.location-not-set + %div.sr-only Location not known + %div.sr-only We can't show you what's nearby \ No newline at end of file From 31f0052b9d569dab7145f10b2b509ba7cdab960a Mon Sep 17 00:00:00 2001 From: Eric Tillberg Date: Tue, 31 May 2016 06:49:17 -0400 Subject: [PATCH 361/392] added to contributors list --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index deab23739..2e5be03f3 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -66,3 +66,4 @@ submit the change with your pull request. - Anthony Atkinson / [sha1sum](https://github.com/sha1sum) - Terence Conquest / [twconquest](https://github.com/twconquest) - Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX) +- Eric Tillberg / [Thrillberg](https://github.com/Thrillberg) From e2053e2f8becd90b3222e83e714f68bdca57610a Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Tue, 31 May 2016 07:33:40 -0500 Subject: [PATCH 362/392] adding me to CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index deab23739..8d261111d 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -66,3 +66,4 @@ submit the change with your pull request. - Anthony Atkinson / [sha1sum](https://github.com/sha1sum) - Terence Conquest / [twconquest](https://github.com/twconquest) - Daniel O'Connor / [CloCkWeRX](https://github.com/CloCkWeRX) +- DV Dasari / [dv2](https://github.com/dv2) From 6dd7ec9f9526b1f503d400db3acf4947428c2d80 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Wed, 1 Jun 2016 14:54:13 +0100 Subject: [PATCH 363/392] Fix coverage calculations SimpleCov was reporting 0% coverage for any files loaded before `SimpleCov.start` was called, even if they were fully tested. This patch loads the application *after* starting SimpleCov, leading to more accurate coverage figures. --- spec/rails_helper.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 938d2a2a0..aa8d32946 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,9 +1,5 @@ # This file is copied to spec/ when you run 'rails generate rspec:install' ENV["RAILS_ENV"] ||= 'test' -require 'spec_helper' -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' -# Add additional requires below this line. Rails is not loaded until this point! require 'simplecov' require 'coveralls' @@ -21,6 +17,12 @@ SimpleCov.start :rails do add_filter 'vendor/' end +require 'spec_helper' +require File.expand_path("../../config/environment", __FILE__) +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! +Rails.application.eager_load! + require 'capybara' require 'capybara/poltergeist' require 'capybara/rspec' From 848c7e117b7209cc9235180ba72eeeca41e93a83 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Tue, 31 May 2016 16:29:31 -0500 Subject: [PATCH 364/392] Add test coverage for Seeds Helper --- spec/helpers/seeds_helper_spec.rb | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 spec/helpers/seeds_helper_spec.rb diff --git a/spec/helpers/seeds_helper_spec.rb b/spec/helpers/seeds_helper_spec.rb new file mode 100644 index 000000000..1049ddc9c --- /dev/null +++ b/spec/helpers/seeds_helper_spec.rb @@ -0,0 +1,38 @@ +require 'rails_helper' + +describe SeedsHelper do + describe "display_seed_description" do + it "no description" do + seed = FactoryGirl.create(:seed, + description: nil + ) + result = helper.display_seed_description(seed) + expect(result).to eq "no description provided." + end + + it "description is less than 130 chars" do + seed = FactoryGirl.create(:seed, + description: 'a' * 20 + ) + result = helper.display_seed_description(seed) + expect(result).to eq 'a' * 20 + end + + it "description is 130 chars" do + seed = FactoryGirl.create(:seed, + description: 'a' * 130 + ) + result = helper.display_seed_description(seed) + link = link_to("Read more", seed_path(seed)) + expect(result).to eq 'a' * 130 + end + + it "description is more than 130 chars" do + seed = FactoryGirl.create(:seed, + description: 'a' * 140 + ) + result = helper.display_seed_description(seed) + expect(result).to eq 'a' * 126 + '...' + ' ' + link_to("Read more", seed_path(seed)) + end + end +end From 21d86a8c2de01cbf8b8285a2d77c1509fcaa0bc2 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Wed, 1 Jun 2016 09:11:43 -0500 Subject: [PATCH 365/392] improve the test descriptions to be more readable --- spec/helpers/seeds_helper_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/helpers/seeds_helper_spec.rb b/spec/helpers/seeds_helper_spec.rb index 1049ddc9c..c86dc2637 100644 --- a/spec/helpers/seeds_helper_spec.rb +++ b/spec/helpers/seeds_helper_spec.rb @@ -1,8 +1,8 @@ require 'rails_helper' describe SeedsHelper do - describe "display_seed_description" do - it "no description" do + describe "seed description" do + it "is missing" do seed = FactoryGirl.create(:seed, description: nil ) @@ -10,7 +10,7 @@ describe SeedsHelper do expect(result).to eq "no description provided." end - it "description is less than 130 chars" do + it "is less than 130 characters long" do seed = FactoryGirl.create(:seed, description: 'a' * 20 ) @@ -18,7 +18,7 @@ describe SeedsHelper do expect(result).to eq 'a' * 20 end - it "description is 130 chars" do + it "is 130 characters long" do seed = FactoryGirl.create(:seed, description: 'a' * 130 ) @@ -27,7 +27,7 @@ describe SeedsHelper do expect(result).to eq 'a' * 130 end - it "description is more than 130 chars" do + it "is more than 130 characters long" do seed = FactoryGirl.create(:seed, description: 'a' * 140 ) From 40d7b11d90d9d407557d8cd8900807afe55abcac Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 2 Jun 2016 13:13:52 +0930 Subject: [PATCH 366/392] #952 Try ruby 2.3.1 --- .ruby-version | 2 +- Gemfile | 2 +- Gemfile.lock | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.ruby-version b/.ruby-version index 530cdd91a..2bf1c1ccf 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.2.4 +2.3.1 diff --git a/Gemfile b/Gemfile index d5182a1d1..ae8a85ccf 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ruby '2.2.4' +ruby '2.3.1' gem 'rails', '~> 4.1.11' diff --git a/Gemfile.lock b/Gemfile.lock index 7d175309f..d79197a13 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -503,8 +503,5 @@ DEPENDENCIES webrat will_paginate (~> 3.0) -RUBY VERSION - ruby 2.1.8p440 - BUNDLED WITH 1.12.4 From f8a1ef6066aa4b5c3547684f8f6fde683f45e2af Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 2 Jun 2016 13:14:10 +0930 Subject: [PATCH 367/392] #952 Try ruby 2.3.1 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 9a3401865..253a8a96a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ env: global: secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" rvm: -- 2.2.4 +- 2.3.1 before_script: - psql -c 'create database growstuff_test;' -U postgres script: From 10064121a674b4f0d29542c0434f107ba36e5fae Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 2 Jun 2016 13:30:42 +0930 Subject: [PATCH 368/392] #953 Swap to geocoder 1.1.9; which is the release just after what we had previously pinned --- Gemfile | 4 +--- Gemfile.lock | 13 ++----------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Gemfile b/Gemfile index d5182a1d1..9948759db 100644 --- a/Gemfile +++ b/Gemfile @@ -60,9 +60,7 @@ gem 'friendly_id', '~> 5.0.4' gem 'gravatar-ultimate' # For geolocation -gem 'geocoder', - :git => 'https://github.com/alexreisner/geocoder.git', - :ref => '104d46' +gem 'geocoder', '1.1.9' # For easy calendar selection gem 'bootstrap-datepicker-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 7d175309f..50bbf6936 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,3 @@ -GIT - remote: https://github.com/alexreisner/geocoder.git - revision: 104d466ba7097b7dce5ba19f8e4091b7f69ccdf6 - ref: 104d46 - specs: - geocoder (1.1.8) - PATH remote: vendor/gems/active_utils-1.0.5 specs: @@ -178,6 +171,7 @@ GEM formatador (0.2.5) friendly_id (5.0.5) activerecord (>= 4.0.0) + geocoder (1.1.9) gibbon (1.2.0) httparty multi_json (>= 1.9.0) @@ -465,7 +459,7 @@ DEPENDENCIES flickraw font-awesome-sass friendly_id (~> 5.0.4) - geocoder! + geocoder (= 1.1.9) gibbon (~> 1.2.0) gravatar-ultimate guard @@ -503,8 +497,5 @@ DEPENDENCIES webrat will_paginate (~> 3.0) -RUBY VERSION - ruby 2.1.8p440 - BUNDLED WITH 1.12.4 From a74ef7de6b478250a01b6846bf79f4fa152622e6 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 2 Jun 2016 13:49:13 +0930 Subject: [PATCH 369/392] Upgrade to devise 4.0.3 --- Gemfile | 2 +- Gemfile.lock | 10 +++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index d5182a1d1..e9c5c077c 100644 --- a/Gemfile +++ b/Gemfile @@ -51,7 +51,7 @@ gem 'bluecloth' gem 'will_paginate', '~> 3.0' # user signup/login/etc -gem 'devise', '~> 3.5.0' +gem 'devise', '~> 4.0.0' # nicely formatted URLs gem 'friendly_id', '~> 5.0.4' diff --git a/Gemfile.lock b/Gemfile.lock index 7d175309f..7ad919e49 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -133,12 +133,11 @@ GEM dalli (2.7.6) database_cleaner (1.5.3) debug_inspector (0.0.2) - devise (3.5.10) + devise (4.0.3) bcrypt (~> 3.0) orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) + railties (>= 4.1.0, < 5.1) responders - thread_safe (~> 0.1) warden (~> 1.2.3) diff-lcs (1.2.5) docile (1.1.5) @@ -457,7 +456,7 @@ DEPENDENCIES csv_shaper dalli database_cleaner (~> 1.5.0) - devise (~> 3.5.0) + devise (~> 4.0.0) elasticsearch-model elasticsearch-rails factory_girl_rails (~> 4.5.0) @@ -503,8 +502,5 @@ DEPENDENCIES webrat will_paginate (~> 3.0) -RUBY VERSION - ruby 2.1.8p440 - BUNDLED WITH 1.12.4 From f979da315a6e52a6e229e9f8b2720672e4ec6309 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Thu, 2 Jun 2016 13:50:25 +0930 Subject: [PATCH 370/392] Explicitly swap from config.email_regexp = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/ to the new default --- config/initializers/devise.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 801a6677f..a11c9b5ca 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -121,7 +121,7 @@ Devise.setup do |config| # Email regex used to validate email formats. It simply asserts that # an one (and only one) @ exists in the given string. This is mainly # to give user feedback and not to assert the e-mail validity. - # config.email_regexp = /\A[^@]+@[^@]+\z/ + config.email_regexp = /\A[^@]+@[^@]+\z/ # ==> Configuration for :timeoutable # The time you want to timeout the user session without activity. After this From dcd36dcd67a1f9315995faf6b53e29269cec55ca Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 2 Jun 2016 13:45:53 +0100 Subject: [PATCH 371/392] Remove the Capistrano configuration file Finishes work started in 93e468876dd4fbdad8b226d322bb16e310980652. --- Capfile | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 Capfile diff --git a/Capfile b/Capfile deleted file mode 100644 index 6a798eb2b..000000000 --- a/Capfile +++ /dev/null @@ -1,4 +0,0 @@ -load 'deploy' -# Uncomment if you are using Rails' asset pipeline - # load 'deploy/assets' -load 'config/deploy' # remove this line to skip loading any of the default tasks \ No newline at end of file From 0075040aab696c5554e82724298c974324be7f9b Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Wed, 1 Jun 2016 12:02:48 +0000 Subject: [PATCH 372/392] Fix #875 edited date on comments on homepage --- app/views/posts/_summary.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 59a58dd47..0d8e38e19 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -15,7 +15,10 @@ %td.hidden-xs =link_to post.author, post.author %td - = post.recent_activity.to_date.to_formatted_s(:short) + - if post.updated_at > post.recent_activity + = post.update_at_to_date.to_formatted_s(:short) + - else + = post.recent_activity.to_date.to_formatted_s(:short) // once the site gets more active, can change this to include time as well // can't make it relative (distance_of_time_in_words) as it's cached %td.hidden-xs From f93ea3c0a1df8cd851cf31af5232af5f4169d87f Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:00:08 +0930 Subject: [PATCH 373/392] Upgrade httparty to current --- Gemfile.lock | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1028aac34..d09bc9a77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,7 +209,7 @@ GEM haml (~> 4.0.0) nokogiri (~> 1.6.0) ruby_parser (~> 3.5) - httparty (0.13.3) + httparty (0.13.7) json (~> 1.8) multi_xml (>= 0.5.2) i18n (0.7.0) @@ -496,5 +496,8 @@ DEPENDENCIES webrat will_paginate (~> 3.0) +RUBY VERSION + ruby 2.3.1p112 + BUNDLED WITH - 1.12.4 + 1.12.5 From ac1cd88ae114721b58698833e1511607d5e613db Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:01:38 +0930 Subject: [PATCH 374/392] Upgrade kaminari to current --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index d09bc9a77..1d3de471b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -232,7 +232,7 @@ GEM railties (>= 3.2) sprockets-rails json (1.8.3) - kaminari (0.16.3) + kaminari (0.17.0) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.10.0) From 235314bc13aa83a0aa8a55ef641a6e660b7cd5ac Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:02:37 +0930 Subject: [PATCH 375/392] Upgrade js-routes to current --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1d3de471b..1abb39bdf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -228,7 +228,7 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (5.0.5) railties (>= 3.2.16) - js-routes (1.2.5) + js-routes (1.2.6) railties (>= 3.2) sprockets-rails json (1.8.3) From 857422719ab1f92a0fb170b1e3ecd6f5c75114a0 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:04:09 +0930 Subject: [PATCH 376/392] Upgrade byebug to current --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1abb39bdf..171572c25 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -65,7 +65,7 @@ GEM sass (>= 3.3.4) bootstrap_form (2.3.0) builder (3.2.2) - byebug (9.0.4) + byebug (9.0.5) cancancan (1.14.0) capybara (2.7.1) addressable From b1ab319bf7aa25dbdb11af54a6d2c124122f76aa Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:05:46 +0930 Subject: [PATCH 377/392] Update mime-types-data to current --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 171572c25..c09c26998 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -255,7 +255,7 @@ GEM method_source (0.8.2) mime-types (3.0) mime-types-data (~> 3.2015) - mime-types-data (3.2016.0221) + mime-types-data (3.2016.0521) mimemagic (0.3.0) mini_portile2 (2.0.0) minitest (5.9.0) From 870aa674b0d93ba2149075c2b4d3fd1889f7eadb Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:07:28 +0930 Subject: [PATCH 378/392] Upgrade autoprefixer-rails to current --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index c09c26998..78b7626ff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -44,7 +44,7 @@ GEM addressable (2.4.0) arel (5.0.1.20140414130214) ast (2.2.0) - autoprefixer-rails (6.3.6.1) + autoprefixer-rails (6.3.6.2) execjs bcrypt (3.1.11) better_errors (2.1.1) From 259c1e1731fafdb855028fb6b2cb3f88596ea8fd Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Thu, 2 Jun 2016 14:10:18 +0000 Subject: [PATCH 379/392] Fix #476 show edited and posted date on posts and comments --- app/views/comments/_single.html.haml | 7 +- app/views/posts/_single.html.haml | 7 +- spec/views/posts/_single.html.haml_spec.rb | 75 ++++++++++++++++++++-- 3 files changed, 81 insertions(+), 8 deletions(-) diff --git a/app/views/comments/_single.html.haml b/app/views/comments/_single.html.haml index af6c328e5..895002b1e 100644 --- a/app/views/comments/_single.html.haml +++ b/app/views/comments/_single.html.haml @@ -5,10 +5,13 @@ = render :partial => "members/avatar", :locals => { :member => comment.author } .col-md-11 .comment-meta - = (comment.created_at == comment.updated_at) ? 'Posted by' : 'Edited by' + Posted by = link_to comment.author.login_name, member_path(comment.author) on - = (comment.created_at == comment.updated_at) ? comment.created_at : comment.updated_at + = comment.created_at + - if comment.updated_at > comment.created_at + and edited at + = comment.updated_at .comment-body :growstuff_markdown diff --git a/app/views/posts/_single.html.haml b/app/views/posts/_single.html.haml index 44750ceac..3ba1e6194 100644 --- a/app/views/posts/_single.html.haml +++ b/app/views/posts/_single.html.haml @@ -9,13 +9,16 @@ .post-meta %p - = (post.created_at == post.updated_at) ? 'Posted by' : 'Edited by' + Posted by = link_to post.author.login_name, member_path(post.author) - if post.forum in = link_to post.forum, post.forum on - = (post.created_at == post.updated_at) ? post.created_at : post.updated_at + = post.created_at + - if post.updated_at > post.created_at + and edited at + = post.updated_at .post-body :growstuff_markdown diff --git a/spec/views/posts/_single.html.haml_spec.rb b/spec/views/posts/_single.html.haml_spec.rb index 75a57b99c..b3a9c0dd9 100644 --- a/spec/views/posts/_single.html.haml_spec.rb +++ b/spec/views/posts/_single.html.haml_spec.rb @@ -129,8 +129,75 @@ describe "posts/_single" do end end + + context "when post has been edited" do + before(:each) do + @member = FactoryGirl.create(:member) + sign_in @member + controller.stub(:current_user) { @member } + @post = FactoryGirl.create(:post, :author => @member) + @post.update(body: "I am updated") + render_post + end + + it "shows edited at" do + rendered.should have_content "edited at" + end + + it "shows the updated time" do + rendered.should have_content @post.updated_at + end + end + + context "when comment has been edited" do + before(:each) do + @member = FactoryGirl.create(:member) + sign_in @member + controller.stub(:current_user) { @member } + @post = FactoryGirl.create(:post, :author => @member) + @comment = FactoryGirl.create(:comment, :post => @post) + @comment.update(body: "I've been updated") + render :partial => "comments/single", :locals => { :comment => @comment } + end + + it "shows edited at time" do + rendered.should have_content "edited at" + end + + it "shows updated time" do + rendered.should have_content @comment.updated_at + end + end + + context "when post has not been edited" do + before(:each) do + @member = FactoryGirl.create(:member) + sign_in @member + controller.stub(:current_user) { @member } + @post = FactoryGirl.create(:post, :author => @member) + @post.update(updated_at: @post.created_at) + render_post + end + + it "does not show edited at" do + rendered.should_not have_content "edited at #{@post.updated_at}" + end + end + + context "when comment has not been edited" do + before(:each) do + @member = FactoryGirl.create(:member) + sign_in @member + controller.stub(:current_user) { @member } + @post = FactoryGirl.create(:post, :author => @member) + @comment = FactoryGirl.create(:comment, :post => @post) + @comment.update(updated_at: @comment.created_at) + render :partial => "comments/single", :locals => { :comment => @comment } + end + + it "does not show edited at" do + rendered.should_not have_content "edited at #{@comment.updated_at}" + end + end + end - - - - From 3e4dc1f9e3e1b8bd8930e0452e8d74261a3d4983 Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Thu, 2 Jun 2016 14:27:56 +0000 Subject: [PATCH 380/392] Issue #875 typo causing test error --- app/views/posts/_summary.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 0d8e38e19..38db48a67 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -16,7 +16,7 @@ =link_to post.author, post.author %td - if post.updated_at > post.recent_activity - = post.update_at_to_date.to_formatted_s(:short) + = post.updated_at.to_date.to_formatted_s(:short) - else = post.recent_activity.to_date.to_formatted_s(:short) // once the site gets more active, can change this to include time as well From 2844e132981a6725ee0062d7a178339aa842497e Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:10:25 +0930 Subject: [PATCH 381/392] Upgrade factory_girl_rails, factory_girl --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 4fc4feb28..942096de1 100644 --- a/Gemfile +++ b/Gemfile @@ -106,7 +106,7 @@ group :development, :test do gem 'byebug' # debugging gem 'database_cleaner', '~> 1.5.0' gem 'webrat' # provides HTML matchers for view tests - gem 'factory_girl_rails', '~> 4.5.0' # for creating test data + gem 'factory_girl_rails' # for creating test data gem 'coveralls', require: false # coverage analysis gem 'capybara' # integration tests gem 'capybara-email' # integration tests for email diff --git a/Gemfile.lock b/Gemfile.lock index 78b7626ff..00abe98d6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -154,10 +154,10 @@ GEM erubis (2.7.0) excon (0.49.0) execjs (2.7.0) - factory_girl (4.5.0) + factory_girl (4.7.0) activesupport (>= 3.0.0) - factory_girl_rails (4.5.0) - factory_girl (~> 4.5.0) + factory_girl_rails (4.7.0) + factory_girl (~> 4.7.0) railties (>= 3.0.0) faraday (0.9.2) multipart-post (>= 1.2, < 3) @@ -453,7 +453,7 @@ DEPENDENCIES devise (~> 4.0.0) elasticsearch-model elasticsearch-rails - factory_girl_rails (~> 4.5.0) + factory_girl_rails figaro flickraw font-awesome-sass From b5c030905a7b72a8c9d7ae320ac2667bdf1e68e8 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:16:00 +0930 Subject: [PATCH 382/392] Upgrade to geocoder current (we shouldn't be affected by the deprecations in 1.2.X or 1.3.X) --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 942096de1..34f5b8bed 100644 --- a/Gemfile +++ b/Gemfile @@ -60,7 +60,7 @@ gem 'friendly_id', '~> 5.0.4' gem 'gravatar-ultimate' # For geolocation -gem 'geocoder', '1.1.9' +gem 'geocoder' # For easy calendar selection gem 'bootstrap-datepicker-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 00abe98d6..4e07dfb1e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,7 +170,7 @@ GEM formatador (0.2.5) friendly_id (5.0.5) activerecord (>= 4.0.0) - geocoder (1.1.9) + geocoder (1.3.6) gibbon (1.2.0) httparty multi_json (>= 1.9.0) @@ -458,7 +458,7 @@ DEPENDENCIES flickraw font-awesome-sass friendly_id (~> 5.0.4) - geocoder (= 1.1.9) + geocoder gibbon (~> 1.2.0) gravatar-ultimate guard From f77fd009315ef18715859e8954beffa3e4392b68 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:19:49 +0930 Subject: [PATCH 383/392] Remove version pin for rspec-rails --- Gemfile | 2 +- Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 34f5b8bed..f549e8994 100644 --- a/Gemfile +++ b/Gemfile @@ -101,7 +101,7 @@ end group :development, :test do gem 'haml-rails' # HTML templating language - gem 'rspec-rails', '~> 3.4.0' # unit testing framework + gem 'rspec-rails' # unit testing framework gem 'rspec-activemodel-mocks' gem 'byebug' # debugging gem 'database_cleaner', '~> 1.5.0' diff --git a/Gemfile.lock b/Gemfile.lock index 4e07dfb1e..c9e3ebdf9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -487,7 +487,7 @@ DEPENDENCIES rails_12factor rake (>= 10.0.0) rspec-activemodel-mocks - rspec-rails (~> 3.4.0) + rspec-rails ruby-units sass-rails (~> 5.0.4) selenium-webdriver From 88a66a705b56ac4707a8ceaff0d8a10b1d1e41c2 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 00:23:58 +0930 Subject: [PATCH 384/392] Update devise to 4.1.X and unpin --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index f549e8994..ac28c61b6 100644 --- a/Gemfile +++ b/Gemfile @@ -51,7 +51,7 @@ gem 'bluecloth' gem 'will_paginate', '~> 3.0' # user signup/login/etc -gem 'devise', '~> 4.0.0' +gem 'devise', '>= 4.0.0' # nicely formatted URLs gem 'friendly_id', '~> 5.0.4' diff --git a/Gemfile.lock b/Gemfile.lock index c9e3ebdf9..c02073c8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -126,7 +126,7 @@ GEM dalli (2.7.6) database_cleaner (1.5.3) debug_inspector (0.0.2) - devise (4.0.3) + devise (4.1.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0, < 5.1) @@ -450,7 +450,7 @@ DEPENDENCIES csv_shaper dalli database_cleaner (~> 1.5.0) - devise (~> 4.0.0) + devise (>= 4.0.0) elasticsearch-model elasticsearch-rails factory_girl_rails From fc38e1edeab0d53d6e443b31e1e252999e71a8f4 Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Thu, 2 Jun 2016 14:27:04 +0000 Subject: [PATCH 385/392] Issue #476 test update --- spec/features/comments/commenting_a_comment_spec.rb | 2 +- spec/features/posts/posting_a_post_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/features/comments/commenting_a_comment_spec.rb b/spec/features/comments/commenting_a_comment_spec.rb index b39d28618..49183c274 100644 --- a/spec/features/comments/commenting_a_comment_spec.rb +++ b/spec/features/comments/commenting_a_comment_spec.rb @@ -27,7 +27,7 @@ feature 'Commenting on a post' do fill_in "comment_body", with: "Testing edit for comment" click_button "Post comment" expect(page).to have_content "Comment was successfully updated" - expect(page).to have_content "Edited by" + expect(page).to have_content "edited at" end end end \ No newline at end of file diff --git a/spec/features/posts/posting_a_post_spec.rb b/spec/features/posts/posting_a_post_spec.rb index a1f32942e..ac31b6fec 100644 --- a/spec/features/posts/posting_a_post_spec.rb +++ b/spec/features/posts/posting_a_post_spec.rb @@ -27,7 +27,7 @@ feature 'Post a post' do fill_in "post_subject", with: "Testing Edit" click_button "Post" expect(page).to have_content "Post was successfully updated" - expect(page).to have_content "Edited by" + expect(page).to have_content "edited at" end end -end \ No newline at end of file +end From 7550bc860f0bffadeddae92652ec6ea70af90327 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 01:01:03 +0930 Subject: [PATCH 386/392] #816 Add better opengraph behaviour, fix facebook share thumbnail size --- app/assets/images/facebook-thumbnail.png | Bin 0 -> 19948 bytes app/views/alternate_names/show.html.haml | 7 +++++++ app/views/comments/show.html.haml | 8 ++++++++ app/views/crops/show.html.haml | 7 +++++++ app/views/forums/show.html.haml | 7 +++++++ app/views/gardens/show.html.haml | 10 +++++++++- app/views/harvests/show.html.haml | 8 ++++++++ app/views/layouts/_meta.html.haml | 13 ++++++++----- app/views/members/show.html.haml | 7 +++++++ app/views/photos/show.html.haml | 9 ++++++++- app/views/places/show.html.haml | 5 +++++ app/views/plant_parts/show.html.haml | 5 +++++ app/views/plantings/show.html.haml | 9 +++++++++ app/views/posts/show.html.haml | 7 +++++++ app/views/scientific_names/show.html.haml | 9 +++++++++ app/views/seeds/show.html.haml | 9 +++++++++ 16 files changed, 113 insertions(+), 7 deletions(-) create mode 100644 app/assets/images/facebook-thumbnail.png diff --git a/app/assets/images/facebook-thumbnail.png b/app/assets/images/facebook-thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..a1b4736bac8da43a5be97156c66c80f0c5ede740 GIT binary patch literal 19948 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 literal 0 HcmV?d00001 diff --git a/app/views/alternate_names/show.html.haml b/app/views/alternate_names/show.html.haml index fc2b7b335..4306ceb23 100644 --- a/app/views/alternate_names/show.html.haml +++ b/app/views/alternate_names/show.html.haml @@ -1,3 +1,10 @@ += content_for :title, @alternate_name.name +- content_for :opengraph do + = tag("meta", property: "og:title", content: @alternate_name.name) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) + %p#notice= notice = render :partial => 'crops/approval_status_message', :locals => { :crop => @alternate_name.crop } diff --git a/app/views/comments/show.html.haml b/app/views/comments/show.html.haml index a43473ffc..6f58faf68 100644 --- a/app/views/comments/show.html.haml +++ b/app/views/comments/show.html.haml @@ -1,4 +1,12 @@ = content_for :title, @comment.post.subject +- content_for :opengraph do + = tag("meta", property: "og:image", content: avatar_uri(@comment.post.author, 150)) + = tag("meta", property: "og:image:user_generated", content: "true") + = tag("meta", property: "og:title", content: @comment.post.subject) + = tag("meta", property: "og:description", content: strip_tags(@comment.post.body).split(' ')[0..20].join(' ')) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) = render :partial => "posts/single", :locals => { :post => @comment.post } diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index 40c5d1812..acc4d0490 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -1,5 +1,12 @@ - content_for :title, @crop.name - content_for :subtitle, @crop.default_scientific_name +- content_for :opengraph do + = @crop.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:title", content: @crop.name) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) = render :partial => 'approval_status_message', :locals => { :crop => @crop } diff --git a/app/views/forums/show.html.haml b/app/views/forums/show.html.haml index 08bc3b55c..ced31ae01 100644 --- a/app/views/forums/show.html.haml +++ b/app/views/forums/show.html.haml @@ -1,4 +1,11 @@ - content_for :title, @forum.name +- content_for :opengraph do + - if @forum.description + = tag("meta", property: "og:description", content: strip_tags(@forum.description).split(' ')[0..20].join(' ')) + = tag("meta", property: "og:title", content: @forum.name) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) %p#notice= notice diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 0900eac40..e682a99b5 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -1,5 +1,13 @@ =content_for :title, "#{@garden.owner}'s #{@garden}" - +- content_for :opengraph do + = @garden.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_url) + - if @garden.description + = tag("meta", property: "og:description", content: @garden.description) + = tag("meta", property: "og:title", content: "#{@garden.owner}'s #{@garden}") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) .row .col-md-9 - if can? :edit, @garden or can? :delete, @garden diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index 4673c7e13..bd7ce9d7b 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -1,4 +1,12 @@ =content_for :title, "#{@harvest.crop} harvested by #{@harvest.owner}" +- content_for :opengraph do + = @harvest.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_uri) + = tag("meta", property: "og:image:user_generated", content: "true") + = tag("meta", property: "og:title", content: "#{@harvest.crop} harvested by #{@harvest.owner}") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) .row .col-md-6 diff --git a/app/views/layouts/_meta.html.haml b/app/views/layouts/_meta.html.haml index 1032821ef..70785e06d 100644 --- a/app/views/layouts/_meta.html.haml +++ b/app/views/layouts/_meta.html.haml @@ -1,11 +1,14 @@ %head - - - - - + - if content_for?(:opengraph) + = yield(:opengraph) + - else + = tag("meta", property: "og:image", content: image_url('facebook-thumbnail.png')) + = tag("meta", property: "og:title", content: "#{content_for?(:title) ? yield(:title) + " - #{ ENV['GROWSTUFF_SITE_NAME']} " : ENV['GROWSTUFF_SITE_NAME']}") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: root_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) - if (content_for?(:member_rss_login_name) && content_for(:member_rss_slug)) = auto_discovery_link_tag(:rss, { :controller => "/members", :action => 'show', :format => "rss", :id => yield(:member_rss_slug) }, { :title => "#{ ENV['GROWSTUFF_SITE_NAME'] }- #{yield(:member_rss_login_name)}'s posts" }) diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 591c2be77..6f6c47f88 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -1,5 +1,12 @@ - content_for :title, @member.login_name - content_for :subtitle, @member.location +- content_for :opengraph do + = tag("meta", property: "og:image", content: avatar_uri(@member, 150)) + = tag("meta", property: "og:image:user_generated", content: "true") + = tag("meta", property: "og:title", content: @member.login_name) + = tag("meta", property: "og:type", content: "profile") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) - content_for :buttonbar do - if can? :update, @member = link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default' diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml index 5d941c2ba..0ad731132 100644 --- a/app/views/photos/show.html.haml +++ b/app/views/photos/show.html.haml @@ -1,4 +1,11 @@ --content_for :title, @photo.title +- content_for :title, @photo.title +- content_for :opengraph do + = tag("meta", property: "og:title", content: @photo.title) + = tag("meta", property: "og:image", content: @photo.fullsize_url) + = tag("meta", property: "og:image:user_generated", content: "true") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) .row .col-md-6 diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 70fa11faa..d37da8433 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -1,4 +1,9 @@ -content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} community near #{@place}" +- content_for :opengraph do + = tag("meta", property: "og:title", content: "#{ENV['GROWSTUFF_SITE_NAME']} community near #{@place}") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) = render partial: 'search_form' diff --git a/app/views/plant_parts/show.html.haml b/app/views/plant_parts/show.html.haml index 0af93e520..c24cf6ea0 100644 --- a/app/views/plant_parts/show.html.haml +++ b/app/views/plant_parts/show.html.haml @@ -1,4 +1,9 @@ - content_for :title, @plant_part.name.titlecase +- content_for :opengraph do + = tag("meta", property: "og:title", content: @plant_part.name.titlecase) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) - if @plant_part.crops.empty? %p No crops are harvested for this plant part (yet). diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index b3b396783..865377644 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -1,4 +1,13 @@ =content_for :title, "#{@planting.crop} in #{@planting.location}" +- content_for :opengraph do + = @planting.crop.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:title", content: "#{@planting.crop} in #{@planting.location}") + - if @planting.description + = tag("meta", property: "og:description", content: @planting.description) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) .row.planting .col-md-6 diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml index 1a656997d..49fe665e4 100644 --- a/app/views/posts/show.html.haml +++ b/app/views/posts/show.html.haml @@ -1,4 +1,11 @@ = content_for :title, @post.subject +- content_for :opengraph do + = tag("meta", property: "og:image", content: avatar_uri(@post.author, 150)) + = tag("meta", property: "og:description", content: "#{strip_tags(@post.body).split(' ')[0..20].join(' ')}...") + = tag("meta", property: "og:title", content: @post.subject) + = tag("meta", property: "og:type", content: "article") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) - unless current_member .alert.alert-info diff --git a/app/views/scientific_names/show.html.haml b/app/views/scientific_names/show.html.haml index dffbdffc3..514d74a99 100644 --- a/app/views/scientific_names/show.html.haml +++ b/app/views/scientific_names/show.html.haml @@ -1,3 +1,12 @@ +- content_for :opengraph do + = @scientific_name.crop.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_url) + + = tag("meta", property: "og:title", content: @scientific_name.scientific_name) + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) + %p#notice= notice = render :partial => 'crops/approval_status_message', :locals => { :crop => @scientific_name.crop } diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index 643445a05..92293afcc 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -1,4 +1,13 @@ - content_for :title, "#{@seed.owner}'s #{@seed.crop} seeds" +- content_for :opengraph do + = @seed.crop.photos.each do |photo| + = tag("meta", property: "og:image", content: photo.thumbnail_url) + - if @seed.description + = tag("meta", property: "og:description", content: @seed.description) + = tag("meta", property: "og:image", content: "#{@seed.owner}'s #{@seed.crop} seeds") + = tag("meta", property: "og:type", content: "website") + = tag("meta", property: "og:url", content: request.original_url) + = tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME']) .row .col-md-6 From c278b368584723dd9478e2d2443f8b2defebd3a5 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 01:45:43 +0930 Subject: [PATCH 387/392] Up the various opengraph images to 200x200 --- app/views/comments/show.html.haml | 2 +- app/views/members/show.html.haml | 2 +- app/views/posts/show.html.haml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/comments/show.html.haml b/app/views/comments/show.html.haml index 6f58faf68..84cd72159 100644 --- a/app/views/comments/show.html.haml +++ b/app/views/comments/show.html.haml @@ -1,6 +1,6 @@ = content_for :title, @comment.post.subject - content_for :opengraph do - = tag("meta", property: "og:image", content: avatar_uri(@comment.post.author, 150)) + = tag("meta", property: "og:image", content: avatar_uri(@comment.post.author, 200)) = tag("meta", property: "og:image:user_generated", content: "true") = tag("meta", property: "og:title", content: @comment.post.subject) = tag("meta", property: "og:description", content: strip_tags(@comment.post.body).split(' ')[0..20].join(' ')) diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 6f6c47f88..c40482641 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -1,7 +1,7 @@ - content_for :title, @member.login_name - content_for :subtitle, @member.location - content_for :opengraph do - = tag("meta", property: "og:image", content: avatar_uri(@member, 150)) + = tag("meta", property: "og:image", content: avatar_uri(@member, 200)) = tag("meta", property: "og:image:user_generated", content: "true") = tag("meta", property: "og:title", content: @member.login_name) = tag("meta", property: "og:type", content: "profile") diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml index 49fe665e4..6e0ee6161 100644 --- a/app/views/posts/show.html.haml +++ b/app/views/posts/show.html.haml @@ -1,6 +1,6 @@ = content_for :title, @post.subject - content_for :opengraph do - = tag("meta", property: "og:image", content: avatar_uri(@post.author, 150)) + = tag("meta", property: "og:image", content: avatar_uri(@post.author, 200)) = tag("meta", property: "og:description", content: "#{strip_tags(@post.body).split(' ')[0..20].join(' ')}...") = tag("meta", property: "og:title", content: @post.subject) = tag("meta", property: "og:type", content: "article") From 0e83a230b950cdfad836f492d17a901f23beb6af Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 01:54:26 +0930 Subject: [PATCH 388/392] Helps not to render excess info --- app/views/crops/show.html.haml | 2 +- app/views/gardens/show.html.haml | 2 +- app/views/harvests/show.html.haml | 2 +- app/views/plantings/show.html.haml | 2 +- app/views/scientific_names/show.html.haml | 2 +- app/views/seeds/show.html.haml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index acc4d0490..808a896db 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -1,7 +1,7 @@ - content_for :title, @crop.name - content_for :subtitle, @crop.default_scientific_name - content_for :opengraph do - = @crop.photos.each do |photo| + - @crop.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_url) = tag("meta", property: "og:title", content: @crop.name) = tag("meta", property: "og:type", content: "website") diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index e682a99b5..dd573ac05 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -1,6 +1,6 @@ =content_for :title, "#{@garden.owner}'s #{@garden}" - content_for :opengraph do - = @garden.photos.each do |photo| + - @garden.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_url) - if @garden.description = tag("meta", property: "og:description", content: @garden.description) diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index bd7ce9d7b..5b39bfece 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -1,6 +1,6 @@ =content_for :title, "#{@harvest.crop} harvested by #{@harvest.owner}" - content_for :opengraph do - = @harvest.photos.each do |photo| + - @harvest.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_uri) = tag("meta", property: "og:image:user_generated", content: "true") = tag("meta", property: "og:title", content: "#{@harvest.crop} harvested by #{@harvest.owner}") diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 865377644..12fccbc72 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -1,6 +1,6 @@ =content_for :title, "#{@planting.crop} in #{@planting.location}" - content_for :opengraph do - = @planting.crop.photos.each do |photo| + - @planting.crop.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_url) = tag("meta", property: "og:title", content: "#{@planting.crop} in #{@planting.location}") - if @planting.description diff --git a/app/views/scientific_names/show.html.haml b/app/views/scientific_names/show.html.haml index 514d74a99..a56d56419 100644 --- a/app/views/scientific_names/show.html.haml +++ b/app/views/scientific_names/show.html.haml @@ -1,5 +1,5 @@ - content_for :opengraph do - = @scientific_name.crop.photos.each do |photo| + - @scientific_name.crop.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_url) = tag("meta", property: "og:title", content: @scientific_name.scientific_name) diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index 92293afcc..8531416dd 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -1,6 +1,6 @@ - content_for :title, "#{@seed.owner}'s #{@seed.crop} seeds" - content_for :opengraph do - = @seed.crop.photos.each do |photo| + - @seed.crop.photos.each do |photo| = tag("meta", property: "og:image", content: photo.thumbnail_url) - if @seed.description = tag("meta", property: "og:description", content: @seed.description) From faaf07cad8f797691fc1e7ab445f8416a53857f2 Mon Sep 17 00:00:00 2001 From: Daniel O'Connor Date: Fri, 3 Jun 2016 01:58:34 +0930 Subject: [PATCH 389/392] Render the full size image, as facebook doesn't like smaller thumbnails --- app/views/crops/show.html.haml | 2 +- app/views/gardens/show.html.haml | 2 +- app/views/harvests/show.html.haml | 2 +- app/views/plantings/show.html.haml | 2 +- app/views/scientific_names/show.html.haml | 2 +- app/views/seeds/show.html.haml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index 808a896db..288629464 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -2,7 +2,7 @@ - content_for :subtitle, @crop.default_scientific_name - content_for :opengraph do - @crop.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:image", content: photo.fullsize_url) = tag("meta", property: "og:title", content: @crop.name) = tag("meta", property: "og:type", content: "website") = tag("meta", property: "og:url", content: request.original_url) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index dd573ac05..fb5eeae12 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -1,7 +1,7 @@ =content_for :title, "#{@garden.owner}'s #{@garden}" - content_for :opengraph do - @garden.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:image", content: photo.fullsize_url) - if @garden.description = tag("meta", property: "og:description", content: @garden.description) = tag("meta", property: "og:title", content: "#{@garden.owner}'s #{@garden}") diff --git a/app/views/harvests/show.html.haml b/app/views/harvests/show.html.haml index 5b39bfece..f4e6220d8 100644 --- a/app/views/harvests/show.html.haml +++ b/app/views/harvests/show.html.haml @@ -1,7 +1,7 @@ =content_for :title, "#{@harvest.crop} harvested by #{@harvest.owner}" - content_for :opengraph do - @harvest.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_uri) + = tag("meta", property: "og:image", content: photo.fullsize_url) = tag("meta", property: "og:image:user_generated", content: "true") = tag("meta", property: "og:title", content: "#{@harvest.crop} harvested by #{@harvest.owner}") = tag("meta", property: "og:type", content: "website") diff --git a/app/views/plantings/show.html.haml b/app/views/plantings/show.html.haml index 12fccbc72..6ad55ff15 100644 --- a/app/views/plantings/show.html.haml +++ b/app/views/plantings/show.html.haml @@ -1,7 +1,7 @@ =content_for :title, "#{@planting.crop} in #{@planting.location}" - content_for :opengraph do - @planting.crop.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:image", content: photo.fullsize_url) = tag("meta", property: "og:title", content: "#{@planting.crop} in #{@planting.location}") - if @planting.description = tag("meta", property: "og:description", content: @planting.description) diff --git a/app/views/scientific_names/show.html.haml b/app/views/scientific_names/show.html.haml index a56d56419..b5d9c332f 100644 --- a/app/views/scientific_names/show.html.haml +++ b/app/views/scientific_names/show.html.haml @@ -1,6 +1,6 @@ - content_for :opengraph do - @scientific_name.crop.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:image", content: photo.fullsize_url) = tag("meta", property: "og:title", content: @scientific_name.scientific_name) = tag("meta", property: "og:type", content: "website") diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index 8531416dd..e4e55f68e 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -1,7 +1,7 @@ - content_for :title, "#{@seed.owner}'s #{@seed.crop} seeds" - content_for :opengraph do - @seed.crop.photos.each do |photo| - = tag("meta", property: "og:image", content: photo.thumbnail_url) + = tag("meta", property: "og:image", content: photo.fullsize_url) - if @seed.description = tag("meta", property: "og:description", content: @seed.description) = tag("meta", property: "og:image", content: "#{@seed.owner}'s #{@seed.crop} seeds") From 085fcc958e9f5b793e54396f4e83687e26963899 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Thu, 2 Jun 2016 22:22:14 -0500 Subject: [PATCH 390/392] Add test coverage for GardensHelper --- spec/helpers/gardens_helper_spec.rb | 110 ++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 spec/helpers/gardens_helper_spec.rb diff --git a/spec/helpers/gardens_helper_spec.rb b/spec/helpers/gardens_helper_spec.rb new file mode 100644 index 000000000..2dee1ba0a --- /dev/null +++ b/spec/helpers/gardens_helper_spec.rb @@ -0,0 +1,110 @@ +require 'rails_helper' + +describe GardensHelper do + describe "garden description" do + it "is missing" do + garden = FactoryGirl.create(:garden, + description: nil + ) + result = helper.display_garden_description(garden) + expect(result).to eq "no description provided." + end + + it "is less than 130 characters long" do + garden = FactoryGirl.create(:garden, + description: 'a' * 20 + ) + result = helper.display_garden_description(garden) + expect(result).to eq 'a' * 20 + end + + it "is 130 characters long" do + garden = FactoryGirl.create(:garden, + description: 'a' * 130 + ) + result = helper.display_garden_description(garden) + link = link_to("Read more", garden_path(garden)) + expect(result).to eq 'a' * 130 + end + + it "is more than 130 characters long" do + garden = FactoryGirl.create(:garden, + description: 'a' * 140 + ) + result = helper.display_garden_description(garden) + expect(result).to eq 'a' * 126 + '...' + ' ' + link_to("Read more", garden_path(garden)) + end + end + + describe "garden plantings" do + it "is missing" do + garden = FactoryGirl.create(:garden) + plantings = nil + result = helper.display_garden_plantings(plantings) + expect(result).to eq "None" + end + + it "has 1 planting" do + garden = FactoryGirl.create(:garden) + plantings = [] + crop = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop) + result = helper.display_garden_plantings(plantings) + + output = "
  • " + output += "10 " + link_to(crop.name, crop) + output += ", planted on #{plantings.first.planted_at}" + output += "
  • " + expect(result).to eq output + end + + it "has 2 planting" do + garden = FactoryGirl.create(:garden) + plantings = [] + + crop1 = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop1) + + crop2 = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop2) + + result = helper.display_garden_plantings(plantings) + + output = "
  • " + output += "10 " + link_to(crop1.name, crop1) + output += ", planted on #{plantings.first.planted_at}" + output += "
  • " + output += "
  • " + output += "10 " + link_to(crop2.name, crop2) + output += ", planted on #{plantings.first.planted_at}" + output += "
  • " + expect(result).to eq output + end + + it "has 3 planting" do + garden = FactoryGirl.create(:garden) + plantings = [] + + crop1 = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop1) + + crop2 = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop2) + + crop3 = FactoryGirl.create(:crop) + plantings << FactoryGirl.create(:planting, quantity: 10, crop: crop3) + + result = helper.display_garden_plantings(plantings) + + output = "
  • " + output += "10 " + link_to(crop1.name, crop1) + output += ", planted on #{plantings.first.planted_at}" + output += "
  • " + output += "
  • " + output += "10 " + link_to(crop2.name, crop2) + output += ", planted on #{plantings.first.planted_at}" + output += "
  • " + expect(result).to eq output + end + end +end From ed4269ea4c5b9c43723522f448e7f50b9e0b2ec9 Mon Sep 17 00:00:00 2001 From: DV Dasari Date: Fri, 3 Jun 2016 07:54:24 -0500 Subject: [PATCH 391/392] fixing grammar in test descriptions --- spec/helpers/gardens_helper_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/helpers/gardens_helper_spec.rb b/spec/helpers/gardens_helper_spec.rb index 2dee1ba0a..c561c32d1 100644 --- a/spec/helpers/gardens_helper_spec.rb +++ b/spec/helpers/gardens_helper_spec.rb @@ -58,7 +58,7 @@ describe GardensHelper do expect(result).to eq output end - it "has 2 planting" do + it "has 2 plantings" do garden = FactoryGirl.create(:garden) plantings = [] @@ -81,7 +81,7 @@ describe GardensHelper do expect(result).to eq output end - it "has 3 planting" do + it "has 3 plantings" do garden = FactoryGirl.create(:garden) plantings = [] From 681798b5829310aa8e5237589625a6fa7a09f66b Mon Sep 17 00:00:00 2001 From: Cesy Avon Date: Fri, 3 Jun 2016 13:12:19 +0000 Subject: [PATCH 392/392] Updating readme with current wiki status and Gitter link --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a63764bc6..3e6898ded 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ encourage participation from people of all backgrounds and skill levels. * [Issues](http://github.com/Growstuff/growstuff/issues) (features we're working on, known bugs, etc) -* [Discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) (mailing lists, IRC, etc) -* [Wiki](http://wiki.growstuff.org/) (general documentation) +* [Discussion forums](http://talk.growstuff.org/) (design ideas, planning releases) +* IRC: #growstuff on Freenode (general chat, brainstorming and troubleshooting) or [Gitter](https://gitter.im/Growstuff/growstuff) +* [Wiki](http://wiki.growstuff.org/) (general documentation, currently down but should be fixed soon) ## For coders @@ -30,7 +31,7 @@ frontend features. We welcome contributions -- see * To set up your development environment, see [Getting started](http://wiki.growstuff.org/index.php/Development/Getting_Started). * We encourage [pair programming](http://wiki.growstuff.org/index.php/Pairing), especially for newer developers. [Find a pair programming partner.](http://talk.growstuff.org/t/find-a-pair-programming-partner/13) -* Drop in to one of our [discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) to chat to other developers, get help, etc. +* Drop in to our [discussion forums](http://talk.growstuff.org/), IRC or Gitter to chat to other developers, get help, etc. * You may also be interested in our [API](http://wiki.growstuff.org/index.php/API). The wiki is down right now, so here's what you need to do on Mac OS X to get set up. @@ -58,12 +59,13 @@ Here on Github, you might find these useful: * [needs: visual design](https://github.com/Growstuff/growstuff/labels/needs:%20visual design) - tasks requiring visual/graphical design * [needs: documentation](https://github.com/Growstuff/growstuff/labels/needs:%20documentation) * [needs: data](https://github.com/Growstuff/growstuff/labels/needs:%20data) - tasks requiring data entry, data design, data import, or similar +* [curated:beginner](https://github.com/Growstuff/growstuff/labels/curated:%20beginner) - tasks that are ideal for beginner programmers or people new to the project Feel free to comment on any of the issues you find there, or open up a broader conversation on [Growstuff Talk](http://talk.growstuff.org). ## Contact -For more information about this project, contact [info@growstuff.org](mailto:info@growstuff.org). +For more information about this project, contact one of the active committers - the email [info@growstuff.org](mailto:info@growstuff.org) is down right now. You can also contact us on [Twitter](http://twitter.com/growstufforg/) or [Facebook](https://www.facebook.com/pages/Growstuff/1531133417099494).

    -kp8wuk*CK)Wj*MJr8r0Hh$Y0&w?a#ODjG*xG~} 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 literal 22816 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 diff --git a/app/assets/images/sunniness_sun.png b/app/assets/images/sunniness_sun.png index f1248651ab3ae508c7489bd6196238ab521a5662..8713ffac9c6efceacbd6f3b28be58d86c828dbb8 100644 GIT binary patch literal 6019 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 J0u#6J{{ZcUVy*xH From 6a6f83c6a4ecdd6c62bff9e8021f9386233913c1 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 7 Jul 2015 11:04:44 +0800 Subject: [PATCH 125/392] Added feature request #720 --- app/views/places/show.html.haml | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 8cc9f86ef..ab3479af6 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -11,5 +11,46 @@ - @nearby_members.first(30).each do |member| .col-md-4.three-across = render :partial => "members/thumbnail", :locals => { :member => member } + = link_to "View all members >>", members_path - elsif @place %p No results found + +%h3 + = "Seeds available for trade near #{@place}" +%br +- if !@nearby_members.empty? + .row + - crop_id = [] + - @nearby_members.first(10).each do |member| + - member.seeds.first(5).each do |seed| + - crop_id.push seed.crop.id + - crop_id.uniq.first(20).each do |crop| + .col-md-2.six-across + = render :partial => "crops/thumbnail", :locals => { :crop => Crop.find(crop) } + = link_to "View all seeds >>", seeds_path + +- elsif @place + %p No results found + +%h3 + = "Recent plantings near #{@place}" +%br +- if !@nearby_members.empty? + - plantings = [] + - @nearby_members.first(10).each do |member| + - member.plantings.first(5).each do |planting| + - plantings << planting + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 + - plantings.first(10).each.with_index do |planting, index| + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + = link_to "View all plantings >>", plantings_path + +- elsif @place + %p No results found \ No newline at end of file From 43d7c36fc5eb9b3ec58dc5857ca467c9fddc0fb7 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Tue, 7 Jul 2015 13:11:26 +0800 Subject: [PATCH 126/392] Created feature tests for showing nearby plantings, seeds, and members on search --- app/views/places/show.html.haml | 74 +++++++++---------- .../features/places/searching_a_place_spec.rb | 43 ++++++++++- 2 files changed, 75 insertions(+), 42 deletions(-) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index ab3479af6..3b9eae70d 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -4,7 +4,7 @@ %div#placesmap{ :style => "height:300px"} -%h3 Nearby members +%h3= "Nearby members" - if !@nearby_members.empty? .row @@ -12,45 +12,41 @@ .col-md-4.three-across = render :partial => "members/thumbnail", :locals => { :member => member } = link_to "View all members >>", members_path -- elsif @place - %p No results found -%h3 - = "Seeds available for trade near #{@place}" -%br -- if !@nearby_members.empty? - .row - - crop_id = [] - - @nearby_members.first(10).each do |member| - - member.seeds.first(5).each do |seed| - - crop_id.push seed.crop.id - - crop_id.uniq.first(20).each do |crop| - .col-md-2.six-across - = render :partial => "crops/thumbnail", :locals => { :crop => Crop.find(crop) } - = link_to "View all seeds >>", seeds_path - -- elsif @place - %p No results found - -%h3 - = "Recent plantings near #{@place}" -%br -- if !@nearby_members.empty? - - plantings = [] + %h3= "Seeds available for trade near #{@place}" + - crop_id = [] - @nearby_members.first(10).each do |member| - - member.plantings.first(5).each do |planting| - - plantings << planting - .row - .col-md-1 - %b # - .col-md-3 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - - plantings.first(10).each.with_index do |planting, index| - = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} - = link_to "View all plantings >>", plantings_path + - member.seeds.first(5).each do |seed| + - crop_id.push seed.crop.id + - if !crop_id.blank? + .row + - crop_id.uniq.first(20).each do |crop| + .col-md-2.six-across + = render :partial => "crops/thumbnail", :locals => { :crop => Crop.find(crop) } + = link_to "View all seeds >>", seeds_path + - else + %p No nearby seeds found -- elsif @place + %h3= "Recent plantings near #{@place}" + + .row + - plantings = [] + - @nearby_members.first(10).each do |member| + - member.plantings.first(5).each do |planting| + - plantings << planting + - if !plantings.blank? + .row + .col-md-1 + %b # + .col-md-3 + %b Photo + .col-md-6 + %b Planting Details + .col-md-2 + - plantings.first(10).each.with_index do |planting, index| + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + = link_to "View all plantings >>", plantings_path + - else + %p No nearby plantings found +- else %p No results found \ No newline at end of file diff --git a/spec/features/places/searching_a_place_spec.rb b/spec/features/places/searching_a_place_spec.rb index 6812e6413..4f69c1321 100644 --- a/spec/features/places/searching_a_place_spec.rb +++ b/spec/features/places/searching_a_place_spec.rb @@ -1,7 +1,12 @@ require "rails_helper" RSpec.feature "User searches", :type => :feature do - + let(:member) { FactoryGirl.create(:member, location: "Philippines") } + let!(:maize) { FactoryGirl.create(:maize) } + let(:garden) { FactoryGirl.create(:garden, owner: member) } + let!(:seed1) { FactoryGirl.create(:seed, owner: member) } + let!(:planting){ FactoryGirl.create(:planting, garden: garden, owner: member, planted_at: Date.parse("2013-3-10")) } + scenario "with a valid place" do visit places_path search_with("Philippines") @@ -9,6 +14,7 @@ RSpec.feature "User searches", :type => :feature do expect(page).to have_button "search_button" page.has_content?('placesmap') expect(page).to have_content "Nearby members" + expect(page).to_not have_content "No results found" end scenario "with a blank search string" do @@ -19,9 +25,40 @@ RSpec.feature "User searches", :type => :feature do page.has_content?('placesmap') end - def search_with(search_string) + describe "Nearby plantings, seed, and members" do + before(:each) do + login_as(member) + visit places_path + search_with("Philippines") + end + + it "should show that there are nearby seeds, plantings, and members" do + expect(page).to have_content "Nearby members" + expect(page).to have_content "Seeds available for trade near Philippines" + expect(page).to have_content "Recent plantings near Philippines" + find_link("View all members").visible? + find_link("View all seeds").visible? + find_link("View all plantings").visible? + end + + it "should go to members' index page" do + click_link('View all members >>') + current_path.should == members_path + end + + it "should go to plantings' index page" do + click_link('View all plantings >>') + current_path.should == plantings_path + end + + it "should go to seeds' index page" do + click_link('View all seeds >>') + current_path.should == seeds_path + end + end + + def search_with(search_string) fill_in "new_place", :with => search_string click_button "search_button" end - end \ No newline at end of file From 01e676678cfa0feefdd0c852fbb4a08fd2fbfbf1 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Wed, 8 Jul 2015 10:30:37 +0800 Subject: [PATCH 127/392] Removed the '#' column on plantings/_thumbnail partial. --- app/views/gardens/show.html.haml | 14 +++++--------- app/views/members/_gardens.html.haml | 8 +++----- app/views/places/show.html.haml | 4 +--- app/views/plantings/_thumbnail.html.haml | 7 ++----- app/views/plantings/index.html.haml | 8 +++----- 5 files changed, 14 insertions(+), 27 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index cef4c95f8..1bfee9516 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -47,15 +47,13 @@ - if @garden.plantings.current.size > 0 .container .row - .col-md-1 - %b # - .col-md-3 + .col-md-4 %b Photo .col-md-6 %b Planting Details .col-md-2 - @garden.plantings.current.each.with_index do |planting_current, index_current| - = render partial: "plantings/thumbnail", locals: {:planting => planting_current, :index => index_current} + = render partial: "plantings/thumbnail", locals: {:planting => planting_current} - else %p Nothing is currently planted here. @@ -64,15 +62,13 @@ - if @garden.plantings.finished.size > 0 .container .row - .col-md-1 - %b # - .col-md-3 + .col-md-4 %b Photo .col-md-6 %b Planting Details .col-md-2 - - @garden.plantings.finished.each.with_index do |planting_finished, index_finished| - = render partial: "plantings/thumbnail", locals: {:planting => planting_finished, :index => index_finished} + - @garden.plantings.finished.each.with_index do |planting_finished| + = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} .col-md-3 %h4 About this garden diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 7f5d4de2b..4ac7b8e8c 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -37,15 +37,13 @@ - if g.featured_plantings.size > 0 .container .row - .col-md-1 - %b # - .col-md-3 + .col-md-4 %b Photo .col-md-6 %b Planting Details .col-md-2 - - g.featured_plantings.each.with_index do |planting, index| - = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + - g.featured_plantings.each.with_index do |planting| + = render partial: "plantings/thumbnail", locals: {:planting => planting} %p = link_to "More about this garden...", url_for(g) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 3b9eae70d..46b846a4f 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -36,9 +36,7 @@ - plantings << planting - if !plantings.blank? .row - .col-md-1 - %b # - .col-md-3 + .col-md-4 %b Photo .col-md-6 %b Planting Details diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index 2cebfcbd7..be8e1d879 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,7 +1,5 @@ .row - .col-md-1 - = "##{index+1}" - .col-md-3 + .col-md-4 = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting .col-md-6 %dl.dl-horizontal @@ -29,8 +27,7 @@ - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' .row - .col-md-1 - .col-md-3 + .col-md-4 %ul{:style => "list-style-type:none"} %li %b Crop name: diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index aa01c9129..84f7400eb 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -20,15 +20,13 @@ - if @plantings.size > 0 .row - .col-md-1 - %b # - .col-md-3 + .col-md-4 %b Photo .col-md-6 %b Planting Details .col-md-2 - - @plantings.each.with_index do |planting, index| - = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + - @plantings.each.with_index do |planting| + = render partial: "plantings/thumbnail", locals: {:planting => planting} %div.pagination = page_entries_info @plantings, :model => "plantings" From 80c1e1bf234ef6396f3bec12d9a890a2a4d5453e Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 9 Jul 2015 08:05:13 +0800 Subject: [PATCH 128/392] Removed the column headers of planting thumbnails. --- app/views/gardens/show.html.haml | 22 ++++------------------ app/views/members/_gardens.html.haml | 11 ++--------- app/views/places/show.html.haml | 6 ------ app/views/plantings/index.html.haml | 6 ------ 4 files changed, 6 insertions(+), 39 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 1bfee9516..c0feee7eb 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -45,30 +45,16 @@ %h3 What's planted here? - if @garden.plantings.current.size > 0 - .container - .row - .col-md-4 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - - @garden.plantings.current.each.with_index do |planting_current, index_current| - = render partial: "plantings/thumbnail", locals: {:planting => planting_current} + - @garden.plantings.current.each.with_index do |planting_current, index_current| + = render partial: "plantings/thumbnail", locals: {:planting => planting_current} - else %p Nothing is currently planted here. %h3 Previously planted in this garden - if @garden.plantings.finished.size > 0 - .container - .row - .col-md-4 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - - @garden.plantings.finished.each.with_index do |planting_finished| - = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} + - @garden.plantings.finished.each.with_index do |planting_finished| + = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} .col-md-3 %h4 About this garden diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 4ac7b8e8c..f5b0deb6e 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -35,15 +35,8 @@ %h3 What's planted here? - if g.featured_plantings.size > 0 - .container - .row - .col-md-4 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - - g.featured_plantings.each.with_index do |planting| - = render partial: "plantings/thumbnail", locals: {:planting => planting} + - g.featured_plantings.each.with_index do |planting| + = render partial: "plantings/thumbnail", locals: {:planting => planting} %p = link_to "More about this garden...", url_for(g) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index 46b846a4f..bf3d8d631 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -35,12 +35,6 @@ - member.plantings.first(5).each do |planting| - plantings << planting - if !plantings.blank? - .row - .col-md-4 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - plantings.first(10).each.with_index do |planting, index| = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} = link_to "View all plantings >>", plantings_path diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 84f7400eb..95258e479 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -19,12 +19,6 @@ = will_paginate @plantings - if @plantings.size > 0 - .row - .col-md-4 - %b Photo - .col-md-6 - %b Planting Details - .col-md-2 - @plantings.each.with_index do |planting| = render partial: "plantings/thumbnail", locals: {:planting => planting} From 9f3d3b2b8f35fb2b0fd2e081c311c3b21281e5a8 Mon Sep 17 00:00:00 2001 From: "Jym Paul A. Carandang" Date: Fri, 10 Jul 2015 12:51:36 +0800 Subject: [PATCH 129/392] Signout redirects to last page visited --- app/controllers/application_controller.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9dd23395c..bb1d276a5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,6 +22,10 @@ class ApplicationController < ActionController::Base stored_location_for(:member) || root_path end + def after_sign_out_path_for(resource_or_scope) + request.referrer + end + # tweak CanCan defaults because we don't have a "current_user" method # this means that we use current_user in specs but current_member everywhere # else in the code. @@ -33,7 +37,7 @@ class ApplicationController < ActionController::Base rescue_from CanCan::AccessDenied do |exception| redirect_to request.referer || root_url, :alert => exception.message end - + def set_locale I18n.locale = params[:locale] || extract_locale_from_subdomain || I18n.default_locale end @@ -48,7 +52,7 @@ class ApplicationController < ActionController::Base protected def configure_permitted_parameters - devise_parameter_sanitizer.for(:sign_up) do |member| + devise_parameter_sanitizer.for(:sign_up) do |member| member.permit(:login_name, :email, :password, :password_confirmation, :remember_me, :login, # terms of service From 89424b931b8c0a0ffdca95b451b54629a99274e8 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 13:17:43 +0800 Subject: [PATCH 130/392] Replaced 'sunniness_not specified.png' icon with a darker one. --- app/assets/images/sunniness_not specified.png | Bin 6384 -> 16135 bytes app/assets/images/sunniness_sun.png | Bin 6019 -> 5906 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/assets/images/sunniness_not specified.png b/app/assets/images/sunniness_not specified.png index e4374bf2cf374b64705365365d6c04cb791a5d94..108505a70d0a324cf1cef89779deaebe7d57291a 100644 GIT binary patch literal 16135 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 diff --git a/app/assets/images/sunniness_sun.png b/app/assets/images/sunniness_sun.png index 8713ffac9c6efceacbd6f3b28be58d86c828dbb8..1c6c310cf2d95ddd11eacaffcb16c7eb59b6b235 100644 GIT binary patch literal 5906 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 Date: Fri, 10 Jul 2015 15:11:15 +0800 Subject: [PATCH 131/392] Made the plantings/_thumbnail partial flexible for small and large screen sizes. --- app/views/places/show.html.haml | 3 ++- app/views/plantings/_thumbnail.html.haml | 25 +++++++++++------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/app/views/places/show.html.haml b/app/views/places/show.html.haml index bf3d8d631..75be54058 100644 --- a/app/views/places/show.html.haml +++ b/app/views/places/show.html.haml @@ -36,7 +36,8 @@ - plantings << planting - if !plantings.blank? - plantings.first(10).each.with_index do |planting, index| - = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} + .col-xs-12.col-lg-6 + = render partial: "plantings/thumbnail", locals: {:planting => planting, :index => index} = link_to "View all plantings >>", plantings_path - else %p No nearby plantings found diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index be8e1d879..bec2230ad 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,7 +1,7 @@ .row - .col-md-4 + .col-xs-4.col-md-2 = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => planting.crop_id, :class => 'img'), planting - .col-md-6 + .col-xs-4.col-md-6 %dl.dl-horizontal %dt Owner: %dd= link_to planting.owner.login_name, planting.owner @@ -17,7 +17,7 @@ %dd= "#{display_sunniness(planting)}" %dt Planted from: %dd= "#{display_planted_from(planting)}" - .col-md-2 + .col-xs-4.col-md-4 %ul{:style => "list-style-type:none"} %li= link_to 'Details', planting, :class => 'btn btn-default btn-xs' - if can? :edit, planting @@ -27,15 +27,12 @@ - if can? :destroy, planting %li= link_to 'Delete', planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs' .row - .col-md-4 - %ul{:style => "list-style-type:none"} - %li - %b Crop name: - = link_to planting.crop.name, planting.crop - %li - %b Days until maturity: - = "#{display_days_before_maturity(planting)}" + .col-xs-3.col-md-4 + %dl + %dt Crop name: + %dd= link_to planting.crop.name, planting.crop + %dt Days until maturity: + %dd= "#{display_days_before_maturity(planting)}" - .col-md-8 - %ul{:style => "list-style-type:none"} - %li= render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file + .col-xs-9.col-md-8 + = render partial: 'plantings/planting_progress', locals: {:planting => planting} \ No newline at end of file From 3ea9f2b5f2f82e999e694c948e34ce12eeaa8afa Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 15:18:39 +0800 Subject: [PATCH 132/392] Applied the responsive planting thumbnail to plantings/index page. --- app/views/plantings/index.html.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 95258e479..cb2796c44 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -20,7 +20,8 @@ - if @plantings.size > 0 - @plantings.each.with_index do |planting| - = render partial: "plantings/thumbnail", locals: {:planting => planting} + .col-xs-12.col-lg-6 + = render partial: "plantings/thumbnail", locals: {:planting => planting} %div.pagination = page_entries_info @plantings, :model => "plantings" From 9eaaa8856fe54998fba0b3c50ecc0f47b9dd154a Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 15:27:34 +0800 Subject: [PATCH 133/392] Added row divs for members/_gardens, gardens/show, planting/index page. --- app/views/gardens/show.html.haml | 14 ++++++++------ app/views/members/_gardens.html.haml | 8 +++++--- app/views/plantings/index.html.haml | 21 +++++++++++---------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index c0feee7eb..59a16db52 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -44,17 +44,19 @@ = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' %h3 What's planted here? - - if @garden.plantings.current.size > 0 - - @garden.plantings.current.each.with_index do |planting_current, index_current| - = render partial: "plantings/thumbnail", locals: {:planting => planting_current} + .row + - if @garden.plantings.current.size > 0 + - @garden.plantings.current.each.with_index do |planting_current, index_current| + = render partial: "plantings/thumbnail", locals: {:planting => planting_current} - else %p Nothing is currently planted here. %h3 Previously planted in this garden - - if @garden.plantings.finished.size > 0 - - @garden.plantings.finished.each.with_index do |planting_finished| - = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} + .row + - if @garden.plantings.finished.size > 0 + - @garden.plantings.finished.each.with_index do |planting_finished| + = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} .col-md-3 %h4 About this garden diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index f5b0deb6e..ddee17d3a 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -34,9 +34,11 @@ = link_to "Add photo", new_photo_path(:type => "garden", :id => g.id), :class => 'btn btn-primary' %h3 What's planted here? - - if g.featured_plantings.size > 0 - - g.featured_plantings.each.with_index do |planting| - = render partial: "plantings/thumbnail", locals: {:planting => planting} + .row + - if g.featured_plantings.size > 0 + - g.featured_plantings.each.with_index do |planting| + .col-xs-12.col-lg-6 + = render partial: "plantings/thumbnail", locals: {:planting => planting} %p = link_to "More about this garden...", url_for(g) diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index cb2796c44..27fed56b3 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -14,18 +14,19 @@ - else = render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" } - %div.pagination - = page_entries_info @plantings, :model => "plantings" - = will_paginate @plantings +%div.pagination + = page_entries_info @plantings, :model => "plantings" + = will_paginate @plantings -- if @plantings.size > 0 - - @plantings.each.with_index do |planting| - .col-xs-12.col-lg-6 - = render partial: "plantings/thumbnail", locals: {:planting => planting} +.row + - if @plantings.size > 0 + - @plantings.each.with_index do |planting| + .col-xs-12.col-lg-6 + = render partial: "plantings/thumbnail", locals: {:planting => planting} - %div.pagination - = page_entries_info @plantings, :model => "plantings" - = will_paginate @plantings +%div.pagination + = page_entries_info @plantings, :model => "plantings" + = will_paginate @plantings %ul.list-inline %li The data on this page is available in the following formats: From 4193e380340bd5ec81d8b715292d32eec728e0fb Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Fri, 10 Jul 2015 15:43:08 +0800 Subject: [PATCH 134/392] Fixed feature test errors on garden/show page. --- app/views/gardens/show.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index 59a16db52..526074e4a 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -44,8 +44,8 @@ = link_to "Add photo", new_photo_path(:type => "garden", :id => @garden.id), :class => 'btn btn-primary' %h3 What's planted here? - .row - - if @garden.plantings.current.size > 0 + - if @garden.plantings.current.size > 0 + .row - @garden.plantings.current.each.with_index do |planting_current, index_current| = render partial: "plantings/thumbnail", locals: {:planting => planting_current} - else @@ -53,8 +53,8 @@ Nothing is currently planted here. %h3 Previously planted in this garden - .row - - if @garden.plantings.finished.size > 0 + - if @garden.plantings.finished.size > 0 + .row - @garden.plantings.finished.each.with_index do |planting_finished| = render partial: "plantings/thumbnail", locals: {:planting => planting_finished} From 2faada7f14ac35aaf24c6d30cd7c1b976506327e Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 10 Jul 2015 17:37:28 +0100 Subject: [PATCH 135/392] Find interesting crops using DB queries --- app/models/crop.rb | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/app/models/crop.rb b/app/models/crop.rb index 2773bbe38..08d4f127f 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -29,6 +29,12 @@ class Crop < ActiveRecord::Base scope :pending_approval, -> { where(:approval_status => "pending") } scope :approved, -> { where(:approval_status => "approved") } scope :rejected, -> { where(:approval_status => "rejected") } + # Crops with enough plantings and photos + # ActiveRecord wizardry copied from + # http://stackoverflow.com/questions/13226913/how-do-i-select-all-records-with-more-than-n-child-records + scope :has_plantings, ->(min_plantings) { select("crops.*").joins(:plantings).group("crops.id").having("count(crops.id) >= ?", min_plantings) } + scope :has_photos, ->(min_photos) { select("crops.*").joins(:photos).group("crops.id").having("count(crops.id) >= ?", min_photos) } + scope :interesting, -> { has_plantings(3).has_photos(3).randomized.limit(12) } ## Wikipedia urls are only necessary when approving a crop validates :en_wikipedia_url, @@ -174,14 +180,6 @@ class Crop < ActiveRecord::Base return popular_plant_parts end - def interesting? - min_plantings = 3 # needs this many plantings to be interesting - min_photos = 3 # needs this many photos to be interesting - return false unless photos.size >= min_photos - return false unless plantings_count >= min_plantings - return true - end - def pending? approval_status == "pending" end @@ -202,19 +200,6 @@ class Crop < ActiveRecord::Base [ "already in database", "not edible", "not enough information", "other" ] end - # Crop.interesting - # returns a list of interesting crops, for use on the homepage etc - def Crop.interesting - howmany = 12 # max number to find - interesting_crops = Array.new - Crop.randomized.each do |c| - break if interesting_crops.size == howmany - next unless c.interesting? - interesting_crops.push(c) - end - return interesting_crops - end - # Crop.create_from_csv(row) # used by db/seeds.rb and rake growstuff:import_crops # CSV fields: From 07c976b1fc2637e3179c415742700f9d4e66ccc1 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 10 Jul 2015 17:54:53 +0100 Subject: [PATCH 136/392] Filter plantings-with-photos in the DB, not Ruby. --- app/models/planting.rb | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index f06ccf9ac..70d65e4d2 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -116,11 +116,13 @@ class Planting < ActiveRecord::Base interesting_plantings = Array.new seen_owners = Hash.new(false) # keep track of which owners we've seen already - Planting.all.each do |p| + if require_photo then + candidates = Planting.joins(:photos).uniq + else + candidates = Planting + end + candidates.each do |p| break if interesting_plantings.size == howmany # got enough yet? - if require_photo - next unless p.photos.present? # skip those without photos, if required - end next if seen_owners[p.owner] # skip if we already have one from this owner seen_owners[p.owner] = true # we've seen this owner interesting_plantings.push(p) From 492bdd915f249790c3d97d22f49ba77a28e335e4 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 10 Jul 2015 18:51:55 +0100 Subject: [PATCH 137/392] Move the rest of Planting.interesting into the DB We could maybe make it a scope at this point... --- app/models/planting.rb | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index 70d65e4d2..e2ce8ee4c 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -113,21 +113,15 @@ class Planting < ActiveRecord::Base # we can't do this via a scope (as far as we know) so sadly we have to # do it this way. def Planting.interesting(howmany=12, require_photo=true) - interesting_plantings = Array.new - seen_owners = Hash.new(false) # keep track of which owners we've seen already - if require_photo then candidates = Planting.joins(:photos).uniq else candidates = Planting end - candidates.each do |p| - break if interesting_plantings.size == howmany # got enough yet? - next if seen_owners[p.owner] # skip if we already have one from this owner - seen_owners[p.owner] = true # we've seen this owner - interesting_plantings.push(p) - end - - return interesting_plantings + # Find the most recent acceptable planting for each member + most_recent_ids = candidates.select("max(plantings.id)") + .unscope(:order) + .group("plantings.owner_id") + return candidates.where(id: most_recent_ids).limit(howmany) end end From 9e7957709d1b239954747eb2163ce0d445c9d95d Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 10 Jul 2015 19:03:18 +0100 Subject: [PATCH 138/392] Remove BUNDLED BY line from Gemfile.lock This keeps getting removed by some automatic process, and it's cluttering up my `git diff` output. --- Gemfile.lock | 3 --- 1 file changed, 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7e3b4aa92..fef7b8258 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,6 +458,3 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) - -BUNDLED WITH - 1.10.3 From fc1dc0e4c37b74258a64d95fb9d286f21bfb757c Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Fri, 10 Jul 2015 19:13:32 +0100 Subject: [PATCH 139/392] Remove unused Planting#interesting? method. --- app/models/planting.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/models/planting.rb b/app/models/planting.rb index e2ce8ee4c..c9ba22398 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -90,10 +90,6 @@ class Planting < ActiveRecord::Base return photos.first end - def interesting? - return photos.present? - end - def calculate_days_before_maturity(planting, crop) p_crop = Planting.where(:crop_id => crop).where.not(:id => planting) differences = p_crop.collect do |p| From 91b5c3e7980aada2e01c0803f5644e871e046225 Mon Sep 17 00:00:00 2001 From: "Jym Paul A. Carandang" Date: Mon, 13 Jul 2015 09:52:05 +0800 Subject: [PATCH 140/392] Added test for signount redirection --- spec/features/signout_spec.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 spec/features/signout_spec.rb diff --git a/spec/features/signout_spec.rb b/spec/features/signout_spec.rb new file mode 100644 index 000000000..00a389069 --- /dev/null +++ b/spec/features/signout_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +feature "signout" do + let(:member){FactoryGirl.create(:member)} + + scenario "redirect to previous page after signout" do + visit crops_path # some random page + click_link 'Sign in' + fill_in 'Login', with: member.login_name + fill_in 'Password', with: member.password + click_button 'Sign in' + click_link 'Sign out' + current_path.should eq crops_path + end + + scenario "after signout, redirect to signin page if page needs authentication" do + models = %w[plantings harvests posts photos gardens seeds] + models.each do |model| + visit "/#{model}/new" + current_path.should eq new_member_session_path + fill_in 'Login', with: member.login_name + fill_in 'Password', with: member.password + click_button 'Sign in' + current_path.should eq "/#{model}/new" + click_link 'Sign out' + current_path.should eq new_member_session_path + end + end + +end From 0816b6b114684103fe4d3c05065394f8ae905d78 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Mon, 13 Jul 2015 10:42:06 +0800 Subject: [PATCH 141/392] Added link to owner's profile from seeds', plantings', and harvests' index --- Gemfile.lock | 3 --- app/views/harvests/index.html.haml | 2 ++ app/views/plantings/index.html.haml | 2 ++ app/views/seeds/index.html.haml | 2 ++ spec/features/harvests/harvesting_a_crop_spec.rb | 6 ++++++ spec/features/plantings/planting_a_crop_spec.rb | 6 ++++++ spec/features/seeds/misc_seeds_spec.rb | 6 ++++++ 7 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7e3b4aa92..fef7b8258 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -458,6 +458,3 @@ DEPENDENCIES unicorn webrat will_paginate (~> 3.0) - -BUNDLED WITH - 1.10.3 diff --git a/app/views/harvests/index.html.haml b/app/views/harvests/index.html.haml index 82281a3af..5d35a40ae 100644 --- a/app/views/harvests/index.html.haml +++ b/app/views/harvests/index.html.haml @@ -1,4 +1,6 @@ - content_for :title, @owner ? "#{@owner}'s harvests" : @crop ? "Everyone's #{@crop.name} harvests" : "Everyone's harvests" +- if @owner + = link_to "View #{@owner}'s profile >>", member_path(@owner) %p #{ENV['GROWSTUFF_SITE_NAME']} helps you track what you're diff --git a/app/views/plantings/index.html.haml b/app/views/plantings/index.html.haml index 27fed56b3..5563ffbfc 100644 --- a/app/views/plantings/index.html.haml +++ b/app/views/plantings/index.html.haml @@ -1,4 +1,6 @@ - content_for :title, @owner ? "#{@owner}'s plantings" : @crop ? "Everyone's #{@crop.name} plantings" : "Everyone's plantings" +- if @owner + = link_to "View #{@owner}'s profile >>", member_path(@owner) %p - if can? :create, Planting diff --git a/app/views/seeds/index.html.haml b/app/views/seeds/index.html.haml index 9ce88690f..0554984de 100644 --- a/app/views/seeds/index.html.haml +++ b/app/views/seeds/index.html.haml @@ -1,4 +1,6 @@ - content_for :title, @owner ? "#{@owner}'s seeds" : @crop ? "Everyone's #{@crop.name} seeds" : "Everyone's seeds" +- if @owner + = link_to "View #{@owner}'s profile >>", member_path(@owner) %p #{ENV['GROWSTUFF_SITE_NAME']} helps you track your seed diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index 8f4cc6e1b..3719164e1 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -26,6 +26,12 @@ feature "Harvesting a crop", :js => true do expect(page).to have_content "Harvest was successfully created" end + scenario "Clicking link to owner's profile" do + visit harvests_by_owner_path(member) + click_link "View #{member}'s profile >>" + current_path.should eq member_path(member) + end + scenario "Harvesting from crop page" do visit crop_path(maize) click_link "Harvest this" diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 531a08b73..808b70880 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -30,6 +30,12 @@ feature "Planting a crop", :js => true do expect(page).to have_content "Progress: 0% - Days before maturity unknown" end + scenario "Clicking link to owner's profile" do + visit plantings_by_owner_path(member) + click_link "View #{member}'s profile >>" + current_path.should eq member_path(member) + end + describe "Progress bar status on planting creation" do before(:each) do DateTime.stub(:now){DateTime.new(2015, 10, 20, 10, 34)} diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 7fc4e32d6..048ef6efb 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -25,6 +25,12 @@ feature "seeds" do page.should have_content 'Add seeds' end + scenario "Clicking link to owner's profile" do + visit plantings_by_owner_path(member) + click_link "View #{member}'s profile >>" + current_path.should eq member_path(member) + end + # actually adding seeds is in spec/features/seeds_new_spec.rb scenario "edit seeds" do From 85e4708b71edc605f9b30c41b09a856fe3758b73 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Thu, 16 Jul 2015 08:06:01 +0800 Subject: [PATCH 142/392] Changed plantings_by_owner_path to seeds_by_owner_path on misc_seeds_spec.rb --- spec/features/seeds/misc_seeds_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 048ef6efb..4c02ceecf 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -26,7 +26,7 @@ feature "seeds" do end scenario "Clicking link to owner's profile" do - visit plantings_by_owner_path(member) + visit seeds_by_owner_path(member) click_link "View #{member}'s profile >>" current_path.should eq member_path(member) end From 41ab646b209ec728736400e4afae6f09f6842825 Mon Sep 17 00:00:00 2001 From: Miles Gould Date: Thu, 16 Jul 2015 23:58:57 +0100 Subject: [PATCH 143/392] Added @manmeetsingh to CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ad76d09fa..b8122dc13 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -54,4 +54,5 @@ submit the change with your pull request. - Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal) - Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) - Savant Krishna / [sksavant](https://github.com/sksavant) +- Manmeet Singh / [manmeetsingh](https://github.com/manmeetsingh) From 7f88b167b49983596b63864e285c505614f40fe2 Mon Sep 17 00:00:00 2001 From: AELOGICA Date: Mon, 29 Jun 2015 15:23:16 +0800 Subject: [PATCH 144/392] Added dynamic adding and removing additional scientific names --- app/assets/javascripts/seeds.js.coffee | 19 ++++++++++++++++++ app/views/alternate_names/_form.html.haml | 7 ++----- app/views/crops/_form.html.haml | 24 +++++++++++------------ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/seeds.js.coffee b/app/assets/javascripts/seeds.js.coffee index ab5b73462..b6a6aefce 100644 --- a/app/assets/javascripts/seeds.js.coffee +++ b/app/assets/javascripts/seeds.js.coffee @@ -4,3 +4,22 @@ jQuery -> $('.add-datepicker').datepicker('format' : 'yyyy-mm-dd') + +$ -> + template = "