Merge branch 'dev' into members_nearby

Conflicts:
	spec/factories/member.rb
This commit is contained in:
Miles Gould
2013-04-02 13:10:38 +01:00
46 changed files with 564 additions and 128 deletions

View File

@@ -1,5 +1,27 @@
class HomeController < ApplicationController
skip_authorize_resource
def index
@member_count = Member.confirmed.count
@crop_count = Crop.count
@planting_count = Planting.count
@garden_count = Garden.count
@interesting_members = Member.interesting.limit(6)
# customise what we show on the homepage based on whether you're
# logged in or not.
@member = current_member
@plantings = current_member ?
current_member.plantings.limit(10) :
Planting.limit(10)
@posts = current_member ?
current_member.posts.limit(10) :
Post.limit(10)
respond_to do |format|
format.html # index.html.haml
end
end
end

View File

@@ -9,7 +9,7 @@ class MembersController < ApplicationController
end
def show
@member = Member.find_confirmed(params[:id])
@member = Member.confirmed.find(params[:id])
@posts = @member.posts
# The garden form partial is called from the "New Garden" tab;
# it requires a garden to be passed in @garden.

View File

@@ -1,18 +1,15 @@
class NotificationsController < ApplicationController
load_and_authorize_resource
# GET /notifications
# GET /notifications.json
def index
@notifications = Notification.find_all_by_recipient_id(current_member)
respond_to do |format|
format.html # index.html.erb
format.json { render json: @notifications }
end
end
# GET /notifications/1
# GET /notifications/1.json
def show
@notification = Notification.find(params[:id])
@notification.read = true
@@ -20,19 +17,42 @@ class NotificationsController < ApplicationController
respond_to do |format|
format.html # show.html.erb
format.json { render json: @notification }
end
end
# GET /notifications/new
def new
@notification = Notification.new
@recipient = Member.find_by_id(params[:recipient_id])
respond_to do |format|
format.html # new.html.erb
end
end
# DELETE /notifications/1
# DELETE /notifications/1.json
def destroy
@notification = Notification.find(params[:id])
@notification.destroy
respond_to do |format|
format.html { redirect_to notifications_url }
format.json { head :no_content }
end
end
# POST /notifications
def create
params[:notification][:sender_id] = current_member.id
@notification = Notification.new(params[:notification])
@recipient = Member.find_by_id(params[:notification][:recipient_id])
respond_to do |format|
if @notification.save
format.html { redirect_to @recipient, notice: 'Message was successfully sent.' }
else
format.html { render action: "new" }
end
end
end
end

View File

@@ -18,6 +18,7 @@ class PostsController < ApplicationController
# GET /posts/1.json
def show
@post = Post.find(params[:id])
@comments = @post.comments
respond_to do |format|
format.html # show.html.haml

View File

@@ -7,6 +7,7 @@ class Ability
# everyone can do these things, even non-logged in
can :read, :all
cannot :read, Notification
cannot :create, Notification
# nobody should be able to view this except admins
cannot :read, Role
@@ -28,7 +29,13 @@ class Ability
# can read/delete notifications that were sent to them
can :read, Notification, :recipient_id => member.id
can :destroy, Notification, :recipient_id => member.id
# note we don't support create/update for notifications
# can send a private message to anyone but themselves
# note: sadly, we can't test for this from the view, but it works
# for the model/controller
can :create, Notification do |n|
n.recipient_id != member.id
end
# note we don't support update for notifications
# only crop wranglers can create/edit/destroy crops
if member.has_role? :crop_wrangler

View File

@@ -3,6 +3,8 @@ class Comment < ActiveRecord::Base
belongs_to :author, :class_name => 'Member'
belongs_to :post
default_scope order("created_at asc")
after_create do
recipient = self.post.author.id
sender = self.author.id

View File

