Merge branch 'dev' into photos

Conflicts:
	db/schema.rb
This commit is contained in:
Miles Gould
2013-05-31 11:24:19 +01:00
92 changed files with 831 additions and 288 deletions

3
.gitignore vendored
View File

@@ -6,3 +6,6 @@
*~
*.DS_Store
credentials.sh
Pathogen:
custom_plan.rb
zeus.json

39
CONTRIBUTORS.md Normal file
View File

@@ -0,0 +1,39 @@
This is a list of contributors to Growstuff's codebase. We maintain
this list because we work in pairs, but Github only knows about the
person who actually does the commits. This gives credit to both members
of the pair.
If you contribute, please add yourself to the bottom of the list and
submit the change with your pull request.
## Committers
- Alex Bayley / [Skud](https://github.com/Skud)
- Cesy / [cesy](https://github.com/cesy)
- Miles Gould / [pozorvlak](https://github.com/pozorvlak)
- Joseph Caudle / [jcaudle](https://github.com/jcaudle)
## Contributors
- Ricky Amianym / [amianym](https://github.com/amianym)
- Juliet Kemp / [julietk](https://github.com/julietk)
- Federico Mena Quintero / [federicomenaquintero](https://github.com/federicomenaquintero)
- Jay Springett / [thejaymo](https://github.com/thejaymo)
- Maia Sauren / [sauramaia](https://github.com/sauramaia)
- Norman Ancajas / [nbancajas](https://github.com/nbancajas)
- Jonathan "Duke" Leto / [leto](https://github.com/leto)
- Mackenzie Morgan / [maco](https://github.com/maco)
- Amy Hendrix / [sabreuse](https://github.com/sabreuse)
- CephLPod / [cephLpod](https://github.com/cephLpod/)
- Gemma Mason / [gemmaellen](https://github.com/gemmaellen)
- Courtney Webster / [phazel](https://github.com/phazel/)
- Cathy Sullivan / [cesullivan](https://github.com/cesullivan)
- Jared McCorkindale / [jmcorkindale](https://github.com/jmcorkindale)
- Florian Vallen / [flov](https://github.com/flov)
- Samuel Cochrane / [sj26](https://github.com/sj26)
- Craig Read / [Catharz](https://github.com/Catharz)
- Ju Transcendancing / [transcendancing](https://github.com/transcendancing)
- Lillian Ryan / [attlebish](https://github.com/attlebish)
- Gary Traffanstedt / [blimey85](https://github.com/blimey85)
- Yaw Boakye / [yawboakye](https://github.com/yawboakye)
- Ryan Clark / [IAMRYO](https://github.com/IAMRYO)

View File

@@ -80,7 +80,6 @@ gem 'bootstrap-datepicker-rails'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-flickr'
gem 'authbuttons-rails'
# for phusion passenger (i.e. mod_rails) on the server
gem 'passenger'

View File

@@ -29,7 +29,6 @@ GEM
i18n (= 0.6.1)
multi_json (~> 1.0)
arel (3.0.2)
authbuttons-rails (0.1.2)
bcrypt-ruby (3.0.1)
bluecloth (2.2.0)
bootstrap-datepicker-rails (1.0.0)
@@ -234,7 +233,6 @@ PLATFORMS
ruby
DEPENDENCIES
authbuttons-rails
bluecloth
bootstrap-datepicker-rails
bundler (>= 1.1.5)

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -2,12 +2,12 @@ class CommentsController < ApplicationController
# GET /comments
# GET /comments.json
def index
@comments = Comment.all
@recent_comments = Comment.limit(100).order('created_at desc').all
@comments = Comment.paginate(:page => params[:page])
respond_to do |format|
format.html # index.html.erb
format.json { render json: @comments }
format.rss { render :layout => false }
end
end

View File

@@ -5,7 +5,6 @@ class CropsController < ApplicationController
# GET /crops.json
def index
@crops = Crop.paginate(:page => params[:page])
@new_crops = Crop.limit(20).order('created_at desc').all
respond_to do |format|
format.html # index.html.haml

View File

@@ -1,4 +1,5 @@
class NotificationsController < ApplicationController
include NotificationsHelper
load_and_authorize_resource
# GET /notifications
def index
@@ -14,6 +15,7 @@ class NotificationsController < ApplicationController
@notification = Notification.find(params[:id])
@notification.read = true
@notification.save
@reply_link = reply_link(@notification)
respond_to do |format|
format.html # show.html.erb
@@ -25,6 +27,7 @@ class NotificationsController < ApplicationController
def new
@notification = Notification.new
@recipient = Member.find_by_id(params[:recipient_id])
@subject = params[:subject] || ""
respond_to do |format|
format.html # new.html.erb
@@ -49,7 +52,7 @@ class NotificationsController < ApplicationController
respond_to do |format|
if @notification.save
format.html { redirect_to @recipient, notice: 'Message was successfully sent.' }
format.html { redirect_to notifications_path, notice: 'Message was successfully sent.' }
else
format.html { render action: "new" }
end

View File

@@ -3,8 +3,7 @@ class PlantingsController < ApplicationController
# GET /plantings
# GET /plantings.json
def index
@plantings = Planting.all
@recent_plantings = Planting.limit(100).order('created_at desc').all
@plantings = Planting.paginate(:page => params[:page])
respond_to do |format|
format.html # index.html.erb
@@ -85,10 +84,11 @@ class PlantingsController < ApplicationController
# DELETE /plantings/1.json
def destroy
@planting = Planting.find(params[:id])
@garden = @planting.garden
@planting.destroy
respond_to do |format|
format.html { redirect_to plantings_url }
format.html { redirect_to @garden }
format.json { head :no_content }
end
end

View File

@@ -5,7 +5,6 @@ class PostsController < ApplicationController
def index
@posts = Post.paginate(:page => params[:page])
@recent_posts = Post.limit(100).order('created_at desc').all
respond_to do |format|
format.html # index.html.haml
@@ -23,6 +22,10 @@ class PostsController < ApplicationController
respond_to do |format|
format.html # show.html.haml
format.json { render json: @post }
format.rss { render(
:layout => false,
:locals => { :post => @post }
)}
end
end

View File

@@ -26,6 +26,7 @@ class ScientificNamesController < ApplicationController
# GET /scientific_names/new.json
def new
@scientific_name = ScientificName.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
respond_to do |format|
format.html # new.html.haml
@@ -45,7 +46,7 @@ class ScientificNamesController < ApplicationController
respond_to do |format|
if @scientific_name.save
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully created.' }
format.html { redirect_to @scientific_name.crop, notice: 'Scientific name was successfully created.' }
format.json { render json: @scientific_name, status: :created, location: @scientific_name }
else
format.html { render action: "new" }
@@ -61,7 +62,7 @@ class ScientificNamesController < ApplicationController
respond_to do |format|
if @scientific_name.update_attributes(params[:scientific_name])
format.html { redirect_to @scientific_name, notice: 'Scientific name was successfully updated.' }
format.html { redirect_to @scientific_name.crop, notice: 'Scientific name was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
@@ -74,10 +75,11 @@ class ScientificNamesController < ApplicationController
# DELETE /scientific_names/1.json
def destroy
@scientific_name = ScientificName.find(params[:id])
@crop = @scientific_name.crop
@scientific_name.destroy
respond_to do |format|
format.html { redirect_to scientific_names_url }
format.html { redirect_to @crop }
format.json { head :no_content }
end
end

View File

@@ -1,7 +0,0 @@
module ApplicationHelper
def random_crop
Crop.random
end
end

View File

@@ -1,2 +0,0 @@
module CommentsHelper
end

View File

@@ -1,2 +0,0 @@
module CropsHelper
end

View File

@@ -1,2 +0,0 @@
module ForumsHelper
end

View File

@@ -1,2 +0,0 @@
module GardensHelper
end

View File

@@ -1,2 +0,0 @@
module HomeHelper
end

View File

@@ -1,9 +0,0 @@
module MembersHelper
def shorten(str, max_length)
if str.length > max_length
return str.slice(0, max_length - 3) + "..."
else
return str
end
end
end

View File

@@ -1,2 +1,16 @@
module NotificationsHelper
def reply_link(notification)
if notification.post
# comment on the post in question
new_comment_url(:post_id => notification.post.id)
else
# by default, reply link sends a PM in return
new_notification_url(
:recipient_id => notification.sender.id,
:subject => notification.subject =~ /^Re: / ?
notification.subject :
"Re: " + notification.subject
)
end
end
end

View File

@@ -1,2 +0,0 @@
module PlantingsHelper
end

View File

@@ -1,2 +0,0 @@
module PostsHelper
end

View File

@@ -1,2 +0,0 @@
module RolesHelper
end

View File

@@ -1,2 +0,0 @@
module ScientificNamesHelper
end

View File

@@ -1,8 +1,11 @@
class Notifier < ActionMailer::Base
include NotificationsHelper
default from: "Growstuff <noreply@growstuff.org>"
def notify(notification)
@notification = notification
@reply_link = reply_link(@notification)
mail(:to => @notification.recipient.email,
:subject => @notification.subject)
end

View File

@@ -3,7 +3,8 @@ class Comment < ActiveRecord::Base
belongs_to :author, :class_name => 'Member'
belongs_to :post
default_scope order("created_at asc")
default_scope order("created_at DESC")
scope :post_order, reorder("created_at ASC") # for display on post page
after_create do
recipient = self.post.author.id

View File

@@ -1,11 +1,22 @@
class Crop < ActiveRecord::Base
extend FriendlyId
friendly_id :system_name, use: :slugged
attr_accessible :en_wikipedia_url, :system_name
attr_accessible :en_wikipedia_url, :system_name, :parent_id
has_many :scientific_names
has_many :plantings
belongs_to :parent, :class_name => 'Crop'
has_many :varieties, :class_name => 'Crop', :foreign_key => 'parent_id'
default_scope order("lower(system_name) asc")
validates :en_wikipedia_url,
:format => {
:with => /^https?:\/\/en\.wikipedia\.org\/wiki/,
:message => 'is not a valid English Wikipedia URL'
}
def Crop.random
@crop = Crop.offset(rand(Crop.count)).first
return @crop

View File

@@ -7,8 +7,15 @@ class Garden < ActiveRecord::Base
has_many :plantings, :order => 'created_at DESC', :dependent => :destroy
has_many :crops, :through => :plantings
# before_create :replace_blank_name
default_scope order("lower(name) asc")
validates :name,
:format => {
:with => /\S/
}
def garden_slug
"#{owner.login_name}-#{name}".downcase.gsub(' ', '-')
end

View File

@@ -1,8 +1,3 @@
= render :partial => "posts/single", :locals => { :post => @post || @comment.post, :subject => true }
= render :partial => "posts/comments"
%h2 Your comment
= form_for @comment do |f|
- if @comment.errors.any?
#error_explanation

View File

@@ -1,3 +1,7 @@
= content_for :title, "Editing comment"
%p
Editing comment on
= link_to @comment.post.subject, @comment.post
= render 'form'

View File

@@ -1,7 +1,15 @@
= content_for :title, "Recent comments"
- @recent_comments.each do |comment|
%div.pagination
= page_entries_info @comments, :model => "comments"
= will_paginate @comments
- @comments.each do |comment|
%h2
Comment on
= link_to comment.post.subject, comment.post
= render :partial => "single", :locals => { :comment => comment }
%div.pagination
= page_entries_info @comments, :model => "comments"
= will_paginate @comments

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - Recent comments on all posts
%link= comments_url
- @comments.each do |comment|
%item
%title Comment by #{comment.author.login_name} on #{comment.post.subject}
%author= comment.author.login_name
%description
:escaped
<p>
Comment on
#{ link_to comment.post.subject, post_url(comment.post) }
</p>
:escaped_markdown
#{ strip_tags comment.body }
%pubDate= comment.created_at.to_s(:rfc822)
%link= post_url(comment.post)
%guid= post_url(comment.post)

View File

@@ -1,3 +1,9 @@
= content_for :title, "New comment"
= render :partial => "posts/single", :locals => { :post => @post || @comment.post, :subject => true }
= render :partial => "posts/comments", :locals => {:post => @post || @comment.post}
%p Your comment:
= render 'form'

View File

@@ -1,4 +1,4 @@
= form_for @crop do |f|
= form_for @crop, :html => {:class => 'form-horizontal'} do |f|
- if @crop.errors.any?
#error_explanation
%h3= "#{pluralize(@crop.errors.count, "error")} prohibited this crop from being saved:"
@@ -6,11 +6,26 @@
- @crop.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :system_name
= f.text_field :system_name
.field
= f.label :en_wikipedia_url
= f.text_field :en_wikipedia_url
.actions
= f.submit 'Save'
%p
%span.help-block
For detailed crop wrangling guidelines, please consult the
=link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
on the Growstuff wiki.
.control-group
= f.label :system_name, :class => 'control-label'
.controls
= f.text_field :system_name
%span.help-inline Name in US English; singular; capitalize proper nouns only.
.control-group
= f.label :en_wikipedia_url, 'Wikipedia URL', :class => 'control-label'
.controls
= f.text_field :en_wikipedia_url
%span.help-inline Link to this crop's page on the English language Wikipedia.
.control-group
= f.label :parent_id, 'Parent crop', :class => 'control-label'
.controls
= collection_select(:crop, :parent_id, Crop.all, :id, :system_name, {:include_blank => true})
%span.help-inline Optional. For setting up crop hierarchies for varieties etc.
.form-actions
= f.submit 'Save', :class => 'btn btn-primary'

View File

@@ -1,16 +0,0 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "#{Growstuff::Application.config.site_name} - Recently added crops"
xml.link crops_url
for crop in @new_crops
xml.item do
xml.title crop.system_name
xml.pubDate crop.created_at.to_s(:rfc822)
xml.link crop_url(crop)
xml.guid crop_url(crop)
end
end
end
end

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - Recently added crops
%link= crops_url
- @crops.each do |crop|
%item
%title= crop.system_name
%pubDate= crop.created_at.to_s(:rfc822)
%link= post_url(crop)
%guid= post_url(crop)

View File

@@ -2,6 +2,19 @@
.row
.span9
- if @crop.parent
%p
= @crop.system_name
is a variety of
= succeed "." do
= link_to @crop.parent, @crop.parent
- if @crop.varieties.count > 0
%p
Varieties of
= succeed ":" do
= @crop.system_name
!= @crop.varieties.map{ |c| link_to c, c }.join(", ")
- if @crop.plantings_count > 0
%p
Planted
@@ -17,19 +30,30 @@
%p= link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-primary'
.span3
- if can? :edit, @crop or can? :destroy, @crop
%h4 Crop wrangling
%p
You are a
= succeed "." do
%strong CROP WRANGLER
%p
- if can? :edit, @crop
= link_to 'Edit crop', edit_crop_path(@crop), { :class => 'btn btn-mini' }
- if can? :destroy, @crop
= link_to 'Delete crop', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini'
%h4 Scientific names:
%ul
- @crop.scientific_names.each do |sn|
%li= sn.scientific_name
%li
= sn.scientific_name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-mini' }
- if can? :destroy, sn
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini'
%p
- if can? :edit, @crop
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-mini' }
%h4 More information:
%ul
%li= link_to 'Wikipedia (English)', @crop.en_wikipedia_url
- if can? :edit, @crop or can? :destroy, @crop
%h4 Crop wrangling:
%p
- if can? :edit, @crop
= link_to 'Edit', edit_crop_path(@crop), { :class => 'btn btn-mini' }
- if can? :destroy, @crop
= link_to 'Delete', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini'

View File

@@ -53,6 +53,7 @@
- else
=link_to 'Connect to Twitter', '/auth/twitter'
%p
= image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo'
- if @flickr_auth
You are connected to Flickr as
= succeed "." do

View File

@@ -7,7 +7,7 @@
= label_tag :distance, "Find members within", :class => 'control-label'
= text_field_tag :distance, @distance, :class => 'input-mini'
= select_tag :units, options_for_select({"miles" => :mi, "km" => :km}, @units), :class => 'input-small'
= label_tag :location, "miles of", :class => 'control-label'
= label_tag :location, "of", :class => 'control-label'
= text_field_tag :location, @location
= submit_tag "Search", :class => 'btn btn-primary'

View File

@@ -9,7 +9,7 @@
-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'
=link_to 'Send Message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-primary'
%p
%strong Member since:
@@ -25,7 +25,7 @@
- if @flickr_auth
%p
Flickr:
= image_tag "flickr_32.png", :size => "32x32", :alt => 'Flickr logo'
=link_to @flickr_auth.name, "http://flickr.com/photos/#{@flickr_auth.uid}"
- if @member.show_email
@@ -66,7 +66,7 @@
%div
:markdown
#{g.description}
#{ strip_tags g.description }
%h3 What's planted here?
- g.featured_plantings.each do |p|

View File

@@ -1,18 +0,0 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "#{Growstuff::Application.config.site_name} - #{@member.login_name}'s recent posts"
xml.link member_url(@member)
for post in @posts
xml.item do
xml.author @member.login_name
xml.title post.subject
xml.description post.body
xml.pubDate post.created_at.to_s(:rfc822)
xml.link post_url(post)
xml.guid post_url(post)
end
end
end
end

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - #{@member.login_name}'s recent posts
%link= member_url(@member)
- @posts.each do |post|
%item
%pubDate= post.created_at.to_s(:rfc822)
%link= post_url(post)
%guid= post_url(post)
%author= @member.login_name
%title= post.subject
%description
:escaped_markdown
#{ strip_tags post.body }

View File

@@ -13,7 +13,7 @@
To:
= link_to @recipient, @recipient
= label_tag :notification, "Subject:"
= f.text_field :subject, :class => 'input-block-level'
= f.text_field :subject, :value => @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

View File

@@ -1,4 +1,4 @@
- content_for :title, "Notifications"
- content_for :title, "Inbox"
- if @notifications.length > 0
%table.table.table-striped

View File

@@ -15,4 +15,5 @@
#{ strip_tags(@notification.body) }
%p
=link_to 'Delete', @notification, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-mini'
=link_to 'Delete', @notification, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn'
=link_to 'Reply', @reply_link, :class => 'btn btn-primary'

View File

@@ -14,6 +14,8 @@
#{strip_tags @notification.body}
%p
= link_to "Reply to this message", @reply_link
%br/
= link_to "View this message in your inbox", notification_url(@notification)
%br/
= link_to "Turn off these notifications", edit_member_registration_url

View File

@@ -2,7 +2,13 @@
%p Here are the latest things planted by #{Growstuff::Application.config.site_name} members.
- @recent_plantings.each do |p|
%div.pagination
= page_entries_info @plantings, :model => "plantings"
= will_paginate @plantings
- @plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p }
%div.pagination
= page_entries_info @plantings, :model => "plantings"
= will_paginate @plantings

View File

@@ -1,18 +0,0 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "#{Growstuff::Application.config.site_name} - Recent plantings from all members"
xml.link plantings_url
for planting in @recent_plantings
xml.item do
xml.author planting.owner.login_name
xml.title planting.crop.system_name
xml.pubDate planting.created_at.to_s(:rfc822)
xml.description planting.description
xml.link planting_url(planting)
xml.guid planting_url(planting)
end
end
end
end

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - Recent plantings from all members
%link= plantings_url
- @plantings.each do |planting|
%item
%author= planting.owner.login_name
%title= planting.crop.system_name
%pubDate= planting.created_at.to_s(:rfc822)
%description
:escaped_markdown
#{ strip_tags planting.description }
%link= planting_url(planting)
%guid= planting_url(planting)

View File

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

View File

@@ -1,18 +0,0 @@
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "#{Growstuff::Application.config.site_name} - Recent posts from all members"
xml.link posts_url
for post in @recent_posts
xml.item do
xml.author post.author.login_name
xml.title post.subject
xml.description post.body
xml.pubDate post.created_at.to_s(:rfc822)
xml.link post_url(post)
xml.guid post_url(post)
end
end
end
end

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - Recent posts from all members
%link= posts_url
- @posts.each do |post|
%item
%author= post.author.login_name
%title= post.subject
%description
:escaped_markdown
#{ strip_tags post.body }
%pubDate= post.created_at.to_s(:rfc822)
%link= post_url(post)
%guid= post_url(post)

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
%rss{:version => 2.0}
%channel
%title #{Growstuff::Application.config.site_name} - Recent comments on #{@post.subject}
%link= post_url(@post)
- @post.comments.each do |comment|
%item
%title Comment by #{comment.author.login_name} on #{comment.created_at.to_s}
%author= comment.author.login_name
%description
:escaped
<p>
Comment on
#{ link_to @post.subject, post_url(@post) }
</p>
:escaped_markdown
#{ strip_tags comment.body }
%pubDate= comment.created_at.to_s(:rfc822)
%link= post_url(@post)
%guid= post_url(@post)

View File

@@ -1,4 +1,4 @@
= form_for @scientific_name do |f|
= form_for @scientific_name, :html => {:class => 'form-horizontal'} do |f|
- if @scientific_name.errors.any?
#error_explanation
%h2= "#{pluralize(@scientific_name.errors.count, "error")} prohibited this scientific_name from being saved:"
@@ -6,11 +6,19 @@
- @scientific_name.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :scientific_name
= f.text_field :scientific_name
.field
= f.label :crop_id
= f.number_field :crop_id
.actions
= f.submit 'Save'
%p
%span.help-block
For detailed crop wrangling guidelines, please consult the
=link_to "crop wrangling guide", "http://wiki.growstuff.org/index.php/Crop_wrangling"
on the Growstuff wiki.
.control-group
= f.label :crop_id, :class => 'control-label'
.controls
= collection_select(:scientific_name, :crop_id, Crop.all, :id, :system_name, :selected => @scientific_name.crop_id || @crop.id)
.control-group
= f.label :scientific_name, :class => 'control-label'
.controls
= f.text_field :scientific_name
.form-actions
= f.submit 'Save', :class => 'btn btn-primary'

View File

@@ -1,3 +1,3 @@
%h1 Editing scientific_name
- content_for :title, "Edit scientific name"
= render 'form'

View File

@@ -1,3 +1,3 @@
%h1 New scientific_name
- content_for :title, "New scientific name"
= render 'form'

View File

@@ -0,0 +1 @@
require 'haml/filters/escaped_markdown'

View File

@@ -0,0 +1,5 @@
class AddParentToCrop < ActiveRecord::Migration
def change
add_column :crops, :parent_id, :integer
end
end

View File

@@ -11,7 +11,23 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130509123711) do
ActiveRecord::Schema.define(:version => 20130518002942) do
create_table "account_types", :force => true do |t|
t.string "name", :null => false
t.boolean "is_paid"
t.boolean "is_permanent_paid"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "accounts", :force => true do |t|
t.integer "member_id", :null => false
t.integer "account_type_id"
t.datetime "paid_until"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "authentications", :force => true do |t|
t.integer "member_id", :null => false
@@ -40,6 +56,7 @@ ActiveRecord::Schema.define(:version => 20130509123711) do
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "slug"
t.integer "parent_id"
end
add_index "crops", ["slug"], :name => "index_crops_on_slug", :unique => true
@@ -120,10 +137,19 @@ ActiveRecord::Schema.define(:version => 20130509123711) do
t.datetime "updated_at", :null => false
end
create_table "order_items", :force => true do |t|
t.integer "order_id"
t.integer "product_id"
t.integer "price"
t.integer "quantity"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "orders", :force => true do |t|
t.string "member_id", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "member_id", :limit => 255, :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "completed_at"
end
@@ -132,14 +158,6 @@ ActiveRecord::Schema.define(:version => 20130509123711) do
t.integer "product_id"
end
create_table "payments", :force => true do |t|
t.integer "payer_id"
t.string "payment_type"
t.decimal "amount"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "photos", :force => true do |t|
t.integer "owner_id", :null => false
t.integer "flickr_photo_id", :null => false
@@ -181,11 +199,13 @@ ActiveRecord::Schema.define(:version => 20130509123711) do
add_index "posts", ["slug"], :name => "index_updates_on_slug", :unique => true
create_table "products", :force => true do |t|
t.string "name", :null => false
t.string "description", :null => false
t.decimal "min_price", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "name", :null => false
t.string "description", :null => false
t.integer "min_price", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "account_type_id"
t.integer "paid_months"
end
create_table "roles", :force => true do |t|

View File

@@ -0,0 +1,17 @@
require 'bluecloth'
module Haml::Filters
module EscapedMarkdown
include Haml::Filters::Base
def render(text)
bc = BlueCloth.new(text)
return Haml::Helpers.html_escape bc.to_html
end
end
# Register it as the handler for the :escaped_markdown HAML command.
# The automatic system gives us :escapedmarkdown, which is ugly.
defined['escaped_markdown'] = EscapedMarkdown
end

View File

@@ -26,6 +26,20 @@ namespace :growstuff do
end
end
task :empty_garden_names => :environment do
desc "May 2013: replace any empty garden names with Garden"
# this is inefficient as it checks every Garden, but the
# site is small and there aren't many of them, so it shouldn't matter
# for this one-off script.
Garden.all.each do |g|
if g.name.nil? or g.name =~ /^\s*$/
g.name = "Garden"
g.save
end
end
end
end
end

View File

@@ -1,5 +1,9 @@
require 'rake'
begin
require 'rspec/core/rake_task'
task(:spec).clear
RSpec::Core::RakeTask.new(:spec) do |t|
t.verbose = false
end
rescue LoadError
end

View File

@@ -14,7 +14,15 @@ describe CommentsController do
comment = Comment.create! valid_attributes
get :index, {}
assigns(:comments).should eq([comment])
assigns(:recent_comments).should eq([comment])
end
end
describe "GET RSS feed" do
it "returns an RSS feed" do
get :index, :format => "rss"
response.should be_success
response.should render_template("comments/index")
response.content_type.should eq("application/rss+xml")
end
end
@@ -63,7 +71,7 @@ describe CommentsController do
old_comment = FactoryGirl.create(:comment, :post => post)
comment = FactoryGirl.create(:comment, :post => post)
get :edit, {:id => comment.to_param}
assigns(:comments).should eq([old_comment, comment])
assigns(:comments).should eq([comment, old_comment])
end
end

View File

@@ -5,7 +5,10 @@ describe CropsController do
login_member(:crop_wrangling_member)
def valid_attributes
{ :system_name => "Tomato" }
{
:system_name => "Tomato",
:en_wikipedia_url => 'http://en.wikipedia.org/wiki/Tomato'
}
end
describe "GET index" do
@@ -13,7 +16,6 @@ describe CropsController do
crop = Crop.create! valid_attributes
get :index, {}
assigns(:crops).should eq([crop])
assigns(:new_crops).should eq([crop])
end
end

View File

@@ -7,7 +7,8 @@ describe NotificationsController do
def valid_attributes
{
"recipient_id" => subject.current_member.id,
"sender_id" => FactoryGirl.create(:member).id
"sender_id" => FactoryGirl.create(:member).id,
"subject" => 'test'
}
end
@@ -19,7 +20,8 @@ describe NotificationsController do
def valid_attributes_for_sender
{
"sender_id" => subject.current_member.id,
"recipient_id" => FactoryGirl.create(:member).id
"recipient_id" => FactoryGirl.create(:member).id,
"subject" => 'test'
}
end
@@ -42,6 +44,28 @@ describe NotificationsController do
assigns(:notification).should eq(notification)
end
it "assigns the reply link for a PM" do
notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id, :post_id => nil)
subject = "Re: " + notification.subject
get :show, {:id => notification.to_param}
assigns(:reply_link).should_not be_nil
assigns(:reply_link).should eq new_notification_url(
:recipient_id => notification.sender_id,
:subject => subject
)
end
it "assigns the reply link for a post comment" do
notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id)
get :show, {:id => notification.to_param}
assigns(:reply_link).should_not be_nil
assigns(:reply_link).should eq new_comment_url(
:post_id => notification.post.id
)
end
it "marks notifications as read" do
notification = FactoryGirl.create(:notification, :recipient_id => subject.current_member.id)
get :show, {:id => notification.to_param}
@@ -95,8 +119,8 @@ describe NotificationsController do
it "redirects to the recipient's profile" do
@recipient = FactoryGirl.create(:member)
post :create, { :notification => { :recipient_id => @recipient.id } }
response.should redirect_to(@recipient)
post :create, { :notification => { :recipient_id => @recipient.id, :subject => 'foo' } }
response.should redirect_to(notifications_path)
end
end

View File

@@ -16,7 +16,6 @@ describe PlantingsController do
planting = Planting.create! valid_attributes
get :index, {}
assigns(:plantings).should eq([planting])
assigns(:recent_plantings).should eq([planting])
end
end
@@ -161,10 +160,11 @@ describe PlantingsController do
}.to change(Planting, :count).by(-1)
end
it "redirects to the plantings list" do
it "redirects to the garden" do
planting = Planting.create! valid_attributes
garden = planting.garden
delete :destroy, {:id => planting.to_param}
response.should redirect_to(plantings_url)
response.should redirect_to(garden)
end
end

View File

@@ -13,7 +13,6 @@ describe PostsController do
post = Post.create! valid_attributes
get :index, {}
assigns(:posts).should eq([post])
assigns(:recent_posts).should eq([post])
end
end
@@ -34,6 +33,16 @@ describe PostsController do
end
end
describe "GET RSS feed for individual post" do
it "returns an RSS feed" do
post = Post.create! valid_attributes
get :show, { :format => "rss", :id => post.slug }
response.should be_success
response.should render_template("posts/show")
response.content_type.should eq("application/rss+xml")
end
end
describe "GET new" do
it "assigns a new post as @post" do
get :new, {}

View File

@@ -4,8 +4,12 @@ describe ScientificNamesController do
login_member(:crop_wrangling_member)
before(:each) do
@crop = FactoryGirl.create(:tomato)
end
def valid_attributes
{ :scientific_name => 'Solanum lycopersicum', :crop_id => 1 }
{ :scientific_name => 'Solanum lycopersicum', :crop_id => @crop.id }
end
describe "GET index" do
@@ -29,6 +33,32 @@ describe ScientificNamesController do
get :new, {}
assigns(:scientific_name).should be_a_new(ScientificName)
end
it "assigns crop if specified" do
get :new, { :crop_id => 1 }
assigns(:crop).should be_an_instance_of Crop
end
it "assigns crop if specified" do
end
end
describe "GET edit" do
it "assigns the requested scientific_name as @scientific_name" do
scientific_name = ScientificName.create! valid_attributes
get :edit, {:id => scientific_name.to_param}
assigns(:scientific_name).should eq(scientific_name)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new ScientificName" do
expect {
post :create, {:scientific_name => valid_attributes}
}.to change(ScientificName, :count).by(1)
end
end
end
describe "GET edit" do
@@ -55,7 +85,7 @@ describe ScientificNamesController do
it "redirects to the created scientific_name" do
post :create, {:scientific_name => valid_attributes}
response.should redirect_to(ScientificName.last)
response.should redirect_to(ScientificName.last.crop)
end
end
@@ -97,7 +127,7 @@ describe ScientificNamesController do
it "redirects to the scientific_name" do
scientific_name = ScientificName.create! valid_attributes
put :update, {:id => scientific_name.to_param, :scientific_name => valid_attributes}
response.should redirect_to(scientific_name)
response.should redirect_to(scientific_name.crop)
end
end
@@ -130,8 +160,9 @@ describe ScientificNamesController do
it "redirects to the scientific_names list" do
scientific_name = ScientificName.create! valid_attributes
crop = scientific_name.crop
delete :destroy, {:id => scientific_name.to_param}
response.should redirect_to(scientific_names_url)
response.should redirect_to(crop)
end
end

View File

@@ -30,6 +30,16 @@ FactoryGirl.define do
system_name "Pear"
end
# for testing varieties
factory :roma do
system_name "Roma tomato"
end
factory :popcorn do
system_name "popcorn"
end
# This should have a name that is alphabetically earlier than :uppercase
# crop to ensure that the ordering tests work.
factory :lowercasecrop do

View File

@@ -1,12 +1,17 @@
FactoryGirl.define do
factory :scientific_name do
association :crop, factory: :crop
scientific_name "Beanus Magicus"
factory :zea_mays do
association :crop, factory: :maize
scientific_name "Zea mays"
end
factory :solanum_lycopersicum do
association :crop, factory: :tomato
scientific_name "Solanum lycopersicum"
end
end
end

View File

@@ -0,0 +1,34 @@
require 'spec_helper'
describe NotificationsHelper do
describe "reply_link" do
before(:each) do
@member = FactoryGirl.create(:member)
end
it "replies to PMs with PMs" do
notification = FactoryGirl.create(:notification, :recipient_id => @member.id, :post_id => nil)
subject = "Re: " + notification.subject
link = helper.reply_link(notification)
link.should_not be_nil
link.should eq new_notification_url(
:recipient_id => notification.sender_id,
:subject => subject
)
end
it "replies to post comments with post comments" do
notification = FactoryGirl.create(:notification, :recipient_id => @member.id)
link = helper.reply_link(notification)
link.should_not be_nil
link.should eq new_comment_url(
:post_id => notification.post.id
)
end
end
end

View File

@@ -1,14 +0,0 @@
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the PlantingsHelper. For example:
#
# describe PlantingsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# helper.concat_strings("this","that").should == "this that"
# end
# end
# end
describe PlantingsHelper do
end

View File

@@ -0,0 +1,16 @@
require 'haml/filters'
require 'haml/filters/escaped_markdown'
require 'haml/helpers'
describe 'Haml::Filters::Escaped_Markdown' do
it 'is registered as the handler for :escaped_markdown' do
Haml::Filters::defined['escaped_markdown'].should ==
Haml::Filters::EscapedMarkdown
end
it 'converts Markdown to escaped HTML' do
rendered = Haml::Filters::EscapedMarkdown.render("**foo**")
rendered.should == "&lt;p&gt;&lt;strong&gt;foo&lt;/strong&gt;&lt;/p&gt;"
end
end

View File

@@ -2,40 +2,65 @@ require 'spec_helper'
describe Comment do
before(:each) do
@comment = FactoryGirl.create(:comment)
context "basic" do
before(:each) do
@comment = FactoryGirl.create(:comment)
end
it "belongs to a post" do
@comment.post.should be_an_instance_of Post
end
it "belongs to an author" do
@comment.author.should be_an_instance_of Member
end
end
it "belongs to a post" do
@comment.post.should be_an_instance_of Post
context "notifications" do
before(:each) do
@comment = FactoryGirl.create(:comment)
end
it "sends a notification when a comment is posted" do
expect {
FactoryGirl.create(:comment)
}.to change(Notification, :count).by(1)
end
it "sets the notification fields" do
@c = FactoryGirl.create(:comment)
@n = Notification.first
@n.sender.should eq @c.author
@n.recipient.should eq @c.post.author
@n.subject.should match /commented on/
@n.body.should eq @c.body
@n.post.should eq @c.post
end
it "doesn't send notifications to yourself" do
@m = FactoryGirl.create(:member)
@p = FactoryGirl.create(:post, :author => @m)
expect {
FactoryGirl.create(:comment, :post => @p, :author => @m)
}.to change(Notification, :count).by(0)
end
end
it "belongs to an author" do
@comment.author.should be_an_instance_of Member
end
context "ordering" do
before(:each) do
@m = FactoryGirl.create(:member)
@p = FactoryGirl.create(:post, :author => @m)
@c1 = FactoryGirl.create(:comment, :post => @p, :author => @m)
@c2 = FactoryGirl.create(:comment, :post => @p, :author => @m)
end
it "sends a notification when a comment is posted" do
expect {
FactoryGirl.create(:comment)
}.to change(Notification, :count).by(1)
end
it 'is in DESC order by default' do
Comment.all.should eq [@c2, @c1]
end
it "sets the notification fields" do
@c = FactoryGirl.create(:comment)
@n = Notification.first
@n.sender.should eq @c.author
@n.recipient.should eq @c.post.author
@n.subject.should match /commented on/
@n.body.should eq @c.body
@n.post.should eq @c.post
end
it "doesn't send notifications to yourself" do
@m = FactoryGirl.create(:member)
@p = FactoryGirl.create(:post, :author => @m)
expect {
FactoryGirl.create(:comment, :post => @p, :author => @m)
}.to change(Notification, :count).by(0)
it 'has a scope for ASC order for displaying on post page' do
Comment.post_order.should eq [@c1, @c2]
end
end
end

View File

@@ -27,22 +27,11 @@ describe Crop do
context 'invalid data' do
it 'should not save a crop without a system name' do
@crop = Crop.new
@crop = FactoryGirl.build(:crop, :system_name => nil)
expect { @crop.save }.to raise_error ActiveRecord::StatementInvalid
end
end
context 'random' do
before(:each) do
@crop = FactoryGirl.create(:tomato)
end
it 'should find a random crop' do
@rand_crop = Crop.random
@rand_crop.system_name.should == 'Tomato'
end
end
context 'ordering' do
it "should be sorted case-insensitively" do
uppercase = FactoryGirl.create(:uppercasecrop)
@@ -64,4 +53,20 @@ describe Crop do
FactoryGirl.create(:planting, :crop => @c)
@c.plantings_count.should eq 1
end
it 'validates en_wikipedia_url' do
@crop = FactoryGirl.build(:tomato, :en_wikipedia_url => 'this is not valid')
@crop.should_not be_valid
@crop = FactoryGirl.build(:tomato, :en_wikipedia_url => 'http://en.wikipedia.org/wiki/SomePage')
@crop.should be_valid
end
context 'varieties' do
it 'has a crop hierarchy' do
@tomato = FactoryGirl.create(:tomato)
@roma = FactoryGirl.create(:roma, :parent_id => @tomato.id)
@roma.parent.should eq @tomato
@tomato.varieties.should eq [@roma]
end
end
end

View File

@@ -14,6 +14,21 @@ describe Garden do
@garden.description.should == "This is a **totally** cool garden"
end
it "doesn't allow a nil name" do
@garden = FactoryGirl.build(:garden, :name => nil)
@garden.should_not be_valid
end
it "doesn't allow a blank name" do
@garden = FactoryGirl.build(:garden, :name => "")
@garden.should_not be_valid
end
it "doesn't allow a name with only spaces" do
@garden = FactoryGirl.build(:garden, :name => " ")
@garden.should_not be_valid
end
it "should have an owner" do
@garden.owner.should be_an_instance_of Member
end

View File

@@ -3,10 +3,17 @@ require 'spec_helper'
describe "comments/index" do
before(:each) do
controller.stub(:current_user) { nil }
assign(:recent_comments, [
FactoryGirl.create(:comment),
FactoryGirl.create(:comment, :body => 'ROFL')
])
page = 1
per_page = 2
total_entries = 2
comments = WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
pager.replace([
FactoryGirl.create(:comment),
FactoryGirl.create(:comment, :body => 'ROFL')
])
end
assign(:comments, comments)
render
end
it "renders a list of comments" do

View File

@@ -0,0 +1,32 @@
require 'spec_helper'
describe 'comments/index.rss.haml' do
before(:each) do
controller.stub(:current_user) { nil }
@author = FactoryGirl.create(:member)
@post = FactoryGirl.create(:post)
assign(:comments, [
FactoryGirl.create(:comment, :author => @author, :post => @post),
FactoryGirl.create(:comment, :author => @author, :post => @post)
])
render
end
it 'shows RSS feed title' do
rendered.should contain "Recent comments on all posts"
end
it 'shows item title' do
rendered.should contain "Comment by #{@author.login_name}"
end
it 'escapes html for link to post' do
# it's then unescaped by 'render' so we don't actually look for &lt;
rendered.should contain '<a href='
end
it 'shows content of comments' do
rendered.should contain "OMG LOL"
end
end

View File

@@ -4,9 +4,9 @@ describe "comments/new" do
before(:each) do
controller.stub(:current_user) { nil }
@post = FactoryGirl.create(:post)
@previous_comment = FactoryGirl.create(:comment, :post => @post)
assign(:comment, FactoryGirl.create(:comment, :post => @post))
assign(:comments, [@previous_comment])
@comment = FactoryGirl.create(:comment, :post => @post)
assign(:comment, @comment)
assign(:comments, [@comment])
render
end
@@ -15,7 +15,7 @@ describe "comments/new" do
end
it "shows previous comments" do
rendered.should contain @previous_comment.body
rendered.should contain @comment.body
end
it "shows the correct comment count" do

View File

@@ -0,0 +1,23 @@
require 'spec_helper'
describe 'crops/index.rss.haml' do
before(:each) do
controller.stub(:current_user) { nil }
@author = FactoryGirl.create(:member)
assign(:crops, [
FactoryGirl.create(:tomato),
FactoryGirl.create(:maize)
])
render
end
it 'shows RSS feed title' do
rendered.should contain "Recently added crops"
end
it 'shows names of crops' do
rendered.should contain "Tomato"
rendered.should contain "Maize"
end
end

View File

@@ -10,12 +10,16 @@ describe "crops/new" do
end
it "renders new crop form" do
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", :action => crops_path, :method => "post" do
assert_select "input#crop_system_name", :name => "crop[system_name]"
assert_select "input#crop_en_wikipedia_url", :name => "crop[en_wikipedia_url]"
assert_select "select#crop_parent_id", :name => "crop[parent_id]"
end
end
it "shows a link to crop wrangling guidelines" do
assert_select "a[href^=http://wiki.growstuff.org]", "crop wrangling guide"
end
end

View File

@@ -44,6 +44,25 @@ describe "crops/show" do
rendered.should contain "Springfield Community Garden"
end
context 'varieties' do
before(:each) do
@popcorn = FactoryGirl.create(:popcorn, :parent_id => @crop.id)
@ubercrop = FactoryGirl.create(:crop, :system_name => 'ubercrop')
@crop.parent_id = @ubercrop.id
@crop.save
render
end
it 'shows popcorn as a child variety' do
rendered.should contain @popcorn.system_name
end
it 'shows parent crop' do
rendered.should contain @ubercrop.system_name
end
end
context "logged in and crop wrangler" do
before(:each) do
@@ -54,7 +73,15 @@ describe "crops/show" do
end
it "links to the edit crop form" do
rendered.should contain "Edit"
assert_select "a[href=#{edit_crop_path(@crop)}]", :text => "Edit crop"
end
it "links to the add scientific name form" do
assert_select "a[href^=#{new_scientific_name_path}]", :text => "Add"
end
it "links to the edit scientific name form" do
assert_select "a[href=#{edit_scientific_name_path(@crop.scientific_names.first)}]", :text => "Edit"
end
end

View File

@@ -1,11 +1,11 @@
require 'spec_helper'
describe 'members/show.rss.builder', :type => "view" do
describe 'members/show.rss.haml', :type => "view" do
before(:each) do
@member = assign(:member, FactoryGirl.create(:member))
assign(:posts, [
FactoryGirl.build(:post, :id => 1, :author => @member),
FactoryGirl.build(:post, :id => 2, :author => @member)
FactoryGirl.build(:markdown_post, :id => 2, :author => @member)
])
render
end
@@ -18,4 +18,10 @@ describe 'members/show.rss.builder', :type => "view" do
rendered.should contain "This is some text."
end
it 'renders post bodies to HTML and XML-escapes them' do
# The variable "rendered" has been entity-replaced and tag-stripped
# The literal string output contains "&lt;strong&gt;" etc.
rendered.should contain "<strong>strong</strong>"
end
end

View File

@@ -5,7 +5,6 @@ describe "notifications/new" 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
@@ -23,6 +22,22 @@ describe "notifications/new" do
rendered.should contain @recipient.login_name
end
it "puts the recipient in a hidden field" do
render
assert_select "input#notification_recipient_id[type=hidden]", :name => "notification[recipient_id]"
end
it "fills in the subject if provided" do
assign(:subject, 'Foo')
render
assert_select "input#notification_subject", :value => "Foo"
end
it "leaves the subject empty if not provided" do
render
assert_select "input#notification_subject", :value => ""
end
it "Tells you to write your message here" do
render
rendered.should contain "Type your message here"

View File

@@ -5,6 +5,7 @@ describe "notifications/show" do
@member = FactoryGirl.create(:member)
@notification = FactoryGirl.create(:notification, :recipient => @member)
assign(:notification, @notification)
@reply_link = assign(:reply_link, new_notification_path)
controller.stub(:current_user) { @member }
render
end
@@ -18,4 +19,8 @@ describe "notifications/show" do
assert_select "a", "Delete"
end
it "includes a reply button" do
assert_select "a[href=#{@reply_link}]", "Reply"
end
end

View File

@@ -4,6 +4,8 @@ describe 'notifier/notify.html.haml', :type => "view" do
before(:each) do
@notification = FactoryGirl.create(:notification)
@reply_link = "http://example.com"
assign(:reply_link, @reply_link)
render
end
@@ -16,6 +18,10 @@ describe 'notifier/notify.html.haml', :type => "view" do
rendered.should contain @notification.post.subject
end
it 'should include a reply link' do
assert_select "a[href=#{@reply_link}]", :text => /Reply/
end
it 'should contain a link to your inbox' do
assert_select "a[href*=notifications]"
end

View File

@@ -7,18 +7,24 @@ describe "plantings/index" do
@garden = FactoryGirl.create(:garden, :owner => @member)
@tomato = FactoryGirl.create(:tomato)
@maize = FactoryGirl.create(:maize)
assign(:recent_plantings, [
FactoryGirl.create(:planting,
:garden => @garden,
:crop => @tomato
),
FactoryGirl.create(:planting,
:garden => @garden,
:crop => @maize,
:description => '',
:planted_at => Time.local(2013, 1, 13)
)
])
page = 1
per_page = 2
total_entries = 2
plantings = WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
pager.replace([
FactoryGirl.create(:planting,
:garden => @garden,
:crop => @tomato
),
FactoryGirl.create(:planting,
:garden => @garden,
:crop => @maize,
:description => '',
:planted_at => Time.local(2013, 1, 13)
)
])
end
assign(:plantings, plantings)
render
end

View File

@@ -1,9 +1,9 @@
require 'spec_helper'
describe 'plantings/index.rss.builder', :type => "view" do
describe 'plantings/index.rss.haml' do
before(:each) do
controller.stub(:current_user) { nil }
assign(:recent_plantings, [
assign(:plantings, [
FactoryGirl.create(:planting)
])
render
@@ -13,8 +13,8 @@ describe 'plantings/index.rss.builder', :type => "view" do
rendered.should contain "Recent plantings from all members"
end
it 'shows content of posts' do
rendered.should contain "This is a *really* good plant."
it 'shows formatted content of posts' do
rendered.should contain "This is a <em>really</em> good plant."
end
end

View File

@@ -1,10 +1,10 @@
require 'spec_helper'
describe 'posts/index.rss.builder', :type => "view" do
describe 'posts/index.rss.haml', :type => "view" do
before(:each) do
controller.stub(:current_user) { nil }
@author = FactoryGirl.create(:member)
assign(:recent_posts, [
assign(:posts, [
FactoryGirl.build(:post, :id => 1, :author => @author),
FactoryGirl.build(:post, :id => 2, :author => @author)
])

View File

@@ -0,0 +1,31 @@
require 'spec_helper'
describe 'posts/show.rss.haml' do
before(:each) do
controller.stub(:current_user) { nil }
@author = FactoryGirl.create(:member)
@post = FactoryGirl.create(:post)
FactoryGirl.create(:comment, :author => @author, :post => @post)
FactoryGirl.create(:comment, :author => @author, :post => @post)
assign(:post, @post)
render
end
it 'shows RSS feed title' do
rendered.should contain "Recent comments on #{@post.subject}"
end
it 'shows item title' do
rendered.should contain "Comment by #{@author.login_name}"
end
it 'escapes html for link to post' do
# it's then unescaped by 'render' so we don't actually look for &lt;
rendered.should contain '<a href='
end
it 'shows content of comments' do
rendered.should contain "OMG LOL"
end
end

View File

@@ -15,7 +15,7 @@ describe "scientific_names/edit" do
it "renders the edit scientific_name form" do
assert_select "form", :action => scientific_names_path(@scientific_name), :method => "post" do
assert_select "input#scientific_name_scientific_name", :name => "scientific_name[scientific_name]"
assert_select "input#scientific_name_crop_id", :name => "scientific_name[crop_id]"
assert_select "select#scientific_name_crop_id", :name => "scientific_name[crop_id]"
end
end
end

View File

@@ -18,7 +18,7 @@ describe "scientific_names/new" do
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "form", :action => scientific_names_path, :method => "post" do
assert_select "input#scientific_name_scientific_name", :name => "scientific_name[scientific_name]"
assert_select "input#scientific_name_crop_id", :name => "scientific_name[crop_id]"
assert_select "select#scientific_name_crop_id", :name => "scientific_name[crop_id]"
end
end