Compare commits

...

109 Commits

Author SHA1 Message Date
Cesy
e578ca2c77 Merge pull request #1153 from Growstuff/dev
Release 18
2017-01-22 07:47:42 +00:00
Daniel O'Connor
c4c50a4174 Merge pull request #1158 from Br3nda/bw/controller-translations
more controller translations
2017-01-22 15:34:14 +10:30
Brenda Wallace
a1c74bfdfb Translations for members controller 2017-01-22 17:36:48 +13:00
Brenda Wallace
2f9453780e Translations for harvests controller 2017-01-22 17:28:49 +13:00
Brenda Wallace
725ae817d4 Translations for gardens controller 2017-01-22 17:26:30 +13:00
Daniel O'Connor
eab9bcb37d Merge pull request #1157 from Br3nda/bw/rubocop-hash-braces
Removed unnecesary braces on hash args
2017-01-22 13:22:11 +10:30
Brenda Wallace
40a981c94d Removed unnecesary braces on hash args 2017-01-22 15:10:11 +13:00
Cesy
dd2af6a0e3 Merge pull request #1155 from CloCkWeRX/2017-01-21-gem-updates
2017 01 21 gem updates
2017-01-21 19:49:05 +00:00
Daniel O'Connor
9192ccf52b Update coveralls 2017-01-21 17:02:40 +10:30
Daniel O'Connor
4e79fd201c Update omniauth 2017-01-21 17:01:59 +10:30
Daniel O'Connor
d266d7ed1a Update i18n-tasks 2017-01-21 16:52:24 +10:30
Daniel O'Connor
f7f1907b74 Silence config/routes.rb:1:39: W: Lint/UnneededDisable: Unnecessary disabling of Metrics/BlockLength for now 2017-01-21 16:45:04 +10:30
Daniel O'Connor
c42e9ca410 Upgrade factory_girl_rails 2017-01-21 16:42:04 +10:30
Daniel O'Connor
f97c465a92 Update geocoder 2017-01-21 16:41:15 +10:30
Daniel O'Connor
a5b566a207 Update lumberjack 2017-01-21 16:40:27 +10:30
Daniel O'Connor
c6d16c92f5 Update public_suffix 2017-01-21 16:40:04 +10:30
Daniel O'Connor
c5b2e37730 Update diff-lcs 2017-01-21 16:39:31 +10:30
Daniel O'Connor
5c642dfef9 Really disable 2017-01-21 16:37:30 +10:30
Daniel O'Connor
a9b8253dfa Update connection_pool 2017-01-21 16:35:33 +10:30
Daniel O'Connor
58a3cbf569 Disable check for now 2017-01-21 16:28:57 +10:30
Daniel O'Connor
8b4c8fef3b Pin to earlier version of rainbow until https://github.com/sickill/rainbow/issues/44 is sorted 2017-01-21 16:14:37 +10:30
Daniel O'Connor
36c0de4504 Upgrade to selenium-webdriver 3.0.0 2017-01-21 16:04:15 +10:30
Daniel O'Connor
3208bf9fb6 Regenerate rubocop configuration 2017-01-21 15:58:52 +10:30
Daniel O'Connor
4eebf5c867 Error: The Style/MethodCallParentheses cop has been renamed to Style/MethodCallWithoutArgsParentheses. 2017-01-21 15:57:01 +10:30
Daniel O'Connor
61f7bdfdd2 Update rubocop 2017-01-21 15:56:02 +10:30
Daniel O'Connor
06838d7ad1 Update ruby_dep, unicode-display_width 2017-01-21 15:55:22 +10:30
Daniel O'Connor
676f246e85 Merge pull request #1154 from Br3nda/bw/translations
More translations
2017-01-21 15:51:41 +10:30
Shiny
6121a9bc6e Merge branch 'dev' into bw/translations 2017-01-20 21:05:31 +11:00
Brenda Wallace
c2804f1725 Merge branch 'bw/controller-translations' into bw/translations
Conflicts:
	config/locales/en.yml
2017-01-20 23:04:00 +13:00
Brenda Wallace
b198305d36 Translations for account controller 2017-01-20 22:48:04 +13:00
Brenda Wallace
7d7f5bfda3 Translations for account types 2017-01-20 22:46:12 +13:00
Brenda Wallace
d97af8e76e Adding missing translation for harvests 2017-01-20 22:40:14 +13:00
Brenda Wallace
91adc5f59e Normalise english translations file 2017-01-20 22:23:38 +13:00
pozorvlak
a8d5b14d46 Merge pull request #1150 from Br3nda/bw/rubocop
Rubocop fix up for the models
2017-01-17 17:43:24 +00:00
pozorvlak
cc59c4f49b Merge branch 'dev' into bw/rubocop 2017-01-17 16:47:07 +00:00
pozorvlak
8a7b7e75ef Merge pull request #1141 from Br3nda/bw/active-plantings
Show only active plantings by default
2017-01-17 16:41:22 +00:00
Shiny
f8dda12de6 Merge branch 'dev' into bw/active-plantings 2017-01-15 17:36:32 +13:00
Shiny
ab332976da Merge branch 'dev' into bw/rubocop 2017-01-15 17:36:17 +13:00
pozorvlak
331c778350 Merge pull request #1152 from CloCkWeRX/upgrade-comfortable-mexican-sofa
Upgrade to current comfortable_mexican_sofa
2017-01-14 22:20:54 +00:00
Cesy
48b6a2297b Merge branch 'master' into dev 2017-01-14 20:21:46 +00:00
pozorvlak
27ea2e0432 Merge branch 'dev' into upgrade-comfortable-mexican-sofa 2017-01-14 19:53:06 +00:00
pozorvlak
4c0000b964 Merge pull request #1145 from Br3nda/bw/description-photo-links
Descriptive links from photo page
2017-01-14 19:51:20 +00:00
Daniel O'Connor
a3ee17bd4d #1054 Upgrade to current comfortable_mexican_sofa 2017-01-15 02:19:15 +10:30
Brenda Wallace
958e7eb955 Removed rubocop excludes that we have fixed 2017-01-14 21:13:59 +13:00
Brenda Wallace
39888d44e2 Rubocop compliance for the account model 2017-01-14 21:11:02 +13:00
Brenda Wallace
b603bae1a7 Rubocop compliance for the notification model 2017-01-14 21:09:47 +13:00
Brenda Wallace
05db5f3109 Rubocop compliance for the order_item model 2017-01-14 21:08:47 +13:00
Brenda Wallace
ad72ab0ba8 Rubocop compliance for the role model 2017-01-14 21:04:19 +13:00
Brenda Wallace
3beb3974fc Rubocop compliance for the product model 2017-01-14 21:03:01 +13:00
Brenda Wallace
fa15fd2912 Rubocop compliance for the photo model 2017-01-14 21:01:46 +13:00
Brenda Wallace
78ed7869c5 Rubocop compliance for the member model 2017-01-14 20:57:18 +13:00
Brenda Wallace
0fa9f54c9c Rename member.has_role? to role? 2017-01-14 20:54:43 +13:00
Brenda Wallace
f214f608ff Rename member.is_paid? to paid? 2017-01-14 20:51:22 +13:00
Brenda Wallace
eb70f6dc57 Rubocop compliance for the seed model 2017-01-14 20:48:19 +13:00
Brenda Wallace
43c4b154f9 Rubocop compliance for the follow model 2017-01-14 20:45:54 +13:00
Brenda Wallace
21a536bf86 Merge remote-tracking branch 'upstream/dev' into bw/rubocop 2017-01-14 20:43:02 +13:00
Brenda Wallace
832a20eac9 Rubocop compliance for order model 2017-01-14 20:42:32 +13:00
Brenda Wallace
f6cc0f3e13 rubocop compliance in post model 2017-01-14 20:34:08 +13:00
Brenda Wallace
5be5585084 Rubocop disable Rails/HasAndBelongsToMany 2017-01-14 20:31:34 +13:00
Brenda Wallace
989f176fb7 Crop model adhering to rubocop 2017-01-14 20:09:54 +13:00
Brenda Wallace
be07b5fd0e Only check values.zero? if they are present 2017-01-14 20:09:09 +13:00
Shiny
180505a1ca Merge branch 'dev' into bw/active-plantings 2017-01-14 18:27:18 +13:00
Shiny
e11603cb3e Merge branch 'dev' into bw/description-photo-links 2017-01-14 18:25:52 +13:00
Daniel O'Connor
97c5eb1c42 Merge pull request #1149 from Br3nda/bw/quotes-in-name
Removed unwanted quotes in member name in menu
2017-01-14 15:09:04 +10:30
Brenda Wallace
d07509f9e4 Rubocop compliance for comment model 2017-01-14 17:23:39 +13:00
Brenda Wallace
0c1220d11f Rubocop compliance for harvest model 2017-01-14 17:22:33 +13:00
Brenda Wallace
f889b112fe Rubocop compliance for garden model 2017-01-14 17:20:21 +13:00
Brenda Wallace
a1cfa826d9 Removed unwanted quotes in member name in menu
Fix for Issue #1144
2017-01-14 17:11:58 +13:00
Brenda Wallace
477f9669bd Added nav for plantings 2017-01-14 16:54:37 +13:00
Brenda Wallace
c1da5e4dc8 Split plantings#index into two methods to simplify 2017-01-14 16:47:29 +13:00
Brenda Wallace
6bdfe5a669 Moved plantings nav bar to own file and simplified 2017-01-14 16:32:03 +13:00
Shiny
8138aa8c09 Merge branch 'dev' into bw/active-plantings 2017-01-14 15:33:28 +13:00
Brenda Wallace
eba397117c Planting needs to calculate slugs before model is valid 2017-01-14 11:41:48 +13:00
Brenda Wallace
f9396248e6 Merge remote-tracking branch 'upstream/dev' into bw/description-photo-links 2017-01-11 12:12:36 +13:00
pozorvlak
f31342c6e0 Merge pull request #1147 from Br3nda/alpha-bundle
Bundle alphabetical order to comply with stricter rubocop.

Patch is semantically a no-op, and the static check failure is expected.
2017-01-09 12:11:45 +00:00
Brenda Wallace
87a091d694 Bundle alpha-order to comply with stricter rubocop 2017-01-08 20:50:52 +00:00
Brenda Wallace
2e04d56225 Merge remote-tracking branch 'origin/bw/description-photo-links' into bw/description-photo-links 2017-01-08 21:48:58 +13:00
Brenda Wallace
405dfe4bc9 Merge remote-tracking branch 'upstream/dev' into bw/description-photo-links 2017-01-08 21:35:59 +13:00
Shiny
15de4ac08c Merge branch 'dev' into bw/active-plantings 2017-01-08 11:16:19 +13:00
Shiny
c55208713b Merge branch 'dev' into bw/description-photo-links 2017-01-08 11:09:19 +13:00
Shiny
48c1b4d0f9 Merge pull request #1142 from Br3nda/bw/harvests-linkto-plantings
Link a harvest to a planting, and display
2017-01-08 11:08:42 +13:00
Brenda Wallace
2f38a8585b Revert "update spec for stringify"
This reverts commit 144823bd13.
2017-01-07 13:50:11 +13:00
Brenda Wallace
062ff16acf Put garden.to_s back to garden.name 2017-01-07 13:17:53 +13:00
Brenda Wallace
7f30ce04e0 Garden name (truncated) on front page link 2017-01-07 13:09:35 +13:00
Brenda Wallace
144823bd13 update spec for stringify 2017-01-07 12:52:47 +13:00
Brenda Wallace
90b19d52bb Don't rely on to_s for slug. Fragile with translations 2017-01-07 12:49:57 +13:00
Brenda Wallace
76be980163 Translate garden.location 2017-01-07 12:48:14 +13:00
Brenda Wallace
88b1f02574 Added require of photo model constants 2017-01-07 12:44:08 +13:00
Brenda Wallace
5b633b484b Fixes link to seeds, and spec for link to seeds 2017-01-07 12:22:28 +13:00
Brenda Wallace
3be379cee9 updated specs to match new links on photo page 2017-01-07 12:05:35 +13:00
Brenda Wallace
5319d23ee3 Using translations on links from photo page 2017-01-07 12:03:31 +13:00
Brenda Wallace
350c1d4c08 Descriptive links from photo page 2017-01-06 22:25:13 +13:00
Shiny
5ca8829727 Merge branch 'dev' into bw/active-plantings 2017-01-05 16:35:39 +13:00
Shiny
d40eccdb63 Merge branch 'dev' into bw/harvests-linkto-plantings 2017-01-05 16:31:22 +13:00
pozorvlak
478fae53ab Merge pull request #1136 from Br3nda/bw/garden-specs
Controller garden specs for member doing what they shouldn't
2017-01-04 12:06:10 +00:00
Shiny
fc71cba6ba Merge branch 'dev' into bw/harvests-linkto-plantings 2017-01-04 22:52:54 +13:00
Brenda Wallace
283bb76a9e Link a harvest to a planting, and display 2017-01-04 22:45:49 +13:00
Brenda Wallace
18e58809c3 Merge remote-tracking branch 'upstream/dev' into bw/active-plantings 2017-01-04 16:25:44 +13:00
Brenda Wallace
b27b361e2f Show active plantings by default 2017-01-04 16:25:19 +13:00
Shiny
3fafa87afd Merge branch 'dev' into bw/garden-specs 2017-01-04 16:18:54 +13:00
pozorvlak
de60dbb9b0 Merge pull request #1140 from Br3nda/bw/descriptive-spec
descriptive spec
2017-01-03 12:12:18 +00:00
Brenda Wallace
8047aef692 Merge remote-tracking branch 'upstream/dev' into bw/descriptive-spec
Conflicts:
	spec/features/signin_spec.rb
2017-01-03 22:16:24 +13:00
Brenda Wallace
b38728c5df Add login() to signin spec to reduce code duplication 2017-01-03 22:13:27 +13:00
Brenda Wallace
241c3cfdc0 Moves model name into spec description
so we can tell which failed.
2017-01-03 22:12:23 +13:00
Shiny
8b3b28b9d6 Merge branch 'dev' into bw/garden-specs 2017-01-03 20:50:20 +13:00
Daniel O'Connor
5f6fc37efd Merge pull request #1138 from Br3nda/bw/garden-name-in-link
Garden's name in link
2017-01-03 13:33:59 +10:30
Brenda Wallace
881acdccc9 Shortening long garden names on a user's page 2017-01-02 20:54:22 +13:00
Brenda Wallace
3b1753d3d5 Garden's name in link 2017-01-02 20:36:25 +13:00
Brenda Wallace
ab75f830fb Controller garden specs for member doing what they shouldn't 2016-12-25 10:38:07 +13:00
77 changed files with 774 additions and 748 deletions

View File