@@ -10,7 +10,15 @@ class Member < ActiveRecord::Base
has_and_belongs_to_many :roles
has_many :notifications, :foreign_key => 'recipient_id'
has_many :sent_notifications, :foreign_key => 'sender_id'
default_scope order("lower(login_name) asc")
scope :confirmed, where('confirmed_at IS NOT NULL')
scope :located, where('location IS NOT NULL')
scope :recently_signed_in, reorder('updated_at DESC')
# this is used on the signed-out homepage so we're basically
# just trying to select some members who look good.
scope :interesting, confirmed.located.recently_signed_in
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
@@ -68,14 +76,6 @@ class Member < ActiveRecord::Base
end
end
def self.find_confirmed(params)
find(params, :conditions => 'confirmed_at IS NOT NULL')
end
def self.confirmed
where('confirmed_at IS NOT NULL')
end
def to_s
return login_name
end

View File

@@ -1,5 +1,5 @@
class Notification < ActiveRecord::Base
attr_accessible :sender_id, :recipient_id,
attr_accessible :sender_id, :recipient_id,
:subject, :body, :post_id, :read
belongs_to :sender, :class_name => 'Member'

View File

@@ -2,17 +2,29 @@ class Planting < ActiveRecord::Base
extend FriendlyId
friendly_id :planting_slug, use: :slugged
attr_accessible :crop_id, :description, :garden_id, :planted_at, :quantity,
:planted_at_string
attr_accessible :crop_id, :description, :garden_id, :planted_at,
:quantity, :sunniness, :planted_at_string
belongs_to :garden
belongs_to :crop
delegate :default_scientific_name,
default_scope order("created_at desc")
delegate :system_name,
:en_wikipedia_url,
:default_scientific_name,
:plantings_count,
:to => :crop,
:prefix => true
default_scope order("created_at desc")
SUNNINESS_VALUES = %w(sun semi-shade shade)
validates :sunniness, :inclusion => { :in => SUNNINESS_VALUES,
:message => "%{value} is not a valid sunniness value" },
:allow_nil => true,
:allow_blank => true
def planting_slug
"#{owner.login_name}-#{garden}-#{crop}".downcase.gsub(' ', '-')
end
@@ -34,6 +46,6 @@ class Planting < ActiveRecord::Base
end
def planted_at_string=(str)
self.planted_at = Time.parse(str)
self.planted_at = str == '' ? nil : Time.parse(str)
end
end

View File

@@ -1,5 +1,4 @@
.thumbnail(style='height: 200px')
.thumbnail(style='height: 220px')
- if crop
= link_to image_tag('http://placehold.it/150x150', :alt => '', :class => 'img-rounded'), crop
%p

View File

@@ -1,6 +1,15 @@
%h1
= Growstuff::Application.config.site_name
%h1= Growstuff::Application.config.site_name
%p #{Growstuff::Application.config.site_name} is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
%p
#{Growstuff::Application.config.site_name} is a community of food gardeners. We're building an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. We offer growing information tailored to your location, and help you connect with your local food-growing community.
%p= link_to 'Learn more', 'http://wiki.growstuff.org/', :class => 'btn btn-primary btn-large'
%strong
So far,
= link_to "#{@member_count} members", members_path
have planted
= link_to "#{@crop_count} crops", crops_path
#{@planting_count} times in #{@garden_count} gardens.
You could be one of them. Sign up for a free account and start tracking your food garden today.
%p
= link_to 'Join now', new_member_registration_path, :class => 'btn btn-primary btn-large'

View File

