Compare commits

..

1 Commits

Author SHA1 Message Date
Daniel O'Connor
d443ae6154 Rubocop: Layout/HashAlignment 2026-04-23 12:56:58 +00:00
187 changed files with 1822 additions and 2121 deletions

View File

@@ -6,6 +6,13 @@
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again. # versions of RuboCop, may require this file to be generated again.
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: TreatCommentsAsGroupSeparators, ConsiderPunctuation.
Bundler/OrderedGems:
Exclude:
- 'Gemfile'
# Offense count: 19 # Offense count: 19
Capybara/NegationMatcherAfterVisit: Capybara/NegationMatcherAfterVisit:
Exclude: Exclude:
@@ -18,6 +25,22 @@ Capybara/NegationMatcherAfterVisit:
- 'spec/features/members/profile_spec.rb' - 'spec/features/members/profile_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb' - 'spec/features/plantings/planting_a_crop_spec.rb'
# Offense count: 34
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: DefaultSelector.
Capybara/RSpec/HaveSelector:
Exclude:
- 'spec/features/conversations/index_spec.rb'
- 'spec/features/footer_spec.rb'
- 'spec/features/gardens/adding_gardens_spec.rb'
- 'spec/features/harvests/harvesting_a_crop_spec.rb'
- 'spec/features/members/list_spec.rb'
- 'spec/features/plantings/planting_a_crop_spec.rb'
- 'spec/features/seeds/adding_seeds_spec.rb'
- 'spec/features/shared_examples/crop_suggest.rb'
- 'spec/support/feature_helpers.rb'
- 'spec/views/posts/show.html.haml_spec.rb'
# Offense count: 14 # Offense count: 14
Capybara/SpecificMatcher: Capybara/SpecificMatcher:
Exclude: Exclude:
@@ -63,6 +86,11 @@ FactoryBot/ExcessiveCreateList:
- 'spec/features/crops/show_spec.rb' - 'spec/features/crops/show_spec.rb'
- 'spec/features/percy/percy_spec.rb' - 'spec/features/percy/percy_spec.rb'
# Offense count: 1158
# This cop supports unsafe autocorrection (--autocorrect-all).
FactoryBot/SyntaxMethods:
Enabled: false
# Offense count: 312 # Offense count: 312
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle. # Configuration parameters: AllowMultipleStyles, EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle.
@@ -71,13 +99,6 @@ FactoryBot/ExcessiveCreateList:
# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit
Layout/HashAlignment: Layout/HashAlignment:
Exclude: Exclude:
- 'app/helpers/application_helper.rb'
- 'app/helpers/crops_helper.rb'
- 'app/models/concerns/search_harvests.rb'
- 'app/models/concerns/search_plantings.rb'
- 'app/models/crop.rb'
- 'config/sitemap.rb'
- 'lib/tasks/import.rake'
- 'spec/requests/api/v1/activities_request_spec.rb' - 'spec/requests/api/v1/activities_request_spec.rb'
- 'spec/requests/api/v1/members_request_spec.rb' - 'spec/requests/api/v1/members_request_spec.rb'
@@ -136,6 +157,18 @@ Lint/DuplicateMethods:
Exclude: Exclude:
- 'app/models/planting.rb' - 'app/models/planting.rb'
# Offense count: 8
# Configuration parameters: AllowComments, AllowEmptyLambdas.
Lint/EmptyBlock:
Exclude:
- 'db/migrate/20171022032108_all_the_predictions.rb'
- 'spec/controllers/home_controller_spec.rb'
- 'spec/controllers/likes_controller_spec.rb'
- 'spec/controllers/plant_parts_controller_spec.rb'
- 'spec/factories/crop_companions.rb'
- 'spec/features/crops/crop_detail_page_spec.rb'
- 'spec/requests/authentications_spec.rb'
# Offense count: 1 # Offense count: 1
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
Lint/RedundantCopDisableDirective: Lint/RedundantCopDisableDirective:
@@ -242,6 +275,12 @@ RSpec/BeforeAfterAll:
Exclude: Exclude:
- 'spec/tasks/import_spec.rb' - 'spec/tasks/import_spec.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
RSpec/ContextMethod:
Exclude:
- 'spec/requests/api/v1/activities_request_spec.rb'
# Offense count: 299 # Offense count: 299
# Configuration parameters: Prefixes, AllowedPatterns. # Configuration parameters: Prefixes, AllowedPatterns.
# Prefixes: when, with, without # Prefixes: when, with, without
@@ -293,6 +332,14 @@ RSpec/EmptyLineAfterExample:
RSpec/ExampleLength: RSpec/ExampleLength:
Max: 27 Max: 27
# Offense count: 1
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: method_call, block
RSpec/ExpectChange:
Exclude:
- 'spec/models/crop_spec.rb'
# Offense count: 32 # Offense count: 32
RSpec/ExpectInHook: RSpec/ExpectInHook:
Exclude: Exclude:
@@ -472,6 +519,23 @@ RSpec/VerifiedDoubles:
- 'spec/controllers/gardens_controller_spec.rb' - 'spec/controllers/gardens_controller_spec.rb'
- 'spec/views/devise/shared/_links_spec.rb' - 'spec/views/devise/shared/_links_spec.rb'
# Offense count: 7
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: ResponseMethods.
# ResponseMethods: response, last_response
RSpecRails/HaveHttpStatus:
Exclude:
- 'spec/controllers/api/v1/plantings_controller_spec.rb'
- 'spec/controllers/harvests_controller_spec.rb'
- 'spec/controllers/likes_controller_spec.rb'
- 'spec/requests/harvests_spec.rb'
# Offense count: 17
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: Inferences.
RSpecRails/InferredSpecType:
Enabled: false
# Offense count: 30 # Offense count: 30
# Configuration parameters: Database. # Configuration parameters: Database.
# SupportedDatabases: mysql, postgresql # SupportedDatabases: mysql, postgresql
@@ -591,6 +655,7 @@ Rails/RedundantActiveRecordAllMethod:
- 'app/controllers/scientific_names_controller.rb' - 'app/controllers/scientific_names_controller.rb'
- 'spec/features/members/deletion_spec.rb' - 'spec/features/members/deletion_spec.rb'
- 'spec/features/percy/percy_spec.rb' - 'spec/features/percy/percy_spec.rb'
- 'spec/models/harvest_spec.rb'
# Offense count: 5 # Offense count: 5
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
@@ -672,6 +737,12 @@ Rails/WhereEquals:
- 'app/models/harvest.rb' - 'app/models/harvest.rb'
- 'app/models/planting.rb' - 'app/models/planting.rb'
# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Rails/WhereMissing:
Exclude:
- 'app/controllers/crops_controller.rb'
# Offense count: 3 # Offense count: 3
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
Rails/WhereRange: Rails/WhereRange:

View File

@@ -204,5 +204,5 @@ gem "i18n_data", "~> 1.1"
gem "paper_trail", "~> 17.0" gem "paper_trail", "~> 17.0"
gem 'aws-sdk-s3', '~> 1', '>= 1.114.0'
gem 'sitemap_generator' gem 'sitemap_generator'
gem 'aws-sdk-s3', '~> 1', '>= 1.114.0'

View File

@@ -498,7 +498,7 @@ GEM
date date
stringio stringio
public_suffix (7.0.5) public_suffix (7.0.5)
puma (8.0.0) puma (7.2.0)
nio4r (~> 2.0) nio4r (~> 2.0)
query_diet (0.7.3) query_diet (0.7.3)
racc (1.8.1) racc (1.8.1)

View File

@@ -160,7 +160,7 @@ class CropsController < ApplicationController
when 'youtube' when 'youtube'
Crop.approved.where(en_youtube_url: [nil, '']).order(plantings_count: :desc) Crop.approved.where(en_youtube_url: [nil, '']).order(plantings_count: :desc)
when 'alternate_names' when 'alternate_names'
Crop.approved.where.missing(:alternate_names).order(plantings_count: :desc) Crop.approved.left_joins(:alternate_names).where(alternate_names: { id: nil }).order(plantings_count: :desc)
when 'wikidata' when 'wikidata'
crops_with_wikidata = Crop.joins(:scientific_names).where.not(scientific_names: { wikidata_id: nil }).distinct crops_with_wikidata = Crop.joins(:scientific_names).where.not(scientific_names: { wikidata_id: nil }).distinct
Crop.approved.where.not(id: crops_with_wikidata).order(plantings_count: :desc) Crop.approved.where.not(id: crops_with_wikidata).order(plantings_count: :desc)

View File

@@ -1,53 +0,0 @@
# frozen_string_literal: true
class WeatherObservationsController < DataController
def index
@owner = Member.find_by(slug: params[:member_slug])
@show_all = params[:all] == '1'
@show_jump_to = params[:member_slug].present? ? true : false
# @weather_observations = @weather_observations.includes(:owner)
# @weather_observations = @weather_observations.active unless @show_all
# @weather_observations = @weather_observations.where(owner: @owner) if @owner.present?
# @weather_observations = @weather_observations.where.not(members: { confirmed_at: nil })
# .order(:name).paginate(page: params[:page])
respond_with(@weather_observations)
end
def show
respond_with(@weather_observation)
end
def new
@weather_observation = WeatherObservation.new
respond_with(@weather_observation)
end
def edit
respond_with(@weather_observation)
end
def create
@weather_observation.owner_id = current_member.id
flash[:notice] = I18n.t('weather_observations.created') if @weather_observation.save
respond_with(@weather_observation)
end
def update
flash[:notice] = I18n.t('weather_observations.updated') if @weather_observation.update(weather_observation_params)
respond_with(@weather_observation)
end
def destroy
@weather_observation.destroy
flash[:notice] = I18n.t('weather_observations.deleted')
redirect_to(member_weather_observations_path(@weather_observation.owner))
end
private
def weather_observation_params
params.require(:weather_observation).permit!
end
end

View File

@@ -130,9 +130,9 @@ module ApplicationHelper
doc = Nokogiri::XML(response.body) doc = Nokogiri::XML(response.body)
doc.xpath('//xmlns:entry').first(2).map do |entry| doc.xpath('//xmlns:entry').first(2).map do |entry|
{ {
title: entry.xpath('xmlns:title').text, title: entry.xpath('xmlns:title').text,
content: entry.xpath('xmlns:content').text, content: entry.xpath('xmlns:content').text,
link: entry.xpath('xmlns:link/@href').text, link: entry.xpath('xmlns:link/@href').text,
updated: entry.xpath('xmlns:updated').text updated: entry.xpath('xmlns:updated').text
} }
end end

View File

@@ -56,11 +56,11 @@ module CropsHelper
crop.posts.each do |post| crop.posts.each do |post|
subject_of_entities << { subject_of_entities << {
'@type': "SocialMediaPosting", '@type': "SocialMediaPosting",
url: post_url(post), url: post_url(post),
author: { author: {
'@type': 'Person', '@type': 'Person',
name: post.author.login_name name: post.author.login_name
}, },
'datePublished': post.created_at 'datePublished': post.created_at
} }

View File

@@ -56,7 +56,7 @@ module SearchHarvests
# Disabled for now so that more relevant harvests are # Disabled for now so that more relevant harvests are
# surfaced; even if we're falling back to crop photos. # surfaced; even if we're falling back to crop photos.
# photos_count: { gt: 0 }, # photos_count: { gt: 0 },
owner_id: { not: owners } owner_id: { not: owners }
} }
one_record = search('*', one_record = search('*',
limit: 1, limit: 1,

View File

@@ -69,7 +69,7 @@ module SearchPlantings
# Disabled for now so that more relevant plantings are # Disabled for now so that more relevant plantings are
# surfaced; even if we're falling back to crop photos. # surfaced; even if we're falling back to crop photos.
# photos_count: { gt: 0 }, # photos_count: { gt: 0 },
owner_id: { not: owners } owner_id: { not: owners }
} }
one_record = search('*', one_record = search('*',
limit: 1, limit: 1,

View File

@@ -61,7 +61,7 @@ class Crop < ApplicationRecord
}, },
if: :approved? if: :approved?
validates :en_youtube_url, validates :en_youtube_url,
format: { format: {
with: %r{\A(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:(?:v|e(?:mbed)?)/|\S*?[?&]v=)|youtu\.be/)[a-zA-Z0-9_-]{11}(?:[?&]\S*)?\z}, with: %r{\A(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:(?:v|e(?:mbed)?)/|\S*?[?&]v=)|youtu\.be/)[a-zA-Z0-9_-]{11}(?:[?&]\S*)?\z},
message: 'is not a valid YouTube URL' message: 'is not a valid YouTube URL'
}, },

View File

@@ -10,7 +10,6 @@ class Garden < ApplicationRecord
has_many :plantings, dependent: :destroy has_many :plantings, dependent: :destroy
has_many :crops, through: :plantings has_many :crops, through: :plantings
has_many :weather_observations, dependent: :destroy
has_many :activities, dependent: :destroy has_many :activities, dependent: :destroy
has_many :garden_collaborators, dependent: :destroy has_many :garden_collaborators, dependent: :destroy

View File

@@ -1,22 +0,0 @@
# frozen_string_literal: true
# A weather observation is intended to be a snapshot aligned to
# https://github.com/schemaorg/schemaorg/issues/362
class WeatherObservation < ApplicationRecord
belongs_to :owner
validates :source, presence: true
validates :observed_at, presence: true
attr_accessible :source, :observation_at, :solvar_uv_index, :dew_point_temperature_centigrade,
:air_temperature_centigrade, :relative_humidity, :wind_speed_kmh, :wind_gust_speed_kmh, :owner_id, :wind_direction, :precipitation_probability, :pressure,
:visibility_distance_metres, :weather_type
# Lowest temp on earth: -89.2°C (-128.6°F)
# Highest: 56.7°C
validates :dew_point_temperature_centigrade, numericality: { min: -90, max: 60 }, allow_nil: true
validates :air_temperature_centigrade, numericality: { min: -90, max: 60 }, allow_nil: true
validates :relative_humidity, numericality: { min: 0, max: 100 }, allow_nil: true
validates :wind_speed_kmh, numericality: { min: 0, max: 450 }, allow_nil: true # Highest 408 km/h
validates :wind_gust_speed_kmh, min: 0, max: 450, allow_nil: true # Highest 408 km/h
end

View File

@@ -1,18 +0,0 @@
- if can?(:edit, garden)
.dropdown.garden-actions
%a#garden-actions-button.btn.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", type: "button", href: '#'} Actions
.dropdown-menu.dropdown-menu-xs{"aria-labelledby" => "garden-actions-button"}
- if can?(:edit, garden)
= garden_plant_something_button(garden, classes: 'dropdown-item') if garden.active
- if garden.active
= garden_mark_inactive_button(garden, classes: 'dropdown-item')
- else
= garden_mark_active_button(garden, classes: 'dropdown-item')
= garden_edit_button(garden, classes: 'dropdown-item')
= add_photo_button(garden, classes: 'dropdown-item')
- if can?(:destroy, garden)
.dropdown-divider
= delete_button(garden, classes: 'dropdown-item text-danger',
message: 'All plantings associated with this garden will also be deleted. Are you sure?')

View File

@@ -1,40 +0,0 @@
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
= bootstrap_form_for(@garden) do |f|
- if content_for? :title
.card-header
%h1.h2-responsive.text-center
%strong=yield :title
.card-body
= required_field_help_text
- if @garden.errors.any?
#error_explanation.alert.alert-warning{:role => "alert"}
%h4.alert-heading
= pluralize(@garden.errors.size, "error")
prohibited this garden from being saved
%ul
- @garden.errors.full_messages.each do |msg|
%li= msg
= f.text_field :name, maxlength: 255, required: true
= f.text_area :description, rows: 6
= f.text_field :location,
value: @garden.location || current_member.location,
class: 'form-control', maxlength: 255
%span.help-block
= t('.location_helper')
- if current_member.location.blank?
= link_to "Set your location now.", edit_member_registration_path
- else
= link_to "Change your location.", edit_member_registration_path
.row
.col-md-5.col-12= f.number_field :area, class: 'input-small', step: "any"
.col-md-7.col-12= f.select(:area_unit, Garden::AREA_UNITS_VALUES, { include_blank: false })
.col-12= f.select(:garden_type_id, GardenType.all.order(:name).pluck(:name, :id),
selected: @garden.garden_type_id, include_blank: true)
.col-12
= f.check_box :active, label: 'Active?'
%p
You can mark a garden as inactive if you no longer use it.
Note: this will mark all plantings in the garden as "finished".
.card-footer
.text-right= f.submit 'Save Garden'

View File

@@ -1,20 +0,0 @@
.panel.panel-success
.panel-heading
%h3.panel-title
= link_to garden.name, garden_path(garden)
.panel-body
.row
.col-md-2.col-xs-12.garden-info
%p= render 'gardens/photo', garden: garden
%p= display_garden_description(garden)
- if can?(:edit, garden)
= render 'gardens/actions', garden: garden
.col-md-10
- if garden.plantings.current.size.positive?
.row
- garden.plantings.current.order(created_at: :desc).includes(:crop, :photos).each do |planting|
.col-lg-2.col-sm-4.col-xs-6
= render "plantings/thumbnail", planting: planting
- else
no plantings

View File

@@ -1,3 +0,0 @@
= link_to image_tag(garden_image_path(garden),
alt: garden.name, class: 'img-responsive'),
garden_path(garden)

View File

@@ -1,18 +0,0 @@
%h2 Previously planted in this garden
- if @finished_plantings.any?
- year = nil
- @finished_plantings.where.not(planted_at: nil).order(planted_at: :desc).each do |planting|
- if year != planting.planted_at.year
- year = planting.planted_at.year
%h4= year
= render "plantings/tiny", planting: planting
- if @finished_plantings.where(planted_at: nil).any?
%h4 Unknown year
- @finished_plantings.where(planted_at: nil).each do |planting|
= render "plantings/tiny", planting: planting
- else
.col-md-12
%p Nothing has been planted here.

View File

@@ -1,3 +0,0 @@
= content_for :title, "Edit garden"
= render "form"

View File

@@ -1,65 +0,0 @@
- content_for :title, @owner ? "#{@owner}'s weather_observations" : "Everyone's weather_observations"
%h1= @owner ? "#{@owner}'s weather_observations" : "Everyone's weather_observations"
- content_for :breadcrumbs do
- if @owner
%li.breadcrumb-item= link_to 'weather_observations', weather_observations_path
%li.breadcrumb-item.active= link_to "#{@owner}'s weather_observations", member_weather_observations_path(@owner)
- else
%li.breadcrumb-item.active= link_to 'weather_observations', weather_observations_path
.row
.col-md-2
= render 'layouts/nav', model: weather_observation
= link_to show_inactive_tickbox_path('weather_observations', owner: @owner, show_all: @show_all) do
= check_box_tag 'active', 'all', @show_all
include in-active
- if @owner.present?
%hr/
= render @owner
.col-md-10
- if @weather_observations.empty?
%p There are no weather_observations to display.
- if can?(:create, weather_observation) && @owner == current_member
= link_to 'Add a weather_observation', new_weather_observation_path, class: 'btn btn-primary'
- else
%section
%h2= page_entries_info @weather_observations
= will_paginate @weather_observations
- if @show_jump_to == true
%section
.jump
jump to:
- @weather_observations.each do |weather_observation|
.badge.badge-primary
- if @owner.present?
= link_to weather_observation.weather_type, member_weather_observations_path(@owner, anchor: "weather_observation-#{weather_observation.id}")
- else
= link_to weather_observation.weather_type, weather_observations_path(anchor: "weather_observation-#{weather_observation.id}")
- @weather_observations.each do |weather_observation|
.card
.card-header
.row
.col-12.col-md-3
%h2= link_to weather_observation.weather_type, weather_observation, name: "weather_observation-#{weather_observation.id}"
.row
.col-md-3
- if @owner.blank?
owner:
= render 'members/tiny', member: weather_observation.owner
.col-md-9
%section
= render 'weather_observations/actions', weather_observation: weather_observation
.row
.col-12= page_entries_info @weather_observations
.col-12= will_paginate @weather_observations

View File

@@ -1,3 +0,0 @@
- content_for :title, "New weather observation"
= render 'form'

View File

@@ -1,117 +0,0 @@
= content_for :title, "#{@weather_observation.owner}'s #{@weather_observation}"
- content_for :opengraph do
- if @weather_observation.weather_type
= tag("meta", property: "og:description", content: og_description(@weather_observation. - if @weather_observation.weather_type))
= tag("meta", property: "og:title", content: "#{@weather_observation.owner}'s #{@weather_observation}")
= tag("meta", property: "og:type", content: "website")
= tag("meta", property: "og:url", content: request.original_url)
= tag("meta", property: "og:site_name", content: ENV['GROWSTUFF_SITE_NAME'])
- content_for :breadcrumbs do
%li.breadcrumb-item= link_to 'weather_observations', weather_observations_path
%li.breadcrumb-item.active= link_to @weather_observation.weather_type, weather_observations_path(@weather_observation)
.row
.col-md-9.col-12
%h2.h1
%strong= @weather_observation
.col-md-3.col-12
= render 'weather_observations/actions', weather_observation: @weather_observation
.row
%div
%p
:growstuff_markdown
#{strip_tags @weather_observation.weather_type}
- unless @weather_observation.description
.row-fluid
%p No description available yet.
- if can? :edit, @weather_observation
%p
Why not
= link_to 'tell us more.', edit_weather_observation_path(@weather_observation)
- if @weather_observation.plantings.where.not(planted_at: nil).any?
%section.card
%h2 weather_observation progress
.card-body
= render 'plantings/progress_list', plantings: @weather_observation.plantings.active
%section
%h2 Current plantings in weather_observation
.index-cards
- if @current_plantings.size.positive?
- @current_plantings.each do |planting|
= render "plantings/card", planting: planting
- else
.col-md-12
%p Nothing is currently planted here.
%section.companions
%h2 Suggestioned companions
- @suggested_companions.each do |companion|
= render 'crops/tiny', crop: companion
%section= render 'previously'
.col-md-3
.card
.card-image
= image_tag weather_observation_image_path(@weather_observation), class: 'img-card', alt: 'photo of this weather_observation'
.card-body
%h4 About this weather_observation
%p
%strong Owner:
= link_to @weather_observation.owner, @weather_observation.owner
- if @weather_observation.location.present?
%p
%strong Location:
= @weather_observation.location
- if @weather_observation.area.present?
%p
%strong Area:
= pluralize(@weather_observation.area, @weather_observation.area_unit)
- if @weather_observation.weather_observation_type.present?
%p
%strong weather_observation type:
= @weather_observation.weather_observation_type.name
.card
.card-header
%h4 #{@weather_observation.owner}'s weather_observations
.card-body
%ul.list-group.list-group-flush
- @weather_observation.owner.weather_observations.active.order_by_name.each do |weather_observation|
%li.list-group-item.list-group-flush
= weather_observation_icon
- if @weather_observation == weather_observation
= @weather_observation
- else
= link_to weather_observation, weather_observation_path(weather_observation)
- unless @weather_observation.owner.weather_observations.inactive.empty?
%h4 Inactive weather_observations
%ul
- @weather_observation.owner.weather_observations.inactive.order_by_name.each do |otherweather_observation|
%li
- if @weather_observation == otherweather_observation
= @weather_observation.name
- else
= link_to otherweather_observation, weather_observation_path(otherweather_observation)
- if @weather_observation.owner == current_member
%p
= link_to new_weather_observation_path, class: 'btn btn-default btn-xs' do
Add New weather_observation
- if can?(:edit, @weather_observation) && can?(:create, Photo)
%%p
= add_photo_button(@weather_observation)
- if @weather_observation.photos.size.positive?
%section.photos
%h2= localize_plural(@weather_observation.photos, Photo)
.index-cards
- @weather_observation.photos.includes(:owner).each do |photo|
= render 'photos/thumbnail', photo: photo

View File

@@ -117,7 +117,6 @@ Rails.application.routes.draw do
resources :plantings resources :plantings
resources :harvests resources :harvests
resources :posts resources :posts
resources :weather_observations
resources :activities resources :activities
resources :follows resources :follows

View File

@@ -7,9 +7,9 @@ SitemapGenerator::Sitemap.default_host = 'https://growstuff.org'
SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new( SitemapGenerator::Sitemap.adapter = SitemapGenerator::AwsSdkAdapter.new(
ENV['S3_SITEMAP_BUCKET'], ENV['S3_SITEMAP_BUCKET'],
access_key_id: ENV['S3_ACCESS_KEY'], access_key_id: ENV['S3_ACCESS_KEY'],
secret_access_key: ENV['S3_SECRET_KEY'], secret_access_key: ENV['S3_SECRET_KEY'],
region: ENV.fetch('S3_AWS_REGION', 'us-east-1') region: ENV.fetch('S3_AWS_REGION', 'us-east-1')
) )
SitemapGenerator::Sitemap.create do SitemapGenerator::Sitemap.create do

View File

@@ -18,6 +18,7 @@ class AllThePredictions < ActiveRecord::Migration[4.2]
remove_column :plantings, :days_before_maturity, :integer remove_column :plantings, :days_before_maturity, :integer
create_table :median_functions create_table :median_functions do |t|
end
end end
end end

View File

@@ -1,24 +0,0 @@
# frozen_string_literal: true
class AddWeatherObservations < ActiveRecord::Migration[7.0]
def change
# See https://github.com/schemaorg/schemaorg/issues/362
create_table :weather_observations do |t|
t.string :source
t.datetime :observation_at
t.integer :solar_uv_index
t.decimal :wind_speed_kmh
t.decimal :wind_gust_speed_kmh
t.string :wind_direction
t.decimal :air_temperature_centigrade
t.decimal :relative_humidity
t.decimal :precipitation_probability
t.decimal :dew_point_temperature_centigrade
t.decimal :pressure
t.integer :visibility_distance_metres
t.string :weather_type
t.references :owner
t.timestamps
end
end
end

View File

@@ -970,26 +970,6 @@ ActiveRecord::Schema[7.2].define(version: 2025_12_01_045000) do
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id" t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
end end
create_table "weather_observations", force: :cascade do |t|
t.string "source"
t.datetime "observation_at"
t.integer "solar_uv_index"
t.decimal "wind_speed_kmh"
t.decimal "wind_gust_speed_kmh"
t.string "wind_direction"
t.decimal "air_temperature_centigrade"
t.decimal "relative_humidity"
t.decimal "precipitation_probability"
t.decimal "dew_point_temperature_centigrade"
t.decimal "pressure"
t.integer "visibility_distance_metres"
t.string "weather_type"
t.bigint "owner_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["owner_id"], name: "index_weather_observations_on_owner_id"
end
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "harvests", "plantings" add_foreign_key "harvests", "plantings"

View File

