Merge remote-tracking branch 'origin/photos/seeds' into photos/seeds

This commit is contained in:
Brenda Wallace
2019-02-15 08:48:51 +13:00
167 changed files with 638 additions and 401 deletions

View File

@@ -93,5 +93,4 @@ submit the change with your pull request.
### Security and Dependency Updates
- DeppBot / [deppbot](https://github.com/deppbot)
- dependabot[bot] / [dependabot-bot] / [dependabot] (https://github.com/dependabot-bot)
- dependabot / [dependabot](https://github.com/dependabot)
- dependabot[bot] (https://github.com/dependabot-bot)

View File

@@ -80,7 +80,7 @@ GEM
uniform_notifier (~> 1.11)
byebug (10.0.2)
cancancan (2.3.0)
capybara (3.13.0)
capybara (3.13.2)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
@@ -134,7 +134,7 @@ GEM
activesupport (>= 3.0.0)
dalli (2.7.9)
database_cleaner (1.7.0)
devise (4.5.0)
devise (4.6.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 6.0)
@@ -164,7 +164,7 @@ GEM
factory_bot_rails (4.11.1)
factory_bot (~> 4.11.1)
railties (>= 3.0.0)
faker (1.9.1)
faker (1.9.2)
i18n (>= 0.7)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
@@ -221,7 +221,7 @@ GEM
httparty (0.16.3)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.5.2)
i18n (1.5.3)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.28)
activesupport (>= 4.0.2)
@@ -406,7 +406,7 @@ GEM
rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-rails (3.8.1)
rspec-rails (3.8.2)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
@@ -415,7 +415,7 @@ GEM
rspec-mocks (~> 3.8.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
rubocop (0.61.1)
rubocop (0.64.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1)

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 965 B

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,3 @@
$(function() {
$('[data-toggle="tooltip"]').tooltip();
});

View File

@@ -6,3 +6,4 @@
@import 'overrides'
@import 'graphs'
@import 'predictions'
@import 'plantings'

View File

@@ -41,7 +41,6 @@ h3
.profile-sidebar
margin-top: -5rem
.avatar
border-radius: 50%
border-radius: 50%
z-index: 2
position: relative
@@ -114,37 +113,8 @@ p.stats
.progress
border-radius: 0
.badge-super-late
background-color: $red
.badge-harvest
background-color: $blue
.planting-super-late
.planting-late
background-color: $beige
.planting
.planting-badges
position: absolute
.planting-thumbnail
padding: 0
border: 1px solid darken($beige, 10%)
border-radius: 4px
.planting-name
position: relative
top: -1em
.planting-quick-actions
position: absolute
top: 0
right: 2em
dl.planting-attributes
dt
text-align: left
dd
margin-left: auto
.progress-bar-text
text-align: center
.layout-actions
width: 100%

View File

@@ -0,0 +1,38 @@
.planting
.planting-badges
font-size: 100%
position: absolute
top: 3em
.badge-super-late
background-color: $red
.badge-harvest
background-color: $blue
.planting-super-late
.planting-late
background-color: $beige
.planting-thumbnail
width: 150px
padding: 0em
margin-bottom: 0.5em
margin-top: 0.5em
border: 1px solid darken($beige, 10%)
border-radius: 4px
.planting-name
position: relative
text-align: center
font-size: 150%
top: -0.5em
.planting-quick-actions
position: absolute
left: 142px
top: 6px
.planting-thumbnail-photo
height: 150px
dl.planting-attributes
dt
text-align: left
dd
margin-left: auto

View File

@@ -1,10 +1,14 @@
.predictions
.metric
.prediction-metric
text-align: center
height: 180px
border: 1px solid lighten($green, 20%)
border-radius: 5%
background: $white
margin: 4px
strong
font-size: 250%
font-size: 4em
font-align: center
h3
span
display: block

View File

@@ -9,9 +9,10 @@ module Api
has_many :photos
has_many :harvests
attribute :slug
attribute :planted_at
attribute :finished_at
attribute :finished
attribute :finished_at
attribute :quantity
attribute :description
attribute :sunniness
@@ -23,6 +24,28 @@ module Api
attribute :percentage_grown
attribute :first_harvest_date
attribute :last_harvest_date
filter :slug
filter :crop
filter :planted_from
filter :garden
filter :owner
filter :finished, default: nil
attribute :percentage_grown
def percentage_grown
@model.percentage_grown
end
attribute :crop_name
def crop_name
@model.crop.name
end
attribute :thumbnail
def thumbnail
@model.default_photo&.thumbnail_url
end
end
end
end

View File

@@ -12,24 +12,21 @@
= link_to 'https://en.wikipedia.org/wiki/Annual_vs._perennial_plant_evolution' do
an annual crop
(living and reproducing in a single year or less)
.row
- if crop.annual? && crop.median_lifespan.present?
.metric.col-md-3.col-xs-5
.prediction-metric.col-md-3.col-xs-5
%h3 Median lifespan
%strong= crop.median_lifespan
%span days
- if crop.median_days_to_first_harvest.present?
.metric.col-md-3.col-xs-5
.prediction-metric.col-md-3.col-xs-5
%h3 First harvest expected
%strong= crop.median_days_to_first_harvest
%span days
after planting
%span days after planting
- if crop.annual? && crop.median_days_to_last_harvest.present?
.metric.col-md-3.col-xs-5
.prediction-metric.col-md-3.col-xs-5
%h3 Last harvest expected
%strong= crop.median_days_to_last_harvest
%span days
after planting
%span days after planting

View File

@@ -5,18 +5,15 @@
.panel-body
.row
.col-md-2.col-xs-12.garden-info
.row
.col-md-12.col-xs-6
= render 'gardens/photo', garden: garden
.col-md-12.col-xs-6
= display_garden_description(garden)
%p= render 'gardens/photo', garden: garden
%p= display_garden_description(garden)
.col-md-10
.row
- if garden.plantings.current.size.positive?
- if garden.plantings.current.size.positive?
.row
- garden.plantings.current.order(created_at: :desc).includes(:crop, :photos).each do |planting|
.col-md-2.col-sm-4.col-xs-6
.col-lg-2.col-sm-4.col-xs-6
= render "plantings/thumbnail", planting: planting
- else
.col-md-2.col-sm-6.col-xs-6 no plantings
- else
no plantings
- if can?(:edit, garden)
.panel-footer= render 'gardens/actions', garden: garden

View File

@@ -1,21 +1,24 @@
- unless planting.finished?
// Finish times
- if planting.finish_is_predicatable?
- if planting.super_late?
%span.badge.badge-super-late= t('.super_late')
= planting_finish_button(planting)
- elsif planting.late?
%span.badge.badge-late= t('.late_finishing')
- else
%span.badge
= days_from_now_to_finished(planting)
= t('.days_until_finished')
.planting-badges
- unless planting.finished?
// Finish times
- if planting.finish_is_predicatable?
- if planting.super_late?
.badge.badge-super-late= t('.super_late')
= planting_finish_button(planting)
- elsif planting.late?
.badge.badge-late= t('.late_finishing')
- else
.badge{'data-toggle': "tooltip", 'data-placement': "top", title: 'Predicted days until planting is finished'}
= finished_icon
= t('label.days_until_finished', number: days_from_now_to_finished(planting))
// Harvest times
- unless planting.super_late?
- if planting.harvest_time?
%span.badge.badge-harvest= t('.harvesting_now')
- elsif planting.before_harvest_time?
%span.badge
= days_from_now_to_first_harvest(planting)
= t('.days_until_harvest')
// Harvest times
- unless planting.super_late?
- if planting.harvest_time?
.badge.badge-harvest{'data-toggle': "tooltip", 'data-placement': "top", title: 'Planting is ready for harvesting now'}
= harvest_icon
= t('label.harvesting_now')
- elsif planting.before_harvest_time?
.badge{'data-toggle': "tooltip", 'data-placement': "top", title: 'Predicted days until harvest'}
= harvest_icon
= t('label.days_until_harvest', number: days_from_now_to_first_harvest(planting))

View File

@@ -1,11 +1,13 @@
.progress
- if progress.nil?
= status
.progress-bar-text= status
- else
-# haml-lint:disable InlineStyles
%div{ class: "progress-bar progress-bar-#{status}", role: "progressbar", style: "width: #{progress}%" }
- if progress >= 30
#{sprintf '%.0f', progress}%
.progress-bar-text
#{sprintf '%.0f', progress}%
- if progress < 30
#{sprintf '%.0f', progress}%
.progress-bar-text
#{sprintf '%.0f', progress}%
-# haml-lint:enable InlineStyles

View File

@@ -0,0 +1,13 @@
- if can?(:edit, planting)
.planting-quick-actions.pull-right
%a.btn.btn-default.btn-xs#actionsMenu.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#"}
=icon('fas', 'bars')
%ul.dropdown-menu{"aria-labelledby" => "actionsMenu"}
- if can?(:edit, planting)
%li= planting_edit_button(planting)
%li= add_photo_button(planting)
- if planting.active?
%li= planting_finish_button(planting)
%li= planting_harvest_button(planting)
%li= planting_save_seeds_button(planting)

View File

@@ -1,20 +1,12 @@
.planting
.planting-badges
.planting-thumbnail
= render 'plantings/quick_actions', planting: planting
= render 'plantings/badges', planting: planting
.planting-thumbnail-image
= link_to planting do
= image_tag(planting_image_path(planting),
class: 'img-responsive planting-thumbnail-photo',
alt: planting)
.planting-quick-actions.pull-right
%a.btn.btn-default.btn-xs#actionsMenu.nav-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", href: "#"}
=icon('fas', 'bars')
.dropdown-menu{"aria-labelledby" => "actionsMenu"}
%p= render 'plantings/actions', planting: planting
.thumbnail
.planting-thumbnail{ class: planting_classes(planting) }
= link_to image_tag(planting_image_path(planting),
alt: planting.crop.name, class: 'img'), planting_path(planting)
= render 'plantings/progress', planting: planting, show_explanation: false
.planting-name
= link_to planting.crop.name, planting
= render 'plantings/progress', planting: planting, show_explanation: false
.planting-name= link_to planting.crop.name, planting

View File

@@ -190,6 +190,10 @@ en:
number_crops_linktext: "%{count} crops"
number_gardens_linktext: "%{count} gardens"
number_plantings_linktext: "%{count} times"
label:
days_until_harvest: "%{number} days"
days_until_finished: "%{number} days"
harvesting_now: harvesting now
layouts:
header:
account: Account

View File

@@ -1,6 +1,8 @@
#!/usr/bin/env ruby
require "English"
puts "Checking to see if you're in CONTRIBUTORS.md..."
if ENV['TRAVIS']
if ENV['TRAVIS_PULL_REQUEST']
require 'httparty'
@@ -27,7 +29,10 @@ Please set it using
end
end
unless system('grep', '-i', author, 'CONTRIBUTORS.md')
# Escape chars in name, and make case insensitive
author_to_search_for = Regexp.new(Regexp.escape(author), Regexp::IGNORECASE)
unless File.read('CONTRIBUTORS.md').match?(author_to_search_for)
abort %(
Thanks for your contribution, #{author}!
Please add your name and GitHub handle to the file CONTRIBUTORS.md,

View File

@@ -5,6 +5,7 @@ describe AdminController do
describe "GET admin/newsletter" do
before { get :newsletter }
describe 'fetches the admin newsletter page' do
it { expect(response).to be_success }
it { expect(response).to render_template("admin/newsletter") }
@@ -12,6 +13,7 @@ describe AdminController do
describe 'assigns @members' do
let!(:m) { FactoryBot.create(:newsletter_recipient_member) }
it { expect(assigns(:members)).to eq [m] }
end
end

View File

@@ -0,0 +1,84 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Api::V1::PlantingsController, type: :controller do
subject { JSON.parse response.body }
let(:headers) do
{
'Accept' => 'application/vnd.api+json',
'Content-Type' => 'application/vnd.api+json'
}
end
let!(:member) { FactoryBot.create :member }
describe '#index' do
let(:matching_planting) { subject['data'].select { |planting| planting['id'] == my_planting.id.to_s }.first }
describe 'GET #index' do
context 'basic planting' do
let!(:my_planting) { FactoryBot.create(:planting, owner: member, planted_at: '2000-01-01') }
let(:expected_attributes) do
{
'crop-name' => my_planting.crop.name,
'description' => my_planting.description,
'expected-lifespan' => nil,
'finish-predicted-at' => nil,
'finished' => my_planting.finished,
'finished-at' => my_planting.finished_at,
'first-harvest-date' => nil,
'last-harvest-date' => nil,
'percentage-grown' => nil,
'planted-at' => '2000-01-01',
'planted-from' => my_planting.planted_from,
'quantity' => my_planting.quantity,
'slug' => my_planting.slug,
'sunniness' => nil,
'thumbnail' => nil
}
end
before { get :index, format: :json }
it { expect(matching_planting).to include('id' => my_planting.id.to_s) }
it { expect(matching_planting['attributes']).to eq expected_attributes }
it { expect(response.status).to eq 200 }
end
context 'with photo' do
let!(:my_planting) { FactoryBot.create(:planting, owner: member, planted_at: '2000-01-01') }
let(:expected_attributes) do
{
'crop-name' => my_planting.crop.name,
'description' => my_planting.description,
'expected-lifespan' => nil,
'finish-predicted-at' => nil,
'finished' => my_planting.finished,
'finished-at' => my_planting.finished_at,
'first-harvest-date' => nil,
'last-harvest-date' => nil,
'percentage-grown' => nil,
'planted-at' => '2000-01-01',
'planted-from' => my_planting.planted_from,
'quantity' => my_planting.quantity,
'slug' => my_planting.slug,
'sunniness' => nil,
'thumbnail' => photo.thumbnail_url
}
end
let(:photo) { FactoryBot.create(:photo, owner: my_planting.owner) }
before do
my_planting.photos << photo
get :index, format: :json
end
it { expect(matching_planting).to include('id' => my_planting.id.to_s) }
it { expect(matching_planting['attributes']).to eq expected_attributes }
it { expect(response.status).to eq 200 }
end
end
end
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe AuthenticationsController do
before(:each) do
before do
@member = FactoryBot.create(:member)
sign_in @member
controller.stub(:current_member) { @member }

View File

@@ -3,16 +3,22 @@ require 'rails_helper'
describe Charts::CropsController do
describe 'GET charts' do
let(:crop) { FactoryBot.create :crop }
describe 'sunniness' do
before { get :sunniness, params: { crop_slug: crop.to_param } }
it { expect(response).to be_success }
end
describe 'planted_from' do
before { get :planted_from, params: { crop_slug: crop.to_param } }
it { expect(response).to be_success }
end
describe 'harvested_for' do
before { get :harvested_for, params: { crop_slug: crop.to_param } }
it { expect(response).to be_success }
end
end

View File

@@ -9,17 +9,19 @@ describe Charts::GardensController do
context "when not signed in" do
describe 'GET timeline' do
before { get :timeline, params: { garden_id: garden.to_param } }
it { expect(response).to be_success }
end
end
context "when signed in" do
before(:each) { sign_in member }
before { sign_in member }
let!(:member) { FactoryBot.create(:member) }
describe 'GET timeline' do
before { get :timeline, params: { garden_id: garden.to_param } }
it { expect(response).to be_success }
end
end

View File

@@ -5,7 +5,7 @@ describe CommentsController do
let(:member) { FactoryBot.create(:member) }
before(:each) do
before do
sign_in member
controller.stub(:current_member) { member }
end
@@ -35,12 +35,11 @@ describe CommentsController do
describe "with valid params" do
before { get :new, params: { post_id: post.id } }
let(:old_comment) { FactoryBot.create(:comment, post: post) }
it "picks up post from params" do
expect(assigns(:post)).to eq(post)
end
let(:old_comment) { FactoryBot.create(:comment, post: post) }
it "assigns the old comments as @comments" do
expect(assigns(:comments)).to eq [old_comment]
end
@@ -54,6 +53,7 @@ describe CommentsController do
describe "GET edit" do
let(:post) { FactoryBot.create(:post) }
before { get :edit, params: { id: comment.to_param } }
describe "my comment" do

View File

@@ -9,11 +9,13 @@ RSpec.describe GardensController, type: :controller do
context "when not signed in" do
describe 'GET new' do
before { get :new, params: { id: garden.to_param } }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'PUT create' do
before { put :create, params: { garden: valid_params } }
it { expect(response).to redirect_to(new_member_session_path) }
end
@@ -29,23 +31,26 @@ RSpec.describe GardensController, type: :controller do
describe 'GET edit' do
before { get :edit, params: { id: garden.to_param } }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'POST update' do
before { post :update, params: { id: garden.to_param, garden: valid_params } }
it { expect(response).to redirect_to(new_member_session_path) }
end
describe 'DELETE' do
before { delete :destroy, params: { id: garden.to_param, params: { garden: valid_params } } }
it { expect(response).to redirect_to(new_member_session_path) }
end
end
end
context "when signed in" do
before(:each) { sign_in member }
before { sign_in member }
let!(:member) { FactoryBot.create(:member) }
@@ -63,16 +68,19 @@ RSpec.describe GardensController, type: :controller do
describe 'GET edit' do
before { get :edit, params: { id: not_my_garden.to_param } }
it { expect(response).to redirect_to(root_path) }
end
describe 'POST update' do
before { post :update, params: { id: not_my_garden.to_param, garden: valid_params } }
it { expect(response).to redirect_to(root_path) }
end
describe 'DELETE' do
before { delete :destroy, params: { id: not_my_garden.to_param, params: { garden: valid_params } } }
it { expect(response).to redirect_to(root_path) }
end
end

View File

@@ -22,17 +22,20 @@ describe HarvestsController do
describe "assigns all harvests as @harvests" do
before { get :index, params: {} }
it { expect(assigns(:harvests)).to eq [harvest1, harvest2] }
end
describe "picks up owner from params and shows owner's harvests only" do
before { get :index, params: { member_slug: member1.slug } }
it { expect(assigns(:owner)).to eq member1 }
it { expect(assigns(:harvests)).to eq [harvest1] }
end
describe "picks up crop from params and shows the harvests for the crop only" do
before { get :index, params: { crop_slug: maize.name } }
it { expect(assigns(:crop)).to eq maize }
it { expect(assigns(:harvests)).to eq [harvest2] }
end
@@ -49,6 +52,7 @@ describe HarvestsController do
describe "assigns the requested harvest as @harvest" do
before { get :show, params: { id: harvest.to_param } }
it { expect(assigns(:harvest)).to eq(harvest) }
end
end
@@ -70,6 +74,7 @@ describe HarvestsController do
describe "assigns the requested harvest as @harvest" do
before { get :edit, params: { id: harvest.to_param } }
it { expect(assigns(:harvest)).to eq(harvest) }
end
end
@@ -84,18 +89,22 @@ describe HarvestsController do
describe "assigns a newly created harvest as @harvest" do
before { post :create, params: { harvest: valid_attributes } }
it { expect(assigns(:harvest)).to be_a(Harvest) }
it { expect(assigns(:harvest)).to be_persisted }
end
describe "redirects to the created harvest" do
before { post :create, params: { harvest: valid_attributes } }
it { expect(response).to redirect_to(Harvest.last) }
end
describe "links to planting" do
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) } }
it { expect(Harvest.last.planting.id).to eq(planting.id) }
end
end
@@ -111,6 +120,7 @@ describe HarvestsController do
describe "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
before { post :create, params: { harvest: { "crop_id" => "invalid value" } } }
it { expect(response).to render_template("new") }
end
end
@@ -133,6 +143,7 @@ describe HarvestsController do
describe "PUT update" do
describe "with valid params" do
let(:harvest) { Harvest.create! valid_attributes }
it "updates the requested harvest" do
new_crop = FactoryBot.create :crop
expect do
@@ -143,11 +154,13 @@ describe HarvestsController do
describe "assigns the requested harvest as @harvest" do
before { put :update, params: { id: harvest.to_param, harvest: valid_attributes } }
it { expect(assigns(:harvest)).to eq(harvest) }
end
describe "redirects to the harvest" do
before { put :update, params: { id: harvest.to_param, harvest: valid_attributes } }
it { expect(response).to redirect_to(harvest) }
end
end

View File

@@ -9,8 +9,9 @@ describe LikesController do
before { sign_in member }
describe "POST create" do
it { expect(response.content_type).to eq "application/json" }
before { post :create, params: { post_id: blogpost.id, format: :json } }
it { expect(response.content_type).to eq "application/json" }
it { expect(Like.last.likeable_id).to eq(blogpost.id) }
it { expect(Like.last.likeable_type).to eq('Post') }
it { JSON.parse(response.body)["description"] == "1 like" }
@@ -26,6 +27,7 @@ describe LikesController do
describe "DELETE destroy" do
before { delete :destroy, params: { id: like.id, format: :json } }
it { expect(response.content_type).to eq "application/json" }
describe "un-liking something i liked before" do

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe MembersController do
before :each do
before do
@member = FactoryBot.create(:member)
@posts = [FactoryBot.create(:post, author: @member)]
@twitter_auth = FactoryBot.create(:authentication, member: @member)
@@ -58,6 +58,7 @@ describe MembersController do
describe "GET member's RSS feed" do
describe "returns an RSS feed" do
before { get :show, params: { slug: @member.to_param }, format: "rss" }
it { response.should be_success }
it { response.should render_template("members/show") }
it { response.content_type.should eq("application/rss+xml") }

View File

@@ -35,7 +35,7 @@ describe PhotosController do
let(:member) { FactoryBot.create(:member) }
let!(:auth) { FactoryBot.create(:flickr_authentication, member: member) }
before(:each) do
before do
sign_in member
member.stub(:flickr_photos) { [[], 0] }
member.stub(:flickr_sets) { { "foo" => "bar" } }
@@ -43,7 +43,8 @@ describe PhotosController do
end
describe "planting photos" do
before(:each) { get :new, params: { type: "planting", id: planting.id } }
before { get :new, params: { type: "planting", id: planting.id } }
it { assigns(:flickr_auth).should be_an_instance_of(Authentication) }
it { assigns(:item).should eq planting }
it { expect(flash[:alert]).not_to be_present }
@@ -52,19 +53,21 @@ describe PhotosController do
describe "harvest photos" do
before { get :new, params: { type: "harvest", id: harvest.id } }
it { assigns(:item).should eq harvest }
it { expect(flash[:alert]).not_to be_present }
end
describe "garden photos" do
before { get :new, params: { type: "garden", id: garden.id } }
it { expect(assigns(:item)).to eq garden }
it { expect(flash[:alert]).not_to be_present }
end
end
describe "POST create" do
before(:each) do
before do
Photo.any_instance.stub(:flickr_metadata).and_return(title: "A Heartbreaking work of staggering genius",
license_name: "CC-BY",
license_url: "http://example.com/aybpl",
@@ -135,6 +138,7 @@ describe PhotosController do
describe "for the second time" do
let(:planting) { FactoryBot.create :planting, owner: member }
let(:valid_params) { { photo: { flickr_photo_id: 1 }, id: planting.id, type: 'planting' } }
it "does not add a photo twice" do
expect { post :create, params: valid_params }.to change(Photo, :count).by(1)
expect { post :create, params: valid_params }.not_to change(Photo, :count)
@@ -156,6 +160,7 @@ describe PhotosController do
before do
post :create, params: { photo: { flickr_photo_id: photo.flickr_photo_id }, type: "harvest", id: harvest.id }
end
it { expect(flash[:alert]).not_to be_present }
it { expect(Photo.last.harvests.first).to eq harvest }
end

View File

@@ -1,12 +1,12 @@
require 'rails_helper'
describe PlacesController do
before :each do
before do
controller.stub(:current_member) { nil }
end
describe "GET show" do
before(:each) do
before do
@member_london = FactoryBot.create(:london_member)
@member_south_pole = FactoryBot.create(:south_pole_member)
end

View File

@@ -26,12 +26,14 @@ describe PlantingsController do
describe "picks up owner from params and shows owner's plantings only" do
before { get :index, params: { member_slug: member1.slug } }
it { expect(assigns(:owner)).to eq member1 }
it { expect(assigns(:plantings)).to eq [planting1] }
end
describe "picks up crop from params and shows the plantings for the crop only" do
before { get :index, params: { crop_slug: maize.slug } }
it { expect(assigns(:crop)).to eq maize }
it { expect(assigns(:plantings)).to eq [planting2] }
end
@@ -40,44 +42,56 @@ describe PlantingsController do
describe "GET new" do
describe "picks up crop from params" do
let(:crop) { FactoryBot.create(:crop) }
before { get :new, params: { crop_id: crop.id } }
it { expect(assigns(:crop)).to eq(crop) }
end
describe "doesn't die if no crop specified" do
before { get :new, params: {} }
it { expect(assigns(:crop)).to be_a_new(Crop) }
end
describe "picks up member's garden from params" do
let(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { garden_id: garden.id } }
it { expect(assigns(:garden)).to eq(garden) }
end
describe "Doesn't display another member's garden on planting form" do
let(:another_member) { FactoryBot.create(:member) } # over-riding member from login_member()
let(:garden) { FactoryBot.create(:garden, owner: another_member) }
before { get :new, params: { garden_id: garden.id } }
it { expect(assigns(:garden)).not_to eq(garden) }
end
describe "Doesn't display un-approved crops on planting form" do
let(:crop) { FactoryBot.create(:crop, approval_status: 'pending') }
let!(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { crop_id: crop.id } }
it { expect(assigns(:crop)).not_to eq(crop) }
end
describe "Doesn't display rejected crops on planting form" do
let(:crop) { FactoryBot.create(:crop, approval_status: 'rejected', reason_for_rejection: 'nope') }
let!(:garden) { FactoryBot.create(:garden, owner: member) }
before { get :new, params: { crop_id: crop.id } }
it { expect(assigns(:crop)).not_to eq(crop) }
end
describe "doesn't die if no garden specified" do
before { get :new, params: {} }
it { expect(assigns(:garden)).to be_a_new(Garden) }
end
@@ -89,7 +103,9 @@ describe PlantingsController do
context 'with parent seed' do
let(:seed) { FactoryBot.create :seed, owner: member }
before { get :new, params: { seed_id: seed.to_param } }
it { expect(assigns(:seed)).to eq(seed) }
end
end
@@ -97,6 +113,7 @@ describe PlantingsController do
describe 'POST :create' do
describe "sets the owner automatically" do
before { post :create, params: { planting: valid_attributes } }
it { expect(assigns(:planting).owner).to eq subject.current_member }
end
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe RegistrationsController do
before :each do
before do
@member = FactoryBot.create(:member)
sign_in @member
controller.stub(:current_user) { @member }

View File

@@ -5,8 +5,10 @@ describe SeedsController do
describe "GET index" do
let(:owner) { FactoryBot.create(:member) }
describe "picks up owner from params" do
before { get :index, params: { member_slug: owner.slug } }
it { expect(assigns(:owner)).to eq(owner) }
end
end
@@ -22,7 +24,9 @@ describe SeedsController do
context 'with parent planting' do
let(:planting) { FactoryBot.create :planting, owner: owner }
before { get :new, params: { planting_id: planting.to_param } }
it { expect(assigns(:planting)).to eq(planting) }
end
end

View File

@@ -5,6 +5,7 @@ FactoryBot.define do
sender { FactoryBot.create :member }
recipient { FactoryBot.create :member }
subject { "MyString" }
body { "MyText" }
read { false }
post

View File

@@ -34,6 +34,7 @@ feature "crop wranglers", js: true do
describe "visiting a crop can see wrangler links" do
before { visit crop_path(crops.first) }
it { expect(page).to have_content 'You are a CROP WRANGLER' }
it { expect(page).to have_link 'Edit' }
it { expect(page).to have_link 'Delete' }

View File

@@ -13,6 +13,7 @@ feature "browse crops" do
context "when the most recently created harvest is not the most recently harvested" do
before { FactoryBot.create_list :harvest, 20, crop: tomato, harvested_at: 1.year.ago, created_at: 1.minute.ago }
let!(:most_recent_harvest) do
FactoryBot.create :harvest, crop: tomato, harvested_at: 60.minutes.ago, created_at: 10.minutes.ago
end
@@ -25,6 +26,7 @@ feature "browse crops" do
context "when the most recently created planting is not the most recently planted" do
before { FactoryBot.create_list :planting, 20, crop: tomato, planted_at: 1.year.ago, created_at: 1.minute.ago }
let!(:most_recent_planting) do
FactoryBot.create :planting, crop: tomato, planted_at: 60.minutes.ago, created_at: 10.minutes.ago
end

View File

@@ -55,13 +55,16 @@ feature "Gardens" do
describe '#show' do
describe 'my garden' do
before { visit garden_path(garden) }
it { is_expected.to have_link 'Edit' }
it { is_expected.to have_link 'Delete' }
it { is_expected.to have_content "Plant something here" }
it { is_expected.to have_content "Add photo" }
end
describe "someone else's garden" do
before { visit garden_path(other_member_garden) }
it { is_expected.not_to have_link 'Edit' }
it { is_expected.not_to have_link 'Delete' }
it { is_expected.not_to have_content "Plant something here" }

View File

@@ -34,7 +34,7 @@ feature "Gardens#index", :js do
it "show active garden" do
expect(page).to have_text active_garden.name
end
it "should not show inactive garden" do
it "does not show inactive garden" do
expect(page).not_to have_text inactive_garden.name
end
it "links to active garden" do
@@ -74,7 +74,7 @@ feature "Gardens#index", :js do
let(:member) { FactoryBot.create :member, login_name: 'robbieburns' }
let(:crop) { FactoryBot.create :crop }
before(:each) do
before do
# time to harvest = 50 day
# time to finished = 90 days
FactoryBot.create(:harvest,
@@ -104,8 +104,8 @@ feature "Gardens#index", :js do
it { expect(page).to have_link href: planting_path(planting) }
it { expect(page).to have_link href: garden_path(planting.garden) }
it { expect(page).to have_text '50 days until harvest' }
it { expect(page).to have_text '90 days until finished' }
it { expect(page).to have_text '50 days' }
it { expect(page).to have_text '90 days' }
it { expect(page).not_to have_text 'harvesting now' }
end
@@ -121,8 +121,8 @@ feature "Gardens#index", :js do
it { expect(crop.median_lifespan).to eq 90 }
it { expect(page).to have_text 'harvesting now' }
it { expect(page).to have_text '39 days until finished' }
it { expect(page).not_to have_text 'days until harvest' }
it { expect(page).to have_text '39 days' }
it { expect(page).not_to have_text 'Predicted days until harvest' }
end
describe 'super late' do
@@ -134,8 +134,8 @@ feature "Gardens#index", :js do
it { expect(page).to have_text 'super late' }
it { expect(page).not_to have_text 'harvesting now' }
it { expect(page).not_to have_text 'days until harvest' }
it { expect(page).not_to have_text 'days until finished' }
it { expect(page).not_to have_text 'Predicted days until harvest' }
it { expect(page).not_to have_text 'Predicted days until planting is finished' }
end
end
end

View File

@@ -21,7 +21,7 @@ feature "browse harvests" do
feature "filled in optional fields" do
let!(:harvest) { create :harvest, :long_description }
before(:each) do
before do
visit harvests_path
end

View File

@@ -87,6 +87,7 @@ feature "home page" do
describe 'should say welcome' do
before { visit root_path }
it { expect(page).to have_content "Welcome to #{ENV['GROWSTUFF_SITE_NAME']}, #{member.login_name}" }
end
end

View File

@@ -30,23 +30,23 @@ feature "User searches" do
search_with "Philippines"
end
it "should show that there are nearby seeds, plantings, and members" do
it "shows that there are nearby seeds, plantings, and members" do
expect(page).to have_content "Nearby members"
expect(page).to have_content "Seeds available for trade near Philippines"
expect(page).to have_content "Recent plantings near Philippines"
end
it "should go to members' index page" do
it "goes to members' index page" do
click_link 'View all members >>'
expect(current_path).to eq members_path
end
it "should go to plantings' index page" do
it "goes to plantings' index page" do
click_link 'View all plantings >>'
expect(current_path).to eq plantings_path
end
it "should go to seeds' index page" do
it "goes to seeds' index page" do
click_link 'View all seeds >>'
expect(current_path).to eq seeds_path
end

View File

@@ -64,7 +64,7 @@ feature "Planting a crop", :js, :elasticsearch do
@a_future_date = 1.year.from_now.strftime("%Y-%m-%d")
end
it "should show that it is not planted yet" do
it "shows that it is not planted yet" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -80,7 +80,7 @@ feature "Planting a crop", :js, :elasticsearch do
expect(page).to have_content "0%"
end
it "should show that days before maturity is unknown" do
it "shows that days before maturity is unknown" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -96,7 +96,7 @@ feature "Planting a crop", :js, :elasticsearch do
expect(page).to have_content "Not enough data"
end
it "should show that planting is in progress" do
it "shows that planting is in progress" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -115,7 +115,7 @@ feature "Planting a crop", :js, :elasticsearch do
expect(page).not_to have_content "Not enough data"
end
it "should show that planting is 100% complete (no date specified)" do
it "shows that planting is 100% complete (no date specified)" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -133,7 +133,7 @@ feature "Planting a crop", :js, :elasticsearch do
expect(page).to have_content "Yes (no date specified)"
end
it "should show that planting is 100% complete (date specified)" do
it "shows that planting is 100% complete (date specified)" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -234,13 +234,14 @@ feature "Planting a crop", :js, :elasticsearch do
click_button "Save"
end
end
it { expect(page).to have_content "planting was successfully created" }
it { expect(page).to have_content "Finished: Yes (no date specified)" }
it { expect(page).to have_content "100%" }
end
describe "Planting sunniness" do
it "should show the a sunny image" do
it "shows the a sunny image" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do
@@ -256,7 +257,7 @@ feature "Planting a crop", :js, :elasticsearch do
expect(page).to have_css("img[alt='sun']")
end
it "should show a sunniness not specified image" do
it "shows a sunniness not specified image" do
fill_autocomplete "crop", with: "mai"
select_from_autocomplete "maize"
within "form#new_planting" do

View File

@@ -47,6 +47,7 @@ feature "Seeds", :js, :elasticsearch do
click_button "Save"
end
end
it { expect(page).to have_content "Successfully added maize seed to your stash" }
it { expect(page).to have_content "Quantity: 42" }
it { expect(page).to have_content "Days until maturity: 9991999" }

View File

@@ -10,10 +10,12 @@ feature "seeds", js: true do
describe "button on index to edit seed" do
let!(:seed) { create :seed, owner: member }
before do
visit seeds_path
click_link "edit_seed_glyphicon"
end
it { expect(current_path).to eq edit_seed_path(seed) }
it { expect(page).to have_content 'Editing seeds' }
end
@@ -23,6 +25,7 @@ feature "seeds", js: true do
visit root_path
click_link "Save seeds"
end
it { expect(current_path).to eq new_seed_path }
it { expect(page).to have_content 'Save seeds' }
end
@@ -32,6 +35,7 @@ feature "seeds", js: true do
visit member_seeds_path(member)
click_link "View #{member}'s profile >>"
end
it { expect(current_path).to eq member_path(member) }
end
@@ -49,32 +53,39 @@ feature "seeds", js: true do
describe "delete seeds" do
let(:seed) { FactoryBot.create :seed, owner: member }
before do
visit seed_path(seed)
click_link 'Delete'
end
it { expect(current_path).to eq seeds_path }
end
describe '#show' do
before { visit seed_path(seed) }
describe "view seeds with max and min days until maturity" do
let(:seed) { FactoryBot.create :seed, days_until_maturity_min: 5, days_until_maturity_max: 7 }
it { expect(page).to have_content "Days until maturity: 57" }
end
describe "view seeds with only max days until maturity" do
let(:seed) { FactoryBot.create :seed, days_until_maturity_max: 7 }
it { expect(page).to have_content "Days until maturity: 7" }
end
describe "view seeds with only min days until maturity" do
let(:seed) { FactoryBot.create :seed, days_until_maturity_min: 5 }
it { expect(page).to have_content "Days until maturity: 5" }
end
describe "view seeds with neither max nor min days until maturity" do
let(:seed) { FactoryBot.create :seed }
it { expect(page).to have_content "Days until maturity: unknown" }
end
end

View File

@@ -3,6 +3,7 @@ require 'rails_helper'
feature "signout" do
let(:member) { create :member }
let(:path) {}
scenario "redirect to previous page after signout" do
visit crops_path # some random page
click_link 'Sign in'
@@ -29,8 +30,6 @@ feature "signout" do
end
end
let(:path) {}
describe 'after signout, redirect to signin page if page needs authentication' do
include_examples "sign-in redirects", "/plantings/new"
include_examples "sign-in redirects", "/harvests/new"

View File

@@ -17,25 +17,25 @@ describe ApplicationHelper do
describe '#avatar_uri' do
context 'with a normal user' do
before :each do
before do
@member = FactoryBot.build(:member, email: 'example@example.com', preferred_avatar_uri: nil)
end
it 'should render a gravatar uri' do
it 'renders a gravatar uri' do
expect(avatar_uri(@member)).to eq 'http://www.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?size=150&default=identicon'
end
it 'should render a gravatar uri for a given size' do
it 'renders a gravatar uri for a given size' do
expect(avatar_uri(@member, 456)).to eq 'http://www.gravatar.com/avatar/23463b99b62a72f26ed677cc556c44e8?size=456&default=identicon'
end
end
context 'with a user who specified a preferred avatar uri' do
before :each do
before do
@member = FactoryBot.build(:member, email: 'example@example.com', preferred_avatar_uri: 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg')
end
it 'should render a the specified uri' do
it 'renders a the specified uri' do
expect(avatar_uri(@member)).to eq 'http://media.catmoji.com/post/ujg/cat-in-hat.jpg'
end
end

View File

@@ -11,7 +11,8 @@ require 'rails_helper'
# end
# end
RSpec.describe ButtonsHelper, type: :helper do
before { allow(self).to receive(:can?) { true } }
before { allow(self).to receive(:can?).and_return(true) }
let(:garden) { FactoryBot.create :garden }
let(:planting) { FactoryBot.create :planting }
let(:harvest) { FactoryBot.create :harvest }

View File

@@ -2,13 +2,13 @@ require 'rails_helper'
describe CropsHelper do
describe "display_seed_availability" do
before :each do
@member = create :member
before do
@member = create :member
@crop = create :tomato
end
context "with no seeds" do
it 'should render' do
it 'renders' do
expect(helper.display_seed_availability(@member, @crop)).to eq "You don't have any seeds of this crop."
end
end
@@ -18,7 +18,7 @@ describe CropsHelper do
create :seed, crop: @crop, quantity: nil, owner: @member
end
it 'should render' do
it 'renders' do
expect(
helper.display_seed_availability(@member, @crop)
).to eq "You have an unknown quantity of seeds of this crop."
@@ -35,7 +35,7 @@ describe CropsHelper do
create :seed, crop: a_different_crop, quantity: 3, owner: @member
end
it 'should render' do
it 'renders' do
expect(helper.display_seed_availability(@member, @crop)).to eq "You have 33 seeds of this crop."
end
end

View File

@@ -2,12 +2,12 @@ require 'rails_helper'
require './lib/actions/oauth_signup_action'
describe 'Growstuff::OauthSignupAction' do
before :each do
before do
@action = Growstuff::OauthSignupAction.new
end
context 'with a valid authentication' do
before :each do
before do
@auth = OmniAuth::AuthHash.new('provider' => 'facebook',
'uid' => '123545',
'info' => {
@@ -23,7 +23,7 @@ describe 'Growstuff::OauthSignupAction' do
end
context 'no existing user' do
before :each do
before do
@auth['info']['email'] = 'no.existing.user@gmail.com'
Member.where(email: @auth['info']['email']).delete_all
@@ -32,36 +32,36 @@ describe 'Growstuff::OauthSignupAction' do
@authentication = @action.establish_authentication(@auth, @member)
end
after :each do
after do
@member.delete
@authentication.delete
end
it 'should create a new user' do
it 'creates a new user' do
expect(@action.member_created?).to eq true
end
it 'should set the right email' do
it 'sets the right email' do
expect(@member.email).to eq @auth['info']['email']
end
it 'should generate a login_name' do
it 'generates a login_name' do
expect(@member.login_name).to eq 'JohnnyB'
end
it 'should set an avatar' do
it 'sets an avatar' do
expect(@member.preferred_avatar_uri).to eq @auth['info']['image']
end
it 'should generate a random password' do
it 'generates a random password' do
expect(@member.password).not_to eq nil
end
it 'should not agree to the tos' do
it 'does not agree to the tos' do
expect(@member.tos_agreement).to eq nil
end
it 'should store the uid and provider for the member' do
it 'stores the uid and provider for the member' do
expect(@authentication.member.id).to eq @member.id
expect(@authentication.provider).to eq 'facebook'
expect(@authentication.uid).to eq '123545'
@@ -70,7 +70,7 @@ describe 'Growstuff::OauthSignupAction' do
context 'an existing user' do
context 'who has never used oauth' do
before :each do
before do
@auth['info']['email'] = 'never.used.oauth@yahoo.com'
Member.where(email: @auth['info']['email']).delete_all
@@ -82,29 +82,29 @@ describe 'Growstuff::OauthSignupAction' do
@authentication = @action.establish_authentication(@auth, @member)
end
after :each do
after do
@existing_member.delete
@member.delete
@authentication.delete
end
it 'should not create a new user' do
it 'does not create a new user' do
expect(@action.member_created?).to eq nil
end
it 'should locate the existing member by email' do
it 'locates the existing member by email' do
expect(@member.id).to eq @existing_member.id
end
it 'should not generate a login_name' do
it 'does not generate a login_name' do
expect(@member.login_name).to eq 'existing'
end
it 'should not change the avatar' do
it 'does not change the avatar' do
expect(@member.preferred_avatar_uri).to eq 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
end
it 'should store the uid and provider for the member' do
it 'stores the uid and provider for the member' do
expect(@authentication.member.id).to eq @member.id
expect(@authentication.provider).to eq 'facebook'
expect(@authentication.uid).to eq '123545'
@@ -112,7 +112,7 @@ describe 'Growstuff::OauthSignupAction' do
end
context 'who has used oauth' do
before :each do
before do
@auth['info']['email'] = 'i.used.oauth.once@coolemail.com'
Member.where(email: @auth['info']['email']).delete_all
@@ -131,30 +131,30 @@ describe 'Growstuff::OauthSignupAction' do
@authentication = @action.establish_authentication(@auth, @member)
end
after :each do
after do
@existing_member.delete
@member.delete
@existing_authentication.delete
@authentication.delete
end
it 'should not create a new user' do
it 'does not create a new user' do
expect(@action.member_created?).to eq nil
end
it 'should locate the existing member by uid and provider' do
it 'locates the existing member by uid and provider' do
expect(@member.id).to eq @existing_member.id
end
it 'should not generate a login_name' do
it 'does not generate a login_name' do
expect(@member.login_name).to eq 'schrodingerscat'
end
it 'should not change the avatar' do
it 'does not change the avatar' do
expect(@member.preferred_avatar_uri).to eq 'http://cl.jroo.me/z3/W/H/K/e/a.baa-very-cool-hat-you-.jpg'
end
it 'should locate the existing uid and provider for the member' do
it 'locates the existing uid and provider for the member' do
expect(@authentication.id).to eq @existing_authentication.id
end
end

View File

@@ -51,7 +51,7 @@ describe Ability do
context "crop wrangler" do
let(:role) { FactoryBot.create(:crop_wrangler) }
before(:each) do
before do
member.roles << role
end

View File

@@ -3,11 +3,11 @@ require 'rails_helper'
describe AlternateName do
let(:an) { FactoryBot.create(:alternate_eggplant) }
it 'should save a basic alternate name' do
it 'saves a basic alternate name' do
expect(an.save).to be(true)
end
it 'should be possible to add multiple alternate names to a crop' do
it 'is possible to add multiple alternate names to a crop' do
crop = an.crop
an2 = AlternateName.create(
name: "really alternative tomato",

View File

@@ -42,7 +42,7 @@ describe Comment do
end
context "ordering" do
before(:each) do
before do
@m = FactoryBot.create(:member)
@p = FactoryBot.create(:post, author: @m)
@c1 = FactoryBot.create(:comment, post: @p, author: @m)

View File

@@ -1,7 +1,7 @@
require 'spec_helper'
describe Follow do
before(:each) do
before do
@member1 = FactoryBot.create(:member)
@member2 = FactoryBot.create(:member)
end
@@ -20,20 +20,20 @@ describe Follow do
end
context "when follow is created" do
before(:each) do
before do
@follow = Follow.create(follower_id: @member1.id, followed_id: @member2.id)
end
it "should not duplicate follows" do
it "does not duplicate follows" do
expect(Follow.create(follower_id: @member1.id, followed_id: @member2.id)).not_to be_valid
end
it "should list users in following/follower collections when follow is created" do
it "lists users in following/follower collections when follow is created" do
expect(@member1.followed).to include(@member2)
expect(@member2.followers).to include(@member1)
end
it "should no longer list users in following/follower collections when follow is deleted" do
it "noes longer list users in following/follower collections when follow is deleted" do
@follow.destroy
expect(@member1.followed).not_to include(@member2)
expect(@member2.followers).not_to include(@member1)

View File

@@ -4,11 +4,11 @@ describe Garden do
let(:owner) { FactoryBot.create(:member, login_name: 'hatupatu') }
let(:garden) { FactoryBot.create(:garden, owner: owner, name: 'Springfield Community Garden') }
it "should have a slug" do
it "has a slug" do
garden.slug.should match(/hatupatu-springfield-community-garden/)
end
it "should have a description" do
it "has a description" do
garden.description.should == "This is a **totally** cool garden"
end
@@ -47,11 +47,11 @@ describe Garden do
garden.should_not be_valid
end
it "should have an owner" do
it "has an owner" do
garden.owner.should be_an_instance_of Member
end
it "should stringify as its name" do
it "stringifies as its name" do
garden.to_s.should == garden.name
end
@@ -63,14 +63,14 @@ describe Garden do
let(:pear) { FactoryBot.create(:pear) }
let(:walnut) { FactoryBot.create(:walnut) }
it "should fetch < 4 featured plantings if insufficient exist" do
it "fetches < 4 featured plantings if insufficient exist" do
@p1 = FactoryBot.create(:planting, crop: tomato, garden: garden, owner: garden.owner)
@p2 = FactoryBot.create(:planting, crop: maize, garden: garden, owner: garden.owner)
expect(garden.featured_plantings).to eq [@p2, @p1]
end
it "should fetch most recent 4 featured plantings" do
it "fetches most recent 4 featured plantings" do
@p1 = FactoryBot.create(:planting, crop: tomato, garden: garden, owner: garden.owner)
@p2 = FactoryBot.create(:planting, crop: maize, garden: garden, owner: garden.owner)
@p3 = FactoryBot.create(:planting, crop: chard, garden: garden, owner: garden.owner)
@@ -80,7 +80,7 @@ describe Garden do
expect(garden.featured_plantings).to eq [@p5, @p4, @p3, @p2]
end
it "should skip repeated plantings" do
it "skips repeated plantings" do
@p1 = FactoryBot.create(:planting, crop: tomato, garden: garden, owner: garden.owner)
@p2 = FactoryBot.create(:planting, crop: maize, garden: garden, owner: garden.owner)
@p3 = FactoryBot.create(:planting, crop: chard, garden: garden, owner: garden.owner)
@@ -148,7 +148,7 @@ describe Garden do
end
end
it 'should refuse invalid unit values' do
it 'refuses invalid unit values' do
garden = FactoryBot.build(:garden, area_unit: 'not valid')
garden.should_not be_valid
garden.errors[:area_unit].should include("not valid is not a valid area unit")

View File

@@ -52,7 +52,7 @@ describe Harvest do
end
end
it 'should refuse invalid unit values' do
it 'refuses invalid unit values' do
@harvest = FactoryBot.build(:harvest, unit: 'not valid')
@harvest.should_not be_valid
@harvest.errors[:unit].should include("not valid is not a valid unit")
@@ -105,7 +105,7 @@ describe Harvest do
end
end
it 'should refuse invalid weight unit values' do
it 'refuses invalid weight unit values' do
@harvest = FactoryBot.build(:harvest, weight_unit: 'not valid')
@harvest.should_not be_valid
@harvest.errors[:weight_unit].should include("not valid is not a valid unit")
@@ -223,23 +223,23 @@ describe Harvest do
end
context 'photos' do
before :each do
before do
@harvest = FactoryBot.create(:harvest)
end
context 'without a photo' do
it 'should have no default photo' do
it 'has no default photo' do
expect(@harvest.default_photo).to eq nil
end
context 'and with a crop(planting) photo' do
before :each do
before do
@planting = FactoryBot.create(:planting, crop: @harvest.crop)
@photo = FactoryBot.create(:photo, owner: @planting.owner)
@planting.photos << @photo
end
it 'should have a default photo' do
it 'has a default photo' do
expect(@harvest.default_photo).to eq @photo
end
end
@@ -270,19 +270,19 @@ describe Harvest do
end
context 'and with a crop(planting) photo' do
before :each do
before do
@planting = FactoryBot.create(:planting, crop: @harvest.crop)
@crop_photo = FactoryBot.create(:photo, owner: @planting.owner)
@planting.photos << @crop_photo
end
it 'should prefer the harvest photo' do
it 'prefers the harvest photo' do
expect(@harvest.default_photo).to eq @photo
end
end
context 'and a second photo' do
before :each do
before do
@photo2 = FactoryBot.create(:photo, owner: @harvest.owner)
@harvest.photos << @photo2
end

View File

@@ -5,7 +5,7 @@ describe 'like' do
let(:post) { FactoryBot.create(:post) }
context 'existing like' do
before(:each) do
before do
@like = Like.create(member: member, likeable: post)
end

View File

@@ -6,6 +6,7 @@ describe 'member' do
describe 'should be fetchable from the database' do
subject { Member.find(member.id) }
it { is_expected.to be_an_instance_of Member }
it { expect(subject.encrypted_password).not_to be_nil }
end
@@ -19,7 +20,7 @@ describe 'member' do
expect(member.bio).to eq 'I love seeds'
end
it 'should have a default garden' do
it 'has a default garden' do
expect(member.gardens.count).to eq 1
end
@@ -27,16 +28,16 @@ describe 'member' do
expect(member.show_email).to eq false
end
it 'should stringify as the login_name' do
it 'stringifies as the login_name' do
expect(member.to_s).to eq 'hinemoa'
end
it 'should be able to fetch posts' do
it 'is able to fetch posts' do
post = FactoryBot.create(:post, author: member)
expect(member.posts).to eq [post]
end
it 'should be able to fetch gardens' do
it 'is able to fetch gardens' do
expect(member.gardens.first.name).to eq "Garden"
end
@@ -92,7 +93,7 @@ describe 'member' do
context 'no TOS agreement' do
let(:member) { FactoryBot.build(:no_tos_member) }
it "should refuse to save a member who hasn't agreed to the TOS" do
it "refuses to save a member who hasn't agreed to the TOS" do
member.save.should_not be(true)
end
end
@@ -107,7 +108,7 @@ describe 'member' do
end
context 'same :login_name' do
it "should not allow two members with the same login_name" do
it "does not allow two members with the same login_name" do
FactoryBot.create(:member, login_name: "bob")
member = FactoryBot.build(:member, login_name: "bob")
member.should_not be_valid
@@ -199,7 +200,7 @@ describe 'member' do
end
context 'confirmed scope' do
before(:each) do
before do
FactoryBot.create(:member)
FactoryBot.create(:member)
end
@@ -251,7 +252,7 @@ describe 'member' do
# 4) ordered by the most recent sign in
context 'with a few members and plantings' do
before :each do
before do
@members = [
:london_member, :london_member, :london_member,
:unconfirmed_member, # !1

View File

@@ -218,25 +218,25 @@ describe Planting do
planting.location.should eq "#{garden_owner.login_name}'s #{garden.name}"
end
it "should have a slug" do
it "has a slug" do
planting.slug.should match(/^hatupatu-springfield-community-garden-tomato$/)
end
it 'should sort in reverse creation order' do
it 'sorts in reverse creation order' do
@planting2 = FactoryBot.create(:planting)
Planting.first.should eq @planting2
end
describe '#planted?' do
it "should be false for future plantings" do
it "is false for future plantings" do
planting = FactoryBot.create :planting, planted_at: Time.zone.today + 1
expect(planting.planted?).to eq(false)
end
it "should be false for never planted" do
it "is false for never planted" do
planting = FactoryBot.create :planting, planted_at: nil
expect(planting.planted?).to eq(false)
end
it "should be true for past plantings" do
it "is true for past plantings" do
planting = FactoryBot.create :planting, planted_at: Time.zone.today - 1
expect(planting.planted?).to eq(true)
end
@@ -287,7 +287,7 @@ describe Planting do
context 'sunniness' do
let(:planting) { FactoryBot.create(:sunny_planting) }
it 'should have a sunniness value' do
it 'has a sunniness value' do
planting.sunniness.should eq 'sun'
end
@@ -298,7 +298,7 @@ describe Planting do
end
end
it 'should refuse invalid sunniness values' do
it 'refuses invalid sunniness values' do
@planting = FactoryBot.build(:planting, sunniness: 'not valid')
@planting.should_not be_valid
@planting.errors[:sunniness].should include("not valid is not a valid sunniness value")
@@ -306,7 +306,7 @@ describe Planting do
end
context 'planted from' do
it 'should have a planted_from value' do
it 'has a planted_from value' do
@planting = FactoryBot.create(:seed_planting)
@planting.planted_from.should eq 'seed'
end
@@ -320,7 +320,7 @@ describe Planting do
end
end
it 'should refuse invalid planted_from values' do
it 'refuses invalid planted_from values' do
@planting = FactoryBot.build(:planting, planted_from: 'not valid')
@planting.should_not be_valid
@planting.errors[:planted_from].should include("not valid is not a valid planting method")
@@ -332,6 +332,7 @@ describe Planting do
context 'photos' do
let(:planting) { FactoryBot.create(:planting) }
let(:photo) { FactoryBot.create(:photo, owner_id: planting.owner_id) }
before { planting.photos << photo }
it 'has a photo' do

View File

@@ -2,9 +2,10 @@ require 'rails_helper'
describe Post do
let(:member) { FactoryBot.create(:member, login_name: 'whinacooper') }
it_behaves_like "it is likeable"
it "should have a slug" do
it "has a slug" do
post = FactoryBot.create(:post, author: member)
time = post.created_at
datestr = time.strftime("%Y%m%d")
@@ -135,16 +136,16 @@ describe Post do
let!(:chard) { FactoryBot.create(:chard) }
let!(:post) { FactoryBot.create(:post, body: "[maize](crop)[tomato](crop)[tomato](crop)") }
it "should be generated" do
it "is generated" do
expect(tomato.posts).to eq [post]
expect(maize.posts).to eq [post]
end
it "should not duplicate" do
it "does not duplicate" do
expect(post.crops) =~ [tomato, maize]
end
it "should be updated when post was modified" do
it "is updated when post was modified" do
post.update(body: "[chard](crop)")
expect(post.crops).to eq [chard]
@@ -158,12 +159,12 @@ describe Post do
post.destroy
end
it "should delete the association" do
it "deletes the association" do
expect(Crop.find(tomato.id).posts).to eq []
expect(Crop.find(maize.id).posts).to eq []
end
it "should not delete the crops" do
it "does not delete the crops" do
expect(Crop.find(tomato.id)).not_to eq nil
expect(Crop.find(maize.id)).not_to eq nil
end

View File

@@ -4,11 +4,11 @@ describe ScientificName do
context 'all fields present' do
let(:sn) { FactoryBot.create(:zea_mays) }
it 'should save a basic scientific name' do
it 'saves a basic scientific name' do
sn.save.should be(true)
end
it 'should be fetchable from the database' do
it 'is fetchable from the database' do
sn.save
@sn2 = ScientificName.find_by(name: 'Zea mays')
@sn2.crop.name.should == 'maize'
@@ -21,7 +21,7 @@ describe ScientificName do
end
context 'invalid data' do
it 'should not save a scientific name without a name' do
it 'does not save a scientific name without a name' do
sn = ScientificName.new
expect { sn.save! }.to raise_error ActiveRecord::RecordInvalid
end

View File

@@ -4,11 +4,11 @@ describe Seed do
let(:owner) { FactoryBot.create :owner, login_name: 'tamateapokaiwhenua' }
let(:seed) { FactoryBot.build(:seed, owner: owner) }
it 'should save a basic seed' do
it 'saves a basic seed' do
seed.save.should be(true)
end
it "should have a slug" do
it "has a slug" do
seed.save
seed.slug.should match(/tamateapokaiwhenua-magic-bean/)
end
@@ -45,7 +45,7 @@ describe Seed do
end
end
it 'should refuse invalid tradable_to values' do
it 'refuses invalid tradable_to values' do
@seed = FactoryBot.build(:seed, tradable_to: 'not valid')
@seed.should_not be_valid
@seed.errors[:tradable_to].should include(
@@ -54,7 +54,7 @@ describe Seed do
)
end
it 'should not allow nil or blank values' do
it 'does not allow nil or blank values' do
@seed = FactoryBot.build(:seed, tradable_to: nil)
@seed.should_not be_valid
@seed = FactoryBot.build(:seed, tradable_to: '')
@@ -112,7 +112,7 @@ describe Seed do
end
end
it 'should refuse invalid organic/GMO/heirloom values' do
it 'refuses invalid organic/GMO/heirloom values' do
%i(organic gmo heirloom).each do |field|
@seed = FactoryBot.build(:seed, field => 'not valid')
@seed.should_not be_valid
@@ -120,7 +120,7 @@ describe Seed do
end
end
it 'should not allow nil or blank values' do
it 'does not allow nil or blank values' do
%i(organic gmo heirloom).each do |field|
@seed = FactoryBot.build(:seed, field => nil)
@seed.should_not be_valid
@@ -154,6 +154,7 @@ describe Seed do
let(:seed) { FactoryBot.create :seed }
before { seed.photos << FactoryBot.create(:photo, owner: seed.owner) }
it 'is found in has_photos scope' do
Seed.has_photos.should include(seed)
end
@@ -162,6 +163,7 @@ describe Seed do
context 'ancestry' do
let(:parent_planting) { FactoryBot.create :planting }
let(:seed) { FactoryBot.create :seed, parent_planting: parent_planting, owner: parent_planting.owner }
it "seed has a parent planting" do
expect(seed.parent_planting).to eq(parent_planting)
end

View File

@@ -65,11 +65,13 @@ RSpec.describe 'Plantings', type: :request do
describe '#index' do
before { get '/api/v1/crops', params: {}, headers: headers }
it { expect(subject['data']).to include(crop_encoded_as_json_api) }
end
describe '#show' do
before { get "/api/v1/crops/#{crop.id}", params: {}, headers: headers }
it { expect(subject['data']['attributes']).to eq(attributes) }
it { expect(subject['data']['relationships']).to include("plantings" => plantings_as_json_api) }
it { expect(subject['data']['relationships']).to include("harvests" => harvests_as_json_api) }

View File

@@ -59,11 +59,13 @@ RSpec.describe 'Harvests', type: :request do
describe '#index' do
before { get '/api/v1/harvests', params: {}, headers: headers }
it { expect(subject['data']).to include(harvest_encoded_as_json_api) }
end
describe '#show' do
before { get "/api/v1/harvests/#{harvest.id}", params: {}, headers: headers }
it { expect(subject['data']['attributes']).to eq(attributes) }
it { expect(subject['data']['relationships']).to include("planting" => planting_as_json_api) }
it { expect(subject['data']['relationships']).to include("crop" => crop_as_json_api) }

View File

@@ -59,11 +59,13 @@ RSpec.describe 'Members', type: :request do
describe '#index' do
before { get '/api/v1/members', params: {}, headers: headers }
it { expect(subject['data']).to include(member_encoded_as_json_api) }
end
describe '#show' do
before { get "/api/v1/members/#{member.id}", params: {}, headers: headers }
it { expect(subject['data']['relationships']).to include("gardens" => gardens_as_json_api) }
it { expect(subject['data']['relationships']).to include("plantings" => plantings_as_json_api) }
it { expect(subject['data']['relationships']).to include("seeds" => seeds_as_json_api) }

View File

@@ -57,11 +57,13 @@ RSpec.describe 'Photos', type: :request do
describe '#index' do
before { get '/api/v1/photos', params: {}, headers: headers }
it { expect(subject['data']).to include(photo_encoded_as_json_api) }
end
describe '#show' do
before { get "/api/v1/photos/#{photo.id}", params: {}, headers: headers }
it { expect(subject['data']['attributes']).to eq(attributes) }
it { expect(subject['data']['relationships']).to include("plantings" => plantings_as_json_api) }
it { expect(subject['data']['relationships']).to include("harvests" => harvests_as_json_api) }

View File

@@ -53,18 +53,21 @@ RSpec.describe 'Plantings', type: :request do
let(:attributes) do
{
"slug" => planting.slug,
"planted-at" => "2014-07-30",
"finished-at" => nil,
"finished" => false,
"quantity" => 33,
"description" => planting.description,
"crop-name" => planting.crop.name,
"sunniness" => nil,
"planted-from" => nil,
"expected-lifespan" => nil,
"finish-predicted-at" => nil,
"percentage-grown" => nil,
"first-harvest-date" => nil,
"last-harvest-date" => nil
"last-harvest-date" => nil,
"thumbnail" => nil
}
end

View File

@@ -46,11 +46,13 @@ RSpec.describe 'Photos', type: :request do
describe '#index' do
before { get '/api/v1/seeds', params: {}, headers: headers }
it { expect(subject['data']).to include(seed_encoded_as_json_api) }
end
describe '#show' do
before { get "/api/v1/seeds/#{seed.id}", params: {}, headers: headers }
it { expect(subject['data']['attributes']).to eq(attributes) }
it { expect(subject['data']['relationships']).to include("owner" => owner_as_json_api) }
it { expect(subject['data']['relationships']).to include("crop" => crop_as_json_api) }

View File

@@ -2,7 +2,7 @@
module ControllerMacros
def login_member(member_factory = :member)
let(:member) { FactoryBot.create(member_factory || :member) }
before(:each) do
before do
@request.env["devise.mapping"] = Devise.mappings[:member]
sign_in member
end

View File

@@ -3,7 +3,7 @@ RSpec.configure do |config|
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
config.before do
DatabaseCleaner.strategy = :transaction
end
@@ -11,11 +11,11 @@ RSpec.configure do |config|
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
config.before do
DatabaseCleaner.start
end
config.after(:each) do
config.after do
DatabaseCleaner.clean
end
end

View File

@@ -1,5 +1,5 @@
shared_examples "it is likeable" do
before(:each) do
before do
# Possibly a horrible hack.
# Will fail if factory name does not match the model name..
@likeable = FactoryBot.create(described_class.to_s.underscore.to_sym)
@@ -17,7 +17,7 @@ shared_examples "it is likeable" do
expect(@likeable.members.length).to eq 2
end
it 'should destroy the like when it is destroyed' do
it 'destroys the like when it is destroyed' do
like_count = -1 * @likeable.likes.count
expect { @likeable.destroy }.to change(Like, :count).by like_count
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'admin/index.html.haml', type: "view" do
before(:each) do
before do
@member = FactoryBot.create(:admin_member)
sign_in @member
controller.stub(:current_user) { @member }

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'admin/newsletter.html.haml', type: "view" do
before(:each) do
before do
@member = FactoryBot.create(:admin_member)
sign_in @member
controller.stub(:current_user) { @member }

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "comments/edit" do
before(:each) do
before do
controller.stub(:current_user) { nil }
assign(:comment, FactoryBot.create(:comment))
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "comments/index" do
before(:each) do
before do
controller.stub(:current_user) { nil }
page = 1
per_page = 2

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'comments/index.rss.haml' do
before(:each) do
before do
controller.stub(:current_user) { nil }
@author = FactoryBot.create(:member)
@post = FactoryBot.create(:post)

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "comments/new" do
before(:each) do
before do
controller.stub(:current_user) { nil }
@post = FactoryBot.create(:post)
@comment = FactoryBot.create(:comment, post: @post)

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "comments/show" do
before(:each) do
before do
controller.stub(:current_user) { nil }
@comment = assign(:comment, FactoryBot.create(:comment))
render

View File

@@ -5,7 +5,7 @@ describe "crops/_planting_advice" do
let(:planting) { FactoryBot.create(:planting) }
shared_examples "render planting_advice" do
shared_context "render planting_advice" do
before { render 'crops/planting_advice', crop: planting.crop }
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/_popover" do
before(:each) do
before do
@tomato = FactoryBot.create(:tomato)
@sn = FactoryBot.create(:solanum_lycopersicum, crop: @tomato)
@planting = FactoryBot.create(:planting, crop: @tomato)

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/edit" do
before(:each) do
before do
controller.stub(:current_user) do
FactoryBot.create(:crop_wrangling_member)
end

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/hierarchy" do
before(:each) do
before do
controller.stub(:current_user) { nil }
@tomato = FactoryBot.create(:tomato)
@roma = FactoryBot.create(:crop, name: 'Roma tomato', parent: @tomato)

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/index" do
before(:each) do
before do
controller.stub(:current_user) { nil }
page = 1
per_page = 2
@@ -29,7 +29,7 @@ describe "crops/index" do
end
context "logged in and crop wrangler" do
before(:each) do
before do
@member = FactoryBot.create(:crop_wrangling_member)
sign_in @member
controller.stub(:current_user) { @member }

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe 'crops/index.rss.haml' do
before(:each) do
before do
controller.stub(:current_user) { nil }
@author = FactoryBot.create(:member)
@tomato = FactoryBot.create(:tomato)

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/new" do
before(:each) do
before do
@crop = FactoryBot.create(:maize)
3.times do
@crop.scientific_names.build

View File

@@ -1,7 +1,7 @@
require 'rails_helper'
describe "crops/wrangle" do
before(:each) do
before do
@member = FactoryBot.create(:crop_wrangling_member)
controller.stub(:current_user) { @member }
page = 1

View File

@@ -1,5 +1,5 @@
describe 'devise/confirmations/new.html.haml', type: "view" do
before(:each) do
before do
@view.stub(:resource).and_return(Member.new)
@view.stub(:resource_name).and_return("member")
@view.stub(:resource_class).and_return(Member)
@@ -7,7 +7,7 @@ describe 'devise/confirmations/new.html.haml', type: "view" do
render
end
it 'should contain a login field' do
it 'contains a login field' do
rendered.should have_content "Enter either your login name or your email address"
end
end

View File

@@ -2,16 +2,16 @@ require 'rails_helper'
describe 'devise/mailer/confirmation_instructions.html.haml', type: "view" do
context "logged in" do
before(:each) do
before do
@resource = FactoryBot.create(:member)
render
end
it 'should have a confirmation link' do
it 'has a confirmation link' do
rendered.should have_content 'Confirm my account'
end
it 'should have a link to the homepage' do
it 'has a link to the homepage' do
rendered.should have_content root_url
end
end

View File

@@ -2,14 +2,14 @@ require 'rails_helper'
describe 'devise/mailer/reset_password_instructions.html.haml', type: "view" do
context "logged in" do
before(:each) do
before do
@resource = mock_model(Member)
@resource.stub(:email).and_return("example@example.com")
@resource.stub(:reset_password_token).and_return("joe")
render
end
it 'should have some of the right text' do
it 'has some of the right text' do
rendered.should have_content 'Change my password'
rendered.should have_content 'Someone has requested a link to reset your password'
end

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