@@ -45,78 +45,30 @@
.row
.span6
%h2 Your recent plantings
- if current_member.plantings.count > 0
%ul
- current_member.plantings.limit(10).each do |p|
%li
= link_to "#{p.crop.system_name} in #{p.location}", p
- if p.planted_at
on
= p.planted_at.to_s(:date)
- else
%p None yet.
- if can? :create, Planting
%p= link_to "Plant something", new_planting_path, :class => 'btn btn-primary'
= render :partial => 'shared/recent_plantings'
.span6
%h2 Your recent posts
- if current_member.posts.count > 0
%ul
- current_member.posts.limit(10).each do |p|
%li
= link_to p.subject, p
- if p.forum
in
= link_to p.forum.name, p.forum
on
= p.created_at.to_s(:date)
- else
%p None yet.
- if can? :create, Planting
%p= link_to "Post something", new_post_path, :class => 'btn btn-primary'
.span6
= render :partial => 'shared/recent_posts'
- else
.visible-desktop.visible-tablet
.hero-unit
= render :partial => 'blurb'
.visible-phone
= render :partial => 'blurb'
.row
.span3
%h2 Track
%p
Track your garden, your
= link_to 'crops', crops_path
, and everything to do with them. |
Remember what you planted or harvested, and plan for what you want to do next. |
Import and export your data to a spreadsheet or other format.
- if @interesting_members
%h2 Some of our members
%ul.thumbnails
- @interesting_members.each do |m|
%li.span2
= render :partial => "members/thumbnail", :locals => { :member => m }
.span3
%h2 Connect
%p
Connect with friends, people who live in your area, or others |
who share your gardening interests. Show off your crops and |
harvests, share updates and tips, and
= link_to 'see', posts_path
what everyone else is doing, too.
.span3
%h2 Learn
%p
Browse our
= link_to 'crops', crops_path
database and learn about food plants for your
climate and garden type. Read other
= link_to "members' posts", posts_path
and tips, or post questions and discuss food gardening issues in our forums.
.span3
%h2 Trade
%p
Use #{ Growstuff::Application.config.site_name } as a marketplace
for everything related to food gardens. Buy and sell, trade,
or give away anything from seeds to garden supplies, or find
events and businesses in your area.
.row
.span6
%h2 Recent plantings
= render :partial => 'shared/recent_plantings'
.span6
%h2 Recent posts
= render :partial => 'shared/recent_posts'

View File

@@ -25,4 +25,4 @@
/ Placed at the end of the document so the pages load faster
= javascript_include_tag "application"
= Growstuff::Application.config.analytics_code
!= Growstuff::Application.config.analytics_code

View File

@@ -0,0 +1,8 @@
.thumbnail(style="height: 220px")
= render :partial => "members/avatar", :locals => { :member => member }
%p
= link_to member.to_s, member
- if member.location
%br/
%i
%small= member.location

View File

@@ -11,9 +11,7 @@
%ul.thumbnails
- @members.each do |m|
%li.span2
.thumbnail(style="height: 190px")
= render :partial => "members/avatar", :locals => { :member => m }
= link_to m.to_s, m
= render :partial => "members/thumbnail", :locals => { :member => m }
%div.pagination
= page_entries_info @members, :model => "members"

View File

@@ -6,6 +6,11 @@
.span3
= render :partial => "members/avatar", :locals => { :member => @member }
-if can? :create, Notification and current_member != @member
%p
%br/
=link_to 'Send Message', new_notification_path(:sender_id => current_member.id, :recipient_id => @member.id), :class => 'btn btn-primary'
%p
= "Member since: #{@member.created_at.to_s(:date)}"
- if @member.location.to_s != ''

View File

@@ -0,0 +1,22 @@
= form_for @notification do |f|
- if @notification.errors.any?
#error_explanation
%h2= "#{pluralize(@post.errors.count, "error")} prohibited this message from being sent:"
%ul
- @notification.errors.full_messages.each do |msg|
%li= msg
.field
= f.hidden_field :recipient_id, :value => @recipient.id
%p
To:
= link_to @recipient, @recipient
= label_tag :notification, "Subject:"
= f.text_field :subject, :class => 'input-block-level'
= label_tag :body, "Type your message here:"
= f.text_area :body, :rows => 12, :class => 'input-block-level'
%span.help-block
= render :partial => "shared/markdown_help"
= f.submit "Send", :class => 'btn btn-primary'

View File