@@ -4,299 +4,299 @@ namespace :import do
desc "Import Australian Food Classification Data from a CSV file" desc "Import Australian Food Classification Data from a CSV file"
task australian_food_classification_data: :environment do task australian_food_classification_data: :environment do
HEADER_MAP = { HEADER_MAP = {
"Public Food Key" => :public_food_key, "Public Food Key" => :public_food_key,
"Classification" => :classification, "Classification" => :classification,
"Food Name" => :food_name, "Food Name" => :food_name,
"Energy with dietary fibre, equated \n(kJ)" => :energy_with_dietary_fibre_equated_kj, "Energy with dietary fibre, equated \n(kJ)" => :energy_with_dietary_fibre_equated_kj,
"Energy, without dietary fibre, equated \n(kJ)" => :energy_without_dietary_fibre_equated_kj, "Energy, without dietary fibre, equated \n(kJ)" => :energy_without_dietary_fibre_equated_kj,
"Moisture (water) \n(g)" => :moisture_water_g, "Moisture (water) \n(g)" => :moisture_water_g,
"Protein \n(g)" => :protein_g, "Protein \n(g)" => :protein_g,
"Nitrogen \n(g)" => :nitrogen_g, "Nitrogen \n(g)" => :nitrogen_g,
"Fat, total \n(g)" => :fat_total_g, "Fat, total \n(g)" => :fat_total_g,
"Ash \n(g)" => :ash_g, "Ash \n(g)" => :ash_g,
"Total dietary fibre \n(g)" => :total_dietary_fibre_g, "Total dietary fibre \n(g)" => :total_dietary_fibre_g,
"Alcohol \n(g)" => :alcohol_g, "Alcohol \n(g)" => :alcohol_g,
"Fructose \n(g)" => :fructose_g, "Fructose \n(g)" => :fructose_g,
"Glucose \n(g)" => :glucose_g, "Glucose \n(g)" => :glucose_g,
"Sucrose\n(g)" => :sucrose_g, "Sucrose\n(g)" => :sucrose_g,
"Maltose \n(g)" => :maltose_g, "Maltose \n(g)" => :maltose_g,
"Lactose \n(g)" => :lactose_g, "Lactose \n(g)" => :lactose_g,
"Galactose \n(g)" => :galactose_g, "Galactose \n(g)" => :galactose_g,
"Maltotrios \n(g)" => :maltotrios_g, "Maltotrios \n(g)" => :maltotrios_g,
"Total sugars (g)" => :total_sugars_g, "Total sugars (g)" => :total_sugars_g,
"Added sugars (g)" => :added_sugars_g, "Added sugars (g)" => :added_sugars_g,
"Free sugars \n(g)" => :free_sugars_g, "Free sugars \n(g)" => :free_sugars_g,
"Starch \n(g)" => :starch_g, "Starch \n(g)" => :starch_g,
"Dextrin \n(g)" => :dextrin_g, "Dextrin \n(g)" => :dextrin_g,
"Glycerol \n(g)" => :glycerol_g, "Glycerol \n(g)" => :glycerol_g,
"Glycogen \n(g)" => :glycogen_g, "Glycogen \n(g)" => :glycogen_g,
"Inulin \n(g)" => :inulin_g, "Inulin \n(g)" => :inulin_g,
"Erythritol \n(g)" => :erythritol_g, "Erythritol \n(g)" => :erythritol_g,
"Maltitol \n(g)" => :maltitol_g, "Maltitol \n(g)" => :maltitol_g,
"Mannitol \n(g)" => :mannitol_g, "Mannitol \n(g)" => :mannitol_g,
"Xylitol \n(g)" => :xylitol_g, "Xylitol \n(g)" => :xylitol_g,
"Maltodextrin (g)" => :maltodextrin_g, "Maltodextrin (g)" => :maltodextrin_g,
"Oligosaccharides \n(g)" => :oligosaccharides_g, "Oligosaccharides \n(g)" => :oligosaccharides_g,
"Polydextrose \n(g)" => :polydextrose_g, "Polydextrose \n(g)" => :polydextrose_g,
"Raffinose \n(g)" => :raffinose_g, "Raffinose \n(g)" => :raffinose_g,
"Stachyose \n(g)" => :stachyose_g, "Stachyose \n(g)" => :stachyose_g,
"Sorbitol \n(g)" => :sorbitol_g, "Sorbitol \n(g)" => :sorbitol_g,
"Resistant starch \n(g)" => :resistant_starch_g, "Resistant starch \n(g)" => :resistant_starch_g,
"Available carbohydrate, without sugar alcohols \n(g)" => :available_carbohydrate_without_sugar_alcohols_g, "Available carbohydrate, without sugar alcohols \n(g)" => :available_carbohydrate_without_sugar_alcohols_g,
"Available carbohydrate, with sugar alcohols \n(g)" => :available_carbohydrate_with_sugar_alcohols_g, "Available carbohydrate, with sugar alcohols \n(g)" => :available_carbohydrate_with_sugar_alcohols_g,
"Acetic acid \n(g)" => :acetic_acid_g, "Acetic acid \n(g)" => :acetic_acid_g,
"Citric acid \n(g)" => :citric_acid_g, "Citric acid \n(g)" => :citric_acid_g,
"Fumaric acid \n(g)" => :fumaric_acid_g, "Fumaric acid \n(g)" => :fumaric_acid_g,
"Lactic acid \n(g)" => :lactic_acid_g, "Lactic acid \n(g)" => :lactic_acid_g,
"Malic acid\n (g)" => :malic_acid_g, "Malic acid\n (g)" => :malic_acid_g,
"Oxalic acid \n(g)" => :oxalic_acid_g, "Oxalic acid \n(g)" => :oxalic_acid_g,
"Propionic acid \n(g)" => :propionic_acid_g, "Propionic acid \n(g)" => :propionic_acid_g,
"Quinic acid \n(g)" => :quinic_acid_g, "Quinic acid \n(g)" => :quinic_acid_g,
"Shikimic acid \n(g)" => :shikimic_acid_g, "Shikimic acid \n(g)" => :shikimic_acid_g,
"Succinic acid \n(g)" => :succinic_acid_g, "Succinic acid \n(g)" => :succinic_acid_g,
"Tartaric acid \n(g)" => :tartaric_acid_g, "Tartaric acid \n(g)" => :tartaric_acid_g,
"Aluminium (Al) \n(ug)" => :aluminium_al_ug, "Aluminium (Al) \n(ug)" => :aluminium_al_ug,
"Antimony (Sb) \n(ug)" => :antimony_sb_ug, "Antimony (Sb) \n(ug)" => :antimony_sb_ug,
"Arsenic (As) \n(ug)" => :arsenic_as_ug, "Arsenic (As) \n(ug)" => :arsenic_as_ug,
"Cadmium (Cd) \n(ug)" => :cadmium_cd_ug, "Cadmium (Cd) \n(ug)" => :cadmium_cd_ug,
"Calcium (Ca) \n(mg)" => :calcium_ca_mg, "Calcium (Ca) \n(mg)" => :calcium_ca_mg,
"Chromium (Cr) \n(ug)" => :chromium_cr_ug, "Chromium (Cr) \n(ug)" => :chromium_cr_ug,
"Chloride (Cl) \n(mg)" => :chloride_cl_mg, "Chloride (Cl) \n(mg)" => :chloride_cl_mg,
"Cobalt (Co) \n(ug)" => :cobalt_co_ug, "Cobalt (Co) \n(ug)" => :cobalt_co_ug,
"Copper (Cu) \n(mg)" => :copper_cu_mg, "Copper (Cu) \n(mg)" => :copper_cu_mg,
"Fluoride (F) \n(ug)" => :fluoride_f_ug, "Fluoride (F) \n(ug)" => :fluoride_f_ug,
"Iodine (I) \n(ug)" => :iodine_i_ug, "Iodine (I) \n(ug)" => :iodine_i_ug,
"Iron (Fe) \n(mg)" => :iron_fe_mg, "Iron (Fe) \n(mg)" => :iron_fe_mg,
"Lead (Pb) \n(ug)" => :lead_pb_ug, "Lead (Pb) \n(ug)" => :lead_pb_ug,
"Magnesium (Mg) \n(mg)" => :magnesium_mg_mg, "Magnesium (Mg) \n(mg)" => :magnesium_mg_mg,
"Manganese (Mn) \n(mg)" => :manganese_mn_mg, "Manganese (Mn) \n(mg)" => :manganese_mn_mg,
"Mercury (Hg) \n(ug)" => :mercury_hg_ug, "Mercury (Hg) \n(ug)" => :mercury_hg_ug,
"Molybdenum (Mo) \n(ug)" => :molybdenum_mo_ug, "Molybdenum (Mo) \n(ug)" => :molybdenum_mo_ug,
"Nickel (Ni) \n(ug)" => :nickel_ni_ug, "Nickel (Ni) \n(ug)" => :nickel_ni_ug,
"Phosphorus (P) \n(mg)" => :phosphorus_p_mg, "Phosphorus (P) \n(mg)" => :phosphorus_p_mg,
"Potassium (K) \n(mg)" => :potassium_k_mg, "Potassium (K) \n(mg)" => :potassium_k_mg,
"Selenium (Se) \n(ug)" => :selenium_se_ug, "Selenium (Se) \n(ug)" => :selenium_se_ug,
"Sodium (Na) \n(mg)" => :sodium_na_mg, "Sodium (Na) \n(mg)" => :sodium_na_mg,
"Sulphur (S) \n(mg)" => :sulphur_s_mg, "Sulphur (S) \n(mg)" => :sulphur_s_mg,
"Tin (Sn) \n(ug)" => :tin_sn_ug, "Tin (Sn) \n(ug)" => :tin_sn_ug,
"Zinc (Zn) \n(mg)" => :zinc_zn_mg, "Zinc (Zn) \n(mg)" => :zinc_zn_mg,
"Retinol (preformed vitamin A) \n(ug)" => :retinol_preformed_vitamin_a_ug, "Retinol (preformed vitamin A) \n(ug)" => :retinol_preformed_vitamin_a_ug,
"Alpha-carotene \n(ug)" => :alpha_carotene_ug, "Alpha-carotene \n(ug)" => :alpha_carotene_ug,
"Beta-carotene \n(ug)" => :beta_carotene_ug, "Beta-carotene \n(ug)" => :beta_carotene_ug,
"Cryptoxanthin \n(ug)" => :cryptoxanthin_ug, "Cryptoxanthin \n(ug)" => :cryptoxanthin_ug,
"Beta-carotene equivalents (provitamin A) \n(ug)" => :beta_carotene_equivalents_provitamin_a_ug, "Beta-carotene equivalents (provitamin A) \n(ug)" => :beta_carotene_equivalents_provitamin_a_ug,
"Vitamin A retinol equivalents \n(ug)" => :vitamin_a_retinol_equivalents_ug, "Vitamin A retinol equivalents \n(ug)" => :vitamin_a_retinol_equivalents_ug,
"Lutein \n(ug)" => :lutein_ug, "Lutein \n(ug)" => :lutein_ug,
"Lycopene \n(ug)" => :lycopene_ug, "Lycopene \n(ug)" => :lycopene_ug,
"Xanthophyl \n(ug)" => :xanthophyl_ug, "Xanthophyl \n(ug)" => :xanthophyl_ug,
"Thiamin (B1) \n(mg)" => :thiamin_b1_mg, "Thiamin (B1) \n(mg)" => :thiamin_b1_mg,
"Riboflavin (B2) \n(mg)" => :riboflavin_b2_mg, "Riboflavin (B2) \n(mg)" => :riboflavin_b2_mg,
"Niacin (B3) \n(mg)" => :niacin_b3_mg, "Niacin (B3) \n(mg)" => :niacin_b3_mg,
"Niacin derived from tryptophan \n(mg)" => :niacin_derived_from_tryptophan_mg, "Niacin derived from tryptophan \n(mg)" => :niacin_derived_from_tryptophan_mg,
"Niacin derived equivalents \n(mg)" => :niacin_derived_equivalents_mg, "Niacin derived equivalents \n(mg)" => :niacin_derived_equivalents_mg,
"Pantothenic acid (B5) \n(mg)" => :pantothenic_acid_b5_mg, "Pantothenic acid (B5) \n(mg)" => :pantothenic_acid_b5_mg,
"Pyridoxine (B6) \n(mg)" => :pyridoxine_b6_mg, "Pyridoxine (B6) \n(mg)" => :pyridoxine_b6_mg,
"Biotin (B7) \n(ug)" => :biotin_b7_ug, "Biotin (B7) \n(ug)" => :biotin_b7_ug,
"Cobalamin (B12) \n(ug)" => :cobalamin_b12_ug, "Cobalamin (B12) \n(ug)" => :cobalamin_b12_ug,
"Folate, natural \n(ug)" => :folate_natural_ug, "Folate, natural \n(ug)" => :folate_natural_ug,
"Folic acid \n(ug)" => :folic_acid_ug, "Folic acid \n(ug)" => :folic_acid_ug,
"Total folates \n(ug)" => :total_folates_ug, "Total folates \n(ug)" => :total_folates_ug,
"Dietary folate equivalents \n(ug)" => :dietary_folate_equivalents_ug, "Dietary folate equivalents \n(ug)" => :dietary_folate_equivalents_ug,
"Vitamin C \n(mg)" => :vitamin_c_mg, "Vitamin C \n(mg)" => :vitamin_c_mg,
"Cholecalciferol (D3) \n(ug)" => :cholecalciferol_d3_ug, "Cholecalciferol (D3) \n(ug)" => :cholecalciferol_d3_ug,
"Ergocalciferol (D2) \n(ug)" => :ergocalciferol_d2_ug, "Ergocalciferol (D2) \n(ug)" => :ergocalciferol_d2_ug,
"25-hydroxy cholecalciferol (25-OH D3) \n(ug)" => :c25_hydroxy_cholecalciferol_25_oh_d3_ug, "25-hydroxy cholecalciferol (25-OH D3) \n(ug)" => :c25_hydroxy_cholecalciferol_25_oh_d3_ug,
"25-hydroxy ergocalciferol (25-OH D2) \n(ug)" => :c25_hydroxy_ergocalciferol_25_oh_d2_ug, "25-hydroxy ergocalciferol (25-OH D2) \n(ug)" => :c25_hydroxy_ergocalciferol_25_oh_d2_ug,
"Vitamin D3 equivalents \n(ug)" => :vitamin_d3_equivalents_ug, "Vitamin D3 equivalents \n(ug)" => :vitamin_d3_equivalents_ug,
"Alpha tocopherol \n(mg)" => :alpha_tocopherol_mg, "Alpha tocopherol \n(mg)" => :alpha_tocopherol_mg,
"Alpha tocotrienol \n(mg)" => :alpha_tocotrienol_mg, "Alpha tocotrienol \n(mg)" => :alpha_tocotrienol_mg,
"Beta tocopherol \n(mg)" => :beta_tocopherol_mg, "Beta tocopherol \n(mg)" => :beta_tocopherol_mg,
"Beta tocotrienol \n(mg)" => :beta_tocotrienol_mg, "Beta tocotrienol \n(mg)" => :beta_tocotrienol_mg,
"Delta tocopherol \n(mg)" => :delta_tocopherol_mg, "Delta tocopherol \n(mg)" => :delta_tocopherol_mg,
"Delta tocotrienol \n(mg)" => :delta_tocotrienol_mg, "Delta tocotrienol \n(mg)" => :delta_tocotrienol_mg,
"Gamma tocopherol \n(mg)" => :gamma_tocopherol_mg, "Gamma tocopherol \n(mg)" => :gamma_tocopherol_mg,
"Gamma tocotrienol \n(mg)" => :gamma_tocotrienol_mg, "Gamma tocotrienol \n(mg)" => :gamma_tocotrienol_mg,
"Vitamin E \n(mg)" => :vitamin_e_mg, "Vitamin E \n(mg)" => :vitamin_e_mg,
"C4 (%T)" => :c4_t, "C4 (%T)" => :c4_t,
"C6 (%T)" => :c6_t, "C6 (%T)" => :c6_t,
"C8 (%T)" => :c8_t, "C8 (%T)" => :c8_t,
"C10 (%T)" => :c10_t, "C10 (%T)" => :c10_t,
"C11 (%T)" => :c11_t, "C11 (%T)" => :c11_t,
"C12 (%T)" => :c12_t, "C12 (%T)" => :c12_t,
"C13 (%T)" => :c13_t, "C13 (%T)" => :c13_t,
"C14 (%T)" => :c14_t, "C14 (%T)" => :c14_t,
"C15 (%T)" => :c15_t, "C15 (%T)" => :c15_t,
"C16 (%T)" => :c16_t, "C16 (%T)" => :c16_t,
"C17 (%T)" => :c17_t, "C17 (%T)" => :c17_t,
"C18 (%T)" => :c18_t, "C18 (%T)" => :c18_t,
"C19 (%T)" => :c19_t, "C19 (%T)" => :c19_t,
"C20 (%T)" => :c20_t, "C20 (%T)" => :c20_t,
"C21 (%T)" => :c21_t, "C21 (%T)" => :c21_t,
"C22 (%T)" => :c22_t, "C22 (%T)" => :c22_t,
"C23 (%T)" => :c23_t, "C23 (%T)" => :c23_t,
"C24 (%T)" => :c24_t, "C24 (%T)" => :c24_t,
"Total saturated fatty acids, equated (%T)" => :total_saturated_fatty_acids_equated_t, "Total saturated fatty acids, equated (%T)" => :total_saturated_fatty_acids_equated_t,
"C10:1 (%T)" => :c10_1_t, "C10:1 (%T)" => :c10_1_t,
"C12:1 (%T)" => :c12_1_t, "C12:1 (%T)" => :c12_1_t,
"C14:1 (%T)" => :c14_1_t, "C14:1 (%T)" => :c14_1_t,
"C15:1 (%T)" => :c15_1_t, "C15:1 (%T)" => :c15_1_t,
"C16:1 (%T)" => :c16_1_t, "C16:1 (%T)" => :c16_1_t,
"C17:1 (%T)" => :c17_1_t, "C17:1 (%T)" => :c17_1_t,
"C18:1 (%T)" => :c18_1_t, "C18:1 (%T)" => :c18_1_t,
"C18:1w5 (%T)" => :c18_1w5_t, "C18:1w5 (%T)" => :c18_1w5_t,
"C18:1w6 (%T)" => :c18_1w6_t, "C18:1w6 (%T)" => :c18_1w6_t,
"C18:1w7 (%T)" => :c18_1w7_t, "C18:1w7 (%T)" => :c18_1w7_t,
"C18:1w9 (%T)" => :c18_1w9_t, "C18:1w9 (%T)" => :c18_1w9_t,
"C20:1 (%T)" => :c20_1_t, "C20:1 (%T)" => :c20_1_t,
"C20:1w9 (%T)" => :c20_1w9_t, "C20:1w9 (%T)" => :c20_1w9_t,
"C20:1w13 (%T)" => :c20_1w13_t, "C20:1w13 (%T)" => :c20_1w13_t,
"C20:1w11 (%T)" => :c20_1w11_t, "C20:1w11 (%T)" => :c20_1w11_t,
"C22:1 (%T)" => :c22_1_t, "C22:1 (%T)" => :c22_1_t,
"C22:1w9 (%T)" => :c22_1w9_t, "C22:1w9 (%T)" => :c22_1w9_t,
"C22:1w11 (%T)" => :c22_1w11_t, "C22:1w11 (%T)" => :c22_1w11_t,
"C24:1 (%T)" => :c24_1_t, "C24:1 (%T)" => :c24_1_t,
"C24:1w9 (%T)" => :c24_1w9_t, "C24:1w9 (%T)" => :c24_1w9_t,
"C24:1w11 (%T)" => :c24_1w11_t, "C24:1w11 (%T)" => :c24_1w11_t,
"C24:1w13 (%T)" => :c24_1w13_t, "C24:1w13 (%T)" => :c24_1w13_t,
"Total monounsaturated fatty acids, equated (%T)" => :total_monounsaturated_fatty_acids_equated_t, "Total monounsaturated fatty acids, equated (%T)" => :total_monounsaturated_fatty_acids_equated_t,
"C12:2 (%T)" => :c12_2_t, "C12:2 (%T)" => :c12_2_t,
"C16:2w4 (%T)" => :c16_2w4_t, "C16:2w4 (%T)" => :c16_2w4_t,
"C16:3 (%T)" => :c16_3_t, "C16:3 (%T)" => :c16_3_t,
"C18:2w6 (%T)" => :c18_2w6_t, "C18:2w6 (%T)" => :c18_2w6_t,
"C18:3w3 (%T)" => :c18_3w3_t, "C18:3w3 (%T)" => :c18_3w3_t,
"C18:3w4 (%T)" => :c18_3w4_t, "C18:3w4 (%T)" => :c18_3w4_t,
"C18:3w6 (%T)" => :c18_3w6_t, "C18:3w6 (%T)" => :c18_3w6_t,
"C18:4w1 (%T)" => :c18_4w1_t, "C18:4w1 (%T)" => :c18_4w1_t,
"C18:4w3 (%T)" => :c18_4w3_t, "C18:4w3 (%T)" => :c18_4w3_t,
"C20:2 (%T)" => :c20_2_t, "C20:2 (%T)" => :c20_2_t,
"C20:2w6 (%T)" => :c20_2w6_t, "C20:2w6 (%T)" => :c20_2w6_t,
"C20:3 (%T)" => :c20_3_t, "C20:3 (%T)" => :c20_3_t,
"C20:4 (%T)" => :c20_4_t, "C20:4 (%T)" => :c20_4_t,
"C20:3w3 (%T)" => :c20_3w3_t, "C20:3w3 (%T)" => :c20_3w3_t,
"C20:3w6 (%T)" => :c20_3w6_t, "C20:3w6 (%T)" => :c20_3w6_t,
"C20:4w3 (%T)" => :c20_4w3_t, "C20:4w3 (%T)" => :c20_4w3_t,
"C20:4w6 (%T)" => :c20_4w6_t, "C20:4w6 (%T)" => :c20_4w6_t,
"C20:5w3 (%T)" => :c20_5w3_t, "C20:5w3 (%T)" => :c20_5w3_t,
"C21:5w3 (%T)" => :c21_5w3_t, "C21:5w3 (%T)" => :c21_5w3_t,
"C22:2 (%T)" => :c22_2_t, "C22:2 (%T)" => :c22_2_t,
"C22:2w6 (%T)" => :c22_2w6_t, "C22:2w6 (%T)" => :c22_2w6_t,
"C22:4w6 (%T)" => :c22_4w6_t, "C22:4w6 (%T)" => :c22_4w6_t,
"C22:5w3 (%T)" => :c22_5w3_t, "C22:5w3 (%T)" => :c22_5w3_t,
"C22:5w6 (%T)" => :c22_5w6_t, "C22:5w6 (%T)" => :c22_5w6_t,
"C22:6w3 (%T)" => :c22_6w3_t, "C22:6w3 (%T)" => :c22_6w3_t,
"Total polyunsaturated fatty acids, equated (%T)" => :total_polyunsaturated_fatty_acids_equated_t, "Total polyunsaturated fatty acids, equated (%T)" => :total_polyunsaturated_fatty_acids_equated_t,
"Total long chain omega 3 fatty acids, equated \n(%T)" => :total_long_chain_omega_3_fatty_acids_equated_t, "Total long chain omega 3 fatty acids, equated \n(%T)" => :total_long_chain_omega_3_fatty_acids_equated_t,
"Total undifferentiated fatty acids \n(%T)" => :total_undifferentiated_fatty_acids_t, "Total undifferentiated fatty acids \n(%T)" => :total_undifferentiated_fatty_acids_t,
"Total trans fatty acids, imputed \n(%T)" => :total_trans_fatty_acids_imputed_t, "Total trans fatty acids, imputed \n(%T)" => :total_trans_fatty_acids_imputed_t,
"C4 (g)" => :c4_g, "C4 (g)" => :c4_g,
"C6 (g)" => :c6_g, "C6 (g)" => :c6_g,
"C8 (g)" => :c8_g, "C8 (g)" => :c8_g,
"C10 (g)" => :c10_g, "C10 (g)" => :c10_g,
"C11 (g)" => :c11_g, "C11 (g)" => :c11_g,
"C12 (g)" => :c12_g, "C12 (g)" => :c12_g,
"C13 (g)" => :c13_g, "C13 (g)" => :c13_g,
"C14 (g)" => :c14_g, "C14 (g)" => :c14_g,
"C15 (g)" => :c15_g, "C15 (g)" => :c15_g,
"C16 (g)" => :c16_g, "C16 (g)" => :c16_g,
"C17 (g)" => :c17_g, "C17 (g)" => :c17_g,
"C18 (g)" => :c18_g, "C18 (g)" => :c18_g,
"C19 (g)" => :c19_g, "C19 (g)" => :c19_g,
"C20 (g)" => :c20_g, "C20 (g)" => :c20_g,
"C21 (g)" => :c21_g, "C21 (g)" => :c21_g,
"C22 (g)" => :c22_g, "C22 (g)" => :c22_g,
"C23 (g)" => :c23_g, "C23 (g)" => :c23_g,
"C24 (g)" => :c24_g, "C24 (g)" => :c24_g,
"Total saturated fatty acids, equated \n(g)" => :total_saturated_fatty_acids_equated_g, "Total saturated fatty acids, equated \n(g)" => :total_saturated_fatty_acids_equated_g,
"C10:1 (g)" => :c10_1_g, "C10:1 (g)" => :c10_1_g,
"C12:1 (g)" => :c12_1_g, "C12:1 (g)" => :c12_1_g,
"C14:1 (g)" => :c14_1_g, "C14:1 (g)" => :c14_1_g,
"C15:1 (g)" => :c15_1_g, "C15:1 (g)" => :c15_1_g,
"C16:1 (g)" => :c16_1_g, "C16:1 (g)" => :c16_1_g,
"C17:1 (g)" => :c17_1_g, "C17:1 (g)" => :c17_1_g,
"C18:1 (g)" => :c18_1_g, "C18:1 (g)" => :c18_1_g,
"C18:1w5 (mg)" => :c18_1w5_mg, "C18:1w5 (mg)" => :c18_1w5_mg,
"C18:1w6 (mg)" => :c18_1w6_mg, "C18:1w6 (mg)" => :c18_1w6_mg,
"C18:1w7 (g)" => :c18_1w7_g, "C18:1w7 (g)" => :c18_1w7_g,
"C18:1w9 (mg)" => :c18_1w9_mg, "C18:1w9 (mg)" => :c18_1w9_mg,
"C20:1 (g)" => :c20_1_g, "C20:1 (g)" => :c20_1_g,
"C20:1w9 (mg)" => :c20_1w9_mg, "C20:1w9 (mg)" => :c20_1w9_mg,
"C20:1w13 (mg)" => :c20_1w13_mg, "C20:1w13 (mg)" => :c20_1w13_mg,
"C20:1w11 (mg)" => :c20_1w11_mg, "C20:1w11 (mg)" => :c20_1w11_mg,
"C22:1 (g)" => :c22_1_g, "C22:1 (g)" => :c22_1_g,
"C22:1w9 (mg)" => :c22_1w9_mg, "C22:1w9 (mg)" => :c22_1w9_mg,
"C22:1w11 (mg)" => :c22_1w11_mg, "C22:1w11 (mg)" => :c22_1w11_mg,
"C24:1 (g)" => :c24_1_g, "C24:1 (g)" => :c24_1_g,
"C24:1w9 (mg)" => :c24_1w9_mg, "C24:1w9 (mg)" => :c24_1w9_mg,
"C24:1w11 (mg)" => :c24_1w11_mg, "C24:1w11 (mg)" => :c24_1w11_mg,
"C24:1w13 (mg)" => :c24_1w13_mg, "C24:1w13 (mg)" => :c24_1w13_mg,
"Total monounsaturated fatty acids, equated \n(g)" => :total_monounsaturated_fatty_acids_equated_g, "Total monounsaturated fatty acids, equated \n(g)" => :total_monounsaturated_fatty_acids_equated_g,
"C12:2 (g)" => :c12_2_g, "C12:2 (g)" => :c12_2_g,
"C16:2w4 (mg)" => :c16_2w4_mg, "C16:2w4 (mg)" => :c16_2w4_mg,
"C16:3 (g)" => :c16_3_g, "C16:3 (g)" => :c16_3_g,
"C18:2w6 (g)" => :c18_2w6_g, "C18:2w6 (g)" => :c18_2w6_g,
"C18:3w3 (g)" => :c18_3w3_g, "C18:3w3 (g)" => :c18_3w3_g,
"C18:3w4 (g)" => :c18_3w4_g, "C18:3w4 (g)" => :c18_3w4_g,
"C18:3w6 (mg)" => :c18_3w6_mg, "C18:3w6 (mg)" => :c18_3w6_mg,
"C18:4w1 (g)" => :c18_4w1_g, "C18:4w1 (g)" => :c18_4w1_g,
"C18:4w3 (mg)" => :c18_4w3_mg, "C18:4w3 (mg)" => :c18_4w3_mg,
"C20:2 (mg)" => :c20_2_mg, "C20:2 (mg)" => :c20_2_mg,
"C20:2w6 (mg)" => :c20_2w6_mg, "C20:2w6 (mg)" => :c20_2w6_mg,
"C20:3 (mg)" => :c20_3_mg, "C20:3 (mg)" => :c20_3_mg,
"C20:3w3 (mg)" => :c20_3w3_mg, "C20:3w3 (mg)" => :c20_3w3_mg,
"C20:3w6 (mg)" => :c20_3w6_mg, "C20:3w6 (mg)" => :c20_3w6_mg,
"C20:4 (g)" => :c20_4_g, "C20:4 (g)" => :c20_4_g,
"C20:4w3 (mg)" => :c20_4w3_mg, "C20:4w3 (mg)" => :c20_4w3_mg,
"C20:4w6 (mg)" => :c20_4w6_mg, "C20:4w6 (mg)" => :c20_4w6_mg,
"C20:5w3 (mg)" => :c20_5w3_mg, "C20:5w3 (mg)" => :c20_5w3_mg,
"C21:5w3 (g)" => :c21_5w3_g, "C21:5w3 (g)" => :c21_5w3_g,
"C22:5w3 (mg)" => :c22_5w3_mg, "C22:5w3 (mg)" => :c22_5w3_mg,
"C22:4w6 (mg)" => :c22_4w6_mg, "C22:4w6 (mg)" => :c22_4w6_mg,
"C22:2 (g)" => :c22_2_g, "C22:2 (g)" => :c22_2_g,
"C22:2w6 (mg)" => :c22_2w6_mg, "C22:2w6 (mg)" => :c22_2w6_mg,
"C22:5w6 (g)" => :c22_5w6_g, "C22:5w6 (g)" => :c22_5w6_g,
"C22:6w3 (mg)" => :c22_6w3_mg, "C22:6w3 (mg)" => :c22_6w3_mg,
"Total polyunsaturated fatty acids, equated \n(g)" => :total_polyunsaturated_fatty_acids_equated_g, "Total polyunsaturated fatty acids, equated \n(g)" => :total_polyunsaturated_fatty_acids_equated_g,
"Total long chain omega 3 fatty acids, equated \n(mg)" => :total_long_chain_omega_3_fatty_acids_equated_mg, "Total long chain omega 3 fatty acids, equated \n(mg)" => :total_long_chain_omega_3_fatty_acids_equated_mg,
"Total undifferentiated fatty acids, mass basis basis \n(mg)" => :total_undifferentiated_fatty_acids_mass_basis_basis_mg, "Total undifferentiated fatty acids, mass basis basis \n(mg)" => :total_undifferentiated_fatty_acids_mass_basis_basis_mg,
"Total trans fatty acids, imputed \n(mg)" => :total_trans_fatty_acids_imputed_mg, "Total trans fatty acids, imputed \n(mg)" => :total_trans_fatty_acids_imputed_mg,
"Caffeine \n(mg)" => :caffeine_mg, "Caffeine \n(mg)" => :caffeine_mg,
"Cholesterol \n(mg)" => :cholesterol_mg, "Cholesterol \n(mg)" => :cholesterol_mg,
"Alanine \n(mg/gN)" => :alanine_mg_gn, "Alanine \n(mg/gN)" => :alanine_mg_gn,
"Arginine \n(mg/gN)" => :arginine_mg_gn, "Arginine \n(mg/gN)" => :arginine_mg_gn,
"Aspartic acid \n(mg/gN)" => :aspartic_acid_mg_gn, "Aspartic acid \n(mg/gN)" => :aspartic_acid_mg_gn,
"Cystine plus cysteine \n(mg/gN)" => :cystine_plus_cysteine_mg_gn, "Cystine plus cysteine \n(mg/gN)" => :cystine_plus_cysteine_mg_gn,
"Glutamic acid \n(mg/gN)" => :glutamic_acid_mg_gn, "Glutamic acid \n(mg/gN)" => :glutamic_acid_mg_gn,
"Glycine \n(mg/gN)" => :glycine_mg_gn, "Glycine \n(mg/gN)" => :glycine_mg_gn,
"Histidine \n(mg/gN)" => :histidine_mg_gn, "Histidine \n(mg/gN)" => :histidine_mg_gn,
"Isoleucine \n(mg/gN)" => :isoleucine_mg_gn, "Isoleucine \n(mg/gN)" => :isoleucine_mg_gn,
"Leucine \n(mg/gN)" => :leucine_mg_gn, "Leucine \n(mg/gN)" => :leucine_mg_gn,
"Lysine \n(mg/gN)" => :lysine_mg_gn, "Lysine \n(mg/gN)" => :lysine_mg_gn,
"Methionine \n(mg/gN)" => :methionine_mg_gn, "Methionine \n(mg/gN)" => :methionine_mg_gn,
"Phenylalanine \n(mg/gN)" => :phenylalanine_mg_gn, "Phenylalanine \n(mg/gN)" => :phenylalanine_mg_gn,
"Proline \n(mg/gN)" => :proline_mg_gn, "Proline \n(mg/gN)" => :proline_mg_gn,
"Serine \n(mg/gN)" => :serine_mg_gn, "Serine \n(mg/gN)" => :serine_mg_gn,
"Threonine \n(mg/gN)" => :threonine_mg_gn, "Threonine \n(mg/gN)" => :threonine_mg_gn,
"Tyrosine \n(mg/gN)" => :tyrosine_mg_gn, "Tyrosine \n(mg/gN)" => :tyrosine_mg_gn,
"Tryptophan \n(mg/gN)" => :tryptophan_mg_gn, "Tryptophan \n(mg/gN)" => :tryptophan_mg_gn,
"Valine \n(mg/gN)" => :valine_mg_gn, "Valine \n(mg/gN)" => :valine_mg_gn,
"Alanine \n(mg)" => :alanine_mg, "Alanine \n(mg)" => :alanine_mg,
"Arginine \n(mg)" => :arginine_mg, "Arginine \n(mg)" => :arginine_mg,
"Aspartic acid \n(mg)" => :aspartic_acid_mg, "Aspartic acid \n(mg)" => :aspartic_acid_mg,
"Cystine plus cysteine \n(mg)" => :cystine_plus_cysteine_mg, "Cystine plus cysteine \n(mg)" => :cystine_plus_cysteine_mg,
"Glutamic acid \n(mg)" => :glutamic_acid_mg, "Glutamic acid \n(mg)" => :glutamic_acid_mg,
"Glycine \n(mg)" => :glycine_mg, "Glycine \n(mg)" => :glycine_mg,
"Histidine \n(mg)" => :histidine_mg, "Histidine \n(mg)" => :histidine_mg,
"Isoleucine \n(mg)" => :isoleucine_mg, "Isoleucine \n(mg)" => :isoleucine_mg,
"Leucine \n(mg)" => :leucine_mg, "Leucine \n(mg)" => :leucine_mg,
"Lysine \n(mg)" => :lysine_mg, "Lysine \n(mg)" => :lysine_mg,
"Methionine \n(mg)" => :methionine_mg, "Methionine \n(mg)" => :methionine_mg,
"Phenylalanine \n(mg)" => :phenylalanine_mg, "Phenylalanine \n(mg)" => :phenylalanine_mg,
"Proline \n(mg)" => :proline_mg, "Proline \n(mg)" => :proline_mg,
"Serine \n(mg)" => :serine_mg, "Serine \n(mg)" => :serine_mg,
"Threonine \n(mg)" => :threonine_mg, "Threonine \n(mg)" => :threonine_mg,
"Tyrosine \n(mg)" => :tyrosine_mg, "Tyrosine \n(mg)" => :tyrosine_mg,
"Tryptophan \n(mg)" => :tryptophan_mg, "Tryptophan \n(mg)" => :tryptophan_mg,
"Valine \n(mg)" => :valine_mg "Valine \n(mg)" => :valine_mg
}.freeze }.freeze
csv_file = File.read(Rails.root.join('lib', 'tasks', 'australian_food_classification_data.csv')) csv_file = File.read(Rails.root.join('lib', 'tasks', 'australian_food_classification_data.csv'))

