diff --git a/.rspec b/.rspec index 4e1e0d2f7..83e16f804 100644 --- a/.rspec +++ b/.rspec @@ -1 +1,2 @@ --color +--require spec_helper diff --git a/.travis.yml b/.travis.yml index af5732a70..dd6853a02 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,37 @@ ---- +sudo: false language: ruby - -env: GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -bundler_args: --without development production staging +cache: bundler +env: + matrix: + - GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + global: + secure: "Z5TpM2jEX4UCvNePnk/LwltQX48U2u9BRc+Iypr1x9QW2o228QJhPIOH39a8RMUrepGnkQIq9q3ZRUn98RfrJz1yThtlNFL3NmzdQ57gKgjGwfpa0e4Dwj/ZJqV2D84tDGjvdVYLP7zzaYZxQcwk/cgNpzKf/jq97HLNP7CYuf4=" +bundler_args: "--without development production staging" rvm: - - 2.1.5 +- 2.1.5 before_script: - - psql -c 'create database growstuff_test;' -U postgres +- psql -c 'create database growstuff_test;' -U postgres script: - - bundle exec rake db:migrate --trace - - bundle exec rspec spec/ +- bundle exec rake db:migrate --trace +- bundle exec rspec spec/ +services: + - elasticsearch +before_deploy: + - bundle exec script/heroku_maintenance.rb on +deploy: + provider: heroku + api_key: + secure: WrQxf0fEKkCdXrjcejurobOnNNz3he4dDwjBbToXbQTQNDObPp7NetJrLsfM8FiUFEeOuvhIHHiDQtMvY720zGGAGxDptvgFS+0QHCUqoTRZA/yFfUmHlG2jROXTzk5uVK0AE4k6Ion5kX8+mM0EnMT/7u+MTFiukrJctSiEXfg= + on: + repo: Growstuff/growstuff + app: + dev: growstuff-staging + travis_deploy: tranquil-basin-3130 + travis_containers: tranquil-basin-3130 + run: + - "rake db:migrate" + - "script/deploy-tasks.sh" + - restart +after_deploy: + - bundle exec script/heroku_maintenance.rb off + diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4b582e92a..71e94bd6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,8 @@ Thanks for contributing to Growstuff! -Please include the following information in your pull request: +When you create a pull request, please include the following: -* A link to the [Pivotal Tracker](http://tracker.growstuff.org/) task to which it relates. +* Mention the issue it solves (eg. #123) * Your code should follow our [Coding style guide](http://wiki.growstuff.org/index.php/Coding_style_guide) * Make sure you have automated tests for your work, where possible. * Add your name (and that of your pair partner, if any) to [CONTRIBUTORS.md](CONTRIBUTORS.md). diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 99b4a1550..11e8e31e5 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -11,10 +11,11 @@ submit the change with your pull request. - Alex Bayley / [Skud](https://github.com/Skud) - Cesy / [cesy](https://github.com/cesy) - Miles Gould / [pozorvlak](https://github.com/pozorvlak) -- Joseph Caudle / [jcaudle](https://github.com/jcaudle) +- Taylor Griffin / [tygriffin](https://github.com/tygriffin) ## Contributors +- Joseph Caudle / [jcaudle](https://github.com/jcaudle) - Ricky Amianym / [amianym](https://github.com/amianym) - Juliet Kemp / [julietk](https://github.com/julietk) - Federico Mena Quintero / [federicomenaquintero](https://github.com/federicomenaquintero) @@ -40,7 +41,6 @@ submit the change with your pull request. - Marty Hines / [martyhines](https://github.com/martyhines) - Amelia Greenhall / [ameliagreenhall](https://github.com/ameliagreenhall) - Barb Natali / [barbnatali](https://github.com/barbnatali) -- Taylor Griffin / [tygriffin](https://github.com/tygriffin) - Marlena Compton / [Marlena](https://github.com/marlena) - Elizabeth A. Kari / [catfriend](https://github.com/catfriend) - Cheri Allen / [cherimarie](https://github.com/cherimarie) @@ -51,5 +51,8 @@ submit the change with your pull request. - Yoong Kang Lim / [yoongkang](https://github.com/yoongkang) - Kevin Yang / [kevieyang](https://github.com/kevieyang) - Justin Hamman / [juzham](https://github.com/juzham) +- Rocky Jaiswal / [rocky-jaiswal](https://github.com/rocky-jaiswal) +- Robert Landreaux / [robertlandreaux](https://github.com/robertlandreaux) +- Savant Krishna / [sksavant](https://github.com/sksavant) - Marlena Compton / [marlena] (https://github/marlena) -- Ryan Dy / [rdy] (https://github/rdy) +- Ryan Dy / [rdy] (https://github/rdy) \ No newline at end of file diff --git a/Gemfile b/Gemfile index 15b665424..eff675b2e 100644 --- a/Gemfile +++ b/Gemfile @@ -1,92 +1,55 @@ source 'https://rubygems.org' -ruby "2.1.5" +ruby '2.1.5' + +gem 'rails', '4.1.9' gem 'bundler', '>=1.1.5' -gem 'rails', '3.2.13' -gem 'rack', '~>1.4.5' -gem 'json', '~>1.7.7' +gem 'sass-rails', '~> 4.0.4' +gem 'coffee-rails', '~> 4.1.0' gem 'haml' + +# Another CSS preprocessor, used for Bootstrap overrides +gem 'less', '~>2.5.0' +gem 'less-rails', '~> 2.5.0' +# CSS framework +gem 'less-rails-bootstrap', '~> 3.2.0' + +gem 'uglifier', '~> 2.5.3' # JavaScript compressor + +gem 'jquery-rails' +gem 'jquery-ui-rails', '~> 5.0.2' +gem 'js-routes' # provides access to Rails routes in Javascript +gem 'flickraw' + gem 'leaflet-rails' gem 'leaflet-markercluster-rails' -gem 'unicorn' # http server - +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 'csv_shaper' # CSV export +gem 'ruby-units' # for unit conversion -gem 'figaro' # for handling config via ENV variables - -gem 'cancan' # for checking member privileges - -gem 'gibbon' # for Mailchimp newsletter subscriptions - -gem 'csv_shaper' # CSV export +gem 'comfortable_mexican_sofa', '~> 1.12.0' # content management system # vendored activemerchant for testing- needed for bogus paypal # gateway monkeypatch gem 'activemerchant', '1.33.0', - :path => 'vendor/gems/activemerchant-1.33.0', + :path => 'vendor/gems/activemerchant-1.33.0', :require => 'active_merchant' gem 'active_utils', '1.0.5', - :path => 'vendor/gems/active_utils-1.0.5' + :path => 'vendor/gems/active_utils-1.0.5' -group :production, :staging do - gem 'newrelic_rpm' - gem 'dalli' - gem 'memcachier' - gem 'rails_12factor' # supresses heroku plugin injection -end - -# Gems used only for assets and not required -# in production environments by default. -group :assets do - # CSS preprocessor, used for app/assets/stylesheets/application.css - gem 'sass-rails', '~> 3.2.3' - # CoffeeScript is a Python-like language that compiles to JavaScript - gem 'coffee-rails', '~> 3.2.1' - - # less-rails depends on a JavaScript engine; we use therubyracer. - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - # long term, we'll probably want node.js for performance, but this will do - # for now as it's easier for new people to install - gem "therubyracer", "~> 0.12", :platforms => :ruby - # libv8 is needed by therubyracer and is a bit finicky - gem 'libv8', '3.16.14.7' - - # Another CSS preprocessor, used for Bootstrap overrides - gem "less", '~>2.5.0' - gem "less-rails", '~> 2.5.0' - # CSS framework - gem "less-rails-bootstrap", '~> 3.2.0' - - gem 'uglifier', '>= 1.0.3' # JavaScript compressor - - gem 'compass-rails', '~> 1.0.3' # Yet Another CSS framework -end - -gem 'jquery-rails' -gem 'jquery-ui-rails' -gem 'js-routes' # provides access to Rails routes in Javascript -gem 'flickraw' - -# To use ActiveModel has_secure_password -# gem 'bcrypt-ruby', '~> 3.0.0' - -# To use Jbuilder templates for JSON -# gem 'jbuilder' - -# Use unicorn as the app server -# gem 'unicorn' - -group :development do - # A debugger and irb alternative. Pry doesn't play nice - # with unicorn, so start a Webrick server when debugging - # with Pry - gem 'pry' - gem 'better_errors' - gem 'binding_of_caller' - gem 'letter_opener' -end +# less-rails depends on a JavaScript engine; we use therubyracer. +# See https://github.com/sstephenson/execjs#readme for more supported runtimes +# long term, we'll probably want node.js for performance, but this will do +# for now as it's easier for new people to install +gem 'therubyracer', '~> 0.12', :platforms => :ruby +# libv8 is needed by therubyracer and is a bit finicky +gem 'libv8', '3.16.14.7' # Markdown formatting for updates etc gem 'bluecloth' @@ -95,10 +58,10 @@ gem 'bluecloth' gem 'will_paginate', '~> 3.0' # user signup/login/etc -gem 'devise', '~> 3.2.0' +gem 'devise', '~> 3.4.1' # nicely formatted URLs -gem 'friendly_id', '~> 4.0.10' +gem 'friendly_id', '~> 5.0.4' # gravatars gem 'gravatar-ultimate' @@ -116,20 +79,51 @@ gem 'omniauth' gem 'omniauth-twitter' gem 'omniauth-flickr', '>= 0.0.15' +# client for Elasticsearch. Elasticsearch is a flexible +# and powerful, distributed, real-time search and analytics engine. +# An example of the use in the project is fuzzy crop search. +gem "elasticsearch-model" +gem "elasticsearch-rails" + gem 'rake', '>= 10.0.0' -group :development, :test do - gem 'byebug' # debugging - gem 'haml-rails' # HTML templating language - gem 'rspec-rails', '~> 2.12.1' # unit testing framework - gem 'database_cleaner', '~> 1.3.0' - gem 'webrat' # provides HTML matchers for view tests - gem 'factory_girl_rails', '~> 4.0' # for creating test data - 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 'i18n-tasks' # adds tests for finding missing and unused translations - gem 'jasmine' - gem 'd3-rails' +group :production, :staging do + gem 'newrelic_rpm' + gem 'dalli' + gem 'memcachier' + gem 'rails_12factor' # supresses heroku plugin injection + gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku +end + +group :development do + # A debugger and irb alternative. Pry doesn't play nice + # with unicorn, so start a Webrick server when debugging + # with Pry + gem 'pry' + gem 'better_errors' + gem 'binding_of_caller' + gem 'letter_opener' + gem 'quiet_assets' +end + +group :development, :test do + gem 'haml-rails' # HTML templating language + gem 'rspec-rails', '~> 3.1.0' # unit testing framework + gem 'rspec-activemodel-mocks' + gem 'byebug' # debugging + gem 'database_cleaner', '~> 1.3.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 + gem 'capybara' # integration tests + gem 'capybara-email' # integration tests for email + gem 'poltergeist', '~> 1.5.1' # for headless JS testing + gem 'i18n-tasks' # adds tests for finding missing and unused translations + gem 'jasmine' # javascript unit testing + gem 'd3-rails' # charting + +end + +group :travis do + gem 'heroku-api' end diff --git a/Gemfile.lock b/Gemfile.lock index 81b04c44b..9521250b2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,35 +20,39 @@ PATH GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.13) - actionpack (= 3.2.13) - mail (~> 2.5.3) - actionpack (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) + actionmailer (4.1.9) + actionpack (= 4.1.9) + actionview (= 4.1.9) + mail (~> 2.5, >= 2.5.4) + actionpack (4.1.9) + actionview (= 4.1.9) + activesupport (= 4.1.9) + rack (~> 1.5.2) + rack-test (~> 0.6.2) + actionview (4.1.9) + activesupport (= 4.1.9) + builder (~> 3.1) erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.5) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.2.1) - activemodel (3.2.13) - activesupport (= 3.2.13) - builder (~> 3.0.0) - activerecord (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activeresource (3.2.13) - activemodel (= 3.2.13) - activesupport (= 3.2.13) - activesupport (3.2.13) - i18n (= 0.6.1) - multi_json (~> 1.0) + active_link_to (1.0.2) + actionpack + activemodel (4.1.9) + activesupport (= 4.1.9) + builder (~> 3.1) + activerecord (4.1.9) + activemodel (= 4.1.9) + activesupport (= 4.1.9) + arel (~> 5.0.0) + activesupport (4.1.9) + i18n (~> 0.6, >= 0.6.9) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.1) + tzinfo (~> 1.1) addressable (2.3.6) - arel (3.0.3) + arel (5.0.1.20140414130214) + autoprefixer-rails (5.1.1) + execjs + json bcrypt (3.1.9) better_errors (2.0.0) coderay (>= 1.0.0) @@ -57,14 +61,19 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) bluecloth (2.2.0) + bonsai-elasticsearch-rails (0.0.4) bootstrap-datepicker-rails (1.3.0.2) railties (>= 3.0) - builder (3.0.4) + bootstrap-sass (3.3.3) + autoprefixer-rails (>= 5.0.0.1) + sass (>= 3.2.19) + bootstrap_form (2.2.0) + builder (3.2.2) byebug (3.5.1) columnize (~> 0.8) debugger-linecache (~> 1.2) slop (~> 3.6) - cancan (1.6.10) + cancancan (1.9.2) capybara (2.4.4) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -74,24 +83,38 @@ GEM capybara-email (2.4.0) capybara (~> 2.4) mail - chunky_png (1.3.3) + climate_control (0.0.3) + activesupport (>= 3.0) cliver (0.3.2) + cocaine (0.5.5) + climate_control (>= 0.0.3, < 1.0) + codemirror-rails (4.8) + railties (>= 3.0, < 5) coderay (1.1.0) - coffee-rails (3.2.2) + coffee-rails (4.1.0) coffee-script (>= 2.2.0) - railties (~> 3.2.0) + railties (>= 4.0.0, < 5.0) coffee-script (2.3.0) coffee-script-source execjs coffee-script-source (1.8.0) - columnize (0.8.9) + columnize (0.9.0) + comfortable_mexican_sofa (1.12.7) + active_link_to (>= 1.0.0) + bootstrap-sass (>= 3.2.0) + bootstrap_form (>= 2.2.0) + codemirror-rails (>= 3.0.0) + coffee-rails (>= 3.1.0) + haml-rails (>= 0.3.0) + jquery-rails (>= 3.0.0) + jquery-ui-rails (>= 5.0.0) + kramdown (>= 1.0.0) + paperclip (>= 4.0.0) + plupload-rails (>= 1.2.1) + rails (>= 4.0.0, < 5) + rails-i18n (>= 4.0.0) + sass-rails (>= 4.0.3) commonjs (0.2.7) - compass (0.12.7) - chunky_png (~> 1.2) - fssm (>= 0.2.7) - sass (~> 3.2.19) - compass-rails (1.0.3) - compass (>= 0.12.2, < 0.14) coveralls (0.7.1) multi_json (~> 1.3) rest-client @@ -106,51 +129,77 @@ GEM database_cleaner (1.3.0) debug_inspector (0.0.2) debugger-linecache (1.2.0) - devise (3.2.4) + devise (3.4.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 3.2.6, < 5) + responders thread_safe (~> 0.1) warden (~> 1.2.3) - diff-lcs (1.1.3) + diff-lcs (1.2.5) docile (1.1.5) easy_translate (0.5.0) json thread thread_safe + elasticsearch (1.0.6) + elasticsearch-api (= 1.0.6) + elasticsearch-transport (= 1.0.6) + elasticsearch-api (1.0.6) + multi_json + elasticsearch-model (0.1.6) + activesupport (> 3) + elasticsearch (> 0.4) + hashie + elasticsearch-rails (0.1.6) + elasticsearch-transport (1.0.6) + faraday + multi_json erubis (2.7.0) + excon (0.43.0) execjs (2.2.2) 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) + multipart-post (>= 1.2, < 3) figaro (1.0.0) thor (~> 0.14) flickraw (0.9.8) - friendly_id (4.0.10.1) - activerecord (>= 3.0, < 4.0) - fssm (0.2.10) + friendly_id (5.0.4) + activerecord (>= 4.0.0) gibbon (1.1.4) httparty multi_json (>= 1.3.4) gravatar-ultimate (2.0.0) activesupport (>= 2.3.14) rack - haml (4.0.5) + haml (4.1.0.beta.1) tilt - haml-rails (0.4) - actionpack (>= 3.1, < 4.1) - activesupport (>= 3.1, < 4.1) - haml (>= 3.1, < 4.1) - railties (>= 3.1, < 4.1) + haml-rails (0.6.0) + actionpack (>= 4.0.1) + activesupport (>= 4.0.1) + haml (>= 3.1, < 5.0) + html2haml (>= 1.0.1) + railties (>= 4.0.1) hashie (3.3.2) + heroku-api (0.3.22) + excon (~> 0.38) + multi_json (~> 1.8) highline (1.6.21) hike (1.2.3) - httparty (0.11.0) - multi_json (~> 1.0) + hpricot (0.8.6) + html2haml (1.0.1) + erubis (~> 2.7.0) + haml (>= 4.0.0.rc.1) + hpricot (~> 0.8.6) + ruby_parser (~> 3.1.1) + httparty (0.13.3) + json (~> 1.8) multi_xml (>= 0.5.2) - i18n (0.6.1) + i18n (0.7.0) i18n-tasks (0.7.8) activesupport easy_translate (>= 0.5.0) @@ -160,6 +209,7 @@ GEM slop (>= 3.5.0) term-ansicolor terminal-table +<<<<<<< HEAD jasmine (2.1.0) jasmine-core (~> 2.1.0) phantomjs @@ -167,16 +217,19 @@ GEM rake jasmine-core (2.1.2) journey (1.0.4) +======= +>>>>>>> dev jquery-rails (3.1.2) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (4.1.2) - railties (>= 3.1.0) + jquery-ui-rails (5.0.3) + railties (>= 3.2.16) js-routes (0.9.9) railties (>= 3.2) sprockets-rails - json (1.7.7) + json (1.8.2) kgio (2.9.2) + kramdown (1.5.0) launchy (2.4.3) addressable (~> 2.3) leaflet-markercluster-rails (0.7.0) @@ -189,20 +242,21 @@ GEM less (~> 2.5.0) less-rails-bootstrap (3.2.0) less-rails (~> 2.5.0) - letter_opener (1.2.0) + letter_opener (1.3.0) launchy (~> 2.2) libv8 (3.16.14.7) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) + mail (2.6.3) + mime-types (>= 1.16, < 3) memcachier (0.0.2) method_source (0.8.2) - mime-types (1.25.1) + mime-types (2.4.3) mini_portile (0.6.1) + minitest (5.5.1) multi_json (1.10.1) multi_xml (0.5.5) - netrc (0.8.0) - newrelic_rpm (3.9.7.266) + multipart-post (2.0.0) + netrc (0.10.0) + newrelic_rpm (3.9.8.273) nokogiri (1.6.5) mini_portile (~> 0.6.0) oauth (0.4.7) @@ -218,82 +272,108 @@ 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) + mime-types pg (0.17.1) +<<<<<<< HEAD phantomjs (1.9.7.1) +======= + plupload-rails (1.2.1) + rails (>= 3.1) +>>>>>>> dev poltergeist (1.5.1) capybara (~> 2.1) cliver (~> 0.3.1) multi_json (~> 1.0) websocket-driver (>= 0.2.0) - polyglot (0.3.5) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) - rack (1.4.5) - rack-cache (1.2) - rack (>= 0.4) - rack-ssl (1.3.4) - rack - rack-test (0.6.2) + quiet_assets (1.1.0) + railties (>= 3.1, < 5.0) + rack (1.5.2) + rack-test (0.6.3) rack (>= 1.0) - rails (3.2.13) - actionmailer (= 3.2.13) - actionpack (= 3.2.13) - activerecord (= 3.2.13) - activeresource (= 3.2.13) - activesupport (= 3.2.13) - bundler (~> 1.0) - railties (= 3.2.13) + 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) + bundler (>= 1.3.0, < 2.0) + railties (= 4.1.9) + sprockets-rails (~> 2.0) + rails-i18n (4.0.3) + i18n (~> 0.6) + 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) - railties (3.2.13) - actionpack (= 3.2.13) - activesupport (= 3.2.13) - rack-ssl (~> 1.3.2) + railties (4.1.9) + actionpack (= 4.1.9) + activesupport (= 4.1.9) rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) + thor (>= 0.18.1, < 2.0) raindrops (0.13.0) - rake (10.4.0) - rdoc (3.12.2) - json (~> 1.4) + rake (10.4.2) 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-core (2.12.2) - rspec-expectations (2.12.1) - diff-lcs (~> 1.1.3) - rspec-mocks (2.12.2) - rspec-rails (2.12.2) + 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) + 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 (~> 2.12.0) - rspec-expectations (~> 2.12.0) - rspec-mocks (~> 2.12.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) + ruby-units (1.4.5) + ruby_parser (3.1.3) + sexp_processor (~> 4.1) sass (3.2.19) - sass-rails (3.2.6) - railties (~> 3.2.0) - sass (>= 3.1.10) - tilt (~> 1.3) + sass-rails (4.0.5) + railties (>= 4.0.0, < 5.0) + sass (~> 3.2.2) + sprockets (~> 2.8, < 3.0) + sprockets-rails (~> 2.0) + sexp_processor (4.4.4) simplecov (0.9.1) docile (~> 1.1.0) multi_json (~> 1.0) simplecov-html (~> 0.8.0) simplecov-html (0.8.0) slop (3.6.0) - sprockets (2.2.3) + sprockets (2.12.3) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (0.0.1) - sprockets (>= 1.0.2) + sprockets-rails (2.2.2) + actionpack (>= 3.0) + activesupport (>= 3.0) + sprockets (>= 2.8, < 4.0) term-ansicolor (1.3.0) tins (~> 1.0) terminal-table (1.4.5) @@ -305,13 +385,11 @@ GEM thread_safe (0.3.4) tilt (1.4.1) tins (1.3.3) - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) - tzinfo (0.3.42) - uglifier (2.2.1) + tzinfo (1.2.2) + thread_safe (~> 0.1) + uglifier (2.5.3) execjs (>= 0.3.0) - multi_json (~> 1.0, >= 1.0.2) + json (>= 1.8.0) unicorn (4.8.3) kgio (~> 2.6) rack @@ -322,7 +400,9 @@ GEM nokogiri (>= 1.2.0) rack (>= 1.0) rack-test (>= 0.5.3) - websocket-driver (0.4.0) + websocket-driver (0.5.0) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.0) will_paginate (3.0.7) xpath (2.0.0) nokogiri (~> 1.3) @@ -336,35 +416,38 @@ DEPENDENCIES better_errors binding_of_caller bluecloth + bonsai-elasticsearch-rails bootstrap-datepicker-rails bundler (>= 1.1.5) byebug - cancan + cancancan (~> 1.9) capybara capybara-email - coffee-rails (~> 3.2.1) - compass-rails (~> 1.0.3) + coffee-rails (~> 4.1.0) + comfortable_mexican_sofa (~> 1.12.0) coveralls csv_shaper d3-rails dalli database_cleaner (~> 1.3.0) - devise (~> 3.2.0) - factory_girl_rails (~> 4.0) + devise (~> 3.4.1) + elasticsearch-model + elasticsearch-rails + factory_girl_rails (~> 4.5.0) figaro flickraw - friendly_id (~> 4.0.10) + friendly_id (~> 5.0.4) geocoder! gibbon gravatar-ultimate haml haml-rails + heroku-api i18n-tasks jasmine jquery-rails - jquery-ui-rails + jquery-ui-rails (~> 5.0.2) js-routes - json (~> 1.7.7) leaflet-markercluster-rails leaflet-rails less (~> 2.5.0) @@ -380,14 +463,16 @@ DEPENDENCIES pg poltergeist (~> 1.5.1) pry - rack (~> 1.4.5) - rails (= 3.2.13) + quiet_assets + rails (= 4.1.9) rails_12factor rake (>= 10.0.0) - rspec-rails (~> 2.12.1) - sass-rails (~> 3.2.3) + rspec-activemodel-mocks + rspec-rails (~> 3.1.0) + ruby-units + sass-rails (~> 4.0.4) therubyracer (~> 0.12) - uglifier (>= 1.0.3) + uglifier (~> 2.5.3) unicorn webrat will_paginate (~> 3.0) diff --git a/README.md b/README.md index b4c49cc9e..f3cfb101b 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,42 @@ encourage participation from people of all backgrounds and skill levels. ## Important links -* [Wiki](http://wiki.growstuff.org/) (general documentation) -* [Task tracker](http://tracker.growstuff.org/) (recent and upcoming work, bugs, etc) +* [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) -## For developers +## For coders + +Growstuff is built in Ruby on Rails and also uses JavaScript for +frontend features. We welcome contributions -- see +[CONTRIBUTING](CONTRIBUTING.md) for details. -* Start by looking at our [task tracker](http://tracker.growstuff.org/) for something to work on. -* Drop in to one of our [discussion forums](http://wiki.growstuff.org/index.php/Discussion_forums) to talk to our team about it. * 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. +* 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. * You may also be interested in our [API](http://wiki.growstuff.org/index.php/API). +## For designers, writers, researchers, data wranglers, and other contributors + +There are heaps of ways to get involved and contribute no matter what +your skills and interests. + +You might like to check out: + +* The [Get Involved](http://wiki.growstuff.org/index.php/Get_involved) + page on our wiki, which has lots of detail for different areas +* [Growstuff Talk](http://talk.growstuff.org/) especially the [Idea category](http://talk.growstuff.org/c/idea) + +Here on Github, you might find these useful: + +* [needs: design](https://github.com/Growstuff/growstuff/labels/needs:%20design) - tasks requiring high-level design +* [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 + +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). diff --git a/app/assets/images/facebook_32.png b/app/assets/images/facebook_32.png index 1b65634c2..4339f6b5a 100644 Binary files a/app/assets/images/facebook_32.png and b/app/assets/images/facebook_32.png differ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b0ddef510..400a71296 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -15,7 +15,7 @@ //= require js-routes //= require jquery //= require jquery_ujs -//= require jquery.ui.autocomplete +//= require jquery-ui/autocomplete //= require twitter/bootstrap //= require_tree . -//= require bootstrap-datepicker \ No newline at end of file +//= require bootstrap-datepicker diff --git a/app/assets/javascripts/comfy/admin/cms/custom.js.coffee b/app/assets/javascripts/comfy/admin/cms/custom.js.coffee new file mode 100644 index 000000000..d40d4c9c3 --- /dev/null +++ b/app/assets/javascripts/comfy/admin/cms/custom.js.coffee @@ -0,0 +1 @@ +# Custom JS for the admin area \ No newline at end of file diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 98c343be5..c9c1a79d1 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -3,7 +3,7 @@ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at * the top of the compiled file, but it's generally better to create a new file per style scope. *= require_self - *= require jquery.ui.autocomplete + *= require jquery-ui/autocomplete *= require bootstrap-datepicker *= require leaflet *= require leaflet.markercluster diff --git a/app/assets/stylesheets/comfy/admin/cms/custom.sass b/app/assets/stylesheets/comfy/admin/cms/custom.sass new file mode 100644 index 000000000..328d897f1 --- /dev/null +++ b/app/assets/stylesheets/comfy/admin/cms/custom.sass @@ -0,0 +1 @@ +// custom CSS for admin area \ No newline at end of file diff --git a/app/assets/stylesheets/overrides.css.less b/app/assets/stylesheets/overrides.css.less index e08579efb..679e48f7d 100644 --- a/app/assets/stylesheets/overrides.css.less +++ b/app/assets/stylesheets/overrides.css.less @@ -122,7 +122,7 @@ p.stats { color: @brown; } -.crop-thumbnail { +.photo-thumbnail { position:relative; padding:0; img { @@ -149,33 +149,55 @@ p.stats { } } -.member-thumbnail { - img { - height: 85px; - width: 85px; - max-width: 85px - } -} .thumbnail { + border: none; + text-align: center; margin-bottom: 1.5em; - - .scientific-name small, .crop-name a { - display: inline-block; - max-width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - line-height: 1em; - padding-bottom: 2px; + + .member-thumbnail { + text-align: left; + img { + height: 85px; + width: 85px; + max-width: 85px + } } - .crop-name a { - padding-top: 2px; - } + .crop-thumbnail { + height: 220px; + .cropinfo { + display: inline-block; + max-width: 100%; + white-space: nowrap; + line-height: 1em; + padding-bottom: 2px; - .scientific-name small { - margin-bottom: -2px; + .cropname { + overflow: hidden; + text-overflow: ellipsis; + } + + .scientificname { + font-size: small; + font-style: italic; + overflow: hidden; + text-overflow: ellipsis; + } + + .plantingcount { + font-size: small; + } + } + + + .crop-name a { + padding-top: 2px; + } + + .scientific-name small { + margin-bottom: -2px; + } } } @@ -192,31 +214,48 @@ li.crop-hierarchy { margin: 40px 0px 0px 0px !important; } -// navbar centering -footer .navbar .nav { - float: none; - display: inline-block; - *display: inline; - /* ie7 fix */ - *zoom: 1; - /* hasLayout ie7 trigger */ - vertical-align: top; - > li { - float: none; - display: inline-block; - *display: inline; - /* ie7 fix */ - *zoom: 1; - /* hasLayout ie7 trigger */ - vertical-align: top; +// footer + +footer { + #contact, #about-growstuff, #policies { + text-align: left; + padding-top: 1em; + padding-bottom: 2em; + ul { + list-style-type: none; + list-style-position: outside; + padding-left: 0px; + margin-left: 0px; + } + a { + color: @navbar-default-link-color; + text-decoration: none; + } + a:hover { + color: @navbar-default-link-hover-color; + } + a:active { + color: @navbar-default-link-active-color; + } + } + + .navbar-bottom.navbar { + border-radius: 0; } } -.navbar-bottom.navbar { - text-align: center; - border-radius: 0; +// ensure footer is pushed to bottom of browser window + +#maincontainer { + min-height: 80%; } +html, body { + height: 100%; +} + +// + .crop-image, .member-image { width: 100%; height: 100%; @@ -244,6 +283,12 @@ footer .navbar .nav { text-decoration: underline; } +.alert { + a { + font-weight: 800; + } +} + // Overrides applying only to mobile view. This must be at the end of the overrides file. @media only screen and (max-width: 767px) { @@ -261,3 +306,13 @@ footer .navbar .nav { display: block; } } + +/* override "info" alert boxes to be green, not blue, on Growstuff */ +@state-info-text: darken(@green, 10%); +@state-info-bg: lighten(@green, 50%); + +/* and set "success" to be the same, as it was just very slightly + * different because the default bootstrap green is slightly different + * from ours */ +@state-success-text: darken(@green, 10%); +@state-success-bg: lighten(@green, 50%); diff --git a/app/controllers/account_types_controller.rb b/app/controllers/account_types_controller.rb index ce448ceba..4c3da9080 100644 --- a/app/controllers/account_types_controller.rb +++ b/app/controllers/account_types_controller.rb @@ -36,7 +36,7 @@ class AccountTypesController < ApplicationController # POST /account_types def create - @account_type = AccountType.new(params[:account_type]) + @account_type = AccountType.new(account_type_params) respond_to do |format| if @account_type.save @@ -52,7 +52,7 @@ class AccountTypesController < ApplicationController @account_type = AccountType.find(params[:id]) respond_to do |format| - if @account_type.update_attributes(params[:account_type]) + if @account_type.update(account_type_params) format.html { redirect_to @account_type, notice: 'Account type was successfully updated.' } else format.html { render action: "edit" } @@ -69,4 +69,10 @@ class AccountTypesController < ApplicationController format.html { redirect_to account_types_url, notice: 'Account type was successfully deleted.' } end end + + private + + def account_type_params + params.require(:account_type).permit(:is_paid, :is_permanent_paid, :name) + end end diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index c163e0ffc..cdfcc2d00 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -30,7 +30,7 @@ class AccountsController < ApplicationController @account = Account.find(params[:id]) respond_to do |format| - if @account.update_attributes(params[:account]) + if @account.update(params[:account]) format.html { redirect_to @account, notice: 'Account detail was successfully updated.' } else format.html { render action: "edit" } @@ -38,4 +38,10 @@ class AccountsController < ApplicationController end end + private + + def account_params + params.require(:account).permit(:account_type_id, :member_id, :paid_until) + end + end diff --git a/app/controllers/alternate_names_controller.rb b/app/controllers/alternate_names_controller.rb index 21cb294a0..f75f8e442 100644 --- a/app/controllers/alternate_names_controller.rb +++ b/app/controllers/alternate_names_controller.rb @@ -45,7 +45,7 @@ class AlternateNamesController < ApplicationController # POST /alternate_names.json def create params[:alternate_name][:creator_id] = current_member.id - @alternate_name = AlternateName.new(params[:alternate_name]) + @alternate_name = AlternateName.new(alternate_name_params) respond_to do |format| if @alternate_name.save @@ -64,7 +64,7 @@ class AlternateNamesController < ApplicationController @alternate_name = AlternateName.find(params[:id]) respond_to do |format| - if @alternate_name.update_attributes(params[:alternate_name]) + if @alternate_name.update(alternate_name_params) format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' } format.json { head :no_content } else @@ -88,4 +88,10 @@ class AlternateNamesController < ApplicationController format.json { head :no_content } end end + + private + + def alternate_name_params + params.require(:alternate_name).permit(:crop_id, :name, :creator_id) + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index e417984fa..9dd23395c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -43,4 +43,36 @@ class ApplicationController < ActionController::Base I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil end + before_action :configure_permitted_parameters, if: :devise_controller? + + protected + + def configure_permitted_parameters + devise_parameter_sanitizer.for(:sign_up) do |member| + member.permit(:login_name, :email, :password, :password_confirmation, + :remember_me, :login, + # terms of service + :tos_agreement, + # profile stuff + :bio, :location, :latitude, :longitude, + # email settings + :show_email, :newsletter, :send_notification_email, :send_planting_reminder + ) + end + + devise_parameter_sanitizer.for(:account_update) do |member| + member.permit(:login_name, :email, :password, :password_confirmation, + :remember_me, :login, + # terms of service + :tos_agreement, + # profile stuff + :bio, :location, :latitude, :longitude, + # email settings + :show_email, :newsletter, :send_notification_email, :send_planting_reminder, + #update password + :current_password + ) + end + end + end diff --git a/app/controllers/authentications_controller.rb b/app/controllers/authentications_controller.rb index 898310a3b..9a873bebb 100644 --- a/app/controllers/authentications_controller.rb +++ b/app/controllers/authentications_controller.rb @@ -2,15 +2,6 @@ class AuthenticationsController < ApplicationController before_filter :authenticate_member! load_and_authorize_resource - # GET /authentications - def index - @authentications = current_member.authentications if member_signed_in? - - respond_to do |format| - format.html # index.html.erb - end - end - # POST /authentications def create auth = request.env['omniauth.auth'] @@ -27,12 +18,17 @@ class AuthenticationsController < ApplicationController name = auth['info']['name'] end - @authentication = current_member.authentications.find_or_create_by_provider_and_uid( - :provider => auth['provider'], - :uid => auth['uid'], + @authentication = current_member.authentications + .create_with( :name => name, :token => auth['credentials']['token'], - :secret => auth['credentials']['secret']) + :secret => auth['credentials']['secret'] + ) + .find_or_create_by( + :provider => auth['provider'], + :uid => auth['uid'], + :name => name) + flash[:notice] = "Authentication successful." else flash[:notice] = "Authentication failed." diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index a24b4fed3..0caac18ed 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -2,8 +2,6 @@ class CommentsController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - cache_sweeper :comment_sweeper - # GET /comments # GET /comments.json def index @@ -55,11 +53,11 @@ class CommentsController < ApplicationController # POST /comments.json def create params[:comment][:author_id] = current_member.id - @comment = Comment.new(params[:comment]) + @comment = Comment.new(comment_params) respond_to do |format| if @comment.save - format.html { redirect_to @comment.post, notice: 'Comment was successfully created.' } + format.html { redirect_to @comment.post, notice: "Comment was successfully created." } format.json { render json: @comment, status: :created, location: @comment } else format.html { render action: "new" } @@ -79,7 +77,7 @@ class CommentsController < ApplicationController params[:comment].delete("author_id") respond_to do |format| - if @comment.update_attributes(params[:comment]) + if @comment.update(comment_params) format.html { redirect_to @comment.post, notice: 'Comment was successfully updated.' } format.json { head :no_content } else @@ -101,4 +99,10 @@ class CommentsController < ApplicationController format.json { head :no_content } end end + + private + + def comment_params + params.require(:comment).permit(:author_id, :body, :post_id) + end end diff --git a/app/controllers/crops_controller.rb b/app/controllers/crops_controller.rb index be4eccc2e..fc0ce9bb5 100644 --- a/app/controllers/crops_controller.rb +++ b/app/controllers/crops_controller.rb @@ -3,18 +3,18 @@ class CropsController < ApplicationController load_and_authorize_resource skip_authorize_resource :only => [:hierarchy, :search] - cache_sweeper :crop_sweeper - # GET /crops # GET /crops.json def index @sort = params[:sort] if @sort == 'alpha' # alphabetical order - @crops = Crop.includes(:scientific_names, {:plantings => :photos}).paginate(:page => params[:page]) + @crops = Crop.includes(:scientific_names, {:plantings => :photos}) + @paginated_crops = @crops.paginate(:page => params[:page]) else # default to sorting by popularity - @crops = Crop.popular.includes(:scientific_names, {:plantings => :photos}).paginate(:page => params[:page]) + @crops = Crop.popular.includes(:scientific_names, {:plantings => :photos}) + @paginated_crops = @crops.paginate(:page => params[:page]) end respond_to do |format| @@ -34,7 +34,18 @@ class CropsController < ApplicationController # GET /crops/wrangle def wrangle - @crops = Crop.recent.paginate(:page => params[:page]) + @approval_status = params[:approval_status] + case @approval_status + when "pending" + @crops = Crop.pending_approval + when "rejected" + @crops = Crop.rejected + else + @crops = Crop.recent + end + + @crops = @crops.paginate(:page => params[:page]) + @crop_wranglers = Role.crop_wranglers respond_to do |format| format.html @@ -52,17 +63,17 @@ class CropsController < ApplicationController # GET /crops/search def search @search = params[:search] - @exact_match = Crop.find_by_name(params[:search]) - - @partial_matches = Crop.search(params[:search]) - # exclude exact match from partial match list - @partial_matches.reject!{ |r| @exact_match && r.eql?(@exact_match) } - - @fuzzy = Crop.search(params[:term]) + @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 respond_to do |format| format.html - format.json { render :json => @fuzzy } + format.json { render :json => Crop.search(@search) } end end @@ -98,17 +109,35 @@ class CropsController < ApplicationController # GET /crops/1/edit def edit @crop = Crop.find(params[:id]) + + (3 - @crop.scientific_names.length).times do + @crop.scientific_names.build + end end # POST /crops # POST /crops.json def create - params[:crop][:creator_id] = current_member.id - @crop = Crop.new(params[:crop]) + @crop = Crop.new(crop_params) + + if current_member.has_role? :crop_wrangler + @crop.creator = current_member + success_msg = "Crop was successfully created." + else + @crop.requester = current_member + @crop.approval_status = "pending" + success_msg = "Crop was successfully requested." + end respond_to do |format| if @crop.save - format.html { redirect_to @crop, notice: 'Crop was successfully created.' } + unless current_member.has_role? :crop_wrangler + Role.crop_wranglers.each do |w| + Notifier.new_crop_request(w, @crop).deliver! + end + end + + format.html { redirect_to @crop, notice: success_msg } format.json { render json: @crop, status: :created, location: @crop } else format.html { render action: "new" } @@ -122,8 +151,18 @@ class CropsController < ApplicationController def update @crop = Crop.find(params[:id]) + previous_status = @crop.approval_status + + @crop.creator = current_member if previous_status == "pending" + respond_to do |format| - if @crop.update_attributes(params[:crop]) + if @crop.update(crop_params) + if previous_status == "pending" + requester = @crop.requester + new_status = @crop.approval_status + Notifier.crop_request_approved(requester, @crop).deliver! if new_status == "approved" + Notifier.crop_request_rejected(requester, @crop).deliver! if new_status == "rejected" + end format.html { redirect_to @crop, notice: 'Crop was successfully updated.' } format.json { head :no_content } else @@ -144,4 +183,10 @@ class CropsController < ApplicationController format.json { head :no_content } end end + + 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]) + end end diff --git a/app/controllers/follows_controller.rb b/app/controllers/follows_controller.rb index d6e38c81f..b5a0b48ab 100644 --- a/app/controllers/follows_controller.rb +++ b/app/controllers/follows_controller.rb @@ -1,8 +1,12 @@ class FollowsController < ApplicationController + before_filter :authenticate_member! + load_and_authorize_resource + skip_load_resource :only => :create # POST /follows def create - @follow = current_member.follows.build(:followed_id => params[:followed_id]) + + @follow = current_member.follows.build(:followed_id => follow_params[:followed_id]) if @follow.save flash[:notice] = "Followed #{ @follow.followed.login_name }" @@ -15,11 +19,17 @@ class FollowsController < ApplicationController # DELETE /follows/1 def destroy - @follow = current_member.follows.find(params[:id]) + @follow = current_member.follows.find(follow_params[:id]) unfollowed_name = @follow.followed.login_name @follow.destroy flash[:notice] = "Unfollowed #{ unfollowed_name }" redirect_to root_path end + + private + + def follow_params + params.permit(:id, :followed_id, :follower_id, :authenticity_token, :_method) + end end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index b77939111..132924edc 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -1,8 +1,6 @@ class ForumsController < ApplicationController load_and_authorize_resource - cache_sweeper :forum_sweeper - # GET /forums # GET /forums.json def index @@ -44,7 +42,7 @@ class ForumsController < ApplicationController # POST /forums # POST /forums.json def create - @forum = Forum.new(params[:forum]) + @forum = Forum.new(forum_params) respond_to do |format| if @forum.save @@ -63,7 +61,7 @@ class ForumsController < ApplicationController @forum = Forum.find(params[:id]) respond_to do |format| - if @forum.update_attributes(params[:forum]) + if @forum.update(forum_params) format.html { redirect_to @forum, notice: 'Forum was successfully updated.' } format.json { head :no_content } else @@ -84,4 +82,10 @@ class ForumsController < ApplicationController format.json { head :no_content } end end + + private + + def forum_params + params.require(:forum).permit(:description, :name, :owner_id, :slug) + end end diff --git a/app/controllers/gardens_controller.rb b/app/controllers/gardens_controller.rb index dd3d56542..f2ce6103a 100644 --- a/app/controllers/gardens_controller.rb +++ b/app/controllers/gardens_controller.rb @@ -1,8 +1,7 @@ class GardensController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - - cache_sweeper :garden_sweeper + # GET /gardens # GET /gardens.json @@ -50,12 +49,13 @@ class GardensController < ApplicationController # POST /gardens.json def create params[:garden][:owner_id] = current_member.id - @garden = Garden.new(params[:garden]) + @garden = Garden.new(garden_params) respond_to do |format| if @garden.save format.html { redirect_to @garden, notice: 'Garden was successfully created.' } format.json { render json: @garden, status: :created, location: @garden } + expire_fragment("homepage_stats") else format.html { render action: "new" } format.json { render json: @garden.errors, status: :unprocessable_entity } @@ -69,7 +69,7 @@ class GardensController < ApplicationController @garden = Garden.find(params[:id]) respond_to do |format| - if @garden.update_attributes(params[:garden]) + if @garden.update(garden_params) format.html { redirect_to @garden, notice: 'Garden was successfully updated.' } format.json { head :no_content } else @@ -84,10 +84,18 @@ class GardensController < ApplicationController def destroy @garden = Garden.find(params[:id]) @garden.destroy + 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.json { head :no_content } end end + + private + + def garden_params + params.require(:garden).permit(:name, :slug, :owner_id, :description, :active, + :location, :latitude, :longitude, :area, :area_unit) + end end diff --git a/app/controllers/harvests_controller.rb b/app/controllers/harvests_controller.rb index a51ee574e..4bc3a5d90 100644 --- a/app/controllers/harvests_controller.rb +++ b/app/controllers/harvests_controller.rb @@ -20,7 +20,7 @@ class HarvestsController < ApplicationController format.html { @harvests = @harvests.paginate(:page => params[:page]) } format.json { render json: @harvests } format.csv do - specifics = (@owner ? "#{@owner.name}-" : @crop ? "#{@crop.name}-" : nil) + specifics = (@owner ? "#{@owner.login_name}-" : @crop ? "#{@crop.name}-" : nil) @filename = "Growstuff-#{specifics}Harvests-#{Time.zone.now.to_s(:number)}.csv" render :csv => @harvests end @@ -62,7 +62,7 @@ class HarvestsController < ApplicationController def create params[:harvest][:owner_id] = current_member.id params[:harvested_at] = parse_date(params[:harvested_at]) - @harvest = Harvest.new(params[:harvest]) + @harvest = Harvest.new(harvest_params) respond_to do |format| if @harvest.save @@ -81,7 +81,7 @@ class HarvestsController < ApplicationController @harvest = Harvest.find(params[:id]) respond_to do |format| - if @harvest.update_attributes(params[:harvest]) + if @harvest.update(harvest_params) format.html { redirect_to @harvest, notice: 'Harvest was successfully updated.' } format.json { head :no_content } else @@ -102,4 +102,11 @@ class HarvestsController < ApplicationController format.json { head :no_content } end end + + private + + def harvest_params + params.require(:harvest).permit(:crop_id, :harvested_at, :description, :owner_id, + :quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug, :si_weight) + end end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index ac53f4194..744e93f4c 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -1,12 +1,17 @@ class MembersController < ApplicationController load_and_authorize_resource - cache_sweeper :member_sweeper - skip_authorize_resource :only => :nearby + after_action :expire_cache_fragments, :only => :create + def index - @members = Member.confirmed.paginate(:page => params[:page]) + @sort = params[:sort] + if @sort == 'recently_joined' + @members = Member.confirmed.recently_joined.paginate(:page => params[:page]) + else + @members = Member.confirmed.paginate(:page => params[:page]) + end respond_to do |format| format.html # index.html.haml @@ -44,4 +49,10 @@ class MembersController < ApplicationController @followers = @member.followers.paginate(:page => params[:page]) end + private + + def expire_cache_fragments + expire_fragment("homepage_stats") + end + end diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index a5905d088..3d3a217ad 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.find_all_by_recipient_id(current_member) + @notifications = Notification.where(recipient_id: current_member) respond_to do |format| format.html # index.html.erb @@ -49,7 +49,7 @@ class NotificationsController < ApplicationController # POST /notifications def create params[:notification][:sender_id] = current_member.id - @notification = Notification.new(params[:notification]) + @notification = Notification.new(notification_params) @recipient = Member.find_by_id(params[:notification][:recipient_id]) respond_to do |format| @@ -60,4 +60,10 @@ class NotificationsController < ApplicationController end end end + + private + + def notification_params + params.require(:notification).permit(:sender_id, :recipient_id, :subject, :body, :post_id, :read) + end end diff --git a/app/controllers/order_items_controller.rb b/app/controllers/order_items_controller.rb index d9c072b28..37a7e7b74 100644 --- a/app/controllers/order_items_controller.rb +++ b/app/controllers/order_items_controller.rb @@ -7,7 +7,7 @@ class OrderItemsController < ApplicationController if params[:order_item][:price] params[:order_item][:price] = params[:order_item][:price].to_f * 100 # convert to cents end - @order_item = OrderItem.new(params[:order_item]) + @order_item = OrderItem.new(order_item_params) @order_item.order = current_member.current_order || Order.create(:member_id => current_member.id) respond_to do |format| @@ -20,4 +20,10 @@ class OrderItemsController < ApplicationController end end end + + private + + def order_item_params + params.require(:order_item).permit(:order_id, :price, :product_id, :quantity) + end end diff --git a/app/controllers/orders_controller.rb b/app/controllers/orders_controller.rb index 7ee0b5a56..3cc4caa9c 100644 --- a/app/controllers/orders_controller.rb +++ b/app/controllers/orders_controller.rb @@ -4,7 +4,7 @@ class OrdersController < ApplicationController # GET /orders def index - @orders = Order.find_all_by_member_id(current_member.id) + @orders = Order.where(member_id: current_member.id) respond_to do |format| format.html # index.html.erb diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index c745f403d..63672efe1 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -1,8 +1,6 @@ class PhotosController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - - cache_sweeper :photo_sweeper # GET /photos # GET /photos.json @@ -61,13 +59,13 @@ class PhotosController < ApplicationController # POST /photos.json def create @photo = Photo.find_by_flickr_photo_id(params[:photo][:flickr_photo_id]) || - Photo.new(params[:photo]) + Photo.new(photo_params) @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"] + valid_models = ["planting", "harvest", "garden"] if params[:type] if valid_models.include?(params[:type]) if params[:id] @@ -111,7 +109,7 @@ class PhotosController < ApplicationController @photo = Photo.find(params[:id]) respond_to do |format| - if @photo.update_attributes(params[:photo]) + if @photo.update(photo_params) format.html { redirect_to @photo, notice: 'Photo was successfully updated.' } format.json { head :no_content } else @@ -132,4 +130,11 @@ class PhotosController < ApplicationController format.json { head :no_content } end end + + private + + def photo_params + params.require(:photo).permit(:flickr_photo_id, :owner_id, :title, :license_name, + :license_url, :thumbnail_url, :fullsize_url, :link_url) + end end diff --git a/app/controllers/plant_parts_controller.rb b/app/controllers/plant_parts_controller.rb index f27f0ead3..ed67926c7 100644 --- a/app/controllers/plant_parts_controller.rb +++ b/app/controllers/plant_parts_controller.rb @@ -42,7 +42,7 @@ class PlantPartsController < ApplicationController # POST /plant_parts # POST /plant_parts.json def create - @plant_part = PlantPart.new(params[:plant_part]) + @plant_part = PlantPart.new(plant_part_params) respond_to do |format| if @plant_part.save @@ -61,7 +61,7 @@ class PlantPartsController < ApplicationController @plant_part = PlantPart.find(params[:id]) respond_to do |format| - if @plant_part.update_attributes(params[:plant_part]) + if @plant_part.update(plant_part_params) format.html { redirect_to @plant_part, notice: 'Plant part was successfully updated.' } format.json { head :no_content } else @@ -82,4 +82,10 @@ class PlantPartsController < ApplicationController format.json { head :no_content } end end + + private + + def plant_part_params + params.require(:plant_part).permit(:name, :slug) + end end diff --git a/app/controllers/plantings_controller.rb b/app/controllers/plantings_controller.rb index c9086307e..9fdefc388 100644 --- a/app/controllers/plantings_controller.rb +++ b/app/controllers/plantings_controller.rb @@ -1,9 +1,6 @@ class PlantingsController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - - - cache_sweeper :planting_sweeper # GET /plantings # GET /plantings.json @@ -33,7 +30,7 @@ class PlantingsController < ApplicationController # GET /plantings/1 # GET /plantings/1.json def show - @planting = Planting.includes(:owner, :crop, :garden, :photos).find(params[:id]) + @planting = Planting.includes(:owner, :crop, :garden, :photos).friendly.find(params[:id]) respond_to do |format| format.html # show.html.erb @@ -68,14 +65,15 @@ class PlantingsController < ApplicationController # POST /plantings # POST /plantings.json def create - params[:planting][:owner_id] = current_member.id params[:planted_at] = parse_date(params[:planted_at]) - @planting = Planting.new(params[:planting]) + @planting = Planting.new(planting_params) + @planting.owner = current_member respond_to do |format| if @planting.save format.html { redirect_to @planting, notice: 'Planting was successfully created.' } format.json { render json: @planting, status: :created, location: @planting } + expire_fragment("homepage_stats") else format.html { render action: "new" } format.json { render json: @planting.errors, status: :unprocessable_entity } @@ -90,7 +88,7 @@ class PlantingsController < ApplicationController params[:planted_at] = parse_date(params[:planted_at]) respond_to do |format| - if @planting.update_attributes(params[:planting]) + if @planting.update(planting_params) format.html { redirect_to @planting, notice: 'Planting was successfully updated.' } format.json { head :no_content } else @@ -106,10 +104,19 @@ class PlantingsController < ApplicationController @planting = Planting.find(params[:id]) @garden = @planting.garden @planting.destroy + expire_fragment("homepage_stats") respond_to do |format| format.html { redirect_to @garden } format.json { head :no_content } end end + + private + + def planting_params + params.require(:planting).permit(:crop_id, :description, :garden_id, :planted_at, + :quantity, :sunniness, :planted_from, :owner_id, :finished, + :finished_at) + end end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index d36a809ae..ceb4730cc 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -2,8 +2,6 @@ class PostsController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - cache_sweeper :post_sweeper - # GET /posts # GET /posts.json @@ -58,7 +56,7 @@ class PostsController < ApplicationController # POST /posts.json def create params[:post][:author_id] = current_member.id - @post = Post.new(params[:post]) + @post = Post.new(post_params) respond_to do |format| if @post.save @@ -77,7 +75,7 @@ class PostsController < ApplicationController @post = Post.find(params[:id]) respond_to do |format| - if @post.update_attributes(params[:post]) + if @post.update(post_params) format.html { redirect_to @post, notice: 'Post was successfully updated.' } format.json { head :no_content } else @@ -98,4 +96,10 @@ class PostsController < ApplicationController format.json { head :no_content } end end + + private + + def post_params + params.require(:post).permit(:body, :subject, :author_id, :forum_id) + end end diff --git a/app/controllers/products_controller.rb b/app/controllers/products_controller.rb index 41754199b..1ed69703f 100644 --- a/app/controllers/products_controller.rb +++ b/app/controllers/products_controller.rb @@ -36,7 +36,7 @@ class ProductsController < ApplicationController # POST /products def create - @product = Product.new(params[:product]) + @product = Product.new(product_params) respond_to do |format| if @product.save @@ -52,7 +52,7 @@ class ProductsController < ApplicationController @product = Product.find(params[:id]) respond_to do |format| - if @product.update_attributes(params[:product]) + if @product.update(product_params) format.html { redirect_to @product, notice: 'Product was successfully updated.' } else format.html { render action: "edit" } @@ -69,4 +69,11 @@ class ProductsController < ApplicationController format.html { redirect_to products_url } end end + + private + + def product_params + params.require(:product).permit(:description, :min_price, :recommended_price, :name, + :account_type_id, :paid_months) + end end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 50eccef0c..c4883bd4d 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -1,7 +1,5 @@ class RegistrationsController < Devise::RegistrationsController - cache_sweeper :member_sweeper - def edit @twitter_auth = current_member.auth('twitter') @flickr_auth = current_member.auth('flickr') diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 8aecf5c2a..c932d75ae 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -36,7 +36,7 @@ class RolesController < ApplicationController # POST /roles def create - @role = Role.new(params[:role]) + @role = Role.new(role_params) respond_to do |format| if @role.save @@ -52,7 +52,7 @@ class RolesController < ApplicationController @role = Role.find(params[:id]) respond_to do |format| - if @role.update_attributes(params[:role]) + if @role.update(role_params) format.html { redirect_to @role, notice: 'Role was successfully updated.' } else format.html { render action: "edit" } @@ -69,4 +69,10 @@ class RolesController < ApplicationController format.html { redirect_to roles_url } end end + + private + + def role_params + params.require(:role).permit(:description, :name, :members, :slug) + end end diff --git a/app/controllers/scientific_names_controller.rb b/app/controllers/scientific_names_controller.rb index 1a727f715..511a96279 100644 --- a/app/controllers/scientific_names_controller.rb +++ b/app/controllers/scientific_names_controller.rb @@ -2,8 +2,6 @@ class ScientificNamesController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - cache_sweeper :scientific_name_sweeper - # GET /scientific_names # GET /scientific_names.json def index @@ -47,7 +45,7 @@ class ScientificNamesController < ApplicationController # POST /scientific_names.json def create params[:scientific_name][:creator_id] = current_member.id - @scientific_name = ScientificName.new(params[:scientific_name]) + @scientific_name = ScientificName.new(scientific_name_params) respond_to do |format| if @scientific_name.save @@ -66,7 +64,7 @@ class ScientificNamesController < ApplicationController @scientific_name = ScientificName.find(params[:id]) respond_to do |format| - if @scientific_name.update_attributes(params[:scientific_name]) + if @scientific_name.update(scientific_name_params) format.html { redirect_to @scientific_name.crop, notice: 'Scientific name was successfully updated.' } format.json { head :no_content } else @@ -90,4 +88,10 @@ class ScientificNamesController < ApplicationController format.json { head :no_content } end end + + private + + def scientific_name_params + params.require(:scientific_name).permit(:crop_id, :scientific_name, :creator_id) + end end diff --git a/app/controllers/seeds_controller.rb b/app/controllers/seeds_controller.rb index d1205dab7..a2e79afaf 100644 --- a/app/controllers/seeds_controller.rb +++ b/app/controllers/seeds_controller.rb @@ -2,8 +2,6 @@ class SeedsController < ApplicationController before_filter :authenticate_member!, :except => [:index, :show] load_and_authorize_resource - cache_sweeper :seed_sweeper - # GET /seeds # GET /seeds.json def index @@ -68,7 +66,7 @@ class SeedsController < ApplicationController # POST /seeds.json def create params[:seed][:owner_id] = current_member.id - @seed = Seed.new(params[:seed]) + @seed = Seed.new(seed_params) respond_to do |format| if @seed.save @@ -87,7 +85,7 @@ class SeedsController < ApplicationController @seed = Seed.find(params[:id]) respond_to do |format| - if @seed.update_attributes(params[:seed]) + if @seed.update(seed_params) format.html { redirect_to @seed, notice: 'Seed was successfully updated.' } format.json { head :no_content } else @@ -108,4 +106,13 @@ class SeedsController < ApplicationController format.json { head :no_content } end end + + private + + def seed_params + params.require(:seed).permit( + :owner_id, :crop_id, :description, :quantity, :plant_before, + :days_until_maturity_min, :days_until_maturity_max, :organic, :gmo, + :heirloom, :tradable_to, :slug) + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index ff8132be8..5e1264b4a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -24,5 +24,12 @@ module ApplicationHelper :target => "_blank" end + # Produces a cache key for uniquely identifying cached fragments. + def cache_key_for(klass, identifier="all") + count = klass.count + max_updated_at = klass.maximum(:updated_at).try(:utc).try(:to_s, :number) + "#{klass.name.downcase.pluralize}/#{identifier}-#{count}-#{max_updated_at}" + end + end diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index c1c7768b3..53bae3092 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -13,8 +13,8 @@ class Notifier < ActionMailer::Base def planting_reminder(member) @member = member - @plantings = @member.plantings.reorder.last(5) - @harvests = @member.harvests.reorder.last(5) + @plantings = @member.plantings.first(5) + @harvests = @member.harvests.first(5) if @member.send_planting_reminder mail(:to => @member.email, @@ -22,4 +22,19 @@ class Notifier < ActionMailer::Base 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") + end + + def crop_request_approved(member, crop) + @member, @crop = member, crop + 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") + end + end diff --git a/app/models/ability.rb b/app/models/ability.rb index 579a87022..1997ddf49 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -21,7 +21,24 @@ class Ability cannot :read, Account cannot :read, AccountType + # nobody should be able to view unapproved crops unless they + # are wranglers or admins + cannot :read, Crop + 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| + sn.crop.approved? + end + # ... same for alternate names + cannot :read, AlternateName + can :read, AlternateName do |an| + an.crop.approved? + end + if member + # members can see even rejected or pending crops if they requested it + can :read, Crop, :requester_id => member.id # managing your own user settings can :update, Member, :id => member.id @@ -45,6 +62,9 @@ class Ability can :manage, AlternateName end + # any member can create a crop provisionally + can :create, Crop + # can create & destroy their own authentications against other sites. can :create, Authentication can :destroy, Authentication, :member_id => member.id @@ -94,9 +114,11 @@ class Ability cannot :destroy, OrderItem, :order => { :member_id => member.id, :completed_at => nil } # following/unfollowing permissions - can :create, Follow do |f| - !member.already_following?(f.followed) && f.followed_id != member.id - end + can :create, Follow + 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 if member.has_role? :admin diff --git a/app/models/account.rb b/app/models/account.rb index c0348e611..547fc57bf 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -1,5 +1,4 @@ class Account < ActiveRecord::Base - attr_accessible :account_type_id, :member_id, :paid_until belongs_to :member belongs_to :account_type @@ -9,7 +8,7 @@ class Account < ActiveRecord::Base before_create do |account| unless account.account_type - account.account_type = AccountType.find_or_create_by_name( + account.account_type = AccountType.find_or_create_by(name: Growstuff::Application.config.default_account_type ) end diff --git a/app/models/account_type.rb b/app/models/account_type.rb index dc464707b..d6be51a94 100644 --- a/app/models/account_type.rb +++ b/app/models/account_type.rb @@ -1,5 +1,4 @@ class AccountType < ActiveRecord::Base - attr_accessible :is_paid, :is_permanent_paid, :name has_many :products def to_s diff --git a/app/models/alternate_name.rb b/app/models/alternate_name.rb index fb92a2bc9..cb6f79e9d 100644 --- a/app/models/alternate_name.rb +++ b/app/models/alternate_name.rb @@ -1,5 +1,5 @@ class AlternateName < ActiveRecord::Base - attr_accessible :crop_id, :name, :creator_id + after_commit { |an| an.crop.__elasticsearch__.index_document if an.crop } belongs_to :crop belongs_to :creator, :class_name => 'Member' end diff --git a/app/models/authentication.rb b/app/models/authentication.rb index 325bffe40..e6171c8b7 100644 --- a/app/models/authentication.rb +++ b/app/models/authentication.rb @@ -1,4 +1,3 @@ class Authentication < ActiveRecord::Base belongs_to :member - attr_accessible :provider, :uid, :token, :secret, :name end diff --git a/app/models/comment.rb b/app/models/comment.rb index f797848e0..f7da18842 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -1,10 +1,9 @@ class Comment < ActiveRecord::Base - attr_accessible :author_id, :body, :post_id belongs_to :author, :class_name => 'Member' belongs_to :post - default_scope order("created_at DESC") - scope :post_order, reorder("created_at ASC") # for display on post page + default_scope { order("created_at DESC") } + scope :post_order, -> { reorder("created_at ASC") } # for display on post page after_create do recipient = self.post.author.id diff --git a/app/models/comment_sweeper.rb b/app/models/comment_sweeper.rb deleted file mode 100644 index fed7b6f4c..000000000 --- a/app/models/comment_sweeper.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CommentSweeper < ActionController::Caching::Sweeper - observe Comment - - def after_create(comment) - expire_fragment('recent_posts') - end - - def after_update(comment) - end - - def after_destroy(comment) - expire_fragment('recent_posts') - end - -end diff --git a/app/models/crop.rb b/app/models/crop.rb index b63f9a8a5..1f514f3ce 100644 --- a/app/models/crop.rb +++ b/app/models/crop.rb @@ -1,38 +1,113 @@ class Crop < ActiveRecord::Base extend FriendlyId - friendly_id :name, use: :slugged - attr_accessible :en_wikipedia_url, :name, :parent_id, :creator_id, :scientific_names_attributes + friendly_id :name, use: [:slugged, :finders] - has_many :scientific_names + 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 - has_many :alternate_names + has_many :alternate_names, after_add: :update_index, after_remove: :update_index has_many :plantings has_many :photos, :through => :plantings has_many :seeds has_many :harvests - has_many :plant_parts, :through => :harvests, :uniq => :true + 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' 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 :rejected, -> { where(:approval_status => "rejected") } - default_scope order("lower(name) asc") - scope :recent, reorder("created_at desc") - scope :toplevel, where(:parent_id => nil) - scope :popular, reorder("plantings_count desc, lower(name) asc") - scope :randomized, reorder('random()') # ok on sqlite and psql, but not on mysql - + ## Wikipedia urls are only necessary when approving a crop validates :en_wikipedia_url, :format => { - :with => /^https?:\/\/en\.wikipedia\.org\/wiki/, + :with => /\Ahttps?:\/\/en\.wikipedia\.org\/wiki/, :message => 'is not a valid English Wikipedia URL' - } + }, + :if => :approved? + + ## Reasons are only necessary when rejecting + validates :reason_for_rejection, :presence => true, :if => :rejected? + + ## This validation addresses a race condition + validate :approval_status_cannot_be_changed_again + + validate :must_be_rejected_if_rejected_reasons_present + + validate :must_have_meaningful_reason_for_rejection + + #################################### + # Elastic search configuration + include Elasticsearch::Model + include Elasticsearch::Model::Callbacks + # In order to avoid clashing between different environments, + # use Rails.env as a part of index name (eg. development_growstuff) + index_name [Rails.env, "growstuff"].join('_') + settings index: { number_of_shards: 1 }, + analysis: { + tokenizer: { + gs_edgeNGram_tokenizer: { + type: "edgeNGram", # edgeNGram: NGram match from the start of a token + min_gram: 3, + max_gram: 10, + # token_chars: Elasticsearch will split on characters + # that don’t belong to any of these classes + token_chars: [ "letter", "digit" ] + } + }, + analyzer: { + gs_edgeNGram_analyzer: { + tokenizer: "gs_edgeNGram_tokenizer", + filter: ["lowercase"] + } + }, + } do + mappings dynamic: 'false' do + indexes :id, type: 'long' + indexes :name, type: 'string', analyzer: 'gs_edgeNGram_analyzer' + indexes :scientific_names do + indexes :scientific_name, + type: 'string', + analyzer: 'gs_edgeNGram_analyzer', + # Disabling field-length norm (norm). If the norm option is turned on(by default), + # higher weigh would be given for shorter fields, which in our case is irrelevant. + norms: { enabled: false } + end + indexes :alternate_names do + indexes :name, type: 'string', analyzer: 'gs_edgeNGram_analyzer' + end + end + end + + def as_indexed_json(options={}) + self.as_json( + only: [:id, :name], + include: { + scientific_names: { only: :scientific_name }, + alternate_names: { only: :name } + }) + end + + # update the Elasticsearch index (only if we're using it in this + # environment) + def update_index(name_obj) + if ENV["GROWSTUFF_ELASTICSEARCH"] == "true" + __elasticsearch__.index_document + end + end + + # End Elasticsearch section def to_s return name @@ -105,6 +180,26 @@ class Crop < ActiveRecord::Base return true end + def pending? + approval_status == "pending" + end + + def approved? + approval_status == "approved" + end + + def rejected? + approval_status == "rejected" + end + + def approval_statuses + [ 'rejected', 'pending', 'approved' ] + end + + def reasons_for_rejection + [ "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 @@ -132,7 +227,7 @@ class Crop < ActiveRecord::Base cropbot = Member.find_by_login_name('cropbot') raise "cropbot account not found: run rake db:seed" unless cropbot - crop = Crop.find_or_create_by_name(name) + crop = Crop.find_or_create_by(name: name) crop.update_attributes( :en_wikipedia_url => en_wikipedia_url, :creator_id => cropbot.id @@ -203,10 +298,48 @@ class Crop < ActiveRecord::Base end # Crop.search(string) - # searches for crops whose names match the string given - # just uses SQL LIKE for now, but can be made fancier later def self.search(query) - where("name ILIKE ?", "%#{query}%") + if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" + search_str = query.nil? ? "" : query.downcase + response = __elasticsearch__.search( { + # Finds documents which match any field, but uses the _score from + # the best field insead of adding up _score from each field. + query: { + multi_match: { + query: "#{search_str}", + fields: ["name", "scientific_names.scientific_name", "alternate_names.name"] + } + }, + size: 50 + } + ) + return response.records.to_a + else + where("name ILIKE ?", "%#{query}%").load + end + end + + # Custom validations + + def approval_status_cannot_be_changed_again + previous = previous_changes.include?(:approval_status) ? previous_changes.approval_status : {} + if previous.include?(:rejected) || previous.include?(:approved) + errors.add(:approval_status, "has already been set to #{approval_status}") + end + end + + def must_be_rejected_if_rejected_reasons_present + unless rejected? + if reason_for_rejection.present? || rejection_notes.present? + errors.add(:approval_status, "must be rejected if a reason for rejection is present") + end + end + end + + def must_have_meaningful_reason_for_rejection + if reason_for_rejection == "other" && rejection_notes.blank? + errors.add(:rejection_notes, "must be added if the reason for rejection is \"other\"") + end end end diff --git a/app/models/crop_sweeper.rb b/app/models/crop_sweeper.rb deleted file mode 100644 index fef9927f3..000000000 --- a/app/models/crop_sweeper.rb +++ /dev/null @@ -1,21 +0,0 @@ -class CropSweeper < ActionController::Caching::Sweeper - observe Crop - - def after_create(crop) - expire_fragment('homepage_stats') - expire_fragment('recent_crops') - expire_fragment('full_crop_hierarchy') - end - - def after_update(crop) - expire_fragment("crop_image_#{crop.id}") - end - - def after_destroy(crop) - expire_fragment('homepage_stats') - expire_fragment('recent_crops') - expire_fragment('full_crop_hierarchy') - end - -end - diff --git a/app/models/follow.rb b/app/models/follow.rb index f8767c10c..d7028c8ed 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -1,5 +1,4 @@ class Follow < ActiveRecord::Base - attr_accessible :followed_id, :follower_id belongs_to :follower, class_name: "Member" belongs_to :followed, class_name: "Member" validates :follower_id, uniqueness: { :scope => :followed_id } diff --git a/app/models/forum.rb b/app/models/forum.rb index b673dbf19..fd4a79509 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -1,7 +1,7 @@ class Forum < ActiveRecord::Base extend FriendlyId - friendly_id :name, use: :slugged - attr_accessible :description, :name, :owner_id, :slug + friendly_id :name, use: [:slugged, :finders] + has_many :posts belongs_to :owner, :class_name => "Member" diff --git a/app/models/forum_sweeper.rb b/app/models/forum_sweeper.rb deleted file mode 100644 index cccffc524..000000000 --- a/app/models/forum_sweeper.rb +++ /dev/null @@ -1,16 +0,0 @@ -class ForumSweeper < ActionController::Caching::Sweeper - observe Forum - - def after_create(forum) - expire_fragment('homepage_forums') - end - - def after_update(forum) - expire_fragment('homepage_forums') - end - - def after_destroy(forum) - expire_fragment('homepage_forums') - end - -end diff --git a/app/models/garden.rb b/app/models/garden.rb index 6465a474a..0514f2a96 100644 --- a/app/models/garden.rb +++ b/app/models/garden.rb @@ -1,24 +1,32 @@ class Garden < ActiveRecord::Base include Geocodable extend FriendlyId - friendly_id :garden_slug, use: :slugged - - attr_accessible :name, :slug, :owner_id, :description, :active, - :location, :latitude, :longitude, :area, :area_unit + 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 :plantings, -> { order(created_at: :desc) }, :dependent => :destroy has_many :crops, :through => :plantings + has_and_belongs_to_many :photos + + before_destroy do |garden| + photolist = garden.photos.to_a # save a temp copy of the photo list + garden.photos.clear # clear relationship b/w garden and photo + + photolist.each do |photo| + photo.destroy_if_unused + end + end + # set up geocoding geocoded_by :location after_validation :geocode after_validation :empty_unwanted_geocodes after_save :mark_inactive_garden_plantings_as_finished - default_scope order("lower(name) asc") - scope :active, where(:active => true) - scope :inactive, where(:active => false) + default_scope { order("lower(name) asc") } + scope :active, -> { where(:active => true) } + scope :inactive, -> { where(:active => false) } validates :name, :format => { @@ -26,7 +34,9 @@ class Garden < ActiveRecord::Base } validates :area, - :numericality => { :only_integer => false, :greater_than_or_equal_to => 0 }, + :numericality => { + :only_integer => false, + :greater_than_or_equal_to => 0 }, :allow_nil => true AREA_UNITS_VALUES = { @@ -86,4 +96,8 @@ class Garden < ActiveRecord::Base end end + def default_photo + return photos.first + end + end diff --git a/app/models/garden_sweeper.rb b/app/models/garden_sweeper.rb deleted file mode 100644 index 3913a7c11..000000000 --- a/app/models/garden_sweeper.rb +++ /dev/null @@ -1,16 +0,0 @@ -class GardenSweeper < ActionController::Caching::Sweeper - observe Garden - - def after_create(garden) - expire_fragment('homepage_stats') - expire_fragment('interesting_members') if garden.owner.interesting? - expire_fragment("member_thumbnail_#{garden.owner.id}") - end - - def after_destroy(garden) - expire_fragment('homepage_stats') - expire_fragment('interesting_members') if garden.owner.interesting? - expire_fragment("member_thumbnail_#{garden.owner.id}") - end -end - diff --git a/app/models/harvest.rb b/app/models/harvest.rb index 48e9eac19..4339a30fa 100644 --- a/app/models/harvest.rb +++ b/app/models/harvest.rb @@ -1,10 +1,7 @@ class Harvest < ActiveRecord::Base include ActionView::Helpers::NumberHelper extend FriendlyId - friendly_id :harvest_slug, use: :slugged - - attr_accessible :crop_id, :harvested_at, :description, :owner_id, - :quantity, :unit, :weight_quantity, :weight_unit, :plant_part_id, :slug + friendly_id :harvest_slug, use: [:slugged, :finders] belongs_to :crop belongs_to :owner, :class_name => 'Member' @@ -21,12 +18,16 @@ class Harvest < ActiveRecord::Base end end - default_scope order('created_at DESC') + default_scope { order('created_at DESC') } + + validates :crop, :approved => true validates :crop, :presence => {:message => "must be present and exist in our database"} validates :quantity, - :numericality => { :only_integer => false }, + :numericality => { + :only_integer => false, + :greater_than_or_equal_to => 0 }, :allow_nil => true UNITS_VALUES = { @@ -62,6 +63,17 @@ class Harvest < ActiveRecord::Base after_validation :cleanup_quantities + before_save :set_si_weight + + # we're storing the harvest weight in kilograms in the db too + # to make data manipulation easier + 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 + end + end + def cleanup_quantities if quantity == 0 self.quantity = nil diff --git a/app/models/member.rb b/app/models/member.rb index 63682bcdf..6c00fb8ce 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -2,7 +2,7 @@ class Member < ActiveRecord::Base include Geocodable extend FriendlyId - friendly_id :login_name, use: :slugged + friendly_id :login_name, use: [:slugged, :finders] has_many :posts, :foreign_key => 'author_id' has_many :comments, :foreign_key => 'author_id' @@ -27,18 +27,20 @@ class Member < ActiveRecord::Base has_many :photos + + default_scope { order("lower(login_name) asc") } + scope :confirmed, -> { where('confirmed_at IS NOT NULL') } + 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) } + 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 - default_scope order("lower(login_name) asc") - scope :confirmed, where('confirmed_at IS NOT NULL') - scope :located, where("location <> '' and latitude IS NOT NULL and longitude IS NOT NULL") - scope :recently_signed_in, reorder('updated_at DESC') - scope :wants_newsletter, where(:newsletter => true) - # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, # :lockable, :timeoutable and :omniauthable @@ -46,16 +48,6 @@ class Member < ActiveRecord::Base :recoverable, :rememberable, :trackable, :validatable, :confirmable, :lockable, :timeoutable - # Setup accessible (or protected) attributes for your model - attr_accessible :login_name, :email, :password, :password_confirmation, - :remember_me, :login, - # terms of service - :tos_agreement, - # profile stuff - :bio, :location, :latitude, :longitude, - # email settings - :show_email, :newsletter, :send_notification_email, :send_planting_reminder - # set up geocoding geocoded_by :location after_validation :geocode @@ -80,7 +72,7 @@ class Member < ActiveRecord::Base :message => "name is reserved" }, :format => { - :with => /^\w+$/, + :with => /\A\w+\z/, :message => "may only include letters, numbers, or underscores" }, :uniqueness => { @@ -93,7 +85,7 @@ class Member < ActiveRecord::Base # 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 => member.id) } + after_create {|member| Account.find_or_create_by(:member_id => member.id) } after_save :update_newsletter_subscription @@ -243,17 +235,19 @@ class Member < ActiveRecord::Base end end - def newsletter_subscribe + def newsletter_subscribe(testing=false) + 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 alredy confirmed their email with us + :double_optin => false # they already confirmed their email with us }) end - def newsletter_unsubscribe + def newsletter_unsubscribe(testing=false) + return true if (Rails.env.test? && !testing) gb = Gibbon::API.new res = gb.lists.unsubscribe({ :id => ENV['GROWSTUFF_MAILCHIMP_NEWSLETTER_ID'], diff --git a/app/models/member_sweeper.rb b/app/models/member_sweeper.rb deleted file mode 100644 index 205131e19..000000000 --- a/app/models/member_sweeper.rb +++ /dev/null @@ -1,23 +0,0 @@ -class MemberSweeper < ActionController::Caching::Sweeper - observe Member - - def after_create(member) - expire_fragment('homepage_stats') - end - - def after_update(member) - expire_fragment('interesting_members') if member.interesting? - expire_fragment("interesting_seeds") if member.seeds.tradable.present? - expire_fragment("member_thumbnail_#{member.id}") - - if member.plantings.present? - member.plantings.each do |p| - expire_fragment("plantings_listitem_#{p.id}") if p.interesting? - end - expire_fragment('interesting_plantings') - end - - end - -end - diff --git a/app/models/notification.rb b/app/models/notification.rb index 3fc48a0c7..304b86b03 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -1,13 +1,10 @@ class Notification < ActiveRecord::Base - attr_accessible :sender_id, :recipient_id, - :subject, :body, :post_id, :read - belongs_to :sender, :class_name => 'Member' belongs_to :recipient, :class_name => 'Member' belongs_to :post - default_scope order('created_at DESC') - scope :unread, where(:read => false) + default_scope { order('created_at DESC') } + 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 122d83700..e9f97034f 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -1,10 +1,9 @@ class Order < ActiveRecord::Base - attr_accessible :member_id, :completed_at, :referral_code belongs_to :member has_many :order_items, :dependent => :destroy - default_scope order('created_at DESC') + default_scope { order('created_at DESC') } validates :referral_code, :format => { :with => /\A[a-zA-Z0-9 ]*\z/, diff --git a/app/models/order_item.rb b/app/models/order_item.rb index 3a06097d1..159876dd5 100644 --- a/app/models/order_item.rb +++ b/app/models/order_item.rb @@ -1,6 +1,4 @@ class OrderItem < ActiveRecord::Base - attr_accessible :order_id, :price, :product_id, :quantity - belongs_to :order belongs_to :product diff --git a/app/models/photo.rb b/app/models/photo.rb index 862b9d28b..54cc94de3 100644 --- a/app/models/photo.rb +++ b/app/models/photo.rb @@ -1,20 +1,20 @@ class Photo < ActiveRecord::Base - attr_accessible :flickr_photo_id, :owner_id, :title, :license_name, - :license_url, :thumbnail_url, :fullsize_url, :link_url belongs_to :owner, :class_name => 'Member' has_and_belongs_to_many :plantings has_and_belongs_to_many :harvests + has_and_belongs_to_many :gardens before_destroy do |photo| photo.plantings.clear photo.harvests.clear + photo.gardens.clear end - default_scope order("created_at desc") + default_scope { order("created_at desc") } # remove photos that aren't used by anything def destroy_if_unused - unless plantings.size > 0 or harvests.size > 0 + unless plantings.size > 0 or harvests.size > 0 or gardens.size > 0 self.destroy end end diff --git a/app/models/photo_sweeper.rb b/app/models/photo_sweeper.rb deleted file mode 100644 index 1bb388b11..000000000 --- a/app/models/photo_sweeper.rb +++ /dev/null @@ -1,13 +0,0 @@ -class PhotoSweeper < ActionController::Caching::Sweeper - observe Photo - - def after_create(photo) - expire_fragment('interesting_plantings') - end - - def after_destroy(photo) - expire_fragment('interesting_plantings') - end - -end - diff --git a/app/models/plant_part.rb b/app/models/plant_part.rb index 41e8d26ea..33d2292fa 100644 --- a/app/models/plant_part.rb +++ b/app/models/plant_part.rb @@ -1,11 +1,9 @@ class PlantPart < ActiveRecord::Base extend FriendlyId - friendly_id :name, :use => :slugged + friendly_id :name, :use => [:slugged, :finders] has_many :harvests - has_many :crops, :through => :harvests, :uniq => true - - attr_accessible :name, :slug + has_many :crops, -> { uniq }, :through => :harvests def to_s return name diff --git a/app/models/planting.rb b/app/models/planting.rb index 889fb2d80..958ba625f 100644 --- a/app/models/planting.rb +++ b/app/models/planting.rb @@ -1,10 +1,6 @@ class Planting < ActiveRecord::Base extend FriendlyId - friendly_id :planting_slug, use: :slugged - - attr_accessible :crop_id, :description, :garden_id, :planted_at, - :quantity, :sunniness, :planted_from, :owner_id, :finished, - :finished_at + friendly_id :planting_slug, use: [:slugged, :finders] belongs_to :garden belongs_to :owner, :class_name => 'Member', :counter_cache => true @@ -21,9 +17,9 @@ class Planting < ActiveRecord::Base end end - default_scope order("created_at desc") - scope :finished, where(:finished => true) - scope :current, where(:finished => false) + default_scope { order("created_at desc") } + scope :finished, -> { where(:finished => true) } + scope :current, -> { where(:finished => false) } delegate :name, :en_wikipedia_url, @@ -32,12 +28,16 @@ class Planting < ActiveRecord::Base :to => :crop, :prefix => true - default_scope order("created_at desc") + default_scope { order("created_at desc") } - validates :crop_id, :presence => {:message => "must be present and exist in our database"} + validates :crop, :approved => true + + validates :crop, :presence => {:message => "must be present and exist in our database"} validates :quantity, - :numericality => { :only_integer => true }, + :numericality => { + :only_integer => true, + :greater_than_or_equal_to => 0 }, :allow_nil => true SUNNINESS_VALUES = %w(sun semi-shade shade) diff --git a/app/models/planting_sweeper.rb b/app/models/planting_sweeper.rb deleted file mode 100644 index 8e8de10df..000000000 --- a/app/models/planting_sweeper.rb +++ /dev/null @@ -1,25 +0,0 @@ -class PlantingSweeper < ActionController::Caching::Sweeper - observe Planting - - def after_create(planting) - expire_fragment('homepage_stats') - expire_fragment("member_thumbnail_#{planting.owner.id}") - expire_fragment("interesting_members") if planting.owner.interesting? - expire_fragment("crop_image_#{planting.crop.id}") - end - - def after_update(planting) - expire_fragment("planting_listitem_#{planting.id}") - expire_fragment("planting_image_#{planting.id}") - expire_fragment("interesting_plantings") - end - - def after_destroy(planting) - expire_fragment('homepage_stats') - expire_fragment("crop_image_#{planting.crop.id}") - expire_fragment('interesting_plantings') if planting.interesting? - expire_fragment("interesting_members") if planting.owner.interesting? - end - -end - diff --git a/app/models/post.rb b/app/models/post.rb index 7f72a4e57..88c6355cc 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,7 +1,6 @@ class Post < ActiveRecord::Base extend FriendlyId - friendly_id :author_date_subject, use: :slugged - attr_accessible :body, :subject, :author_id, :forum_id + friendly_id :author_date_subject, use: [:slugged, :finders] belongs_to :author, :class_name => 'Member' belongs_to :forum has_many :comments, :dependent => :destroy @@ -11,7 +10,7 @@ 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. - default_scope order("created_at desc") + default_scope { order("created_at desc") } validates :subject, :format => { diff --git a/app/models/post_sweeper.rb b/app/models/post_sweeper.rb deleted file mode 100644 index e6ad03427..000000000 --- a/app/models/post_sweeper.rb +++ /dev/null @@ -1,16 +0,0 @@ -class PostSweeper < ActionController::Caching::Sweeper - observe Post - - def after_create(post) - expire_fragment('recent_posts') - end - - def after_update(post) - expire_fragment('recent_posts') - end - - def after_destroy(post) - expire_fragment('recent_posts') - end - -end diff --git a/app/models/product.rb b/app/models/product.rb index 70193ea7a..68d483665 100644 --- a/app/models/product.rb +++ b/app/models/product.rb @@ -1,12 +1,12 @@ class Product < ActiveRecord::Base - attr_accessible :description, :min_price, :recommended_price, :name, - :account_type_id, :paid_months - has_and_belongs_to_many :orders belongs_to :account_type - validates :paid_months, :numericality => { :only_integer => true, - :allow_nil => true } + validates :paid_months, + :numericality => { + :only_integer => true, + :greater_than_or_equal_to => 0 }, + :allow_nil => true def to_s name diff --git a/app/models/role.rb b/app/models/role.rb index 284fdd0d8..a3364fb89 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -1,7 +1,7 @@ class Role < ActiveRecord::Base extend FriendlyId - friendly_id :name, use: :slugged - attr_accessible :description, :name, :members, :slug + friendly_id :name, use: [:slugged, :finders] + has_and_belongs_to_many :members class << self diff --git a/app/models/scientific_name.rb b/app/models/scientific_name.rb index 56c86b21b..7469b3946 100644 --- a/app/models/scientific_name.rb +++ b/app/models/scientific_name.rb @@ -1,5 +1,5 @@ class ScientificName < ActiveRecord::Base - attr_accessible :crop_id, :scientific_name, :creator_id + after_commit { |sn| sn.crop.__elasticsearch__.index_document if sn.crop } belongs_to :crop belongs_to :creator, :class_name => 'Member' end diff --git a/app/models/scientific_name_sweeper.rb b/app/models/scientific_name_sweeper.rb deleted file mode 100644 index 2ac626526..000000000 --- a/app/models/scientific_name_sweeper.rb +++ /dev/null @@ -1,17 +0,0 @@ -class ScientificNameSweeper < ActionController::Caching::Sweeper - observe ScientificName - - def after_create(scientific_name) - expire_fragment("crop_image_#{scientific_name.crop.id}") - end - - def after_update(scientific_name) - expire_fragment("crop_image_#{scientific_name.crop.id}") - end - - def after_destroy(scientific_name) - expire_fragment("crop_image_#{scientific_name.crop.id}") - end - -end - diff --git a/app/models/seed.rb b/app/models/seed.rb index 38cd3b714..9fa005907 100644 --- a/app/models/seed.rb +++ b/app/models/seed.rb @@ -1,21 +1,32 @@ class Seed < ActiveRecord::Base extend FriendlyId - friendly_id :seed_slug, use: :slugged - - attr_accessible :owner_id, :crop_id, :description, :quantity, :plant_before, - :tradable_to, :slug + friendly_id :seed_slug, use: [:slugged, :finders] belongs_to :crop belongs_to :owner, :class_name => 'Member', :foreign_key => 'owner_id' - default_scope order("created_at desc") + default_scope { order("created_at desc") } + + validates :crop, :approved => true validates :crop, :presence => {:message => "must be present and exist in our database"} validates :quantity, - :numericality => { :only_integer => 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 + validates :days_until_maturity_max, + :numericality => { + :only_integer => true, + :greater_than_or_equal_to => 0 }, :allow_nil => true - scope :tradable, where("tradable_to != 'nowhere'") + scope :tradable, -> { where("tradable_to != 'nowhere'") } TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally) validates :tradable_to, :inclusion => { :in => TRADABLE_TO_VALUES, @@ -23,6 +34,32 @@ class Seed < ActiveRecord::Base :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 + + 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 + + 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 + def tradable? if self.tradable_to == 'nowhere' return false diff --git a/app/models/seed_sweeper.rb b/app/models/seed_sweeper.rb deleted file mode 100644 index 1b7d663a4..000000000 --- a/app/models/seed_sweeper.rb +++ /dev/null @@ -1,26 +0,0 @@ -class SeedSweeper < ActionController::Caching::Sweeper - observe Seed - - def after_create(seed) - if seed.tradable? && seed.interesting? - expire_fragment('interesting_seeds') - end - expire_fragment('interesting_members') if seed.owner.interesting? - expire_fragment("member_thumbnail_#{seed.owner.id}") - end - - def after_update(seed) - expire_fragment('interesting_seeds') - end - - def after_destroy(seed) - if seed.tradable? && seed.interesting? - expire_fragment('interesting_seeds') - end - expire_fragment('interesting_members') if seed.owner.interesting? - expire_fragment("member_thumbnail_#{seed.owner.id}") - end - -end - - diff --git a/app/validators/approved_validator.rb b/app/validators/approved_validator.rb new file mode 100644 index 000000000..4016058aa --- /dev/null +++ b/app/validators/approved_validator.rb @@ -0,0 +1,7 @@ +class ApprovedValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + unless record.crop.try(:approved?) + record.errors[attribute] << (options[:message] || 'must be approved') + end + end +end diff --git a/app/views/admin/index.html.haml b/app/views/admin/index.html.haml index 18f0a043e..958ed39ed 100644 --- a/app/views/admin/index.html.haml +++ b/app/views/admin/index.html.haml @@ -8,6 +8,7 @@ %li= link_to "Roles", roles_path %li= link_to "Forums", forums_path %li= link_to "Newsletter subscribers", admin_newsletter_path + %li= link_to "CMS", comfy_admin_cms_path %h2 Orders diff --git a/app/views/authentications/index.html.haml b/app/views/authentications/index.html.haml deleted file mode 100644 index 3bb1607f1..000000000 --- a/app/views/authentications/index.html.haml +++ /dev/null @@ -1,22 +0,0 @@ -- content_for :title, "Linked accounts on other sites" - -- if @authentications - - unless @authentications.empty? - .authentications - - @authentications.each do |authentication| - %a{ :href => "http://twitter.com/#{authentication.name}" } - .authentication - = image_tag "#{authentication.provider}_64.png", :size => "64x64" - .provider - = authentication.provider.titleize - .name - = authentication.name - = link_to "X", authentication, :confirm => "Are you sure you want to remove this authentication?", :method => :delete, :class => "remove" - .clear - %p - %strong Link another external account: - - else - %p - %strong Link to an external account: - -= link_to image_tag("twitter_64.png", :size => "64x64"), "/auth/twitter", :class => "auth_provider" diff --git a/app/views/crops/_find_seeds.html.haml b/app/views/crops/_find_seeds.html.haml index 9b7797144..66990ed69 100644 --- a/app/views/crops/_find_seeds.html.haml +++ b/app/views/crops/_find_seeds.html.haml @@ -1,4 +1,4 @@ -%h4 Find seeds +%h4 Find #{ crop.name } seeds - if crop.seeds.empty? %p There are no seeds available to trade. diff --git a/app/views/crops/_form.html.haml b/app/views/crops/_form.html.haml index 0c8fc8c45..e7be7cd62 100644 --- a/app/views/crops/_form.html.haml +++ b/app/views/crops/_form.html.haml @@ -6,40 +6,87 @@ - @crop.errors.full_messages.each do |msg| %li= msg - %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. + - 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. .form-group = f.label :name, :class => 'control-label col-md-2' .col-md-8 = f.text_field :name, :class => 'form-control' - %span.help-block Name in US English; singular; capitalize proper nouns only. + %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. + .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 Link to this crop's page on the English language Wikipedia. - .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| + %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 + .form-group - = sn.label :scientific_name, "Scientific name", :class => 'control-label col-md-2' + = f.label :parent_id, 'Parent crop', :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" + = 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'}) + + .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 + %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 = f.submit 'Save', :class => 'btn btn-primary' diff --git a/app/views/crops/_harvests.html.haml b/app/views/crops/_harvests.html.haml index bac61e580..003e72bfa 100644 --- a/app/views/crops/_harvests.html.haml +++ b/app/views/crops/_harvests.html.haml @@ -1,4 +1,4 @@ -%h4 Harvests +%h4 #{ crop.name.capitalize } harvests - if crop.harvests.empty? %p Nobody has harvested this crop yet. diff --git a/app/views/crops/_image_with_popover.html.haml b/app/views/crops/_image_with_popover.html.haml index 46e1b4ee8..0b9e969e0 100644 --- a/app/views/crops/_image_with_popover.html.haml +++ b/app/views/crops/_image_with_popover.html.haml @@ -1,4 +1,4 @@ -- cache "crop_image_#{crop.id}" do +- cache crop do = link_to | image_tag( | crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png', | diff --git a/app/views/crops/_index_card.html.haml b/app/views/crops/_index_card.html.haml index df706401b..84eb73062 100644 --- a/app/views/crops/_index_card.html.haml +++ b/app/views/crops/_index_card.html.haml @@ -1,7 +1,7 @@ .well .row .col-md-4 - = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img-rounded crop-image'), crop + = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img crop-image'), crop .col-md-8 %h3{:style => 'padding-top: 0px; margin-top: 0px'} = link_to crop, crop diff --git a/app/views/crops/_plantings.html.haml b/app/views/crops/_plantings.html.haml index 85a2ff88a..621a6d125 100644 --- a/app/views/crops/_plantings.html.haml +++ b/app/views/crops/_plantings.html.haml @@ -1,4 +1,4 @@ -%h4 Plantings +%h4 See who's planted #{ crop.name.pluralize } - if crop.plantings.empty? %p Nobody has planted this crop yet. diff --git a/app/views/crops/_thumbnail.html.haml b/app/views/crops/_thumbnail.html.haml index 7ac7d786b..6fc8a723e 100644 --- a/app/views/crops/_thumbnail.html.haml +++ b/app/views/crops/_thumbnail.html.haml @@ -1,14 +1,13 @@ -.thumbnail(style='height: 220px') - - if crop - = link_to image_tag((crop.default_photo ? crop.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => crop.name, :class => 'img-rounded'), crop - %p.crop-name - = link_to crop.name, crop - - if crop.scientific_names.count > 0 - %br/ - %i.scientific-name - %small +.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.count > 0 + .scientificname = crop.scientific_names.first.scientific_name - %br/ - %small + .plantingcount Planted = pluralize(crop.plantings.size, "time") diff --git a/app/views/crops/edit.html.haml b/app/views/crops/edit.html.haml index 135f74a7c..dca7fb221 100644 --- a/app/views/crops/edit.html.haml +++ b/app/views/crops/edit.html.haml @@ -1,4 +1,4 @@ -- content_for :title, "Editing crop" +- content_for :title, "Review crop: #{@crop.name}" %p Added by diff --git a/app/views/crops/hierarchy.html.haml b/app/views/crops/hierarchy.html.haml index 8391e7572..11bdb4832 100644 --- a/app/views/crops/hierarchy.html.haml +++ b/app/views/crops/hierarchy.html.haml @@ -5,5 +5,5 @@ = succeed "." do = link_to "crops database", crops_path -- cache("full_crop_hierarchy") do +- cache cache_key_for(Crop) do = render :partial => "hierarchy", :locals => { :display_crops => @crops } diff --git a/app/views/crops/index.html.haml b/app/views/crops/index.html.haml index 1b5663c25..d1be6fa49 100644 --- a/app/views/crops/index.html.haml +++ b/app/views/crops/index.html.haml @@ -1,5 +1,8 @@ -- content_for :title, "Crops" +- content_for :title, "Browse crops" +- content_for :subtitle, "#{@crops.size} total" +- if can? :wrangle, Crop + = link_to 'Wrangle Crops', wrangle_crops_path, :class => 'btn btn-primary' %p #{ENV['GROWSTUFF_SITE_NAME']} tracks who's growing what, where. View any crop page to see which of our members have planted it and find @@ -12,11 +15,10 @@ = submit_tag "Show", :class => 'btn btn-primary' %div.pagination - = page_entries_info @crops, :model => "crops" - = will_paginate @crops + = will_paginate @paginated_crops .row - - @crops.each do |crop| + - @paginated_crops.each do |crop| .col-md-2.six-across = render :partial => "thumbnail", :locals => { :crop => crop } @@ -25,8 +27,7 @@ = link_to 'New Crop', new_crop_path, {:class => 'btn btn-primary'} %div.pagination - = page_entries_info @crops, :model => "crops" - = will_paginate @crops + = will_paginate @paginated_crops %ul.list-inline diff --git a/app/views/crops/new.html.haml b/app/views/crops/new.html.haml index 63382ee95..f472c4791 100644 --- a/app/views/crops/new.html.haml +++ b/app/views/crops/new.html.haml @@ -1,3 +1,14 @@ -- content_for :title, "New crop" +- content_for :title, (can?(:wrangle, @crop) ? "New crop" : "Suggest a crop") + +- unless can? :wrangler, @crop + + %p Thanks for taking the time to suggest a crop! Our crop database is managed by volunteers, and we appreciate your help. Here are some things to consider when suggesting a new crop: + + %ul + %li First, you might want to #{link_to 'search our crops', crops_search_path} to make sure we don't have it already, perhaps under an alternate name. + + %li The Growstuff database only contains edible crops. In future we hope to support other crops, but for now, if your suggestion is not edible we won't be able to add it. + + %li At this time, we are only adding crops which have a Wikipedia page. If you want to add a specific variety of crop that doesn't have its own Wikipedia entry, please use the more general form of the crop instead and put the name of your variety in the notes/description. = render 'form' diff --git a/app/views/crops/search.html.haml b/app/views/crops/search.html.haml index e10ae6f76..9b57e1b7a 100644 --- a/app/views/crops/search.html.haml +++ b/app/views/crops/search.html.haml @@ -1,6 +1,18 @@ -- content_for :title, "Crops matching #{@search}" +- if @search + - content_for :title, "Crops matching \"#{@search}\"" + - if @all_matches + - content_for :subtitle, "#{@all_matches.size} total" +- else + - content_for :title, "Crop search" -- unless (@exact_match || @partial_matches.length > 0) +%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 + = submit_tag "Search", :class => 'btn btn-primary' + +- if @all_matches.empty? %h2 No results found %p Sorry, we couldn't find any crops that matched your search for "#{@search}". @@ -9,18 +21,15 @@ = link_to "browsing our crop database", crops_path instead. -- if @exact_match - %div#exact_match - %h2 Exact match +- else + %div.pagination + = will_paginate @paginated_matches + %div#paginated_matches .row - .col-md-2.six-across - = render :partial => "thumbnail", :locals => { :crop => @exact_match } - -- if ! @partial_matches.empty? - %div#partial_matches - %h2 Partial matches - .row - - @partial_matches.each do |c| + - @paginated_matches.each do |c| .col-md-2.six-across = render :partial => "thumbnail", :locals => { :crop => c } + + %div.pagination + = will_paginate @paginated_matches diff --git a/app/views/crops/show.html.haml b/app/views/crops/show.html.haml index e23c6ff76..2f400549b 100644 --- a/app/views/crops/show.html.haml +++ b/app/views/crops/show.html.haml @@ -1,18 +1,34 @@ - content_for :title, @crop.name - content_for :subtitle, @crop.default_scientific_name -- content_for :buttonbar do - - if can? :create, Planting - = link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-default' - - if can? :create, Harvest - = link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-default' +- 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 can? :create, Seed - = link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-default' +- 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}. + +- if @crop.approved? + - content_for :buttonbar do + - if can? :create, Planting + = link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-default' + + - if can? :create, Harvest + = link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-default' + + - if can? :create, Seed + = link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-default' .row .col-md-9 + - unless current_member + Learn how to grow #{ @crop.name.pluralize } from growers around the world. #{ ENV['GROWSTUFF_SITE_NAME'] } has tips and advice from real-life growers, including when to plant #{ @crop.name.pluralize }, how to harvest #{ @crop.name.pluralize }, and more. = render :partial => 'photos', :locals => { :crop => @crop } @@ -35,38 +51,48 @@ %div#cropmap %a{:name => 'posts'} - %div.pagination - = page_entries_info @posts, :model => "posts" - = will_paginate @posts, :params => {:anchor => "posts"} + %h2 What people are saying about #{ @crop.name.pluralize } - - unless @posts.empty? + - if @posts.empty? + %p + Nobody has posted about #{ @crop.name.pluralize } yet. + %p + - if can? :create, Post + = link_to "Post something", new_post_path, :class => 'btn btn-default' + - else + = 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" + = 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" - = will_paginate @posts, :params => {:anchor => "posts"} + %div.pagination + = page_entries_info @posts, :model => "posts" + = will_paginate @posts, :params => {:anchor => "posts"} .col-md-3 = render :partial => 'wrangle', :locals => { :crop => @crop } - = render :partial => 'scientific_names', :locals => { :crop => @crop } - = render :partial => 'alternate_names', :locals => { :crop => @crop } - %h4 Planting advice + %h4 How to grow #{ @crop.name.pluralize } = render :partial => 'grown_for', :locals => { :crop => @crop } = render :partial => 'planting_advice', :locals => { :crop => @crop } - %h4 Varieties + = render :partial => 'scientific_names', :locals => { :crop => @crop } + = render :partial => 'alternate_names', :locals => { :crop => @crop } + + %h4 #{ @crop.name.capitalize } varieties = render :partial => 'varieties', :locals => { :crop => @crop } - - %h4 More information - %ul - %li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url - = render :partial => 'plantings', :locals => { :crop => @crop } = render :partial => 'harvests', :locals => { :crop => @crop } = render :partial => 'find_seeds', :locals => { :crop => @crop } + + %h4 Learn more about #{ @crop.name.pluralize } + %ul + %li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url + diff --git a/app/views/crops/wrangle.html.haml b/app/views/crops/wrangle.html.haml index b26f29fc9..549a737a1 100644 --- a/app/views/crops/wrangle.html.haml +++ b/app/views/crops/wrangle.html.haml @@ -15,18 +15,38 @@ %li.crop_wrangler = link_to crop_wrangler.login_name, crop_wrangler -%h2 Recently added crops +.tabbable + %ul.nav.nav-tabs + %li{:class => @approval_status.blank? ? 'active' : ''} + = link_to "Recently added", wrangle_crops_path + %li{:class => @approval_status == "pending" ? 'active' : ''} + = link_to "Pending approval", wrangle_crops_path(:approval_status => "pending") + %li{:class => @approval_status == "rejected" ? 'active' : ''} + = link_to "Rejected", wrangle_crops_path(:approval_status => "rejected") + +%h2 + - if @approval_status == "pending" + Requested Crops + - elsif @approval_status == "rejected" + Rejected Crops + - else + Recently added crops + %div.pagination = page_entries_info @crops, :model => "crops" = will_paginate @crops -%table.table.table-striped +%table{:class => "table table-striped", :id => @approval_status.blank? ? 'recently-added-crops' : "#{@approval_status}-crops"} %tr %th System name %th English Wikipedia URL %th Scientific names - %th Added by + %th Requested by + - if @approval_status == "rejected" + %th Rejected by + - if @approval_status != "rejected" && @approval_status != "pending" + %th Added by %th When - @crops.each do |c| %tr @@ -36,7 +56,9 @@ - c.scientific_names.each do |s| = link_to s.scientific_name, s %br/ - %td= link_to c.creator, c.creator + %td= c.requester.present? ? (link_to c.requester, c.requester) : "N/A" + - unless @approval_status == "pending" + %td= c.creator.present? ? (link_to c.creator, c.creator) : "N/A" %td = distance_of_time_in_words(c.created_at, Time.zone.now) ago. @@ -44,3 +66,5 @@ %div.pagination = page_entries_info @crops, :model => "crops" = will_paginate @crops + + diff --git a/app/views/gardens/show.html.haml b/app/views/gardens/show.html.haml index a0630d3a8..25c707fb3 100644 --- a/app/views/gardens/show.html.haml +++ b/app/views/gardens/show.html.haml @@ -29,6 +29,21 @@ :growstuff_markdown #{strip_tags @garden.description} + - if @garden.photos.count > 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 } + - 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' + + %h3 What's planted here? diff --git a/app/views/harvests/index.csv.shaper b/app/views/harvests/index.csv.shaper index 4560dde80..b75b7a879 100644 --- a/app/views/harvests/index.csv.shaper +++ b/app/views/harvests/index.csv.shaper @@ -10,6 +10,7 @@ csv.headers :id, :unit, :weight_quantity, :weight_unit, + :si_weight, :date_harvested, :description, :date_added, @@ -31,7 +32,7 @@ csv.headers :id, csv.cell :plant_part_id, h.plant_part ? h.plant_part.id : '' csv.cell :plant_part_name, h.plant_part ? h.plant_part.to_s : '' - csv.cells :quantity, :unit, :weight_quantity, :weight_unit + csv.cells :quantity, :unit, :weight_quantity, :weight_unit, :si_weight csv.cell :date_harvested, h.created_at.to_s(:db) diff --git a/app/views/home/_crops.html.haml b/app/views/home/_crops.html.haml index ce3c775ce..c56f72657 100644 --- a/app/views/home/_crops.html.haml +++ b/app/views/home/_crops.html.haml @@ -1,19 +1,24 @@ .row - .col-md-6.hidden-xs - - cache "interesting_crops", :expires_in => 1.day do + .col-md-8 + - cache cache_key_for(Crop, 'interesting'), :expires_in => 1.day do %h2= t('.our_crops') - - Crop.interesting.each do |c| - .col-md-3{:style => 'margin:0px; padding: 3px'} - = render :partial => 'crops/image_with_popover', :locals => { :crop => c } + .hidden-xs + - Crop.interesting.first(8).each do |c| + .col-md-3 + = render :partial => 'crops/thumbnail', :locals => { :crop => c } + .visible-xs + - Crop.interesting.first(3).each do |c| + .col-md-3 + = render :partial => 'crops/thumbnail', :locals => { :crop => c } - .col-md-6 - - cache "interesting_plantings" do + .col-md-4.hidden-xs + - cache cache_key_for(Planting) do %h2= t('.recently_planted') - = render :partial => 'plantings/list', :locals => { :plantings => Planting.interesting.first(4) } + = render :partial => 'plantings/list', :locals => { :plantings => Planting.interesting.first(6) } .row .col-md-12 - - cache "recent_crops" do + - cache cache_key_for(Crop, 'recent') do %p{ :style => 'margin-top: 11.25px' } %strong #{t('.recently_added')}: diff --git a/app/views/home/_discuss.html.haml b/app/views/home/_discuss.html.haml index 22b9972b9..de1d362f1 100644 --- a/app/views/home/_discuss.html.haml +++ b/app/views/home/_discuss.html.haml @@ -1,11 +1,10 @@ %h2= t('.discussion') -- cache "recent_posts" do - - posts = Post.limit(6) - - if posts - =render :partial => "posts/summary", :locals => { :posts => posts, :howmany => 6 } +- posts = Post.limit(6) +- if posts + =render :partial => "posts/summary", :locals => { :posts => posts, :howmany => 6 } -- cache "homepage_forums" do +- cache cache_key_for(Forum) do - forums = Forum.all - if forums %ul.list-inline diff --git a/app/views/home/_keep_in_touch.html.haml b/app/views/home/_keep_in_touch.html.haml deleted file mode 100644 index 536cd4071..000000000 --- a/app/views/home/_keep_in_touch.html.haml +++ /dev/null @@ -1,17 +0,0 @@ -%h2= t('.keep_in_touch') - -%p - = link_to(image_tag("twitter_32.png", :alt => ''), 'http://twitter.com/growstufforg', :target => "_blank") - = t('.twitter_html', link: link_to(t('.twitter_linktext'), 'http://twitter.com/growstufforg', :target => "_blank")) - -%p - = link_to(image_tag("facebook_32.png", :alt => ''), 'https://www.facebook.com/Growstufforg', :target => "_blank") - = t('.facebook_html', link: link_to(t('.facebook_linktext'), 'https://www.facebook.com/Growstufforg', :target => "_blank")) - -%p - = link_to(image_tag("blog_32.png", :alt => ''), 'http://blog.growstuff.org/', :target => "_blank") - = t('.blog_html', link: link_to(t('.blog_linktext'), 'http://blog.growstuff.org/', :target => "_blank")) - -%p - = link_to(image_tag("email_32.png", :alt => ''), 'http://blog.growstuff.org/newsletter', :target => "_blank") - = t('.newsletter_html', link: link_to(t('.newsletter_linktext'), 'http://blog.growstuff.org/newsletter', :target => "_blank")) \ No newline at end of file diff --git a/app/views/home/_members.html.haml b/app/views/home/_members.html.haml index 25cb0867b..cca5829d6 100644 --- a/app/views/home/_members.html.haml +++ b/app/views/home/_members.html.haml @@ -1,4 +1,4 @@ -- cache "interesting_members" do +- cache cache_key_for(Member) do .hidden-xs - members = Member.interesting.first(6) - if members.present? @@ -6,7 +6,7 @@ .row - members.each do |m| - .col-md-6.homepage-members + .col-md-4.homepage-members = render :partial => "members/thumbnail", :locals => { :member => m } %p.text-right diff --git a/app/views/home/_open.html.haml b/app/views/home/_open.html.haml deleted file mode 100644 index fa7c00f57..000000000 --- a/app/views/home/_open.html.haml +++ /dev/null @@ -1,29 +0,0 @@ -%h2= t('.open_source_title') - -%p - = t('.open_source_body_html', why: link_to(t('.why_linktext'), 'http://blog.growstuff.org/2013/02/20/why-growstuff-is-open-source/'), - github: link_to(t('.github_linktext'), 'http://github.com/Growstuff/growstuff'), - site_name: ENV['GROWSTUFF_SITE_NAME'] ) - - -%h2= t('.open_data_title') - -%p - = t('.open_data_body_html', creative_commons_link: link_to(t('.creative_commons_linktext'), 'http://creativecommons.org/licenses/by-sa/3.0/'), - wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/index.php/Open_data'), - api_docs_link: link_to(t('.api_docs_linktext'), 'http://wiki.growstuff.org/index.php/API')) - - - -%h2= t('.get_involved_title') - -%p - = t('.get_involved_body_html', talk_link: link_to(t('.talk_linktext'), 'http://talk.growstuff.org/'), - wiki_link: link_to(t('.wiki_linktext'), 'http://wiki.growstuff.org/')) - - -%h2= t('.support_title') - -%p - = t('.support_body_html', ad_free: link_to(t('.ad_free_linktext'), 'http://wiki.growstuff.org/index.php/Why_no_ads%3F'), - buy_account: link_to(t('.buy_account_linktext'), shop_path)) diff --git a/app/views/home/_seeds.html.haml b/app/views/home/_seeds.html.haml index 52d996373..817af347c 100644 --- a/app/views/home/_seeds.html.haml +++ b/app/views/home/_seeds.html.haml @@ -3,7 +3,7 @@ %h2= t('.title') - - cache "interesting_seeds" do + - cache cache_key_for(Seed) do - if seeds.length > 0 %table.table.table-striped diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 2c7bac88a..931dcec5c 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -17,13 +17,9 @@ = render :partial => 'blurb' .visible-xs = render :partial => 'blurb' -.row - .col-md-8.main + = render :partial => 'crops' = render :partial => 'seeds' = render :partial => 'members' = render :partial => 'discuss' - .col-md-4.sidebar - = render :partial => 'keep_in_touch' - = render :partial => 'open' diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml index d9235ff25..e7dba1d25 100644 --- a/app/views/layouts/_footer.html.haml +++ b/app/views/layouts/_footer.html.haml @@ -1,10 +1,9 @@ .navbar.navbar-default.navbar-bottom .container - %ul.nav.navbar-nav.text-center - %li= link_to "About", "http://wiki.growstuff.org/index.php/About%20Growstuff" - %li= link_to "Contact", url_for(:controller => '/about', :action => 'contact') - %li= link_to "Terms of Service", url_for(:controller => '/policy', :action => 'tos') - %li= link_to "Privacy Policy", url_for(:controller => %'/policy', :action => 'privacy') - %li= link_to "Community Guidelines", url_for(:controller => '/policy', :action => 'community') - %li= link_to "Support/FAQ", url_for(:controller => '/support') - %li= link_to "Open Source", "https://github.com/Growstuff/growstuff" + .row + .col-md-4#about-growstuff + != cms_snippet_content(:footer1) + .col-md-4#policies + != cms_snippet_content(:footer2) + .col-md-4#contact + != cms_snippet_content(:footer3) diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml index d68f6dc73..7560ebeec 100644 --- a/app/views/layouts/_header.html.haml +++ b/app/views/layouts/_header.html.haml @@ -9,7 +9,7 @@ %span.icon-bar %span.icon-bar %a.navbar-brand(href=root_path) - = image_tag("/assets/growstuff-brand.png", :size => "200x50", :alt => ENV['GROWSTUFF_SITE_NAME']) + = image_tag("growstuff-brand.png", :size => "200x50", :alt => ENV['GROWSTUFF_SITE_NAME']) .navbar-collapse.collapse#navbar-collapse %ul.nav.navbar-nav %li.dropdown< @@ -65,12 +65,14 @@ %li= link_to "Sign out", destroy_member_session_path, :method => :delete - else - %li= link_to 'Sign in', new_member_session_path - %li= link_to 'Sign up', new_member_registration_path + %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, :class => 'navbar-form pull-right' do + = 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' + = submit_tag "Search", :class => 'btn sr-only' - # anchor tag for accessibility link to skip the navigation menu %a{:name => 'skipnav'} diff --git a/app/views/layouts/_meta.html.haml b/app/views/layouts/_meta.html.haml index c5313fb8d..13acb28bc 100644 --- a/app/views/layouts/_meta.html.haml +++ b/app/views/layouts/_meta.html.haml @@ -16,5 +16,5 @@ = javascript_include_tag "http://html5shim.googlecode.com/svn/trunk/html5.js" = stylesheet_link_tag "application", :media => "all" - %link(href="/assets/growstuff-apple-touch-icon-precomposed.png" rel="apple-touch-icon-precomposed") - = favicon_link_tag '/assets/favicon.ico' + %link(href="/growstuff-apple-touch-icon-precomposed.png" rel="apple-touch-icon-precomposed") + = favicon_link_tag 'favicon.ico' diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index a3e1fd1d5..66b78017a 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -5,7 +5,7 @@ = render :partial => "layouts/header" = render :partial => "layouts/crowdfunding" - .container + #maincontainer.container .row .col-md-12 - if content_for?(:title) diff --git a/app/views/members/_avatar.html.haml b/app/views/members/_avatar.html.haml index 25c0e3140..da33ac2da 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-rounded img-responsive avatar' ), | + :class => 'img img-responsive avatar' ), | member_path(member) diff --git a/app/views/members/_gardens.html.haml b/app/views/members/_gardens.html.haml index 89ed8f83e..38831922c 100644 --- a/app/views/members/_gardens.html.haml +++ b/app/views/members/_gardens.html.haml @@ -19,6 +19,20 @@ :growstuff_markdown #{ strip_tags g.description } + - if g.photos.count > 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 What's planted here? - g.featured_plantings.each do |p| = render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true } diff --git a/app/views/members/_thumbnail.html.haml b/app/views/members/_thumbnail.html.haml index bbb06f2f7..c90faba8a 100644 --- a/app/views/members/_thumbnail.html.haml +++ b/app/views/members/_thumbnail.html.haml @@ -1,4 +1,4 @@ -- cache "member_thumbnail_#{member.id}" do +- cache member do .row .member-thumbnail .col-md-3 diff --git a/app/views/members/index.html.haml b/app/views/members/index.html.haml index 83a663d47..36ba70887 100644 --- a/app/views/members/index.html.haml +++ b/app/views/members/index.html.haml @@ -1,5 +1,11 @@ = content_for :title, "#{ENV['GROWSTUFF_SITE_NAME']} members" += form_tag(members_path, :method => :get, :class => 'form-inline', :role => 'form') do + .form-group + = label_tag :sort, "Sort by:", :class => 'sr-only' + = select_tag "sort", options_for_select({"Sort alphabetically" => 'alpha', "Sort by recently joined" => "recently_joined"}, @sort || 'alpha'), :class => 'form-control' + = submit_tag "Show", :class => 'btn btn-primary' + %div.pagination = page_entries_info @members, :model => "members" = will_paginate @members diff --git a/app/views/members/show.html.haml b/app/views/members/show.html.haml index 6ddebaeb4..591c2be77 100644 --- a/app/views/members/show.html.haml +++ b/app/views/members/show.html.haml @@ -5,14 +5,16 @@ = link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default' - if @member == current_member && !@member.is_paid? = link_to "Upgrade account", shop_path, :class => 'btn btn-default' - -if can? :create, Notification and current_member != @member - =link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default' - - if can? :create, Follow and current_member != @member - - if !current_member.already_following?(@member) + - if can? :create, Notification and current_member != @member + = link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default' + + - if current_member and current_member != @member # must be logged in, can't follow yourself + - follow = current_member.get_follow(@member) + - if !follow and can? :create, Follow # not already following = link_to 'Follow', follows_path(:followed_id => @member.id), :method => :post, :class => 'btn btn-default' - - else - - follow = current_member.get_follow(@member) + - if follow and can? :destroy, follow # already following = link_to 'Unfollow', follow_path(follow), :method => :delete, :class => 'btn btn-default' + - content_for :member_rss_login_name, @member.login_name - content_for :member_rss_slug, @member.slug diff --git a/app/views/notifier/_signature.html.haml b/app/views/notifier/_signature.html.haml new file mode 100644 index 000000000..14a7d47a7 --- /dev/null +++ b/app/views/notifier/_signature.html.haml @@ -0,0 +1,6 @@ +- site_name = ENV['GROWSTUFF_SITE_NAME'] + +%p + The #{site_name} team. + %br/ + =link_to root_url, root_url diff --git a/app/views/notifier/crop_request_approved.html.haml b/app/views/notifier/crop_request_approved.html.haml new file mode 100644 index 000000000..5fea20246 --- /dev/null +++ b/app/views/notifier/crop_request_approved.html.haml @@ -0,0 +1,16 @@ +- site_name = ENV['GROWSTUFF_SITE_NAME'] +%p Hello #{@member.login_name}, + +%p + Your request for the new crop: #{link_to @crop.name, crop_url(@crop)} has been approved! + +%ul + %li + = link_to "Plant #{@crop.name}", new_planting_url(crop_id: @crop.id) + %li + = link_to "Harvest #{@crop.name}", new_harvest_url(crop_id: @crop.id) + %li + = link_to "Stash seeds for #{@crop.name}", new_seed_url(crop_id: @crop.id) + += render :partial => 'signature' + diff --git a/app/views/notifier/crop_request_rejected.html.haml b/app/views/notifier/crop_request_rejected.html.haml new file mode 100644 index 000000000..c58e2546b --- /dev/null +++ b/app/views/notifier/crop_request_rejected.html.haml @@ -0,0 +1,9 @@ +- site_name = ENV['GROWSTUFF_SITE_NAME'] +%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. + + = @crop.reason_for_rejection + += render :partial => 'signature' \ No newline at end of file diff --git a/app/views/notifier/new_crop_request.html.haml b/app/views/notifier/new_crop_request.html.haml new file mode 100644 index 000000000..163c898f4 --- /dev/null +++ b/app/views/notifier/new_crop_request.html.haml @@ -0,0 +1,21 @@ +- site_name = ENV['GROWSTUFF_SITE_NAME'] + +%p Hello #{@member.login_name}, + +%p + #{@request.requester.login_name} has requested a new crop on #{site_name}. + +%ul + %li Name: #{@request.name} + %li Wikipedia URL: #{@request.en_wikipedia_url.present? ? @request.en_wikipedia_url : "not specified"} + +%p + As a crop wrangler, you can #{link_to "approve or reject this request", edit_crop_url(@request)}. + +%p + Or, discuss this and other crop wrangling issues in our #{link_to "crop wrangling forum", "http://talk.growstuff.org/c/crop-wrangling"}. + +%p + Thanks for your help! + += render :partial => 'signature' \ No newline at end of file diff --git a/app/views/notifier/notify.html.haml b/app/views/notifier/notify.html.haml index b6e962fb3..ed9cf32f2 100644 --- a/app/views/notifier/notify.html.haml +++ b/app/views/notifier/notify.html.haml @@ -20,7 +20,4 @@ %br/ = link_to "Turn off these notifications", edit_member_registration_url -%p - The #{site_name} team. - %br/ - =link_to root_url, root_url += 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 7edf063b5..4dea05123 100644 --- a/app/views/notifier/planting_reminder.html.haml +++ b/app/views/notifier/planting_reminder.html.haml @@ -59,10 +59,7 @@ %h2 See you soon on #{site_name}! -%p - The #{site_name} team. - %br/ - =link_to root_url, root_url += render :partial => 'signature' %hr/ %p diff --git a/app/views/photos/_thumbnail.html.haml b/app/views/photos/_thumbnail.html.haml index fd331fd77..5efd7fdbd 100644 --- a/app/views/photos/_thumbnail.html.haml +++ b/app/views/photos/_thumbnail.html.haml @@ -1,5 +1,5 @@ -.thumbnail.crop-thumbnail - = link_to image_tag(photo.thumbnail_url, :alt => photo.title, :class => 'img-rounded img-responsive'), photo +.thumbnail.photo-thumbnail + = link_to image_tag(photo.thumbnail_url, :alt => photo.title, :class => 'img img-responsive'), photo .text %p = link_to photo.title, photo diff --git a/app/views/photos/index.html.haml b/app/views/photos/index.html.haml index 023c102e2..10a14f88e 100644 --- a/app/views/photos/index.html.haml +++ b/app/views/photos/index.html.haml @@ -10,7 +10,7 @@ - @photos.each do |p| .col-md-2.six-across .thumbnail(style='height: 220px') - = link_to image_tag(p.thumbnail_url, :alt => p.title, :class => 'img-rounded'), p + = link_to image_tag(p.thumbnail_url, :alt => p.title, :class => 'img'), p %p = link_to p.title, p by diff --git a/app/views/photos/new.html.haml b/app/views/photos/new.html.haml index 7b89997be..6b4e589b0 100644 --- a/app/views/photos/new.html.haml +++ b/app/views/photos/new.html.haml @@ -27,7 +27,7 @@ - @photos.each do |p| .col-md-2.six-across .thumbnail(style='height: 220px') - = link_to image_tag(FlickRaw.url_q(p), :alt => '', :class => 'img-rounded'), photos_path(:photo => { :flickr_photo_id => p.id }, :type => @type, :id => @id), :method => :post + = link_to image_tag(FlickRaw.url_q(p), :alt => '', :class => 'img'), photos_path(:photo => { :flickr_photo_id => p.id }, :type => @type, :id => @id), :method => :post %p =p.title diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml index 4d510df15..ad331bd48 100644 --- a/app/views/photos/show.html.haml +++ b/app/views/photos/show.html.haml @@ -27,5 +27,5 @@ .row .col-md-12 - %p= image_tag(@photo.fullsize_url, :alt => @photo.title, :class => 'img-rounded') + %p= image_tag(@photo.fullsize_url, :alt => @photo.title, :class => 'img') diff --git a/app/views/plantings/_image_with_popover.html.haml b/app/views/plantings/_image_with_popover.html.haml index 01d39128e..0e9b46a7d 100644 --- a/app/views/plantings/_image_with_popover.html.haml +++ b/app/views/plantings/_image_with_popover.html.haml @@ -1,4 +1,4 @@ -- cache "planting_image_#{planting.id}" do +- cache planting do = link_to | image_tag( | planting.photos.present? ? planting.photos.first.thumbnail_url : 'placeholder_150.png', | diff --git a/app/views/plantings/_list.html.haml b/app/views/plantings/_list.html.haml index 0efc1be37..2ea1204ff 100644 --- a/app/views/plantings/_list.html.haml +++ b/app/views/plantings/_list.html.haml @@ -1,5 +1,5 @@ - plantings.each do |p| - - cache "plantings_listitem_#{p.id}" do + - cache p do .row .col-md-3{:style => 'padding-bottom: 6px'} = render :partial => 'plantings/image_with_popover', :locals => { :planting => p } diff --git a/app/views/plantings/_thumbnail.html.haml b/app/views/plantings/_thumbnail.html.haml index fd34b0703..f1b67c2cb 100644 --- a/app/views/plantings/_thumbnail.html.haml +++ b/app/views/plantings/_thumbnail.html.haml @@ -1,7 +1,7 @@ .well .row .col-md-3 - = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img-rounded'), planting + = link_to image_tag((planting.default_photo ? planting.default_photo.thumbnail_url : 'placeholder_150.png'), :alt => '', :class => 'img'), planting .col-md-9 %h4 diff --git a/app/views/posts/_summary.html.haml b/app/views/posts/_summary.html.haml index 6e8e30895..f04dd2fb0 100644 --- a/app/views/posts/_summary.html.haml +++ b/app/views/posts/_summary.html.haml @@ -8,13 +8,14 @@ %th.hidden-xs Comments - posts.recently_active[0..howmany-1].each do |post| - %tr - %td - = link_to truncate(strip_tags(post.subject), :length => 40, :separator => ' '), post - %td.hidden-xs - =link_to post.author, post.author - %td - = distance_of_time_in_words(post.recent_activity, Time.zone.now) - ago - %td.hidden-xs - = post.comments.count.to_s + - cache post do + %tr + %td + = link_to truncate(strip_tags(post.subject), :length => 40, :separator => ' '), post + %td.hidden-xs + =link_to post.author, post.author + %td + = distance_of_time_in_words(post.recent_activity, Time.zone.now) + ago + %td.hidden-xs + = post.comments.count.to_s diff --git a/app/views/posts/show.html.haml b/app/views/posts/show.html.haml index 16421996b..b6e07bde7 100644 --- a/app/views/posts/show.html.haml +++ b/app/views/posts/show.html.haml @@ -1,5 +1,19 @@ = content_for :title, @post.subject +- unless current_member + .alert.alert-info + = link_to @post.author.login_name, member_path(@post.author) + is using + = link_to ENV["GROWSTUFF_SITE_NAME"], root_path + to discuss #{ @post.subject } with a community of food gardeners worldwide. + We have advice on growing + = succeed "," do + = link_to 'hundreds of different crops', crops_url + and a community from all around the world. + + = render :partial => "shared/signin_signup", + :locals => { :to => "or to start using #{ENV["GROWSTUFF_SITE_NAME"]} to track what you're planting and harvesting" } + = render :partial => "single", :locals => { :post => @post, :subject => false, :hide_comments => true } - if can? :edit, @post or can? :destroy, @post diff --git a/app/views/seeds/_days_until_maturity.html.haml b/app/views/seeds/_days_until_maturity.html.haml new file mode 100644 index 000000000..b8db4a203 --- /dev/null +++ b/app/views/seeds/_days_until_maturity.html.haml @@ -0,0 +1,9 @@ +- if seed.days_until_maturity_min.blank? + - if seed.days_until_maturity_max.blank? + unknown + - else + = seed.days_until_maturity_max.to_s +- elsif seed.days_until_maturity_max.blank? + = seed.days_until_maturity_min.to_s +- else + != "#{seed.days_until_maturity_min}–#{seed.days_until_maturity_max}" diff --git a/app/views/seeds/_form.html.haml b/app/views/seeds/_form.html.haml index 642a5de01..8d8eeaa97 100644 --- a/app/views/seeds/_form.html.haml +++ b/app/views/seeds/_form.html.haml @@ -21,6 +21,29 @@ = 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) : '' + .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' + .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' + .col-md-1 + = f.label :dummy, 'days', :class => 'control-label' + .form-group + = 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 + = 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 + = 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 diff --git a/app/views/seeds/show.html.haml b/app/views/seeds/show.html.haml index 7db91c1a6..c2f3399ea 100644 --- a/app/views/seeds/show.html.haml +++ b/app/views/seeds/show.html.haml @@ -13,6 +13,18 @@ %p %b Plant before: = @seed.plant_before.to_s + %p + %b Days until maturity: + = render :partial => 'days_until_maturity', :locals => { :seed => @seed } + %p + %b Organic? + = @seed.organic + %p + %b GMO? + = @seed.gmo + %p + %b Heirloom? + = @seed.heirloom %p %b Will trade: = @seed.tradable_to diff --git a/app/views/shared/_account_status.html.haml b/app/views/shared/_account_status.html.haml index 5ee44faff..7c14f7d4a 100644 --- a/app/views/shared/_account_status.html.haml +++ b/app/views/shared/_account_status.html.haml @@ -9,5 +9,5 @@ %strong Paid until: = current_member.account.paid_until_string -- if ! current_member.is_paid? +- if !current_member.is_paid? = link_to "Upgrade and support #{ENV['GROWSTUFF_SITE_NAME']}", shop_path, :class => 'btn btn-primary' diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..728cd85aa --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..17240489f --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/config/application.rb b/config/application.rb index 5b01d3aa8..113d0bc66 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,6 +1,7 @@ require File.expand_path('../boot', __FILE__) require 'rails/all' +require 'openssl' if defined?(Bundler) # If you precompile assets before deploying to production, use this line @@ -25,6 +26,8 @@ module Growstuff # Activate observers that should always be running. # config.active_record.observers = :cacher, :garbage_collector, :forum_observer + I18n.config.enforce_available_locales = true + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. config.time_zone = 'UTC' @@ -59,7 +62,7 @@ module Growstuff # This will create an empty whitelist of attributes available for mass-assignment for all models # in your app. As such, your models will need to explicitly whitelist or blacklist accessible # parameters by using an attr_accessible or attr_protected declaration. - config.active_record.whitelist_attributes = true + # config.active_record.whitelist_attributes = true # Enable the asset pipeline config.assets.enabled = true diff --git a/config/application.yml.example b/config/application.yml.example index f00978be0..03e8afe2c 100644 --- a/config/application.yml.example +++ b/config/application.yml.example @@ -62,6 +62,13 @@ GROWSTUFF_PAYPAL_USERNAME: "dummy" GROWSTUFF_PAYPAL_PASSWORD: "dummy" GROWSTUFF_PAYPAL_SIGNATURE: "dummy" +# Elasticsearch is used for flexible search and it requires another component +# to be installed. To make it easy for people who don't need to test this feature +# it's been turned off for test and development environment as a default. +# If you want to test this functionality, install elasticsearch and +# set this flag to "true". +GROWSTUFF_ELASTICSEARCH: "false" + ############################################################################## # Other environments # You can override the above for staging, production, etc. @@ -78,6 +85,8 @@ test: staging: GROWSTUFF_SITE_NAME: Growstuff (staging) + GROWSTUFF_ELASTICSEARCH: "true" production: GROWSTUFF_SITE_NAME: Growstuff + GROWSTUFF_ELASTICSEARCH: "true" diff --git a/config/environments/development.rb b/config/environments/development.rb index 7b25f588c..45d7b96bf 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,14 +1,14 @@ Growstuff::Application.configure do # Settings specified here will take precedence over those in config/application.rb + # Do not eager load code on boot. + config.eager_load = false + # In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true @@ -25,19 +25,24 @@ Growstuff::Application.configure do # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - config.active_record.auto_explain_threshold_in_seconds = 0.5 - # Do not compress assets config.assets.compress = false # Expands the lines which load the assets config.assets.debug = true + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + # 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' } @@ -68,4 +73,6 @@ Growstuff::Application.configure do ::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options) ::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options) end + + config.action_controller.action_on_unpermitted_parameters = :raise end diff --git a/config/environments/production.rb b/config/environments/production.rb index a5b131a4b..523418b32 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,6 +1,12 @@ Growstuff::Application.configure do # Settings specified here will take precedence over those in config/application.rb + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + # Code is not reloaded between requests config.cache_classes = true @@ -11,8 +17,9 @@ Growstuff::Application.configure do # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false - # Compress JavaScripts and CSS - config.assets.compress = true + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + config.assets.css_compressor = :sass # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = true @@ -20,9 +27,6 @@ Growstuff::Application.configure do # Generate digests for assets URLs config.assets.digest = true - # Defaults to nil and saved in location specified by config.assets.prefix - # config.assets.manifest = YOUR_PATH - # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx @@ -45,15 +49,10 @@ Growstuff::Application.configure do # Enable serving of images, stylesheets, and JavaScripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) - # config.assets.precompile += %w( search.js ) - - # Disable delivery errors, bad email addresses will be ignored + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode - # config.threadsafe! - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true @@ -61,9 +60,11 @@ Growstuff::Application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + 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" diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 6e00f6327..150c62d8c 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -1,6 +1,14 @@ Growstuff::Application.configure do # Settings specified here will take precedence over those in config/application.rb + config.action_controller.action_on_unpermitted_parameters = :raise + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + # Code is not reloaded between requests config.cache_classes = true @@ -11,8 +19,9 @@ Growstuff::Application.configure do # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false - # Compress JavaScripts and CSS - config.assets.compress = true + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + config.assets.css_compressor = :sass # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = true @@ -20,9 +29,6 @@ Growstuff::Application.configure do # Generate digests for assets URLs config.assets.digest = true - # Defaults to nil and saved in location specified by config.assets.prefix - # config.assets.manifest = YOUR_PATH - # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx @@ -45,15 +51,10 @@ Growstuff::Application.configure do # Enable serving of images, stylesheets, and JavaScripts from an asset server # config.action_controller.asset_host = "http://assets.example.com" - # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) - # config.assets.precompile += %w( search.js ) - - # Disable delivery errors, bad email addresses will be ignored + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode - # config.threadsafe! - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) config.i18n.fallbacks = true @@ -61,9 +62,11 @@ Growstuff::Application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false # Growstuff configuration config.new_crops_request_link = "http://example.com/not-a-real-url" diff --git a/config/environments/test.rb b/config/environments/test.rb index 6fb8cad3e..ffdc4c972 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,6 +1,11 @@ Growstuff::Application.configure do # Settings specified here will take precedence over those in config/application.rb + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that # your test database is "scratch space" for the test suite and is wiped @@ -13,9 +18,6 @@ Growstuff::Application.configure do config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false @@ -31,12 +33,12 @@ Growstuff::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Raise exception on mass assignment protection for Active Record models - config.active_record.mass_assignment_sanitizer = :strict - # Print deprecation notices to the stderr config.active_support.deprecation = :stderr + # Raises error for missing translations + # 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' } diff --git a/config/initializers/comfortable_mexican_sofa.rb b/config/initializers/comfortable_mexican_sofa.rb new file mode 100644 index 000000000..fe6e80ace --- /dev/null +++ b/config/initializers/comfortable_mexican_sofa.rb @@ -0,0 +1,103 @@ +# encoding: utf-8 + +ComfortableMexicanSofa.configure do |config| + # Title of the admin area + # config.cms_title = 'ComfortableMexicanSofa CMS Engine' + + # Controller that is inherited from CmsAdmin::BaseController + # config.base_controller = 'ApplicationController' + + # Module responsible for authentication. You can replace it with your own. + # It simply needs to have #authenticate method. See http_auth.rb for reference. + config.admin_auth = 'CmsDeviseAuth' + + # Module responsible for authorization on admin side. It should have #authorize + # method that returns true or false based on params and loaded instance + # variables available for a given controller. + # config.admin_authorization = 'ComfyAdminAuthorization' + + # Module responsible for public authentication. Similar to the above. You also + # will have access to @cms_site, @cms_layout, @cms_page so you can use them in + # your logic. Default module doesn't do anything. + # config.public_auth = 'ComfyPublicAuthentication' + + # When arriving at /cms-admin you may chose to redirect to arbirtary path, + # for example '/cms-admin/users' + # config.admin_route_redirect = '' + + # File uploads use Paperclip and can support filesystem or s3 uploads. Override + # the upload method and appropriate settings based on Paperclip. For S3 see: + # http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/S3, and for + # filesystem see: http://rdoc.info/gems/paperclip/2.3.8/Paperclip/Storage/Filesystem + # If you are using S3 and HTTPS, pass :s3_protocol => '' to have URLs that use the protocol of the page + # config.upload_file_options = {:url => '/system/:class/:id/:attachment/:style/:filename'} + + # Sofa allows you to setup entire site from files. Database is updated with each + # request (if necessary). Please note that database entries are destroyed if there's + # no corresponding file. Fixtures are disabled by default. + # config.enable_fixtures = false + + # Path where fixtures can be located. + # config.fixtures_path = File.expand_path('db/cms_fixtures', Rails.root) + + # Importing fixtures into Database + # To load fixtures into the database just run this rake task: + # local: $ rake comfortable_mexican_sofa:fixtures:import FROM=example.local TO=localhost + # Heroku: $ heroku run rake comfortable_mexican_sofa:fixtures:import FROM=example.local TO=yourapp.herokuapp.com + # From indicates folder the fixtures are in and to is the Site hostname you have defined in the database. + + # Exporting fixtures into Files + # If you need to dump database contents into fixture files run: + # local: $ rake comfortable_mexican_sofa:fixtures:export FROM=localhost TO=example.local + # Heroku: $ heroku run rake comfortable_mexican_sofa:fixtures:export FROM=yourapp.herokuapp.com TO=example.local + # This will create example.local folder and dump all content from example.com Site. + + # Content for Layouts, Pages and Snippets has a revision history. You can revert + # a previous version using this system. You can control how many revisions per + # object you want to keep. Set it to 0 if you wish to turn this feature off. + # config.revisions_limit = 25 + + # Locale definitions. If you want to define your own locale merge + # {:locale => 'Locale Title'} with this. + # config.locales = {:en => 'English', :es => 'Español'} + + # Admin interface will respect the locale of the site being managed. However you can + # force it to English by setting this to `:en` + # config.admin_locale = nil + + # A class that is included as a sweeper to admin base controller if it's set + # config.admin_cache_sweeper = nil + + # By default you cannot have irb code inside your layouts/pages/snippets. + # Generally this is to prevent putting something like this: + # <% User.delete_all %> but if you really want to allow it... + # config.allow_irb = false + + # Whitelist of all helper methods that can be used via {{cms:helper}} tag. By default + # all helpers are allowed except `eval`, `send`, `call` and few others. Empty array + # will prevent rendering of all helpers. + # config.allowed_helpers = nil + + # Whitelist of partials paths that can be used via {{cms:partial}} tag. All partials + # are accessible by default. Empty array will prevent rendering of all partials. + # config.allowed_partials = nil + + # Site aliases, if you want to have aliases for your site. Good for harmonizing + # production env with dev/testing envs. + # e.g. config.hostname_aliases = {'host.com' => 'host.inv', 'host_a.com' => ['host.lvh.me', 'host.dev']} + # Default is nil (not used) + # config.hostname_aliases = nil + + # Reveal partials that can be overwritten in the admin area. + # Default is false. + # config.reveal_cms_partials = false + +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.' + end + end +end diff --git a/config/initializers/friendly_id.rb b/config/initializers/friendly_id.rb new file mode 100644 index 000000000..3a88f87be --- /dev/null +++ b/config/initializers/friendly_id.rb @@ -0,0 +1,88 @@ +# FriendlyId Global Configuration +# +# Use this to set up shared configuration options for your entire application. +# Any of the configuration options shown here can also be applied to single +# models by passing arguments to the `friendly_id` class method or defining +# methods in your model. +# +# To learn more, check out the guide: +# +# http://norman.github.io/friendly_id/file.Guide.html + +FriendlyId.defaults do |config| + # ## Reserved Words + # + # Some words could conflict with Rails's routes when used as slugs, or are + # undesirable to allow as slugs. Edit this list as needed for your app. + # config.use :reserved + + # config.reserved_words = %w(new edit index session login logout users admin + # stylesheets assets javascripts images) + + # ## Friendly Finders + # + # Uncomment this to use friendly finders in all models. By default, if + # you wish to find a record by its friendly id, you must do: + # + # MyModel.friendly.find('foo') + # + # If you uncomment this, you can do: + # + # MyModel.find('foo') + # + # This is significantly more convenient but may not be appropriate for + # all applications, so you must explicity opt-in to this behavior. You can + # always also configure it on a per-model basis if you prefer. + # + # Something else to consider is that using the :finders addon boosts + # performance because it will avoid Rails-internal code that makes runtime + # calls to `Module.extend`. + # + # config.use :finders + # + # ## Slugs + # + # Most applications will use the :slugged module everywhere. If you wish + # to do so, uncomment the following line. + # + # config.use :slugged + # + # By default, FriendlyId's :slugged addon expects the slug column to be named + # 'slug', but you can change it if you wish. + # + # config.slug_column = 'slug' + # + # When FriendlyId can not generate a unique ID from your base method, it appends + # a UUID, separated by a single dash. You can configure the character used as the + # separator. If you're upgrading from FriendlyId 4, you may wish to replace this + # with two dashes. + # + # config.sequence_separator = '-' + # + # ## Tips and Tricks + # + # ### Controlling when slugs are generated + # + # As of FriendlyId 5.0, new slugs are generated only when the slug field is + # nil, but if you're using a column as your base method can change this + # behavior by overriding the `should_generate_new_friendly_id` method that + # FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave + # more like 4.0. + # + # config.use Module.new { + # def should_generate_new_friendly_id? + # slug.blank? || _changed? + # end + # } + # + # FriendlyId uses Rails's `parameterize` method to generate slugs, but for + # languages that don't use the Roman alphabet, that's not usually suffient. Here + # we use the Babosa library to transliterate Russian Cyrillic slugs to ASCII. If + # you use this, don't forget to add "babosa" to your Gemfile. + # + # config.use Module.new { + # def normalize_friendly_id(text) + # text.to_slug.normalize! :transliterations => [:russian, :latin] + # end + # } +end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 1d78b7ba8..caaa7c059 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -16,4 +16,11 @@ ActiveSupport::Inflector.inflections do |inflect| inflect.plural 'square foot', 'square feet' + inflect.plural 'broccoli', 'broccoli' + inflect.plural 'kale', 'kale' + inflect.plural 'squash', 'squash' + inflect.plural 'bok choy', 'bok choy' + inflect.plural 'achiote', 'achiote' + inflect.plural 'alfalfa', 'alfalfa' + inflect.plural 'allspice', 'allspice' end diff --git a/config/locales/en.yml b/config/locales/en.yml index dcf4c7e9f..84f8cf9e0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -14,8 +14,22 @@ en: manage: all: "Not authorized to %{action} %{subject}." + layouts: + 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: + blurb: intro: "%{site_name} is a community of food gardeners. We're building an open source platform to help you learn about growing food, track what you plant and harvest, and swap seeds and produce with other gardeners near you." perks: "Join now for your free garden journal, seed sharing, forums, and more." sign_up: "Sign up" @@ -33,16 +47,6 @@ en: forums: "Forums" view_all: "View all posts" - keep_in_touch: - keep_in_touch: "Keep in touch" - twitter_html: "Follow %{link} on Twitter" - twitter_linktext: "@growstufforg" - facebook_html: "Like us on %{link}" - facebook_linktext: "Facebook" - blog_html: "Subscribe to the %{link}" - blog_linktext: "Growstuff Blog" - newsletter_html: "Subscribe to our %{link}" - newsletter_linktext: "email newsletter" members: title: "Some of our members" view_all: "View all members" diff --git a/config/routes.rb b/config/routes.rb index 1b9c30c05..69680ae2d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,6 @@ Growstuff::Application.routes.draw do + resources :plant_parts devise_for :members, :controllers => { :registrations => "registrations", :passwords => "passwords" } @@ -8,32 +9,32 @@ Growstuff::Application.routes.draw do resources :photos - resources :authentications + resources :authentications, :only => [:create, :destroy] resources :plantings - match '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner' - match '/plantings/crop/:crop' => 'plantings#index', :as => 'plantings_by_crop' + get '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner' + get '/plantings/crop/:crop' => 'plantings#index', :as => 'plantings_by_crop' resources :gardens - match '/gardens/owner/:owner' => 'gardens#index', :as => 'gardens_by_owner' + get '/gardens/owner/:owner' => 'gardens#index', :as => 'gardens_by_owner' resources :seeds - match '/seeds/owner/:owner' => 'seeds#index', :as => 'seeds_by_owner' - match '/seeds/crop/:crop' => 'seeds#index', :as => 'seeds_by_crop' + get '/seeds/owner/:owner' => 'seeds#index', :as => 'seeds_by_owner' + get '/seeds/crop/:crop' => 'seeds#index', :as => 'seeds_by_crop' resources :harvests - match '/harvests/owner/:owner' => 'harvests#index', :as => 'harvests_by_owner' - match '/harvests/crop/:crop' => 'harvests#index', :as => 'harvests_by_crop' + get '/harvests/owner/:owner' => 'harvests#index', :as => 'harvests_by_owner' + get '/harvests/crop/:crop' => 'harvests#index', :as => 'harvests_by_crop' resources :posts - match '/posts/author/:author' => 'posts#index', :as => 'posts_by_author' + get '/posts/author/:author' => 'posts#index', :as => 'posts_by_author' resources :scientific_names resources :alternate_names - match 'crops/wrangle' => 'crops#wrangle', :as => 'wrangle_crops' - match 'crops/hierarchy' => 'crops#hierarchy', :as => 'crops_hierarchy' - match 'crops/search' => 'crops#search', :as => 'crops_search' + get 'crops/wrangle' => 'crops#wrangle', :as => 'wrangle_crops' + get 'crops/hierarchy' => 'crops#hierarchy', :as => 'crops_hierarchy' + get 'crops/search' => 'crops#search', :as => 'crops_search' resources :crops resources :comments @@ -54,9 +55,9 @@ Growstuff::Application.routes.draw do resources :account_types resources :accounts resources :orders - match 'orders/:id/checkout' => 'orders#checkout', :as => 'checkout_order' - match 'orders/:id/complete' => 'orders#complete', :as => 'complete_order' - match 'orders/:id/cancel' => 'orders#cancel', :as => 'cancel_order' + get 'orders/:id/checkout' => 'orders#checkout', :as => 'checkout_order' + get 'orders/:id/complete' => 'orders#complete', :as => 'complete_order' + get 'orders/:id/cancel' => 'orders#cancel', :as => 'cancel_order' resources :order_items resources :products @@ -64,26 +65,28 @@ Growstuff::Application.routes.draw do get "home/index" root :to => 'home#index' - match 'auth/:provider/callback' => 'authentications#create' + get 'auth/:provider/callback' => 'authentications#create' - match '/policy/:action' => 'policy#:action' + get '/policy/:action' => 'policy#:action' - match '/support' => 'support#index' - match '/support/:action' => 'support#:action' + get '/support' => 'support#index' + get '/support/:action' => 'support#:action' - match '/about' => 'about#index' - match '/about/:action' => 'about#:action' + get '/about' => 'about#index' + get '/about/:action' => 'about#:action' - match '/shop' => 'shop#index' - match '/shop/:action' => 'shop#:action' - - match '/admin/orders' => 'admin/orders#index' - match '/admin/orders/:action' => 'admin/orders#:action' - match '/admin' => 'admin#index' - match '/admin/newsletter' => 'admin#newsletter', :as => :admin_newsletter - match '/admin/:action' => 'admin#:action' + get '/shop' => 'shop#index' + get '/shop/:action' => 'shop#:action' + get '/admin/orders' => 'admin/orders#index' + get '/admin/orders/:action' => 'admin/orders#:action' + get '/admin' => 'admin#index' + get '/admin/newsletter' => 'admin#newsletter', :as => :admin_newsletter + get '/admin/:action' => 'admin#:action' +# CMS stuff -- must remain LAST + comfy_route :cms_admin, :path => '/cms/admin' + comfy_route :cms, :path => '/', :sitemap => false end diff --git a/db/migrate/20150124110540_add_properties_to_seeds.rb b/db/migrate/20150124110540_add_properties_to_seeds.rb new file mode 100644 index 000000000..e2fa64fe7 --- /dev/null +++ b/db/migrate/20150124110540_add_properties_to_seeds.rb @@ -0,0 +1,9 @@ +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' + end +end diff --git a/db/migrate/20150127043022_add_gardens_photos_table.rb b/db/migrate/20150127043022_add_gardens_photos_table.rb new file mode 100644 index 000000000..c0cfd76fc --- /dev/null +++ b/db/migrate/20150127043022_add_gardens_photos_table.rb @@ -0,0 +1,9 @@ +class AddGardensPhotosTable < ActiveRecord::Migration + def change + create_table :gardens_photos, :id => false do |t| + t.integer :photo_id + t.integer :garden_id + end + add_index(:gardens_photos, [:garden_id, :photo_id]) + end +end diff --git a/db/migrate/20150129034206_add_si_weight_to_harvest.rb b/db/migrate/20150129034206_add_si_weight_to_harvest.rb new file mode 100644 index 000000000..b1e532d8d --- /dev/null +++ b/db/migrate/20150129034206_add_si_weight_to_harvest.rb @@ -0,0 +1,5 @@ +class AddSiWeightToHarvest < ActiveRecord::Migration + def change + add_column :harvests, :si_weight, :float + end +end diff --git a/db/migrate/20150130224814_add_requester_to_crops.rb b/db/migrate/20150130224814_add_requester_to_crops.rb new file mode 100644 index 000000000..f284a6f68 --- /dev/null +++ b/db/migrate/20150130224814_add_requester_to_crops.rb @@ -0,0 +1,6 @@ +class AddRequesterToCrops < ActiveRecord::Migration + def change + add_column :crops, :requester_id, :integer + add_index :crops, :requester_id + end +end diff --git a/db/migrate/20150201052245_create_cms.rb b/db/migrate/20150201052245_create_cms.rb new file mode 100644 index 000000000..9e999488f --- /dev/null +++ b/db/migrate/20150201052245_create_cms.rb @@ -0,0 +1,140 @@ +class CreateCms < ActiveRecord::Migration + + def self.up + + text_limit = case ActiveRecord::Base.connection.adapter_name + when 'PostgreSQL' + { } + else + { :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 :path + 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 :parent_id + t.string :app_layout + 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.timestamps + end + add_index :comfy_cms_layouts, [:parent_id, :position] + 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 :layout_id + t.integer :parent_id + t.integer :target_page_id + t.string :label, :null => false + t.string :slug + 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.timestamps + end + add_index :comfy_cms_pages, [:site_id, :full_path] + add_index :comfy_cms_pages, [:parent_id, :position] + + # -- Page Blocks -------------------------------------------------------- + create_table :comfy_cms_blocks do |t| + t.string :identifier, :null => false + t.text :content, text_limit + t.references :blockable, :polymorphic => true + t.timestamps + end + add_index :comfy_cms_blocks, [:identifier] + add_index :comfy_cms_blocks, [:blockable_id, :blockable_type] + + # -- 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.text :content, text_limit + 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, :position] + + # -- Files -------------------------------------------------------------- + create_table :comfy_cms_files do |t| + 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.timestamps + end + add_index :comfy_cms_files, [:site_id, :label] + add_index :comfy_cms_files, [:site_id, :file_file_name] + add_index :comfy_cms_files, [:site_id, :position] + 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 + 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' + + # -- 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 + 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' + + 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' + end + + def self.down + drop_table :comfy_cms_sites + drop_table :comfy_cms_layouts + drop_table :comfy_cms_pages + drop_table :comfy_cms_snippets + drop_table :comfy_cms_blocks + drop_table :comfy_cms_files + drop_table :comfy_cms_revisions + drop_table :comfy_cms_categories + drop_table :comfy_cms_categorizations + end +end + diff --git a/db/migrate/20150201053200_add_approval_status_to_crops.rb b/db/migrate/20150201053200_add_approval_status_to_crops.rb new file mode 100644 index 000000000..07b1e0879 --- /dev/null +++ b/db/migrate/20150201053200_add_approval_status_to_crops.rb @@ -0,0 +1,5 @@ +class AddApprovalStatusToCrops < ActiveRecord::Migration + def change + add_column :crops, :approval_status, :string, default: "approved" + end +end diff --git a/db/migrate/20150201062506_add_reason_for_rejection_to_crops.rb b/db/migrate/20150201062506_add_reason_for_rejection_to_crops.rb new file mode 100644 index 000000000..0fd283a67 --- /dev/null +++ b/db/migrate/20150201062506_add_reason_for_rejection_to_crops.rb @@ -0,0 +1,5 @@ +class AddReasonForRejectionToCrops < ActiveRecord::Migration + def change + add_column :crops, :reason_for_rejection, :text + end +end diff --git a/db/migrate/20150201064502_add_request_notes_to_crops.rb b/db/migrate/20150201064502_add_request_notes_to_crops.rb new file mode 100644 index 000000000..0720bf4cb --- /dev/null +++ b/db/migrate/20150201064502_add_request_notes_to_crops.rb @@ -0,0 +1,5 @@ +class AddRequestNotesToCrops < ActiveRecord::Migration + def change + add_column :crops, :request_notes, :text + end +end diff --git a/db/migrate/20150209105410_add_rejection_notes_to_crops.rb b/db/migrate/20150209105410_add_rejection_notes_to_crops.rb new file mode 100644 index 000000000..59239fd55 --- /dev/null +++ b/db/migrate/20150209105410_add_rejection_notes_to_crops.rb @@ -0,0 +1,5 @@ +class AddRejectionNotesToCrops < ActiveRecord::Migration + def change + add_column :crops, :rejection_notes, :text + end +end diff --git a/db/schema.rb b/db/schema.rb index cd0dd7466..7f8c479ce 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,103 +9,231 @@ # from scratch. The latter is a flawed and unsustainable approach (the more migrations # you'll amass, the slower it'll run and the greater likelihood for issues). # -# It's strongly recommended to check this file into your version control system. +# It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(:version => 20141119130555) do +ActiveRecord::Schema.define(version: 20150209105410) do - create_table "account_types", :force => true do |t| - t.string "name", :null => false + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "account_types", force: true do |t| + t.string "name", null: false t.boolean "is_paid" t.boolean "is_permanent_paid" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "accounts", :force => true do |t| - t.integer "member_id", :null => false + create_table "accounts", force: true do |t| + t.integer "member_id", null: false t.integer "account_type_id" t.datetime "paid_until" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "alternate_names", :force => true do |t| - t.string "name", :null => false - t.integer "crop_id", :null => false - t.integer "creator_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "alternate_names", force: true do |t| + t.string "name", null: false + t.integer "crop_id", null: false + t.integer "creator_id", null: false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "authentications", :force => true do |t| - t.integer "member_id", :null => false - t.string "provider", :null => false + create_table "authentications", force: true do |t| + t.integer "member_id", null: false + t.string "provider", null: false t.string "uid" t.string "token" t.string "secret" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "name" end - add_index "authentications", ["member_id"], :name => "index_authentications_on_member_id" + add_index "authentications", ["member_id"], name: "index_authentications_on_member_id", using: :btree - create_table "comments", :force => true do |t| - t.integer "post_id", :null => false - t.integer "author_id", :null => false - t.text "body", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "comfy_cms_blocks", force: true do |t| + t.string "identifier", null: false + t.text "content" + t.integer "blockable_id" + t.string "blockable_type" + t.datetime "created_at" + t.datetime "updated_at" end - create_table "crops", :force => true do |t| - t.string "name", :null => false + add_index "comfy_cms_blocks", ["blockable_id", "blockable_type"], name: "index_comfy_cms_blocks_on_blockable_id_and_blockable_type", using: :btree + add_index "comfy_cms_blocks", ["identifier"], name: "index_comfy_cms_blocks_on_identifier", using: :btree + + 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"], name: "index_cms_categories_on_site_id_and_cat_type_and_label", unique: true, using: :btree + + 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"], name: "index_cms_categorizations_on_cat_id_and_catd_type_and_catd_id", unique: true, using: :btree + + create_table "comfy_cms_files", force: true do |t| + 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", default: 0, null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "comfy_cms_files", ["site_id", "block_id"], name: "index_comfy_cms_files_on_site_id_and_block_id", using: :btree + add_index "comfy_cms_files", ["site_id", "file_file_name"], name: "index_comfy_cms_files_on_site_id_and_file_file_name", using: :btree + add_index "comfy_cms_files", ["site_id", "label"], name: "index_comfy_cms_files_on_site_id_and_label", using: :btree + add_index "comfy_cms_files", ["site_id", "position"], name: "index_comfy_cms_files_on_site_id_and_position", using: :btree + + create_table "comfy_cms_layouts", force: true do |t| + 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.text "content" + t.text "css" + t.text "js" + t.integer "position", default: 0, null: false + t.boolean "is_shared", default: false, null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "comfy_cms_layouts", ["parent_id", "position"], name: "index_comfy_cms_layouts_on_parent_id_and_position", using: :btree + add_index "comfy_cms_layouts", ["site_id", "identifier"], name: "index_comfy_cms_layouts_on_site_id_and_identifier", unique: true, using: :btree + + create_table "comfy_cms_pages", force: true do |t| + 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 "slug" + t.string "full_path", null: false + t.text "content_cache" + t.integer "position", default: 0, null: false + t.integer "children_count", default: 0, null: false + t.boolean "is_published", default: true, null: false + t.boolean "is_shared", default: false, null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "comfy_cms_pages", ["parent_id", "position"], name: "index_comfy_cms_pages_on_parent_id_and_position", using: :btree + add_index "comfy_cms_pages", ["site_id", "full_path"], name: "index_comfy_cms_pages_on_site_id_and_full_path", using: :btree + + create_table "comfy_cms_revisions", force: true do |t| + t.string "record_type", null: false + t.integer "record_id", null: false + t.text "data" + 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", using: :btree + + create_table "comfy_cms_sites", force: true do |t| + t.string "label", null: false + t.string "identifier", null: false + t.string "hostname", null: false + t.string "path" + t.string "locale", default: "en", null: false + t.boolean "is_mirrored", default: false, null: false + end + + add_index "comfy_cms_sites", ["hostname"], name: "index_comfy_cms_sites_on_hostname", using: :btree + add_index "comfy_cms_sites", ["is_mirrored"], name: "index_comfy_cms_sites_on_is_mirrored", using: :btree + + create_table "comfy_cms_snippets", force: true do |t| + t.integer "site_id", null: false + t.string "label", null: false + t.string "identifier", null: false + t.text "content" + t.integer "position", default: 0, null: false + t.boolean "is_shared", default: false, null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "comfy_cms_snippets", ["site_id", "identifier"], name: "index_comfy_cms_snippets_on_site_id_and_identifier", unique: true, using: :btree + add_index "comfy_cms_snippets", ["site_id", "position"], name: "index_comfy_cms_snippets_on_site_id_and_position", using: :btree + + create_table "comments", force: true do |t| + t.integer "post_id", null: false + t.integer "author_id", null: false + t.text "body", null: false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "crops", force: true do |t| + t.string "name", null: false t.string "en_wikipedia_url" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" t.integer "parent_id" - t.integer "plantings_count", :default => 0 + t.integer "plantings_count", default: 0 t.integer "creator_id" + t.integer "requester_id" + t.string "approval_status", default: "approved" + t.text "reason_for_rejection" + t.text "request_notes" + t.text "rejection_notes" end - add_index "crops", ["name"], :name => "index_crops_on_name" - add_index "crops", ["slug"], :name => "index_crops_on_slug", :unique => true + add_index "crops", ["name"], name: "index_crops_on_name", using: :btree + add_index "crops", ["requester_id"], name: "index_crops_on_requester_id", using: :btree + add_index "crops", ["slug"], name: "index_crops_on_slug", unique: true, using: :btree - create_table "crops_posts", :id => false, :force => true do |t| + create_table "crops_posts", id: false, force: true do |t| t.integer "crop_id" t.integer "post_id" end - add_index "crops_posts", ["crop_id", "post_id"], :name => "index_crops_posts_on_crop_id_and_post_id" - add_index "crops_posts", ["crop_id"], :name => "index_crops_posts_on_crop_id" + add_index "crops_posts", ["crop_id", "post_id"], name: "index_crops_posts_on_crop_id_and_post_id", using: :btree + add_index "crops_posts", ["crop_id"], name: "index_crops_posts_on_crop_id", using: :btree - create_table "follows", :force => true do |t| + create_table "follows", force: true do |t| t.integer "follower_id" t.integer "followed_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "forums", :force => true do |t| - t.string "name", :null => false - t.text "description", :null => false - t.integer "owner_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "forums", force: true do |t| + t.string "name", null: false + t.text "description", null: false + t.integer "owner_id", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" end - add_index "forums", ["slug"], :name => "index_forums_on_slug", :unique => true + add_index "forums", ["slug"], name: "index_forums_on_slug", unique: true, using: :btree - create_table "gardens", :force => true do |t| - t.string "name", :null => false + create_table "gardens", force: true do |t| + t.string "name", null: false t.integer "owner_id" - t.string "slug", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.string "slug", null: false + t.datetime "created_at" + t.datetime "updated_at" t.text "description" - t.boolean "active", :default => true + t.boolean "active", default: true t.string "location" t.float "latitude" t.float "longitude" @@ -113,38 +241,46 @@ ActiveRecord::Schema.define(:version => 20141119130555) do t.string "area_unit" end - add_index "gardens", ["owner_id"], :name => "index_gardens_on_user_id" - add_index "gardens", ["slug"], :name => "index_gardens_on_slug", :unique => true + add_index "gardens", ["owner_id"], name: "index_gardens_on_owner_id", using: :btree + add_index "gardens", ["slug"], name: "index_gardens_on_slug", unique: true, using: :btree - create_table "harvests", :force => true do |t| - t.integer "crop_id", :null => false - t.integer "owner_id", :null => false + create_table "gardens_photos", id: false, force: true do |t| + t.integer "photo_id" + t.integer "garden_id" + end + + add_index "gardens_photos", ["garden_id", "photo_id"], name: "index_gardens_photos_on_garden_id_and_photo_id", using: :btree + + create_table "harvests", force: true do |t| + t.integer "crop_id", null: false + t.integer "owner_id", null: false t.date "harvested_at" t.decimal "quantity" t.string "unit" t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" t.decimal "weight_quantity" t.string "weight_unit" t.integer "plant_part_id" + t.float "si_weight" end - create_table "harvests_photos", :id => false, :force => true do |t| + create_table "harvests_photos", id: false, force: true do |t| t.integer "photo_id" t.integer "harvest_id" end - add_index "harvests_photos", ["harvest_id", "photo_id"], :name => "index_harvests_photos_on_harvest_id_and_photo_id" + add_index "harvests_photos", ["harvest_id", "photo_id"], name: "index_harvests_photos_on_harvest_id_and_photo_id", using: :btree - create_table "members", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :default => "", :null => false + create_table "members", force: true do |t| + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - 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" @@ -153,11 +289,11 @@ ActiveRecord::Schema.define(:version => 20141119130555) do t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.string "unconfirmed_email" - t.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", default: 0 t.string "unlock_token" t.datetime "locked_at" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "login_name" t.string "slug" t.boolean "tos_agreement" @@ -165,47 +301,47 @@ ActiveRecord::Schema.define(:version => 20141119130555) do t.string "location" t.float "latitude" t.float "longitude" - t.boolean "send_notification_email", :default => true + t.boolean "send_notification_email", default: true t.text "bio" t.integer "plantings_count" t.boolean "newsletter" - t.boolean "send_planting_reminder", :default => true + t.boolean "send_planting_reminder", default: true end - add_index "members", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true - add_index "members", ["email"], :name => "index_users_on_email", :unique => true - add_index "members", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true - add_index "members", ["slug"], :name => "index_users_on_slug", :unique => true - add_index "members", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true + add_index "members", ["confirmation_token"], name: "index_members_on_confirmation_token", unique: true, using: :btree + add_index "members", ["email"], name: "index_members_on_email", unique: true, using: :btree + add_index "members", ["reset_password_token"], name: "index_members_on_reset_password_token", unique: true, using: :btree + add_index "members", ["slug"], name: "index_members_on_slug", unique: true, using: :btree + add_index "members", ["unlock_token"], name: "index_members_on_unlock_token", unique: true, using: :btree - create_table "members_roles", :id => false, :force => true do |t| + create_table "members_roles", id: false, force: true do |t| t.integer "member_id" t.integer "role_id" end - create_table "notifications", :force => true do |t| + create_table "notifications", force: true do |t| t.integer "sender_id" - t.integer "recipient_id", :null => false + t.integer "recipient_id", null: false t.string "subject" t.text "body" - t.boolean "read", :default => false + t.boolean "read", default: false t.integer "post_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "order_items", :force => true do |t| + create_table "order_items", force: true do |t| t.integer "order_id" t.integer "product_id" t.integer "price" t.integer "quantity" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" end - create_table "orders", :force => true do |t| - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "orders", force: true do |t| + t.datetime "created_at" + t.datetime "updated_at" t.datetime "completed_at" t.integer "member_id" t.string "paypal_express_token" @@ -213,109 +349,114 @@ ActiveRecord::Schema.define(:version => 20141119130555) do t.string "referral_code" end - create_table "orders_products", :id => false, :force => true do |t| + create_table "orders_products", id: false, force: true do |t| t.integer "order_id" t.integer "product_id" end - create_table "photos", :force => true do |t| - t.integer "owner_id", :null => false - t.string "thumbnail_url", :null => false - t.string "fullsize_url", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "title", :null => false - t.string "license_name", :null => false + create_table "photos", force: true do |t| + t.integer "owner_id", null: false + t.string "thumbnail_url", null: false + t.string "fullsize_url", null: false + t.datetime "created_at" + t.datetime "updated_at" + t.string "title", null: false + t.string "license_name", null: false t.string "license_url" - t.string "link_url", :null => false + t.string "link_url", null: false t.string "flickr_photo_id" end - create_table "photos_plantings", :id => false, :force => true do |t| + create_table "photos_plantings", id: false, force: true do |t| t.integer "photo_id" t.integer "planting_id" end - create_table "plant_parts", :force => true do |t| + create_table "plant_parts", force: true do |t| t.string "name" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" end - create_table "plantings", :force => true do |t| - t.integer "garden_id", :null => false - t.integer "crop_id", :null => false + create_table "plantings", force: true do |t| + t.integer "garden_id", null: false + t.integer "crop_id", null: false t.date "planted_at" t.integer "quantity" t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" 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" end - add_index "plantings", ["slug"], :name => "index_plantings_on_slug", :unique => true + add_index "plantings", ["slug"], name: "index_plantings_on_slug", unique: true, using: :btree - create_table "posts", :force => true do |t| - t.integer "author_id", :null => false - t.string "subject", :null => false - t.text "body", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "posts", force: true do |t| + t.integer "author_id", null: false + t.string "subject", null: false + t.text "body", null: false + t.datetime "created_at" + 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_updates_on_created_at_and_user_id" - add_index "posts", ["slug"], :name => "index_updates_on_slug", :unique => true + add_index "posts", ["created_at", "author_id"], name: "index_posts_on_created_at_and_author_id", using: :btree + add_index "posts", ["slug"], name: "index_posts_on_slug", unique: true, using: :btree - create_table "products", :force => true do |t| - t.string "name", :null => false - t.text "description", :null => false - t.integer "min_price", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "products", force: true do |t| + t.string "name", null: false + t.text "description", null: false + t.integer "min_price", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "account_type_id" t.integer "paid_months" t.integer "recommended_price" end - create_table "roles", :force => true do |t| - t.string "name", :null => false + create_table "roles", force: true do |t| + t.string "name", null: false t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.datetime "created_at" + t.datetime "updated_at" t.string "slug" end - add_index "roles", ["slug"], :name => "index_roles_on_slug", :unique => true + add_index "roles", ["slug"], name: "index_roles_on_slug", unique: true, using: :btree - create_table "scientific_names", :force => true do |t| - t.string "scientific_name", :null => false - t.integer "crop_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + create_table "scientific_names", force: true do |t| + t.string "scientific_name", null: false + t.integer "crop_id", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "creator_id" end - create_table "seeds", :force => true do |t| - t.integer "owner_id", :null => false - t.integer "crop_id", :null => false + create_table "seeds", force: true do |t| + t.integer "owner_id", null: false + t.integer "crop_id", null: false t.text "description" t.integer "quantity" t.date "plant_before" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "tradable_to", :default => "nowhere" + t.datetime "created_at" + t.datetime "updated_at" + t.string "tradable_to", default: "nowhere" t.string "slug" + t.integer "days_until_maturity_min" + t.integer "days_until_maturity_max" + t.text "organic", default: "unknown" + t.text "gmo", default: "unknown" + t.text "heirloom", default: "unknown" end - add_index "seeds", ["slug"], :name => "index_seeds_on_slug", :unique => true + add_index "seeds", ["slug"], name: "index_seeds_on_slug", unique: true, using: :btree end diff --git a/db/seeds.rb b/db/seeds.rb index 2aa4fd12b..3fdd6226e 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -11,13 +11,15 @@ def load_data create_cropbot load_crops load_plant_parts + load_paid_account_types + load_products - # for development environments only + # We don't load these in an environment except development to + # prevent creating users in the wild - especially admins - with + # known passwords. if Rails.env.development? load_test_users load_admin_users - load_paid_account_types - load_products end end @@ -156,7 +158,7 @@ def load_plant_parts 'other' ] plant_parts.each do |pp| - PlantPart.find_or_create_by_name!(pp) + PlantPart.find_or_create_by!(name: pp) end end diff --git a/lib/tasks/growstuff.rake b/lib/tasks/growstuff.rake index d78f6c66f..bfb7b8642 100644 --- a/lib/tasks/growstuff.rake +++ b/lib/tasks/growstuff.rake @@ -98,36 +98,36 @@ namespace :growstuff do desc "June 2013: create account types and products." task :setup_shop => :environment do puts "Adding account types..." - AccountType.find_or_create_by_name( + AccountType.find_or_create_by( :name => "Free", :is_paid => false, :is_permanent_paid => false ) - @paid_account = AccountType.find_or_create_by_name( + @paid_account = AccountType.find_or_create_by( :name => "Paid", :is_paid => true, :is_permanent_paid => false ) - @seed_account = AccountType.find_or_create_by_name( + @seed_account = AccountType.find_or_create_by( :name => "Seed", :is_paid => true, :is_permanent_paid => true ) - @staff_account = AccountType.find_or_create_by_name( + @staff_account = AccountType.find_or_create_by( :name => "Staff", :is_paid => true, :is_permanent_paid => true ) puts "Adding products..." - Product.find_or_create_by_name( + 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 ) - Product.find_or_create_by_name( + 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, @@ -252,7 +252,7 @@ namespace :growstuff do 'other' ] plant_parts.each do |pp| - PlantPart.find_or_create_by_name!(pp) + PlantPart.find_or_create_by!(name: pp) end end @@ -314,6 +314,20 @@ namespace :growstuff do end end end + + desc "January 2015: fill in si_weight column" + task :populate_si_weight => :environment do + Harvest.find_each do |h| + h.set_si_weight + h.save + end + end + + desc "January 2015: build Elasticsearch index" + task :elasticsearch_create_index => :environment do + Crop.__elasticsearch__.create_index! force: true + Crop.import + end end # end oneoff section end diff --git a/script/deploy-tasks.sh b/script/deploy-tasks.sh index 3d427ed85..e8461294c 100755 --- a/script/deploy-tasks.sh +++ b/script/deploy-tasks.sh @@ -18,3 +18,9 @@ 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 diff --git a/script/heroku_maintenance.rb b/script/heroku_maintenance.rb new file mode 100755 index 000000000..cf23b398f --- /dev/null +++ b/script/heroku_maintenance.rb @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby + +require 'heroku-api' +require 'yaml' + +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 + app = travis_config['deploy']['app'][branch] +else + abort "No Heroku app found for branch #{branch}" +end + +case ARGV[0] +when "on" + maintenance_state = 1 +when "off" + maintenance_state = 0 +else + abort "usage: #{$0} (on|off)" +end + +puts "Turning #{maintenance_state} maintenance mode on app #{app}" +heroku.post_app_maintenance(app, maintenance_state) diff --git a/spec/controllers/account_types_controller_spec.rb b/spec/controllers/account_types_controller_spec.rb index 6beee69b6..a22146a79 100644 --- a/spec/controllers/account_types_controller_spec.rb +++ b/spec/controllers/account_types_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AccountTypesController do diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index 31ac5b014..eb2ff7f65 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +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 090bbb68b..08dfb9933 100644 --- a/spec/controllers/admin/orders_controller_spec.rb +++ b/spec/controllers/admin/orders_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Admin::OrdersController do diff --git a/spec/controllers/admin_controller_spec.rb b/spec/controllers/admin_controller_spec.rb index 76f56b78a..fc31f80b9 100644 --- a/spec/controllers/admin_controller_spec.rb +++ b/spec/controllers/admin_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AdminController do diff --git a/spec/controllers/authentications_controller_spec.rb b/spec/controllers/authentications_controller_spec.rb index 8add74c8c..4fc5b98a5 100644 --- a/spec/controllers/authentications_controller_spec.rb +++ b/spec/controllers/authentications_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AuthenticationsController do diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index 6b830180a..0e10ffe42 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe CommentsController do diff --git a/spec/controllers/crops_controller_spec.rb b/spec/controllers/crops_controller_spec.rb index 997aa71a9..54226c27c 100644 --- a/spec/controllers/crops_controller_spec.rb +++ b/spec/controllers/crops_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe CropsController do @@ -7,7 +7,8 @@ describe CropsController do def valid_attributes { :name => "Tomato", - :en_wikipedia_url => 'http://en.wikipedia.org/wiki/Tomato' + :en_wikipedia_url => 'http://en.wikipedia.org/wiki/Tomato', + :approval_status => 'approved' } end diff --git a/spec/controllers/forums_controller_spec.rb b/spec/controllers/forums_controller_spec.rb index 324c46120..369919ff6 100644 --- a/spec/controllers/forums_controller_spec.rb +++ b/spec/controllers/forums_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ForumsController do diff --git a/spec/controllers/gardens_controller_spec.rb b/spec/controllers/gardens_controller_spec.rb index 242ec6ffa..2bba8a2f8 100644 --- a/spec/controllers/gardens_controller_spec.rb +++ b/spec/controllers/gardens_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe GardensController do diff --git a/spec/controllers/harvests_controller_spec.rb b/spec/controllers/harvests_controller_spec.rb index 38b0edf8c..efd762368 100644 --- a/spec/controllers/harvests_controller_spec.rb +++ b/spec/controllers/harvests_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe HarvestsController do @@ -37,6 +37,11 @@ describe HarvestsController do assigns(:crop).should eq @maize assigns(:harvests).should eq [@harvest2] end + + it "generates a csv" do + get :index, {:format => "csv"} + response.status.should eq 200 + end end describe "GET show" do @@ -105,9 +110,9 @@ describe HarvestsController do harvest = Harvest.create! valid_attributes # Assuming there are no other harvests in the database, this # specifies that the Harvest created on the previous line - # receives the :update_attributes message with whatever params are + # receives the :update message with whatever params are # submitted in the request. - Harvest.any_instance.should_receive(:update_attributes).with({ "crop_id" => "1" }) + Harvest.any_instance.should_receive(:update).with({ "crop_id" => "1" }) put :update, {:id => harvest.to_param, :harvest => { "crop_id" => "1" }} end diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index bfbfc6adf..da5edc384 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe HomeController do diff --git a/spec/controllers/member_controller_spec.rb b/spec/controllers/member_controller_spec.rb index ff5a0ae42..35d5b0c6d 100644 --- a/spec/controllers/member_controller_spec.rb +++ b/spec/controllers/member_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe MembersController do diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 99add1cf4..d55b7df26 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +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 a33c55cc3..c8d23a4fd 100644 --- a/spec/controllers/order_items_controller_spec.rb +++ b/spec/controllers/order_items_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe OrderItemsController do diff --git a/spec/controllers/orders_controller_spec.rb b/spec/controllers/orders_controller_spec.rb index 9fecc3695..d01f37f92 100644 --- a/spec/controllers/orders_controller_spec.rb +++ b/spec/controllers/orders_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe OrdersController do diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 1c3b47780..e231c8b96 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PhotosController do @@ -48,6 +48,12 @@ describe PhotosController do assigns(:type).should eq "harvest" end + it "assigns a garden id" do + 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' } assigns(:current_set).should eq "foo" diff --git a/spec/controllers/places_controller_spec.rb b/spec/controllers/places_controller_spec.rb index 7d5841a6d..0c83c206a 100644 --- a/spec/controllers/places_controller_spec.rb +++ b/spec/controllers/places_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PlacesController do before :each do diff --git a/spec/controllers/plant_parts_controller_spec.rb b/spec/controllers/plant_parts_controller_spec.rb index 9aefaa953..e813e0f38 100644 --- a/spec/controllers/plant_parts_controller_spec.rb +++ b/spec/controllers/plant_parts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PlantPartsController do diff --git a/spec/controllers/plantings_controller_spec.rb b/spec/controllers/plantings_controller_spec.rb index 4b3a518a5..aa6fcbe4e 100644 --- a/spec/controllers/plantings_controller_spec.rb +++ b/spec/controllers/plantings_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PlantingsController do diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index bbb8bdccb..8121b318e 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PostsController do diff --git a/spec/controllers/products_controller_spec.rb b/spec/controllers/products_controller_spec.rb index f2daad383..5804ad09d 100644 --- a/spec/controllers/products_controller_spec.rb +++ b/spec/controllers/products_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ProductsController do diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 0ba0e29e6..8c0a669b4 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe RegistrationsController do diff --git a/spec/controllers/roles_controller_spec.rb b/spec/controllers/roles_controller_spec.rb index 0665101b4..f34bb79e3 100644 --- a/spec/controllers/roles_controller_spec.rb +++ b/spec/controllers/roles_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +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 254ebf1c8..45dd92066 100644 --- a/spec/controllers/scientific_names_controller_spec.rb +++ b/spec/controllers/scientific_names_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ScientificNamesController do diff --git a/spec/controllers/seeds_controller_spec.rb b/spec/controllers/seeds_controller_spec.rb index d41fe7c3b..7b0da6593 100644 --- a/spec/controllers/seeds_controller_spec.rb +++ b/spec/controllers/seeds_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe SeedsController do describe "GET index" do diff --git a/spec/controllers/shop_controller_spec.rb b/spec/controllers/shop_controller_spec.rb index 2aaaa58ff..626757b52 100644 --- a/spec/controllers/shop_controller_spec.rb +++ b/spec/controllers/shop_controller_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ShopController do diff --git a/spec/factories/crop.rb b/spec/factories/crop.rb index c6839e983..4be8c4f09 100644 --- a/spec/factories/crop.rb +++ b/spec/factories/crop.rb @@ -3,6 +3,7 @@ FactoryGirl.define do factory :crop do name "magic bean" en_wikipedia_url "http://en.wikipedia.org/wiki/Magic_bean" + approval_status "approved" creator factory :tomato do @@ -54,6 +55,21 @@ FactoryGirl.define do name "Swiss chard" end + #for testing crop request + factory :crop_request do + name "Ultra berry" + en_wikipedia_url "" + approval_status "pending" + association :requester, factory: :member + request_notes "Please approve this even though it's fake." + end + + factory :rejected_crop do + name "Fail bean" + approval_status "rejected" + reason_for_rejection "Totally fake" + end + end end diff --git a/spec/factories/roles.rb b/spec/factories/roles.rb index dc4aa3b9c..d2f7ba262 100644 --- a/spec/factories/roles.rb +++ b/spec/factories/roles.rb @@ -4,7 +4,7 @@ FactoryGirl.define do factory :role do name "Moderator" description "These people moderate the forums" - initialize_with { Role.find_or_create_by_name(name) } + initialize_with { Role.find_or_create_by(name: name) } factory :admin do name "admin" diff --git a/spec/factories/seeds.rb b/spec/factories/seeds.rb index bd5944d1b..323cdf2f2 100644 --- a/spec/factories/seeds.rb +++ b/spec/factories/seeds.rb @@ -8,6 +8,11 @@ FactoryGirl.define do quantity 1 plant_before "2013-07-15" tradable_to 'nowhere' + organic 'unknown' + gmo 'unknown' + heirloom 'unknown' + days_until_maturity_min nil + days_until_maturity_max nil factory :tradable_seed do tradable_to "locally" diff --git a/spec/features/admin/account_types_spec.rb b/spec/features/admin/account_types_spec.rb index 2f8cda09f..b56144344 100644 --- a/spec/features/admin/account_types_spec.rb +++ b/spec/features/admin/account_types_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "account types" do context "admin user" do diff --git a/spec/features/admin/forums_spec.rb b/spec/features/admin/forums_spec.rb index a5c6f4fb1..e9f8a43f9 100644 --- a/spec/features/admin/forums_spec.rb +++ b/spec/features/admin/forums_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "forums" do context "admin user" do diff --git a/spec/features/admin/products.rb b/spec/features/admin/products.rb new file mode 100644 index 000000000..2e85ead60 --- /dev/null +++ b/spec/features/admin/products.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +feature "products" do + context "admin user" do + let(:member) { FactoryGirl.create(:admin_member) } + background do + login_as(member) + end + + scenario "navigating to product admin" do + visit admin_path + click_link "Products" + current_path.should 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' + # 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' + click_button 'Save' + current_path.should eq product_path(Product.last) + page.should have_content 'Product was successfully created' + end + + scenario 'editing product' do + p = FactoryGirl.create(:product) + visit product_path(p) + click_link 'Edit' + 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' + end + + scenario 'deleting product' + # this isn't possible. Should it be? + end +end diff --git a/spec/features/cms_spec.rb b/spec/features/cms_spec.rb new file mode 100644 index 000000000..fb3f2ca93 --- /dev/null +++ b/spec/features/cms_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +feature "cms admin" do + before(:each) do + @member = FactoryGirl.create(:member) + @admin_member = FactoryGirl.create(:admin_member) + end + + 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") + end + + 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' + 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' + visit comfy_admin_cms_path + current_path.should match /#{comfy_admin_cms_path}/ # match any CMS admin page + end +end diff --git a/spec/features/crop_wranglers_spec.rb b/spec/features/crop_wranglers_spec.rb deleted file mode 100644 index 32c96e639..000000000 --- a/spec/features/crop_wranglers_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -require 'spec_helper' - -feature "crop wranglers" do - context "signed in member" do - let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) } - let(:member){crop_wranglers.first} - - background do - login_as(member) - end - - scenario "crop wranglers are listed on the crop wrangler page" do - visit root_path - click_link 'Crop Wrangling' - - 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) - end - end - end - end -end diff --git a/spec/features/alternate_name_spec.rb b/spec/features/crops/alternate_name_spec.rb similarity index 99% rename from spec/features/alternate_name_spec.rb rename to spec/features/crops/alternate_name_spec.rb index 086584c40..8ec2a21fe 100644 --- a/spec/features/alternate_name_spec.rb +++ b/spec/features/crops/alternate_name_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "Alternate names" do let!(:alternate_eggplant) { FactoryGirl.create(:alternate_eggplant) } diff --git a/spec/features/crops/browse_crops_spec.rb b/spec/features/crops/browse_crops_spec.rb new file mode 100644 index 000000000..5df5dbd36 --- /dev/null +++ b/spec/features/crops/browse_crops_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +feature "browse crops" do + + let(:tomato) { FactoryGirl.create(:tomato) } + let(:maize) { FactoryGirl.create(:maize) } + + scenario "has a form for sorting by" do + visit crops_path + expect(page).to have_css "select#sort" + end + + scenario "shows a list of crops" do + crop1 = tomato + visit crops_path + expect(page).to have_content crop1.name + end + +end diff --git a/spec/features/crops/crop_detail_page_spec.rb b/spec/features/crops/crop_detail_page_spec.rb index a941cb075..437d3e786 100644 --- a/spec/features/crops/crop_detail_page_spec.rb +++ b/spec/features/crops/crop_detail_page_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "crop detail page" do @@ -28,5 +28,34 @@ feature "crop detail page" do end end + + context "SEO" do + + background do + visit crop_path(crop) + end + + scenario "has seed heading with SEO" do + expect(page).to have_content "Find #{ crop.name } seeds" + end + + scenario "has harvest heading with SEO" do + expect(page).to have_content "#{ crop.name.capitalize } harvests" + end + + scenario "has planting heading with SEO" do + expect(page).to have_content "See who's planted #{ crop.name.pluralize }" + end + + scenario "has planting advice with SEO" do + expect(page).to have_content "How to grow #{ crop.name }" + end + + 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 + end + + end end end diff --git a/spec/features/crops/crop_search_spec.rb b/spec/features/crops/crop_search_spec.rb new file mode 100644 index 000000000..48e68dfc2 --- /dev/null +++ b/spec/features/crops/crop_search_spec.rb @@ -0,0 +1,22 @@ +require 'rails_helper' + +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" + click_button "Search" + end + expect(page).to have_css "h1", text: "Crops matching \"tomato\"" + end + + scenario "search page with no search term shows suitable title" do + visit crops_search_path + expect(page).to have_css "h1", text: "Crop search" + end + + scenario "search page has a search form on it" do + visit crops_search_path + expect(page).to have_css "form#crop-search" + end +end diff --git a/spec/features/crops/crop_wranglers_spec.rb b/spec/features/crops/crop_wranglers_spec.rb new file mode 100644 index 000000000..1b2af3f06 --- /dev/null +++ b/spec/features/crops/crop_wranglers_spec.rb @@ -0,0 +1,88 @@ +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) } + + background do + login_as(wrangler) + end + + scenario "sees crop wranglers listed on the crop wrangler page" do + visit root_path + click_link 'Crop Wrangling' + + 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) + 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' + within '#recently-added-crops' 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' + 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" + click_on 'Save' + expect(page).to have_content 'Crop was successfully created' + expect(page).to have_content 'planticus maximus' + end + + scenario "View pending crops" do + visit wrangle_crops_path(:approval_status => "pending") + within "#pending-crops" do + click_link "Ultra berry" + end + 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 + 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 + + 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 new file mode 100644 index 000000000..26ef46e30 --- /dev/null +++ b/spec/features/crops/crop_wrangling_button_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +feature "crop wrangling button" do + + 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 + + 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 + end + end diff --git a/spec/features/crops/inflections_spec.rb b/spec/features/crops/inflections_spec.rb new file mode 100644 index 000000000..93c1f0e24 --- /dev/null +++ b/spec/features/crops/inflections_spec.rb @@ -0,0 +1,13 @@ +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. + scenario "crops which are mass nouns" 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 new file mode 100644 index 000000000..0a1cac2a7 --- /dev/null +++ b/spec/features/crops/request_new_crop_spec.rb @@ -0,0 +1,50 @@ +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) } + + before { login_as member } + + scenario "Submit request" do + visit new_crop_path + fill_in "Name", with: "Couch potato" + fill_in "Comments", with: "Couch potatoes are real for real." + click_button "Save" + expect(page).to have_content "Crop was successfully requested." + end + + end + + context "As a crop wrangler" do + + let(:wrangler) { FactoryGirl.create(:crop_wrangling_member) } + let!(:crop) { FactoryGirl.create(:crop_request) } + let!(:already_approved) { FactoryGirl.create(:crop) } + + before { login_as wrangler } + + scenario "Approve a request" do + visit edit_crop_path(crop) + 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" + click_button "Save" + expect(page).to have_content "Crop was successfully updated." + end + + scenario "Rejecting a crop" do + visit edit_crop_path(crop) + select "rejected", from: "Approval Status" + select "not edible", from: "Reason for rejection" + click_button "Save" + expect(page).to have_content "Crop was successfully updated." + end + + end + +end \ No newline at end of file diff --git a/spec/features/following_spec.rb b/spec/features/following_spec.rb new file mode 100644 index 000000000..891a38b02 --- /dev/null +++ b/spec/features/following_spec.rb @@ -0,0 +1,89 @@ +require 'rails_helper' + +feature "follows", :js => true do + + context "when signed out" do + let(:member) { FactoryGirl.create(:member) } + + scenario "follow buttons on member profile page" do + visit member_path(member) + expect(page).to_not have_link "Follow" + expect(page).to_not have_link "Unfollow" + end + end + + context "when signed in" do + let(:member) { FactoryGirl.create(:member) } + let(:other_member) { FactoryGirl.create(:member) } + + background do + login_as(member) + end + + scenario "your profile doesn't have a follow button" do + visit member_path(member) + expect(page).not_to have_link "Follow" + expect(page).not_to have_link "Unfollow" + end + + context "following another member" do + background do + visit member_path(other_member) + end + + scenario "has a follow button" do + 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)) + end + + scenario "has a followed member listed in the following page" do + click_link 'Follow' + visit member_follows_path(member) + expect(page).to have_content "#{other_member.login_name}" + end + + scenario "does not die when passed an authenticity_token" do + visit member_follows_path( + member, + :params => {:authenticity_token => "Ultima ratio regum"}) + expect(page.status_code).to equal 200 + end + + scenario "has correct message and follow button after unfollow" do + click_link 'Follow' + 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) + end + + scenario "has member in following list" do + click_link 'Follow' + visit member_follows_path(member) + expect(page).to have_content "#{other_member.login_name}" + end + + scenario "appears in in followed member's followers list" do + click_link 'Follow' + visit member_followers_path(other_member) + expect(page).to have_content "#{member.login_name}" + end + + scenario "removes members from following and followers lists after unfollow" do + click_link 'Follow' + click_link 'Unfollow' + 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}" + end + + end + + end +end diff --git a/spec/features/footer_spec.rb b/spec/features/footer_spec.rb index aa8449b15..400b153a4 100644 --- a/spec/features/footer_spec.rb +++ b/spec/features/footer_spec.rb @@ -1,9 +1,12 @@ -require 'spec_helper' +require 'rails_helper' feature "footer" do - scenario "contact page has Twitter link" do + + scenario "footer is on home page" do visit root_path - click_link 'Contact' - page.should have_link '@growstufforg', :href => 'http://twitter.com/growstufforg' + expect(page).to have_css 'footer' 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 diff --git a/spec/features/gardens_spec.rb b/spec/features/gardens_spec.rb index 5c689db44..8f311804e 100644 --- a/spec/features/gardens_spec.rb +++ b/spec/features/gardens_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "Planting a crop", :js => true do let!(:garden) { FactoryGirl.create(:garden) } diff --git a/spec/features/harvests/harvesting_a_crop_spec.rb b/spec/features/harvests/harvesting_a_crop_spec.rb index caffb237d..c1148cf4b 100644 --- a/spec/features/harvests/harvesting_a_crop_spec.rb +++ b/spec/features/harvests/harvesting_a_crop_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "Harvesting a crop", :js => true do let(:member) { FactoryGirl.create(:member) } @@ -7,12 +7,13 @@ feature "Harvesting a crop", :js => true do background do login_as(member) visit new_harvest_path + sync_elasticsearch([maize]) end it_behaves_like "crop suggest", "harvest", "crop" scenario "Creating a new harvest", :js => true do - fill_autocomplete "crop", :with => "m" + fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" within "form#new_harvest" do fill_in "When?", :with => "2014-06-15" diff --git a/spec/features/locale_spec.rb b/spec/features/locale_spec.rb index b5893858d..36b07b5c9 100644 --- a/spec/features/locale_spec.rb +++ b/spec/features/locale_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "Changing locales" do diff --git a/spec/features/member_profile_spec.rb b/spec/features/member_profile_spec.rb index 27c3c7619..2c7343a8d 100644 --- a/spec/features/member_profile_spec.rb +++ b/spec/features/member_profile_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "member profile" do @@ -13,8 +13,6 @@ feature "member profile" do 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_not have_link "Follow" - expect(page).to_not have_link "Unfollow" end scenario "no bio" do @@ -146,52 +144,6 @@ feature "member profile" do expect(page).to have_link "Send message", :href => new_notification_path(:recipient_id => other_member.id) end - scenario "has a follow button" do - expect(page).to have_link "Follow", :href => follows_path(:followed_id => other_member.id) - end - end - - context "following another member" do - background do - visit member_path(other_member) - click_link 'Follow' - end - - scenario "has correct message and unfollow button" do - expect(page).to have_content "Followed #{other_member.login_name}" - 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 - visit member_follows_path(member) - expect(page).to have_content "#{other_member.login_name}" - end - - scenario "has correct message and follow button after unfollow" 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) - end - - scenario "has member in following list" do - visit member_follows_path(member) - expect(page).to have_content "#{other_member.login_name}" - end - - scenario "appears in in followed member's followers list" do - visit member_followers_path(other_member) - expect(page).to have_content "#{member.login_name}" - end - - scenario "removes members from following and followers lists after unfollow" do - click_link 'Unfollow' - 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}" - end - end context "home page" do diff --git a/spec/features/members_list_spec.rb b/spec/features/members_list_spec.rb new file mode 100644 index 000000000..68cbb6d1f --- /dev/null +++ b/spec/features/members_list_spec.rb @@ -0,0 +1,35 @@ +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')) } + + scenario "default alphabetical sort" do + visit members_path + expect(page).to have_css "#sort" + expect(page).to have_selector "form" + click_button('Show') + all_links = page.all("#maincontainer p") + expect(all_links.first).to have_text member1.login_name + expect(all_links.last).to have_text member2.login_name + end + + scenario "recently joined sort" do + visit members_path + expect(page).to have_css "#sort" + expect(page).to have_selector "form" + select("recently", :from => 'sort') + click_button('Show') + 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 diff --git a/spec/features/planting_reminder_spec.rb b/spec/features/planting_reminder_spec.rb index 5adb44095..3d694c013 100644 --- a/spec/features/planting_reminder_spec.rb +++ b/spec/features/planting_reminder_spec.rb @@ -1,10 +1,16 @@ -require 'spec_helper' +require 'rails_helper' require 'capybara/email/rspec' feature "Planting reminder email", :js => true do let(:member) { FactoryGirl.create(:member) } let(:mail) { Notifier.planting_reminder(member) } + # Unfortunately, we can't use the default url options for ActionMailer as configured in + # test.rb, since this isn't a mailer spec. + def self.default_url_options + { host: 'localhost', port: 8080 } + end + scenario "has a greeting" do expect(mail).to have_content "Hello" end @@ -34,10 +40,8 @@ feature "Planting reminder email", :js => true do scenario "lists plantings" do expect(mail).to have_content "most recent plantings you've told us about" - expect(mail).to have_content @p1.to_s - expect(mail).to have_content @p2.to_s - # can't test for links to your plantings due to this weirdness: - # https://github.com/Skud/growstuff/commit/8e6a57c4429eac88ab934f422ab11bf16b0a7663 + 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 @@ -65,10 +69,8 @@ feature "Planting reminder email", :js => true do scenario "lists harvests" do expect(mail).to have_content "the last few things you harvested were" - expect(mail).to have_content @h1.to_s - expect(mail).to have_content @h2.to_s - # can't test for links to your harvests due to this weirdness: - # https://github.com/Skud/growstuff/commit/8e6a57c4429eac88ab934f422ab11bf16b0a7663 + 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 diff --git a/spec/features/plantings/planting_a_crop_spec.rb b/spec/features/plantings/planting_a_crop_spec.rb index 82d180d84..bda85fadc 100644 --- a/spec/features/plantings/planting_a_crop_spec.rb +++ b/spec/features/plantings/planting_a_crop_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" feature "Planting a crop", :js => true do let(:member) { FactoryGirl.create(:member) } @@ -9,12 +9,13 @@ feature "Planting a crop", :js => true do background do login_as(member) visit new_planting_path + sync_elasticsearch([maize]) end it_behaves_like "crop suggest", "planting" scenario "Creating a new planting" do - fill_autocomplete "crop", :with => "m" + fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" within "form#new_planting" do fill_in "When", :with => "2014-06-15" @@ -41,7 +42,7 @@ feature "Planting a crop", :js => true do end scenario "Marking a planting as finished" do - fill_autocomplete "crop", :with => "m" + fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" within "form#new_planting" do fill_in "When?", :with => "2014-07-01" @@ -77,7 +78,7 @@ feature "Planting a crop", :js => true do end scenario "Marking a planting as finished without a date" do - fill_autocomplete "crop", :with => "m" + fill_autocomplete "crop", :with => "mai" select_from_autocomplete "maize" within "form#new_planting" do check "Mark as finished" diff --git a/spec/features/scientific_name_spec.rb b/spec/features/scientific_name_spec.rb index 1fda79d42..c6cd60c6a 100644 --- a/spec/features/scientific_name_spec.rb +++ b/spec/features/scientific_name_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "Scientific names" do let!(:zea_mays) { FactoryGirl.create(:zea_mays) } diff --git a/spec/features/seeds/adding_seeds_spec.rb b/spec/features/seeds/adding_seeds_spec.rb index ca79c5b8c..b14622d47 100644 --- a/spec/features/seeds/adding_seeds_spec.rb +++ b/spec/features/seeds/adding_seeds_spec.rb @@ -1,28 +1,40 @@ -require 'spec_helper' +require 'rails_helper' -feature "Harvesting a crop", :js => true do +feature "Seeds", :js => true do let(:member) { FactoryGirl.create(:member) } let!(:maize) { FactoryGirl.create(:maize) } background do login_as(member) visit new_seed_path + sync_elasticsearch([maize]) end it_behaves_like "crop suggest", "seed", "crop" scenario "Adding a new seed", :js => true do - fill_autocomplete "crop", :with => "m" + 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?" fill_in "Description", :with => "It's killer." select "internationally", :from => "Will trade:" click_button "Save" end expect(page).to have_content "Successfully added maize seed to your stash" + expect(page).to have_content "Quantity: 42" + expect(page).to have_content "Days until maturity: 999–1999" + expect(page).to have_content "certified organic" + expect(page).to have_content "non-certified GMO-free" + expect(page).to have_content "Heirloom? heirloom" + expect(page).to have_content "It's killer." end scenario "Adding a seed from crop page" do diff --git a/spec/features/seeds/misc_seeds_spec.rb b/spec/features/seeds/misc_seeds_spec.rb index 30c624e27..1e434a754 100644 --- a/spec/features/seeds/misc_seeds_spec.rb +++ b/spec/features/seeds/misc_seeds_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "seeds" do context "signed in user" do @@ -45,5 +45,30 @@ feature "seeds" do click_link 'Delete' current_path.should 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) + 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) + 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) + 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) + 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_spec.rb b/spec/features/shared_examples/append_date.rb similarity index 100% rename from spec/features/shared_examples/append_date_spec.rb rename to spec/features/shared_examples/append_date.rb diff --git a/spec/features/shared_examples/crop_suggest.rb b/spec/features/shared_examples/crop_suggest.rb index da10072a3..9856282ca 100644 --- a/spec/features/shared_examples/crop_suggest.rb +++ b/spec/features/shared_examples/crop_suggest.rb @@ -1,27 +1,39 @@ +require 'rails_helper' + shared_examples "crop suggest" do |resource| - let!(:popcorn) { FactoryGirl.create(:popcorn) } + let!(:pea) { FactoryGirl.create(:crop, :name => 'pea') } let!(:pear) { FactoryGirl.create(:pear) } let!(:tomato) { FactoryGirl.create(:tomato) } let!(:roma) { FactoryGirl.create(:roma) } + background do + sync_elasticsearch([pea, pear, maize, tomato]) + end + scenario "See 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 within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "p" + 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" end expect(page).to have_content("pear") - expect(page).to have_content("popcorn") + expect(page).to have_content("pea") within "form#new_#{resource}" do fill_autocomplete "crop", :with => "pear" end expect(page).to have_content("pear") - expect(page).to_not have_content("popcorn") select_from_autocomplete("pear") @@ -30,16 +42,16 @@ shared_examples "crop suggest" do |resource| scenario "Typing and pausing does not affect input" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "p" + fill_autocomplete "crop", :with => "pea" end expect(page).to have_content("pear") - expect(find_field("crop").value).to eq("p") + expect(find_field("crop").value).to eq("pea") end scenario "Searching for a crop casts a wide net on results" do within "form#new_#{resource}" do - fill_autocomplete "crop", :with => "to" + fill_autocomplete "crop", :with => "tom" end expect(page).to have_content("tomato") diff --git a/spec/features/signin_spec.rb b/spec/features/signin_spec.rb index 3ad259213..dced5f2ac 100644 --- a/spec/features/signin_spec.rb +++ b/spec/features/signin_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "signin" do let(:member){FactoryGirl.create(:member)} diff --git a/spec/features/signup_spec.rb b/spec/features/signup_spec.rb index 9962df359..aa4c9d65f 100644 --- a/spec/features/signup_spec.rb +++ b/spec/features/signup_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' feature "signup" do @@ -11,7 +11,6 @@ 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 end diff --git a/spec/helpers/application_helper.rb b/spec/helpers/application_helper.rb index 912ffbfd5..9a39e59a7 100644 --- a/spec/helpers/application_helper.rb +++ b/spec/helpers/application_helper.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ApplicationHelper do it "formats prices" do diff --git a/spec/helpers/harvests_helper_spec.rb b/spec/helpers/harvests_helper_spec.rb index ecc30a51e..7bc516162 100644 --- a/spec/helpers/harvests_helper_spec.rb +++ b/spec/helpers/harvests_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe HarvestsHelper do describe "display_quantity" do diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 9db3a95aa..85f96d664 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe NotificationsHelper do describe "reply_link" do diff --git a/spec/lib/haml/filters/escaped_markdown_spec.rb b/spec/lib/haml/filters/escaped_markdown_spec.rb index 9e2c1ce1f..60066160f 100644 --- a/spec/lib/haml/filters/escaped_markdown_spec.rb +++ b/spec/lib/haml/filters/escaped_markdown_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'haml/filters' require 'haml/filters/escaped_markdown' require 'haml/helpers' diff --git a/spec/lib/haml/filters/growstuff_markdown_spec.rb b/spec/lib/haml/filters/growstuff_markdown_spec.rb index 718645322..8abe8aee4 100644 --- a/spec/lib/haml/filters/growstuff_markdown_spec.rb +++ b/spec/lib/haml/filters/growstuff_markdown_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'haml/filters' require 'haml/filters/growstuff_markdown' diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb index 6ade0fb78..ce552f99b 100644 --- a/spec/mailers/notifier_spec.rb +++ b/spec/mailers/notifier_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe Notifier do @@ -44,4 +44,84 @@ describe Notifier do end end + + + describe "new crop request" do + let(:member) { FactoryGirl.create(:crop_wrangling_member) } + let(:crop) { FactoryGirl.create(:crop_request) } + let(:mail) { Notifier.new_crop_request(member, crop) } + + it 'sets the subject correctly' do + mail.subject.should == "#{crop.requester.login_name} has requested Ultra berry as a new crop" + end + + it 'comes from noreply@growstuff.org' do + mail.from.should == ['noreply@growstuff.org'] + end + + it 'sends the mail to the recipient of the notification' do + mail.to.should == [member.email] + end + + it 'includes the requested crop URL' do + mail.body.encoded.should match crop_url(crop) + end + end + + describe "crop approved" do + let(:member) { FactoryGirl.create(:member) } + let(:crop) { FactoryGirl.create(:crop) } + let(:mail) { Notifier.crop_request_approved(member, crop) } + + it 'sets the subject correctly' do + expect(mail.subject).to eq "Magic bean has been approved" + end + + it 'comes from noreply@growstuff.org' do + expect(mail.from).to eq ['noreply@growstuff.org'] + end + + it 'sends the mail to the recipient of the notification' do + expect(mail.to).to eq [member.email] + end + + it 'includes the approved crop URL' do + expect(mail.body.encoded).to match crop_url(crop) + end + + it 'includes links to plant, harvest and stash seeds for the new crop' do + expect(mail.body.encoded).to match "#{new_planting_url}\\?crop_id=#{crop.id}" + expect(mail.body.encoded).to match "#{new_harvest_url}\\?crop_id=#{crop.id}" + expect(mail.body.encoded).to match "#{new_seed_url}\\?crop_id=#{crop.id}" + end + + end + + describe "crop rejected" do + let(:member) { FactoryGirl.create(:member) } + let(:crop) { FactoryGirl.create(:rejected_crop) } + let(:mail) { Notifier.crop_request_rejected(member, crop) } + + it 'sets the subject correctly' do + expect(mail.subject).to eq "Fail bean has been rejected" + end + + it 'comes from noreply@growstuff.org' do + expect(mail.from).to eq ['noreply@growstuff.org'] + end + + it 'sends the mail to the recipient of the notification' do + expect(mail.to).to eq [member.email] + end + + it 'includes the rejected crop URL' do + expect(mail.body.encoded).to match crop_url(crop) + end + + it 'includes the reason for rejection' do + expect(mail.body.encoded).to match "Totally fake" + end + end + + end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 06ac61b7c..87d8a3b1d 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' require 'cancan/matchers' describe Ability do @@ -45,11 +45,14 @@ describe Ability do context "standard member" do it "can't manage crops" do - @ability.should_not be_able_to(:create, 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) + end + it "can read crops" do @ability.should be_able_to(:read, @crop) end diff --git a/spec/models/account_spec.rb b/spec/models/account_spec.rb index 8b2acd470..b1765ccc0 100644 --- a/spec/models/account_spec.rb +++ b/spec/models/account_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Account do before(:each) do diff --git a/spec/models/account_type_spec.rb b/spec/models/account_type_spec.rb index 8dfe24bf7..c65c113ba 100644 --- a/spec/models/account_type_spec.rb +++ b/spec/models/account_type_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe AccountType do end diff --git a/spec/models/alternate_name_spec.rb b/spec/models/alternate_name_spec.rb index f7acd0efc..ecbdc10eb 100644 --- a/spec/models/alternate_name_spec.rb +++ b/spec/models/alternate_name_spec.rb @@ -1,10 +1,10 @@ -require 'spec_helper' +require 'rails_helper' describe AlternateName do let(:an) { FactoryGirl.create(:alternate_eggplant) } it 'should save a basic alternate name' do - expect(an.save).to be_true + expect(an.save).to be(true) end it 'should be possible to add multiple alternate names to a crop' do diff --git a/spec/models/authentication_spec.rb b/spec/models/authentication_spec.rb index 2a9df9aec..0159361ff 100644 --- a/spec/models/authentication_spec.rb +++ b/spec/models/authentication_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Authentication do diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index d487d0b91..d54cd5606 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Comment do diff --git a/spec/models/crop_spec.rb b/spec/models/crop_spec.rb index 5bd7d01ba..9cda818e8 100644 --- a/spec/models/crop_spec.rb +++ b/spec/models/crop_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Crop do context 'all fields present' do @@ -8,7 +8,7 @@ describe Crop do end 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 @@ -328,6 +328,7 @@ describe Crop do context "search" do before :each do @mushroom = FactoryGirl.create(:crop, :name => 'mushroom') + sync_elasticsearch([@mushroom]) end it "finds exact matches" do Crop.search('mushroom').should eq [@mushroom] diff --git a/spec/models/forum_spec.rb b/spec/models/forum_spec.rb index 98ce1c24a..9769882c6 100644 --- a/spec/models/forum_spec.rb +++ b/spec/models/forum_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Forum do before(:each) do diff --git a/spec/models/garden_spec.rb b/spec/models/garden_spec.rb index 9ed7e5196..7a6590596 100644 --- a/spec/models/garden_spec.rb +++ b/spec/models/garden_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Garden do before :each do @@ -206,4 +206,32 @@ describe Garden do p2.finished.should eq false end + context 'photos' do + before(:each) do + @garden = FactoryGirl.create(:garden) + @photo = FactoryGirl.create(:photo) + @garden.photos << @photo + end + + it 'has a photo' do + @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 + end + + it 'has a default photo' do + @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 + end + end + end diff --git a/spec/models/harvest_spec.rb b/spec/models/harvest_spec.rb index e1bc76ee7..cd6d5f1ef 100644 --- a/spec/models/harvest_spec.rb +++ b/spec/models/harvest_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Harvest do @@ -118,6 +118,26 @@ describe Harvest do end end + context "standardized weights" do + it 'converts from pounds' do + @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.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.should be_valid + @harvest.reload.si_weight.should eq 2.0 + end + end + context 'ordering' do it 'lists most recent harvests first' do @h1 = FactoryGirl.create(:harvest, :created_at => 1.day.ago) diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 17f764453..9b0481298 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'member' do @@ -33,11 +33,11 @@ describe 'member' do 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.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 @@ -101,7 +101,7 @@ describe 'member' do end 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 @@ -311,7 +311,7 @@ describe 'member' 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.is_paid?.should be(true) end it "recognises a current paid account" do @@ -319,7 +319,7 @@ describe 'member' do :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.is_paid?.should be(true) end it "recognises an expired paid account" do @@ -327,14 +327,14 @@ describe 'member' do :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.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.is_paid?.should be(false) end it "recognises a free account even with paid_until set" do @@ -342,7 +342,7 @@ describe 'member' do :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.is_paid?.should be(false) end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index a8bddb9fa..27924ebed 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Notification do before(:each) do diff --git a/spec/models/order_item_spec.rb b/spec/models/order_item_spec.rb index e12cc9fbf..20c0be94f 100644 --- a/spec/models/order_item_spec.rb +++ b/spec/models/order_item_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe OrderItem do before(:each) do diff --git a/spec/models/order_spec.rb b/spec/models/order_spec.rb index 60e98ac4d..50fb6f949 100644 --- a/spec/models/order_spec.rb +++ b/spec/models/order_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Order do before(:each) do diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index f17127301..650f0f57c 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Photo do @@ -6,6 +6,7 @@ describe Photo do let(:photo) { FactoryGirl.create(:photo) } let(:planting) { FactoryGirl.create(:planting) } let(:harvest) { FactoryGirl.create(:harvest) } + let(:garden) { FactoryGirl.create(:garden) } context "adds photos" do it 'to a planting' do @@ -19,6 +20,12 @@ describe Photo do expect(harvest.photos.count).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.first).to eq photo + end end context "removing photos" do @@ -34,6 +41,12 @@ describe Photo do expect(harvest.photos.count).to eq 0 end + it 'from a garden' do + garden.photos << photo + photo.destroy + expect(garden.photos.count).to eq 0 + end + it "automatically if unused" do photo.destroy_if_unused expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound @@ -44,7 +57,7 @@ describe Photo do planting.photos << photo harvest.destroy # photo is now used by harvest but not planting photo.destroy_if_unused - expect(lambda { photo.reload }).not_to raise_error ActiveRecord::RecordNotFound + expect(lambda { photo.reload }).not_to raise_error end it 'they are used by harvests but not plantings' do @@ -52,24 +65,36 @@ describe Photo do planting.photos << photo planting.destroy # photo is now used by harvest but not planting photo.destroy_if_unused - expect(lambda { photo.reload }).not_to raise_error ActiveRecord::RecordNotFound + expect(lambda { photo.reload }).not_to raise_error + end + + it 'they are used by gardens but not plantings' do + garden.photos << photo + planting.photos << photo + planting.destroy # photo is now used by garden but not planting + photo.destroy_if_unused + expect(lambda { photo.reload }).not_to raise_error end it 'they are no longer used by anything' do planting.photos << photo harvest.photos << photo + garden.photos << photo expect(photo.plantings.size).to eq 1 expect(photo.harvests.size).to eq 1 + expect(photo.gardens.size).to eq 1 - planting.destroy # photo is still used by harvest + planting.destroy # photo is still used by harvest and garden photo.reload expect(photo.plantings.size).to eq 0 expect(photo.harvests.size).to eq 1 - harvest.destroy # photo is now no longer used by anything - photo.reload + harvest.destroy + garden.destroy # photo is now no longer used by anything + expect(photo.plantings.size).to eq 0 expect(photo.harvests.size).to eq 0 + expect(photo.gardens.size).to eq 0 photo.destroy_if_unused expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound end diff --git a/spec/models/plant_part_spec.rb b/spec/models/plant_part_spec.rb index 45536afe4..f8dc1f290 100644 --- a/spec/models/plant_part_spec.rb +++ b/spec/models/plant_part_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe PlantPart do it 'stringifies' do diff --git a/spec/models/planting_spec.rb b/spec/models/planting_spec.rb index 0f64a53f1..fba4fabe1 100644 --- a/spec/models/planting_spec.rb +++ b/spec/models/planting_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Planting do diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 30c19c500..adce855d2 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Post do before(:each) do diff --git a/spec/models/product_spec.rb b/spec/models/product_spec.rb index 59339a8c9..af1a02ba5 100644 --- a/spec/models/product_spec.rb +++ b/spec/models/product_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Product do diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb index 5a74d6165..6ea5d1a9d 100644 --- a/spec/models/role_spec.rb +++ b/spec/models/role_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Role do let(:member) { FactoryGirl.create(:member) } diff --git a/spec/models/scientific_name_spec.rb b/spec/models/scientific_name_spec.rb index 496cf4dad..020f1cc0d 100644 --- a/spec/models/scientific_name_spec.rb +++ b/spec/models/scientific_name_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe ScientificName do context 'all fields present' do @@ -8,7 +8,7 @@ describe ScientificName do end 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 diff --git a/spec/models/seed_spec.rb b/spec/models/seed_spec.rb index 355edac10..747dbee71 100644 --- a/spec/models/seed_spec.rb +++ b/spec/models/seed_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe Seed do @@ -7,7 +7,7 @@ describe Seed do end it 'should save a basic seed' do - @seed.save.should be_true + @seed.save.should be(true) end it "should have a slug" do @@ -88,6 +88,49 @@ describe Seed do end end + context 'organic, gmo, heirloom' 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.should be_valid + end + end + + 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.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.should be_valid + end + end + + it 'should refuse invalid organic/GMO/heirloom values' do + [:organic, :gmo, :heirloom].each do |field| + @seed = FactoryGirl.build(:seed, field => 'not valid') + @seed.should_not be_valid + @seed.errors[field].should_not be_empty + end + end + + it 'should not allow nil or blank values' do + [:organic, :gmo, :heirloom].each do |field| + @seed = FactoryGirl.build(:seed, field => nil) + @seed.should_not be_valid + @seed = FactoryGirl.build(:seed, field => '') + @seed.should_not be_valid + end + end + end + + context 'interesting' do it 'lists interesting seeds' do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 000000000..784cfba6f --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,85 @@ +# 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' + +# output coverage locally AND send it to coveralls +SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ + SimpleCov::Formatter::HTMLFormatter, + Coveralls::SimpleCov::Formatter +] + +# fail if there's a significant test coverage drop +SimpleCov.maximum_coverage_drop 1 + +SimpleCov.start :rails do + add_filter 'spec/' + add_filter 'vendor/' +end + +require 'capybara' +require 'capybara/poltergeist' +Capybara.javascript_driver = :poltergeist +Capybara.app_host = 'http://localhost' +Capybara.server_port = 8081 + +include Warden::Test::Helpers + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } +Dir[Rails.root.join("spec/features/shared_examples/**/*.rb")].each {|f| require f} + +# Checks for pending migrations before tests are run. +# If you are not using ActiveRecord, you can remove this line. +ActiveRecord::Migration.maintain_test_schema! + +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + # config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = false + + # If true, the base class of anonymous controllers will be inferred + # automatically. This will be the default behavior in future versions of + # rspec-rails. + config.infer_base_class_for_anonymous_controllers = false + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! + + # 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 +end diff --git a/spec/requests/authentications_spec.rb b/spec/requests/authentications_spec.rb index f50942928..6cc612f44 100644 --- a/spec/requests/authentications_spec.rb +++ b/spec/requests/authentications_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Authentications" do describe "GET /authentications" do diff --git a/spec/requests/comments_spec.rb b/spec/requests/comments_spec.rb index 7a38a46e8..c9b2ba9dc 100644 --- a/spec/requests/comments_spec.rb +++ b/spec/requests/comments_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Comments" do describe "GET /comments" do diff --git a/spec/requests/forums_spec.rb b/spec/requests/forums_spec.rb index ee85dacfd..ff7cb283d 100644 --- a/spec/requests/forums_spec.rb +++ b/spec/requests/forums_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Forums" do describe "GET /forums" do diff --git a/spec/requests/gardens_spec.rb b/spec/requests/gardens_spec.rb index bc8cd3ec2..91a8dc8b7 100644 --- a/spec/requests/gardens_spec.rb +++ b/spec/requests/gardens_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Gardens" do describe "GET /gardens" do diff --git a/spec/requests/harvests_spec.rb b/spec/requests/harvests_spec.rb index edb408b0b..f3774b3c0 100644 --- a/spec/requests/harvests_spec.rb +++ b/spec/requests/harvests_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Harvests" do describe "GET /harvests" do diff --git a/spec/requests/notifications_spec.rb b/spec/requests/notifications_spec.rb index 62031013e..85afbdd9f 100644 --- a/spec/requests/notifications_spec.rb +++ b/spec/requests/notifications_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Notifications" do describe "GET /notifications" do diff --git a/spec/requests/photos_spec.rb b/spec/requests/photos_spec.rb index bfb595245..b937ded3d 100644 --- a/spec/requests/photos_spec.rb +++ b/spec/requests/photos_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Photos" do describe "GET /photos" do diff --git a/spec/requests/plant_parts_spec.rb b/spec/requests/plant_parts_spec.rb index 4f607b22f..1fc2150b2 100644 --- a/spec/requests/plant_parts_spec.rb +++ b/spec/requests/plant_parts_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "PlantParts" do describe "GET /plant_parts" do diff --git a/spec/requests/plantings_spec.rb b/spec/requests/plantings_spec.rb index cc5580f58..cb66922e0 100644 --- a/spec/requests/plantings_spec.rb +++ b/spec/requests/plantings_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Plantings" do describe "GET /plantings" do diff --git a/spec/requests/post_spec.rb b/spec/requests/post_spec.rb index 5cfcf60bf..3bb479aa8 100644 --- a/spec/requests/post_spec.rb +++ b/spec/requests/post_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Posts" do describe "GET /posts" do diff --git a/spec/requests/scientific_names_spec.rb b/spec/requests/scientific_names_spec.rb index 0b2d8dd5a..922f6f270 100644 --- a/spec/requests/scientific_names_spec.rb +++ b/spec/requests/scientific_names_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "ScientificNames" do describe "GET /scientific_names" do diff --git a/spec/requests/seeds_spec.rb b/spec/requests/seeds_spec.rb index ac3ee1076..8bc5aeccf 100644 --- a/spec/requests/seeds_spec.rb +++ b/spec/requests/seeds_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "Seeds" do describe "GET /seeds" do diff --git a/spec/routing/account_types_routing_spec.rb b/spec/routing/account_types_routing_spec.rb index 456cedebe..440c16956 100644 --- a/spec/routing/account_types_routing_spec.rb +++ b/spec/routing/account_types_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe AccountTypesController do describe "routing" do diff --git a/spec/routing/authentications_routing_spec.rb b/spec/routing/authentications_routing_spec.rb index 1a639dead..5d907428f 100644 --- a/spec/routing/authentications_routing_spec.rb +++ b/spec/routing/authentications_routing_spec.rb @@ -1,32 +1,11 @@ -require "spec_helper" +require "rails_helper" describe AuthenticationsController do describe "routing" do - - it "routes to #index" do - get("/authentications").should route_to("authentications#index") - end - - it "routes to #new" do - get("/authentications/new").should route_to("authentications#new") - end - - it "routes to #show" do - get("/authentications/1").should route_to("authentications#show", :id => "1") - end - - it "routes to #edit" do - get("/authentications/1/edit").should route_to("authentications#edit", :id => "1") - end - it "routes to #create" do post("/authentications").should route_to("authentications#create") end - it "routes to #update" do - put("/authentications/1").should route_to("authentications#update", :id => "1") - end - it "routes to #destroy" do delete("/authentications/1").should route_to("authentications#destroy", :id => "1") end diff --git a/spec/routing/comments_routing_spec.rb b/spec/routing/comments_routing_spec.rb index 73c80563e..4a0fe8026 100644 --- a/spec/routing/comments_routing_spec.rb +++ b/spec/routing/comments_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe CommentsController do describe "routing" do diff --git a/spec/routing/crops_routing_spec.rb b/spec/routing/crops_routing_spec.rb index 450ad30f3..1e1fe4aac 100644 --- a/spec/routing/crops_routing_spec.rb +++ b/spec/routing/crops_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe CropsController do describe "routing" do diff --git a/spec/routing/forums_routing_spec.rb b/spec/routing/forums_routing_spec.rb index c783d5199..4bd7d6097 100644 --- a/spec/routing/forums_routing_spec.rb +++ b/spec/routing/forums_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe ForumsController do describe "routing" do diff --git a/spec/routing/gardens_routing_spec.rb b/spec/routing/gardens_routing_spec.rb index e3fbd6f31..1c627e091 100644 --- a/spec/routing/gardens_routing_spec.rb +++ b/spec/routing/gardens_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe GardensController do describe "routing" do diff --git a/spec/routing/harvests_routing_spec.rb b/spec/routing/harvests_routing_spec.rb index 66ab7151e..8b34d920a 100644 --- a/spec/routing/harvests_routing_spec.rb +++ b/spec/routing/harvests_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe HarvestsController do describe "routing" do diff --git a/spec/routing/notifications_routing_spec.rb b/spec/routing/notifications_routing_spec.rb index 421a443b3..35f54689f 100644 --- a/spec/routing/notifications_routing_spec.rb +++ b/spec/routing/notifications_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe NotificationsController do describe "routing" do diff --git a/spec/routing/order_items_routing_spec.rb b/spec/routing/order_items_routing_spec.rb index 1993db17d..858a873ad 100644 --- a/spec/routing/order_items_routing_spec.rb +++ b/spec/routing/order_items_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe OrderItemsController do describe "routing" do diff --git a/spec/routing/orders_routing_spec.rb b/spec/routing/orders_routing_spec.rb index 77e2c131d..7fc9735ee 100644 --- a/spec/routing/orders_routing_spec.rb +++ b/spec/routing/orders_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe OrdersController do describe "routing" do diff --git a/spec/routing/photos_routing_spec.rb b/spec/routing/photos_routing_spec.rb index d7dc394ed..5bdfeca07 100644 --- a/spec/routing/photos_routing_spec.rb +++ b/spec/routing/photos_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PhotosController do describe "routing" do diff --git a/spec/routing/plant_parts_routing_spec.rb b/spec/routing/plant_parts_routing_spec.rb index 419b4a05e..54d02caa1 100644 --- a/spec/routing/plant_parts_routing_spec.rb +++ b/spec/routing/plant_parts_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PlantPartsController do describe "routing" do diff --git a/spec/routing/plantings_routing_spec.rb b/spec/routing/plantings_routing_spec.rb index 08fb24301..bf3e1e8b8 100644 --- a/spec/routing/plantings_routing_spec.rb +++ b/spec/routing/plantings_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PlantingsController do describe "routing" do diff --git a/spec/routing/products_routing_spec.rb b/spec/routing/products_routing_spec.rb index e50a77956..a9c2fa004 100644 --- a/spec/routing/products_routing_spec.rb +++ b/spec/routing/products_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe ProductsController do describe "routing" do diff --git a/spec/routing/roles_routing_spec.rb b/spec/routing/roles_routing_spec.rb index 4084a6e7e..0a7900f9d 100644 --- a/spec/routing/roles_routing_spec.rb +++ b/spec/routing/roles_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe RolesController do describe "routing" do diff --git a/spec/routing/scientific_names_routing_spec.rb b/spec/routing/scientific_names_routing_spec.rb index c78d1ff7d..00c049289 100644 --- a/spec/routing/scientific_names_routing_spec.rb +++ b/spec/routing/scientific_names_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe ScientificNamesController do describe "routing" do diff --git a/spec/routing/seeds_routing_spec.rb b/spec/routing/seeds_routing_spec.rb index d4746d299..4fe46774a 100644 --- a/spec/routing/seeds_routing_spec.rb +++ b/spec/routing/seeds_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe SeedsController do describe "routing" do diff --git a/spec/routing/updates_routing_spec.rb b/spec/routing/updates_routing_spec.rb index 0266d9686..9ff2b5ccd 100644 --- a/spec/routing/updates_routing_spec.rb +++ b/spec/routing/updates_routing_spec.rb @@ -1,4 +1,4 @@ -require "spec_helper" +require "rails_helper" describe PostsController do describe "routing" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f77c8b267..191e049ee 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,70 +1,87 @@ -# This file is copied to spec/ when you run 'rails generate rspec:install' -ENV["RAILS_ENV"] ||= 'test' - -require File.expand_path("../../config/environment", __FILE__) -require 'rspec/rails' -require 'rspec/autorun' - -require 'simplecov' -require 'coveralls' - -# output coverage locally AND send it to coveralls -SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ - SimpleCov::Formatter::HTMLFormatter, - Coveralls::SimpleCov::Formatter -] - -# fail if there's a significant test coverage drop -SimpleCov.maximum_coverage_drop 1 - -SimpleCov.start :rails do - add_filter 'spec/' - add_filter 'vendor/' -end - -require 'capybara' -require 'capybara/poltergeist' -Capybara.javascript_driver = :poltergeist -Capybara.app_host = 'http://localhost' -Capybara.server_port = 8080 - -include Warden::Test::Helpers - -# Requires supporting ruby files with custom matchers and macros, etc, -# in spec/support/ and its subdirectories. -Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} -Dir[Rails.root.join("spec/features/shared_examples/**/*.rb")].each {|f| require f} - +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause this +# file to always be loaded, without a need to explicitly require it in any files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| - # ## Mock Framework - # - # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line - # - # config.mock_with :mocha - # config.mock_with :flexmock - # config.mock_with :rr + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.syntax = [:should, :expect] + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end - # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures - config.fixture_path = "#{::Rails.root}/spec/fixtures" + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = false + mocks.syntax = [:should, :expect] + end - # If you're not using ActiveRecord, or you'd prefer not to run each of your - # examples within a transaction, remove the following line or assign false - # instead of true. - config.use_transactional_fixtures = false +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. - # If true, the base class of anonymous controllers will be inferred - # automatically. This will be the default behavior in future versions of - # rspec-rails. - config.infer_base_class_for_anonymous_controllers = false + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Limits the available syntax to the non-monkey patched syntax that is recommended. + # For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + # config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 3 # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 - config.order = "random" + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed - # 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 end diff --git a/spec/support/elasticsearch_helpers.rb b/spec/support/elasticsearch_helpers.rb new file mode 100644 index 000000000..0d89eb33b --- /dev/null +++ b/spec/support/elasticsearch_helpers.rb @@ -0,0 +1,18 @@ +module ElasticsearchHelpers + def sync_elasticsearch(crops) + if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" + crops.each {|crop| crop.__elasticsearch__.index_document} + Crop.__elasticsearch__.refresh_index! + end + end +end + +RSpec.configure do |config| + config.include ElasticsearchHelpers + + config.before(:each) do + if ENV['GROWSTUFF_ELASTICSEARCH'] == "true" + Crop.__elasticsearch__.create_index! force: true + end + end +end diff --git a/spec/views/about/contact_spec.rb b/spec/views/about/contact_spec.rb index 85d232126..f655a1394 100644 --- a/spec/views/about/contact_spec.rb +++ b/spec/views/about/contact_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'about/contact.html.haml', :type => "view" do before(:each) do @@ -7,6 +7,6 @@ describe 'about/contact.html.haml', :type => "view" do it 'should show support faq' do render - rendered.should contain 'General contact email' + rendered.should have_content 'General contact email' end end diff --git a/spec/views/account_types/edit.html.haml_spec.rb b/spec/views/account_types/edit.html.haml_spec.rb index bb5fbf433..cf77a0402 100644 --- a/spec/views/account_types/edit.html.haml_spec.rb +++ b/spec/views/account_types/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "account_types/edit" do before(:each) do diff --git a/spec/views/account_types/index.html.haml_spec.rb b/spec/views/account_types/index.html.haml_spec.rb index cded5ef32..1bbd0dc72 100644 --- a/spec/views/account_types/index.html.haml_spec.rb +++ b/spec/views/account_types/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "account_types/index" do before(:each) do diff --git a/spec/views/account_types/new.html.haml_spec.rb b/spec/views/account_types/new.html.haml_spec.rb index 3babc2fb9..a9e97ee54 100644 --- a/spec/views/account_types/new.html.haml_spec.rb +++ b/spec/views/account_types/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "account_types/new" do before(:each) do diff --git a/spec/views/account_types/show.html.haml_spec.rb b/spec/views/account_types/show.html.haml_spec.rb index 941026cf4..bee9cebd5 100644 --- a/spec/views/account_types/show.html.haml_spec.rb +++ b/spec/views/account_types/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "account_types/show" do before(:each) do diff --git a/spec/views/accounts/edit.html.haml_spec.rb b/spec/views/accounts/edit.html.haml_spec.rb index af3931dfa..124ec1d12 100644 --- a/spec/views/accounts/edit.html.haml_spec.rb +++ b/spec/views/accounts/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "accounts/edit" do before(:each) do diff --git a/spec/views/accounts/index.html.haml_spec.rb b/spec/views/accounts/index.html.haml_spec.rb index 56e76b0ff..e8c0f1a79 100644 --- a/spec/views/accounts/index.html.haml_spec.rb +++ b/spec/views/accounts/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "accounts/index" do before(:each) do diff --git a/spec/views/accounts/new.html.haml_spec.rb b/spec/views/accounts/new.html.haml_spec.rb index ab60cc346..3a2b7cdbc 100644 --- a/spec/views/accounts/new.html.haml_spec.rb +++ b/spec/views/accounts/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "accounts/new" do before(:each) do diff --git a/spec/views/accounts/show.html.haml_spec.rb b/spec/views/accounts/show.html.haml_spec.rb index 5b429e13e..13dfc3589 100644 --- a/spec/views/accounts/show.html.haml_spec.rb +++ b/spec/views/accounts/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "accounts/show" do before(:each) do @@ -9,8 +9,8 @@ describe "accounts/show" do it "renders attributes in

" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - rendered.should contain @account.member_id.to_s - rendered.should contain 'Free' - rendered.should contain @account.paid_until.to_s + rendered.should have_content @account.member_id.to_s + rendered.should have_content 'Free' + rendered.should have_content @account.paid_until.to_s end end diff --git a/spec/views/admin/index_spec.rb b/spec/views/admin/index_spec.rb index fe92a4193..eb9dd9d01 100644 --- a/spec/views/admin/index_spec.rb +++ b/spec/views/admin/index_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'admin/index.html.haml', :type => "view" do before(:each) do @@ -16,6 +16,6 @@ describe 'admin/index.html.haml', :type => "view" do end it "has a link to newsletter subscribers" do - rendered.should contain "Newsletter subscribers" + rendered.should have_content "Newsletter subscribers" end end diff --git a/spec/views/admin/newsletter_spec.rb b/spec/views/admin/newsletter_spec.rb index a0d871cd4..d072aee2e 100644 --- a/spec/views/admin/newsletter_spec.rb +++ b/spec/views/admin/newsletter_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'admin/newsletter.html.haml', :type => "view" do before(:each) do @@ -11,6 +11,6 @@ describe 'admin/newsletter.html.haml', :type => "view" do end it "lists newsletter subscribers by email" do - rendered.should contain @subscriber.email + rendered.should have_content @subscriber.email end end diff --git a/spec/views/admin/orders/index_spec.rb b/spec/views/admin/orders/index_spec.rb index bc49a0028..e4279fdd0 100644 --- a/spec/views/admin/orders/index_spec.rb +++ b/spec/views/admin/orders/index_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'admin/orders/index.html.haml', :type => "view" do before(:each) do diff --git a/spec/views/authentications/index.html.haml_spec.rb b/spec/views/authentications/index.html.haml_spec.rb deleted file mode 100644 index f780966ae..000000000 --- a/spec/views/authentications/index.html.haml_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe "authentications/index" do - before(:each) do - assign(:authentications, [ - stub_model(Authentication, - :member_id => 1, - :provider => "Provider", - :uid => "Uid", - :name => "Name" - ), - stub_model(Authentication, - :member_id => 1, - :provider => "Provider", - :uid => "Uid", - :name => "Name" - ) - ]) - end - - it "renders a list of authentications" do - render - # Run the generator again with the --webrat flag if you want to use webrat matchers - assert_select ".authentication", :count => 2 - assert_select ".provider", :text => "Provider".to_s, :count => 2 - assert_select ".name", :text => "Name".to_s, :count => 2 - end -end diff --git a/spec/views/comments/edit.html.haml_spec.rb b/spec/views/comments/edit.html.haml_spec.rb index beee78013..87ba9c549 100644 --- a/spec/views/comments/edit.html.haml_spec.rb +++ b/spec/views/comments/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "comments/edit" do before(:each) do diff --git a/spec/views/comments/index.html.haml_spec.rb b/spec/views/comments/index.html.haml_spec.rb index 3cf270149..7161978ab 100644 --- a/spec/views/comments/index.html.haml_spec.rb +++ b/spec/views/comments/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "comments/index" do before(:each) do @@ -18,8 +18,8 @@ describe "comments/index" do it "renders a list of comments" do render - rendered.should contain 'OMG LOL' - rendered.should contain 'ROFL' + rendered.should have_content 'OMG LOL' + rendered.should have_content 'ROFL' end it "contains an RSS feed link" do diff --git a/spec/views/comments/index.rss.haml_spec.rb b/spec/views/comments/index.rss.haml_spec.rb index e5eeeac95..5278a8b56 100644 --- a/spec/views/comments/index.rss.haml_spec.rb +++ b/spec/views/comments/index.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'comments/index.rss.haml' do before(:each) do @@ -13,20 +13,20 @@ describe 'comments/index.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recent comments on all posts" + rendered.should have_content "Recent comments on all posts" end it 'shows item title' do - rendered.should contain "Comment by #{@author.login_name}" + rendered.should have_content "Comment by #{@author.login_name}" end it 'escapes html for link to post' do # it's then unescaped by 'render' so we don't actually look for < - rendered.should contain ' 'crops/grown_for', :locals => { :crop => @crop } - rendered.should contain @pp.name + rendered.should have_content @pp.name 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 19a756a7c..6c2a35481 100644 --- a/spec/views/crops/_planting_advice.html.haml_spec.rb +++ b/spec/views/crops/_planting_advice.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/_planting_advice" do before(:each) do @@ -14,14 +14,14 @@ describe "crops/_planting_advice" do context "sunniness" do it "doesn't show sunniness if none are set" do render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should contain "Plant in: not known." + 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 } - rendered.should contain "Plant in:" - rendered.should contain "sun (1)" + rendered.should have_content "Plant in:" + rendered.should have_content "sun (1)" end it "shows multiple sunniness frequencies" do @@ -29,8 +29,8 @@ describe "crops/_planting_advice" do FactoryGirl.create(:sunny_planting, :crop => @crop) FactoryGirl.create(:shady_planting, :crop => @crop) render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should contain "Plant in:" - rendered.should contain "sun (2), shade (1)" + rendered.should have_content "Plant in:" + rendered.should have_content "sun (2), shade (1)" end end @@ -39,14 +39,14 @@ describe "crops/_planting_advice" do it "doesn't show planted_from if none are set" do render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should contain "Plant from: not known." + 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 } - rendered.should contain "Plant from:" - rendered.should contain "seed (1)" + rendered.should have_content "Plant from:" + rendered.should have_content "seed (1)" end it "shows multiple planted_from frequencies" do @@ -54,8 +54,8 @@ describe "crops/_planting_advice" do FactoryGirl.create(:seed_planting, :crop => @crop) FactoryGirl.create(:cutting_planting, :crop => @crop) render :partial => 'crops/planting_advice', :locals => { :crop => @crop } - rendered.should contain "Plant from:" - rendered.should contain "seed (2), cutting (1)" + rendered.should have_content "Plant from:" + rendered.should have_content "seed (2), cutting (1)" end end diff --git a/spec/views/crops/_popover.html.haml_spec.rb b/spec/views/crops/_popover.html.haml_spec.rb index ad07f8ada..d503a7235 100644 --- a/spec/views/crops/_popover.html.haml_spec.rb +++ b/spec/views/crops/_popover.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/_popover" do before(:each) do @@ -10,11 +10,11 @@ describe "crops/_popover" do end it 'has a scientific name' do - rendered.should contain 'Solanum lycopersicum' + rendered.should have_content 'Solanum lycopersicum' end it 'shows count of plantings' do - rendered.should contain '1 time' + rendered.should have_content '1 time' end end diff --git a/spec/views/crops/edit.html.haml_spec.rb b/spec/views/crops/edit.html.haml_spec.rb index 3db9c52b0..031addb30 100644 --- a/spec/views/crops/edit.html.haml_spec.rb +++ b/spec/views/crops/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/edit" do before(:each) do @@ -14,7 +14,7 @@ describe "crops/edit" do end it "shows the creator" do - rendered.should contain "Added by #{@crop.creator} less than a minute ago." + rendered.should have_content "Added by #{@crop.creator} less than a minute ago." end it "renders the edit crop form" do diff --git a/spec/views/crops/hierarchy.html.haml_spec.rb b/spec/views/crops/hierarchy.html.haml_spec.rb index e5fbc7883..22b02d18f 100644 --- a/spec/views/crops/hierarchy.html.haml_spec.rb +++ b/spec/views/crops/hierarchy.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/hierarchy" do before(:each) do diff --git a/spec/views/crops/index.html.haml_spec.rb b/spec/views/crops/index.html.haml_spec.rb index ca0ecc39b..33ab3e07e 100644 --- a/spec/views/crops/index.html.haml_spec.rb +++ b/spec/views/crops/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/index" do before(:each) do @@ -8,24 +8,11 @@ describe "crops/index" do total_entries = 2 @tomato = FactoryGirl.create(:tomato) @maize = FactoryGirl.create(:maize) - crops = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| + assign(:crops, [@tomato, @maize]) + paginated_crops = WillPaginate::Collection.create(page, per_page, total_entries) do |pager| pager.replace([ @tomato, @maize ]) end - assign(:crops, crops) - end - - it "has a form for sorting by" do - render - assert_select "form" - assert_select "select#sort" - assert_select "option[value=alpha]" - assert_select "option[value=popular]" - end - - it "renders a list of crops" do - render - assert_select "a", :text => @maize.name - assert_select "a", :text => @tomato.name + assign(:paginated_crops, paginated_crops) end it "shows photos where available" do @@ -50,14 +37,14 @@ describe "crops/index" do end it "shows a new crop link" do - rendered.should contain "New Crop" + rendered.should have_content "New Crop" end end context "downloads" do it "offers data downloads" do render - rendered.should contain "The data on this page is available in the following formats:" + 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') diff --git a/spec/views/crops/index.rss.haml_spec.rb b/spec/views/crops/index.rss.haml_spec.rb index f0c5ac653..0e8887411 100644 --- a/spec/views/crops/index.rss.haml_spec.rb +++ b/spec/views/crops/index.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'crops/index.rss.haml' do before(:each) do @@ -11,12 +11,12 @@ describe 'crops/index.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recently added crops" + rendered.should have_content "Recently added crops" end it 'shows names of crops' do - rendered.should contain @tomato.name - rendered.should contain @maize.name + rendered.should have_content @tomato.name + rendered.should have_content @maize.name end end diff --git a/spec/views/crops/new.html.haml_spec.rb b/spec/views/crops/new.html.haml_spec.rb index 0aa443f74..0c834d738 100644 --- a/spec/views/crops/new.html.haml_spec.rb +++ b/spec/views/crops/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/new" do before(:each) do diff --git a/spec/views/crops/search.html.haml_spec.rb b/spec/views/crops/search.html.haml_spec.rb deleted file mode 100644 index c186c6c4c..000000000 --- a/spec/views/crops/search.html.haml_spec.rb +++ /dev/null @@ -1,50 +0,0 @@ -require 'spec_helper' - -describe "crops/search" do - before(:each) do - controller.stub(:current_user) { nil } - end - - context "has results" do - - before :each do - @tomato = FactoryGirl.create(:tomato) - @roma = FactoryGirl.create(:crop, :name => 'Roma tomato', :parent => @tomato) - assign(:search, 'tomato') - assign(:exact_match, @tomato) - assign(:partial_matches, [@roma]) - render - end - - it "shows exact matches" do - assert_select "div#exact_match" do - assert_select "a[href=#{crop_path(@tomato)}]" - end - end - - it "shows partial matches" do - assert_select "div#partial_matches" do - assert_select "a[href=#{crop_path(@roma)}]" - end - end - end - - context "no results" do - before :each do - assign(:exact_match, nil) - assign(:partial_matches, []) - assign(:search, 'tomato') - render - end - - it "tells you there are no matches" do - rendered.should contain "No results found" - end - - it "links to browse crops" do - assert_select "a", :href => crops_path - rendered.should contain "Try browsing our crop database instead" - end - end - -end diff --git a/spec/views/crops/wrangle.html.haml_spec.rb b/spec/views/crops/wrangle.html.haml_spec.rb index a4adde063..4426382d2 100644 --- a/spec/views/crops/wrangle.html.haml_spec.rb +++ b/spec/views/crops/wrangle.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "crops/wrangle" do before(:each) do @@ -18,8 +18,8 @@ describe "crops/wrangle" do it 'contains handy links for wranglers' do render - rendered.should contain "Crop wrangler guidelines" - rendered.should contain "mailing list" + rendered.should have_content "Crop wrangler guidelines" + rendered.should have_content "mailing list" end it 'has a link to add a crop' do diff --git a/spec/views/devise/confirmations/new_spec.rb b/spec/views/devise/confirmations/new_spec.rb index 1f4de467b..1e1555db3 100644 --- a/spec/views/devise/confirmations/new_spec.rb +++ b/spec/views/devise/confirmations/new_spec.rb @@ -9,6 +9,6 @@ describe 'devise/confirmations/new.html.haml', :type => "view" do end it 'should contain a login field' do - rendered.should contain "Enter either your login name or your email address" + rendered.should have_content "Enter either your login name or your email address" end end diff --git a/spec/views/devise/mailer/confirmation_instructions_spec.rb b/spec/views/devise/mailer/confirmation_instructions_spec.rb index 3a0921ae7..e42dd762c 100644 --- a/spec/views/devise/mailer/confirmation_instructions_spec.rb +++ b/spec/views/devise/mailer/confirmation_instructions_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/mailer/confirmation_instructions.html.haml', :type => "view" do @@ -9,11 +9,11 @@ describe 'devise/mailer/confirmation_instructions.html.haml', :type => "view" do end it 'should have a confirmation link' do - rendered.should contain 'Confirm my account' + rendered.should have_content 'Confirm my account' end it 'should have a link to the homepage' do - rendered.should contain root_url + rendered.should have_content root_url end end end diff --git a/spec/views/devise/mailer/reset_password_instructions_spec.rb b/spec/views/devise/mailer/reset_password_instructions_spec.rb index 4f19281a3..d75f69881 100644 --- a/spec/views/devise/mailer/reset_password_instructions_spec.rb +++ b/spec/views/devise/mailer/reset_password_instructions_spec.rb @@ -1,18 +1,18 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/mailer/reset_password_instructions.html.haml', :type => "view" do context "logged in" do before(:each) do @resource = mock_model(Member) - @resource.stub!(:email).and_return("example@example.com") - @resource.stub!(:reset_password_token).and_return("joe") + @resource.stub(:email).and_return("example@example.com") + @resource.stub(:reset_password_token).and_return("joe") render end it 'should have some of the right text' do - rendered.should contain 'Change my password' - rendered.should contain 'Someone has requested a link to reset your password' + rendered.should have_content 'Change my password' + rendered.should have_content 'Someone has requested a link to reset your password' end end end diff --git a/spec/views/devise/mailer/unlock_instructions_spec.rb b/spec/views/devise/mailer/unlock_instructions_spec.rb index 9cbca83a4..fd4c444f8 100644 --- a/spec/views/devise/mailer/unlock_instructions_spec.rb +++ b/spec/views/devise/mailer/unlock_instructions_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/mailer/unlock_instructions.html.haml', :type => "view" do context "logged in" do before(:each) do @@ -7,11 +7,11 @@ describe 'devise/mailer/unlock_instructions.html.haml', :type => "view" do end it "should explain what's happened" do - rendered.should contain "account has been locked" + rendered.should have_content "account has been locked" end it "should have an unlock link" do - rendered.should contain "Unlock my account" + rendered.should have_content "Unlock my account" end end end diff --git a/spec/views/devise/registrations/edit_spec.rb b/spec/views/devise/registrations/edit_spec.rb index f9c48ec1a..c99b84aed 100644 --- a/spec/views/devise/registrations/edit_spec.rb +++ b/spec/views/devise/registrations/edit_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/registrations/edit.html.haml', :type => "view" do @@ -15,7 +15,7 @@ describe 'devise/registrations/edit.html.haml', :type => "view" do it 'should have some fields' do render - rendered.should contain 'Email' + rendered.should have_content 'Email' end context 'email section' do diff --git a/spec/views/devise/registrations/new_spec.rb b/spec/views/devise/registrations/new_spec.rb index b17b000b7..f7dcfffe1 100644 --- a/spec/views/devise/registrations/new_spec.rb +++ b/spec/views/devise/registrations/new_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/registrations/new.html.haml', :type => "view" do @@ -12,7 +12,7 @@ describe 'devise/registrations/new.html.haml', :type => "view" do end it 'should have some fields' do - rendered.should contain 'Email' + rendered.should have_content 'Email' end it 'has a checkbox for newsletter subscription' do diff --git a/spec/views/devise/sessions/new_spec.rb b/spec/views/devise/sessions/new_spec.rb index 9a178e63f..6d66e6a48 100644 --- a/spec/views/devise/sessions/new_spec.rb +++ b/spec/views/devise/sessions/new_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/sessions/new.html.haml', :type => "view" do @@ -12,8 +12,8 @@ describe 'devise/sessions/new.html.haml', :type => "view" do end it 'should have some fields' do - rendered.should contain 'Remember me' - rendered.should contain 'Password' + rendered.should have_content 'Remember me' + rendered.should have_content 'Password' end end end diff --git a/spec/views/devise/shared/_links_spec.rb b/spec/views/devise/shared/_links_spec.rb index b86715a46..41f9b45ef 100644 --- a/spec/views/devise/shared/_links_spec.rb +++ b/spec/views/devise/shared/_links_spec.rb @@ -1,7 +1,7 @@ describe 'devise/shared/_links.haml', :type => "view" do def devise_mapping(register, recover, confirm, lock, oauth) - dm = mock("mappings") + dm = double("mappings") dm.stub(:registerable? => register) dm.stub(:recoverable? => recover) dm.stub(:confirmable? => confirm) diff --git a/spec/views/devise/unlocks/new_spec.rb b/spec/views/devise/unlocks/new_spec.rb index 0259691fe..fec998c4d 100644 --- a/spec/views/devise/unlocks/new_spec.rb +++ b/spec/views/devise/unlocks/new_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'devise/unlocks/new.html.haml', :type => "view" do @@ -12,7 +12,7 @@ describe 'devise/unlocks/new.html.haml', :type => "view" do end it 'should have some fields' do - rendered.should contain 'Email' + rendered.should have_content 'Email' end end end diff --git a/spec/views/forums/edit.html.haml_spec.rb b/spec/views/forums/edit.html.haml_spec.rb index 306f3bbf0..8a49b38be 100644 --- a/spec/views/forums/edit.html.haml_spec.rb +++ b/spec/views/forums/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "forums/edit" do before(:each) do diff --git a/spec/views/forums/index.html.haml_spec.rb b/spec/views/forums/index.html.haml_spec.rb index d2046de48..a946c2407 100644 --- a/spec/views/forums/index.html.haml_spec.rb +++ b/spec/views/forums/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "forums/index" do before(:each) do @@ -28,8 +28,8 @@ describe "forums/index" do it "displays posts" do assert_select "table" - rendered.should contain @post.subject - rendered.should contain "less than a minute ago" + rendered.should have_content @post.subject + rendered.should have_content "less than a minute ago" end it "displays comment count" do diff --git a/spec/views/forums/new.html.haml_spec.rb b/spec/views/forums/new.html.haml_spec.rb index bfda7bfa1..86043eb8c 100644 --- a/spec/views/forums/new.html.haml_spec.rb +++ b/spec/views/forums/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "forums/new" do before(:each) do diff --git a/spec/views/forums/show.html.haml_spec.rb b/spec/views/forums/show.html.haml_spec.rb index 735f5d482..45ff9aeed 100644 --- a/spec/views/forums/show.html.haml_spec.rb +++ b/spec/views/forums/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "forums/show" do before(:each) do @@ -8,8 +8,8 @@ describe "forums/show" do it "renders attributes" do render - rendered.should contain "Everything about permaculture" - rendered.should contain @forum.owner.to_s + rendered.should have_content "Everything about permaculture" + rendered.should have_content @forum.owner.to_s end it "parses markdown description into html" do @@ -24,14 +24,14 @@ describe "forums/show" do it 'has no posts' do render - rendered.should contain "No posts yet." + rendered.should have_content "No posts yet." end it 'shows posts' do @post = FactoryGirl.create(:post, :forum => @forum) render assert_select "table" - rendered.should contain @post.subject - rendered.should contain @post.author.to_s + rendered.should have_content @post.subject + rendered.should have_content @post.author.to_s end end diff --git a/spec/views/gardens/edit.html.haml_spec.rb b/spec/views/gardens/edit.html.haml_spec.rb index 781274c2c..e5381c324 100644 --- a/spec/views/gardens/edit.html.haml_spec.rb +++ b/spec/views/gardens/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +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 123a75db9..a075822be 100644 --- a/spec/views/gardens/index.html.haml_spec.rb +++ b/spec/views/gardens/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "gardens/index" do before(:each) do diff --git a/spec/views/gardens/new.html.haml_spec.rb b/spec/views/gardens/new.html.haml_spec.rb index 5e7d4c1e7..ff52f1f28 100644 --- a/spec/views/gardens/new.html.haml_spec.rb +++ b/spec/views/gardens/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "gardens/new" do before(:each) do diff --git a/spec/views/gardens/show.html.haml_spec.rb b/spec/views/gardens/show.html.haml_spec.rb index cd38a0ec4..6327073ee 100644 --- a/spec/views/gardens/show.html.haml_spec.rb +++ b/spec/views/gardens/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "gardens/show" do before(:each) do @@ -11,15 +11,15 @@ describe "gardens/show" do end it 'should show the location' do - rendered.should contain @garden.location + rendered.should have_content @garden.location end it 'should show the area' do - rendered.should contain pluralize(@garden.area, @garden.area_unit) + rendered.should have_content pluralize(@garden.area, @garden.area_unit) end it 'should show the description' do - rendered.should contain "totally cool garden" + rendered.should have_content "totally cool garden" end it 'renders markdown in the description' do @@ -27,11 +27,11 @@ describe "gardens/show" do end it 'should show plantings on the garden page' do - rendered.should contain @planting.crop.name + rendered.should have_content @planting.crop.name end it "doesn't show the note about random plantings" do - rendered.should_not contain "Note: these are a random selection" + rendered.should_not have_content "Note: these are a random selection" end context 'signed in' do @@ -42,11 +42,11 @@ describe "gardens/show" do end it 'should have an edit button' do - rendered.should contain 'Edit' + rendered.should have_content 'Edit' end it "shows a 'plant something' button" do - rendered.should contain "Plant something" + rendered.should have_content "Plant something" end it "links to the right crop in the planting link" do diff --git a/spec/views/harvests/edit.html.haml_spec.rb b/spec/views/harvests/edit.html.haml_spec.rb index e47d3ad4a..4802bab88 100644 --- a/spec/views/harvests/edit.html.haml_spec.rb +++ b/spec/views/harvests/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "harvests/edit" do before(:each) do diff --git a/spec/views/harvests/index.html.haml_spec.rb b/spec/views/harvests/index.html.haml_spec.rb index 093a383a9..8751a5c41 100644 --- a/spec/views/harvests/index.html.haml_spec.rb +++ b/spec/views/harvests/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "harvests/index" do before(:each) do @@ -37,7 +37,7 @@ describe "harvests/index" do it "provides data links" do render - rendered.should contain "The data on this page is available in the following formats:" + 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') end @@ -45,13 +45,13 @@ describe "harvests/index" do it "displays member's name in title" do assign(:owner, @member) render - view.content_for(:title).should contain @member.login_name + view.content_for(:title).should have_content @member.login_name end it "displays crop's name in title" do assign(:crop, @tomato) render - view.content_for(:title).should contain @tomato.name + view.content_for(:title).should have_content @tomato.name end end diff --git a/spec/views/harvests/new.html.haml_spec.rb b/spec/views/harvests/new.html.haml_spec.rb index 81de2671a..93a595188 100644 --- a/spec/views/harvests/new.html.haml_spec.rb +++ b/spec/views/harvests/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "harvests/new" do before(:each) do diff --git a/spec/views/harvests/show.html.haml_spec.rb b/spec/views/harvests/show.html.haml_spec.rb index f03706be8..7c897a684 100644 --- a/spec/views/harvests/show.html.haml_spec.rb +++ b/spec/views/harvests/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "harvests/show" do before(:each) do @@ -9,9 +9,9 @@ describe "harvests/show" do end it "renders attributes" do - rendered.should contain @crop.name - rendered.should contain @harvest.harvested_at.to_s - rendered.should contain @harvest.plant_part.to_s + rendered.should have_content @crop.name + rendered.should have_content @harvest.harvested_at.to_s + rendered.should have_content @harvest.plant_part.to_s end end diff --git a/spec/views/home/_blurb.html.haml_spec.rb b/spec/views/home/_blurb.html.haml_spec.rb index 3660d0900..285363e5e 100644 --- a/spec/views/home/_blurb.html.haml_spec.rb +++ b/spec/views/home/_blurb.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/_blurb.html.haml', :type => "view" do context 'signed out' do @@ -8,7 +8,7 @@ describe 'home/_blurb.html.haml', :type => "view" do end it 'has description' do - rendered.should contain 'is a community of food gardeners' + rendered.should have_content 'is a community of food gardeners' end it 'has signup section' do @@ -17,7 +17,7 @@ describe 'home/_blurb.html.haml', :type => "view" do end it 'has a link to sign in' do - rendered.should contain "Or sign in if you already have an account" + rendered.should have_content "Or sign in if you already have an account" 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 b479f4ee4..548e0a375 100644 --- a/spec/views/home/_crops.html.haml_spec.rb +++ b/spec/views/home/_crops.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/_crops.html.haml', :type => "view" do before(:each) do @@ -21,7 +21,7 @@ describe 'home/_crops.html.haml', :type => "view" do it 'shows plantings section' do assert_select 'h2', :text => 'Recently planted' - rendered.should contain @planting.location + rendered.should have_content @planting.location end it 'shows recently added crops' do diff --git a/spec/views/home/_keep_in_touch.html.haml_spec.rb b/spec/views/home/_keep_in_touch.html.haml_spec.rb deleted file mode 100644 index 3f12d4145..000000000 --- a/spec/views/home/_keep_in_touch.html.haml_spec.rb +++ /dev/null @@ -1,28 +0,0 @@ -require 'spec_helper' - -describe 'home/_keep_in_touch.html.haml', :type => "view" do - before :each do - render - end - - it 'has a heading' do - assert_select 'h2', 'Keep in touch' - end - - it 'links to twitter' do - assert_select 'a', :href => 'http://twitter.com/growstufforg' - end - - it 'links to facebook' do - assert_select 'a', :href =>'https://www.facebook.com/Growstufforg' - end - - it 'links to the blog' do - assert_select 'a', :href => 'http://blog.growstuff.org' - end - - it 'links to the newsletter' do - assert_select 'a', :href => 'http://blog.growstuff.org/newsletter' - end - -end \ No newline at end of file diff --git a/spec/views/home/_members.html.haml_spec.rb b/spec/views/home/_members.html.haml_spec.rb index 4b527f1a8..81f812a94 100644 --- a/spec/views/home/_members.html.haml_spec.rb +++ b/spec/views/home/_members.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/_members.html.haml', :type => "view" do before(:each) do @@ -11,13 +11,13 @@ describe 'home/_members.html.haml', :type => "view" do end it 'Has a heading' do - rendered.should contain "Some of our members" + rendered.should have_content "Some of our members" end it 'Shows members' do - rendered.should contain @member.login_name - rendered.should contain @member.location - rendered.should contain @planting.crop_name + rendered.should have_content @member.login_name + rendered.should have_content @member.location + rendered.should have_content @planting.crop_name end end diff --git a/spec/views/home/_open.html.haml_spec.rb b/spec/views/home/_open.html.haml_spec.rb deleted file mode 100644 index 543db7630..000000000 --- a/spec/views/home/_open.html.haml_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper' - -describe 'home/_open.html.haml', :type => "view" do - before(:each) do - render - end - - it 'has an open source section' do - assert_select 'h2', 'Open Source' - end - - it 'links to github' do - assert_select 'a', :href => 'http://github.com/Growstuff/growstuff' - end - - it 'has an open data section' do - assert_select 'h2', 'Open Data and APIs' - end - - it 'links to API docs' do - assert_select 'a', :href => 'http://wiki.growstuff.org/index.php/API' - end - - it 'has a get involved section' do - assert_select 'h2', 'Get Involved' - end - - it 'links to the mailing list' do - assert_select 'a', :href => 'http://lists.growstuff.org/mailman/listinfo/discuss' - end -end diff --git a/spec/views/home/_seeds.html.haml_spec.rb b/spec/views/home/_seeds.html.haml_spec.rb index bc5f6d2fa..82efa194d 100644 --- a/spec/views/home/_seeds.html.haml_spec.rb +++ b/spec/views/home/_seeds.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/_seeds.html.haml', :type => "view" do before(:each) do diff --git a/spec/views/home/_stats.html.haml_spec.rb b/spec/views/home/_stats.html.haml_spec.rb index 0f39e9e81..b067e44f8 100644 --- a/spec/views/home/_stats.html.haml_spec.rb +++ b/spec/views/home/_stats.html.haml_spec.rb @@ -1,8 +1,8 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/_stats.html.haml', :type => "view" do it 'has activity stats' do render - rendered.should contain "So far, 0 members have planted 0 crops" + rendered.should have_content "So far, 0 members have planted 0 crops" end end diff --git a/spec/views/home/index_spec.rb b/spec/views/home/index_spec.rb index 829c6fa36..fe651e149 100644 --- a/spec/views/home/index_spec.rb +++ b/spec/views/home/index_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'home/index.html.haml', :type => "view" do before(:each) do @@ -25,8 +25,8 @@ describe 'home/index.html.haml', :type => "view" do end it 'show interesting members' do - rendered.should contain @member.login_name - rendered.should contain @member.location + rendered.should have_content @member.login_name + rendered.should have_content @member.location end end @@ -38,7 +38,7 @@ describe 'home/index.html.haml', :type => "view" do end it 'should say welcome' do - rendered.should contain "Welcome to #{ENV['GROWSTUFF_SITE_NAME']}, #{@member.login_name}" + rendered.should have_content "Welcome to #{ENV['GROWSTUFF_SITE_NAME']}, #{@member.login_name}" end end diff --git a/spec/views/layouts/_footer_spec.rb b/spec/views/layouts/_footer_spec.rb deleted file mode 100644 index c3dc3a9b7..000000000 --- a/spec/views/layouts/_footer_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec_helper' - -describe 'layouts/_footer.html.haml', :type => "view" do - - before(:each) do - render - end - - it 'should have links in footer' do - rendered.should contain 'About' - rendered.should contain 'Contact' - assert_select("a[href=/policy/tos]", 'Terms of Service') - assert_select("a[href=/policy/privacy]", 'Privacy Policy') - assert_select("a[href=/policy/community]", 'Community Guidelines') - rendered.should contain 'Open Source' - assert_select("a[href=/support]", 'Support/FAQ') - end - - it 'should not have an explicit wiki link' do - rendered.should_not contain 'Wiki' - end -end diff --git a/spec/views/layouts/_header_spec.rb b/spec/views/layouts/_header_spec.rb index 2274b25b5..f4ca3034a 100644 --- a/spec/views/layouts/_header_spec.rb +++ b/spec/views/layouts/_header_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'layouts/_header.html.haml', :type => "view" do context "when not logged in" do @@ -12,24 +12,24 @@ describe 'layouts/_header.html.haml', :type => "view" do end it 'should have signup/signin links' do - rendered.should contain 'Sign up' - rendered.should contain 'Sign in' + rendered.should have_content 'Sign up' + rendered.should have_content 'Sign in' end it 'has a Crops link' do - rendered.should contain "Crops" + rendered.should have_content "Crops" end it 'has a Seeds link' do - rendered.should contain "Seeds" + rendered.should have_content "Seeds" end it 'has a Places link' do - rendered.should contain "Community Map" + rendered.should have_content "Community Map" end it 'has a Community section' do - rendered.should contain "Community" + rendered.should have_content "Community" end it 'links to members' do @@ -62,7 +62,7 @@ describe 'layouts/_header.html.haml', :type => "view" do context "your stuff" do it 'should have a Your Stuff section' do - rendered.should contain "Your Stuff" + rendered.should have_content "Your Stuff" end it "should show link to member's gardens" do assert_select("a[href=#{gardens_by_owner_path(:owner => @member.slug)}]", "Gardens") @@ -79,11 +79,11 @@ describe 'layouts/_header.html.haml', :type => "view" do end it 'should show signout link' do - rendered.should contain 'Sign out' + rendered.should have_content 'Sign out' end it 'should show inbox link' do - rendered.should contain 'Inbox' + rendered.should have_content 'Inbox' rendered.should_not match(/Inbox \(\d+\)/) end @@ -91,7 +91,7 @@ describe 'layouts/_header.html.haml', :type => "view" do it 'should show inbox count' do FactoryGirl.create(:notification, :recipient => @member) render - rendered.should contain 'Inbox (1)' + rendered.should have_content 'Inbox (1)' end end diff --git a/spec/views/layouts/_meta_spec.rb b/spec/views/layouts/_meta_spec.rb index a81942d0f..8419ea129 100644 --- a/spec/views/layouts/_meta_spec.rb +++ b/spec/views/layouts/_meta_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'layouts/_meta.html.haml', :type => "view" do before(:each) do diff --git a/spec/views/layouts/application_spec.rb b/spec/views/layouts/application_spec.rb index 0c7bd8b50..45f1e7553 100644 --- a/spec/views/layouts/application_spec.rb +++ b/spec/views/layouts/application_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'layouts/application.html.haml', :type => "view" do before(:each) do @@ -9,7 +9,7 @@ describe 'layouts/application.html.haml', :type => "view" do Growstuff::Application.config.analytics_code = '' render assert_select "script", :text => 'alert("foo!")' - rendered.should_not contain 'script' + rendered.should_not have_content 'script' end end diff --git a/spec/views/members/_location.html.haml_spec.rb b/spec/views/members/_location.html.haml_spec.rb index 96c1e3b8d..54c5d1198 100644 --- a/spec/views/members/_location.html.haml_spec.rb +++ b/spec/views/members/_location.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "members/_location" do context "member with location" do @@ -8,7 +8,7 @@ describe "members/_location" do end it 'shows location if available' do - rendered.should contain @member.location + rendered.should have_content @member.location end it "links to the places page" do @@ -23,7 +23,7 @@ describe "members/_location" do end it 'shows unknown location' do - rendered.should contain "unknown location" + rendered.should have_content "unknown location" end it "doesn't link anywhere" do diff --git a/spec/views/members/index.html.haml_spec.rb b/spec/views/members/index.html.haml_spec.rb index 22fd9c04f..e9174ffd7 100644 --- a/spec/views/members/index.html.haml_spec.rb +++ b/spec/views/members/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "members/index" do before(:each) do @@ -19,7 +19,7 @@ describe "members/index" do end it 'contains member locations' do - rendered.should contain @member.location + rendered.should have_content @member.location end end diff --git a/spec/views/members/show.rss.haml_spec.rb b/spec/views/members/show.rss.haml_spec.rb index df436b8af..e5619cdd6 100644 --- a/spec/views/members/show.rss.haml_spec.rb +++ b/spec/views/members/show.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'members/show.rss.haml', :type => "view" do before(:each) do @@ -10,21 +10,21 @@ describe 'members/show.rss.haml', :type => "view" do end it 'shows RSS feed title' do - rendered.should contain /member\d+'s recent posts/ + rendered.should have_content /member\d+'s recent posts/ end it 'shows content of posts' do - rendered.should contain "This is some text." + rendered.should have_content "This is some text." end it 'renders post bodies to HTML and XML-escapes them' do # The variable "rendered" has been entity-replaced and tag-stripped # The literal string output contains "<strong>" etc. - rendered.should contain "strong" + rendered.should have_content "strong" end it 'gives the author in the item title' do - rendered.should contain "#{@post1.subject} by #{@post1.author}" + rendered.should have_content "#{@post1.subject} by #{@post1.author}" end end diff --git a/spec/views/notifications/index.html.haml_spec.rb b/spec/views/notifications/index.html.haml_spec.rb index 351bbb44f..43fd80ede 100644 --- a/spec/views/notifications/index.html.haml_spec.rb +++ b/spec/views/notifications/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "notifications/index" do before(:each) do @@ -31,7 +31,7 @@ describe "notifications/index" do :sender => @member, :recipient => @member, :subject => nil) assign(:notifications, [@notification]) render - rendered.should contain "(no subject)" + rendered.should have_content "(no subject)" end end @@ -41,7 +41,7 @@ describe "notifications/index" do :sender => @member, :recipient => @member, :subject => " ") assign(:notifications, [@notification]) render - rendered.should contain "(no subject)" + rendered.should have_content "(no subject)" end end diff --git a/spec/views/notifications/new.html.haml_spec.rb b/spec/views/notifications/new.html.haml_spec.rb index d96358da8..8b77f6422 100644 --- a/spec/views/notifications/new.html.haml_spec.rb +++ b/spec/views/notifications/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "notifications/new" do before(:each) do @@ -19,7 +19,7 @@ describe "notifications/new" do it "tells you who the recipient is" do render - rendered.should contain @recipient.login_name + rendered.should have_content @recipient.login_name end it "puts the recipient in a hidden field" do @@ -40,12 +40,12 @@ describe "notifications/new" do it "Tells you to write your message here" do render - rendered.should contain "Type your message here" + rendered.should have_content "Type your message here" end it 'shows markdown help' do render - rendered.should contain 'Markdown' + rendered.should have_content 'Markdown' end end diff --git a/spec/views/notifications/show.html.haml_spec.rb b/spec/views/notifications/show.html.haml_spec.rb index 3028e8f0e..cc33a07e4 100644 --- a/spec/views/notifications/show.html.haml_spec.rb +++ b/spec/views/notifications/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "notifications/show" do before(:each) do @@ -11,8 +11,8 @@ describe "notifications/show" do end it "renders attributes" do - rendered.should contain @notification.sender.to_s - rendered.should contain @notification.body.to_s + rendered.should have_content @notification.sender.to_s + rendered.should have_content @notification.body.to_s end it "includes a delete button" do diff --git a/spec/views/notifier/notify.html.haml_spec.rb b/spec/views/notifier/notify.html.haml_spec.rb index 687e702cc..b5740b548 100644 --- a/spec/views/notifier/notify.html.haml_spec.rb +++ b/spec/views/notifier/notify.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'notifier/notify.html.haml', :type => "view" do @@ -10,12 +10,12 @@ describe 'notifier/notify.html.haml', :type => "view" do end it 'should say that you have a message' do - rendered.should contain 'You have received a message' + rendered.should have_content 'You have received a message' end it 'should include notification metadata' do - rendered.should contain @notification.sender.login_name - rendered.should contain @notification.post.subject + rendered.should have_content @notification.sender.login_name + rendered.should have_content @notification.post.subject end it 'should include a reply link' do diff --git a/spec/views/orders/index.html.haml_spec.rb b/spec/views/orders/index.html.haml_spec.rb index 2eb399abd..ad2116df7 100644 --- a/spec/views/orders/index.html.haml_spec.rb +++ b/spec/views/orders/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "orders/index" do before(:each) do @@ -11,7 +11,7 @@ describe "orders/index" do it "shows your current account status" do render - rendered.should contain "Your current account status" + rendered.should have_content "Your current account status" end it "renders a list of orders" do diff --git a/spec/views/orders/show.html.haml_spec.rb b/spec/views/orders/show.html.haml_spec.rb index 9621de369..98d0eb5e0 100644 --- a/spec/views/orders/show.html.haml_spec.rb +++ b/spec/views/orders/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "orders/show" do @@ -20,7 +20,7 @@ describe "orders/show" do end it "displays order number" do - rendered.should contain "Order number" + rendered.should have_content "Order number" end it "shows order items in a table" do @@ -28,7 +28,7 @@ describe "orders/show" do end it "shows the total" do - rendered.should contain "Total:" + rendered.should have_content "Total:" assert_select "strong", /198.00/ end diff --git a/spec/views/photos/edit.html.haml_spec.rb b/spec/views/photos/edit.html.haml_spec.rb index 3b8cde557..f3a9a0ed7 100644 --- a/spec/views/photos/edit.html.haml_spec.rb +++ b/spec/views/photos/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "photos/edit" do before(:each) do diff --git a/spec/views/photos/index.html.haml_spec.rb b/spec/views/photos/index.html.haml_spec.rb index bf4699c48..5daaa1eda 100644 --- a/spec/views/photos/index.html.haml_spec.rb +++ b/spec/views/photos/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "photos/index" do before(:each) do diff --git a/spec/views/photos/new.html.haml_spec.rb b/spec/views/photos/new.html.haml_spec.rb index c3e47a6b8..8f0f241e3 100644 --- a/spec/views/photos/new.html.haml_spec.rb +++ b/spec/views/photos/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "photos/new" do before(:each) do diff --git a/spec/views/photos/show.html.haml_spec.rb b/spec/views/photos/show.html.haml_spec.rb index 18a201590..5ef9dc9c0 100644 --- a/spec/views/photos/show.html.haml_spec.rb +++ b/spec/views/photos/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "photos/show" do before(:each) do @@ -41,7 +41,7 @@ describe "photos/show" do end it "contains the phrase 'All rights reserved'" do - rendered.should contain "All rights reserved" + rendered.should have_content "All rights reserved" end end diff --git a/spec/views/places/_map_attribution.html.haml_spec.rb b/spec/views/places/_map_attribution.html.haml_spec.rb index e3197dfba..d85875376 100644 --- a/spec/views/places/_map_attribution.html.haml_spec.rb +++ b/spec/views/places/_map_attribution.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "places/_map_attribution.html.haml", :type => :view do before(:each) do diff --git a/spec/views/places/index.html.haml_spec.rb b/spec/views/places/index.html.haml_spec.rb index 0e4af0bb1..f3a3661ae 100644 --- a/spec/views/places/index.html.haml_spec.rb +++ b/spec/views/places/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "places/index" do before(:each) do diff --git a/spec/views/places/show.html.haml_spec.rb b/spec/views/places/show.html.haml_spec.rb index 987212740..8e3e346c5 100644 --- a/spec/views/places/show.html.haml_spec.rb +++ b/spec/views/places/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "places/show" do before(:each) do @@ -20,7 +20,7 @@ describe "places/show" do it "shows the names of nearby members" do @nearby_members.each do |m| - rendered.should contain m.login_name + rendered.should have_content m.login_name end end diff --git a/spec/views/plant_parts/edit.html.haml_spec.rb b/spec/views/plant_parts/edit.html.haml_spec.rb index 2011b34c3..6193ef1b0 100644 --- a/spec/views/plant_parts/edit.html.haml_spec.rb +++ b/spec/views/plant_parts/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plant_parts/edit" do before(:each) do diff --git a/spec/views/plant_parts/index.html.haml_spec.rb b/spec/views/plant_parts/index.html.haml_spec.rb index 6d1020717..1a9469c55 100644 --- a/spec/views/plant_parts/index.html.haml_spec.rb +++ b/spec/views/plant_parts/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plant_parts/index" do before(:each) do @@ -9,7 +9,7 @@ describe "plant_parts/index" do it "renders a list of plant_parts" do render - rendered.should contain @pp.name + rendered.should have_content @pp.name assert_select "a", :href => plant_part_path(@pp) end diff --git a/spec/views/plant_parts/new.html.haml_spec.rb b/spec/views/plant_parts/new.html.haml_spec.rb index 6a415fd4e..d512ecee1 100644 --- a/spec/views/plant_parts/new.html.haml_spec.rb +++ b/spec/views/plant_parts/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plant_parts/new" do before(:each) do diff --git a/spec/views/plant_parts/show.html.haml_spec.rb b/spec/views/plant_parts/show.html.haml_spec.rb index 40392a65d..b65ecb154 100644 --- a/spec/views/plant_parts/show.html.haml_spec.rb +++ b/spec/views/plant_parts/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plant_parts/show" do before(:each) do @@ -11,7 +11,7 @@ describe "plant_parts/show" do it "renders a list of crops harvested for this part" do render @pp.crops.each do |c| - rendered.should contain c.name + rendered.should have_content c.name assert_select "a", :href => crop_path(c) end end diff --git a/spec/views/plantings/_form.html.haml_spec.rb b/spec/views/plantings/_form.html.haml_spec.rb index 69da79c35..88b12bd9e 100644 --- a/spec/views/plantings/_form.html.haml_spec.rb +++ b/spec/views/plantings/_form.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/_form" do before(:each) do diff --git a/spec/views/plantings/_thumbnail.html.haml_spec.rb b/spec/views/plantings/_thumbnail.html.haml_spec.rb index ac1ffaa78..dd5cc2003 100644 --- a/spec/views/plantings/_thumbnail.html.haml_spec.rb +++ b/spec/views/plantings/_thumbnail.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/_thumbnail" do before(:each) do @@ -21,19 +21,19 @@ describe "plantings/_thumbnail" do end it "renders the quantity planted" do - rendered.should contain "33" + rendered.should have_content "33" end it "renders the date planted" do - rendered.should contain @planting.planted_at.to_s(:default) + rendered.should have_content @planting.planted_at.to_s(:default) end it "shows the name of the crop" do - rendered.should contain @crop.name + rendered.should have_content @crop.name end it "shows the description by default" do - rendered.should contain "This is a" + rendered.should have_content "This is a" end end @@ -46,7 +46,7 @@ describe "plantings/_thumbnail" do end it "hides the description if asked" do - rendered.should_not contain "This is a" + rendered.should_not have_content "This is a" end end diff --git a/spec/views/plantings/edit.html.haml_spec.rb b/spec/views/plantings/edit.html.haml_spec.rb index f80f6a0b4..4cc06fcdc 100644 --- a/spec/views/plantings/edit.html.haml_spec.rb +++ b/spec/views/plantings/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/edit" do before(:each) do @@ -49,7 +49,7 @@ describe "plantings/edit" do it "chooses the right garden" do assert_select "select#planting_garden_id", - :html => /option value="#{@garden.id}" selected="selected"/ + :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 f80331117..6a130c8c9 100644 --- a/spec/views/plantings/index.html.haml_spec.rb +++ b/spec/views/plantings/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/index" do before(:each) do @@ -37,23 +37,23 @@ describe "plantings/index" do end it "renders a list of plantings" do - rendered.should contain @tomato.name - rendered.should contain @maize.name - rendered.should contain @member.login_name - rendered.should contain @garden.name + rendered.should have_content @tomato.name + rendered.should have_content @maize.name + rendered.should have_content @member.login_name + rendered.should have_content @garden.name end it "displays planting time" do - rendered.should contain 'January 13, 2013' + rendered.should have_content 'January 13, 2013' end it "displays finished time" do - rendered.should contain 'January 20, 2013' + rendered.should have_content 'January 20, 2013' end it "provides data links" do render - rendered.should contain "The data on this page is available in the following formats:" + 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') @@ -62,12 +62,12 @@ describe "plantings/index" do it "displays member's name in title" do assign(:owner, @member) render - view.content_for(:title).should contain @member.login_name + view.content_for(:title).should have_content @member.login_name end it "displays crop's name in title" do assign(:crop, @tomato) render - view.content_for(:title).should contain @tomato.name + view.content_for(:title).should have_content @tomato.name end end diff --git a/spec/views/plantings/index.rss.haml_spec.rb b/spec/views/plantings/index.rss.haml_spec.rb index 5a7cb48c5..c953382ce 100644 --- a/spec/views/plantings/index.rss.haml_spec.rb +++ b/spec/views/plantings/index.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'plantings/index.rss.haml' do before(:each) do @@ -15,23 +15,23 @@ describe 'plantings/index.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recent plantings from all members" + rendered.should have_content "Recent plantings from all members" end it 'item title shows owner and location' do - rendered.should contain "#{@planting.crop} in #{@planting.location}" + rendered.should have_content "#{@planting.crop} in #{@planting.location}" end it 'shows formatted content of posts' do - rendered.should contain "This is a really good plant." + rendered.should have_content "This is a really good plant." end it 'shows sunniness' do - rendered.should contain 'Sunniness: sun' + rendered.should have_content 'Sunniness: sun' end it 'shows propagation method' do - rendered.should contain 'Planted from: seedling' + rendered.should have_content 'Planted from: seedling' end end @@ -44,7 +44,7 @@ describe 'plantings/index.rss.haml' do end it 'shows title for single member' do - rendered.should contain "Recent plantings from #{@planting.owner}" + rendered.should have_content "Recent plantings from #{@planting.owner}" end end end diff --git a/spec/views/plantings/new.html.haml_spec.rb b/spec/views/plantings/new.html.haml_spec.rb index 61e81eb20..455b9a411 100644 --- a/spec/views/plantings/new.html.haml_spec.rb +++ b/spec/views/plantings/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/new" do before(:each) do @@ -46,7 +46,7 @@ describe "plantings/new" do it "selects a garden given in a param" do assert_select "select#planting_garden_id", - :html => /option value="#{@garden_z.id}" selected="selected"/ + :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 018e5074b..28a44078a 100644 --- a/spec/views/plantings/show.html.haml_spec.rb +++ b/spec/views/plantings/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "plantings/show" do def create_planting_for(member) @@ -25,16 +25,16 @@ describe "plantings/show" do it "shows the sunniness" do render - rendered.should contain 'Sun or shade?' - rendered.should contain 'sun' + 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 contain 'Sun or shade?' - rendered.should_not contain 'sun' + rendered.should_not have_content 'Sun or shade?' + rendered.should_not have_content 'sun' end end @@ -45,16 +45,16 @@ describe "plantings/show" do it "shows planted_from" do render - rendered.should contain 'Planted from:' - rendered.should contain 'cutting' + rendered.should have_content 'Planted from:' + rendered.should have_content 'cutting' end it "doesn't show planted_from if blank" do @p.planted_from = '' @p.save render - rendered.should_not contain 'Planted from:' - rendered.should_not contain 'cutting' + rendered.should_not have_content 'Planted from:' + rendered.should_not have_content 'cutting' end end @@ -67,7 +67,7 @@ describe "plantings/show" do it "shows a link to add photos" do render - rendered.should contain "Add photo" + rendered.should have_content "Add photo" end context "no location set" do @@ -88,7 +88,7 @@ describe "plantings/show" do end it "doesn't contain a () if no location is set" do - rendered.should_not contain "()" + rendered.should_not have_content "()" end end @@ -100,7 +100,7 @@ describe "plantings/show" do end it "shows the member's location in parentheses" do - rendered.should contain "(#{@p.owner.location})" + rendered.should have_content "(#{@p.owner.location})" end end end diff --git a/spec/views/policy/community_spec.rb b/spec/views/policy/community_spec.rb index 70608e463..17f6d3b11 100644 --- a/spec/views/policy/community_spec.rb +++ b/spec/views/policy/community_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'policy/community.html.haml', :type => "view" do before(:each) do @@ -7,6 +7,6 @@ describe 'policy/community.html.haml', :type => "view" do it 'should show community guidelines' do render - rendered.should contain 'is a community by and for food-gardeners.' + 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 index 548deadc3..24cacdf0d 100644 --- a/spec/views/policy/tos_spec.rb +++ b/spec/views/policy/tos_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'policy/tos.html.haml', :type => "view" do before(:each) do @@ -7,6 +7,6 @@ describe 'policy/tos.html.haml', :type => "view" do it 'should show terms of service' do render - rendered.should contain 'Terms of Service' + rendered.should have_content 'Terms of Service' end end diff --git a/spec/views/posts/_single.html.haml_spec.rb b/spec/views/posts/_single.html.haml_spec.rb index eebac11f4..268db854d 100644 --- a/spec/views/posts/_single.html.haml_spec.rb +++ b/spec/views/posts/_single.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "posts/_single" do @@ -101,7 +101,7 @@ describe "posts/_single" do end it "renders no value of comments" do - rendered.should_not contain "1 comment" + rendered.should_not have_content "1 comment" end it "does not contain link to post" do diff --git a/spec/views/posts/edit.html.haml_spec.rb b/spec/views/posts/edit.html.haml_spec.rb index 91e2d9b4f..7b3f0b195 100644 --- a/spec/views/posts/edit.html.haml_spec.rb +++ b/spec/views/posts/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "posts/edit" do before(:each) do @@ -25,7 +25,7 @@ describe "posts/edit" do end it 'no forum mentioned' do - rendered.should_not contain "This post will be posted in the forum" + rendered.should_not have_content "This post will be posted in the forum" end context "forum specified" do @@ -43,7 +43,7 @@ describe "posts/edit" do end it 'tells the user what forum it will be posted in' do - rendered.should contain "This post will be posted in the forum #{@forum.name}" + rendered.should have_content "This post will be posted in the forum #{@forum.name}" end end diff --git a/spec/views/posts/index.html.haml_spec.rb b/spec/views/posts/index.html.haml_spec.rb index 3b7b02611..d5d49951a 100644 --- a/spec/views/posts/index.html.haml_spec.rb +++ b/spec/views/posts/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "posts/index" do before(:each) do diff --git a/spec/views/posts/index.rss.haml_spec.rb b/spec/views/posts/index.rss.haml_spec.rb index b28deb2db..0a303f19b 100644 --- a/spec/views/posts/index.rss.haml_spec.rb +++ b/spec/views/posts/index.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'posts/index.rss.haml', :type => "view" do before(:each) do @@ -11,15 +11,15 @@ describe 'posts/index.rss.haml', :type => "view" do end it 'shows RSS feed title' do - rendered.should contain "Recent posts from all members" + rendered.should have_content "Recent posts from all members" end it 'shows content of posts' do - rendered.should contain "This is some text." + rendered.should have_content "This is some text." end it 'gives the author in the item title' do - rendered.should contain "#{@post1.subject} by #{@post1.author}" + rendered.should have_content "#{@post1.subject} by #{@post1.author}" end end diff --git a/spec/views/posts/new.html.haml_spec.rb b/spec/views/posts/new.html.haml_spec.rb index be69c972c..73448e24c 100644 --- a/spec/views/posts/new.html.haml_spec.rb +++ b/spec/views/posts/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "posts/new" do before(:each) do @@ -24,12 +24,12 @@ describe "posts/new" do it 'no forum mentioned' do render - rendered.should_not contain "This post will be posted in the forum" + rendered.should_not have_content "This post will be posted in the forum" end it "asks what's going on in your garden" do render - rendered.should contain "What's going on in your food garden?" + rendered.should have_content "What's going on in your food garden?" end context "forum specified" do @@ -44,19 +44,19 @@ describe "posts/new" do end it 'tells the user what forum it will be posted in' do - rendered.should contain "This post will be posted in the forum #{@forum.name}" + rendered.should have_content "This post will be posted in the forum #{@forum.name}" end it "asks what's going on generally" do render - rendered.should_not contain "What's going on in your food garden?" - rendered.should contain "What's up?" + rendered.should_not have_content "What's going on in your food garden?" + rendered.should have_content "What's up?" end end it 'shows markdown help' do render - rendered.should contain 'Markdown' + rendered.should have_content 'Markdown' end end diff --git a/spec/views/posts/show.html.haml_spec.rb b/spec/views/posts/show.html.haml_spec.rb index d9682b015..e1ea7a77e 100644 --- a/spec/views/posts/show.html.haml_spec.rb +++ b/spec/views/posts/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "posts/show" do before(:each) do @@ -55,7 +55,7 @@ describe "posts/show" do end it "shows comments" do - rendered.should contain @comment.body + rendered.should have_content @comment.body end it 'has an anchor to the comments' do @@ -79,7 +79,7 @@ describe "posts/show" do end it "shows the oldest comments first" do - rendered.should contain /#{@comment1.body}.*#{@comment2.body}.*#{@comment3.body}.*#{@comment4.body}/m + rendered.should have_content /#{@comment1.body}.*#{@comment2.body}.*#{@comment3.body}.*#{@comment4.body}/m end end @@ -88,7 +88,7 @@ describe "posts/show" do @post = assign(:post, FactoryGirl.create(:forum_post, :author => @author)) render - rendered.should contain "in #{@post.forum.name}" + rendered.should have_content "in #{@post.forum.name}" end end diff --git a/spec/views/posts/show.rss.haml_spec.rb b/spec/views/posts/show.rss.haml_spec.rb index 2f2780d09..72e8e7347 100644 --- a/spec/views/posts/show.rss.haml_spec.rb +++ b/spec/views/posts/show.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'posts/show.rss.haml' do before(:each) do @@ -12,20 +12,20 @@ describe 'posts/show.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recent comments on #{@post.subject}" + rendered.should have_content "Recent comments on #{@post.subject}" end it 'shows item title' do - rendered.should contain "Comment by #{@author.login_name}" + rendered.should have_content "Comment by #{@author.login_name}" end it 'escapes html for link to post' do # it's then unescaped by 'render' so we don't actually look for < - rendered.should contain '" do render # Run the generator again with the --webrat flag if you want to use webrat matchers - rendered.should contain @product.name - rendered.should contain @product.min_price.to_s - rendered.should contain @product.recommended_price.to_s + rendered.should have_content @product.name + rendered.should have_content @product.min_price.to_s + rendered.should have_content @product.recommended_price.to_s end end diff --git a/spec/views/roles/edit.html.haml_spec.rb b/spec/views/roles/edit.html.haml_spec.rb index 2e2f66c7b..2b12e05d5 100644 --- a/spec/views/roles/edit.html.haml_spec.rb +++ b/spec/views/roles/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "roles/edit" do before(:each) do diff --git a/spec/views/roles/index.html.haml_spec.rb b/spec/views/roles/index.html.haml_spec.rb index 3c62e0986..1b732c381 100644 --- a/spec/views/roles/index.html.haml_spec.rb +++ b/spec/views/roles/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "roles/index" do before(:each) do diff --git a/spec/views/roles/new.html.haml_spec.rb b/spec/views/roles/new.html.haml_spec.rb index e15e14226..bba7e62b7 100644 --- a/spec/views/roles/new.html.haml_spec.rb +++ b/spec/views/roles/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "roles/new" do before(:each) do diff --git a/spec/views/roles/show.html.haml_spec.rb b/spec/views/roles/show.html.haml_spec.rb index 389a5c8c3..16f48415f 100644 --- a/spec/views/roles/show.html.haml_spec.rb +++ b/spec/views/roles/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "roles/show" do before(:each) do diff --git a/spec/views/scientific_names/edit.html.haml_spec.rb b/spec/views/scientific_names/edit.html.haml_spec.rb index 1b48c51cd..3e5dc9e91 100644 --- a/spec/views/scientific_names/edit.html.haml_spec.rb +++ b/spec/views/scientific_names/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "scientific_names/edit" do context "logged in" do @@ -13,7 +13,7 @@ describe "scientific_names/edit" do end it "shows the creator" do - rendered.should contain "Added by #{@scientific_name.creator} less than a minute ago." + rendered.should have_content "Added by #{@scientific_name.creator} less than a minute ago." end it "renders the edit scientific_name form" do diff --git a/spec/views/scientific_names/index.html.haml_spec.rb b/spec/views/scientific_names/index.html.haml_spec.rb index fff8874f5..a49b9ef88 100644 --- a/spec/views/scientific_names/index.html.haml_spec.rb +++ b/spec/views/scientific_names/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "scientific_names/index" do before(:each) do @@ -17,8 +17,8 @@ describe "scientific_names/index" do it "doesn't show edit/destroy links" do render - rendered.should_not contain "Edit" - rendered.should_not contain "Delete" + rendered.should_not have_content "Edit" + rendered.should_not have_content "Delete" end context "logged in and crop wrangler" do @@ -30,8 +30,8 @@ describe "scientific_names/index" do it "shows edit/destroy links" do render - rendered.should contain "Edit" - rendered.should contain "Delete" + rendered.should have_content "Edit" + rendered.should have_content "Delete" end end end diff --git a/spec/views/scientific_names/new.html.haml_spec.rb b/spec/views/scientific_names/new.html.haml_spec.rb index 9c892f5ef..151908e7d 100644 --- a/spec/views/scientific_names/new.html.haml_spec.rb +++ b/spec/views/scientific_names/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "scientific_names/new" do before(:each) do diff --git a/spec/views/scientific_names/show.html.haml_spec.rb b/spec/views/scientific_names/show.html.haml_spec.rb index 6fbb95e42..d2927c5a9 100644 --- a/spec/views/scientific_names/show.html.haml_spec.rb +++ b/spec/views/scientific_names/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "scientific_names/show" do before(:each) do diff --git a/spec/views/seeds/edit.html.haml_spec.rb b/spec/views/seeds/edit.html.haml_spec.rb index 03b2064cf..6a0235e4b 100644 --- a/spec/views/seeds/edit.html.haml_spec.rb +++ b/spec/views/seeds/edit.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "seeds/edit" do before(:each) do diff --git a/spec/views/seeds/index.html.haml_spec.rb b/spec/views/seeds/index.html.haml_spec.rb index 036c4aa04..a1d478544 100644 --- a/spec/views/seeds/index.html.haml_spec.rb +++ b/spec/views/seeds/index.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "seeds/index" do before(:each) do @@ -45,7 +45,7 @@ describe "seeds/index" do it "provides data links" do render - rendered.should contain "The data on this page is available in the following formats:" + 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') diff --git a/spec/views/seeds/index.rss.haml_spec.rb b/spec/views/seeds/index.rss.haml_spec.rb index 0b30d19a5..485f390d0 100644 --- a/spec/views/seeds/index.rss.haml_spec.rb +++ b/spec/views/seeds/index.rss.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'seeds/index.rss.haml' do before(:each) do @@ -14,23 +14,23 @@ describe 'seeds/index.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recent seeds from all members" + rendered.should have_content "Recent seeds from all members" end it 'has a useful item title' do - rendered.should contain "#{@seed.owner}'s #{@seed.crop} seeds" + rendered.should have_content "#{@seed.owner}'s #{@seed.crop} seeds" end it 'shows the seed count' do - rendered.should contain "Quantity: #{@seed.quantity}" + rendered.should have_content "Quantity: #{@seed.quantity}" end it 'shows the plant_before date' do - rendered.should contain "Plant before: #{@seed.plant_before.to_s}" + rendered.should have_content "Plant before: #{@seed.plant_before.to_s}" end it 'mentions that one seed is tradable' do - rendered.should contain "Will trade #{@tradable.tradable_to} from #{@tradable.owner.location}" + rendered.should have_content "Will trade #{@tradable.tradable_to} from #{@tradable.owner.location}" end end @@ -44,7 +44,7 @@ describe 'seeds/index.rss.haml' do end it 'shows RSS feed title' do - rendered.should contain "Recent seeds from #{@seed.owner}" + rendered.should have_content "Recent seeds from #{@seed.owner}" end end end diff --git a/spec/views/seeds/new.html.haml_spec.rb b/spec/views/seeds/new.html.haml_spec.rb index a88713181..9abb2f291 100644 --- a/spec/views/seeds/new.html.haml_spec.rb +++ b/spec/views/seeds/new.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "seeds/new" do before(:each) do @@ -22,7 +22,7 @@ describe "seeds/new" do it 'reminds you to set your location' do render - rendered.should contain "Don't forget to set your location." + rendered.should have_content "Don't forget to set your location." assert_select "a", :text => "set your location" end @@ -37,7 +37,7 @@ describe "seeds/new" do it 'shows the location' do render - rendered.should contain "from #{@member.location}." + rendered.should have_content "from #{@member.location}." assert_select 'a', :href => place_path(@member.location) end diff --git a/spec/views/seeds/show.html.haml_spec.rb b/spec/views/seeds/show.html.haml_spec.rb index 737cf0232..af00b4efe 100644 --- a/spec/views/seeds/show.html.haml_spec.rb +++ b/spec/views/seeds/show.html.haml_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe "seeds/show" do before(:each) do @@ -9,7 +9,7 @@ describe "seeds/show" do it "renders attributes in

" do render - rendered.should contain @seed.crop.name + rendered.should have_content @seed.crop.name end context "tradable" do @@ -25,12 +25,12 @@ describe "seeds/show" do it "shows tradable attributes" do render - rendered.should contain "Will trade: locally" + rendered.should have_content "Will trade: locally" end it "shows location of seed owner" do render - rendered.should contain @owner.location + rendered.should have_content @owner.location assert_select 'a', :href => place_path(@owner.location) end @@ -44,7 +44,7 @@ describe "seeds/show" do it 'says "from unspecified location"' do render - rendered.should contain "(from unspecified location)" + rendered.should have_content "(from unspecified location)" end it "links to profile to set location" do @@ -55,7 +55,7 @@ describe "seeds/show" do it "shows button to send message" do render - rendered.should contain "Request seeds" + rendered.should have_content "Request seeds" end end diff --git a/spec/views/shop/index_spec.rb b/spec/views/shop/index_spec.rb index 49034368d..ee9ee59a9 100644 --- a/spec/views/shop/index_spec.rb +++ b/spec/views/shop/index_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'shop/index.html.haml', :type => "view" do before(:each) do @@ -20,7 +20,7 @@ describe 'shop/index.html.haml', :type => "view" do end it 'shows prices in AUD' do - rendered.should contain '9.99 AUD' + rendered.should have_content '9.99 AUD' end it 'should contain an exchange rate link' do @@ -29,7 +29,7 @@ describe 'shop/index.html.haml', :type => "view" do end it 'shows recommended price for products that have it' do - rendered.should contain '12.00 AUD' + rendered.should have_content '12.00 AUD' end it 'should contain an exchange rate link for recommended price' do @@ -55,12 +55,12 @@ describe 'shop/index.html.haml', :type => "view" do end it "recognises the paid member" do - @member.is_paid?.should be_true + @member.is_paid?.should be(true) end it "tells you you have a paid membership" do render - rendered.should contain "You currently have a paid" + rendered.should have_content "You currently have a paid" end it "doesn't show shop" do @@ -77,7 +77,7 @@ describe 'shop/index.html.haml', :type => "view" do end it "tells you to sign up/sign in" do - rendered.should contain "sign in or sign up" + rendered.should have_content "sign in or sign up" end end diff --git a/spec/views/support/index_spec.rb b/spec/views/support/index_spec.rb index 0c7491ed7..fc3a96b12 100644 --- a/spec/views/support/index_spec.rb +++ b/spec/views/support/index_spec.rb @@ -1,4 +1,4 @@ -require 'spec_helper' +require 'rails_helper' describe 'support/index.html.haml', :type => "view" do before(:each) do @@ -6,11 +6,11 @@ describe 'support/index.html.haml', :type => "view" do end it 'should show support faq' do - rendered.should contain 'About Growstuff' + rendered.should have_content 'About Growstuff' end it 'should not mention Courtney any more' do - rendered.should_not contain 'Courtney' - rendered.should_not contain 'phazel' + rendered.should_not have_content 'Courtney' + rendered.should_not have_content 'phazel' end end diff --git a/vendor/plugins/.gitkeep b/vendor/plugins/.gitkeep deleted file mode 100644 index e69de29bb..000000000