@@ -23,9 +23,9 @@
%strong= link_to n.subject, notification_path(n)
%td
- if n.read
= n.created_at.to_s(:date)
= n.created_at
- else
%strong= n.created_at.to_s(:date)
%strong= n.created_at
%td
= link_to 'Delete', n, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini'
- else

View File

@@ -0,0 +1,4 @@
= content_for :title, "Send a message to #{@recipient}"
=render 'form'

View File

@@ -4,7 +4,7 @@
From
= link_to @notification.sender, @notification.sender
on
= @notification.created_at.to_s(:date)
= @notification.created_at
- if @notification.post_id
in response to:

View File

@@ -3,18 +3,18 @@
%p
You have received a message from
= link_to @notification.sender.login_name, url_for(:controller => 'members', :action => 'show', :id => @notification.sender.id, :only_path => false )
on #{site_name} at #{@notification.created_at.to_s(:date)}
= link_to @notification.sender.login_name, member_url(@notification.sender)
on #{site_name} at #{@notification.created_at}
- if @notification.post
in response to
= link_to @notification.post.subject, url_for(:controller => 'posts', :action => 'show', :id => @notification.post.id, :only_path => false)
= link_to @notification.post.subject, post_url(@notification.post)
\.
%blockquote
:markdown
#{strip_tags @notification.body}
%p
= link_to "View this message in your inbox", url_for(:controller => 'notifications', :action => 'show', :id => @notification.id, :only_path => false)
= link_to "View this message in your inbox", notification_url(@notification)
%br/
= link_to "Turn off these notifications", edit_member_registration_url

View File

@@ -20,6 +20,10 @@
= f.label 'How many?', :class => 'control-label'
.controls
= f.number_field :quantity, :class => 'input-small'
.control-group
= f.label 'Sun or shade?', :class => 'control-label'
.controls
= f.select(:sunniness, Planting::SUNNINESS_VALUES, {:include_blank => true})
.control-group
= f.label 'Tell us more about it', :class => 'control-label'
.controls= f.text_area :description, :rows => 6

View File

@@ -8,7 +8,7 @@
%p
Planted
- if planting.planted_at
= planting.planted_at.to_s(:date)
= planting.planted_at
in
= link_to planting.location, planting.garden

View File

@@ -4,7 +4,7 @@
.span6
%p
%b Planted:
= @planting.planted_at ? @planting.planted_at.to_s(:date) : "not specified"
= @planting.planted_at ? @planting.planted_at : "not specified"
%p
%b Where:
=link_to "#{@planting.owner}'s", @planting.owner
@@ -15,6 +15,12 @@
%b Quantity:
= @planting.quantity != 0 ? @planting.quantity : "not specified"
- if ! @planting.sunniness.blank?
%p
%b Sun or shade?
= @planting.sunniness
- if can? :edit, @planting or can? :destroy, @planting
%p
- if can? :edit, @planting

View File

@@ -12,10 +12,10 @@
%a{:name => "comments"}
- if @post.comments.length > 0
- if @comments
%h2
=pluralize(@post.comments.length, "comment")
- @post.comments.each do |c|
=pluralize(@comments.length, "comment")
- @comments.each do |c|
= render :partial => "comments/single", :locals => { :comment => c }
- else

View File

@@ -0,0 +1,12 @@
- if @plantings
%ul
- @plantings.each do |p|
%li
= link_to "#{p.crop_system_name} in #{p.location}", p
- if p.planted_at
on
= p.planted_at
- else
%p None yet.
- if can? :create, Planting
%p= link_to "Plant something", new_planting_path, :class => 'btn btn-primary'

View File

@@ -0,0 +1,17 @@
- if @posts
%ul
- @posts.each do |p|
%li
= link_to p.subject, p
- unless @member
posted by
= link_to p.author, p.author
- if p.forum
in
= link_to p.forum.name, p.forum
on
= p.created_at.to_s(:date)
- else
%p None yet.
- if can? :create, Post
%p= link_to "Post something", new_post_path, :class => 'btn btn-primary'