View File

@@ -14,7 +14,7 @@ describe AdminController do
end end
describe 'assigns @members' do describe 'assigns @members' do
let!(:m) { create(:newsletter_recipient_member) } let!(:m) { FactoryBot.create(:newsletter_recipient_member) }
it { expect(assigns(:members)).to eq [m] } it { expect(assigns(:members)).to eq [m] }
end end

View File

@@ -2,17 +2,17 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Api::V1::PlantingsController do RSpec.describe Api::V1::PlantingsController, type: :controller do
subject { JSON.parse response.body } subject { JSON.parse response.body }
let!(:member) { create(:member) } let!(:member) { FactoryBot.create(:member) }
describe '#index' do describe '#index' do
let(:matching_planting) { subject['data'].select { |planting| planting['id'] == my_planting.id.to_s }.first } let(:matching_planting) { subject['data'].select { |planting| planting['id'] == my_planting.id.to_s }.first }
describe 'GET #index' do describe 'GET #index' do
context 'basic planting' do context 'basic planting' do
let!(:my_planting) { create(:planting, owner: member, planted_at: '2000-01-01') } let!(:my_planting) { FactoryBot.create(:planting, owner: member, planted_at: '2000-01-01') }
let(:expected_attributes) do let(:expected_attributes) do
{ {
'crop-name' => my_planting.crop.name, 'crop-name' => my_planting.crop.name,
@@ -42,11 +42,11 @@ RSpec.describe Api::V1::PlantingsController do
it { expect(matching_planting).to include('id' => my_planting.id.to_s) } it { expect(matching_planting).to include('id' => my_planting.id.to_s) }
it { expect(matching_planting['attributes']).to eq expected_attributes } it { expect(matching_planting['attributes']).to eq expected_attributes }
it { expect(response).to have_http_status :ok } it { expect(response.status).to eq 200 }
end end
context 'with photo' do context 'with photo' do
let!(:my_planting) { create(:planting, owner: member, planted_at: '2000-01-01') } let!(:my_planting) { FactoryBot.create(:planting, owner: member, planted_at: '2000-01-01') }
let(:expected_attributes) do let(:expected_attributes) do
{ {
@@ -72,7 +72,7 @@ RSpec.describe Api::V1::PlantingsController do
'thumbnail' => photo.thumbnail_url 'thumbnail' => photo.thumbnail_url
} }
end end
let(:photo) { create(:photo, owner: my_planting.owner) } let(:photo) { FactoryBot.create(:photo, owner: my_planting.owner) }
before do before do
my_planting.photos << photo my_planting.photos << photo
@@ -81,7 +81,7 @@ RSpec.describe Api::V1::PlantingsController do
it { expect(matching_planting).to include('id' => my_planting.id.to_s) } it { expect(matching_planting).to include('id' => my_planting.id.to_s) }
it { expect(matching_planting['attributes']).to eq expected_attributes } it { expect(matching_planting['attributes']).to eq expected_attributes }
it { expect(response).to have_http_status :ok } it { expect(response.status).to eq 200 }
end end
end end
end end

View File

@@ -4,10 +4,10 @@ require 'rails_helper'
describe AuthenticationsController do describe AuthenticationsController do
before do before do
@member = create(:member) @member = FactoryBot.create(:member)
sign_in @member sign_in @member
controller.stub(:current_member) { @member } controller.stub(:current_member) { @member }
@auth = create(:authentication, member: @member) @auth = FactoryBot.create(:authentication, member: @member)
request.env['omniauth.auth'] = { request.env['omniauth.auth'] = {
'provider' => 'foo', 'provider' => 'foo',
'uid' => 'bar', 'uid' => 'bar',

View File

@@ -4,7 +4,7 @@ require 'rails_helper'
describe Charts::CropsController do describe Charts::CropsController do
describe 'GET charts' do describe 'GET charts' do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
describe 'sunniness' do describe 'sunniness' do
before { get :sunniness, params: { crop_slug: crop.to_param } } before { get :sunniness, params: { crop_slug: crop.to_param } }

View File

@@ -5,7 +5,7 @@ require 'rails_helper'
describe Charts::GardensController do describe Charts::GardensController do
include Devise::Test::ControllerHelpers include Devise::Test::ControllerHelpers
let(:garden) { create(:garden) } let(:garden) { FactoryBot.create(:garden) }
context "when not signed in" do context "when not signed in" do
describe 'GET timeline' do describe 'GET timeline' do
@@ -18,7 +18,7 @@ describe Charts::GardensController do
context "when signed in" do context "when signed in" do
before { sign_in member } before { sign_in member }
let!(:member) { create(:member) } let!(:member) { FactoryBot.create(:member) }
describe 'GET timeline' do describe 'GET timeline' do
before { get :timeline, params: { garden_slug: garden.to_param } } before { get :timeline, params: { garden_slug: garden.to_param } }

View File

@@ -5,7 +5,7 @@ require 'rails_helper'
describe CommentsController do describe CommentsController do
subject { response } subject { response }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
before do before do
sign_in member sign_in member
@@ -13,13 +13,13 @@ describe CommentsController do
end end
def valid_attributes def valid_attributes
@post = create(:post) @post = FactoryBot.create(:post)
{ post_id: @post.id, body: "some text" } { post_id: @post.id, body: "some text" }
end end
describe "GET RSS feed" do describe "GET RSS feed" do
let!(:first_comment) { create(:comment, created_at: 10.days.ago) } let!(:first_comment) { FactoryBot.create(:comment, created_at: 10.days.ago) }
let!(:last_comment) { create(:comment, created_at: 4.minutes.ago) } let!(:last_comment) { FactoryBot.create(:comment, created_at: 4.minutes.ago) }
describe "returns an RSS feed" do describe "returns an RSS feed" do
before { get :index, format: "rss" } before { get :index, format: "rss" }
@@ -32,7 +32,7 @@ describe CommentsController do
end end
describe "GET new" do describe "GET new" do
let(:post) { create(:post) } let(:post) { FactoryBot.create(:post) }
describe "with valid params" do describe "with valid params" do
before do before do
@@ -41,7 +41,7 @@ describe CommentsController do
} }
end end
let(:old_comment) { create(:comment, commentable: post) } let(:old_comment) { FactoryBot.create(:comment, commentable: post) }
it "picks up post from params" do it "picks up post from params" do
expect(assigns(:commentable)).to eq(post) expect(assigns(:commentable)).to eq(post)
@@ -59,13 +59,13 @@ describe CommentsController do
end end
describe "GET edit" do describe "GET edit" do
let(:post) { create(:post) } let(:post) { FactoryBot.create(:post) }
before { get :edit, params: { id: comment.to_param } } before { get :edit, params: { id: comment.to_param } }
describe "my comment" do describe "my comment" do
let!(:comment) { create(:comment, author: member, commentable: post) } let!(:comment) { FactoryBot.create(:comment, author: member, commentable: post) }
let!(:old_comment) { create(:comment, commentable: post, created_at: Time.zone.yesterday) } let!(:old_comment) { FactoryBot.create(:comment, commentable: post, created_at: Time.zone.yesterday) }
it "assigns previous comments as @comments" do it "assigns previous comments as @comments" do
expect(assigns(:comments)).to eq([comment, old_comment]) expect(assigns(:comments)).to eq([comment, old_comment])
@@ -73,7 +73,7 @@ describe CommentsController do
end end
describe "not my comment" do describe "not my comment" do
let(:comment) { create(:comment, commentable: post) } let(:comment) { FactoryBot.create(:comment, commentable: post) }
it { expect(response).not_to be_successful } it { expect(response).not_to be_successful }
end end
@@ -83,7 +83,7 @@ describe CommentsController do
before { put :update, params: { id: comment.to_param, comment: valid_attributes } } before { put :update, params: { id: comment.to_param, comment: valid_attributes } }
describe "my comment" do describe "my comment" do
let(:comment) { create(:comment, author: member) } let(:comment) { FactoryBot.create(:comment, author: member) }
it "redirects to the comment's post" do it "redirects to the comment's post" do
expect(response).to redirect_to(comment.commentable) expect(response).to redirect_to(comment.commentable)
@@ -91,16 +91,16 @@ describe CommentsController do
end end
describe "not my comment" do describe "not my comment" do
let(:comment) { create(:comment) } let(:comment) { FactoryBot.create(:comment) }
it { expect(response).not_to be_successful } it { expect(response).not_to be_successful }
end end
describe "attempting to change post_id" do describe "attempting to change post_id" do
let(:post) { create(:post, subject: 'our post') } let(:post) { FactoryBot.create(:post, subject: 'our post') }
let(:other_post) { create(:post, subject: 'the other post') } let(:other_post) { FactoryBot.create(:post, subject: 'the other post') }
let(:valid_attributes) { { commentable_type: "Post", commentable_id: other_post.id, body: "kōrero" } } let(:valid_attributes) { { commentable_type: "Post", commentable_id: other_post.id, body: "kōrero" } }
let(:comment) { create(:comment, author: member, commentable: post) } let(:comment) { FactoryBot.create(:comment, author: member, commentable: post) }
it "does not change post_id" do it "does not change post_id" do
comment.reload comment.reload
@@ -113,7 +113,7 @@ describe CommentsController do
before { delete :destroy, params: { id: comment.to_param } } before { delete :destroy, params: { id: comment.to_param } }
describe "my comment" do describe "my comment" do
let(:comment) { create(:comment, author: member) } let(:comment) { FactoryBot.create(:comment, author: member) }
it "redirects to the post the comment was on" do it "redirects to the post the comment was on" do
expect(response).to redirect_to(comment.commentable) expect(response).to redirect_to(comment.commentable)
@@ -121,7 +121,7 @@ describe CommentsController do
end end
describe "not my comment" do describe "not my comment" do
let(:comment) { create(:comment) } let(:comment) { FactoryBot.create(:comment) }
it { expect(response).not_to be_successful } it { expect(response).not_to be_successful }
end end

View File

@@ -42,8 +42,8 @@ describe CropsController do
describe "GET crop search" do describe "GET crop search" do
describe 'fetches the crop search page' do describe 'fetches the crop search page' do
let!(:tomato) { create(:tomato) } let!(:tomato) { FactoryBot.create(:tomato) }
let!(:maize) { create(:maize) } let!(:maize) { FactoryBot.create(:maize) }
before { Crop.reindex } before { Crop.reindex }
@@ -140,7 +140,7 @@ describe CropsController do
describe 'DELETE destroy' do describe 'DELETE destroy' do
subject { delete :destroy, params: { slug: crop.to_param } } subject { delete :destroy, params: { slug: crop.to_param } }
let!(:crop) { create(:crop) } let!(:crop) { FactoryBot.create(:crop) }
context 'not logged in' do context 'not logged in' do
it { expect { subject }.not_to change(Crop, :count) } it { expect { subject }.not_to change(Crop, :count) }

View File

@@ -2,11 +2,11 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe GardenTypesController do RSpec.describe GardenTypesController, type: :controller do
include Devise::Test::ControllerHelpers include Devise::Test::ControllerHelpers
let(:valid_params) { { name: 'My second GardenType' } } let(:valid_params) { { name: 'My second GardenType' } }
let(:garden_type) { create(:garden_type) } let(:garden_type) { FactoryBot.create(:garden_type) }
context "when not signed in" do context "when not signed in" do
describe 'GET new' do describe 'GET new' do
@@ -54,7 +54,7 @@ RSpec.describe GardenTypesController do
context "when signed in as a member" do context "when signed in as a member" do
before { sign_in member } before { sign_in member }
let!(:member) { create(:member) } let!(:member) { FactoryBot.create(:member) }
describe "for any garden_type" do describe "for any garden_type" do
let(:any_garden_type) { double('garden_type') } let(:any_garden_type) { double('garden_type') }

View File

@@ -2,12 +2,12 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe GardensController do RSpec.describe GardensController, type: :controller do
include Devise::Test::ControllerHelpers include Devise::Test::ControllerHelpers
let(:valid_params) { { name: 'My second Garden' } } let(:valid_params) { { name: 'My second Garden' } }
let(:garden) { create(:garden) } let(:garden) { FactoryBot.create(:garden) }
context "when not signed in" do context "when not signed in" do
describe 'GET new' do describe 'GET new' do
@@ -55,7 +55,7 @@ RSpec.describe GardensController do
context "when signed in" do context "when signed in" do
before { sign_in member } before { sign_in member }
let!(:member) { create(:member) } let!(:member) { FactoryBot.create(:member) }
describe "for another member's garden" do describe "for another member's garden" do
let(:not_my_garden) { double('garden') } let(:not_my_garden) { double('garden') }

View File

@@ -8,19 +8,19 @@ describe HarvestsController, :search do
def valid_attributes def valid_attributes
{ {
owner_id: subject.current_member.id, owner_id: subject.current_member.id,
crop_id: create(:crop).id, crop_id: FactoryBot.create(:crop).id,
plant_part_id: create(:plant_part).id, plant_part_id: FactoryBot.create(:plant_part).id,
harvested_at: '2017-01-01' harvested_at: '2017-01-01'
} }
end end
describe "GET index" do describe "GET index" do
let!(:member1) { create(:member) } let!(:member1) { FactoryBot.create(:member) }
let(:member2) { create(:member) } let(:member2) { FactoryBot.create(:member) }
let(:tomato) { create(:tomato) } let(:tomato) { FactoryBot.create(:tomato) }
let(:maize) { create(:maize) } let(:maize) { FactoryBot.create(:maize) }
let!(:harvest1) { create(:harvest, owner_id: member1.id, crop_id: tomato.id) } let!(:harvest1) { FactoryBot.create(:harvest, owner_id: member1.id, crop_id: tomato.id) }
let!(:harvest2) { create(:harvest, owner_id: member2.id, crop_id: maize.id) } let!(:harvest2) { FactoryBot.create(:harvest, owner_id: member2.id, crop_id: maize.id) }
before { Harvest.reindex } before { Harvest.reindex }
@@ -51,7 +51,7 @@ describe HarvestsController, :search do
describe "generates a csv" do describe "generates a csv" do
before { get :index, format: "csv" } before { get :index, format: "csv" }
it { expect(response).to have_http_status :ok } it { expect(response.status).to eq 200 }
end end
end end
@@ -109,7 +109,7 @@ describe HarvestsController, :search do
end end
describe "links to planting" do describe "links to planting" do
let(:planting) { create(:planting, owner_id: member.id, garden: member.gardens.first) } let(:planting) { FactoryBot.create(:planting, owner_id: member.id, garden: member.gardens.first) }
before { post :create, params: { harvest: valid_attributes.merge(planting_id: planting.id) } } before { post :create, params: { harvest: valid_attributes.merge(planting_id: planting.id) } }
@@ -134,8 +134,8 @@ describe HarvestsController, :search do
end end
describe "not my planting" do describe "not my planting" do
let(:not_my_planting) { create(:planting) } let(:not_my_planting) { FactoryBot.create(:planting) }
let(:harvest) { create(:harvest) } let(:harvest) { FactoryBot.create(:harvest) }
describe "does not save planting_id" do describe "does not save planting_id" do
before do before do
@@ -153,7 +153,7 @@ describe HarvestsController, :search do
let(:harvest) { Harvest.create! valid_attributes } let(:harvest) { Harvest.create! valid_attributes }
it "updates the requested harvest" do it "updates the requested harvest" do
new_crop = create(:crop) new_crop = FactoryBot.create(:crop)
expect do expect do
put :update, params: { slug: harvest.to_param, harvest: { crop_id: new_crop.id } } put :update, params: { slug: harvest.to_param, harvest: { crop_id: new_crop.id } }
harvest.reload harvest.reload
@@ -190,8 +190,8 @@ describe HarvestsController, :search do
end end
describe "not my planting" do describe "not my planting" do
let(:not_my_planting) { create(:planting) } let(:not_my_planting) { FactoryBot.create(:planting) }
let(:harvest) { create(:harvest) } let(:harvest) { FactoryBot.create(:harvest) }
describe "does not save planting_id" do describe "does not save planting_id" do
before do before do

View File

@@ -0,0 +1,8 @@
# frozen_string_literal: true
require 'rails_helper'
describe HomeController do
describe "GET index" do
end
end

View File

@@ -3,9 +3,9 @@
require 'rails_helper' require 'rails_helper'
describe LikesController do describe LikesController do
let(:like) { create(:like, member:) } let(:like) { FactoryBot.create(:like, member:) }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:blogpost) { create(:post) } let(:blogpost) { FactoryBot.create(:post) }
before { sign_in member } before { sign_in member }
@@ -19,7 +19,10 @@ describe LikesController do
it { JSON.parse(response.body)["description"] == "1 like" } it { JSON.parse(response.body)["description"] == "1 like" }
describe "Liking someone else's post" do describe "Liking someone else's post" do
it { expect(response).to have_http_status(:created) } it { expect(response.code).to eq('201') }
end
describe "Liking your own post" do
end end
end end
@@ -29,14 +32,14 @@ describe LikesController do
it { expect(response.content_type).to eq "application/json; charset=utf-8" } it { expect(response.content_type).to eq "application/json; charset=utf-8" }
describe "un-liking something i liked before" do describe "un-liking something i liked before" do
it { expect(response).to have_http_status(:ok) } it { expect(response.code).to eq('200') }
it { JSON.parse(response.body)["description"] == "0 likes" } it { JSON.parse(response.body)["description"] == "0 likes" }
end end
describe "Deleting someone else's like" do describe "Deleting someone else's like" do
let(:like) { create(:like) } let(:like) { FactoryBot.create(:like) }
it { expect(response).to have_http_status(:forbidden) } it { expect(response.code).to eq('403') }
it { JSON.parse(response.body)["error"] == "Unable to like" } it { JSON.parse(response.body)["error"] == "Unable to like" }
end end
end end

View File

@@ -4,8 +4,8 @@ require 'rails_helper'
describe MembersController do describe MembersController do
before do before do
@member = create(:member) @member = FactoryBot.create(:member)
@flickr_auth = create(:flickr_authentication, member: @member) @flickr_auth = FactoryBot.create(:flickr_authentication, member: @member)
end end
describe "GET index" do describe "GET index" do
@@ -39,7 +39,7 @@ describe MembersController do
end end
it "doesn't show unconfirmed members" do it "doesn't show unconfirmed members" do
@member2 = create(:unconfirmed_member) @member2 = FactoryBot.create(:unconfirmed_member)
get :show, params: { slug: @member2.id } get :show, params: { slug: @member2.id }
expect(response).to have_http_status(:not_found) expect(response).to have_http_status(:not_found)
end end

View File

@@ -17,8 +17,8 @@ describe PhotoAssociationsController do
before { photo.harvests << harvest } before { photo.harvests << harvest }
describe "my harvest my photo" do describe "my harvest my photo" do
let(:harvest) { create(:harvest, owner: member) } let(:harvest) { FactoryBot.create(:harvest, owner: member) }
let(:photo) { create(:photo, owner: member) } let(:photo) { FactoryBot.create(:photo, owner: member) }
it "removes link" do it "removes link" do
expect { delete :destroy, params: valid_params }.to change { photo.harvests.count }.by(-1) expect { delete :destroy, params: valid_params }.to change { photo.harvests.count }.by(-1)
@@ -26,8 +26,8 @@ describe PhotoAssociationsController do
end end
describe "another member's harvest from another member's photo" do describe "another member's harvest from another member's photo" do
let(:harvest) { create(:harvest, owner: photo.owner) } let(:harvest) { FactoryBot.create(:harvest, owner: photo.owner) }
let(:photo) { create(:photo) } let(:photo) { FactoryBot.create(:photo) }
it do it do
expect do expect do

View File

@@ -7,7 +7,7 @@ describe PhotosController, :search do
describe 'GET index' do describe 'GET index' do
describe 'all photos' do describe 'all photos' do
let!(:photo) { create(:photo, :reindex) } let!(:photo) { FactoryBot.create(:photo, :reindex) }
before do before do
Photo.reindex Photo.reindex
@@ -21,10 +21,10 @@ describe PhotosController, :search do
end end
describe '#index crop photos' do describe '#index crop photos' do
let!(:photo) { create(:photo, :reindex, owner: member, title: 'no assocations photo') } let!(:photo) { FactoryBot.create(:photo, :reindex, owner: member, title: 'no assocations photo') }
let!(:crop_photo) { create(:photo, :reindex, owner: member, title: 'photos of planting') } let!(:crop_photo) { FactoryBot.create(:photo, :reindex, owner: member, title: 'photos of planting') }
let!(:planting) { create(:planting, :reindex, crop:, owner: member) } let!(:planting) { FactoryBot.create(:planting, :reindex, crop:, owner: member) }
let!(:crop) { create(:crop, :reindex) } let!(:crop) { FactoryBot.create(:crop, :reindex) }
before do before do
planting.photos << crop_photo planting.photos << crop_photo
@@ -49,12 +49,12 @@ describe PhotosController, :search do
end end
describe "GET new" do describe "GET new" do
let(:tomato) { create(:tomato) } let(:tomato) { FactoryBot.create(:tomato) }
let(:planting) { create(:planting, crop: tomato, owner: member) } let(:planting) { FactoryBot.create(:planting, crop: tomato, owner: member) }
let(:garden) { create(:garden, owner: member) } let(:garden) { FactoryBot.create(:garden, owner: member) }
let(:harvest) { create(:harvest, owner: member) } let(:harvest) { FactoryBot.create(:harvest, owner: member) }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let!(:auth) { create(:flickr_authentication, member:) } let!(:auth) { FactoryBot.create(:flickr_authentication, member:) }
before do before do
sign_in member sign_in member
@@ -97,11 +97,11 @@ describe PhotosController, :search do
link_url: "http://example.com") link_url: "http://example.com")
end end
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:garden) { create(:garden, owner: member) } let(:garden) { FactoryBot.create(:garden, owner: member) }
let(:planting) { create(:planting, garden:, owner: member) } let(:planting) { FactoryBot.create(:planting, garden:, owner: member) }
let(:harvest) { create(:harvest, owner: member) } let(:harvest) { FactoryBot.create(:harvest, owner: member) }
let(:photo) { create(:photo, owner: member) } let(:photo) { FactoryBot.create(:photo, owner: member) }
describe "with valid params" do describe "with valid params" do
before { controller.stub(:current_member) { member } } before { controller.stub(:current_member) { member } }
@@ -153,7 +153,7 @@ describe PhotosController, :search do
end end
it "doesn't attach photo to a comment" do it "doesn't attach photo to a comment" do
comment = create(:comment) comment = FactoryBot.create(:comment)
expect do expect do
post :create, params: { post :create, params: {
photo: { source_id: photo.source_id, source: 'flickr' }, type: "comment", id: comment.id photo: { source_id: photo.source_id, source: 'flickr' }, type: "comment", id: comment.id
@@ -163,7 +163,7 @@ describe PhotosController, :search do
end end
describe "for the second time" do describe "for the second time" do
let(:planting) { create(:planting, owner: member) } let(:planting) { FactoryBot.create(:planting, owner: member) }
let(:valid_params) { { photo: { source_id: 1 }, id: planting.id, type: 'planting' } } let(:valid_params) { { photo: { source_id: 1 }, id: planting.id, type: 'planting' } }
it "does not add a photo twice" do it "does not add a photo twice" do
@@ -176,8 +176,8 @@ describe PhotosController, :search do
before { controller.stub(:current_member) { member } } before { controller.stub(:current_member) { member } }
describe "creates the planting/photo link" do describe "creates the planting/photo link" do
let(:planting) { create(:planting, garden:, owner: member) } let(:planting) { FactoryBot.create(:planting, garden:, owner: member) }
let(:photo) { create(:photo, owner: member) } let(:photo) { FactoryBot.create(:photo, owner: member) }
before { post :create, params: { photo: { source_id: photo.source_id, source: 'flickr' }, type: "planting", id: planting.id } } before { post :create, params: { photo: { source_id: photo.source_id, source: 'flickr' }, type: "planting", id: planting.id } }
@@ -196,11 +196,11 @@ describe PhotosController, :search do
end end
describe "with mismatched owners" do describe "with mismatched owners" do
let(:photo) { create(:photo) } let(:photo) { FactoryBot.create(:photo) }
it "does not create the planting/photo link" do it "does not create the planting/photo link" do
# members will be auto-created, and different # members will be auto-created, and different
another_planting = create(:planting) another_planting = FactoryBot.create(:planting)
expect do expect do
post :create, params: { post :create, params: {
photo: { source_id: photo.source_id, source: 'flickr' }, photo: { source_id: photo.source_id, source: 'flickr' },
@@ -212,7 +212,7 @@ describe PhotosController, :search do
it "does not create the harvest/photo link" do it "does not create the harvest/photo link" do
# members will be auto-created, and different # members will be auto-created, and different
another_harvest = create(:harvest) another_harvest = FactoryBot.create(:harvest)
expect do expect do
post :create, params: { post :create, params: {
photo: { source_id: photo.source_id, source: 'flickr' }, type: "harvest", id: another_harvest.id photo: { source_id: photo.source_id, source: 'flickr' }, type: "harvest", id: another_harvest.id

View File

@@ -9,8 +9,8 @@ describe PlacesController do
describe "GET show" do describe "GET show" do
before do before do
@member_london = create(:london_member) @member_london = FactoryBot.create(:london_member)
@member_south_pole = create(:south_pole_member) @member_south_pole = FactoryBot.create(:south_pole_member)
end end
it "assigns place name" do it "assigns place name" do

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
require 'rails_helper'
describe PlantPartsController do
end

View File

@@ -7,18 +7,18 @@ describe PlantingsController, :search do
def valid_attributes def valid_attributes
{ {
garden_id: create(:garden, owner: subject.current_member).id, garden_id: FactoryBot.create(:garden, owner: subject.current_member).id,
crop_id: create(:crop).id crop_id: FactoryBot.create(:crop).id
} }
end end
describe "GET index", :search do describe "GET index", :search do
let!(:member1) { create(:member) } let!(:member1) { FactoryBot.create(:member) }
let!(:member2) { create(:member) } let!(:member2) { FactoryBot.create(:member) }
let!(:tomato) { create(:tomato) } let!(:tomato) { FactoryBot.create(:tomato) }
let!(:maize) { create(:maize) } let!(:maize) { FactoryBot.create(:maize) }
let!(:planting1) { create(:planting, crop: tomato, owner: member1, created_at: 1.day.ago) } let!(:planting1) { FactoryBot.create(:planting, crop: tomato, owner: member1, created_at: 1.day.ago) }
let!(:planting2) { create(:planting, crop: maize, owner: member2, created_at: 5.days.ago) } let!(:planting2) { FactoryBot.create(:planting, crop: maize, owner: member2, created_at: 5.days.ago) }
before do before do
Planting.reindex Planting.reindex
@@ -50,7 +50,7 @@ describe PlantingsController, :search do
describe "GET new" do describe "GET new" do
describe "picks up crop from params" do describe "picks up crop from params" do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
before { get :new, params: { crop_id: crop.id } } before { get :new, params: { crop_id: crop.id } }
@@ -64,7 +64,7 @@ describe PlantingsController, :search do
end end
describe "picks up member's garden from params" do describe "picks up member's garden from params" do
let(:garden) { create(:garden, owner: member) } let(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { garden_id: garden.id } } before { get :new, params: { garden_id: garden.id } }
@@ -72,8 +72,8 @@ describe PlantingsController, :search do
end end
describe "Doesn't display another member's garden on planting form" do describe "Doesn't display another member's garden on planting form" do
let(:another_member) { create(:member) } # over-riding member from login_member() let(:another_member) { FactoryBot.create(:member) } # over-riding member from login_member()
let(:garden) { create(:garden, owner: another_member) } let(:garden) { FactoryBot.create(:garden, owner: another_member) }
before { get :new, params: { garden_id: garden.id } } before { get :new, params: { garden_id: garden.id } }
@@ -81,8 +81,8 @@ describe PlantingsController, :search do
end end
describe "Doesn't display un-approved crops on planting form" do describe "Doesn't display un-approved crops on planting form" do
let(:crop) { create(:crop, approval_status: 'pending') } let(:crop) { FactoryBot.create(:crop, approval_status: 'pending') }
let!(:garden) { create(:garden, owner: member) } let!(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { crop_id: crop.id } } before { get :new, params: { crop_id: crop.id } }
@@ -90,8 +90,8 @@ describe PlantingsController, :search do
end end
describe "Doesn't display rejected crops on planting form" do describe "Doesn't display rejected crops on planting form" do
let(:crop) { create(:crop, approval_status: 'rejected', reason_for_rejection: 'nope') } let(:crop) { FactoryBot.create(:crop, approval_status: 'rejected', reason_for_rejection: 'nope') }
let!(:garden) { create(:garden, owner: member) } let!(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { crop_id: crop.id } } before { get :new, params: { crop_id: crop.id } }
@@ -111,7 +111,7 @@ describe PlantingsController, :search do
end end
context 'with parent seed' do context 'with parent seed' do
let(:seed) { create(:seed, owner: member) } let(:seed) { FactoryBot.create(:seed, owner: member) }
before { get :new, params: { seed_id: seed.to_param } } before { get :new, params: { seed_id: seed.to_param } }
@@ -128,8 +128,8 @@ describe PlantingsController, :search do
end end
describe 'GET :edit' do describe 'GET :edit' do
let(:my_planting) { create(:planting, owner: member) } let(:my_planting) { FactoryBot.create(:planting, owner: member) }
let(:not_my_planting) { create(:planting) } let(:not_my_planting) { FactoryBot.create(:planting) }
context 'my planting' do context 'my planting' do
before { get :edit, params: { slug: my_planting } } before { get :edit, params: { slug: my_planting } }

View File

@@ -6,14 +6,14 @@ describe PostsController do
login_member login_member
def valid_attributes def valid_attributes
member = create(:member) member = FactoryBot.create(:member)
{ author_id: member.id, subject: "blah", body: "blah blah" } { author_id: member.id, subject: "blah", body: "blah blah" }
end end
describe '#index' do describe '#index' do
before do before do
create_list(:post, 100) FactoryBot.create_list(:post, 100)
create_list(:post, 5, author: member) FactoryBot.create_list(:post, 5, author: member)
end end
describe "everyone's posts" do describe "everyone's posts" do

View File

@@ -4,7 +4,7 @@ require 'rails_helper'
describe RegistrationsController do describe RegistrationsController do
before do before do
@member = create(:member) @member = FactoryBot.create(:member)
sign_in @member sign_in @member
controller.stub(:current_user) { @member } controller.stub(:current_user) { @member }
controller.stub(:devise_mapping).and_return(Devise.mappings[:member]) controller.stub(:devise_mapping).and_return(Devise.mappings[:member])
@@ -17,7 +17,7 @@ describe RegistrationsController do
end end
it "picks up the flickr auth" do it "picks up the flickr auth" do
@auth = create(:flickr_authentication, member: @member) @auth = FactoryBot.create(:flickr_authentication, member: @member)
get :edit get :edit
assigns(:flickr_auth).should eq @auth assigns(:flickr_auth).should eq @auth
end end

View File

@@ -5,7 +5,7 @@ require 'rails_helper'
describe ScientificNamesController do describe ScientificNamesController do
login_member(:crop_wrangling_member) login_member(:crop_wrangling_member)
let!(:crop) { create(:tomato) } let!(:crop) { FactoryBot.create(:tomato) }
def valid_attributes def valid_attributes
{ name: 'Solanum lycopersicum', crop_id: crop.id } { name: 'Solanum lycopersicum', crop_id: crop.id }

View File

@@ -3,7 +3,7 @@
require 'rails_helper' require 'rails_helper'
describe SeedsController, :search do describe SeedsController, :search do
let(:owner) { create(:member) } let(:owner) { FactoryBot.create(:member) }
describe "GET index" do describe "GET index" do
describe "picks up owner from params" do describe "picks up owner from params" do
@@ -26,7 +26,7 @@ describe SeedsController, :search do
end end
context 'with parent planting' do context 'with parent planting' do
let!(:planting) { create(:planting, owner:) } let!(:planting) { FactoryBot.create(:planting, owner:) }
before do before do
Seed.reindex Seed.reindex

View File

@@ -0,0 +1,6 @@
# frozen_string_literal: true
FactoryBot.define do
factory :crop_companion do
end
end

View File

@@ -73,13 +73,13 @@ describe "Conversations", :js do
click_link recipient.login_name click_link recipient.login_name
click_link 'Inbox' click_link 'Inbox'
expect(page).to have_css('.sent') expect(page).to have_selector('.sent')
find('.sent').click find('.sent').click
all('input[type=checkbox]').each(&:click) all('input[type=checkbox]').each(&:click)
click_button 'Delete' click_button 'Delete'
expect(page).to have_css('.sent') expect(page).to have_selector('.sent')
find('.sent').click find('.sent').click
expect(page).to have_no_content 'this is a message' expect(page).to have_no_content 'this is a message'
expect(page).to have_no_content 'this is another message' expect(page).to have_no_content 'this is another message'

View File

@@ -3,10 +3,10 @@
require 'rails_helper' require 'rails_helper'
describe "browse crops", :search do describe "browse crops", :search do
let!(:tomato) { create(:tomato, :reindex) } let!(:tomato) { FactoryBot.create(:tomato, :reindex) }
let!(:maize) { create(:maize, :reindex) } let!(:maize) { FactoryBot.create(:maize, :reindex) }
let!(:pending_crop) { create(:crop_request, :reindex) } let!(:pending_crop) { FactoryBot.create(:crop_request, :reindex) }
let!(:rejected_crop) { create(:rejected_crop, :reindex) } let!(:rejected_crop) { FactoryBot.create(:rejected_crop, :reindex) }
shared_examples 'shows crops' do shared_examples 'shows crops' do
before do before do

View File

@@ -14,7 +14,7 @@ describe "crop detail page", :js do
end end
before do before do
create(:plant_part, name: 'leaf') FactoryBot.create(:plant_part, name: 'leaf')
end end
let(:crop) { create(:crop) } let(:crop) { create(:crop) }
@@ -112,14 +112,14 @@ describe "crop detail page", :js do
describe 'with harvest history data' do describe 'with harvest history data' do
before do before do
# 50 days to harvest # 50 days to harvest
create(:harvest, harvested_at: 150.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 150.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
# 20 days to harvest # 20 days to harvest
create(:harvest, harvested_at: 180.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 180.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
# 10 days to harvest # 10 days to harvest
create(:harvest, harvested_at: 190.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 190.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
crop.update_medians crop.update_medians
end end
@@ -131,13 +131,13 @@ describe "crop detail page", :js do
context 'predictions' do context 'predictions' do
let!(:planting) do let!(:planting) do
create(:planting, crop:, FactoryBot.create(:planting, crop:,
planted_at: 100.days.ago, planted_at: 100.days.ago,
finished_at: 1.day.ago) finished_at: 1.day.ago)
end end
context 'crop is an Annual' do context 'crop is an Annual' do
let(:crop) { create(:annual_crop) } let(:crop) { FactoryBot.create(:annual_crop) }
describe 'with harvests' do describe 'with harvests' do
it_behaves_like "predicts harvest" it_behaves_like "predicts harvest"
@@ -155,7 +155,10 @@ describe "crop detail page", :js do
end end
context 'crop is Perennial' do context 'crop is Perennial' do
let(:crop) { create(:perennial_crop) } let(:crop) { FactoryBot.create(:perennial_crop) }
describe 'with no harvests' do
end
describe 'with harvests' do describe 'with harvests' do
it_behaves_like "predicts harvest" it_behaves_like "predicts harvest"
@@ -168,7 +171,10 @@ describe "crop detail page", :js do
end end
context 'crop Perennial value is null' do context 'crop Perennial value is null' do
let(:crop) { create(:crop, perennial: nil) } let(:crop) { FactoryBot.create(:crop, perennial: nil) }
describe 'with no harvests' do
end
describe 'with harvests' do describe 'with harvests' do
it_behaves_like "predicts harvest" it_behaves_like "predicts harvest"
@@ -180,7 +186,7 @@ describe "crop detail page", :js do
before { visit crop_path(crop) } before { visit crop_path(crop) }
context 'crop is an Annual' do context 'crop is an Annual' do
let(:crop) { create(:annual_crop) } let(:crop) { FactoryBot.create(:annual_crop) }
it { expect(page).to have_text 'Annual' } it { expect(page).to have_text 'Annual' }
it { expect(page).to have_text 'living and reproducing in a single year or less' } it { expect(page).to have_text 'living and reproducing in a single year or less' }
@@ -188,7 +194,7 @@ describe "crop detail page", :js do
end end
context 'crop is Perennial' do context 'crop is Perennial' do
let(:crop) { create(:perennial_crop) } let(:crop) { FactoryBot.create(:perennial_crop) }
it { expect(find('.index-cards.facts')).to have_text 'Perennial' } it { expect(find('.index-cards.facts')).to have_text 'Perennial' }
it { expect(page).to have_text 'living more than two years' } it { expect(page).to have_text 'living more than two years' }
@@ -196,7 +202,7 @@ describe "crop detail page", :js do
end end
context 'crop Perennial value is null' do context 'crop Perennial value is null' do
let(:crop) { create(:crop, perennial: nil) } let(:crop) { FactoryBot.create(:crop, perennial: nil) }
it { expect(find('.index-cards.facts')).to have_no_text 'Perennial' } it { expect(find('.index-cards.facts')).to have_no_text 'Perennial' }
it { expect(page).to have_no_text 'Annual' } it { expect(page).to have_no_text 'Annual' }

View File

@@ -5,22 +5,22 @@ require 'rails_helper'
describe "crop detail page", :js, :search do describe "crop detail page", :js, :search do
subject { page } subject { page }
let!(:owner_member) { create(:member) } let!(:owner_member) { FactoryBot.create(:member) }
let!(:crop) { create(:crop, :reindex) } let!(:crop) { FactoryBot.create(:crop, :reindex) }
let(:plant_part) { create(:plant_part, name: 'fruit') } let(:plant_part) { FactoryBot.create(:plant_part, name: 'fruit') }
let!(:harvest) { create(:harvest, crop:, owner: owner_member, plant_part:) } let!(:harvest) { FactoryBot.create(:harvest, crop:, owner: owner_member, plant_part:) }
let!(:planting) { create(:planting, crop:, owner: owner_member) } let!(:planting) { FactoryBot.create(:planting, crop:, owner: owner_member) }
let!(:seed) { create(:seed, crop:, owner: owner_member) } let!(:seed) { FactoryBot.create(:seed, crop:, owner: owner_member) }
let!(:photo1) { create(:photo, owner: owner_member) } let!(:photo1) { FactoryBot.create(:photo, owner: owner_member) }
let!(:photo2) { create(:photo, owner: owner_member) } let!(:photo2) { FactoryBot.create(:photo, owner: owner_member) }
let!(:photo3) { create(:photo, owner: owner_member) } let!(:photo3) { FactoryBot.create(:photo, owner: owner_member) }
let!(:photo4) { create(:photo, owner: owner_member) } let!(:photo4) { FactoryBot.create(:photo, owner: owner_member) }
let!(:photo5) { create(:photo, owner: owner_member) } let!(:photo5) { FactoryBot.create(:photo, owner: owner_member) }
let!(:photo6) { create(:photo, owner: owner_member) } let!(:photo6) { FactoryBot.create(:photo, owner: owner_member) }
before do before do
planting.photos << photo1 planting.photos << photo1

View File

@@ -4,8 +4,8 @@ require 'rails_helper'
describe "Delete crop spec" do describe "Delete crop spec" do
shared_examples 'delete crop' do shared_examples 'delete crop' do
let!(:pending_crop) { create(:crop_request) } let!(:pending_crop) { FactoryBot.create(:crop_request) }
let!(:approved_crop) { create(:crop) } let!(:approved_crop) { FactoryBot.create(:crop) }
it "deletes approved crop" do it "deletes approved crop" do
visit crop_path(approved_crop) visit crop_path(approved_crop)
click_link 'Actions' click_link 'Actions'

View File

@@ -3,7 +3,7 @@
require 'rails_helper' require 'rails_helper'
describe "browse crops" do describe "browse crops" do
let(:tomato) { create(:tomato) } let(:tomato) { FactoryBot.create(:tomato) }
it "Show crop info" do it "Show crop info" do
visit crop_path(tomato) visit crop_path(tomato)
@@ -11,9 +11,9 @@ describe "browse crops" do
end end
describe "shows varieties" do describe "shows varieties" do
let!(:cherry) { create(:crop, name: 'cherry tomato', parent: tomato) } let!(:cherry) { FactoryBot.create(:crop, name: 'cherry tomato', parent: tomato) }
let!(:heirloom) { create(:crop, name: 'heirloom tomato', parent: tomato) } let!(:heirloom) { FactoryBot.create(:crop, name: 'heirloom tomato', parent: tomato) }
let!(:striped) { create(:crop, name: 'striped tomato', parent: heirloom) } let!(:striped) { FactoryBot.create(:crop, name: 'striped tomato', parent: heirloom) }
before { visit crop_path(tomato) } before { visit crop_path(tomato) }
@@ -23,10 +23,10 @@ describe "browse crops" do
end end
context "when the most recently created harvest is not the most recently harvested" do context "when the most recently created harvest is not the most recently harvested" do
before { create_list(:harvest, 20, crop: tomato, harvested_at: 1.year.ago, created_at: 1.minute.ago) } before { FactoryBot.create_list(:harvest, 20, crop: tomato, harvested_at: 1.year.ago, created_at: 1.minute.ago) }
let!(:most_recent_harvest) do let!(:most_recent_harvest) do
create(:harvest, crop: tomato, harvested_at: 60.minutes.ago, created_at: 10.minutes.ago) FactoryBot.create(:harvest, crop: tomato, harvested_at: 60.minutes.ago, created_at: 10.minutes.ago)
end end
it "Shows most recently harvested harvest" do it "Shows most recently harvested harvest" do
@@ -36,10 +36,10 @@ describe "browse crops" do
end end
context "when the most recently created planting is not the most recently planted" do context "when the most recently created planting is not the most recently planted" do
before { create_list(:planting, 20, crop: tomato, planted_at: 1.year.ago, created_at: 1.minute.ago) } before { FactoryBot.create_list(:planting, 20, crop: tomato, planted_at: 1.year.ago, created_at: 1.minute.ago) }
let!(:most_recent_planting) do let!(:most_recent_planting) do
create(:planting, crop: tomato, planted_at: 60.minutes.ago, created_at: 10.minutes.ago) FactoryBot.create(:planting, crop: tomato, planted_at: 60.minutes.ago, created_at: 10.minutes.ago)
end end
it "Shows most recently planted planting" do it "Shows most recently planted planting" do

View File

@@ -10,7 +10,7 @@ describe "footer" do
end end
it 'has the Open Service link and graphic' do it 'has the Open Service link and graphic' do
expect(page).to have_css 'a[href="https://opendefinition.org/ossd/"]' expect(page).to have_selector 'a[href="https://opendefinition.org/ossd/"]'
end end
# NB: not testing specific content in the footer since I'm going to put them # NB: not testing specific content in the footer since I'm going to put them

View File

@@ -9,7 +9,7 @@ describe "Gardens" do
include_context 'signed in member' include_context 'signed in member'
let(:garden) { member.gardens.first } let(:garden) { member.gardens.first }
let(:other_member_garden) { create(:garden) } let(:other_member_garden) { FactoryBot.create(:garden) }
describe '#index' do describe '#index' do
shared_examples "has buttons bar at top" do shared_examples "has buttons bar at top" do
@@ -47,7 +47,7 @@ describe "Gardens" do
end end
context "other member's garden" do context "other member's garden" do
before { visit gardens_path(member_slug: create(:member).slug) } before { visit gardens_path(member_slug: FactoryBot.create(:member).slug) }
include_examples "has buttons bar at top" include_examples "has buttons bar at top"
describe 'does not show actions on other member garden' do describe 'does not show actions on other member garden' do

View File

@@ -11,10 +11,10 @@ describe "Gardens", :js do
include_examples 'is accessible' include_examples 'is accessible'
it "displays required and optional fields properly" do it "displays required and optional fields properly" do
expect(page).to have_css ".required", text: "Name" expect(page).to have_selector ".required", text: "Name"
expect(page).to have_css 'textarea#garden_description' expect(page).to have_selector 'textarea#garden_description'
expect(page).to have_css 'input#garden_location' expect(page).to have_selector 'input#garden_location'
expect(page).to have_css 'input#garden_area' expect(page).to have_selector 'input#garden_area'
end end
it "Create new garden" do it "Create new garden" do

View File

@@ -6,11 +6,11 @@ require 'custom_matchers'
describe "Gardens#index", :js do describe "Gardens#index", :js do
context "Logged in as member" do context "Logged in as member" do
include_context 'signed in member' include_context 'signed in member'
let(:member) { create(:member, login_name: 'shadow') } let(:member) { FactoryBot.create(:member, login_name: 'shadow') }
context "with 10 gardens" do context "with 10 gardens" do
before do before do
create_list(:garden, 10, owner: member) FactoryBot.create_list(:garden, 10, owner: member)
visit member_gardens_path(member_slug: member.slug) visit member_gardens_path(member_slug: member.slug)
end end
@@ -30,8 +30,8 @@ describe "Gardens#index", :js do
end end
context "with inactive gardens" do context "with inactive gardens" do
let!(:active_garden) { create(:garden, name: "My active garden", owner: member) } let!(:active_garden) { FactoryBot.create(:garden, name: "My active garden", owner: member) }
let!(:inactive_garden) { create(:inactive_garden, name: "retired garden", owner: member) } let!(:inactive_garden) { FactoryBot.create(:inactive_garden, name: "retired garden", owner: member) }
before { visit member_gardens_path(member_slug: member.slug) } before { visit member_gardens_path(member_slug: member.slug) }
@@ -53,14 +53,14 @@ describe "Gardens#index", :js do
end end
context 'with plantings' do context 'with plantings' do
let(:maize) { create(:maize) } let(:maize) { FactoryBot.create(:maize) }
let(:tomato) { create(:tomato) } let(:tomato) { FactoryBot.create(:tomato) }
let!(:planting) do let!(:planting) do
create(:planting, owner: member, crop: maize, garden: member.gardens.first) FactoryBot.create(:planting, owner: member, crop: maize, garden: member.gardens.first)
end end
let!(:finished_planting) do let!(:finished_planting) do
create(:finished_planting, owner: member, crop: tomato, garden: member.gardens.first) FactoryBot.create(:finished_planting, owner: member, crop: tomato, garden: member.gardens.first)
end end
before do before do
@@ -79,19 +79,19 @@ describe "Gardens#index", :js do
describe 'badges' do describe 'badges' do
let(:garden) { member.gardens.first } let(:garden) { member.gardens.first }
let(:member) { create(:member, login_name: 'robbieburns') } let(:member) { FactoryBot.create(:member, login_name: 'robbieburns') }
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
before do before do
# time to harvest = 50 day # time to harvest = 50 day
# time to finished = 90 days # time to finished = 90 days
create(:harvest, FactoryBot.create(:harvest,
harvested_at: 50.days.ago, harvested_at: 50.days.ago,
crop:, crop:,
planting: create(:planting, planting: FactoryBot.create(:planting,
crop:, crop:,
planted_at: 100.days.ago, planted_at: 100.days.ago,
finished_at: 10.days.ago)) finished_at: 10.days.ago))
crop.plantings.each(&:update_harvest_days!) crop.plantings.each(&:update_harvest_days!)
crop.update_lifespan_medians crop.update_lifespan_medians
crop.update_harvest_medians crop.update_harvest_medians
@@ -103,11 +103,11 @@ describe "Gardens#index", :js do
describe 'harvest still growing' do describe 'harvest still growing' do
let!(:planting) do let!(:planting) do
create(:planting, FactoryBot.create(:planting,
crop:, crop:,
owner: member, owner: member,
garden:, garden:,
planted_at: Time.zone.today) planted_at: Time.zone.today)
end end
it { expect(page).to have_link href: planting_path(planting) } it { expect(page).to have_link href: planting_path(planting) }
@@ -118,10 +118,10 @@ describe "Gardens#index", :js do
describe 'harvesting now' do describe 'harvesting now' do
let!(:planting) do let!(:planting) do
create(:planting, FactoryBot.create(:planting,
crop:, crop:,
owner: member, garden:, owner: member, garden:,
planted_at: 51.days.ago) planted_at: 51.days.ago)
end end
it { expect(crop.median_days_to_first_harvest).to eq 50 } it { expect(crop.median_days_to_first_harvest).to eq 50 }
@@ -133,9 +133,9 @@ describe "Gardens#index", :js do
describe 'super late' do describe 'super late' do
let!(:planting) do let!(:planting) do
create(:planting, FactoryBot.create(:planting,
crop:, owner: member, crop:, owner: member,
garden:, planted_at: 260.days.ago) garden:, planted_at: 260.days.ago)
end end
it { expect(page).to have_text 'super late' } it { expect(page).to have_text 'super late' }

View File

@@ -14,10 +14,10 @@ describe "Harvesting a crop", :js, :search do
it_behaves_like "crop suggest", "harvest", "crop" it_behaves_like "crop suggest", "harvest", "crop"
describe "displays required and optional fields properly" do describe "displays required and optional fields properly" do
it { expect(page).to have_css ".required", text: "What did you harvest?" } it { expect(page).to have_selector ".required", text: "What did you harvest?" }
it { expect(page).to have_css 'input#harvest_quantity' } it { expect(page).to have_selector 'input#harvest_quantity' }
it { expect(page).to have_css 'input#harvest_weight_quantity' } it { expect(page).to have_selector 'input#harvest_weight_quantity' }
it { expect(page).to have_css 'textarea#harvest_description' } it { expect(page).to have_selector 'textarea#harvest_description' }
end end
it "Creating a new harvest", :js do it "Creating a new harvest", :js do

View File

@@ -5,18 +5,18 @@ require 'rails_helper'
describe "home page", :search do describe "home page", :search do
subject { page } subject { page }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:photo) { create(:photo, owner: member) } let(:photo) { FactoryBot.create(:photo, owner: member) }
let(:crop) { create(:crop, created_at: 1.day.ago) } let(:crop) { FactoryBot.create(:crop, created_at: 1.day.ago) }
let(:planting) { create(:planting, owner: member, crop:) } let(:planting) { FactoryBot.create(:planting, owner: member, crop:) }
let(:seed) { create(:tradable_seed, owner: member, crop:) } let(:seed) { FactoryBot.create(:tradable_seed, owner: member, crop:) }
let(:harvest) { create(:harvest, owner: member, crop:) } let(:harvest) { FactoryBot.create(:harvest, owner: member, crop:) }
let!(:tradable_seed) { create(:tradable_seed, :reindex, finished: false) } let!(:tradable_seed) { FactoryBot.create(:tradable_seed, :reindex, finished: false) }
let!(:finished_seed) { create(:tradable_seed, :reindex, finished: true) } let!(:finished_seed) { FactoryBot.create(:tradable_seed, :reindex, finished: true) }
let!(:untradable_seed) { create(:untradable_seed, :reindex) } let!(:untradable_seed) { FactoryBot.create(:untradable_seed, :reindex) }
before do before do
# Add photos, so they can appear on home page # Add photos, so they can appear on home page

View File

@@ -3,12 +3,12 @@
require 'rails_helper' require 'rails_helper'
describe 'Likeable', :js, :search do describe 'Likeable', :js, :search do
let(:another_member) { create(:london_member) } let(:another_member) { FactoryBot.create(:london_member) }
let!(:post) { create(:post, :reindex, author: member) } let!(:post) { FactoryBot.create(:post, :reindex, author: member) }
let!(:activity) { create(:activity, :reindex, owner: member) } let!(:activity) { FactoryBot.create(:activity, :reindex, owner: member) }
let!(:photo) { create(:photo, :reindex, owner: member) } let!(:photo) { FactoryBot.create(:photo, :reindex, owner: member) }
let!(:harvest) { create(:harvest, :reindex, owner: member) } let!(:harvest) { FactoryBot.create(:harvest, :reindex, owner: member) }
let!(:planting) { create(:planting, :reindex, owner: member) } let!(:planting) { FactoryBot.create(:planting, :reindex, owner: member) }
before do before do
Photo.reindex Photo.reindex
@@ -68,8 +68,8 @@ describe 'Likeable', :js, :search do
end end
describe 'crops#show' do describe 'crops#show' do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
let(:planting) { create(:planting, owner: member, crop:) } let(:planting) { FactoryBot.create(:planting, owner: member, crop:) }
let(:path) { crop_path(crop) } let(:path) { crop_path(crop) }
before { planting.photos << photo } before { planting.photos << photo }

View File

@@ -5,7 +5,7 @@ require 'rails_helper'
describe "Changing locales", :js do describe "Changing locales", :js do
after { I18n.locale = :en } after { I18n.locale = :en }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
it "Locale can be set with a query param" do it "Locale can be set with a query param" do
# Login then log out, to ensure we're now logged out # Login then log out, to ensure we're now logged out

View File

@@ -3,8 +3,8 @@
require 'rails_helper' require 'rails_helper'
describe "members list" do describe "members list" do
let!(:spammer) { create(:member) } let!(:spammer) { FactoryBot.create(:member) }
let!(:admin) { create(:admin_member) } let!(:admin) { FactoryBot.create(:admin_member) }
context 'logged in as admin' do context 'logged in as admin' do
include_context 'signed in admin' include_context 'signed in admin'

View File

@@ -4,26 +4,26 @@ require 'rails_helper'
describe "member deletion", :flaky do describe "member deletion", :flaky do
context "with activity and followers" do context "with activity and followers" do
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:other_member) { create(:member) } let(:other_member) { FactoryBot.create(:member) }
let(:memberpost) { create(:post, author: member) } let(:memberpost) { FactoryBot.create(:post, author: member) }
let(:othermemberpost) { create(:post, author: other_member) } let(:othermemberpost) { FactoryBot.create(:post, author: other_member) }
let!(:planting) { create(:planting, owner: member) } let!(:planting) { FactoryBot.create(:planting, owner: member) }
let!(:harvest) { create(:harvest, owner: member) } let!(:harvest) { FactoryBot.create(:harvest, owner: member) }
let!(:seed) { create(:seed, owner: member) } let!(:seed) { FactoryBot.create(:seed, owner: member) }
let!(:secondgarden) { create(:garden, owner: member) } let!(:secondgarden) { FactoryBot.create(:garden, owner: member) }
before do before do
member.follows.create!(followed: other_member) member.follows.create!(followed: other_member)
other_member.follows.create!(followed: member) other_member.follows.create!(followed: member)
login_as(member) login_as(member)
create(:comment, author: member, post: othermemberpost) FactoryBot.create(:comment, author: member, post: othermemberpost)
create(:comment, author: other_member, post: memberpost, body: "Fun comment-y thing") FactoryBot.create(:comment, author: other_member, post: memberpost, body: "Fun comment-y thing")
# deletion breaks if no wranglers exist # deletion breaks if no wranglers exist
create(:cropbot) FactoryBot.create(:cropbot)
# deletion breaks if ex_member doesn't exist # deletion breaks if ex_member doesn't exist
create(:member, login_name: "ex_member") FactoryBot.create(:member, login_name: "ex_member")
end end
it "has option to delete on member profile page" do it "has option to delete on member profile page" do
@@ -136,7 +136,7 @@ describe "member deletion", :flaky do
end end
it "replaces comments on others' posts with deletion note, leaving post intact" do it "replaces comments on others' posts with deletion note, leaving post intact" do
create(:comment, post: othermemberpost, author: member, body: 'i am deleting my account') FactoryBot.create(:comment, post: othermemberpost, author: member, body: 'i am deleting my account')
visit post_path(othermemberpost) visit post_path(othermemberpost)
expect(page).to have_no_content member.login_name expect(page).to have_no_content member.login_name
@@ -163,12 +163,12 @@ describe "member deletion", :flaky do
end end
context "for a crop wrangler" do context "for a crop wrangler" do
let(:member) { create(:crop_wrangling_member) } let(:member) { FactoryBot.create(:crop_wrangling_member) }
let!(:ex_wrangler) { create(:crop_wrangling_member, login_name: "ex_wrangler") } let!(:ex_wrangler) { FactoryBot.create(:crop_wrangling_member, login_name: "ex_wrangler") }
let(:otherwrangler) { create(:crop_wrangling_member) } let(:otherwrangler) { FactoryBot.create(:crop_wrangling_member) }
let(:crop) { create(:crop, creator: member) } let(:crop) { FactoryBot.create(:crop, creator: member) }
before { create(:cropbot) } before { FactoryBot.create(:cropbot) }
it "leaves crops behind" do it "leaves crops behind" do
login_as(otherwrangler) login_as(otherwrangler)

View File

@@ -13,7 +13,7 @@ describe "members list" do
before do before do
visit members_path visit members_path
expect(page).to have_css "#sort" expect(page).to have_css "#sort"
expect(page).to have_css "form" expect(page).to have_selector "form"
end end
it "default alphabetical sort" do it "default alphabetical sort" do

View File

@@ -62,10 +62,10 @@ describe "member profile", :js do
end end
context "with some activity" do context "with some activity" do
let!(:planting) { create(:planting, owner: member) } let!(:planting) { FactoryBot.create(:planting, owner: member) }
let!(:harvest) { create(:harvest, owner: member) } let!(:harvest) { FactoryBot.create(:harvest, owner: member) }
let!(:seed) { create(:seed, owner: member) } let!(:seed) { FactoryBot.create(:seed, owner: member) }
let!(:post) { create(:post, author: member) } let!(:post) { FactoryBot.create(:post, author: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -104,10 +104,10 @@ describe "member profile", :js do
shared_examples 'member activity' do shared_examples 'member activity' do
context 'member has plantings' do context 'member has plantings' do
let!(:new_planting) { create(:planting, owner: member, planted_at: Time.zone.now) } let!(:new_planting) { FactoryBot.create(:planting, owner: member, planted_at: Time.zone.now) }
let!(:old_planting) { create(:planting, owner: member, planted_at: 3.years.ago) } let!(:old_planting) { FactoryBot.create(:planting, owner: member, planted_at: 3.years.ago) }
let!(:finished_planting) { create(:finished_planting, owner: member) } let!(:finished_planting) { FactoryBot.create(:finished_planting, owner: member) }
let!(:no_planted_at_planting) { create(:planting, owner: member, planted_at: nil) } let!(:no_planted_at_planting) { FactoryBot.create(:planting, owner: member, planted_at: nil) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -118,9 +118,9 @@ describe "member profile", :js do
end end
context 'member has activities' do context 'member has activities' do
let!(:activity) { create(:activity, owner: member, due_date: 3.days.ago) } let!(:activity) { FactoryBot.create(:activity, owner: member, due_date: 3.days.ago) }
let!(:activity2) { create(:activity, :planting, owner: member) } let!(:activity2) { FactoryBot.create(:activity, :planting, owner: member) }
let!(:activity3) { create(:activity, :garden, owner: member) } let!(:activity3) { FactoryBot.create(:activity, :garden, owner: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -130,7 +130,7 @@ describe "member profile", :js do
end end
context 'member has seeds' do context 'member has seeds' do
let!(:seed) { create(:seed, owner: member) } let!(:seed) { FactoryBot.create(:seed, owner: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -138,7 +138,7 @@ describe "member profile", :js do
end end
context 'member has harvests' do context 'member has harvests' do
let!(:harvest) { create(:harvest, owner: member) } let!(:harvest) { FactoryBot.create(:harvest, owner: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -146,7 +146,7 @@ describe "member profile", :js do
end end
context 'member has posts' do context 'member has posts' do
let!(:post) { create(:post, author: member) } let!(:post) { FactoryBot.create(:post, author: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -154,8 +154,8 @@ describe "member profile", :js do
end end
context 'member has comments' do context 'member has comments' do
let(:post) { create(:post) } let(:post) { FactoryBot.create(:post) }
let!(:comment) { create(:comment, commentable: post, author: member) } let!(:comment) { FactoryBot.create(:comment, commentable: post, author: member) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -164,8 +164,8 @@ describe "member profile", :js do
end end
context 'photos' do context 'photos' do
let(:planting) { create(:planting, owner: member) } let(:planting) { FactoryBot.create(:planting, owner: member) }
let!(:photo) { create(:photo, owner: member, plantings: [planting]) } let!(:photo) { FactoryBot.create(:photo, owner: member, plantings: [planting]) }
before { visit member_path(member) } before { visit member_path(member) }
@@ -174,35 +174,35 @@ describe "member profile", :js do
end end
context 'plantings' do context 'plantings' do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
let(:growing_planting) do let(:growing_planting) do
create(:planting, FactoryBot.create(:planting,
crop:, crop:,
owner: member, owner: member,
planted_at: Time.zone.today) planted_at: Time.zone.today)
end end
let(:harvesting_planting) do let(:harvesting_planting) do
create(:planting, FactoryBot.create(:planting,
crop:, crop:,
owner: member, owner: member,
planted_at: 51.days.ago) planted_at: 51.days.ago)
end end
let(:super_late_planting) do let(:super_late_planting) do
create(:planting, FactoryBot.create(:planting,
crop:, owner: member, crop:, owner: member,
planted_at: 260.days.ago) planted_at: 260.days.ago)
end end
before do before do
# time to harvest = 50 day # time to harvest = 50 day
# time to finished = 90 days # time to finished = 90 days
create(:harvest, FactoryBot.create(:harvest,
harvested_at: 50.days.ago, harvested_at: 50.days.ago,
crop:, crop:,
planting: create(:planting, planting: FactoryBot.create(:planting,
crop:, crop:,
planted_at: 100.days.ago, planted_at: 100.days.ago,
finished_at: 10.days.ago)) finished_at: 10.days.ago))
crop.plantings.each(&:update_harvest_days!) crop.plantings.each(&:update_harvest_days!)
crop.update_lifespan_medians crop.update_lifespan_medians
crop.update_harvest_medians crop.update_harvest_medians

View File

@@ -2,30 +2,30 @@
require 'rails_helper' require 'rails_helper'
describe 'Test with visual testing', :js do describe 'Test with visual testing', :js, type: :feature do
# Use the same random seed every time so our random data is the same # Use the same random seed every time so our random data is the same
# on every run, so doesn't trigger percy to see changes # on every run, so doesn't trigger percy to see changes
before { Faker::Config.random = Random.new(42) } before { Faker::Config.random = Random.new(42) }
let!(:member) { create(:member, login_name: 'percy', preferred_avatar_uri: gravatar) } let!(:member) { FactoryBot.create(:member, login_name: 'percy', preferred_avatar_uri: gravatar) }
let!(:crop_wrangler) { create(:crop_wrangling_member, login_name: 'croppy', preferred_avatar_uri: gravatar2) } let!(:crop_wrangler) { FactoryBot.create(:crop_wrangling_member, login_name: 'croppy', preferred_avatar_uri: gravatar2) }
let!(:admin_user) { create(:admin_member, login_name: 'janitor', preferred_avatar_uri: gravatar3) } let!(:admin_user) { FactoryBot.create(:admin_member, login_name: 'janitor', preferred_avatar_uri: gravatar3) }
let!(:someone_else) { create(:edinburgh_member, login_name: 'ruby', preferred_avatar_uri: gravatar4) } let!(:someone_else) { FactoryBot.create(:edinburgh_member, login_name: 'ruby', preferred_avatar_uri: gravatar4) }
let(:gravatar) { 'https://secure.gravatar.com/avatar/d021434aac03a7f7c7c0de60d07dad1c?size=150&default=identicon' } let(:gravatar) { 'https://secure.gravatar.com/avatar/d021434aac03a7f7c7c0de60d07dad1c?size=150&default=identicon' }
let(:gravatar2) { 'https://secure.gravatar.com/avatar/353d83d3677b142520987e1936fd093c?size=150&default=identicon' } let(:gravatar2) { 'https://secure.gravatar.com/avatar/353d83d3677b142520987e1936fd093c?size=150&default=identicon' }
let(:gravatar3) { 'https://secure.gravatar.com/avatar/622db62c7beab8d5d8b7a80aa6385b2f?size=150&default=identicon' } let(:gravatar3) { 'https://secure.gravatar.com/avatar/622db62c7beab8d5d8b7a80aa6385b2f?size=150&default=identicon' }
let(:gravatar4) { 'https://secure.gravatar.com/avatar/7fd767571ff5ceefc7a687a543b2c402?size=150&default=identicon' } let(:gravatar4) { 'https://secure.gravatar.com/avatar/7fd767571ff5ceefc7a687a543b2c402?size=150&default=identicon' }
let!(:tomato) { create(:tomato, creator: someone_else) } let!(:tomato) { FactoryBot.create(:tomato, creator: someone_else) }
let(:plant_part) { create(:plant_part, name: 'fruit') } let(:plant_part) { FactoryBot.create(:plant_part, name: 'fruit') }
let(:tomato_photo) do let(:tomato_photo) do
create(:photo, FactoryBot.create(:photo,
title: 'look at my tomatoes', title: 'look at my tomatoes',
owner: member, owner: member,
fullsize_url: 'https://farm1.staticflickr.com/177/432250619_2fe19d067d_z.jpg', fullsize_url: 'https://farm1.staticflickr.com/177/432250619_2fe19d067d_z.jpg',
thumbnail_url: 'https://farm1.staticflickr.com/177/432250619_2fe19d067d_q.jpg') thumbnail_url: 'https://farm1.staticflickr.com/177/432250619_2fe19d067d_q.jpg')
end end
let(:post_body) do let(:post_body) do
"So, um, watering's important. Yep. Very important. "So, um, watering's important. Yep. Very important.
@@ -66,7 +66,7 @@ rest of the garden.
[apple](crop) [apple](crop)
" "
end end
let(:post) { create(:post, author: member, subject: "Watering", body: post_body) } let(:post) { FactoryBot.create(:post, author: member, subject: "Watering", body: post_body) }
before do before do
# Freeze time, so we don't have variations in timestamps on the page # Freeze time, so we don't have variations in timestamps on the page
@@ -80,23 +80,23 @@ rest of the garden.
eggplant: 'https://farm8.staticflickr.com/7856/47068736892_1af9b8a4ba_q.jpg', eggplant: 'https://farm8.staticflickr.com/7856/47068736892_1af9b8a4ba_q.jpg',
maize: 'https://farm66.staticflickr.com/65535/46739264475_7cb55b2cbb_q.jpg' maize: 'https://farm66.staticflickr.com/65535/46739264475_7cb55b2cbb_q.jpg'
}.each do |crop_type, photo_url| }.each do |crop_type, photo_url|
crop = create(crop_type, creator: someone_else) crop = FactoryBot.create(crop_type, creator: someone_else)
crop.reindex crop.reindex
owner = create(:interesting_member, login_name: crop_type.to_s.reverse, email: "#{crop.name}@example.com") owner = FactoryBot.create(:interesting_member, login_name: crop_type.to_s.reverse, email: "#{crop.name}@example.com")
planting = create(:planting, crop:, owner:, garden: owner.gardens.first) planting = FactoryBot.create(:planting, crop:, owner:, garden: owner.gardens.first)
photo = create(:photo, owner:, photo = FactoryBot.create(:photo, owner:,
thumbnail_url: "#{photo_url}_q.jpg", fullsize_url: "#{photo_url}_z.jpg") thumbnail_url: "#{photo_url}_q.jpg", fullsize_url: "#{photo_url}_z.jpg")
planting.photos << photo planting.photos << photo
harvest = create(:harvest, crop:, owner:, plant_part:) harvest = FactoryBot.create(:harvest, crop:, owner:, plant_part:)
harvest.photos << photo harvest.photos << photo
create(:planting, crop: tomato, FactoryBot.create(:planting, crop: tomato,
planted_at: 1.year.ago, finished_at: 2.months.ago, planted_at: 1.year.ago, finished_at: 2.months.ago,
sunniness: 'sun', planted_from: 'seed') sunniness: 'sun', planted_from: 'seed')
end end
create(:seed, owner: member, tradable_to: 'nationally') FactoryBot.create(:seed, owner: member, tradable_to: 'nationally')
create(:seed, owner: someone_else, tradable_to: 'nationally') FactoryBot.create(:seed, owner: someone_else, tradable_to: 'nationally')
end end
after { Timecop.return } after { Timecop.return }
@@ -111,16 +111,16 @@ rest of the garden.
describe 'crops' do describe 'crops' do
it 'loads crops#show' do it 'loads crops#show' do
create(:planting, planted_at: 2.months.ago, sunniness: 'shade', planted_from: 'seedling') FactoryBot.create(:planting, planted_at: 2.months.ago, sunniness: 'shade', planted_from: 'seedling')
planting = create(:planting, planted_at: 1.year.ago, sunniness: 'sun', planted_from: 'seed', crop: tomato) planting = FactoryBot.create(:planting, planted_at: 1.year.ago, sunniness: 'sun', planted_from: 'seed', crop: tomato)
create(:harvest, FactoryBot.create(:harvest,
crop: tomato, crop: tomato,
plant_part: create(:plant_part, name: 'berry'), plant_part: FactoryBot.create(:plant_part, name: 'berry'),
planting:, planting:,
harvested_at: 1.day.ago) harvested_at: 1.day.ago)
post = create(:post, subject: 'tomatoes are delicious') post = FactoryBot.create(:post, subject: 'tomatoes are delicious')
tomato.posts << post tomato.posts << post
visit crop_path(tomato) visit crop_path(tomato)
@@ -141,7 +141,7 @@ rest of the garden.
end end
it 'load another member plantings#show' do it 'load another member plantings#show' do
planting = create(:planting, crop: tomato, owner: someone_else, garden: someone_else.gardens.first) planting = FactoryBot.create(:planting, crop: tomato, owner: someone_else, garden: someone_else.gardens.first)
visit planting_path(planting) visit planting_path(planting)
page.percy_snapshot(page, name: "#{prefix}/plantings#show") page.percy_snapshot(page, name: "#{prefix}/plantings#show")
end end
@@ -155,14 +155,14 @@ rest of the garden.
it 'gardens#show' do it 'gardens#show' do
# a garden # a garden
garden = create(:garden, name: 'paradise', owner: member) garden = FactoryBot.create(:garden, name: 'paradise', owner: member)
# with some lettuce (finished) # with some lettuce (finished)
create( FactoryBot.create(
:planting, crop: create(:crop, name: 'lettuce'), :planting, crop: FactoryBot.create(:crop, name: 'lettuce'),
garden:, owner: member, finished_at: 2.weeks.ago garden:, owner: member, finished_at: 2.weeks.ago
) )
# tomato still growing # tomato still growing
tomato_planting = create(:planting, garden:, owner: member, crop: tomato) tomato_planting = FactoryBot.create(:planting, garden:, owner: member, crop: tomato)
tomato_photo.plantings << tomato_planting tomato_photo.plantings << tomato_planting
visit garden_path(garden) visit garden_path(garden)
page.percy_snapshot(page, name: "#{prefix}/gardens#show") page.percy_snapshot(page, name: "#{prefix}/gardens#show")
@@ -176,10 +176,10 @@ rest of the garden.
end end
it 'loads another members#show' do it 'loads another members#show' do
create(:planting, owner: someone_else, created_at: 30.days.ago, crop: tomato) FactoryBot.create(:planting, owner: someone_else, created_at: 30.days.ago, crop: tomato)
create(:planting, owner: someone_else, created_at: 24.days.ago, crop: tomato) FactoryBot.create(:planting, owner: someone_else, created_at: 24.days.ago, crop: tomato)
create(:post, author: someone_else, created_at: 4.days.ago, subject: 'waiting for my tomatoes') FactoryBot.create(:post, author: someone_else, created_at: 4.days.ago, subject: 'waiting for my tomatoes')
create(:harvest, owner: someone_else, created_at: 1.day.ago, crop: tomato) FactoryBot.create(:harvest, owner: someone_else, created_at: 1.day.ago, crop: tomato)
visit member_path(someone_else) visit member_path(someone_else)
page.percy_snapshot(page, name: "#{prefix}/members#show") page.percy_snapshot(page, name: "#{prefix}/members#show")
@@ -188,18 +188,18 @@ rest of the garden.
describe 'posts' do describe 'posts' do
it 'loads posts#show' do it 'loads posts#show' do
create(:comment, commentable: post) FactoryBot.create(:comment, commentable: post)
create(:comment, commentable: post) FactoryBot.create(:comment, commentable: post)
visit post_path(post) visit post_path(post)
page.percy_snapshot(page, name: "#{prefix}/posts#show") page.percy_snapshot(page, name: "#{prefix}/posts#show")
end end
it 'loads posts#index' do it 'loads posts#index' do
Member.all.limit(5).each do |member| Member.all.limit(5).each do |member|
create_list(:post, 12, author: member) FactoryBot.create_list(:post, 12, author: member)
end end
Post.all.order(id: :desc).limit(4) do |post| Post.all.order(id: :desc).limit(4) do |post|
create_list(:comment, rand(1..5), commentable: post) FactoryBot.create_list(:comment, rand(1..5), commentable: post)
end end
visit posts_path visit posts_path
page.percy_snapshot(page, name: "#{prefix}/posts#index") page.percy_snapshot(page, name: "#{prefix}/posts#index")
@@ -208,7 +208,7 @@ rest of the garden.
describe 'photos' do describe 'photos' do
it 'loads photos#show' do it 'loads photos#show' do
tomato_photo.plantings << create(:planting, owner: member, crop: tomato) tomato_photo.plantings << FactoryBot.create(:planting, owner: member, crop: tomato)
visit photo_path(tomato_photo) visit photo_path(tomato_photo)
page.percy_snapshot(page, name: "#{prefix}/photos#show") page.percy_snapshot(page, name: "#{prefix}/photos#show")
end end
@@ -250,7 +250,7 @@ rest of the garden.
it_behaves_like 'visit pages' it_behaves_like 'visit pages'
it 'load my plantings#show' do it 'load my plantings#show' do
planting = create(:planting, crop: tomato, owner: member, garden: member.gardens.first) planting = FactoryBot.create(:planting, crop: tomato, owner: member, garden: member.gardens.first)
visit planting_path(planting) visit planting_path(planting)
page.percy_snapshot(page, name: "#{prefix}/self/plantings#show") page.percy_snapshot(page, name: "#{prefix}/self/plantings#show")
end end
@@ -261,7 +261,7 @@ rest of the garden.
end end
it 'load my gardens#show' do it 'load my gardens#show' do
garden = create(:garden, name: 'paradise', owner: member) garden = FactoryBot.create(:garden, name: 'paradise', owner: member)
visit garden_path(garden) visit garden_path(garden)
page.percy_snapshot(page, name: "#{prefix}/self/gardens#show") page.percy_snapshot(page, name: "#{prefix}/self/gardens#show")
end end
@@ -306,19 +306,19 @@ rest of the garden.
describe '#edit' do describe '#edit' do
it 'loads gardens#edit' do it 'loads gardens#edit' do
garden = create(:garden, owner: member) garden = FactoryBot.create(:garden, owner: member)
visit edit_garden_path(garden) visit edit_garden_path(garden)
page.percy_snapshot(page, name: "#{prefix}/gardens#edit") page.percy_snapshot(page, name: "#{prefix}/gardens#edit")
end end
it 'loads harvests#edit' do it 'loads harvests#edit' do
harvest = create(:harvest, owner: member) harvest = FactoryBot.create(:harvest, owner: member)
visit edit_harvest_path(harvest) visit edit_harvest_path(harvest)
page.percy_snapshot(page, name: "#{prefix}/harvests#edit") page.percy_snapshot(page, name: "#{prefix}/harvests#edit")
end end
it 'loads planting#edit' do it 'loads planting#edit' do
planting = create(:planting, owner: member) planting = FactoryBot.create(:planting, owner: member)
visit edit_planting_path(planting) visit edit_planting_path(planting)
page.percy_snapshot(page, name: "#{prefix}/plantings#edit") page.percy_snapshot(page, name: "#{prefix}/plantings#edit")
end end
@@ -350,7 +350,7 @@ rest of the garden.
context 'wrangling crops' do context 'wrangling crops' do
include_context 'signed in crop wrangler' include_context 'signed in crop wrangler'
let!(:candy) { create(:crop_request, name: 'candy') } let!(:candy) { FactoryBot.create(:crop_request, name: 'candy') }
it 'crop wrangling page' do it 'crop wrangling page' do
visit wrangle_crops_path visit wrangle_crops_path

View File

@@ -6,7 +6,7 @@ describe "new photo page" do
context "signed in member" do context "signed in member" do
include_context 'signed in member' include_context 'signed in member'
context "viewing a planting" do context "viewing a planting" do
let(:planting) { create(:planting, owner: member) } let(:planting) { FactoryBot.create(:planting, owner: member) }
it "add photo" do it "add photo" do
visit planting_path(planting) visit planting_path(planting)
@@ -20,7 +20,7 @@ describe "new photo page" do
end end
context "viewing a harvest" do context "viewing a harvest" do
let(:harvest) { create(:harvest, owner: member) } let(:harvest) { FactoryBot.create(:harvest, owner: member) }
it "add photo" do it "add photo" do
visit harvest_path(harvest) visit harvest_path(harvest)
@@ -33,7 +33,7 @@ describe "new photo page" do
end end
context "viewing a garden" do context "viewing a garden" do
let(:garden) { create(:garden, owner: member) } let(:garden) { FactoryBot.create(:garden, owner: member) }
it "add photo" do it "add photo" do
visit garden_path(garden) visit garden_path(garden)
@@ -46,7 +46,7 @@ describe "new photo page" do
end end
describe "viewing a seed" do describe "viewing a seed" do
let(:seed) { create(:seed, owner: member) } let(:seed) { FactoryBot.create(:seed, owner: member) }
it "add photo" do it "add photo" do
visit seed_path(seed) visit seed_path(seed)

View File

@@ -30,8 +30,8 @@ describe "Planting reminder email", :js do
context "when member has some plantings" do context "when member has some plantings" do
# Bangs are used on the following 2 let blocks in order to ensure that the plantings are present # Bangs are used on the following 2 let blocks in order to ensure that the plantings are present
# in the database before the email is generated: otherwise, they won't be present in the email. # in the database before the email is generated: otherwise, they won't be present in the email.
let!(:p1) { create(:predictable_planting, planted_at: 10.days.ago, garden: member.gardens.first, owner: member) } let!(:p1) { FactoryBot.create(:predictable_planting, planted_at: 10.days.ago, garden: member.gardens.first, owner: member) }
let!(:p2) { create(:predictable_planting, planted_at: 30.days.ago, garden: member.gardens.first, owner: member) } let!(:p2) { FactoryBot.create(:predictable_planting, planted_at: 30.days.ago, garden: member.gardens.first, owner: member) }
describe "lists plantings" do describe "lists plantings" do
it { expect(mail).to have_content "Progress report" } it { expect(mail).to have_content "Progress report" }
@@ -50,10 +50,10 @@ describe "Planting reminder email", :js do
context "when member has some harvests" do context "when member has some harvests" do
# Bangs are used on the following 2 let blocks in order to ensure that the plantings are present # Bangs are used on the following 2 let blocks in order to ensure that the plantings are present
# in the database before the spec is run. # in the database before the spec is run.
let!(:p1) { create(:predictable_planting, garden: member.gardens.first, owner: member, planted_at: 20.days.ago) } let!(:p1) { FactoryBot.create(:predictable_planting, garden: member.gardens.first, owner: member, planted_at: 20.days.ago) }
let!(:p2) { create(:predictable_planting, garden: member.gardens.first, owner: member) } let!(:p2) { FactoryBot.create(:predictable_planting, garden: member.gardens.first, owner: member) }
let!(:h1) { create(:harvest, owner: member, planting: p1, harvested_at: 1.day.ago) } let!(:h1) { FactoryBot.create(:harvest, owner: member, planting: p1, harvested_at: 1.day.ago) }
let!(:h2) { create(:harvest, owner: member, planting: p2, harvested_at: 3.days.ago) } let!(:h2) { FactoryBot.create(:harvest, owner: member, planting: p2, harvested_at: 3.days.ago) }
describe "lists planting that are ready for harvest" do describe "lists planting that are ready for harvest" do
it { expect(mail).to have_content "Ready to harvest" } it { expect(mail).to have_content "Ready to harvest" }

View File

@@ -4,10 +4,10 @@ require "rails_helper"
require 'custom_matchers' require 'custom_matchers'
describe "Planting a crop", :js, :search do describe "Planting a crop", :js, :search do
let!(:maize) { create(:maize) } let!(:maize) { FactoryBot.create(:maize) }
let(:garden) { create(:garden, owner: member, name: 'Orchard') } let(:garden) { FactoryBot.create(:garden, owner: member, name: 'Orchard') }
let!(:planting) do let!(:planting) do
create(:planting, garden:, owner: member, planted_at: Date.parse("2013-03-10")) FactoryBot.create(:planting, garden:, owner: member, planted_at: Date.parse("2013-03-10"))
end end
before { Planting.reindex } before { Planting.reindex }
@@ -19,14 +19,14 @@ describe "Planting a crop", :js, :search do
it_behaves_like "crop suggest", "planting" it_behaves_like "crop suggest", "planting"
describe "displays required and optional fields properly" do describe "displays required and optional fields properly" do
it { expect(page).to have_css ".required", text: "What did you plant?" } it { expect(page).to have_selector ".required", text: "What did you plant?" }
it { expect(page).to have_css ".required", text: "Where did you plant it?" } it { expect(page).to have_selector ".required", text: "Where did you plant it?" }
it { expect(page).to have_css 'input#planting_planted_at' } it { expect(page).to have_selector 'input#planting_planted_at' }
it { expect(page).to have_css 'input#planting_quantity' } it { expect(page).to have_selector 'input#planting_quantity' }
it { expect(page).to have_css 'select#planting_planted_from' } it { expect(page).to have_selector 'select#planting_planted_from' }
it { expect(page).to have_css 'select#planting_sunniness' } it { expect(page).to have_selector 'select#planting_sunniness' }
it { expect(page).to have_css 'textarea#planting_description' } it { expect(page).to have_selector 'textarea#planting_description' }
it { expect(page).to have_css 'input#planting_finished_at' } it { expect(page).to have_selector 'input#planting_finished_at' }
end end
describe "Creating a new planting" do describe "Creating a new planting" do
@@ -237,7 +237,7 @@ describe "Planting a crop", :js, :search do
describe "Transplanting a planting" do describe "Transplanting a planting" do
it "allows transplanting to another garden" do it "allows transplanting to another garden" do
other_garden = create(:garden, owner: member, name: 'Backyard') other_garden = FactoryBot.create(:garden, owner: member, name: 'Backyard')
visit planting_path(planting) visit planting_path(planting)
click_link 'Actions' click_link 'Actions'
select other_garden.name, from: 'Transplant to:' select other_garden.name, from: 'Transplant to:'

View File

@@ -4,9 +4,9 @@ require "rails_helper"
require 'custom_matchers' require 'custom_matchers'
describe "Display a planting", :js do describe "Display a planting", :js do
describe 'planting perennial' do describe 'planting perennial' do
let(:garden) { create(:garden, location: 'Edinburgh') } let(:garden) { FactoryBot.create(:garden, location: 'Edinburgh') }
let(:crop) { create(:crop, name: 'feijoa', perennial: true) } let(:crop) { FactoryBot.create(:crop, name: 'feijoa', perennial: true) }
let(:planting) { create(:planting, crop:, garden:, owner: garden.owner) } let(:planting) { FactoryBot.create(:planting, crop:, garden:, owner: garden.owner) }
describe 'no harvest to predict from' do describe 'no harvest to predict from' do
before { visit planting_path(planting) } before { visit planting_path(planting) }
@@ -17,9 +17,9 @@ describe "Display a planting", :js do
describe 'harvests used to predict' do describe 'harvests used to predict' do
before do before do
create(:harvest, planting:, crop:, harvested_at: '1 May 2019') FactoryBot.create(:harvest, planting:, crop:, harvested_at: '1 May 2019')
create(:harvest, planting:, crop:, harvested_at: '18 June 2019') FactoryBot.create(:harvest, planting:, crop:, harvested_at: '18 June 2019')
create_list(:harvest, 4, planting:, crop:, harvested_at: '18 August 2019') FactoryBot.create_list(:harvest, 4, planting:, crop:, harvested_at: '18 August 2019')
end end
before { visit planting_path(planting) } before { visit planting_path(planting) }
@@ -36,22 +36,22 @@ describe "Display a planting", :js do
before do before do
# Near by planting with harvests # Near by planting with harvests
nearby_garden = create(:garden, location: 'Greenwich, UK') nearby_garden = FactoryBot.create(:garden, location: 'Greenwich, UK')
nearby_planting = create(:planting, crop:, nearby_planting = FactoryBot.create(:planting, crop:,
garden: nearby_garden, owner: nearby_garden.owner, planted_at: '1 January 2000') garden: nearby_garden, owner: nearby_garden.owner, planted_at: '1 January 2000')
create(:harvest, planting: nearby_planting, crop:, FactoryBot.create(:harvest, planting: nearby_planting, crop:,
harvested_at: '1 May 2019') harvested_at: '1 May 2019')
create(:harvest, planting: nearby_planting, crop:, FactoryBot.create(:harvest, planting: nearby_planting, crop:,
harvested_at: '18 June 2019') harvested_at: '18 June 2019')
create_list(:harvest, 4, planting: nearby_planting, crop:, FactoryBot.create_list(:harvest, 4, planting: nearby_planting, crop:,
harvested_at: '18 August 2008') harvested_at: '18 August 2008')
# far away planting harvests # far away planting harvests
faraway_garden = create(:garden, location: 'Amundsen-Scott Base, Antarctica') faraway_garden = FactoryBot.create(:garden, location: 'Amundsen-Scott Base, Antarctica')
faraway_planting = create(:planting, garden: faraway_garden, crop:, faraway_planting = FactoryBot.create(:planting, garden: faraway_garden, crop:,
owner: faraway_garden.owner, planted_at: '16 May 2001') owner: faraway_garden.owner, planted_at: '16 May 2001')
create_list(:harvest, 4, planting: faraway_planting, crop:, FactoryBot.create_list(:harvest, 4, planting: faraway_planting, crop:,
harvested_at: '18 December 2006') harvested_at: '18 December 2006')
end end

View File

@@ -8,25 +8,25 @@ describe "Display a planting", :js do
before { visit planting_path(planting) } before { visit planting_path(planting) }
context 'Perennial planted long ago' do context 'Perennial planted long ago' do
let(:planting) { create(:perennial_planting) } let(:planting) { FactoryBot.create(:perennial_planting) }
it { expect(page).to have_text 'Perennial' } it { expect(page).to have_text 'Perennial' }
end end
context 'Perennial finished' do context 'Perennial finished' do
let(:planting) { create(:perennial_planting, planted_at: 6.years.ago, finished: true, finished_at: 1.year.ago) } let(:planting) { FactoryBot.create(:perennial_planting, planted_at: 6.years.ago, finished: true, finished_at: 1.year.ago) }
it { expect(page).to have_text 'Perennial' } it { expect(page).to have_text 'Perennial' }
end end
context 'Annual no predictions' do context 'Annual no predictions' do
let(:planting) { create(:annual_planting) } let(:planting) { FactoryBot.create(:annual_planting) }
it { expect(page).to have_no_text 'Finish expected' } it { expect(page).to have_no_text 'Finish expected' }
end end
context 'Annual with predicted finish' do context 'Annual with predicted finish' do
let(:planting) { create(:predictable_planting, planted_at: 2.weeks.ago) } let(:planting) { FactoryBot.create(:predictable_planting, planted_at: 2.weeks.ago) }
it { expect(page).to have_text '28%' } it { expect(page).to have_text '28%' }
it { expect(page).to have_text '14/50 days' } it { expect(page).to have_text '14/50 days' }
@@ -35,39 +35,39 @@ describe "Display a planting", :js do
end end
context 'Annual finished' do context 'Annual finished' do
let(:planting) { create(:annual_planting, planted_at: 100.days.ago, finished: true, finished_at: 1.day.ago) } let(:planting) { FactoryBot.create(:annual_planting, planted_at: 100.days.ago, finished: true, finished_at: 1.day.ago) }
it { expect(page).to have_text "Planted #{I18n.l(planting.planted_at)}" } it { expect(page).to have_text "Planted #{I18n.l(planting.planted_at)}" }
end end
context 'Planting with harvests' do context 'Planting with harvests' do
let(:planting) { create(:harvest_with_planting).planting } let(:planting) { FactoryBot.create(:harvest_with_planting).planting }
it { expect(page).to have_text 'Harvest started' } it { expect(page).to have_text 'Harvest started' }
end end
context 'Planting with harvest predictable' do context 'Planting with harvest predictable' do
let(:planting) do let(:planting) do
crop = create(:annual_crop) crop = FactoryBot.create(:annual_crop)
# 50 days to harvest # 50 days to harvest
create(:harvest, harvested_at: 150.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 150.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
# 20 days to harvest # 20 days to harvest
create(:harvest, harvested_at: 180.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 180.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
# 10 days to harvest # 10 days to harvest
create(:harvest, harvested_at: 190.days.ago, crop:, FactoryBot.create(:harvest, harvested_at: 190.days.ago, crop:,
planting: create(:planting, planted_at: 200.days.ago, crop:)) planting: FactoryBot.create(:planting, planted_at: 200.days.ago, crop:))
crop.update_medians crop.update_medians
create(:annual_planting, planted_at: 200.days.ago, crop:) FactoryBot.create(:annual_planting, planted_at: 200.days.ago, crop:)
end end
it { expect(page).to have_text 'First harvest expected' } it { expect(page).to have_text 'First harvest expected' }
end end
context 'with quantity' do context 'with quantity' do
let(:planting) { create(:planting, quantity: 100) } let(:planting) { FactoryBot.create(:planting, quantity: 100) }
it { expect(find('.plantingfact--quantity')).to have_text '100' } it { expect(find('.plantingfact--quantity')).to have_text '100' }
end end
@@ -78,8 +78,8 @@ describe "Display a planting", :js do
before { visit planting_path(planting) } before { visit planting_path(planting) }
context 'with matching seeds' do context 'with matching seeds' do
let(:seed) { create(:seed, saved_at: 1.month.ago, owner: member) } let(:seed) { FactoryBot.create(:seed, saved_at: 1.month.ago, owner: member) }
let(:planting) { create(:planting, planted_at: 1.day.ago, crop: seed.crop, owner: member) } let(:planting) { FactoryBot.create(:planting, planted_at: 1.day.ago, crop: seed.crop, owner: member) }
it { expect(page).to have_text 'Is this from one of these plantings? ' } it { expect(page).to have_text 'Is this from one of these plantings? ' }

View File

@@ -15,16 +15,16 @@ describe "Seeds", :js, :search do
describe "displays required and optional fields properly" do describe "displays required and optional fields properly" do
# NOTE: The required behaviour is pushed down to the control itself, not the form-group as of rails 7.1. # NOTE: The required behaviour is pushed down to the control itself, not the form-group as of rails 7.1.
# Modern browsers enforce the required behaviour better than us doing it ourselves. # Modern browsers enforce the required behaviour better than us doing it ourselves.
it { expect(page).to have_css "label", text: "Crop" } it { expect(page).to have_selector "label", text: "Crop" }
it { expect(page).to have_css 'input#seed_quantity' } it { expect(page).to have_selector 'input#seed_quantity' }
it { expect(page).to have_css 'input#seed_plant_before' } it { expect(page).to have_selector 'input#seed_plant_before' }
it { expect(page).to have_css 'input#seed_days_until_maturity_min' } it { expect(page).to have_selector 'input#seed_days_until_maturity_min' }
it { expect(page).to have_css 'input#seed_days_until_maturity_max' } it { expect(page).to have_selector 'input#seed_days_until_maturity_max' }
it { expect(page).to have_css 'label', text: 'Organic?' } it { expect(page).to have_selector 'label', text: 'Organic?' }
it { expect(page).to have_css 'label', text: 'GMO?' } it { expect(page).to have_selector 'label', text: 'GMO?' }
it { expect(page).to have_css 'label', text: 'Heirloom?' } it { expect(page).to have_selector 'label', text: 'Heirloom?' }
it { expect(page).to have_css 'textarea#seed_description' } it { expect(page).to have_selector 'textarea#seed_description' }
it { expect(page).to have_css 'label', text: 'Will trade' } it { expect(page).to have_selector 'label', text: 'Will trade' }
end end
describe "Adding a new seed", :js do describe "Adding a new seed", :js do

View File

@@ -55,7 +55,7 @@ describe "seeds", :js do
end end
describe "delete seeds" do describe "delete seeds" do
let(:seed) { create(:seed, owner: member) } let(:seed) { FactoryBot.create(:seed, owner: member) }
before do before do
visit seed_path(seed) visit seed_path(seed)
@@ -72,25 +72,25 @@ describe "seeds", :js do
before { visit seed_path(seed) } before { visit seed_path(seed) }
describe "view seeds with max and min days until maturity" do describe "view seeds with max and min days until maturity" do
let(:seed) { create(:seed, days_until_maturity_min: 5, days_until_maturity_max: 7) } let(:seed) { FactoryBot.create(:seed, days_until_maturity_min: 5, days_until_maturity_max: 7) }
it { expect(find('.seedfacts--maturity')).to have_content("57") } it { expect(find('.seedfacts--maturity')).to have_content("57") }
end end
describe "view seeds with only max days until maturity" do describe "view seeds with only max days until maturity" do
let(:seed) { create(:seed, days_until_maturity_max: 7) } let(:seed) { FactoryBot.create(:seed, days_until_maturity_max: 7) }
it { expect(find('.seedfacts--maturity')).to have_content("7") } it { expect(find('.seedfacts--maturity')).to have_content("7") }
end end
describe "view seeds with only min days until maturity" do describe "view seeds with only min days until maturity" do
let(:seed) { create(:seed, days_until_maturity_min: 5) } let(:seed) { FactoryBot.create(:seed, days_until_maturity_min: 5) }
it { expect(find('.seedfacts--maturity')).to have_content("5") } it { expect(find('.seedfacts--maturity')).to have_content("5") }
end end
describe "view seeds with neither max nor min days until maturity" do describe "view seeds with neither max nor min days until maturity" do
let(:seed) { create(:seed) } let(:seed) { FactoryBot.create(:seed) }
it { expect(find('.seedfacts--maturity')).to have_content "unknown" } it { expect(find('.seedfacts--maturity')).to have_content "unknown" }
end end

View File

@@ -10,8 +10,8 @@ describe "Seeds", :js do
include_context 'signed in member' include_context 'signed in member'
before { visit seed_path(seed) } before { visit seed_path(seed) }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let!(:seed) { create(:seed, owner: member) } let!(:seed) { FactoryBot.create(:seed, owner: member) }
it { it {
click_on "Actions" click_on "Actions"
@@ -28,7 +28,7 @@ describe "Seeds", :js do
visit seed_path(seed) visit seed_path(seed)
end end
let!(:photo) { create(:photo, title: 'hello photo', owner: seed.owner) } let!(:photo) { FactoryBot.create(:photo, title: 'hello photo', owner: seed.owner) }
it { is_expected.to have_xpath("//img[contains(@src,'#{photo.thumbnail_url}')]") } it { is_expected.to have_xpath("//img[contains(@src,'#{photo.thumbnail_url}')]") }
it { is_expected.to have_xpath("//a[contains(@href,'#{photo_path(photo)}')]") } it { is_expected.to have_xpath("//a[contains(@href,'#{photo_path(photo)}')]") }
@@ -41,7 +41,7 @@ describe "Seeds", :js do
visit seed_path(seed) visit seed_path(seed)
end end
let!(:photos) { create_list(:photo, 10 * 5, owner: seed.owner) } let!(:photos) { FactoryBot.create_list(:photo, 10 * 5, owner: seed.owner) }
let(:newest_photo) { seed.photos.order(created_at: :desc, id: :desc).first } let(:newest_photo) { seed.photos.order(created_at: :desc, id: :desc).first }
let(:oldest_photo) { seed.photos.order(created_at: :desc, id: :desc).last } let(:oldest_photo) { seed.photos.order(created_at: :desc, id: :desc).last }

View File

@@ -9,7 +9,7 @@ shared_examples "crop suggest" do |resource|
let!(:roma) { create(:roma) } let!(:roma) { create(:roma) }
it "placeholder text in crop auto suggest field" do it "placeholder text in crop auto suggest field" do
expect(page).to have_css("input[placeholder='e.g. lettuce']") expect(page).to have_selector("input[placeholder='e.g. lettuce']")
end end
it "typing in the crop name displays suggestions" do it "typing in the crop name displays suggestions" do
@@ -41,7 +41,7 @@ shared_examples "crop suggest" do |resource|
select_from_autocomplete("pear") select_from_autocomplete("pear")
expect(page).to have_css("input##{resource}_crop_id[value='#{pear.id}']", visible: false) expect(page).to have_selector("input##{resource}_crop_id[value='#{pear.id}']", visible: false)
end end
it "Typing and pausing does not affect input" do it "Typing and pausing does not affect input" do

View File

@@ -3,12 +3,12 @@
require 'rails_helper' require 'rails_helper'
describe "signin" do describe "signin" do
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:recipient) { create(:member) } let(:recipient) { FactoryBot.create(:member) }
let(:wrangler) { create(:crop_wrangling_member) } let(:wrangler) { FactoryBot.create(:crop_wrangling_member) }
before do before do
crop = create(:tomato) crop = FactoryBot.create(:tomato)
crop.reindex crop.reindex
end end

View File

@@ -42,7 +42,7 @@ describe "signout" do
end end
it 'photos' do it 'photos' do
garden = create(:garden, owner: member) garden = FactoryBot.create(:garden, owner: member)
visit "/photos/new?id=#{garden.id}&type=garden" visit "/photos/new?id=#{garden.id}&type=garden"
expect(page).to have_current_path new_member_session_path, ignore_query: true expect(page).to have_current_path new_member_session_path, ignore_query: true
# expect(page).to have_http_status(200) # expect(page).to have_http_status(200)

View File

@@ -3,9 +3,9 @@
require 'rails_helper' require 'rails_helper'
describe "timeline", :js do describe "timeline", :js do
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:friend1) { create(:member) } let(:friend1) { FactoryBot.create(:member) }
let(:friend2) { create(:member) } let(:friend2) { FactoryBot.create(:member) }
before do before do
member.followed << friend1 member.followed << friend1
@@ -13,14 +13,14 @@ describe "timeline", :js do
end end
describe 'visit timeline' do describe 'visit timeline' do
let!(:friend_planting) { create(:planting, owner: friend1, planted_at: 1.day.ago) } let!(:friend_planting) { FactoryBot.create(:planting, owner: friend1, planted_at: 1.day.ago) }
let!(:friend_harvest) { create(:planting, owner: friend2, planted_at: 3.years.ago) } let!(:friend_harvest) { FactoryBot.create(:planting, owner: friend2, planted_at: 3.years.ago) }
let!(:finished_planting) { create(:finished_planting, owner: friend1) } let!(:finished_planting) { FactoryBot.create(:finished_planting, owner: friend1) }
let!(:no_planted_at_planting) { create(:planting, owner: friend2, planted_at: nil) } let!(:no_planted_at_planting) { FactoryBot.create(:planting, owner: friend2, planted_at: nil) }
let!(:friend_photo) { create(:photo, owner: friend1) } let!(:friend_photo) { FactoryBot.create(:photo, owner: friend1) }
let!(:friend_post) { create(:post, author: friend2) } let!(:friend_post) { FactoryBot.create(:post, author: friend2) }
let!(:liked_post) { create(:like, likeable: friend_photo, member: friend2) } let!(:liked_post) { FactoryBot.create(:like, likeable: friend_photo, member: friend2) }
let!(:liked_photo) { create(:like, likeable: friend_post, member: friend1) } let!(:liked_photo) { FactoryBot.create(:like, likeable: friend_post, member: friend1) }
before do before do
login_as(member) login_as(member)

View File

@@ -13,7 +13,7 @@ describe ApplicationHelper do
describe '#avatar_uri' do describe '#avatar_uri' do
context 'with a normal user' do context 'with a normal user' do
before do before do
@member = build(:member, email: 'example@example.com', preferred_avatar_uri: nil) @member = FactoryBot.build(:member, email: 'example@example.com', preferred_avatar_uri: nil)
end end
it 'renders a gravatar uri' do it 'renders a gravatar uri' do
@@ -27,7 +27,7 @@ describe ApplicationHelper do
context 'with a user who specified a preferred avatar uri' do context 'with a user who specified a preferred avatar uri' do
before do before do
@member = build(:member, email: 'example@example.com', preferred_avatar_uri: 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg') @member = FactoryBot.build(:member, email: 'example@example.com', preferred_avatar_uri: 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg')
end end
it 'renders a the specified uri' do it 'renders a the specified uri' do

View File

@@ -12,13 +12,13 @@ require 'rails_helper'
# end # end
# end # end
# end # end
RSpec.describe ButtonsHelper do RSpec.describe ButtonsHelper, type: :helper do
before { allow(self).to receive(:can?).and_return(true) } before { allow(self).to receive(:can?).and_return(true) }
let(:garden) { create(:garden) } let(:garden) { FactoryBot.create(:garden) }
let(:planting) { create(:planting) } let(:planting) { FactoryBot.create(:planting) }
let(:harvest) { create(:harvest) } let(:harvest) { FactoryBot.create(:harvest) }
let(:seed) { create(:seed) } let(:seed) { FactoryBot.create(:seed) }
describe 'add_photo_button' do describe 'add_photo_button' do
it { expect(add_photo_button(garden)).to include "/photos/new?id=#{garden.id}&amp;type=garden" } it { expect(add_photo_button(garden)).to include "/photos/new?id=#{garden.id}&amp;type=garden" }

View File

@@ -2,15 +2,15 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe EventHelper do RSpec.describe EventHelper, type: :helper do
subject { resolve_model(event) } subject { resolve_model(event) }
let(:planting) { create(:planting) } let(:planting) { FactoryBot.create(:planting) }
let(:harvest) { create(:harvest) } let(:harvest) { FactoryBot.create(:harvest) }
let(:seed) { create(:seed) } let(:seed) { FactoryBot.create(:seed) }
let(:post) { create(:post) } let(:post) { FactoryBot.create(:post) }
let(:comment) { create(:comment) } let(:comment) { FactoryBot.create(:comment) }
let(:photo) { create(:photo) } let(:photo) { FactoryBot.create(:photo) }
describe 'plantings' do describe 'plantings' do
let(:event) { OpenStruct.new(id: planting.id, event_type: 'planting') } let(:event) { OpenStruct.new(id: planting.id, event_type: 'planting') }

View File

@@ -5,29 +5,29 @@ require 'rails_helper'
describe GardensHelper do describe GardensHelper do
describe "garden description" do describe "garden description" do
it "is missing" do it "is missing" do
garden = create(:garden, garden = FactoryBot.create(:garden,
description: nil) description: nil)
result = helper.display_garden_description(garden) result = helper.display_garden_description(garden)
expect(result).to eq "no description provided." expect(result).to eq "no description provided."
end end
it "is less than 130 characters long" do it "is less than 130 characters long" do
garden = create(:garden, garden = FactoryBot.create(:garden,
description: 'a' * 20) description: 'a' * 20)
result = helper.display_garden_description(garden) result = helper.display_garden_description(garden)
expect(result).to eq 'a' * 20 expect(result).to eq 'a' * 20
end end
it "is 130 characters long" do it "is 130 characters long" do
garden = create(:garden, garden = FactoryBot.create(:garden,
description: 'a' * 130) description: 'a' * 130)
result = helper.display_garden_description(garden) result = helper.display_garden_description(garden)
expect(result).to eq 'a' * 130 expect(result).to eq 'a' * 130
end end
it "is more than 130 characters long" do it "is more than 130 characters long" do
garden = create(:garden, garden = FactoryBot.create(:garden,
description: 'a' * 140) description: 'a' * 140)
result = helper.display_garden_description(garden) result = helper.display_garden_description(garden)
expect(result).to eq ('a' * 126) + '...' + ' ' + link_to("Read more", garden_path(garden)) expect(result).to eq ('a' * 126) + '...' + ' ' + link_to("Read more", garden_path(garden))
end end
@@ -40,8 +40,8 @@ describe GardensHelper do
end end
it "has 1 planting" do it "has 1 planting" do
crop = create(:crop) crop = FactoryBot.create(:crop)
plantings = [create(:planting, quantity: 10, crop:)] plantings = [FactoryBot.create(:planting, quantity: 10, crop:)]
result = helper.display_garden_plantings(plantings) result = helper.display_garden_plantings(plantings)
output = '<ul class="plantings"><li>' output = '<ul class="plantings"><li>'
@@ -54,11 +54,11 @@ describe GardensHelper do
it "has 2 plantings" do it "has 2 plantings" do
plantings = [] plantings = []
crop1 = create(:crop) crop1 = FactoryBot.create(:crop)
plantings << create(:planting, quantity: 10, crop: crop1) plantings << FactoryBot.create(:planting, quantity: 10, crop: crop1)
crop2 = create(:crop) crop2 = FactoryBot.create(:crop)
plantings << create(:planting, quantity: 10, crop: crop2) plantings << FactoryBot.create(:planting, quantity: 10, crop: crop2)
result = helper.display_garden_plantings(plantings.first(2)) result = helper.display_garden_plantings(plantings.first(2))
@@ -76,14 +76,14 @@ describe GardensHelper do
it "has 3 plantings" do it "has 3 plantings" do
plantings = [] plantings = []
crop1 = create(:crop) crop1 = FactoryBot.create(:crop)
plantings << create(:planting, quantity: 10, crop: crop1) plantings << FactoryBot.create(:planting, quantity: 10, crop: crop1)
crop2 = create(:crop) crop2 = FactoryBot.create(:crop)
plantings << create(:planting, quantity: 10, crop: crop2) plantings << FactoryBot.create(:planting, quantity: 10, crop: crop2)
crop3 = create(:crop) crop3 = FactoryBot.create(:crop)
plantings << create(:planting, quantity: 10, crop: crop3) plantings << FactoryBot.create(:planting, quantity: 10, crop: crop3)
result = helper.display_garden_plantings(plantings.first(2)) result = helper.display_garden_plantings(plantings.first(2))

View File

@@ -5,66 +5,66 @@ require 'rails_helper'
describe HarvestsHelper do describe HarvestsHelper do
describe "display_quantity" do describe "display_quantity" do
it "blank" do it "blank" do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: nil, quantity: nil,
weight_quantity: nil) weight_quantity: nil)
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq 'not specified' result.should eq 'not specified'
end end
it '3 individual' do it '3 individual' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: 3, quantity: 3,
unit: 'individual', unit: 'individual',
weight_quantity: nil) weight_quantity: nil)
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '3' result.should eq '3'
end end
it '1 bunch' do it '1 bunch' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: 1, quantity: 1,
unit: 'bunch', unit: 'bunch',
weight_quantity: nil) weight_quantity: nil)
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '1 bunch' result.should eq '1 bunch'
end end
it '3 bunches' do it '3 bunches' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: 3, quantity: 3,
unit: 'bunch', unit: 'bunch',
weight_quantity: nil) weight_quantity: nil)
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '3 bunches' result.should eq '3 bunches'
end end
it '3 kg' do it '3 kg' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: nil, quantity: nil,
unit: nil, unit: nil,
weight_quantity: 3, weight_quantity: 3,
weight_unit: 'kg') weight_unit: 'kg')
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '3 kg' result.should eq '3 kg'
end end
it '3 individual weighing 3 kg' do it '3 individual weighing 3 kg' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: 3, quantity: 3,
unit: 'individual', unit: 'individual',
weight_quantity: 3, weight_quantity: 3,
weight_unit: 'kg') weight_unit: 'kg')
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '3, weighing 3 kg' result.should eq '3, weighing 3 kg'
end end
it '3 bunches weighing 3 kg' do it '3 bunches weighing 3 kg' do
harvest = create(:harvest, harvest = FactoryBot.create(:harvest,
quantity: 3, quantity: 3,
unit: 'bunch', unit: 'bunch',
weight_quantity: 3, weight_quantity: 3,
weight_unit: 'kg') weight_unit: 'kg')
result = helper.display_quantity(harvest) result = helper.display_quantity(harvest)
result.should eq '3 bunches, weighing 3 kg' result.should eq '3 bunches, weighing 3 kg'
end end

View File

@@ -3,17 +3,17 @@
require 'rails_helper' require 'rails_helper'
describe PhotosHelper do describe PhotosHelper do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
let(:crop_photo_of) { create(:photo, source: 'openfarm') } let(:crop_photo_of) { FactoryBot.create(:photo, source: 'openfarm') }
let(:crop_photo_flickr) { create(:photo, source: 'flickr') } let(:crop_photo_flickr) { FactoryBot.create(:photo, source: 'flickr') }
let(:garden) { create(:garden) } let(:garden) { FactoryBot.create(:garden) }
let(:planting) { create(:planting, crop:, owner: garden.owner) } let(:planting) { FactoryBot.create(:planting, crop:, owner: garden.owner) }
let(:planting_photo) { create(:photo, owner: garden.owner) } let(:planting_photo) { FactoryBot.create(:photo, owner: garden.owner) }
let(:harvest) { create(:harvest, crop:, owner: garden.owner) } let(:harvest) { FactoryBot.create(:harvest, crop:, owner: garden.owner) }
let(:harvest_photo) { create(:photo, owner: garden.owner) } let(:harvest_photo) { FactoryBot.create(:photo, owner: garden.owner) }
let(:seed) { create(:seed, crop:, owner: garden.owner) } let(:seed) { FactoryBot.create(:seed, crop:, owner: garden.owner) }
let(:seed_photo) { create(:photo, owner: garden.owner) } let(:seed_photo) { FactoryBot.create(:photo, owner: garden.owner) }
describe "crops" do describe "crops" do
subject { crop_image_path(crop) } subject { crop_image_path(crop) }
@@ -51,7 +51,7 @@ describe PhotosHelper do
it { is_expected.to eq 'placeholder_600.png' } it { is_expected.to eq 'placeholder_600.png' }
describe "has a flickr photo" do describe "has a flickr photo" do
let(:garden_photo) { create(:photo, owner: garden.owner, source: 'flickr') } let(:garden_photo) { FactoryBot.create(:photo, owner: garden.owner, source: 'flickr') }
before { garden.photos << garden_photo } before { garden.photos << garden_photo }

View File

@@ -4,41 +4,41 @@ require 'rails_helper'
describe PlantingsHelper do describe PlantingsHelper do
describe "display_planting" do describe "display_planting" do
let!(:member) { build(:member, login_name: 'crop_lady') } let!(:member) { FactoryBot.build(:member, login_name: 'crop_lady') }
it "does not have a quantity nor a planted from value provided" do it "does not have a quantity nor a planted from value provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: nil, quantity: nil,
planted_from: '', planted_from: '',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted magic bean." expect(result).to eq "crop_lady planted magic bean."
end end
it "does not have a quantity provided" do it "does not have a quantity provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: nil, quantity: nil,
planted_from: 'seed', planted_from: 'seed',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted seeds." expect(result).to eq "crop_lady planted seeds."
end end
context "when quantity is greater than 1" do context "when quantity is greater than 1" do
it "does not have a planted from value provided" do it "does not have a planted from value provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: 10, quantity: 10,
planted_from: '', planted_from: '',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted 10 units." expect(result).to eq "crop_lady planted 10 units."
end end
it "does have a planted from value provided" do it "does have a planted from value provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: 5, quantity: 5,
planted_from: 'seed', planted_from: 'seed',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted 5 seeds." expect(result).to eq "crop_lady planted 5 seeds."
end end
@@ -46,19 +46,19 @@ describe PlantingsHelper do
context "when quantity is 1" do context "when quantity is 1" do
it "does not have a planted from value provided" do it "does not have a planted from value provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: 1, quantity: 1,
planted_from: '', planted_from: '',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted 1 unit." expect(result).to eq "crop_lady planted 1 unit."
end end
it "does have a planted from value provided" do it "does have a planted from value provided" do
planting = build(:planting, planting = FactoryBot.build(:planting,
quantity: 1, quantity: 1,
planted_from: 'seed', planted_from: 'seed',
owner: member) owner: member)
result = helper.display_planting(planting) result = helper.display_planting(planting)
expect(result).to eq "crop_lady planted 1 seed." expect(result).to eq "crop_lady planted 1 seed."
end end

View File

@@ -5,29 +5,29 @@ require 'rails_helper'
describe SeedsHelper do describe SeedsHelper do
describe "seed description" do describe "seed description" do
it "is missing" do it "is missing" do
seed = create(:seed, seed = FactoryBot.create(:seed,
description: nil) description: nil)
result = helper.display_seed_description(seed) result = helper.display_seed_description(seed)
expect(result).to eq "" expect(result).to eq ""
end end
it "is less than 130 characters long" do it "is less than 130 characters long" do
seed = create(:seed, seed = FactoryBot.create(:seed,
description: 'a' * 20) description: 'a' * 20)
result = helper.display_seed_description(seed) result = helper.display_seed_description(seed)
expect(result).to eq 'a' * 20 expect(result).to eq 'a' * 20
end end
it "is 130 characters long" do it "is 130 characters long" do
seed = create(:seed, seed = FactoryBot.create(:seed,
description: 'a' * 130) description: 'a' * 130)
result = helper.display_seed_description(seed) result = helper.display_seed_description(seed)
expect(result).to eq 'a' * 130 expect(result).to eq 'a' * 130
end end
it "is more than 130 characters long" do it "is more than 130 characters long" do
seed = create(:seed, seed = FactoryBot.create(:seed,
description: 'a' * 140) description: 'a' * 140)
result = helper.display_seed_description(seed) result = helper.display_seed_description(seed)
expect(result).to eq ('a' * 126) + '...' + ' ' + link_to("Read more", seed_path(seed)) expect(result).to eq ('a' * 126) + '...' + ' ' + link_to("Read more", seed_path(seed))
end end

View File

@@ -21,7 +21,7 @@ describe 'Haml::Filters::Escaped_Markdown' do
end end
it 'converts quick crop links' do it 'converts quick crop links' do
@crop = create(:crop) @crop = FactoryBot.create(:crop)
template = <<~HTML template = <<~HTML
:escaped_markdown :escaped_markdown
[#{@crop.name}](crop) [#{@crop.name}](crop)

View File

@@ -28,7 +28,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do
include ApplicationHelper include ApplicationHelper
it 'converts quick crop links' do it 'converts quick crop links' do
@crop = create(:crop) @crop = FactoryBot.create(:crop)
rendered = render_haml(haml_template(input_link(@crop.name))) rendered = render_haml(haml_template(input_link(@crop.name)))
expect(rendered).to match(/#{output_link(@crop)}/) expect(rendered).to match(/#{output_link(@crop)}/)
end end
@@ -39,14 +39,14 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it "doesn't convert escaped crop links" do it "doesn't convert escaped crop links" do
@crop = create(:crop) @crop = FactoryBot.create(:crop)
rendered = render_haml(haml_template("\\" << input_link(@crop.name))) rendered = render_haml(haml_template("\\" << input_link(@crop.name)))
expect(rendered).to match(/\[#{@crop.name}\]\(crop\)/) expect(rendered).to match(/\[#{@crop.name}\]\(crop\)/)
end end
it "handles multiple crop links" do it "handles multiple crop links" do
tomato = create(:tomato) tomato = FactoryBot.create(:tomato)
maize = create(:maize) maize = FactoryBot.create(:maize)
string = "#{input_link(tomato)} #{input_link(maize)}" string = "#{input_link(tomato)} #{input_link(maize)}"
rendered = render_haml(haml_template(string)) rendered = render_haml(haml_template(string))
expect(rendered).to match(/#{output_link(tomato)} #{output_link(maize)}/) expect(rendered).to match(/#{output_link(tomato)} #{output_link(maize)}/)
@@ -59,13 +59,13 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it "finds crops case insensitively" do it "finds crops case insensitively" do
@crop = create(:crop, name: 'tomato', slug: 'tomato') @crop = FactoryBot.create(:crop, name: 'tomato', slug: 'tomato')
rendered = render_haml(haml_template(input_link('ToMaTo'))) rendered = render_haml(haml_template(input_link('ToMaTo')))
expect(rendered).to match(/#{output_link(@crop, 'ToMaTo')}/) expect(rendered).to match(/#{output_link(@crop, 'ToMaTo')}/)
end end
it "fixes PT bug #78615258 (Markdown rendering bug with URLs and crops in same text)" do it "fixes PT bug #78615258 (Markdown rendering bug with URLs and crops in same text)" do
tomato = create(:tomato) tomato = FactoryBot.create(:tomato)
string = "[test](http://example.com) [tomato](crop)" string = "[test](http://example.com) [tomato](crop)"
rendered = render_haml(haml_template(string)) rendered = render_haml(haml_template(string))
@@ -74,7 +74,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it 'converts quick member links' do it 'converts quick member links' do
@member = create(:member) @member = FactoryBot.create(:member)
rendered = render_haml(haml_template(input_member_link(@member.login_name))) rendered = render_haml(haml_template(input_member_link(@member.login_name)))
expect(rendered).to match(/#{output_member_link(@member)}/) expect(rendered).to match(/#{output_member_link(@member)}/)
end end
@@ -85,13 +85,13 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it "doesn't convert escaped members" do it "doesn't convert escaped members" do
@member = create(:member) @member = FactoryBot.create(:member)
rendered = render_haml(haml_template("\\" << input_member_link(@member.login_name))) rendered = render_haml(haml_template("\\" << input_member_link(@member.login_name)))
expect(rendered).to match(/\[#{@member.login_name}\]\(member\)/) expect(rendered).to match(/\[#{@member.login_name}\]\(member\)/)
end end
it 'converts @ member links' do it 'converts @ member links' do
@member = create(:member) @member = FactoryBot.create(:member)
rendered = render_haml(haml_template("Hey @#{@member.login_name}! What's up")) rendered = render_haml(haml_template("Hey @#{@member.login_name}! What's up"))
expect(rendered).to match(/#{output_member_link(@member, "@#{@member.login_name}")}/) expect(rendered).to match(/#{output_member_link(@member, "@#{@member.login_name}")}/)
end end
@@ -102,7 +102,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it "doesn't convert nonexistent @ members" do it "doesn't convert nonexistent @ members" do
@member = create(:member) @member = FactoryBot.create(:member)
@member_name = @member.login_name @member_name = @member.login_name
@member.destroy @member.destroy
rendered = render_haml(haml_template("Hey @#{@member_name}")) rendered = render_haml(haml_template("Hey @#{@member_name}"))
@@ -110,7 +110,7 @@ describe 'Haml::Filters::Growstuff_Markdown' do
end end
it "doesn't convert escaped @ members" do it "doesn't convert escaped @ members" do
@member = create(:member) @member = FactoryBot.create(:member)
rendered = render_haml(haml_template("Hey \\@#{@member.login_name}! What's up")) rendered = render_haml(haml_template("Hey \\@#{@member.login_name}! What's up"))
expect(rendered).to include("Hey @#{@member.login_name}!") expect(rendered).to include("Hey @#{@member.login_name}!")
end end

View File

@@ -4,38 +4,38 @@ require 'rails_helper'
require 'cancan/matchers' require 'cancan/matchers'
describe Ability do describe Ability do
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
let(:ability) { described_class.new(member) } let(:ability) { described_class.new(member) }
context "notifications" do context "notifications" do
it 'member can view their own notifications' do it 'member can view their own notifications' do
notification = create(:notification, recipient: member) notification = FactoryBot.create(:notification, recipient: member)
ability.should be_able_to(:read, notification) ability.should be_able_to(:read, notification)
end end
it "member can't view someone else's notifications" do it "member can't view someone else's notifications" do
notification = create(:notification, notification = FactoryBot.create(:notification,
recipient: create(:member)) recipient: FactoryBot.create(:member))
ability.should_not be_able_to(:read, notification) ability.should_not be_able_to(:read, notification)
end end
it "member can't send messages to themself" do it "member can't send messages to themself" do
ability.should_not be_able_to(:create, ability.should_not be_able_to(:create,
create(:notification, FactoryBot.create(:notification,
recipient: member, recipient: member,
sender: member)) sender: member))
end end
it "member can send messages to someone else" do it "member can send messages to someone else" do
ability.should be_able_to(:create, ability.should be_able_to(:create,
create(:notification, FactoryBot.create(:notification,
recipient: create(:member), recipient: FactoryBot.create(:member),
sender: member)) sender: member))
end end
end end
context "crop wrangling" do context "crop wrangling" do
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
context "standard member" do context "standard member" do
it "can't manage crops" do it "can't manage crops" do
@@ -53,7 +53,7 @@ describe Ability do
end end
context "crop wrangler" do context "crop wrangler" do
let(:role) { create(:crop_wrangler) } let(:role) { FactoryBot.create(:crop_wrangler) }
before do before do
member.roles << role member.roles << role
@@ -78,7 +78,7 @@ describe Ability do
end end
context 'plant parts' do context 'plant parts' do
let(:plant_part) { create(:plant_part) } let(:plant_part) { FactoryBot.create(:plant_part) }
context 'ordinary member' do context 'ordinary member' do
it "can read plant parts" do it "can read plant parts" do
@@ -93,7 +93,7 @@ describe Ability do
end end
context 'admin' do context 'admin' do
let(:role) { create(:admin) } let(:role) { FactoryBot.create(:admin) }
before do before do
member.roles << role member.roles << role
@@ -113,7 +113,7 @@ describe Ability do
end end
it "can't delete a plant part that has harvests" do it "can't delete a plant part that has harvests" do
@harvest = create(:harvest, plant_part:) @harvest = FactoryBot.create(:harvest, plant_part:)
ability.should_not be_able_to(:destroy, plant_part) ability.should_not be_able_to(:destroy, plant_part)
end end
end end
@@ -127,14 +127,14 @@ describe Ability do
end end
context 'admin' do context 'admin' do
let(:role) { create(:admin) } let(:role) { FactoryBot.create(:admin) }
before do before do
member.roles << role member.roles << role
end end
it "can manage members" do it "can manage members" do
ability.should be_able_to(:destroy, create(:member)) ability.should be_able_to(:destroy, FactoryBot.create(:member))
end end
it "cannot delete themselves" do it "cannot delete themselves" do
ability.should_not be_able_to(:destroy, member) ability.should_not be_able_to(:destroy, member)

View File

@@ -3,7 +3,7 @@
require 'rails_helper' require 'rails_helper'
describe AlternateName do describe AlternateName do
let(:an) { create(:alternate_eggplant) } let(:an) { FactoryBot.create(:alternate_eggplant) }
it 'saves a basic alternate name' do it 'saves a basic alternate name' do
expect(an.save).to be(true) expect(an.save).to be(true)
@@ -22,9 +22,9 @@ describe AlternateName do
end end
describe 'relationships' do describe 'relationships' do
let(:alternate_name) { create(:alternate_name, crop:, creator: member) } let(:alternate_name) { FactoryBot.create(:alternate_name, crop:, creator: member) }
let(:crop) { create(:crop) } let(:crop) { FactoryBot.create(:crop) }
let(:member) { create(:member) } let(:member) { FactoryBot.create(:member) }
it { expect(alternate_name.crop).to eq crop } it { expect(alternate_name.crop).to eq crop }
it { expect(alternate_name.creator).to eq member } it { expect(alternate_name.creator).to eq member }

View File

@@ -4,7 +4,7 @@ require 'rails_helper'
describe Authentication do describe Authentication do
it 'creates an authentication' do it 'creates an authentication' do
@auth = create(:authentication) @auth = FactoryBot.create(:authentication)
@auth.should be_an_instance_of described_class @auth.should be_an_instance_of described_class
@auth.member.should be_an_instance_of Member @auth.member.should be_an_instance_of Member
end end

View File

@@ -4,7 +4,7 @@ require 'rails_helper'
describe Comment do describe Comment do
context "basic" do context "basic" do
let(:comment) { create(:comment) } let(:comment) { FactoryBot.create(:comment) }
it "belongs to a post" do it "belongs to a post" do
comment.commentable.should be_an_instance_of Post comment.commentable.should be_an_instance_of Post
@@ -18,12 +18,12 @@ describe Comment do
context "notifications" do context "notifications" do
it "sends a notification when a comment is posted" do it "sends a notification when a comment is posted" do
expect do expect do
create(:comment) FactoryBot.create(:comment)
end.to change(Notification, :count).by(1) end.to change(Notification, :count).by(1)
end end
it "sets the notification fields" do it "sets the notification fields" do
@c = create(:comment) @c = FactoryBot.create(:comment)
@n = Notification.first @n = Notification.first
@n.sender.should eq @c.author @n.sender.should eq @c.author
@n.recipient.should eq @c.commentable.author @n.recipient.should eq @c.commentable.author
@@ -33,20 +33,20 @@ describe Comment do
end end
it "doesn't send notifications to yourself" do it "doesn't send notifications to yourself" do
@m = create(:member) @m = FactoryBot.create(:member)
@p = create(:post, author: @m) @p = FactoryBot.create(:post, author: @m)
expect do expect do
create(:comment, commentable: @p, author: @m) FactoryBot.create(:comment, commentable: @p, author: @m)
end.not_to change(Notification, :count) end.not_to change(Notification, :count)
end end
end end
context "ordering" do context "ordering" do
before do before do
@m = create(:member) @m = FactoryBot.create(:member)
@p = create(:post, author: @m) @p = FactoryBot.create(:post, author: @m)
@c1 = create(:comment, commentable: @p, author: @m) @c1 = FactoryBot.create(:comment, commentable: @p, author: @m)
@c2 = create(:comment, commentable: @p, author: @m) @c2 = FactoryBot.create(:comment, commentable: @p, author: @m)
end end
it 'has a scope for ASC order for displaying on post page' do it 'has a scope for ASC order for displaying on post page' do

View File

@@ -2,11 +2,11 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe CropCompanion do RSpec.describe CropCompanion, type: :model do
it 'has a crop' do it 'has a crop' do
cc = described_class.new cc = described_class.new
cc.crop_a = create :tomato cc.crop_a = FactoryBot.create :tomato
cc.crop_b = create :maize cc.crop_b = FactoryBot.create :maize
cc.save! cc.save!
expect(cc.crop_a.name).to eq 'tomato' expect(cc.crop_a.name).to eq 'tomato'

View File

@@ -4,7 +4,7 @@ require 'rails_helper'
describe Crop do describe Crop do
context 'all fields present' do context 'all fields present' do
let(:crop) { create(:tomato) } let(:crop) { FactoryBot.create(:tomato) }
it 'saves a basic crop' do it 'saves a basic crop' do
crop.save.should be(true) crop.save.should be(true)
@@ -30,15 +30,15 @@ describe Crop do
context 'invalid data' do context 'invalid data' do
it 'does not save a crop without a system name' do it 'does not save a crop without a system name' do
crop = build(:crop, name: nil) crop = FactoryBot.build(:crop, name: nil)
expect { crop.save }.to raise_error ActiveRecord::StatementInvalid expect { crop.save }.to raise_error ActiveRecord::StatementInvalid
end end
end end
context 'ordering' do context 'ordering' do
before do before do
@uppercase = create(:uppercasecrop, created_at: 1.minute.ago) @uppercase = FactoryBot.create(:uppercasecrop, created_at: 1.minute.ago)
@lowercase = create(:lowercasecrop, created_at: 2.days.ago) @lowercase = FactoryBot.create(:lowercasecrop, created_at: 2.days.ago)
end end
it 'recent scope sorts by creation date' do it 'recent scope sorts by creation date' do
@@ -47,39 +47,39 @@ describe Crop do
end end
context 'popularity' do context 'popularity' do
let(:tomato) { create(:tomato) } let(:tomato) { FactoryBot.create(:tomato) }
let(:maize) { create(:maize) } let(:maize) { FactoryBot.create(:maize) }
before do before do
create_list(:planting, 10, crop: maize) FactoryBot.create_list(:planting, 10, crop: maize)
create_list(:planting, 3, crop: tomato) FactoryBot.create_list(:planting, 3, crop: tomato)
end end
it "sorts by most plantings" do it "sorts by most plantings" do
expect(described_class.popular.first).to eq maize expect(described_class.popular.first).to eq maize
create_list(:planting, 10, crop: tomato) FactoryBot.create_list(:planting, 10, crop: tomato)
expect(described_class.popular.first).to eq tomato expect(described_class.popular.first).to eq tomato
end end
end end
it 'finds a default scientific name' do it 'finds a default scientific name' do
@crop = create(:tomato) @crop = FactoryBot.create(:tomato)
expect(@crop.default_scientific_name).to be_nil expect(@crop.default_scientific_name).to be_nil
@sn = create(:solanum_lycopersicum, crop: @crop) @sn = FactoryBot.create(:solanum_lycopersicum, crop: @crop)
@crop.reload @crop.reload
expect(@crop.default_scientific_name.to_s).to eq @sn.name expect(@crop.default_scientific_name.to_s).to eq @sn.name
end end
it 'counts plantings' do it 'counts plantings' do
@crop = create(:tomato) @crop = FactoryBot.create(:tomato)
expect(@crop.plantings.size).to eq 0 expect(@crop.plantings.size).to eq 0
@planting = create(:planting, crop: @crop) @planting = FactoryBot.create(:planting, crop: @crop)
@crop.reload @crop.reload
expect(@crop.plantings.size).to eq 1 expect(@crop.plantings.size).to eq 1
end end
context "wikipedia url" do context "wikipedia url" do
subject { build(:tomato, en_wikipedia_url: wikipedia_url) } subject { FactoryBot.build(:tomato, en_wikipedia_url: wikipedia_url) }
context 'not a url' do context 'not a url' do
let(:wikipedia_url) { 'this is not valid' } let(:wikipedia_url) { 'this is not valid' }
@@ -126,15 +126,15 @@ describe Crop do
context 'varieties' do context 'varieties' do
it 'has a crop hierarchy' do it 'has a crop hierarchy' do
@tomato = create(:tomato) @tomato = FactoryBot.create(:tomato)
@roma = create(:roma, parent_id: @tomato.id) @roma = FactoryBot.create(:roma, parent_id: @tomato.id)
expect(@roma.parent).to eq @tomato expect(@roma.parent).to eq @tomato
expect(@tomato.varieties).to eq [@roma] expect(@tomato.varieties).to eq [@roma]
end end
it 'toplevel scope works' do it 'toplevel scope works' do
@tomato = create(:tomato) @tomato = FactoryBot.create(:tomato)
@roma = create(:roma, parent_id: @tomato.id) @roma = FactoryBot.create(:roma, parent_id: @tomato.id)
expect(described_class.toplevel).to eq [@tomato] expect(described_class.toplevel).to eq [@tomato]
end end
end end
@@ -144,11 +144,11 @@ describe Crop do
it { expect(described_class.has_photos).to include(crop) } it { expect(described_class.has_photos).to include(crop) }
end end
let!(:crop) { create(:tomato) } let!(:crop) { FactoryBot.create(:tomato) }
context 'with a planting photo' do context 'with a planting photo' do
let!(:photo) { create(:photo, owner: planting.owner) } let!(:photo) { FactoryBot.create(:photo, owner: planting.owner) }
let!(:planting) { create(:planting, crop:) } let!(:planting) { FactoryBot.create(:planting, crop:) }
before { planting.photos << photo } before { planting.photos << photo }
@@ -158,8 +158,8 @@ describe Crop do
end end
context 'with a harvest photo' do context 'with a harvest photo' do
let!(:harvest) { create(:harvest, crop:) } let!(:harvest) { FactoryBot.create(:harvest, crop:) }
let!(:photo) { create(:photo, owner: harvest.owner) } let!(:photo) { FactoryBot.create(:photo, owner: harvest.owner) }
before { harvest.photos << photo } before { harvest.photos << photo }
@@ -168,8 +168,8 @@ describe Crop do
include_examples 'has default photo' include_examples 'has default photo'
context 'and planting photo' do context 'and planting photo' do
let(:planting) { create(:planting, crop:) } let(:planting) { FactoryBot.create(:planting, crop:) }
let!(:planting_photo) { create(:photo, owner: planting.owner) } let!(:planting_photo) { FactoryBot.create(:photo, owner: planting.owner) }
before { planting.photos << planting_photo } before { planting.photos << planting_photo }
@@ -191,15 +191,15 @@ describe Crop do
end end
describe 'finding all photos' do describe 'finding all photos' do
let(:planting) { create(:planting, crop:) } let(:planting) { FactoryBot.create(:planting, crop:) }
let(:harvest) { create(:harvest, crop:) } let(:harvest) { FactoryBot.create(:harvest, crop:) }
let(:seed) { create(:seed, crop:) } let(:seed) { FactoryBot.create(:seed, crop:) }
before do before do
# Add photos to all # Add photos to all
planting.photos << create(:photo, owner: planting.owner) planting.photos << FactoryBot.create(:photo, owner: planting.owner)
harvest.photos << create(:photo, owner: harvest.owner) harvest.photos << FactoryBot.create(:photo, owner: harvest.owner)
seed.photos << create(:photo, owner: seed.owner) seed.photos << FactoryBot.create(:photo, owner: seed.owner)
end end
it { expect(crop.photos.size).to eq 3 } it { expect(crop.photos.size).to eq 3 }
@@ -210,83 +210,83 @@ describe Crop do
end end
context 'sunniness' do context 'sunniness' do
let(:crop) { create(:tomato) } let(:crop) { FactoryBot.create(:tomato) }
it 'returns a hash of sunniness values' do it 'returns a hash of sunniness values' do
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:semi_shady_planting, crop:) FactoryBot.create(:semi_shady_planting, crop:)
create(:shady_planting, crop:) FactoryBot.create(:shady_planting, crop:)
crop.sunniness.should be_an_instance_of Hash crop.sunniness.should be_an_instance_of Hash
end end
it 'counts each sunniness value' do it 'counts each sunniness value' do
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:semi_shady_planting, crop:) FactoryBot.create(:semi_shady_planting, crop:)
create(:shady_planting, crop:) FactoryBot.create(:shady_planting, crop:)
crop.sunniness.should == { 'sun' => 2, 'shade' => 1, 'semi-shade' => 1 } crop.sunniness.should == { 'sun' => 2, 'shade' => 1, 'semi-shade' => 1 }
end end
it 'ignores unused sunniness values' do it 'ignores unused sunniness values' do
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:sunny_planting, crop:) FactoryBot.create(:sunny_planting, crop:)
create(:semi_shady_planting, crop:) FactoryBot.create(:semi_shady_planting, crop:)
crop.sunniness.should == { 'sun' => 2, 'semi-shade' => 1 } crop.sunniness.should == { 'sun' => 2, 'semi-shade' => 1 }
end end
end end
context 'planted_from' do context 'planted_from' do
let(:crop) { create(:tomato) } let(:crop) { FactoryBot.create(:tomato) }
it 'returns a hash of sunniness values' do it 'returns a hash of sunniness values' do
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seedling_planting, crop:) FactoryBot.create(:seedling_planting, crop:)
create(:cutting_planting, crop:) FactoryBot.create(:cutting_planting, crop:)
crop.planted_from.should be_an_instance_of Hash crop.planted_from.should be_an_instance_of Hash
end end
it 'counts each planted_from value' do it 'counts each planted_from value' do
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seedling_planting, crop:) FactoryBot.create(:seedling_planting, crop:)
create(:cutting_planting, crop:) FactoryBot.create(:cutting_planting, crop:)
crop.planted_from.should == { 'seed' => 2, 'seedling' => 1, 'cutting' => 1 } crop.planted_from.should == { 'seed' => 2, 'seedling' => 1, 'cutting' => 1 }
end end
it 'ignores unused planted_from values' do it 'ignores unused planted_from values' do
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seed_planting, crop:) FactoryBot.create(:seed_planting, crop:)
create(:seedling_planting, crop:) FactoryBot.create(:seedling_planting, crop:)
crop.planted_from.should == { 'seed' => 2, 'seedling' => 1 } crop.planted_from.should == { 'seed' => 2, 'seedling' => 1 }
end end
end end
context 'popular plant parts' do context 'popular plant parts' do
let(:crop) { create(:tomato) } let(:crop) { FactoryBot.create(:tomato) }
it 'returns a hash of plant_part values' do it 'returns a hash of plant_part values' do
crop.popular_plant_parts.should be_an_instance_of Hash crop.popular_plant_parts.should be_an_instance_of Hash
end end
it 'counts each plant_part value' do it 'counts each plant_part value' do
@fruit = create(:plant_part) @fruit = FactoryBot.create(:plant_part)
@seed = create(:plant_part, name: 'seed') @seed = FactoryBot.create(:plant_part, name: 'seed')
@root = create(:plant_part, name: 'root') @root = FactoryBot.create(:plant_part, name: 'root')
@bulb = create(:plant_part, name: 'bulb') @bulb = FactoryBot.create(:plant_part, name: 'bulb')
@harvest1 = create(:harvest, @harvest1 = FactoryBot.create(:harvest,
crop:, crop:,
plant_part: @fruit) plant_part: @fruit)
@harvest2 = create(:harvest, @harvest2 = FactoryBot.create(:harvest,
crop:, crop:,
plant_part: @fruit) plant_part: @fruit)
@harvest3 = create(:harvest, @harvest3 = FactoryBot.create(:harvest,
crop:, crop:,
plant_part: @seed) plant_part: @seed)
@harvest4 = create(:harvest, @harvest4 = FactoryBot.create(:harvest,
crop:, crop:,
plant_part: @root) plant_part: @root)
crop.popular_plant_parts.should == { [@fruit.id, @fruit.name] => 2, crop.popular_plant_parts.should == { [@fruit.id, @fruit.name] => 2,
[@seed.id, @seed.name] => 1, [@seed.id, @seed.name] => 1,
[@root.id, @root.name] => 1 } [@root.id, @root.name] => 1 }
@@ -297,22 +297,22 @@ describe Crop do
subject { described_class.interesting } subject { described_class.interesting }
# first, a couple of candidate crops # first, a couple of candidate crops
let(:crop1) { create(:crop) } let(:crop1) { FactoryBot.create(:crop) }
let(:crop2) { create(:crop) } let(:crop2) { FactoryBot.create(:crop) }
let(:crop1_planting) { crop1.plantings.first } let(:crop1_planting) { crop1.plantings.first }
let(:crop2_planting) { crop2.plantings.first } let(:crop2_planting) { crop2.plantings.first }
let(:member) { create(:member, login_name: 'pikachu') } let(:member) { FactoryBot.create(:member, login_name: 'pikachu') }
describe 'lists interesting crops' do describe 'lists interesting crops' do
before do before do
# they need 3+ plantings each to be interesting # they need 3+ plantings each to be interesting
create_list(:planting, 3, crop: crop1, owner: member) FactoryBot.create_list(:planting, 3, crop: crop1, owner: member)
create_list(:planting, 3, crop: crop2, owner: member) FactoryBot.create_list(:planting, 3, crop: crop2, owner: member)
# crops need 3+ photos to be interesting # crops need 3+ photos to be interesting
crop1_planting.photos = create_list :photo, 3, owner: member crop1_planting.photos = FactoryBot.create_list :photo, 3, owner: member
crop2_planting.photos = create_list :photo, 3, owner: member crop2_planting.photos = FactoryBot.create_list :photo, 3, owner: member
end end
it { is_expected.to include crop1 } it { is_expected.to include crop1 }
@@ -323,9 +323,9 @@ describe Crop do
describe 'crops without plantings are not interesting' do describe 'crops without plantings are not interesting' do
before do before do
# only crop1 has plantings # only crop1 has plantings
create_list(:planting, 3, crop: crop1, owner: member) FactoryBot.create_list(:planting, 3, crop: crop1, owner: member)
# ... and photos # ... and photos
crop1_planting.photos = create_list(:photo, 3, owner: member) crop1_planting.photos = FactoryBot.create_list(:photo, 3, owner: member)
end end
it { is_expected.to include crop1 } it { is_expected.to include crop1 }
@@ -336,11 +336,11 @@ describe Crop do
describe 'crops without photos are not interesting' do describe 'crops without photos are not interesting' do
before do before do
# both crops have plantings # both crops have plantings
create_list(:planting, 3, crop: crop1, owner: member) FactoryBot.create_list(:planting, 3, crop: crop1, owner: member)
create_list(:planting, 3, crop: crop2, owner: member) FactoryBot.create_list(:planting, 3, crop: crop2, owner: member)
# but only crop1 has photos # but only crop1 has photos
crop1_planting.photos = create_list(:photo, 3, owner: member) crop1_planting.photos = FactoryBot.create_list(:photo, 3, owner: member)
end end
it { is_expected.to include crop1 } it { is_expected.to include crop1 }
@@ -350,8 +350,8 @@ describe Crop do
end end
context "harvests" do context "harvests" do
let!(:crop) { create(:crop) } let!(:crop) { FactoryBot.create(:crop) }
let!(:harvest) { create(:harvest, crop:) } let!(:harvest) { FactoryBot.create(:harvest, crop:) }
it "has harvests" do it "has harvests" do
expect(crop.harvests).to eq [harvest] expect(crop.harvests).to eq [harvest]
@@ -359,10 +359,10 @@ describe Crop do
end end
it "doesn't duplicate plant_parts" do it "doesn't duplicate plant_parts" do
@maize = create(:maize) @maize = FactoryBot.create(:maize)
@pp1 = create(:plant_part) @pp1 = FactoryBot.create(:plant_part)
@h1 = create(:harvest, crop: @maize, plant_part: @pp1) @h1 = FactoryBot.create(:harvest, crop: @maize, plant_part: @pp1)
@h2 = create(:harvest, crop: @maize, plant_part: @pp1) @h2 = FactoryBot.create(:harvest, crop: @maize, plant_part: @pp1)
expect(@maize.plant_parts).to eq [@pp1] expect(@maize.plant_parts).to eq [@pp1]
end end
@@ -370,7 +370,7 @@ describe Crop do
before do before do
# don't use 'let' for this -- we need to actually create it, # don't use 'let' for this -- we need to actually create it,
# regardless of whether it's used. # regardless of whether it's used.
@cropbot = create(:cropbot) @cropbot = FactoryBot.create(:cropbot)
end end
context "scientific names" do context "scientific names" do
@@ -492,7 +492,7 @@ describe Crop do
end end
it "loads a crop with a parent" do it "loads a crop with a parent" do
parent = create(:crop, name: 'parent') parent = FactoryBot.create(:crop, name: 'parent')
crop = CsvImporter.new.import_crop( crop = CsvImporter.new.import_crop(
["tomato", "http://en.wikipedia.org/wiki/Tomato", "parent"] ["tomato", "http://en.wikipedia.org/wiki/Tomato", "parent"]
) )
@@ -525,9 +525,9 @@ describe Crop do
end end
context "crop-post association" do context "crop-post association" do
let!(:tomato) { create(:tomato) } let!(:tomato) { FactoryBot.create(:tomato) }
let!(:maize) { create(:maize) } let!(:maize) { FactoryBot.create(:maize) }
let!(:post) { create(:post, body: "[maize](crop)[tomato](crop)[tomato](crop)") } let!(:post) { FactoryBot.create(:post, body: "[maize](crop)[tomato](crop)[tomato](crop)") }
describe "destroying a crop" do describe "destroying a crop" do
before do before do
@@ -545,8 +545,8 @@ describe Crop do
end end
context "destroying a crop" do context "destroying a crop" do
let!(:crop_a) { create(:crop) } let!(:crop_a) { FactoryBot.create(:crop) }
let!(:crop_b) { create(:crop) } let!(:crop_b) { FactoryBot.create(:crop) }
before do before do
CropCompanion.create(crop_a: crop_a, crop_b: crop_b) CropCompanion.create(crop_a: crop_a, crop_b: crop_b)
@@ -554,21 +554,21 @@ describe Crop do
end end
it "destroys companion links" do it "destroys companion links" do
expect { crop_a.destroy }.to change(CropCompanion, :count).from(2).to(0) expect { crop_a.destroy }.to change { CropCompanion.count }.from(2).to(0)
end end
end end
context "crop rejections" do context "crop rejections" do
let!(:rejected_reason) do let!(:rejected_reason) do
create(:crop, name: 'tomato', FactoryBot.create(:crop, name: 'tomato',
approval_status: 'rejected', approval_status: 'rejected',
reason_for_rejection: 'not edible') reason_for_rejection: 'not edible')
end end
let!(:rejected_other) do let!(:rejected_other) do
create(:crop, name: 'tomato', FactoryBot.create(:crop, name: 'tomato',
approval_status: 'rejected', approval_status: 'rejected',
reason_for_rejection: 'other', reason_for_rejection: 'other',
rejection_notes: 'blah blah blah') rejection_notes: 'blah blah blah')
end end
describe "rejecting a crop" do describe "rejecting a crop" do

View File

@@ -4,8 +4,8 @@ require 'spec_helper'
describe Follow do describe Follow do
before do before do
@member1 = create(:member) @member1 = FactoryBot.create(:member)
@member2 = create(:member) @member2 = FactoryBot.create(:member)
end end
it "sends a notification when a follow is created" do it "sends a notification when a follow is created" do

View File

@@ -3,7 +3,7 @@
require 'rails_helper' require 'rails_helper'
describe Forum do describe Forum do
let(:forum) { create(:forum) } let(:forum) { FactoryBot.create(:forum) }
it "belongs to an owner" do it "belongs to an owner" do
forum.owner.should be_an_instance_of Member forum.owner.should be_an_instance_of Member
@@ -18,8 +18,8 @@ describe Forum do
end end
it "has many posts" do it "has many posts" do
@post1 = create(:forum_post, forum:) @post1 = FactoryBot.create(:forum_post, forum:)
@post2 = create(:forum_post, forum:) @post2 = FactoryBot.create(:forum_post, forum:)
forum.posts.size.should == 2 forum.posts.size.should == 2
end end
end end

View File

@@ -3,8 +3,8 @@
require 'rails_helper' require 'rails_helper'
describe Garden do describe Garden do
let(:owner) { create(:member, login_name: 'hatupatu') } let(:owner) { FactoryBot.create(:member, login_name: 'hatupatu') }
let(:garden) { create(:garden, owner:, name: 'Springfield Community Garden') } let(:garden) { FactoryBot.create(:garden, owner:, name: 'Springfield Community Garden') }
it "has a slug" do it "has a slug" do
garden.slug.should match(/hatupatu-springfield-community-garden/) garden.slug.should match(/hatupatu-springfield-community-garden/)
@@ -15,42 +15,42 @@ describe Garden do
end end
it "doesn't allow a nil name" do it "doesn't allow a nil name" do
garden = build(:garden, name: nil) garden = FactoryBot.build(:garden, name: nil)
garden.should_not be_valid garden.should_not be_valid
end end
it "doesn't allow a blank name" do it "doesn't allow a blank name" do
garden = build(:garden, name: "") garden = FactoryBot.build(:garden, name: "")
garden.should_not be_valid garden.should_not be_valid
end end
it "allows numbers" do it "allows numbers" do
garden = build(:garden, name: "100 vines of 2 kamo-kamo") garden = FactoryBot.build(:garden, name: "100 vines of 2 kamo-kamo")
garden.should be_valid garden.should be_valid
end end
it "allows brackets" do it "allows brackets" do
garden = build(:garden, name: "Garden (second)") garden = FactoryBot.build(:garden, name: "Garden (second)")
garden.should be_valid garden.should be_valid
end end
it "allows macrons" do it "allows macrons" do
garden = build(:garden, name: "Kūmara and pūha patch") garden = FactoryBot.build(:garden, name: "Kūmara and pūha patch")
garden.should be_valid garden.should be_valid
end end
it "allows some punctuation" do it "allows some punctuation" do
garden = build(:garden, name: "best-garden-eva!") garden = FactoryBot.build(:garden, name: "best-garden-eva!")
garden.should be_valid garden.should be_valid
end end
it "doesn't allow a name with only spaces" do it "doesn't allow a name with only spaces" do
garden = build(:garden, name: " ") garden = FactoryBot.build(:garden, name: " ")
garden.should_not be_valid garden.should_not be_valid
end end
it "doesn't allow new line chars in garden names" do it "doesn't allow new line chars in garden names" do
garden = build(:garden, name: "My garden\nI am a 1337 hacker") garden = FactoryBot.build(:garden, name: "My garden\nI am a 1337 hacker")
garden.should_not be_valid garden.should_not be_valid
end end
@@ -63,9 +63,9 @@ describe Garden do
end end
it "destroys plantings when deleted" do it "destroys plantings when deleted" do
garden = create(:garden, owner:) garden = FactoryBot.create(:garden, owner:)
@planting1 = create(:planting, garden:, owner: garden.owner) @planting1 = FactoryBot.create(:planting, garden:, owner: garden.owner)
@planting2 = create(:planting, garden:, owner: garden.owner) @planting2 = FactoryBot.create(:planting, garden:, owner: garden.owner)
expect(garden.plantings.size).to eq(2) expect(garden.plantings.size).to eq(2)
all = Planting.count all = Planting.count
garden.destroy garden.destroy
@@ -74,37 +74,37 @@ describe Garden do
context 'area' do context 'area' do
it 'allows numeric area' do it 'allows numeric area' do
garden = build(:garden, area: 33) garden = FactoryBot.build(:garden, area: 33)
garden.should be_valid garden.should be_valid
end end
it "doesn't allow negative area" do it "doesn't allow negative area" do
garden = build(:garden, area: -5) garden = FactoryBot.build(:garden, area: -5)
garden.should_not be_valid garden.should_not be_valid
end end
it 'allows decimal quantities' do it 'allows decimal quantities' do
garden = build(:garden, area: 3.3) garden = FactoryBot.build(:garden, area: 3.3)
garden.should be_valid garden.should be_valid
end end
it 'allows blank quantities' do it 'allows blank quantities' do
garden = build(:garden, area: '') garden = FactoryBot.build(:garden, area: '')
garden.should be_valid garden.should be_valid
end end
it 'allows nil quantities' do it 'allows nil quantities' do
garden = build(:garden, area: nil) garden = FactoryBot.build(:garden, area: nil)
garden.should be_valid garden.should be_valid
end end
it 'cleans up zero quantities' do it 'cleans up zero quantities' do
garden = build(:garden, area: 0) garden = FactoryBot.build(:garden, area: 0)
expect(garden.area).to eq 0 expect(garden.area).to eq 0
end end
it "doesn't allow non-numeric quantities" do it "doesn't allow non-numeric quantities" do
garden = build(:garden, area: "99a") garden = FactoryBot.build(:garden, area: "99a")
garden.should_not be_valid garden.should_not be_valid
end end
end end
@@ -112,27 +112,27 @@ describe Garden do
context 'units' do context 'units' do
Garden::AREA_UNITS_VALUES.values.push(nil, '').each do |s| Garden::AREA_UNITS_VALUES.values.push(nil, '').each do |s|
it "#{s} should be a valid unit" do it "#{s} should be a valid unit" do
garden = build(:garden, area_unit: s) garden = FactoryBot.build(:garden, area_unit: s)
garden.should be_valid garden.should be_valid
end end
end end
it 'refuses invalid unit values' do it 'refuses invalid unit values' do
garden = build(:garden, area_unit: 'not valid') garden = FactoryBot.build(:garden, area_unit: 'not valid')
garden.should_not be_valid garden.should_not be_valid
garden.errors[:area_unit].should include("not valid is not a valid area unit") garden.errors[:area_unit].should include("not valid is not a valid area unit")
end end
it 'sets area unit to blank if area is blank' do it 'sets area unit to blank if area is blank' do
garden = build(:garden, area: '', area_unit: 'acre') garden = FactoryBot.build(:garden, area: '', area_unit: 'acre')
garden.should be_valid garden.should be_valid
expect(garden.area_unit).to be_nil expect(garden.area_unit).to be_nil
end end
end end
context 'active scopes' do context 'active scopes' do
let(:active) { create(:garden) } let(:active) { FactoryBot.create(:garden) }
let(:inactive) { create(:inactive_garden) } let(:inactive) { FactoryBot.create(:inactive_garden) }
it 'includes active garden in active scope' do it 'includes active garden in active scope' do
described_class.active.should include active described_class.active.should include active
@@ -146,9 +146,9 @@ describe Garden do
end end
it "marks plantings as finished when garden is inactive" do it "marks plantings as finished when garden is inactive" do
garden = create(:garden) garden = FactoryBot.create(:garden)
p1 = create(:planting, garden:, owner: garden.owner) p1 = FactoryBot.create(:planting, garden:, owner: garden.owner)
p2 = create(:planting, garden:, owner: garden.owner) p2 = FactoryBot.create(:planting, garden:, owner: garden.owner)
expect(p1.finished).to be false expect(p1.finished).to be false
expect(p2.finished).to be false expect(p2.finished).to be false
@@ -163,10 +163,10 @@ describe Garden do
end end
it "doesn't mark the wrong plantings as finished" do it "doesn't mark the wrong plantings as finished" do
g1 = create(:garden) g1 = FactoryBot.create(:garden)
g2 = create(:garden) g2 = FactoryBot.create(:garden)
p1 = create(:planting, garden: g1, owner: g1.owner) p1 = FactoryBot.create(:planting, garden: g1, owner: g1.owner)
p2 = create(:planting, garden: g2, owner: g2.owner) p2 = FactoryBot.create(:planting, garden: g2, owner: g2.owner)
# mark the garden as inactive # mark the garden as inactive
g1.active = false g1.active = false
@@ -182,8 +182,8 @@ describe Garden do
end end
context 'photos' do context 'photos' do
let(:garden) { create(:garden) } let(:garden) { FactoryBot.create(:garden) }
let(:photo) { create(:photo, owner: garden.owner) } let(:photo) { FactoryBot.create(:photo, owner: garden.owner) }
before do before do
garden.photos << photo garden.photos << photo
@@ -204,7 +204,7 @@ describe Garden do
end end
it 'chooses the most recent photo' do it 'chooses the most recent photo' do
@photo2 = create(:photo, owner: garden.owner) @photo2 = FactoryBot.create(:photo, owner: garden.owner)
garden.photos << @photo2 garden.photos << @photo2
expect(garden.default_photo).to eq @photo2 expect(garden.default_photo).to eq @photo2
end end

Some files were not shown because too many files have changed in this diff Show More