@@ -1,15 +1,14 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 500`
# on 2016-11-13 10:16:38 +1300 using RuboCop version 0.45.0.
# on 2017-01-21 15:58:02 +1030 using RuboCop version 0.47.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
# Offense count: 24
# Offense count: 22
Lint/AmbiguousRegexpLiteral:
Exclude:
- 'app/models/order.rb'
- 'spec/controllers/admin/orders_controller_spec.rb'
- 'spec/controllers/orders_controller_spec.rb'
- 'spec/features/cms_spec.rb'
@@ -17,7 +16,6 @@ Lint/AmbiguousRegexpLiteral:
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
- 'spec/models/comment_spec.rb'
- 'spec/models/planting_spec.rb'
- 'spec/models/post_spec.rb'
- 'spec/views/members/show.rss.haml_spec.rb'
- 'spec/views/posts/show.html.haml_spec.rb'
@@ -26,18 +24,17 @@ Lint/HandleExceptions:
Exclude:
- 'lib/tasks/testing.rake'
# Offense count: 15
# Offense count: 11
# Cop supports --auto-correct.
# Configuration parameters: IgnoreEmptyBlocks, AllowUnusedKeywordArguments.
Lint/UnusedBlockArgument:
Exclude:
- 'app/controllers/crops_controller.rb'
- 'app/controllers/sessions_controller.rb'
- 'app/models/post.rb'
- 'config/unicorn.rb'
- 'lib/haml/filters/growstuff_markdown.rb'
# Offense count: 8
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods.
Lint/UnusedMethodArgument:
@@ -45,7 +42,6 @@ Lint/UnusedMethodArgument:
- 'app/controllers/application_controller.rb'
- 'app/controllers/passwords_controller.rb'
- 'app/controllers/registrations_controller.rb'
- 'app/models/crop.rb'
- 'app/validators/approved_validator.rb'
- 'spec/views/plantings/show.html.haml_spec.rb'
@@ -56,23 +52,25 @@ Lint/Void:
- 'spec/models/garden_spec.rb'
- 'spec/models/post_spec.rb'
# Offense count: 5
# Offense count: 55
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Exclude:
- '**/*'
# Offense count: 2
# Cop supports --auto-correct.
Performance/StringReplacement:
Exclude:
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/planting.rb'
- 'app/models/seed.rb'
- 'spec/rails_helper.rb'
# Offense count: 10
# Offense count: 9
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: strict, flexible
Rails/Date:
Exclude:
- 'app/controllers/harvests_controller.rb'
- 'app/controllers/plantings_controller.rb'
- 'db/seeds.rb'
- 'lib/tasks/growstuff.rake'
- 'spec/controllers/plantings_controller_spec.rb'
@@ -80,20 +78,10 @@ Rails/Date:
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/features/shared_examples/append_date.rb'
# Offense count: 11
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/HasAndBelongsToMany:
# Offense count: 4
Rails/FilePath:
Exclude:
- 'app/models/crop.rb'
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/member.rb'
- 'app/models/photo.rb'
- 'app/models/planting.rb'
- 'app/models/post.rb'
- 'app/models/product.rb'
- 'app/models/role.rb'
- 'spec/rails_helper.rb'
# Offense count: 3
Rails/OutputSafety:
@@ -102,42 +90,44 @@ Rails/OutputSafety:
- 'app/helpers/auto_suggest_helper.rb'
- 'app/helpers/gardens_helper.rb'
# Offense count: 9
# Offense count: 1
# Configuration parameters: Include.
# Include: db/migrate/*.rb
Rails/ReversibleMigration:
Exclude:
- 'db/migrate/20130215131921_rename_notification_fields.rb'
# Offense count: 4
# Configuration parameters: Blacklist.
# Blacklist: decrement!, decrement_counter, increment!, increment_counter, toggle!, touch, update_all, update_attribute, update_column, update_columns, update_counters
Rails/SkipsModelValidations:
Exclude:
- 'app/controllers/plantings_controller.rb'
- 'db/seeds.rb'
# Offense count: 7
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: strict, flexible
Rails/TimeZone:
Exclude:
- 'app/helpers/plantings_helper.rb'
- 'spec/controllers/accounts_controller_spec.rb'
- 'spec/factories/member.rb'
- 'spec/factories/post.rb'
- 'spec/models/post_spec.rb'
- 'spec/views/plantings/index.html.haml_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/Validation:
Exclude:
- 'app/models/member.rb'
- 'app/models/order_item.rb'
# Offense count: 12
# Offense count: 7
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: always, conditionals
Style/AndOr:
Exclude:
- 'app/models/notification.rb'
- 'app/models/photo.rb'
- 'config/unicorn.rb'
- 'lib/tasks/growstuff.rake'
# Offense count: 2
# Offense count: 1
Style/AsciiComments:
Exclude:
- 'app/models/crop.rb'
- 'config/initializers/comfortable_mexican_sofa.rb'
# Offense count: 5
@@ -149,7 +139,7 @@ Style/BarePercentLiterals:
- 'app/helpers/auto_suggest_helper.rb'
- 'spec/support/feature_helpers.rb'
# Offense count: 25
# Offense count: 26
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods.
# SupportedStyles: line_count_based, semantic, braces_for_chaining
@@ -183,36 +173,6 @@ Style/BlockEndNewline:
- 'spec/models/member_spec.rb'
- 'spec/models/planting_spec.rb'
# Offense count: 93
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: braces, no_braces, context_dependent
Style/BracesAroundHashParameters:
Exclude:
- 'app/controllers/admin/orders_controller.rb'
- 'app/controllers/crops_controller.rb'
- 'app/controllers/posts_controller.rb'
- 'app/helpers/application_helper.rb'
- 'app/models/crop.rb'
- 'app/models/member.rb'
- 'app/models/order.rb'
- 'config/environments/test.rb'
- 'spec/controllers/admin/orders_controller_spec.rb'
- 'spec/controllers/comments_controller_spec.rb'
- 'spec/controllers/harvests_controller_spec.rb'
- 'spec/controllers/member_controller_spec.rb'
- 'spec/controllers/notifications_controller_spec.rb'
- 'spec/controllers/order_items_controller_spec.rb'
- 'spec/controllers/orders_controller_spec.rb'
- 'spec/controllers/places_controller_spec.rb'
- 'spec/controllers/plantings_controller_spec.rb'
- 'spec/controllers/posts_controller_spec.rb'
- 'spec/controllers/scientific_names_controller_spec.rb'
- 'spec/controllers/seeds_controller_spec.rb'
- 'spec/lib/actions/oauth_signup_action_spec.rb'
- 'spec/views/notifier/notify.html.haml_spec.rb'
- 'spec/views/photos/new.html.haml_spec.rb'
# Offense count: 4
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: nested, compact
@@ -223,16 +183,11 @@ Style/ClassAndModuleChildren:
- 'lib/haml/filters/escaped_markdown.rb'
- 'lib/haml/filters/growstuff_markdown.rb'
# Offense count: 8
# Offense count: 1
# Cop supports --auto-correct.
Style/ClassMethods:
Exclude:
- 'app/models/crop.rb'
- 'app/models/member.rb'
- 'app/models/order.rb'
- 'app/models/planting.rb'
- 'app/models/post.rb'
- 'app/models/seed.rb'
# Offense count: 2
# Cop supports --auto-correct.
@@ -262,18 +217,23 @@ Style/EachForSimpleLoop:
- 'spec/models/crop_spec.rb'
- 'spec/views/home/_crops.html.haml_spec.rb'
# Offense count: 1
# Offense count: 11
# Cop supports --auto-correct.
Style/EmptyLiteral:
Exclude:
- 'app/models/member.rb'
# Offense count: 1
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: for, each
Style/For:
# SupportedStyles: compact, expanded
Style/EmptyMethod:
Exclude:
- 'app/models/order.rb'
- 'app/controllers/account_types_controller.rb'
- 'app/controllers/accounts_controller.rb'
- 'app/controllers/alternate_names_controller.rb'
- 'app/controllers/gardens_controller.rb'
- 'app/controllers/photos_controller.rb'
- 'app/controllers/plant_parts_controller.rb'
- 'app/controllers/posts_controller.rb'
- 'app/controllers/products_controller.rb'
- 'app/controllers/roles_controller.rb'
- 'app/controllers/scientific_names_controller.rb'
- 'app/controllers/seeds_controller.rb'
# Offense count: 5
# Configuration parameters: EnforcedStyle, SupportedStyles.
@@ -284,32 +244,19 @@ Style/FormatString:
- 'spec/helpers/application_helper_spec.rb'
- 'spec/views/shop/index_spec.rb'
# Offense count: 4
# Offense count: 2
Style/IdenticalConditionalBranches:
Exclude:
- 'app/controllers/crops_controller.rb'
- 'app/controllers/follows_controller.rb'
# Offense count: 1
Style/IfInsideElse:
Exclude:
- 'app/models/harvest.rb'
# Offense count: 26
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: MaxLineLength.
Style/IfUnlessModifier:
Exclude:
- 'app/controllers/gardens_controller.rb'
- 'app/controllers/shop_controller.rb'
- 'app/helpers/crops_helper.rb'
- 'app/models/crop.rb'
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/member.rb'
- 'app/models/order.rb'
- 'app/models/planting.rb'
- 'app/models/seed.rb'
- 'config/initializers/geocoder.rb'
- 'lib/tasks/growstuff.rake'
@@ -322,22 +269,12 @@ Style/Lambda:
- 'spec/controllers/member_controller_spec.rb'
- 'spec/models/photo_spec.rb'
# Offense count: 3
# Cop supports --auto-correct.
Style/MethodCallParentheses:
Exclude:
- 'app/models/photo.rb'
- 'spec/helpers/application_helper_spec.rb'
- 'spec/views/plantings/new.html.haml_spec.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: symmetrical, new_line, same_line
Style/MultilineArrayBraceLayout:
Style/MethodCallWithoutArgsParentheses:
Exclude:
- 'app/models/seed.rb'
- 'spec/helpers/application_helper_spec.rb'
- 'spec/views/plantings/new.html.haml_spec.rb'
# Offense count: 8
# Cop supports --auto-correct.
@@ -349,17 +286,13 @@ Style/MultilineBlockLayout:
- 'spec/models/member_spec.rb'
- 'spec/models/planting_spec.rb'
# Offense count: 7
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: symmetrical, new_line, same_line
Style/MultilineHashBraceLayout:
Exclude:
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/planting.rb'
- 'app/models/product.rb'
- 'app/models/seed.rb'
# Offense count: 1
# Cop supports --auto-correct.
@@ -367,15 +300,14 @@ Style/MultilineIfModifier:
Exclude:
- 'spec/rails_helper.rb'
# Offense count: 6
# Offense count: 5
# Cop supports --auto-correct.
Style/MultilineIfThen:
Exclude:
- 'lib/tasks/growstuff.rake'
- 'script/check_contributors_md'
- 'script/gemfile_check'
# Offense count: 93
# Offense count: 95
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: symmetrical, new_line, same_line
@@ -384,8 +316,6 @@ Style/MultilineMethodCallBraceLayout:
- 'app/controllers/application_controller.rb'
- 'app/controllers/authentications_controller.rb'
- 'app/controllers/seeds_controller.rb'
- 'app/models/account.rb'
- 'app/models/crop.rb'
- 'spec/controllers/order_items_controller_spec.rb'
- 'spec/helpers/gardens_helper_spec.rb'
- 'spec/helpers/harvests_helper_spec.rb'
@@ -431,25 +361,18 @@ Style/MultilineTernaryOperator:
- 'app/controllers/notifications_controller.rb'
- 'app/controllers/order_items_controller.rb'
# Offense count: 10
# Offense count: 3
# Cop supports --auto-correct.
Style/MutableConstant:
Exclude:
- 'app/controllers/members_controller.rb'
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/planting.rb'
- 'app/models/seed.rb'
# Offense count: 7
# Offense count: 1
# Cop supports --auto-correct.
Style/NegatedIf:
Exclude:
- 'app/controllers/crops_controller.rb'
- 'app/helpers/crops_helper.rb'
- 'app/models/crop.rb'
- 'app/models/garden.rb'
- 'script/check_contributors_md'
# Offense count: 2
Style/NestedTernaryOperator:
@@ -457,13 +380,12 @@ Style/NestedTernaryOperator:
- 'app/controllers/harvests_controller.rb'
- 'app/controllers/plantings_controller.rb'
# Offense count: 2
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles.
# SupportedStyles: skip_modifier_ifs, always
Style/Next:
Exclude:
- 'app/models/post.rb'
- 'lib/tasks/growstuff.rake'
# Offense count: 2
@@ -472,13 +394,6 @@ Style/NilComparison:
Exclude:
- 'lib/tasks/growstuff.rake'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: IncludeSemanticChanges.
Style/NonNilCheck:
Exclude:
- 'app/models/harvest.rb'
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedOctalStyle, SupportedOctalStyles.
@@ -492,20 +407,15 @@ Style/NumericLiteralPrefix:
Style/NumericLiterals:
MinDigits: 9
# Offense count: 16
# Offense count: 5
# Cop supports --auto-correct.
# Configuration parameters: AutoCorrect, EnforcedStyle, SupportedStyles.
# SupportedStyles: predicate, comparison
Style/NumericPredicate:
Exclude:
- 'spec/**/*'
- 'app/helpers/crops_helper.rb'
- 'app/helpers/harvests_helper.rb'
- 'app/helpers/plantings_helper.rb'
- 'app/models/crop.rb'
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/photo.rb'
- 'lib/tasks/growstuff.rake'
- 'script/check_contributors_md'
@@ -515,7 +425,7 @@ Style/ParallelAssignment:
Exclude:
- 'app/mailers/notifier.rb'
# Offense count: 8
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: AllowSafeAssignment.
Style/ParenthesesAroundCondition:
@@ -523,8 +433,6 @@ Style/ParenthesesAroundCondition:
- 'app/controllers/application_controller.rb'
- 'app/controllers/orders_controller.rb'
- 'app/helpers/crops_helper.rb'
- 'app/models/garden.rb'
- 'app/models/member.rb'
- 'config/factory_girl.rb'
# Offense count: 5
@@ -537,60 +445,30 @@ Style/PercentLiteralDelimiters:
- 'spec/features/signin_spec.rb'
- 'spec/features/signout_spec.rb'
# Offense count: 6
# Offense count: 3
# Cop supports --auto-correct.
Style/PerlBackrefs:
Exclude:
- 'app/models/post.rb'
- 'lib/haml/filters/growstuff_markdown.rb'
# Offense count: 3
# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist.
# NamePrefix: is_, has_, have_
# NamePrefixBlacklist: is_, has_, have_
# NameWhitelist: is_a?
Style/PredicateName:
Exclude:
- 'spec/**/*'
- 'app/models/member.rb'
# Offense count: 1
# Cop supports --auto-correct.
Style/RedundantBegin:
Exclude:
- 'app/controllers/members_controller.rb'
# Offense count: 2
# Cop supports --auto-correct.
Style/RedundantParentheses:
Exclude:
- 'app/helpers/plantings_helper.rb'
- 'app/models/garden.rb'
# Offense count: 56
# Offense count: 1
# Cop supports --auto-correct.
Style/RedundantSelf:
Exclude:
- 'app/models/comment.rb'
- 'app/models/crop.rb'
- 'app/models/follow.rb'
- 'app/models/harvest.rb'
- 'app/models/member.rb'
- 'app/models/notification.rb'
- 'app/models/order.rb'
- 'app/models/photo.rb'
- 'app/models/planting.rb'
- 'app/models/post.rb'
- 'app/models/seed.rb'
- 'lib/geocodable.rb'
# Offense count: 9
# Offense count: 6
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes.
# SupportedStyles: slashes, percent_r, mixed
Style/RegexpLiteral:
Exclude:
- 'app/models/crop.rb'
- 'spec/lib/haml/filters/growstuff_markdown_spec.rb'
- 'spec/rails_helper.rb'
- 'spec/views/devise/registrations/edit_spec.rb'
@@ -611,55 +489,39 @@ Style/SelfAssignment:
Style/SpecialGlobalVars:
EnforcedStyle: use_perl_names
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiteralsInInterpolation:
Exclude:
- 'app/models/follow.rb'
- 'app/models/post.rb'
# Offense count: 9
# Offense count: 3
# Cop supports --auto-correct.
# Configuration parameters: IgnoredMethods.
# IgnoredMethods: respond_to, define_method
Style/SymbolProc:
Exclude:
- 'app/controllers/crops_controller.rb'
- 'app/models/crop.rb'
- 'app/models/garden.rb'
- 'app/models/harvest.rb'
- 'app/models/planting.rb'
- 'app/models/post.rb'
- 'lib/tasks/growstuff.rake'
# Offense count: 1
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
Style/TernaryParentheses:
Exclude:
- 'app/helpers/plantings_helper.rb'
# Offense count: 5
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
# SupportedStyles: comma, consistent_comma, no_comma
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInArguments:
Exclude:
- 'app/models/post.rb'
- 'db/seeds.rb'
- 'lib/actions/oauth_signup_action.rb'
- 'lib/tasks/growstuff.rake'
# Offense count: 5
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
# SupportedStyles: comma, consistent_comma, no_comma
# Configuration parameters: EnforcedStyleForMultiline, SupportedStylesForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma
Style/TrailingCommaInLiteral:
Exclude:
- 'app/models/crop.rb'
- 'config/environments/test.rb'
- 'spec/rails_helper.rb'
@@ -669,12 +531,10 @@ Style/UnlessElse:
Exclude:
- 'app/controllers/omniauth_callbacks_controller.rb'
# Offense count: 16
# Offense count: 12
# Cop supports --auto-correct.
Style/UnneededInterpolation:
Exclude:
- 'app/models/crop.rb'
- 'app/models/harvest.rb'
- 'spec/features/crops/crop_wranglers_spec.rb'
- 'spec/features/following_spec.rb'
- 'spec/features/shared_examples/append_date.rb'
@@ -690,19 +550,10 @@ Style/UnneededPercentQ:
Exclude:
- 'spec/support/feature_helpers.rb'
# Offense count: 4
# Offense count: 2
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex.
# Configuration parameters: SupportedStyles, WordRegex.
# SupportedStyles: percent, brackets
Style/WordArray:
Exclude:
- 'app/controllers/omniauth_callbacks_controller.rb'
- 'app/models/crop.rb'
- 'spec/models/seed_spec.rb'
# Offense count: 6
# Cop supports --auto-correct.
Style/ZeroLengthPredicate:
Exclude:
- 'app/models/crop.rb'
- 'app/models/photo.rb'
EnforcedStyle: percent
MinSize: 5

62
Gemfile
View File

@@ -7,9 +7,9 @@ gem 'rails', '~> 4.2.7'
gem 'bundler', '>=1.1.5'
gem 'sass-rails', '~> 5.0.4'
gem 'coffee-rails', '~> 4.1.0'
gem 'haml'
gem 'sass-rails', '~> 5.0.4'
# CSS framework
gem 'bootstrap-sass', '~> 3.3.6'
@@ -17,28 +17,28 @@ gem 'font-awesome-sass'
gem 'uglifier', '~> 2.7.2' # JavaScript compressor
gem 'flickraw'
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 'pg'
gem 'figaro' # for handling config via ENV variables
gem 'cancancan', '~> 1.9' # for checking member privileges
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'csv_shaper' # CSV export
gem 'figaro' # for handling config via ENV variables
gem 'gibbon', '~>1.2.0' # for Mailchimp newsletter subscriptions
gem 'leaflet-markercluster-rails'
gem 'leaflet-rails'
gem 'pg'
gem 'ruby-units' # for unit conversion
gem 'unicorn' # http server
gem 'comfortable_mexican_sofa', '~> 1.12.0' # content management system
gem 'kaminari' # pagination
gem 'bootstrap-kaminari-views' # bootstrap views for kaminari
gem 'kaminari' # pagination
gem 'activemerchant'
gem 'active_utils'
gem 'activemerchant'
gem 'sidekiq'
# Markdown formatting for updates etc
@@ -64,15 +64,15 @@ gem 'bootstrap-datepicker-rails'
# For connecting to other services (eg Twitter)
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-facebook'
gem 'omniauth-flickr', '>= 0.0.15'
gem 'omniauth-twitter'
# 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.
# Project does not use semver, so we want to be in sync with the version of
# Project does not use semver, so we want to be in sync with the version of
# elasticsearch we use
# See https://github.com/elastic/elasticsearch-ruby#compatibility
gem "elasticsearch-api", "~> 2.0.0"
@@ -81,12 +81,15 @@ gem "elasticsearch-rails"
gem 'rake', '>= 10.0.0'
# # CMS
# gem 'comfortable_mexican_sofa', '~> 1.12.0'
group :production, :staging do
gem 'newrelic_rpm'
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
gem 'dalli'
gem 'memcachier'
gem 'newrelic_rpm'
gem 'rails_12factor' # supresses heroku plugin injection
gem 'bonsai-elasticsearch-rails' # Integration with Bonsa-Elasticsearch on heroku
gem 'sparkpost_rails'
end
@@ -94,33 +97,34 @@ 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'
gem 'guard'
gem 'guard-rspec'
gem 'letter_opener'
gem 'pry'
gem 'quiet_assets'
end
group :development, :test do
gem 'haml-rails' # HTML templating language
gem 'rspec-rails' # unit testing framework
gem 'rspec-activemodel-mocks'
gem "active_merchant-paypal-bogus-gateway"
gem 'byebug' # debugging
gem 'database_cleaner', '~> 1.5.0'
gem 'webrat' # provides HTML matchers for view tests
gem 'factory_girl_rails' # for creating test data
gem 'coveralls', require: false # coverage analysis
gem 'capybara' # integration tests
gem 'capybara-email' # integration tests for email
gem 'capybara-screenshot' # for test debugging
gem 'poltergeist' # for headless JS testing
gem 'i18n-tasks' # adds tests for finding missing and unused translations
gem 'selenium-webdriver'
gem 'coveralls', require: false # coverage analysis
gem 'database_cleaner', '~> 1.5.0'
gem 'factory_girl_rails' # for creating test data
gem 'haml-i18n-extractor'
gem "active_merchant-paypal-bogus-gateway"
gem 'haml-rails' # HTML templating language
gem 'i18n-tasks' # adds tests for finding missing and unused translations
gem 'poltergeist' # for headless JS testing
gem 'rspec-activemodel-mocks'
gem 'rspec-rails' # unit testing framework
gem 'rubocop', require: false
gem 'rainbow', '< 2.2.0' # See https://github.com/sickill/rainbow/issues/44
gem 'selenium-webdriver'
gem 'webrat' # provides HTML matchers for view tests
end
group :test do

View File

@@ -50,9 +50,9 @@ GEM
tzinfo (~> 1.1)
addressable (2.5.0)
public_suffix (~> 2.0, >= 2.0.2)
arel (6.0.3)
arel (6.0.4)
ast (2.3.0)
autoprefixer-rails (6.5.3.1)
autoprefixer-rails (6.6.1)
execjs
bcrypt (3.1.11)
better_errors (2.1.1)
@@ -71,8 +71,8 @@ GEM
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
bootstrap_form (2.5.2)
builder (3.2.2)
bootstrap_form (2.5.3)
builder (3.2.3)
byebug (9.0.6)
cancancan (1.15.0)
capybara (2.10.1)
@@ -90,8 +90,7 @@ GEM
launchy
childprocess (0.5.9)
ffi (~> 1.0, >= 1.0.11)
climate_control (0.0.3)
activesupport (>= 3.0)
climate_control (0.1.0)
cliver (0.3.2)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
@@ -106,8 +105,8 @@ GEM
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
comfortable_mexican_sofa (1.12.9)
coffee-script-source (1.12.2)
comfortable_mexican_sofa (1.12.10)
active_link_to (>= 1.0.0)
bootstrap-sass (>= 3.2.0)
bootstrap_form (>= 2.2.0)
@@ -119,17 +118,17 @@ GEM
kramdown (>= 1.0.0)
paperclip (>= 4.0.0)
plupload-rails (>= 1.2.1)
rails (>= 4.0.0, < 5)
rails (>= 4.0.0, < 5.1)
rails-i18n (>= 4.0.0)
sass-rails (>= 4.0.3)
concurrent-ruby (1.0.2)
connection_pool (2.2.0)
coveralls (0.8.16)
concurrent-ruby (1.0.4)
connection_pool (2.2.1)
coveralls (0.8.19)
json (>= 1.8, < 3)
simplecov (~> 0.12.0)
term-ansicolor (~> 1.3.0)
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
tins (>= 1.6.0, < 2)
tins (~> 1.6)
csv_shaper (1.3.0)
activesupport (>= 3.0.0)
dalli (2.7.6)
@@ -141,7 +140,7 @@ GEM
railties (>= 4.1.0, < 5.1)
responders
warden (~> 1.2.3)
diff-lcs (1.2.5)
diff-lcs (1.3)
docile (1.1.5)
easy_translate (0.5.0)
json
@@ -163,14 +162,14 @@ GEM
erubis (2.7.0)
excon (0.54.0)
execjs (2.7.0)
factory_girl (4.7.0)
factory_girl (4.8.0)
activesupport (>= 3.0.0)
factory_girl_rails (4.7.0)
factory_girl (~> 4.7.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
railties (>= 3.0.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
ffi (1.9.14)
ffi (1.9.17)
figaro (1.1.1)
thor (~> 0.14)
flickraw (0.9.9)
@@ -179,7 +178,7 @@ GEM
formatador (0.2.5)
friendly_id (5.0.5)
activerecord (>= 4.0.0)
geocoder (1.3.7)
geocoder (1.4.1)
gibbon (1.2.1)
httparty
multi_json (>= 1.9.0)
@@ -229,7 +228,7 @@ GEM
httparty (0.14.0)
multi_xml (>= 0.5.2)
i18n (0.7.0)
i18n-tasks (0.9.6)
i18n-tasks (0.9.9)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
easy_translate (>= 0.5.0)
@@ -239,7 +238,7 @@ GEM
parser (>= 2.2.3.0)
term-ansicolor (>= 1.3.2)
terminal-table (>= 1.5.1)
jquery-rails (4.2.1)
jquery-rails (4.2.2)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
@@ -248,13 +247,13 @@ GEM
js-routes (1.3.0)
railties (>= 3.2)
sprockets-rails
json (1.8.3)
json (1.8.6)
jwt (1.5.6)
kaminari (0.17.0)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
kgio (2.10.0)
kramdown (1.13.1)
kramdown (1.13.2)
launchy (2.4.3)
addressable (~> 2.3)
leaflet-markercluster-rails (0.7.0)
@@ -268,7 +267,7 @@ GEM
ruby_dep (~> 1.2)
loofah (2.0.3)
nokogiri (>= 1.5.9)
lumberjack (1.0.10)
lumberjack (1.0.11)
mail (2.6.4)
mime-types (>= 1.16, < 4)
memcachier (0.0.2)
@@ -296,7 +295,7 @@ GEM
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
omniauth (1.3.1)
omniauth (1.3.2)
hashie (>= 1.2, < 4)
rack (>= 1.0, < 3)
omniauth-facebook (4.0.0)
@@ -320,7 +319,7 @@ GEM
cocaine (~> 0.5.5)
mime-types
mimemagic (~> 0.3.0)
parser (2.3.2.0)
parser (2.3.3.1)
ast (~> 2.2)
pg (0.19.0)
plupload-rails (1.2.1)
@@ -334,7 +333,7 @@ GEM
coderay (~> 1.1.0)
method_source (~> 0.8.1)
slop (~> 3.4)
public_suffix (2.0.4)
public_suffix (2.0.5)
quiet_assets (1.1.0)
railties (>= 3.1, < 5.0)
rack (1.6.5)
@@ -355,9 +354,9 @@ GEM
sprockets-rails
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.7)
rails-dom-testing (1.0.8)
activesupport (>= 4.2.0.beta, < 5.0)
nokogiri (~> 1.6.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
@@ -408,26 +407,26 @@ GEM
rspec-mocks (~> 3.5.0)
rspec-support (~> 3.5.0)
rspec-support (3.5.0)
rubocop (0.45.0)
parser (>= 2.3.1.1, < 3.0)
rubocop (0.47.1)
parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.8.1)
ruby-units (2.0.1)
ruby_dep (1.4.0)
ruby_parser (3.8.3)
ruby_dep (1.5.0)
ruby_parser (3.8.4)
sexp_processor (~> 4.1)
rubyzip (1.2.0)
sass (3.4.22)
sass (3.4.23)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (2.53.4)
selenium-webdriver (3.0.5)
childprocess (~> 0.5)
rubyzip (~> 1.0)
websocket (~> 1.0)
@@ -450,14 +449,14 @@ GEM
slop (3.6.0)
sparkpost_rails (1.4.0)
rails (>= 4.0, < 5.1)
sprockets (3.7.0)
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.1.1)
sprockets-rails (3.2.0)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
term-ansicolor (1.3.2)
term-ansicolor (1.4.0)
tins (~> 1.0)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
@@ -472,7 +471,7 @@ GEM
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
unicode-display_width (1.1.1)
unicode-display_width (1.1.3)
unicorn (5.1.0)
kgio (~> 2.6)
raindrops (~> 0.7)
@@ -555,6 +554,7 @@ DEPENDENCIES
quiet_assets
rails (~> 4.2.7)
rails_12factor
rainbow (< 2.2.0)
rake (>= 10.0.0)
rspec-activemodel-mocks
rspec-rails
@@ -573,4 +573,4 @@ RUBY VERSION
ruby 2.3.3p222
BUNDLED WITH
1.13.6
1.13.7

View File

@@ -37,7 +37,7 @@ class AccountTypesController < ApplicationController
respond_to do |format|
if @account_type.save
format.html { redirect_to @account_type, notice: 'Account type was successfully created.' }
format.html { redirect_to @account_type, notice: I18n.t('account_types.created') }
else
format.html { render action: "new" }
end
@@ -48,7 +48,7 @@ class AccountTypesController < ApplicationController
def update
respond_to do |format|
if @account_type.update(account_type_params)
format.html { redirect_to @account_type, notice: 'Account type was successfully updated.' }
format.html { redirect_to @account_type, notice: I18n.t('account_types.updated') }
else
format.html { render action: "edit" }
end
@@ -60,7 +60,7 @@ class AccountTypesController < ApplicationController
@account_type.destroy
respond_to do |format|
format.html { redirect_to account_types_url, notice: 'Account type was successfully deleted.' }
format.html { redirect_to account_types_url, notice: I18n.t('account_types.deleted') }
end
end

View File

@@ -26,7 +26,7 @@ class AccountsController < ApplicationController
def update
respond_to do |format|
if @account.update(params[:account])
format.html { redirect_to @account, notice: 'Account detail was successfully updated.' }
format.html { redirect_to @account, notice: I18n.t('account.update') }
else
format.html { render action: "edit" }
end

View File

@@ -8,7 +8,7 @@ class Admin::OrdersController < ApplicationController
def search
authorize! :manage, :all
@orders = Order.search({ by: params[:search_by], for: params[:search_text] })
@orders = Order.search(by: params[:search_by], for: params[:search_text])
if @orders.empty?
flash[:alert] = "Couldn't find order with #{params[:search_by]} = #{params[:search_text]}"

View File

@@ -10,7 +10,7 @@ class CropsController < ApplicationController
def index
@sort = params[:sort]
@crops = if @sort == 'alpha'
Crop.includes(:scientific_names, { plantings: :photos })
Crop.includes(:scientific_names, plantings: :photos)
else
popular_crops
end
@@ -74,7 +74,7 @@ class CropsController < ApplicationController
# GET /crops/1
# GET /crops/1.json
def show
@crop = Crop.includes(:scientific_names, { plantings: :photos }).find(params[:id])
@crop = Crop.includes(:scientific_names, plantings: :photos).find(params[:id])
@posts = @crop.posts.paginate(page: params[:page])
respond_to do |format|
@@ -119,7 +119,7 @@ class CropsController < ApplicationController
def create
@crop = Crop.new(crop_params)
if current_member.has_role? :crop_wrangler
if current_member.role? :crop_wrangler
@crop.creator = current_member
success_msg = "Crop was successfully created."
else
@@ -136,7 +136,7 @@ class CropsController < ApplicationController
params[:sci_name].each do |index, value|
create_name('scientific', value)
end
unless current_member.has_role? :crop_wrangler
unless current_member.role? :crop_wrangler
Role.crop_wranglers.each do |w|
Notifier.new_crop_request(w, @crop).deliver_later!
end
@@ -192,7 +192,7 @@ class CropsController < ApplicationController
private
def popular_crops
Crop.popular.includes(:scientific_names, { plantings: :photos })
Crop.popular.includes(:scientific_names, plantings: :photos)
end
def recreate_names(param_name, name_type)

View File

@@ -45,12 +45,11 @@ class GardensController < ApplicationController
# POST /gardens
# POST /gardens.json
def create
params[:garden][:owner_id] = current_member.id
@garden = Garden.new(garden_params)
@garden.owner_id = current_member.id
respond_to do |format|
if @garden.save
format.html { redirect_to @garden, notice: 'Garden was successfully created.' }
format.html { redirect_to @garden, notice: I18n.t('gardens.created') }
format.json { render json: @garden, status: :created, location: @garden }
expire_fragment("homepage_stats")
else
@@ -65,7 +64,7 @@ class GardensController < ApplicationController
def update
respond_to do |format|
if @garden.update(garden_params)
format.html { redirect_to @garden, notice: 'Garden was successfully updated.' }
format.html { redirect_to @garden, notice: I18n.t('gardens.updated') }
format.json { head :no_content }
else
format.html { render action: "edit" }
@@ -82,7 +81,7 @@ class GardensController < ApplicationController
respond_to do |format|
format.html do
redirect_to gardens_by_owner_path(owner: @garden.owner), notice: 'Garden was successfully deleted.'
redirect_to gardens_by_owner_path(owner: @garden.owner), notice: I18n.t('gardens.deleted')
end
format.json { head :no_content }
end

View File

@@ -26,10 +26,15 @@ class HarvestsController < ApplicationController
end
end
def show
@planting = @harvest.planting if @harvest.planting_id
end
# GET /harvests/new
# GET /harvests/new.json
def new
@harvest = Harvest.new('harvested_at' => Date.today)
@planting = Planting.find_by(slug: params[:planting_id]) if params[:planting_id]
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_or_initialize_by(id: params[:crop_id])
@@ -42,18 +47,17 @@ class HarvestsController < ApplicationController
# GET /harvests/1/edit
def edit
@planting = @harvest.planting if @harvest.planting_id
end
# POST /harvests
# POST /harvests.json
def create
params[:harvest][:owner_id] = current_member.id
params[:harvested_at] = parse_date(params[:harvested_at])
@harvest = Harvest.new(harvest_params)
@harvest.crop_id = @harvest.planting.crop_id if @harvest.planting_id
respond_to do |format|
if @harvest.save
format.html { redirect_to @harvest, notice: 'Harvest was successfully created.' }
format.html { redirect_to @harvest, notice: I18n.t('harvests.created') }
format.json { render json: @harvest, status: :created, location: @harvest }
else
format.html { render action: "new" }
@@ -67,7 +71,7 @@ class HarvestsController < ApplicationController
def update
respond_to do |format|
if @harvest.update(harvest_params)
format.html { redirect_to @harvest, notice: 'Harvest was successfully updated.' }
format.html { redirect_to @harvest, notice: I18n.t('harvests.updated') }
format.json { head :no_content }
else
format.html { render action: "edit" }
@@ -90,7 +94,10 @@ class HarvestsController < ApplicationController
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)
params.require(:harvest)
.permit(:planting_id, :crop_id, :harvested_at, :description,
:quantity, :unit, :weight_quantity, :weight_unit,
:plant_part_id, :slug, :si_weight)
.merge(owner_id: current_member.id)
end
end

View File

@@ -74,10 +74,10 @@ class MembersController < ApplicationController
@type = decrypted_message[:type]
@member.update(@type => false)
flash.now[:notice] = "You have been unsubscribed from #{EMAIL_TYPE_STRING[@type]} emails."
flash.now[:notice] = I18n.t('members.unsubscribed', email_type: EMAIL_TYPE_STRING[@type])
rescue ActiveSupport::MessageVerifier::InvalidSignature
flash.now[:alert] = "We're sorry, there was an error updating your settings."
flash.now[:alert] = I18n.t('members.unsubscribe.error')
end
def finish_signup
@@ -87,9 +87,9 @@ class MembersController < ApplicationController
if @member.update(member_params)
@member.skip_reconfirmation!
bypass_sign_in(@member)
redirect_to root_path, notice: 'Welcome.'
redirect_to root_path, notice: I18n.t('members.welcome')
else
flash[:alert] = 'Failed to complete signup'
flash[:alert] = I18n.t('members.signup.error')
@show_errors = true
end
end

View File

@@ -5,15 +5,10 @@ class PlantingsController < ApplicationController
# GET /plantings
# GET /plantings.json
def index
@owner = Member.find_by(slug: params[:owner])
@crop = Crop.find_by(slug: params[:crop])
@plantings = if @owner
@owner.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
elsif @crop
@crop.plantings.includes(:owner, :crop, :garden).paginate(page: params[:page])
else
Planting.includes(:owner, :crop, :garden).paginate(page: params[:page])
end
@owner = Member.find_by(slug: params[:owner]) if params[:owner]
@crop = Crop.find_by(slug: params[:crop]) if params[:crop]
@show_all = params[:all] == '1'
@plantings = plantings
respond_to do |format|
format.html { @plantings = @plantings.paginate(page: params[:page]) }
@@ -41,7 +36,7 @@ class PlantingsController < ApplicationController
# GET /plantings/new
# GET /plantings/new.json
def new
@planting = Planting.new('planted_at' => Date.today)
@planting = Planting.new('planted_at' => Time.zone.today)
# using find_by_id here because it returns nil, unlike find
@crop = Crop.find_by(id: params[:crop_id]) || Crop.new
@@ -127,4 +122,18 @@ class PlantingsController < ApplicationController
(planting.finished_at - planting.planted_at).to_i
end
end
def plantings
@plantings = if @owner
@owner.plantings
elsif @crop
@crop.plantings
else
Planting
end
@plantings = @plantings.current unless @show_all
@plantings = @plantings.includes(:owner, :crop, :garden).order(:created_at).paginate(page: params[:page])
@plantings
end
end

View File

@@ -8,9 +8,9 @@ class PostsController < ApplicationController
def index
@author = Member.find_by(slug: params[:author])
@posts = if @author
@author.posts.includes(:author, { comments: :author }).paginate(page: params[:page])
@author.posts.includes(:author, comments: :author).paginate(page: params[:page])
else
Post.includes(:author, { comments: :author }).paginate(page: params[:page])
Post.includes(:author, comments: :author).paginate(page: params[:page])
end
respond_to do |format|
@@ -23,7 +23,7 @@ class PostsController < ApplicationController
# GET /posts/1
# GET /posts/1.json
def show
@post = Post.includes(:author, { comments: :author }).find(params[:id])
@post = Post.includes(:author, comments: :author).find(params[:id])
respond_to do |format|
format.html # show.html.haml

View File

@@ -3,7 +3,7 @@ class SessionsController < Devise::SessionsController
def create
super do |resource|
if Crop.pending_approval.present? && current_member.has_role?(:crop_wrangler)
if Crop.pending_approval.present? && current_member.role?(:crop_wrangler)
flash[:alert] = "There are crops waiting to be wrangled."
end
end

View File

@@ -70,10 +70,8 @@ module ApplicationHelper
return uri.to_s
end
Gravatar.new(member.email).image_url({
size: size,
default: :identicon
})
Gravatar.new(member.email).image_url(size: size,
default: :identicon)
end
# Returns a string with the quantity and the right pluralization for a

View File

@@ -9,6 +9,10 @@ module GardensHelper
end
end
def display_garden_name(garden)
truncate(garden.name, length: 50, separator: ' ', omission: '... ')
end
def display_garden_plantings(plantings)
if plantings.blank?
"None"

View File

@@ -57,7 +57,7 @@ class Ability
# note we don't support update for notifications
# only crop wranglers can create/edit/destroy crops
if member.has_role? :crop_wrangler
if member.role? :crop_wrangler
can :wrangle, Crop
can :manage, Crop
can :manage, ScientificName
@@ -92,6 +92,8 @@ class Ability
can :create, Harvest
can :update, Harvest, owner_id: member.id
can :destroy, Harvest, owner_id: member.id
can :update, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :destroy, Harvest, owner_id: member.id, planting: { owner_id: member.id }
can :create, Photo
can :update, Photo, owner_id: member.id
@@ -122,7 +124,7 @@ class Ability
can :destroy, Follow
cannot :destroy, Follow, followed_id: member.id # can't unfollow yourself
return unless member.has_role? :admin
return unless member.role? :admin
can :read, :all
can :manage, :all

View File

@@ -9,8 +9,7 @@ class Account < ActiveRecord::Base
before_create do |account|
unless account.account_type
account.account_type = AccountType.find_or_create_by(name:
Growstuff::Application.config.default_account_type
)
Growstuff::Application.config.default_account_type)
end
end

View File

@@ -6,16 +6,16 @@ class Comment < ActiveRecord::Base
scope :post_order, -> { reorder("created_at ASC") } # for display on post page
after_create do
recipient = self.post.author.id
sender = self.author.id
recipient = post.author.id
sender = author.id
# don't send notifications to yourself
if recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} commented on #{self.post.subject}",
body: self.body,
post_id: self.post.id
subject: "#{author} commented on #{post.subject}",
body: body,
post_id: post.id
)
end
end

View File

@@ -18,7 +18,7 @@ class Crop < ActiveRecord::Base
belongs_to :parent, class_name: 'Crop'
has_many :varieties, class_name: 'Crop', foreign_key: 'parent_id'
has_and_belongs_to_many :posts
has_and_belongs_to_many :posts # rubocop:disable Rails/HasAndBelongsToMany
before_destroy { |crop| crop.posts.clear }
default_scope { order("lower(name) asc") }
@@ -42,7 +42,7 @@ class Crop < ActiveRecord::Base
## Wikipedia urls are only necessary when approving a crop
validates :en_wikipedia_url,
format: {
with: /\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_\.()-]+\z/,
with: %r{\Ahttps?:\/\/en\.wikipedia\.org\/wiki\/[[:alnum:]%_\.()-]+\z},
message: 'is not a valid English Wikipedia URL'
},
if: :approved?
@@ -73,8 +73,8 @@ class Crop < ActiveRecord::Base
min_gram: 3,
max_gram: 10,
# token_chars: Elasticsearch will split on characters
# that dont belong to any of these classes
token_chars: ["letter", "digit"]
# that don't belong to any of these classes
token_chars: %w(letter digit)
}
},
analyzer: {
@@ -82,7 +82,7 @@ class Crop < ActiveRecord::Base
tokenizer: "gs_edgeNGram_tokenizer",
filter: ["lowercase"]
}
},
}
} do
mappings dynamic: 'false' do
indexes :id, type: 'long'
@@ -103,18 +103,19 @@ class Crop < ActiveRecord::Base
end
end
def as_indexed_json(options = {})
self.as_json(
def as_indexed_json(_options = {})
as_json(
only: [:id, :name, :approval_status],
include: {
scientific_names: { only: :name },
alternate_names: { only: :name }
})
}
)
end
# update the Elasticsearch index (only if we're using it in this
# environment)
def update_index(name_obj)
def update_index(_name_obj)
__elasticsearch__.index_document if ENV["GROWSTUFF_ELASTICSEARCH"] == "true"
end
@@ -125,7 +126,7 @@ class Crop < ActiveRecord::Base
end
def default_scientific_name
scientific_names.first.name if scientific_names.size > 0
scientific_names.first.name unless scientific_names.empty?
end
# crop.default_photo
@@ -190,7 +191,7 @@ class Crop < ActiveRecord::Base
end
def approval_statuses
['rejected', 'pending', 'approved']
%w(rejected pending approved)
end
def reasons_for_rejection
@@ -199,7 +200,7 @@ class Crop < ActiveRecord::Base
# Crop.interesting
# returns a list of interesting crops, for use on the homepage etc
def Crop.interesting
def self.interesting
howmany = 12 # max number to find
interesting_crops = []
Crop.includes(:photos).randomized.each do |c|
@@ -218,7 +219,7 @@ class Crop < ActiveRecord::Base
# - parent (name, optional)
# - scientific name (optional, can be picked up from parent if it has one)
def Crop.create_from_csv(row)
def self.create_from_csv(row)
name, en_wikipedia_url, parent, scientific_names, alternate_names = row
cropbot = Member.find_by(login_name: 'cropbot')
@@ -246,16 +247,16 @@ class Crop < ActiveRecord::Base
def add_scientific_names_from_csv(scientific_names)
names_to_add = []
if !scientific_names.blank? # i.e. we actually passed something in, which isn't a given
names_to_add = scientific_names.split(%r{,\s*})
elsif parent && parent.scientific_names.size > 0 # pick up from parent
names_to_add = parent.scientific_names.map { |s| s.name }
names_to_add = scientific_names.split(/,\s*/)
elsif parent && !parent.scientific_names.empty? # pick up from parent
names_to_add = parent.scientific_names.map(&:name)
else
logger.warn("Warning: no scientific name (not even on parent crop) for #{self}")
end
cropbot = Member.find_by(login_name: 'cropbot')
return unless names_to_add.size > 0
return if names_to_add.empty?
raise "cropbot account not found: run rake db:seed" unless cropbot
add_names_to_list(names_to_add, 'scientific')
@@ -266,7 +267,7 @@ class Crop < ActiveRecord::Base
return if alternate_names.blank?
cropbot = Member.find_by!(login_name: 'cropbot')
names_to_add = alternate_names.split(%r{,\s*})
names_to_add = alternate_names.split(/,\s*/)
add_names_to_list(names_to_add, 'alternate')
rescue
raise "cropbot account not found: run rake db:seed" unless cropbot
@@ -281,23 +282,21 @@ class Crop < ActiveRecord::Base
def self.search(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}",
analyzer: "standard",
fields: ["name",
"scientific_names.scientific_name",
"alternate_names.name"]
}
},
filter: {
term: { approval_status: "approved" }
},
size: 50
}
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.to_s,
analyzer: "standard",
fields: ["name",
"scientific_names.scientific_name",
"alternate_names.name"]
}
},
filter: {
term: { approval_status: "approved" }
},
size: 50
)
response.records.to_a
else
@@ -320,7 +319,7 @@ class Crop < ActiveRecord::Base
end
end
def Crop.case_insensitive_name(name)
def self.case_insensitive_name(name)
where(["lower(name) = :value", { value: name.downcase }])
end
@@ -339,20 +338,20 @@ class Crop < ActiveRecord::Base
def create_crop_in_list(list_name, name)
cropbot = Member.find_by(login_name: 'cropbot')
create_hash = {
creator_id: "#{cropbot.id}",
creator_id: cropbot.id.to_s,
name: name
}
self.send("#{list_name}_names").create(create_hash)
send("#{list_name}_names").create(create_hash)
end
def name_already_exists(list_name, name)
self.send("#{list_name}_names").exists?(name: name)
send("#{list_name}_names").exists?(name: name)
end
def count_uses_of_property(col_name)
data = Hash.new(0)
plantings.each do |p|
data[p.send("#{col_name}")] += 1 if !p.send("#{col_name}").blank?
data[p.send(col_name.to_s)] += 1 unless p.send(col_name.to_s).blank?
end
data
end

View File

@@ -5,10 +5,10 @@ class Follow < ActiveRecord::Base
after_create do
Notification.create(
recipient_id: self.followed_id,
sender_id: self.follower_id,
subject: "#{self.follower.login_name} is now following you",
body: "#{self.follower.login_name} just followed you on #{ENV["GROWSTUFF_SITE_NAME"]}. "
recipient_id: followed_id,
sender_id: follower_id,
subject: "#{follower.login_name} is now following you",
body: "#{follower.login_name} just followed you on #{ENV['GROWSTUFF_SITE_NAME']}. "
)
end
end

View File

@@ -30,7 +30,8 @@ class Garden < ActiveRecord::Base
validates :area,
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
AREA_UNITS_VALUES = {
@@ -38,7 +39,7 @@ class Garden < ActiveRecord::Base
"square feet" => "square foot",
"hectares" => "hectare",
"acres" => "acre"
}
}.freeze
validates :area_unit, inclusion: { in: AREA_UNITS_VALUES.values,
message: "%{value} is not a valid area unit" },
allow_nil: true,
@@ -47,12 +48,12 @@ class Garden < ActiveRecord::Base
after_validation :cleanup_area
def cleanup_area
self.area = nil if area == 0
self.area = nil if area && area.zero?
self.area_unit = nil if area.blank?
end
def garden_slug
"#{owner.login_name}-#{name}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{name}".downcase.tr(' ', '-')
end
# featured plantings returns the most recent 4 plantings for a garden,
@@ -62,7 +63,7 @@ class Garden < ActiveRecord::Base
seen_crops = []
plantings.each do |p|
if (!seen_crops.include?(p.crop))
unless seen_crops.include?(p.crop)
unique_plantings.push(p)
seen_crops.push(p.crop)
end

View File

@@ -7,6 +7,7 @@ class Harvest < ActiveRecord::Base
belongs_to :crop
belongs_to :owner, class_name: 'Member'
belongs_to :plant_part
belongs_to :planting
default_scope { order('created_at DESC') }
@@ -19,7 +20,8 @@ class Harvest < ActiveRecord::Base
validates :quantity,
numericality: {
only_integer: false,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
UNITS_VALUES = {
@@ -33,7 +35,7 @@ class Harvest < ActiveRecord::Base
"buckets" => "bucket",
"baskets" => "basket",
"bushels" => "bushel"
}
}.freeze
validates :unit, inclusion: { in: UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
@@ -47,7 +49,7 @@ class Harvest < ActiveRecord::Base
"kg" => "kg",
"lb" => "lb",
"oz" => "oz"
}
}.freeze
validates :weight_unit, inclusion: { in: WEIGHT_UNITS_VALUES.values,
message: "%{value} is not a valid unit" },
allow_nil: true,
@@ -60,20 +62,20 @@ class Harvest < ActiveRecord::Base
# we're storing the harvest weight in kilograms in the db too
# to make data manipulation easier
def set_si_weight
return if self.weight_unit.nil?
weight_string = "#{self.weight_quantity} #{self.weight_unit}"
return if weight_unit.nil?
weight_string = "#{weight_quantity} #{weight_unit}"
self.si_weight = Unit.new(weight_string).convert_to("kg").to_s("%0.3f").delete(" kg").to_f
end
def cleanup_quantities
self.quantity = nil if quantity == 0
self.quantity = nil if quantity && quantity.zero?
self.unit = nil if quantity.blank?
self.weight_quantity = nil if weight_quantity == 0
self.weight_quantity = nil if weight_quantity && weight_quantity.zero?
self.weight_unit = nil if weight_quantity.blank?
end
def harvest_slug
"#{owner.login_name}-#{crop}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{crop}".downcase.tr(' ', '-')
end
# stringify as "beet in Skud's backyard" or similar
@@ -81,28 +83,28 @@ class Harvest < ActiveRecord::Base
# 50 individual apples, weighing 3lb
# 2 buckets of apricots, weighing 10kg
string = ''
if self.quantity
string += "#{number_to_human(self.quantity.to_s, strip_insignificant_zeros: true)} "
string += if self.unit == 'individual'
if quantity
string += "#{number_to_human(quantity.to_s, strip_insignificant_zeros: true)} "
string += if unit == 'individual'
'individual '
elsif self.quantity == 1
"#{self.unit} of "
elsif quantity == 1
"#{unit} of "
else
"#{self.unit.pluralize} of "
"#{unit.pluralize} of "
end
end
string += if self.unit != 'individual' # buckets of apricot*s*
"#{self.crop.name.pluralize}"
elsif self.quantity == 1
"#{self.crop.name}"
string += if unit != 'individual' # buckets of apricot*s*
crop.name.pluralize.to_s
elsif quantity == 1
crop.name.to_s
else
"#{self.crop.name.pluralize}"
crop.name.pluralize.to_s
end
if self.weight_quantity
string += " weighing #{number_to_human(self.weight_quantity, strip_insignificant_zeros: true)}"\
" #{self.weight_unit}"
if weight_quantity
string += " weighing #{number_to_human(weight_quantity, strip_insignificant_zeros: true)}"\
" #{weight_unit}"
end
string

View File

@@ -14,7 +14,7 @@ class Member < ActiveRecord::Base
has_many :seeds, foreign_key: 'owner_id'
has_many :harvests, foreign_key: 'owner_id'
has_and_belongs_to_many :roles
has_and_belongs_to_many :roles # rubocop:disable Rails/HasAndBelongsToMany
has_many :notifications, foreign_key: 'recipient_id'
has_many :sent_notifications, foreign_key: 'sender_id'
@@ -57,8 +57,8 @@ class Member < ActiveRecord::Base
attr_accessor :login
# Requires acceptance of the Terms of Service
validates_acceptance_of :tos_agreement, allow_nil: true,
accept: true
validates :tos_agreement, acceptance: { allow_nil: true,
accept: true }
validates :login_name,
length: {
@@ -100,7 +100,7 @@ class Member < ActiveRecord::Base
login_name
end
def has_role?(role_sym)
def role?(role_sym)
roles.any? { |r| r.name.gsub(/\s+/, "_").underscore.to_sym == role_sym }
end
@@ -114,9 +114,7 @@ class Member < ActiveRecord::Base
# called by order.update_account, which loops through all order items
# and does this for each one.
def update_account_after_purchase(product)
if product.account_type
account.account_type = product.account_type
end
account.account_type = product.account_type if product.account_type
if product.paid_months
start_date = account.paid_until || Time.zone.now
account.paid_until = start_date + product.paid_months.months
@@ -124,7 +122,7 @@ class Member < ActiveRecord::Base
account.save
end
def is_paid?
def paid?
if account.account_type.is_permanent_paid
true
elsif account.account_type.is_paid && account.paid_until >= Time.zone.now
@@ -176,7 +174,7 @@ class Member < ActiveRecord::Base
# Returns a hash of Flickr photosets' ids and titles
def flickr_sets
sets = Hash.new
sets = {}
flickr.photosets.getList.each do |p|
sets[p.title] = p.id
end
@@ -191,27 +189,25 @@ class Member < ActiveRecord::Base
false
end
def Member.login_name_or_email(login)
def self.login_name_or_email(login)
where(["lower(login_name) = :value OR lower(email) = :value", { value: login.downcase }])
end
def Member.case_insensitive_login_name(login)
def self.case_insensitive_login_name(login)
where(["lower(login_name) = :value", { value: login.downcase }])
end
def Member.interesting
def self.interesting
howmany = 12 # max number to find
interesting_members = []
Member.confirmed.located.recently_signed_in.each do |m|
break if interesting_members.size == howmany
if m.interesting?
interesting_members.push(m)
end
interesting_members.push(m) if m.interesting?
end
interesting_members
end
def Member.nearest_to(place)
def self.nearest_to(place)
nearby_members = []
if place
latitude, longitude = Geocoder.coordinates(place, params: { limit: 1 })
@@ -237,28 +233,26 @@ class Member < ActiveRecord::Base
end
def newsletter_subscribe(gb = Gibbon::API.new, testing = false)
return true if (Rails.env.test? && !testing)
gb.lists.subscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
})
return true if Rails.env.test? && !testing
gb.lists.subscribe(
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email },
merge_vars: { login_name: login_name },
double_optin: false # they already confirmed their email with us
)
end
def newsletter_unsubscribe(gb = Gibbon::API.new, testing = false)
return true if (Rails.env.test? && !testing)
gb.lists.unsubscribe({
id: Growstuff::Application.config.newsletter_list_id,
email: { email: email }
})
return true if Rails.env.test? && !testing
gb.lists.unsubscribe(id: Growstuff::Application.config.newsletter_list_id,
email: { email: email })
end
def already_following?(member)
self.follows.exists?(followed_id: member.id)
follows.exists?(followed_id: member.id)
end
def get_follow(member)
self.follows.find_by(followed_id: member.id) if already_following?(member)
follows.find_by(followed_id: member.id) if already_following?(member)
end
end

View File

@@ -13,14 +13,14 @@ class Notification < ActiveRecord::Base
after_create :send_email
def self.unread_count
self.unread.size
unread.size
end
def replace_blank_subject
self.subject = "(no subject)" if self.subject.nil? or self.subject =~ /^\s*$/
self.subject = "(no subject)" if subject.nil? || subject =~ /^\s*$/
end
def send_email
Notifier.notify(self).deliver_later if self.recipient.send_notification_email
Notifier.notify(self).deliver_later if recipient.send_notification_email
end
end

View File

@@ -17,7 +17,7 @@ class Order < ActiveRecord::Base
# total price of an order
def total
sum = 0
for i in order_items do
order_items.each do |i|
subtotal = i.price * i.quantity
sum += subtotal
end
@@ -28,11 +28,9 @@ class Order < ActiveRecord::Base
def activemerchant_items
items = []
order_items.each do |i|
items.push({
name: i.product.name,
quantity: i.quantity,
amount: i.price
})
items.push(name: i.product.name,
quantity: i.quantity,
amount: i.price)
end
items
end
@@ -42,7 +40,7 @@ class Order < ActiveRecord::Base
self.paypal_express_token = token
details = EXPRESS_GATEWAY.details_for(token)
self.paypal_express_payer_id = details.payer_id
self.save
save
end
# when an order is completed, we update the member's account to mark
@@ -56,35 +54,27 @@ class Order < ActiveRecord::Base
# removes whitespace and forces to uppercase (we're somewhat liberal
# in what we accept, but we clean it up anyway.)
def standardize_referral_code
self.referral_code = referral_code.upcase.gsub /\s/, '' if referral_code
self.referral_code = referral_code.upcase.gsub(/\s/, '') if referral_code
end
# search orders (used by admin/orders)
# usage: Order.search({ :by => 'member', :for => 'Skud' })
# can search by: member, order_id, paypal_token, paypal_payer_id,
def Order.search(args = {})
def self.search(args = {})
if args[:for]
case args[:by]
when "member"
member = Member.find_by(login_name: args[:for])
if member
return member.orders
end
return member.orders if member
when "order_id"
order = Order.find_by(id: args[:for])
if order
return [order]
end
return [order] if order
when "paypal_token"
order = Order.find_by(paypal_express_token: args[:for])
if order
return [order]
end
return [order] if order
when "paypal_payer_id"
order = Order.find_by(paypal_express_payer_id: args[:for])
if order
return [order]
end
return [order] if order
when "referral_code"
# coerce to uppercase
return Order.where(referral_code: args[:for].upcase)

View File

@@ -3,8 +3,7 @@ class OrderItem < ActiveRecord::Base
belongs_to :product
validate :price_must_be_greater_than_minimum
validates_uniqueness_of :order_id, message: "may only have one item."
validates :order_id, uniqueness: { message: "may only have one item." }
def price_must_be_greater_than_minimum
@product = Product.find(product_id)

View File

@@ -1,8 +1,9 @@
require_relative '../constants/photo_models.rb'
class Photo < ActiveRecord::Base
belongs_to :owner, class_name: 'Member'
Growstuff::Constants::PhotoModels.relations.each do |relation|
has_and_belongs_to_many relation.to_sym
has_and_belongs_to_many relation.to_sym # rubocop:disable Rails/HasAndBelongsToMany
end
before_destroy { all_associations.clear }
@@ -12,13 +13,13 @@ class Photo < ActiveRecord::Base
def all_associations
associations = []
Growstuff::Constants::PhotoModels.relations.each do |association_name|
associations << self.send(association_name.to_s).to_a
associations << send(association_name.to_s).to_a
end
associations.flatten!
end
def destroy_if_unused
self.destroy unless all_associations.size > 0
destroy if all_associations.empty?
end
# This is split into a side-effect free method and a side-effecting method
@@ -26,7 +27,7 @@ class Photo < ActiveRecord::Base
def flickr_metadata
flickr = owner.flickr
info = flickr.photos.getInfo(photo_id: flickr_photo_id)
licenses = flickr.photos.licenses.getInfo()
licenses = flickr.photos.licenses.getInfo
license = licenses.find { |l| l.id == info.license }
{
title: info.title || "Untitled",
@@ -39,6 +40,6 @@ class Photo < ActiveRecord::Base
end
def set_flickr_metadata
self.update_attributes(flickr_metadata)
update_attributes(flickr_metadata)
end
end

View File

@@ -6,6 +6,7 @@ class Planting < ActiveRecord::Base
belongs_to :garden
belongs_to :owner, class_name: 'Member', counter_cache: true
belongs_to :crop, counter_cache: true
has_many :harvests, -> { order(harvested_at: :desc) }, dependent: :destroy
default_scope { order("created_at desc") }
scope :finished, -> { where(finished: true) }
@@ -63,17 +64,25 @@ class Planting < ActiveRecord::Base
end
def planting_slug
"#{owner.login_name}-#{garden}-#{crop}".downcase.gsub(' ', '-')
if garden.present? && crop.present?
"#{owner.login_name}-#{garden.name}-#{crop.name}"
elsif garden.present?
"#{owner.login_name}-#{garden.name}-null"
elsif crop.present?
"#{owner.login_name}-null-#{crop.name}"
else
"#{owner.login_name}-null-null"
end.downcase.gsub(' ', '-')
end
# location = garden owner + garden name, i.e. "Skud's backyard"
def location
"#{garden.owner.login_name}'s #{garden}"
I18n.t("gardens.location", garden: garden.name, owner: garden.owner.login_name)
end
# stringify as "beet in Skud's backyard" or similar
def to_s
self.crop_name + " in " + self.location
I18n.t('plantings.string', crop: crop.name, garden: garden.name, owner: owner)
end
def default_photo

View File

@@ -4,7 +4,7 @@ class Post < ActiveRecord::Base
belongs_to :author, class_name: 'Member'
belongs_to :forum
has_many :comments, dependent: :destroy
has_and_belongs_to_many :crops
has_and_belongs_to_many :crops # rubocop:disable Rails/HasAndBelongsToMany
before_destroy { |post| post.crops.clear }
after_save :update_crops_posts_association
# also has_many notifications, but kinda meaningless to get at them
@@ -12,27 +12,26 @@ class Post < ActiveRecord::Base
after_create do
recipients = []
sender = self.author.id
self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |m|
sender = author.id
body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_REGEX) do |_m|
# find member case-insensitively and add to list of recipients
member = Member.case_insensitive_login_name($1).first
member = Member.case_insensitive_login_name(Regexp.last_match(1)).first
recipients << member if member && !recipients.include?(member)
end
self.body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_AT_REGEX) do |m|
body.scan(Haml::Filters::GrowstuffMarkdown::MEMBER_AT_REGEX) do |_m|
# find member case-insensitively and add to list of recipients
member = Member.case_insensitive_login_name($1[1..-1]).first
member = Member.case_insensitive_login_name(Regexp.last_match(1)[1..-1]).first
recipients << member if member && !recipients.include?(member)
end
# don't send notifications to yourself
recipients.map { |r| r.id }.each do |recipient|
if recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{self.author} mentioned you in their post #{self.subject}",
body: self.body,
)
end
recipients.map(&:id).each do |recipient|
next unless recipient != sender
Notification.create(
recipient_id: recipient,
sender_id: sender,
subject: "#{author} mentioned you in their post #{subject}",
body: body
)
end
end
@@ -47,22 +46,22 @@ class Post < ActiveRecord::Base
def author_date_subject
# slugs are created before created_at is set
time = created_at || Time.zone.now
"#{author.login_name} #{time.strftime("%Y%m%d")} #{subject}"
"#{author.login_name} #{time.strftime('%Y%m%d')} #{subject}"
end
def comment_count
self.comments.size
comments.size
end
# return the timestamp of the most recent activity on this post
# i.e. the time of the most recent comment, or of the post itself if
# there are no comments.
def recent_activity
self.comments.present? ? self.comments.reorder('created_at DESC').first.created_at : self.created_at
comments.present? ? comments.reorder('created_at DESC').first.created_at : created_at
end
# return posts sorted by recent activity
def Post.recently_active
def self.recently_active
Post.all.sort do |a, b|
b.recent_activity <=> a.recent_activity
end
@@ -71,13 +70,13 @@ class Post < ActiveRecord::Base
private
def update_crops_posts_association
self.crops.destroy_all
crops.destroy_all
# look for crops mentioned in the post. eg. [tomato](crop)
self.body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |m|
body.scan(Haml::Filters::GrowstuffMarkdown::CROP_REGEX) do |_m|
# find crop case-insensitively
crop = Crop.case_insensitive_name($1).first
crop = Crop.case_insensitive_name(Regexp.last_match(1)).first
# create association
self.crops << crop if crop && !self.crops.include?(crop)
crops << crop if crop && !crops.include?(crop)
end
end
end

View File

@@ -1,11 +1,12 @@
class Product < ActiveRecord::Base
has_and_belongs_to_many :orders
has_and_belongs_to_many :orders # rubocop:disable Rails/HasAndBelongsToMany
belongs_to :account_type
validates :paid_months,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
def to_s

View File

@@ -2,7 +2,7 @@ class Role < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: [:slugged, :finders]
has_and_belongs_to_many :members
has_and_belongs_to_many :members # rubocop:disable Rails/HasAndBelongsToMany
class << self
[:crop_wranglers, :admins].each do |method|

View File

@@ -14,22 +14,25 @@ class Seed < ActiveRecord::Base
validates :quantity,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
validates :days_until_maturity_min,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
validates :days_until_maturity_max,
numericality: {
only_integer: true,
greater_than_or_equal_to: 0 },
greater_than_or_equal_to: 0
},
allow_nil: true
scope :tradable, -> { where("tradable_to != 'nowhere'") }
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally)
TRADABLE_TO_VALUES = %w(nowhere locally nationally internationally).freeze
validates :tradable_to, inclusion: { in: TRADABLE_TO_VALUES,
message: "You may only trade seed nowhere, "\
"locally, nationally, or internationally" },
@@ -40,7 +43,8 @@ class Seed < ActiveRecord::Base
'certified organic',
'non-certified organic',
'conventional/non-organic',
'unknown']
'unknown'
].freeze
validates :organic, inclusion: { in: ORGANIC_VALUES,
message: "You must say whether the seeds "\
"are organic or not, or that you don't know" },
@@ -51,21 +55,22 @@ class Seed < ActiveRecord::Base
'certified GMO-free',
'non-certified GMO-free',
'GMO',
'unknown']
'unknown'
].freeze
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)
HEIRLOOM_VALUES = %w(heirloom hybrid unknown).freeze
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'
if tradable_to == 'nowhere'
false
else
true
@@ -81,21 +86,23 @@ class Seed < ActiveRecord::Base
# Seed.interesting
# returns a list of interesting seeds, for use on the homepage etc
def Seed.interesting
def self.interesting
howmany = 12 # max number to find
interesting_seeds = []
Seed.tradable.each do |s|
break if interesting_seeds.size == howmany
if s.interesting?
interesting_seeds.push(s)
end
interesting_seeds.push(s) if s.interesting?
end
interesting_seeds
end
def seed_slug
"#{owner.login_name}-#{crop}".downcase.gsub(' ', '-')
"#{owner.login_name}-#{crop}".downcase.tr(' ', '-')
end
def to_s
I18n.t('seeds.string', crop: crop.name, owner: owner)
end
end

View File

@@ -1,7 +1,7 @@
.panel.panel-success
.panel-heading
%h3.panel-title
= link_to "#{garden.owner.login_name}'s garden", garden
= link_to display_garden_name(garden), garden
- if can? :edit, garden
%a.pull-right{:href => edit_garden_path(garden), :role => "button", :id => "edit_garden_glyphicon"}
%span.glyphicon.glyphicon-pencil{:title => "Edit"}
@@ -12,7 +12,7 @@
.col-md-8
%dl.dl-horizontal
%dt Name :
%dd= link_to garden.name, garden
%dd= link_to display_garden_name(garden), garden
%dt Location :
%dd
- if garden.location.blank?

View File

@@ -10,13 +10,22 @@
.form-group.required
= f.label :crop, 'What did you harvest?', :class => 'control-label col-md-2'
.col-md-4
= auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop
- if @planting
.col-md-8
= link_to @planting.crop.name, planting_path(@planting)
from
= link_to @planting.garden.name, garden_path(@planting.garden)
= f.hidden_field :planting_id, value: @planting.id
- else
.col-md-4
= auto_suggest @harvest, :crop, :class => 'form-control col-md-2', :default => @crop
.col-md-4
= collection_select(:harvest, :plant_part_id, PlantPart.all, :id, :name, { :selected => @harvest.plant_part_id }, { :class => 'form-control', :prompt => 'e.g. fruit', :required => "required" })
%span.help-block.col-md-8
Can't find what you're looking for?
= link_to "Request new crops.", new_crop_path
- unless @planting
%span.help-block.col-md-8
Can't find what you're looking for?
= link_to "Request new crops.", new_crop_path
.form-group
= f.label :harvested_at, 'When?', :class => 'control-label col-md-2'

View File

@@ -24,6 +24,11 @@
%p
%b Harvested:
= @harvest.harvested_at ? @harvest.harvested_at : "not specified"
- if @planting
%p
%b Garden:
= link_to @planting.garden, garden_path(@planting.garden)
%p
%b Quantity:
= display_quantity(@harvest)

View File

@@ -67,11 +67,11 @@
= link_to(t('.inbox_unread', unread_count: current_member.notifications.unread_count), notifications_path)
- else
= link_to(t('.inbox'), notifications_path)
- if current_member.has_role?(:crop_wrangler) || current_member.has_role?(:admin)
- if current_member.role?(:crop_wrangler) || current_member.role?(:admin)
%li{:class => 'divider', :role => 'presentation'}
- if current_member.has_role?(:crop_wrangler)
- if current_member.role?(:crop_wrangler)
%li= link_to t('.crop_wrangling'), wrangle_crops_path
- if current_member.has_role?(:admin)
- if current_member.role?(:admin)
%li= link_to t('.admin'), admin_path

View File

@@ -16,9 +16,9 @@
%p
%strong Member Roles:
%br
- if member.has_role? :admin
- if member.role? :admin
Administrator
- if member.has_role? :crop_wrangler
- if member.role? :crop_wrangler
Crop Wrangler
- else
Member

View File

@@ -5,7 +5,7 @@
- member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
= link_to display_garden_name(g), "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == member
%li.navbar-right
= link_to new_garden_path, class: 'btn' do

View File

@@ -10,7 +10,7 @@
- content_for :buttonbar do
- if can? :update, @member
= link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default'
- if @member == current_member && !@member.is_paid?
- if @member == current_member && !@member.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'

View File

@@ -22,7 +22,7 @@
%strong Referral code:
= @order.referral_code
- if current_member.has_role? :admin
- if current_member.role? :admin
%p
%strong Paypal Express token:
= @order.paypal_express_token

View File

@@ -26,19 +26,17 @@
%p= link_to 'Delete Photo', @photo, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
.col-md-6
- if @photo.plantings.size > 0 or @photo.harvests.size > 0 or @photo.gardens.size > 0
- unless @photo.plantings.empty? && @photo.harvests.empty? && @photo.gardens.empty? && @photo.seeds.empty?
%p This photo depicts:
%ul
- if @photo.plantings.size > 0
- @photo.plantings.each do |p|
%li= link_to t('.thing_by', thing: Planting.model_name.singular, owner: p.owner), p
- if @photo.harvests.size > 0
- @photo.harvests.each do |h|
%li= link_to t('.thing_by', thing: Harvest.model_name.singular, owner: h.owner), h
- if @photo.gardens.size > 0
- @photo.gardens.each do |g|
%li= link_to t('.thing_by', thing: Garden.model_name.singular, owner: g.owner), g
- @photo.plantings.each do |p|
%li= link_to t('.planting', planting: p.to_s, owner: p.owner.to_s), planting_path(p)
- @photo.harvests.each do |h|
%li= link_to t('.harvest', crop: h.crop.name, owner: h.owner.to_s), harvest_path(h)
- @photo.gardens.each do |g|
%li= link_to t('.garden', garden: g.to_s, owner: g.owner.to_s), garden_path(g)
- @photo.seeds.each do |s|
%li= link_to t('.seed', seed: s.to_s, owner: s.owner.to_s), seed_path(s)
.row
.col-md-12

View File

@@ -8,7 +8,7 @@
in
= succeed "'s" do
= link_to p.garden.owner, p.garden.owner
= link_to p.garden, p.garden
= link_to display_garden_name(p.garden), p.garden
%br/
%small
%i

View File

@@ -0,0 +1,22 @@
- content_for :buttonbar do
- if current_member
= link_to 'My Plantings', plantings_by_owner_path(owner: current_member.slug), class: 'btn btn-default'
- if owner && owner != current_member
= link_to "#{owner.login_name}'s Plantings", plantings_by_owner_path(owner: owner.slug), class: 'btn btn-default'
= link_to "Everyone's plantings", plantings_path, :class => 'btn btn-default'
- if owner
- path = plantings_by_owner_path(owner: @owner.slug, all: show_all ? '' : 1)
- else
- path = plantings_path(all: show_all ? '' : 1)
= link_to path do
= check_box_tag 'active', 'all', show_all
include in-active
- if current_member
- if can? :create, Planting
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" }

View File

@@ -0,0 +1,9 @@
Harvests:
- if planting.harvests
%ul
- planting.harvests.each do |harvest|
%li
= harvest.harvested_at ? harvest.harvested_at : "undated"
= link_to harvest, harvest_path(harvest)
- else
= "none"

View File

@@ -29,6 +29,8 @@
%li= link_to 'Details', planting, :class => 'btn btn-default btn-xs'
- if can? :edit, planting
%li= link_to 'Edit', edit_planting_path(planting), :class => 'btn btn-default btn-xs'
- if can? :create, Harvest
%li= link_to 'Harvest', new_planting_harvest_path(planting), :class => 'btn btn-default btn-xs'
- if ! planting.finished
%li= link_to "Mark as finished", planting_path(planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :destroy, planting
@@ -42,3 +44,5 @@
.col-xs-12.col-md-8
= render partial: 'plantings/planting_progress', locals: {planting: planting}
.col-xs-12.col-md-8
= render partial: 'plantings/planting_harvest', locals: {planting: planting}

View File

@@ -1,21 +1,10 @@
- content_for :title, @owner ? t('.title.owner_plantings', owner: @owner) : @crop ? t('.title.crop_plantings', crop: @crop.name) : t('.title.default')
= render 'nav', owner: @owner, show_all: @show_all
- if @owner
= link_to "View #{@owner}'s profile >>", member_path(@owner)
%p
- if can? :create, Planting
- if @owner
%p
- if @owner == current_member
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
= link_to "View everyone's plantings", plantings_path, :class => 'btn btn-default'
- else # everyone's plantings
= link_to 'Plant something', new_planting_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your plantings', plantings_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track what you've planted" }
%div.pagination
= page_entries_info @plantings
= will_paginate @plantings

View File

@@ -48,8 +48,8 @@
%dt Finished:
%dd= "#{display_finished(@planting)}"
%p
= render 'planting_progress', planting: @planting
%p= render 'plantings/planting_harvest', planting: @planting
%p= render 'planting_progress', planting: @planting
- if can? :edit, @planting or can? :destroy, @planting
%p
@@ -57,6 +57,8 @@
=link_to 'Edit', edit_planting_path(@planting), :class => 'btn btn-default btn-xs'
- if ! @planting.finished
= link_to "Mark as finished", planting_path(@planting, :planting => {:finished => 1}), :method => :put, :class => 'btn btn-default btn-xs append-date'
- if can? :create, Harvest
= link_to 'Harvest', new_planting_harvest_path(@planting), :class => 'btn btn-default btn-xs'
- if can? :destroy, @planting
=link_to 'Delete', @planting, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

@@ -9,5 +9,5 @@
%strong Paid until:
= current_member.account.paid_until_string
- if !current_member.is_paid?
- if !current_member.paid?
= link_to "Upgrade and support #{ENV['GROWSTUFF_SITE_NAME']}", shop_path, :class => 'btn btn-primary'

View File

@@ -19,7 +19,7 @@
source, open data platform supporting home food growers and promoting
sustainable food systems!
- if current_member && current_member.is_paid?
- if current_member && current_member.paid?
%h2 Thank you for supporting Growstuff
%p You currently have a paid membership, and can't buy another one at this time.

View File

@@ -112,17 +112,15 @@ end
OmniAuth.config.test_mode = true
# Fake the omniauth
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
}
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new(provider: 'facebook',
uid: '123545',
info: {
name: "John Testerson",
nickname: 'JohnnyT',
email: 'example.oauth.facebook@example.com',
image: 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
credentials: {
token: "token",
secret: "donttell"
})

View File

@@ -95,7 +95,7 @@ end
module CmsDeviseAuth
def authenticate
return if current_member && current_member.has_role?(:admin)
return if current_member && current_member.role?(:admin)
redirect_to root_path, alert: 'Permission denied. Please sign in as an admin user to use the CMS admin area.'
end
end

View File

@@ -1,5 +1,11 @@
---
en:
account:
update: Account detail was successfully updated.
account_types:
created: Account type was successfully created.
deleted: Account type was successfully deleted.
updated: Account type was successfully updated.
activerecord:
models:
comment:
@@ -42,23 +48,24 @@ en:
index:
title: Forums
gardens:
created: Garden was successfully created.
deleted: Garden was successfully deleted.
form:
location_helper: If you have a location set in your profile, it will be used when you create a new garden.
forums:
index:
title: Forums
location: "%{owner}'s %{garden}"
updated: Garden was successfully updated.
harvests:
created: Harvest was successfully created.
index:
title:
crop_harvests: Everyone's %{crop} harvests
default: Everyone's harvests
owner_harvests: "%{owner} harvests"
updated: Harvest was successfully updated.
home:
blurb:
already_html: Or %{sign_in} if you already have an account
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."
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_in_linktext: sign in
sign_up: Sign up
@@ -86,24 +93,14 @@ en:
api_docs_linktext: API documentation
buy_account_linktext: buying a paid account
creative_commons_linktext: Creative Commons license
get_involved_body_html: We believe in collaboration, and work closely with our
members and the wider food-growing community. Our team includes volunteers
from all walks of life and all skill levels. To get involved, visit %{talk_link}
or find more information on the %{wiki_link}.
get_involved_body_html: We believe in collaboration, and work closely with our members and the wider food-growing community. Our team includes volunteers from all walks of life and all skill levels. To get involved, visit %{talk_link} or find more information on the %{wiki_link}.
get_involved_title: Get Involved
github_linktext: Github
open_data_body_html: We're building a database of crops, planting advice, seed
sources, and other information that anyone can use for free, under a %{creative_commons_link}.
You can use this data for research, to build apps, or for any purpose at all. Read
more about our %{wiki_link} and %{api_docs_link}.
open_data_body_html: We're building a database of crops, planting advice, seed sources, and other information that anyone can use for free, under a %{creative_commons_link}. You can use this data for research, to build apps, or for any purpose at all. Read more about our %{wiki_link} and %{api_docs_link}.
open_data_title: Open Data and APIs
open_source_body_html: "%{site_name} is open source software, which means that
we share this website's code for free with our community and the world. We
believe that openness, sustainability, and social good go hand in hand. You
can read more about %{why} or check out our code on %{github}."
open_source_body_html: "%{site_name} is open source software, which means that we share this website's code for free with our community and the world. We believe that openness, sustainability, and social good go hand in hand. You can read more about %{why} or check out our code on %{github}."
open_source_title: Open Source
support_body_html: Growstuff is independent, %{ad_free} and we have no outside
investment. You can support our work by %{buy_account}.
support_body_html: Growstuff is independent, %{ad_free} and we have no outside investment. You can support our work by %{buy_account}.
support_title: Support Growstuff
talk_linktext: Growstuff Talk
why_linktext: why Growstuff is open source
@@ -120,8 +117,7 @@ en:
view_all: View all seeds
stats:
member_linktext: "%{count} members"
message_html: So far, %{member} have planted %{number_crops} %{number_plantings}
in %{number_gardens}.
message_html: So far, %{member} have planted %{number_crops} %{number_plantings} in %{number_gardens}.
number_crops_linktext: "%{count} crops"
number_gardens_linktext: "%{count} gardens"
number_plantings_linktext: "%{count} times"
@@ -131,10 +127,14 @@ en:
admin: Admin
browse_crops: Browse Crops
browse_members: Browse Members
community: Community
community_map: Community Map
crop_wrangling: Crop Wrangling
crops: Crops
current_memberlogin_name: '%{current_memberlogin_name}'
forums: Forums
gardens: Gardens
harvest: Harvest
harvests: Harvests
inbox: Inbox
inbox_unread: Inbox (%{unread_count})
@@ -142,26 +142,34 @@ en:
posts: Posts
profile: Profile
seeds: Seeds
sign_in: Sign in
sign_out: Sign out
sign_up: Sign up
skip: Skip navigation menu
support_growstuff: Support Growstuff
your_stuff: Your Stuff (%{unread_count})
toggle_navigation: Toggle Navigation
crops: Crops
community: Community
current_memberlogin_name: '"%{current_memberlogin_name}"'
sign_out: Sign out
sign_in: Sign in
sign_up: Sign up
your_stuff: Your Stuff (%{unread_count})
members:
index:
title: "%{site_name} members"
signup:
error: Failed to complete signup
unsubscribe:
error: We're sorry, there was an error updating your settings.
unsubscribed: You have been unsubscribed from %{email_type} emails.
welcome: Welcome
photos:
show:
thing_by: A %{thing} by %{owner}
garden: "garden named \"%{garden}\" by %{owner}"
harvest: "%{crop} harvest by %{owner}"
planting: "%{planting}"
seed: "%{seed}"
places:
index:
title: "%{site_name} Community Map"
plantings:
string: "%{crop} planting in %{garden} by %{owner}"
form:
finish_helper: A planting is finished when you've harvested all of the crop, or it dies, or it's otherwise no longer growing in your garden.
index:
@@ -175,6 +183,7 @@ en:
author_posts: "%{author} posts"
default: Everyone's posts
seeds:
string: "%{crop} seeds belonging to %{owner}"
form:
trade_help: Are you interested in trading or swapping seeds with other %{site_name} members? If you list your seeds as available for trade, other members can contact you to request seeds. You can list any conditions or other information in the description, above.
index:

View File

@@ -1,4 +1,4 @@
Growstuff::Application.routes.draw do # rubocop:disable Metrics/BlockLength
Growstuff::Application.routes.draw do
get '/robots.txt' => 'robots#robots'
resources :plant_parts
@@ -20,7 +20,9 @@ Growstuff::Application.routes.draw do # rubocop:disable Metrics/BlockLength
resources :authentications, only: [:create, :destroy]
resources :plantings
resources :plantings do
resources :harvests
end
get '/plantings/owner/:owner' => 'plantings#index', :as => 'plantings_by_owner'
get '/plantings/crop/:crop' => 'plantings#index', :as => 'plantings_by_crop'

View File

@@ -0,0 +1,5 @@
class AddPlantingRefToHarvests < ActiveRecord::Migration
def change
add_reference :harvests, :planting, index: true, foreign_key: true
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161201154922) do
ActiveRecord::Schema.define(version: 20170104035248) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -265,8 +265,11 @@ ActiveRecord::Schema.define(version: 20161201154922) do
t.string "weight_unit"
t.integer "plant_part_id"
t.float "si_weight"
t.integer "planting_id"
end
add_index "harvests", ["planting_id"], name: "index_harvests_on_planting_id", using: :btree
create_table "harvests_photos", id: false, force: :cascade do |t|
t.integer "photo_id"
t.integer "harvest_id"
@@ -467,4 +470,5 @@ ActiveRecord::Schema.define(version: 20161201154922) do
add_index "seeds", ["slug"], name: "index_seeds_on_slug", unique: true, using: :btree
add_foreign_key "harvests", "plantings"
end

View File

@@ -18,12 +18,12 @@ describe Admin::OrdersController do
describe "GET search" do
it "assigns @orders" do
order = FactoryGirl.create(:order)
get :search, { search_by: 'order_id', search_text: order.id }
get :search, search_by: 'order_id', search_text: order.id
assigns(:orders).should eq([order])
end
it "sets an error message if nothing found" do
get :search, { search_by: 'order_id', search_text: 'foo' }
get :search, search_by: 'order_id', search_text: 'foo'
flash[:alert].should match /Couldn't find order with/
end
end

View File

@@ -36,14 +36,14 @@ describe CommentsController do
describe "GET new" do
it "picks up post from params" do
post = FactoryGirl.create(:post)
get :new, { post_id: post.id }
get :new, post_id: post.id
assigns(:post).should eq(post)
end
it "assigns the old comments as @comments" do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
get :new, { post_id: post.id }
get :new, post_id: post.id
assigns(:comments).should eq [old_comment]
end
@@ -58,7 +58,7 @@ describe CommentsController do
post = FactoryGirl.create(:post)
old_comment = FactoryGirl.create(:comment, post: post)
comment = FactoryGirl.create(:comment, post: post, author: @member)
get :edit, { id: comment.to_param }
get :edit, id: comment.to_param
assigns(:comments).should eq([comment, old_comment])
end
end
@@ -67,7 +67,7 @@ describe CommentsController do
describe "with valid params" do
it "redirects to the comment's post" do
comment = Comment.create! valid_attributes
put :update, { id: comment.to_param, comment: valid_attributes }
put :update, id: comment.to_param, comment: valid_attributes
response.should redirect_to(comment.post)
end
end
@@ -77,7 +77,7 @@ describe CommentsController do
it "redirects to the post the comment was on" do
comment = Comment.create! valid_attributes
post = comment.post
delete :destroy, { id: comment.to_param }
delete :destroy, id: comment.to_param
response.should redirect_to(post)
end
end

View File

@@ -12,11 +12,72 @@
require 'rails_helper'
describe GardensController do
login_member
RSpec.describe GardensController, type: :controller do
include Devise::Test::ControllerHelpers
let(:valid_params) { { name: 'My second Garden' } }
def valid_attributes
member = FactoryGirl.create(:member)
{ name: 'My Garden', owner_id: member.id }
context "when not signed in" do
let(:garden) { double('garden') }
describe 'GET new' do
before { get :new, id: garden.to_param }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'PUT create' do
before { put :create, garden: valid_params }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'changing existing records' do
before do
allow(Garden).to receive(:find).and_return(:garden)
expect(garden).not_to receive(:save)
expect(garden).not_to receive(:save!)
expect(garden).not_to receive(:update)
expect(garden).not_to receive(:update!)
expect(garden).not_to receive(:destroy)
end
describe 'GET edit' do
before { get :edit, id: garden.to_param }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'POST update' do
before { post :update, id: garden.to_param, garden: valid_params }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'DELETE' do
before { delete :destroy, id: garden.to_param, params: { garden: valid_params } }
it { expect(response).to redirect_to(new_member_session_path) }
end
end
end
context "when signed in" do
before(:each) { sign_in member }
let!(:member) { FactoryGirl.create(:member) }
describe "for another member's garden" do
let(:not_my_garden) { double('garden') }
before do
expect(Garden).to receive(:find).and_return(:not_my_garden)
expect(not_my_garden).not_to receive(:save)
expect(not_my_garden).not_to receive(:save!)
expect(not_my_garden).not_to receive(:update)
expect(not_my_garden).not_to receive(:update!)
expect(not_my_garden).not_to receive(:destroy)
end
describe 'GET edit' do
before { get :edit, id: not_my_garden.to_param }
it { expect(response).to redirect_to(root_path) }
end
describe 'POST update' do
before { post :update, id: not_my_garden.to_param, garden: valid_params }
it { expect(response).to redirect_to(root_path) }
end
describe 'DELETE' do
before { delete :destroy, id: not_my_garden.to_param, params: { garden: valid_params } }
it { expect(response).to redirect_to(root_path) }
end
end
end
end

View File

@@ -39,19 +39,19 @@ describe HarvestsController do
end
it "picks up owner from params and shows owner's harvests only" do
get :index, { owner: @member1.slug }
get :index, owner: @member1.slug
assigns(:owner).should eq @member1
assigns(:harvests).should eq [@harvest1]
end
it "picks up crop from params and shows the harvests for the crop only" do
get :index, { crop: @maize.name }
get :index, crop: @maize.name
assigns(:crop).should eq @maize
assigns(:harvests).should eq [@harvest2]
end
it "generates a csv" do
get :index, { format: "csv" }
get :index, format: "csv"
response.status.should eq 200
end
end
@@ -59,7 +59,7 @@ describe HarvestsController do
describe "GET show" do
it "assigns the requested harvest as @harvest" do
harvest = Harvest.create! valid_attributes
get :show, { id: harvest.to_param }
get :show, id: harvest.to_param
assigns(:harvest).should eq(harvest)
end
end
@@ -74,7 +74,7 @@ describe HarvestsController do
describe "GET edit" do
it "assigns the requested harvest as @harvest" do
harvest = Harvest.create! valid_attributes
get :edit, { id: harvest.to_param }
get :edit, id: harvest.to_param
assigns(:harvest).should eq(harvest)
end
end
@@ -83,37 +83,52 @@ describe HarvestsController do
describe "with valid params" do
it "creates a new Harvest" do
expect {
post :create, { harvest: valid_attributes }
post :create, harvest: valid_attributes
}.to change(Harvest, :count).by(1)
end
it "assigns a newly created harvest as @harvest" do
post :create, { harvest: valid_attributes }
post :create, harvest: valid_attributes
assigns(:harvest).should be_a(Harvest)
assigns(:harvest).should be_persisted
end
it "redirects to the created harvest" do
post :create, { harvest: valid_attributes }
post :create, harvest: valid_attributes
response.should redirect_to(Harvest.last)
end
it "links to planting" do
planting = FactoryGirl.create(:planting, owner_id: member.id)
post :create, harvest: valid_attributes.merge(planting_id: planting.id)
expect(Harvest.last.planting.id).to eq(planting.id)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved harvest as @harvest" do
# Trigger the behavior that occurs when invalid params are submitted
Harvest.any_instance.stub(:save).and_return(false)
post :create, { harvest: { "crop_id" => "invalid value" } }
post :create, harvest: { "crop_id" => "invalid value" }
assigns(:harvest).should be_a_new(Harvest)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
Harvest.any_instance.stub(:save).and_return(false)
post :create, { harvest: { "crop_id" => "invalid value" } }
post :create, harvest: { "crop_id" => "invalid value" }
response.should render_template("new")
end
end
describe "not my planting" do
let(:not_my_planting) { FactoryGirl.create(:planting) }
let(:harvest) { FactoryGirl.create(:harvest) }
it "does not save planting_id" do
allow(Harvest).to receive(:new).and_return(harvest)
post :create, harvest: valid_attributes.merge(planting_id: not_my_planting.id)
expect(harvest.planting_id).to eq(nil)
end
end
end
describe "PUT update" do
@@ -124,19 +139,19 @@ describe HarvestsController do
# specifies that the Harvest created on the previous line
# receives the :update message with whatever params are
# submitted in the request.
Harvest.any_instance.should_receive(:update).with({ "crop_id" => "1" })
put :update, { id: harvest.to_param, harvest: { "crop_id" => "1" } }
Harvest.any_instance.should_receive(:update).with("crop_id" => "1", "owner_id": member.id)
put :update, id: harvest.to_param, harvest: { "crop_id" => "1" }
end
it "assigns the requested harvest as @harvest" do
harvest = Harvest.create! valid_attributes
put :update, { id: harvest.to_param, harvest: valid_attributes }
put :update, id: harvest.to_param, harvest: valid_attributes
assigns(:harvest).should eq(harvest)
end
it "redirects to the harvest" do
harvest = Harvest.create! valid_attributes
put :update, { id: harvest.to_param, harvest: valid_attributes }
put :update, id: harvest.to_param, harvest: valid_attributes
response.should redirect_to(harvest)
end
end
@@ -146,7 +161,7 @@ describe HarvestsController do
harvest = Harvest.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Harvest.any_instance.stub(:save).and_return(false)
put :update, { id: harvest.to_param, harvest: { "crop_id" => "invalid value" } }
put :update, id: harvest.to_param, harvest: { "crop_id" => "invalid value" }
assigns(:harvest).should eq(harvest)
end
@@ -154,23 +169,32 @@ describe HarvestsController do
harvest = Harvest.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Harvest.any_instance.stub(:save).and_return(false)
put :update, { id: harvest.to_param, harvest: { "crop_id" => "invalid value" } }
put :update, id: harvest.to_param, harvest: { "crop_id" => "invalid value" }
response.should render_template("edit")
end
end
describe "not my planting" do
let(:not_my_planting) { FactoryGirl.create(:planting) }
let(:harvest) { FactoryGirl.create(:harvest) }
it "does not save planting_id" do
allow(Harvest).to receive(:new).and_return(harvest)
put :update, id: harvest.to_param, harvest: valid_attributes.merge(planting_id: not_my_planting.id)
expect(harvest.planting_id).to eq(nil)
end
end
end
describe "DELETE destroy" do
it "destroys the requested harvest" do
harvest = Harvest.create! valid_attributes
expect {
delete :destroy, { id: harvest.to_param }
delete :destroy, id: harvest.to_param
}.to change(Harvest, :count).by(-1)
end
it "redirects to the harvests list" do
harvest = Harvest.create! valid_attributes
delete :destroy, { id: harvest.to_param }
delete :destroy, id: harvest.to_param
response.should redirect_to(harvests_url)
end
end

View File

@@ -36,38 +36,38 @@ describe MembersController do
describe "GET show" do
it "provides JSON for member profile" do
get :show, { id: @member.id, format: 'json' }
get :show, id: @member.id, format: 'json'
response.should be_success
end
it "assigns @posts with the member's posts" do
get :show, { id: @member.id }
get :show, id: @member.id
assigns(:posts).should eq(@posts)
end
it "assigns @twitter_auth" do
get :show, { id: @member.id }
get :show, id: @member.id
assigns(:twitter_auth).should eq(@twitter_auth)
end
it "assigns @flickr_auth" do
get :show, { id: @member.id }
get :show, id: @member.id
assigns(:flickr_auth).should eq(@flickr_auth)
end
it "doesn't show completely nonsense members" do
lambda { get :show, { id: 9999 } }.should raise_error(ActiveRecord::RecordNotFound)
lambda { get :show, id: 9999 }.should raise_error(ActiveRecord::RecordNotFound)
end
it "doesn't show unconfirmed members" do
@member2 = FactoryGirl.create(:unconfirmed_member)
lambda { get :show, { id: @member2.id } }.should raise_error(ActiveRecord::RecordNotFound)
lambda { get :show, id: @member2.id }.should raise_error(ActiveRecord::RecordNotFound)
end
end
describe "GET member's RSS feed" do
it "returns an RSS feed" do
get :show, { id: @member.to_param, format: "rss" }
get :show, id: @member.to_param, format: "rss"
response.should be_success
response.should render_template("members/show")
response.content_type.should eq("application/rss+xml")

View File

@@ -51,14 +51,14 @@ describe NotificationsController do
describe "GET show" do
it "assigns the requested notification as @notification" do
notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id)
get :show, { id: notification.to_param }
get :show, id: notification.to_param
assigns(:notification).should eq(notification)
end
it "assigns the reply link for a post comment" do
notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id)
get :show, { id: notification.to_param }
get :show, id: notification.to_param
assigns(:reply_link).should_not be_nil
assigns(:reply_link).should eq new_comment_url(
post_id: notification.post.id
@@ -67,7 +67,7 @@ describe NotificationsController do
it "marks notifications as read" do
notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id)
get :show, { id: notification.to_param }
get :show, id: notification.to_param
# we need to fetch it from the db again, can't test against the old one
n = Notification.find(notification.id)
n.read.should eq true
@@ -77,7 +77,7 @@ describe NotificationsController do
describe "GET reply" do
it "marks notifications as read" do
notification = FactoryGirl.create(:notification, recipient_id: subject.current_member.id)
get :reply, { id: notification.to_param }
get :reply, id: notification.to_param
# we need to fetch it from the db again, can't test against the old one
n = Notification.find(notification.id)
n.read.should eq true
@@ -87,7 +87,7 @@ describe NotificationsController do
describe "GET new" do
it "assigns a recipient" do
@recipient = FactoryGirl.create(:member)
get :new, { recipient_id: @recipient.id }
get :new, recipient_id: @recipient.id
assigns(:recipient).should be_an_instance_of(Member)
end
end
@@ -96,7 +96,7 @@ describe NotificationsController do
describe "with valid params" do
it "redirects to the recipient's profile" do
@recipient = FactoryGirl.create(:member)
post :create, { notification: { recipient_id: @recipient.id, subject: 'foo' } }
post :create, notification: { recipient_id: @recipient.id, subject: 'foo' }
response.should redirect_to(notifications_path)
end
end

View File

@@ -30,11 +30,11 @@ describe OrderItemsController do
describe "POST create" do
it "redirects to order" do
@order = FactoryGirl.create(:order, member: @member)
post :create, { order_item: {
post :create, order_item: {
order_id: @order.id,
product_id: @product.id,
price: @product.min_price
} }
}
response.should redirect_to(OrderItem.last.order)
end
@@ -43,10 +43,10 @@ describe OrderItemsController do
sign_in @member
@product = FactoryGirl.create(:product)
expect {
post :create, { order_item: {
post :create, order_item: {
product_id: @product.id,
price: @product.min_price
} }
}
}.to change(Order, :count).by(1)
OrderItem.last.order.should be_an_instance_of Order
end
@@ -56,11 +56,11 @@ describe OrderItemsController do
@order = FactoryGirl.create(:order, member: @member)
@product = FactoryGirl.create(:product, min_price: 1)
expect {
post :create, { order_item: {
post :create, order_item: {
order_id: @order.id,
product_id: @product.id,
price: 3.33
} }
}
}.to change(OrderItem, :count).by(1)
OrderItem.last.price.should eq 333
end

View File

@@ -28,7 +28,7 @@ describe OrdersController do
member = FactoryGirl.create(:member)
sign_in member
order = Order.create!(member_id: member.id)
get :checkout, { id: order.to_param, referral_code: 'FOOBAR' }
get :checkout, id: order.to_param, referral_code: 'FOOBAR'
order.reload
order.referral_code.should eq 'FOOBAR'
end
@@ -37,7 +37,7 @@ describe OrdersController do
member = FactoryGirl.create(:member)
sign_in member
order = Order.create!(member_id: member.id)
get :checkout, { id: order.to_param }
get :checkout, id: order.to_param
response.status.should eq 302
response.redirect_url.should match /paypal\.com/
end
@@ -48,7 +48,7 @@ describe OrdersController do
member = FactoryGirl.create(:member)
sign_in member
order = Order.create!(member_id: member.id)
get :complete, { id: order.to_param }
get :complete, id: order.to_param
assigns(:order).should eq(order)
end
end
@@ -58,7 +58,7 @@ describe OrdersController do
member = FactoryGirl.create(:member)
sign_in member
order = Order.create!(member_id: member.id)
delete :destroy, { id: order.id }
delete :destroy, id: order.id
response.should redirect_to(shop_url)
end
end

View File

@@ -24,19 +24,19 @@ describe PlacesController do
end
it "assigns place name" do
get :show, { place: @member_london.location }
get :show, place: @member_london.location
assigns(:place).should eq @member_london.location
end
it "assigns nearby members" do
get :show, { place: @member_london.location }
get :show, place: @member_london.location
assigns(:nearby_members).should eq [@member_london, @member_south_pole]
end
end
describe "GET search" do
it "redirects to the new place" do
get :search, { new_place: "foo" }
get :search, new_place: "foo"
response.should redirect_to place_path("foo")
end
end

View File

@@ -38,13 +38,13 @@ describe PlantingsController do
end
it "picks up owner from params and shows owner's plantings only" do
get :index, { owner: @member1.slug }
get :index, owner: @member1.slug
assigns(:owner).should eq @member1
assigns(:plantings).should eq [@planting1]
end
it "picks up crop from params and shows the plantings for the crop only" do
get :index, { crop: @maize.name }
get :index, crop: @maize.name
assigns(:crop).should eq @maize
assigns(:plantings).should eq [@planting2]
end
@@ -53,7 +53,7 @@ describe PlantingsController do
describe "GET new" do
it "picks up crop from params" do
crop = FactoryGirl.create(:crop)
get :new, { crop_id: crop.id }
get :new, crop_id: crop.id
assigns(:crop).should eq(crop)
end
@@ -65,7 +65,7 @@ describe PlantingsController do
it "picks up garden from params" do
member = FactoryGirl.create(:member)
garden = FactoryGirl.create(:garden, owner: member)
get :new, { garden_id: garden.id }
get :new, garden_id: garden.id
assigns(:garden).should eq(garden)
end
@@ -80,7 +80,7 @@ describe PlantingsController do
end
it "sets the owner automatically" do
post :create, { planting: valid_attributes }
post :create, planting: valid_attributes
assigns(:planting).owner.should eq subject.current_member
end
end

View File

@@ -32,7 +32,7 @@ describe PostsController do
describe "GET RSS feed for individual post" do
it "returns an RSS feed" do
post = Post.create! valid_attributes
get :show, { format: "rss", id: post.slug }
get :show, format: "rss", id: post.slug
response.should be_success
response.should render_template("posts/show")
response.content_type.should eq("application/rss+xml")

View File

@@ -25,7 +25,7 @@ describe ScientificNamesController do
describe "GET new" do
it "assigns crop if specified" do
get :new, { crop_id: 1 }
get :new, crop_id: 1
assigns(:crop).should be_an_instance_of Crop
end
end

View File

@@ -16,7 +16,7 @@ describe SeedsController do
describe "GET index" do
it "picks up owner from params" do
owner = FactoryGirl.create(:member)
get :index, { owner: owner.slug }
get :index, owner: owner.slug
assigns(:owner).should eq(owner)
end
end

View File

@@ -14,7 +14,8 @@ feature "show photo page" do
scenario "shows linkback to planting" do
planting.photos << photo
visit photo_path(photo)
expect(page).to have_link "A planting by #{planting.owner}", href: planting_path(planting)
expect(page).to have_link "#{planting.crop.name} planting in #{planting.garden.name} by #{planting.owner}",
href: planting_path(planting)
end
end
@@ -24,7 +25,7 @@ feature "show photo page" do
scenario "shows linkback to harvest" do
harvest.photos << photo
visit photo_path(photo)
expect(page).to have_link "A harvest by #{harvest.owner}", href: harvest_path(harvest)
expect(page).to have_link "#{harvest.crop.name} harvest by #{harvest.owner}", href: harvest_path(harvest)
end
end
@@ -34,7 +35,17 @@ feature "show photo page" do
scenario "shows linkback to garden" do
garden.photos << photo
visit photo_path(photo)
expect(page).to have_link "A garden by #{garden.owner}", href: garden_path(garden)
expect(page).to have_link "garden named \"#{garden.name}\" by #{garden.owner}", href: garden_path(garden)
end
end
context "linked to seed" do
let(:seed) { create :seed }
scenario "shows linkback to seed" do
seed.photos << photo
visit photo_path(photo)
expect(page).to have_link "#{seed.crop.name} seeds belonging to #{seed.owner}", href: seed_path(seed)
end
end
end

View File

@@ -214,7 +214,12 @@ feature "Planting a crop", :js do
expect(page).to have_content "Planting was successfully created"
expect(page).to have_content "Finished: August 30, 2014"
# shouldn't be on the page
visit plantings_path
expect(page).not_to have_content "maize"
# show all plantings to see this finished planting
visit plantings_path(all: 1)
expect(page).to have_content "August 30, 2014"
end

View File

@@ -6,30 +6,30 @@ feature "signin", js: true do
let(:wrangler) { create :crop_wrangling_member }
let(:notification) { create :notification }
def login
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
end
scenario "via email address" do
visit crops_path # some random page
click_link 'Sign in'
fill_in 'Login', with: member.email
fill_in 'Password', with: member.password
click_button 'Sign in'
login
expect(page).to have_content("Sign out")
end
scenario "redirect to previous page after signin" do
visit crops_path # some random page
click_link 'Sign in'
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
login
expect(current_path).to eq crops_path
end
scenario "don't redirect to devise pages after signin" do
visit new_member_registration_path # devise signup page
click_link 'Sign in'
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
login
expect(current_path).to eq root_path
end
@@ -38,25 +38,27 @@ feature "signin", js: true do
expect(current_path).to eq new_member_session_path
end
scenario "after signin, redirect to what you were trying to do" do
models = %w[plantings harvests posts photos gardens seeds]
models.each do |model|
visit "/#{model}/new"
shared_examples "redirects to what you were trying to do" do
scenario do
visit "/#{model_name}/new"
expect(current_path).to eq new_member_session_path
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
expect(current_path).to eq "/#{model}/new"
click_link 'Sign out'
login
expect(current_path).to eq "/#{model_name}/new"
end
end
describe "redirects to what you were trying to do" do
%w[plantings harvests posts photos gardens seeds].each do |m|
it_behaves_like "redirects to what you were trying to do" do
let(:model_name) { m }
end
end
end
scenario "after signin, redirect to new notifications page" do
visit new_notification_path(recipient: recipient)
expect(current_path).to eq new_member_session_path
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
login
expect(current_path).to eq new_notification_path
end

View File

@@ -8,19 +8,17 @@ describe 'Growstuff::OauthSignupAction' do
context 'with a valid authentication' do
before :each do
@auth = OmniAuth::AuthHash.new({
'provider' => 'facebook',
'uid' => '123545',
'info' => {
'name' => "John Testerson's Brother",
'nickname' => 'JohnnyB',
'email' => 'example.oauth.facebook@example.com',
'image' => 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
'credentials' => {
'token' => "token",
'secret' => "donttell"
}
@auth = OmniAuth::AuthHash.new('provider' => 'facebook',
'uid' => '123545',
'info' => {
'name' => "John Testerson's Brother",
'nickname' => 'JohnnyB',
'email' => 'example.oauth.facebook@example.com',
'image' => 'http://findicons.com/files/icons/1072/face_avatars/300/i04.png'
},
'credentials' => {
'token' => "token",
'secret' => "donttell"
})
end
@@ -76,11 +74,9 @@ describe 'Growstuff::OauthSignupAction' do
@auth['info']['email'] = 'never.used.oauth@yahoo.com'
Member.where(email: @auth['info']['email']).delete_all
@existing_member = create :member, {
email: @auth['info']['email'],
login_name: 'existing',
preferred_avatar_uri: 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
}
@existing_member = create :member, email: @auth['info']['email'],
login_name: 'existing',
preferred_avatar_uri: 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
@member = @action.find_or_create_from_authorization(@auth)
@authentication = @action.establish_authentication(@auth, @member)
@@ -122,18 +118,14 @@ describe 'Growstuff::OauthSignupAction' do
Member.where(email: @auth['info']['email']).delete_all
Authentication.delete_all
@existing_member = create :member, {
email: @auth['info']['email'],
login_name: 'schrodingerscat',
preferred_avatar_uri: 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
}
@existing_member = create :member, email: @auth['info']['email'],
login_name: 'schrodingerscat',
preferred_avatar_uri: 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
@existing_authentication = @existing_member.authentications.create({
provider: 'facebook',
uid: '123545',
name: "John Testerson's Brother",
member_id: @existing_member.id
})
@existing_authentication = @existing_member.authentications.create(provider: 'facebook',
uid: '123545',
name: "John Testerson's Brother",
member_id: @existing_member.id)
@member = @action.find_or_create_from_authorization(@auth)
@authentication = @action.establish_authentication(@auth, @member)

View File

@@ -61,7 +61,7 @@ describe Ability do
end
it "has crop_wrangler role" do
member.has_role?(:crop_wrangler).should be true
member.role?(:crop_wrangler).should be true
end
it "can create crops" do
@@ -96,7 +96,7 @@ describe Ability do
end
it "has admin role" do
member.has_role?(:admin).should be true
member.role?(:admin).should be true
end
it "can read products" do
@@ -210,7 +210,7 @@ describe Ability do
end
it "has admin role" do
member.has_role?(:admin).should be true
member.role?(:admin).should be true
end
it "can read orders" do

View File

@@ -30,7 +30,7 @@ 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.paid?.should be(false)
end
it "doesn't show email by default" do
@@ -194,19 +194,19 @@ describe 'member' do
it 'has a role' do
member.roles.first.should eq role
member.has_role?(:moderator).should eq true
member.role?(:moderator).should eq true
end
it 'sets up roles in factories' do
admin = FactoryGirl.create(:admin_member)
admin.has_role?(:admin).should eq true
admin.role?(:admin).should eq true
end
it 'converts role names properly' do
# need to make sure spaces get turned to underscores
role = FactoryGirl.create(:role, name: "a b c")
member.roles << role
member.has_role?(:a_b_c).should eq true
member.role?(:a_b_c).should eq true
end
end
@@ -305,7 +305,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.paid?.should be(true)
end
it "recognises a current paid account" do
@@ -313,7 +313,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.paid?.should be(true)
end
it "recognises an expired paid account" do
@@ -321,14 +321,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.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.paid?.should be(false)
end
it "recognises a free account even with paid_until set" do
@@ -336,7 +336,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.paid?.should be(false)
end
end

View File

@@ -40,8 +40,8 @@ describe 'notifier/notify.html.haml', type: "view" do
it 'should have fully qualified URLs' do
# lots of lovely fully qualified URLs
assert_select "a[href^='http']", { minimum: 4 }
assert_select "a[href^='http']", minimum: 4
# no relative URLs starting with /
assert_select "a[href^='/']", { count: 0 }
assert_select "a[href^='/']", count: 0
end
end

View File

@@ -35,7 +35,7 @@ describe "photos/new" do
context "user has photosets" do
before(:each) do
assign(:sets, { "foo" => "bar" }) # Hash of names => IDs
assign(:sets, "foo" => "bar") # Hash of names => IDs
end
it "shows a dropdown with sets from Flickr" do

View File

@@ -67,7 +67,7 @@ describe 'shop/index.html.haml', type: "view" do
end
it "recognises the paid member" do
@member.is_paid?.should be(true)
@member.paid?.should be(true)
end
it "tells you you have a paid membership" do