View File

@@ -1 +1,7 @@
Time::DATE_FORMATS[:default] = '%B %d, %Y at %H:%M'
Date::DATE_FORMATS[:default] = "%B %d, %Y"
Time::DATE_FORMATS[:date] = "%B %d, %Y"
Date::DATE_FORMATS[:date] = "%B %d, %Y"
Time::DATE_FORMATS[:datetime] = '%B %d, %Y at %H:%M'

View File

@@ -0,0 +1,5 @@
class AddSunninessToPlanting < ActiveRecord::Migration
def change
add_column :plantings, :sunniness, :string
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130327120024) do
ActiveRecord::Schema.define(:version => 20130329045744) do
create_table "comments", :force => true do |t|
t.integer "post_id", :null => false
@@ -116,6 +116,7 @@ ActiveRecord::Schema.define(:version => 20130327120024) do
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "slug"
t.string "sunniness"
end
add_index "plantings", ["slug"], :name => "index_plantings_on_slug", :unique => true

View File

@@ -0,0 +1,39 @@
require 'spec_helper'
describe HomeController do
describe "GET index" do
it "assigns counts" do
@planting = FactoryGirl.create(:planting)
get :index, {}
assigns(:garden_count).should == 2 # auto-created for member and planting
assigns(:planting_count).should == 1
assigns(:crop_count).should == 1
assigns(:member_count).should == 1
end
it "assigns posts and plantings" do
@post = FactoryGirl.create(:post)
@planting = FactoryGirl.create(:planting)
get :index, {}
assigns(:posts).should eq [@post]
assigns(:plantings).should eq [@planting]
end
it 'assigns interesting members' do
@member = FactoryGirl.create(:geolocated_member)
get :index, {}
assigns(:interesting_members).should eq [@member]
end
context 'logged in' do
login_member
it 'assigns member' do
get :index, {}
assigns(:member).should be_an_instance_of Member
end
end
end
end

View File

@@ -5,7 +5,22 @@ describe NotificationsController do
login_member
def valid_attributes
{ "recipient_id" => subject.current_member.id }
{
"recipient_id" => subject.current_member.id,
"sender_id" => FactoryGirl.create(:member).id
}
end
# this gets a bit confused because for most of the notification tests
# (reading, etc) the logged in member needs to be the recipient.
# However, for sending private messages (create, etc) the logged in
# member needs to be the sender. Hence this separate set of
# attributes.
def valid_attributes_for_sender
{
"sender_id" => subject.current_member.id,
"recipient_id" => FactoryGirl.create(:member).id
}
end
def valid_session
@@ -36,6 +51,19 @@ describe NotificationsController do
end
end
describe "GET new" do
it "assigns a new notification as @notification" do
get :new, {}
assigns(:notification).should be_a_new(Notification)
end
it "assigns a recipient" do
@recipient = FactoryGirl.create(:member)
get :new, {:recipient_id => @recipient.id }
assigns(:recipient).should be_an_instance_of(Member)
end
end
describe "DELETE destroy" do
it "destroys the requested notification" do
notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id)
@@ -51,4 +79,41 @@ describe NotificationsController do
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new notification" do
expect {
post :create, {:notification => valid_attributes_for_sender}
}.to change(Notification, :count).by(1)
end
it "assigns a newly created notification as @notification" do
post :create, {:notification => valid_attributes_for_sender}
assigns(:notification).should be_a(Notification)
assigns(:notification).should be_persisted
end
it "redirects to the recipient's profile" do
@recipient = FactoryGirl.create(:member)
post :create, { :notification => { :recipient_id => @recipient.id } }
response.should redirect_to(@recipient)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved notification as @notification" do
# Trigger the behavior that occurs when invalid params are submitted
Notification.any_instance.stub(:save).and_return(false)
post :create, {:notification => {}}
assigns(:notification).should be_a_new(Notification)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
Notification.any_instance.stub(:save).and_return(false)
post :create, {:notification => {}}
response.should render_template("new")
end
end
end
end

View File

@@ -1,7 +1,7 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :notification do
factory :notification, aliases: [:message] do
sender
recipient
subject "MyString"

View File

@@ -2,8 +2,9 @@ FactoryGirl.define do
factory :planting do
garden
crop
planted_at Time.now
planted_at Date.today
quantity 33
description "This is a *really* good plant."
sunniness 'sun'
end
end

View File

@@ -7,16 +7,34 @@ describe Ability do
@ability = Ability.new(@member)
end
it 'member can view their own notifications' do
@notification = FactoryGirl.create(:notification, :recipient => @member)
@ability.should be_able_to(:read, @notification)
end
context "notifications" do
it 'member can view their own notifications' do
@notification = FactoryGirl.create(:notification, :recipient => @member)
@ability.should be_able_to(:read, @notification)
end
it "member can't view someone else's notifications" do
@notification = FactoryGirl.create(:notification,
:recipient => FactoryGirl.create(:member)
)
@ability.should_not be_able_to(:read, @notification)
it "member can't view someone else's notifications" do
@notification = FactoryGirl.create(:notification,
:recipient => FactoryGirl.create(:member)
)
@ability.should_not be_able_to(:read, @notification)
end
it "member can't send messages to themself" do
@ability.should_not be_able_to(:create,
FactoryGirl.create(:notification,
:recipient => @member,
:sender => @member
)
)
end
it "member can send messages to someone else" do
@ability.should be_able_to(:create,
FactoryGirl.create(:notification,
:recipient => FactoryGirl.create(:member),
:sender => @member
)
)
end
end
context "crop wrangling" do

View File

@@ -199,4 +199,40 @@ describe 'member' do
end
end
context 'confirmed scope' do
before(:each) do
@member1 = FactoryGirl.create(:member)
@member2 = FactoryGirl.create(:member)
end
it 'sees confirmed members' do
Member.confirmed.count.should == 2
end
it 'ignores unconfirmed members' do
@member3 = FactoryGirl.create(:unconfirmed_member)
Member.confirmed.count.should == 2
end
end
context 'interesting scope' do
# active members are defined as:
# 1) confirmed
# 2) ordered by the most recent sign in
it 'finds interesting members' do
@member1 = FactoryGirl.create(:geolocated_member)
@member2 = FactoryGirl.create(:geolocated_member)
@member3 = FactoryGirl.create(:geolocated_member)
@member4 = FactoryGirl.create(:unconfirmed_member)
@member1.updated_at = 3.days.ago
@member2.updated_at = 2.days.ago
@member3.updated_at = 1.days.ago
Member.interesting.should eq [ @member3, @member2, @member1 ]
end
end
end

View File

@@ -19,6 +19,12 @@ describe Planting do
@planting.location.should match /^member\d+'s Springfield Community Garden$/
end
it "sorts plantings in descending order of creation" do
@planting1 = FactoryGirl.create(:planting)
@planting2 = FactoryGirl.create(:planting)
Planting.first.should eq @planting2
end
it "should have a slug" do
@planting.slug.should match /^member\d+-springfield-community-garden-tomato$/
end
@@ -33,9 +39,51 @@ describe Planting do
@planting.planted_at.should == Time.local(2013, 03, 01)
end
it 'should accept blank dates' do
@planting.planted_at_string = ''
@planting.planted_at.should == nil
end
it "should output dates in ISO format" do
@planting.planted_at = Time.local(2013, 03, 01)
@planting.planted_at_string.should == "2013-03-01"
end
it 'should sort in reverse creation order' do
@planting2 = FactoryGirl.create(:planting)
Planting.first.should eq @planting2
end
context 'delegation' do
it 'system name' do
@planting.crop_system_name.should eq @planting.crop.system_name
end
it 'wikipedia url' do
@planting.crop_en_wikipedia_url.should eq @planting.crop.en_wikipedia_url
end
it 'default scientific name' do
@planting.crop_default_scientific_name.should eq @planting.crop.default_scientific_name
end
it 'plantings count' do
@planting.crop_plantings_count.should eq @planting.crop.plantings_count
end
end
it 'should have a sunniness value' do
@planting.sunniness.should eq 'sun'
end
it 'all three valid sunniness values should work' do
['sun', 'shade', 'semi-shade', nil, ''].each do |s|
@planting = FactoryGirl.build(:planting, :sunniness => s)
@planting.should be_valid
end
end
it 'should refuse invalid sunniness values' do
@planting = FactoryGirl.build(:planting, :sunniness => 'not valid')
@planting.should_not be_valid
@planting.errors[:sunniness].should include("not valid is not a valid sunniness value")
end
end

View File

@@ -3,12 +3,33 @@ require 'spec_helper'
describe 'home/index.html.haml', :type => "view" do
context 'logged out' do
before(:each) do
@member = FactoryGirl.create(:geolocated_member)
@member.updated_at = 2.days.ago
@post = FactoryGirl.create(:post, :author => @member)
@planting = FactoryGirl.create(:planting, :garden => @member.gardens.first)
controller.stub(:current_user) { nil }
assign(:interesting_members, [@member])
assign(:plantings, [@planting])
assign(:posts, [@post])
render
end
it 'should have description' do
it 'has description' do
rendered.should contain 'is a community of food gardeners'
rendered.should contain 'We welcome you regardless of your experience, and invite you to be part of our development process.'
end
it 'show recent posts' do
rendered.should contain @post.subject
end
it 'show recent plantings' do
rendered.should contain @planting.crop_system_name
rendered.should contain @planting.garden.name
end
it 'show interesting members' do
rendered.should contain @member.login_name
rendered.should contain @member.location
end
end
@@ -17,11 +38,14 @@ describe 'home/index.html.haml', :type => "view" do
@member = FactoryGirl.create(:geolocated_member)
controller.stub(:current_user) { @member }
sign_in @member
assign(:member, @member)
@planting = FactoryGirl.create(:planting,
:garden => @member.gardens.first
)
assign(:plantings, [@planting])
@forum = FactoryGirl.create(:forum, :owner => @member)
@post = FactoryGirl.create(:post, :author => @member)
assign(:posts, [@post])
@role = FactoryGirl.create(:admin)
@member.roles << @role
render

View File

@@ -58,9 +58,10 @@ describe 'layouts/application.html.haml', :type => "view" do
end
it 'includes the analytics code' do
Growstuff::Application.config.analytics_code = 'ANALYTICS'
Growstuff::Application.config.analytics_code = '<script>alert("foo!")</script>'
render
rendered.should contain 'ANALYTICS'
assert_select "script", :text => 'alert("foo!")'
rendered.should_not contain 'script'
end
end

View File

@@ -6,11 +6,9 @@ describe "members/index" do
page = 1
per_page = 2
total_entries = 2
@member = FactoryGirl.create(:geolocated_member)
members = WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
pager.replace([
FactoryGirl.create(:member),
FactoryGirl.create(:member)
])
pager.replace([ @member, @member ])
end
assign(:members, members)
render
@@ -20,4 +18,8 @@ describe "members/index" do
assert_select "img", :src => /gravatar\.com\/avatar/, :count => 2
end
it 'contains member locations' do
rendered.should contain @member.location
end
end

View File

@@ -76,6 +76,10 @@ describe "members/show" do
it "contains an edit settings button" do
rendered.should contain "Edit Settings"
end
it "contains no send message button" do
rendered.should_not contain "Send Message"
end
end
context "signed in as different member" do
@@ -97,6 +101,10 @@ describe "members/show" do
it "contains no edit settings button" do
rendered.should_not contain "Edit Settings"
end
it "contains a send message button" do
rendered.should contain "Send Message"
end
end
context "public member" do
@@ -108,6 +116,10 @@ describe "members/show" do
it "shows the email address" do
rendered.should contain @member.email
end
it "doesn't show a send message button" do
rendered.should_not contain "Send Message"
end
end
context "geolocations" do

View File

@@ -0,0 +1,36 @@
require 'spec_helper'
describe "notifications/new" do
before(:each) do
@recipient = FactoryGirl.create(:member)
@sender = FactoryGirl.create(:member)
assign(:notification, FactoryGirl.create(:notification, :recipient_id => @recipient.id, :sender_id => @sender.id))
# assign(:forum, Forum.new)
sign_in @sender
controller.stub(:current_user) { @sender}
end
it "renders new message form" do
render
assert_select "form", :action => notifications_path, :method => "notification" do
assert_select "input#notification_subject", :name => "notification[subject]"
assert_select "textarea#notification_body", :name => "notification[body]"
end
end
it "tells you who the recipient is" do
render
rendered.should contain @recipient.login_name
end
it "Tells you to write your message here" do
render
rendered.should contain "Type your message here"
end
it 'shows markdown help' do
render
rendered.should contain 'Markdown'
end
end

View File

@@ -25,7 +25,7 @@ describe "plantings/_thumbnail" do
end
it "renders the date planted" do
rendered.should contain @planting.planted_at.to_s(:date)
rendered.should contain @planting.planted_at.to_s(:default)
end
it "shows the name of the crop" do

View File

@@ -33,6 +33,7 @@ describe "plantings/new" do
assert_select "select#planting_crop_id", :name => "planting[crop_id]"
assert_select "input#planting_quantity", :name => "planting[quantity]"
assert_select "textarea#planting_description", :name => "planting[description]"
assert_select "select#planting_sunniness", :name => "planting[sunniness]"
end
end

View File

@@ -9,6 +9,26 @@ describe "plantings/show" do
)
end
it "shows the sunniness" do
controller.stub(:current_user) { nil }
@member = FactoryGirl.create(:member)
create_planting_for(@member)
render
rendered.should contain 'Sun or shade?'
rendered.should contain 'sun'
end
it "doesn't show sunniness if blank" do
controller.stub(:current_user) { nil }
@member = FactoryGirl.create(:member)
@p = create_planting_for(@member)
@p.sunniness = ''
@p.save
render
rendered.should_not contain 'Sun or shade?'
rendered.should_not contain 'sun'
end
context "no location set" do
before(:each) do
controller.stub(:current_user) { nil }

View File

@@ -46,6 +46,7 @@ describe "posts/show" do
@post = assign(:post,
FactoryGirl.create(:html_post, :author => @author))
@comment = FactoryGirl.create(:comment, :post => @post)
@comments = @post.comments
render
end
@@ -62,6 +63,26 @@ describe "posts/show" do
end
end
context "when there is more than one comment" do
before(:each) do
@post = assign(:post,
FactoryGirl.create(:html_post, :author => @author))
@comment1 = FactoryGirl.create(:comment, :post => @post, :body => "F1rst!!!",
:created_at => Date.new(2010, 5, 17))
@comment3 = FactoryGirl.create(:comment, :post => @post, :body => "Th1rd!!!",
:created_at => Date.new(2012, 5, 17))
@comment4 = FactoryGirl.create(:comment, :post => @post, :body => "F0urth!!!")
@comment2 = FactoryGirl.create(:comment, :post => @post, :body => "S3c0nd!!1!",
:created_at => Date.new(2011, 5, 17))
@comments = @post.comments
render
end
it "shows the oldest comments first" do
rendered.should contain /#{@comment1.body}.*#{@comment2.body}.*#{@comment3.body}.*#{@comment4.body}/m
end
end
context "forum post" do
it "shows forum name" do
@post = assign(:post,