Merge branch 'dev' of https://github.com/Growstuff/growstuff into plantingreminder

This commit is contained in:
Skud
2014-11-11 19:45:51 +11:00
76 changed files with 888 additions and 792 deletions

View File

@@ -1 +1 @@
2.1.1
2.1.2

View File

@@ -4,7 +4,7 @@ language: ruby
env: GROWSTUFF_SITE_NAME="Growstuff (travis)" RAILS_SECRET_TOKEN='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
bundler_args: --without development production staging
rvm:
- 2.1.1
- 2.1.2
before_script:
- psql -c 'create database growstuff_test;' -U postgres
script:

View File

@@ -47,3 +47,4 @@ submit the change with your pull request.
- Cheri Allen / [cherimarie](https://github.com/cherimarie)
- Maki Sugita / [macckii](https:://github.com/macckii)
- Shiho Takagi / [oshiho3](https://github.com/oshiho3)
- Emma Winston / [emmawinston](https://github.com/emmawinston)

View File

@@ -1,6 +1,6 @@
source 'https://rubygems.org'
ruby "2.1.1"
ruby "2.1.2"
gem 'bundler', '>=1.1.5'
@@ -80,9 +80,6 @@ gem 'flickraw'
# To use debugger
group :development do
# Installation of the debugger gem fails on Travis CI,
# so we don't use it in the test environment
gem 'debugger'
# A debugger and irb alternative. Pry doesn't play nice
# with unicorn, so start a Webrick server when debugging
# with Pry

View File

@@ -80,7 +80,6 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.8.0)
columnize (0.8.9)
commonjs (0.2.7)
compass (0.12.7)
chunky_png (~> 1.2)
@@ -99,12 +98,6 @@ GEM
dalli (2.7.2)
database_cleaner (1.3.0)
debug_inspector (0.0.2)
debugger (1.6.8)
columnize (>= 0.3.1)
debugger-linecache (~> 1.2.0)
debugger-ruby_core_source (~> 1.3.5)
debugger-linecache (1.2.0)
debugger-ruby_core_source (1.3.5)
devise (3.2.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -339,7 +332,6 @@ DEPENDENCIES
csv_shaper
dalli
database_cleaner (~> 1.3.0)
debugger
devise (~> 3.2.0)
factory_girl_rails (~> 4.0)
figaro

View File

@@ -0,0 +1,28 @@
if (document.getElementById("membermap") !== null) {
mapbox_map_id = "<%= Rails.env == 'test' ? 0 : Growstuff::Application.config.mapbox_map_id %>";
mapbox_base_url = "https://c.tiles.mapbox.com/v3/" + mapbox_map_id + "/{z}/{x}/{y}.png";
L.Icon.Default.imagePath = '/assets'
$.getJSON(location.pathname + '.json', function(member) {
if (member.latitude && member.longitude) {
membermap = L.map('membermap').setView([member.latitude, member.longitude], 4);
L.tileLayer(mapbox_base_url, {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors under <a href="http://www.openstreetmap.org/copyright">ODbL</a> | Map imagery &copy; <a href="http://mapbox.com">Mapbox</a>',
maxZoom: 18
}).addTo(membermap);
marker = new L.Marker(new L.LatLng(member.latitude, member.longitude));
member_url = "/members/" + member.slug;
member_link = "<a href='" + member_url + "'>" + member.login_name + "</a>";
where = "<p><i>" + member.location + "</i></p>";
marker.bindPopup(member_link + where).openPopup();
marker.addTo(membermap);
}
});
}

View File

@@ -36,6 +36,17 @@ h2 {
font-size: 150%;
}
/*
#subtitle {
color: lighten(@brown, 30%);
margin-top: 0px;
padding-top: 0px;
padding-left: 1em;
font-style: italic;
font-weight: normal;
}
*/
h3 {
font-size: 120%;
}
@@ -98,6 +109,10 @@ p.stats {
height: 500px;
}
#membermap {
height: 250px;
}
.member-location {
font-size: small;
font-style: italic;

View File

@@ -0,0 +1,90 @@
class AlternateNamesController < ApplicationController
load_and_authorize_resource
# GET /alternate_names
# GET /alternate_names.json
def index
@alternate_names = AlternateName.all
respond_to do |format|
format.html # index.html.haml
format.json { render json: @alternate_names }
end
end
# GET /alternate_names/1
# GET /alternate_names/1.json
def show
@alternate_name = AlternateName.find(params[:id])
respond_to do |format|
format.html # show.html.haml
format.json { render json: @alternate_name }
end
end
# GET /alternate_names/new
# GET /alternate_names/new.json
def new
@alternate_name = AlternateName.new
@crop = Crop.find_by_id(params[:crop_id]) || Crop.new
respond_to do |format|
format.html # new.html.haml
format.json { render json: @alternate_name }
end
end
# GET /alternate_names/1/edit
def edit
@alternate_name = AlternateName.find(params[:id])
end
# POST /alternate_names
# POST /alternate_names.json
def create
params[:alternate_name][:creator_id] = current_member.id
@alternate_name = AlternateName.new(params[:alternate_name])
respond_to do |format|
if @alternate_name.save
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully created.' }
format.json { render json: @alternate_name, status: :created, location: @alternate_name }
else
format.html { render action: "new" }
format.json { render json: @alternate_name.errors, status: :unprocessable_entity }
end
end
end
# PUT /alternate_names/1
# PUT /alternate_names/1.json
def update
@alternate_name = AlternateName.find(params[:id])
respond_to do |format|
if @alternate_name.update_attributes(params[:alternate_name])
format.html { redirect_to @alternate_name.crop, notice: 'Alternate name was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @alternate_name.errors, status: :unprocessable_entity }
end
end
end
# DELETE /alternate_names/1
# DELETE /alternate_names/1.json
def destroy
@alternate_name = AlternateName.find(params[:id])
@crop = @alternate_name.crop
@alternate_name.destroy
respond_to do |format|
format.html {
redirect_to @crop, notice: 'Alternate name was successfully deleted.'
}
format.json { head :no_content }
end
end
end

View File

@@ -10,6 +10,7 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # index.html.haml
format.json { render :json => @members.to_json(:only => [:id, :login_name, :slug, :bio, :created_at, :location, :latitude, :longitude]) }
end
end
@@ -25,6 +26,7 @@ class MembersController < ApplicationController
respond_to do |format|
format.html # show.html.haml
format.json { render :json => @member.to_json(:only => [:id, :login_name, :bio, :created_at, :slug, :location, :latitude, :longitude]) }
format.rss { render(
:layout => false,
:locals => { :member => @member }

View File

@@ -9,11 +9,11 @@ class PlantingsController < ApplicationController
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@plantings = @owner.plantings.includes(:owner, :crop, :garden)
@plantings = @owner.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
elsif @crop
@plantings = @crop.plantings.includes(:owner, :crop, :garden)
@plantings = @crop.plantings.includes(:owner, :crop, :garden).paginate(:page => params[:page])
else
@plantings = Planting.includes(:owner, :crop, :garden)
@plantings = Planting.includes(:owner, :crop, :garden).paginate(:page => params[:page])
end
respond_to do |format|

View File

@@ -83,7 +83,9 @@ class ScientificNamesController < ApplicationController
@scientific_name.destroy
respond_to do |format|
format.html { redirect_to @crop }
format.html {
redirect_to @crop, notice: 'Scientific name was successfully deleted.'
}
format.json { head :no_content }
end
end

View File

@@ -7,8 +7,11 @@ class SeedsController < ApplicationController
# GET /seeds.json
def index
@owner = Member.find_by_slug(params[:owner])
@crop = Crop.find_by_slug(params[:crop])
if @owner
@seeds = @owner.seeds.includes(:owner, :crop).paginate(:page => params[:page])
elsif @crop
@seeds = @crop.seeds.includes(:owner, :crop).paginate(:page => params[:page])
else
@seeds = Seed.includes(:owner, :crop).paginate(:page => params[:page])
end

View File

@@ -40,6 +40,7 @@ class Ability
can :wrangle, Crop
can :manage, Crop
can :manage, ScientificName
can :manage, AlternateName
end
# can create & destroy their own authentications against other sites.

View File

@@ -0,0 +1,5 @@
class AlternateName < ActiveRecord::Base
attr_accessible :crop_id, :name, :creator_id
belongs_to :crop
belongs_to :creator, :class_name => 'Member'
end

View File

@@ -8,6 +8,7 @@ class Crop < ActiveRecord::Base
:allow_destroy => true,
:reject_if => :all_blank
has_many :alternate_names
has_many :plantings
has_many :photos, :through => :plantings
has_many :seeds

View File

@@ -14,7 +14,7 @@ class Photo < ActiveRecord::Base
# remove photos that aren't used by anything
def destroy_if_unused
unless plantings.size > 0 and harvests.size > 0
unless plantings.size > 0 or harvests.size > 0
self.destroy
end
end

View File

@@ -1,4 +1,4 @@
%h1 Editing account_type
-content_for :title, "Editing account type"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing account_types
- content_for :title, "Listing account types"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New account_type
- content_for :title, "New account type"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Editing account
- content_for :title, "Editing account"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing accounts
- content_for :title, "Listing accounts"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New account
- content_for :title, "New account"
= render 'form'

View File

@@ -0,0 +1,25 @@
= form_for @alternate_name, :html => {:class => 'form-horizontal', :role => "form"} do |f|
- if @alternate_name.errors.any?
#error_explanation
%h2= "#{pluralize(@alternate_name.errors.count, "error")} prohibited this alternate_name from being saved:"
%ul
- @alternate_name.errors.full_messages.each do |msg|
%li= msg
%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.
.form-group
= f.label :crop_id, :class => 'control-label col-md-2'
.col-md-8
= collection_select(:alternate_name, :crop_id, Crop.all, :id, :name, { :selected => @alternate_name.crop_id || @crop.id }, :class => 'form-control')
.form-group
= f.label :name, :class => 'control-label col-md-2'
.col-md-8
= f.text_field :name, :class => 'form-control'
.form-group
.form-actions.col-md-offset-2.col-md-8
= f.submit 'Save', :class => 'btn btn-primary'

View File

@@ -0,0 +1,9 @@
- content_for :title, "Edit alternate name"
%p
Added by
= @alternate_name.creator
= distance_of_time_in_words(@alternate_name.created_at, Time.zone.now)
ago.
= render 'form'

View File

@@ -0,0 +1,23 @@
- content_for :title, "Listing alternate names"
- if can? :create, AlternateName
%p= link_to 'New alternate name', new_alternate_name_path, :class => 'btn btn-primary'
%table
%tr
%th Alternate name
%th Crop
%th
%th
- @alternate_names.each do |alternate_name|
%tr
%td= link_to alternate_name.name, alternate_name
%td= alternate_name.crop
%td= link_to 'Show', alternate_name
%td
- if can? :edit, alternate_name
= link_to 'Edit', edit_alternate_name_path(alternate_name), :class => 'btn btn-default btn-xs'
%td
- if can? :destroy, alternate_name
= link_to 'Delete', alternate_name, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'

View File

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

View File

@@ -0,0 +1,13 @@
%p#notice= notice
%p
%b Alternate name:
= @alternate_name.name
%p
%b Crop:
= link_to @alternate_name.crop, @alternate_name.crop
- if can? :edit, @alternate_name
= link_to 'Edit', edit_alternate_name_path(@alternate_name), :class => 'btn btn-default btn-xs'
\|
= link_to 'Back', alternate_names_path

View File

@@ -1,4 +1,4 @@
%h1 Linked accounts on other sites
- content_for :title, "Linked accounts on other sites"
- if @authentications
- unless @authentications.empty?

View File

@@ -8,7 +8,9 @@
%li
= link_to "#{seed.owner} will trade #{seed.tradable_to}.", seed_path(seed)
= render :partial => 'members/location', :locals => { :member => seed.owner }
%p
= link_to "View all #{crop.name} seeds", seeds_by_crop_path(crop)
- if current_member
= link_to "List your seeds to trade.", new_seed_path()
= link_to "List achiote seeds to trade", new_seed_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'list your seeds to trade' }

View File

@@ -11,11 +11,11 @@
%small
= distance_of_time_in_words(harvest.created_at, Time.zone.now)
ago.
%p.col-md-offset-1
= link_to "See all #{crop.name} harvests", harvests_by_crop_path(crop)
%p
= link_to "View all #{crop.name} harvests", harvests_by_crop_path(crop)
- if current_member
%p.col-md-offset-1
= link_to "Track your #{crop.name} harvests.", new_harvest_path(:crop_id => crop.id)
%p
= link_to "Harvest #{crop.name}", new_harvest_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} harvests" }

View File

@@ -11,11 +11,11 @@
%small
= distance_of_time_in_words(planting.created_at, Time.zone.now)
ago.
%p.col-md-offset-1
= link_to "See all #{crop.name} plantings", plantings_by_crop_path(crop)
%p
= link_to "View all #{crop.name} plantings", plantings_by_crop_path(crop)
- if current_member
%p.col-md-offset-1
= link_to "Track your #{crop.name} plantings.", new_planting_path(:crop_id => crop.id)
%p
= link_to "Plant #{crop.name}", new_planting_path(:crop_id => crop.id)
- else
= render :partial => 'shared/signin_signup', :locals => { :to => "track your #{crop.name} plantings" }

View File

@@ -1,18 +1,18 @@
- content_for :title, @crop.name
- content_for :subtitle, @crop.default_scientific_name
- content_for :buttonbar do
- if can? :create, Planting
= link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-default'
- if can? :create, Harvest
= link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-default'
- if can? :create, Seed
= link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-default'
.row
.col-md-9
%p
- if can? :create, Planting
= link_to "Plant this", new_planting_path(:crop_id => @crop.id), :class => 'btn btn-primary'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'plant this crop' }
- if can? :create, Harvest
= link_to "Harvest this", new_harvest_path(:crop_id => @crop.id), :class => 'btn btn-primary'
- if can? :create, Seed
= link_to 'Add seeds to stash', new_seed_path(:params => { :crop_id => @crop.id }), :class => 'btn btn-primary'
= render :partial => 'photos', :locals => { :crop => @crop }
@@ -59,18 +59,33 @@
- if can? :destroy, @crop
= link_to 'Delete crop', @crop, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%h4 Scientific names
%ul
- @crop.scientific_names.each do |sn|
%li
= sn.scientific_name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, sn
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
.scientific_names
%h4 Scientific names
%ul
- @crop.scientific_names.each do |sn|
%li
= sn.scientific_name
- if can? :edit, sn
= link_to 'Edit', edit_scientific_name_path(sn), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, sn
= link_to 'Delete', sn, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_scientific_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
.alternate_names
%h4 Alternate names
%ul
- @crop.alternate_names.each do |an|
%li
= an.name
- if can? :edit, an
= link_to 'Edit', edit_alternate_name_path(an), { :class => 'btn btn-default btn-xs' }
- if can? :destroy, an
= link_to 'Delete', an, method: :delete, data: { confirm: 'Are you sure?' }, :class => 'btn btn-default btn-xs'
%p
- if can? :edit, @crop
= link_to 'Add', new_alternate_name_path( :crop_id => @crop.id ), { :class => 'btn btn-default btn-xs' }
= render :partial => 'varieties', :locals => { :crop => @crop }

View File

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

View File

@@ -10,11 +10,11 @@
%p
- if @owner == current_member
= link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary'
= link_to "View everyone's harvests", harvests_path, :class => 'btn'
= link_to "View everyone's harvests", harvests_path, :class => 'btn btn-default'
- else # everyone's harvests
= link_to 'Add harvest', new_harvest_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your harvests', harvests_by_owner_path(:owner => current_member.slug), :class => 'btn'
= link_to 'View your harvests', harvests_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'track your harvests' }

View File

@@ -9,7 +9,15 @@
.row
.col-md-12
- if content_for?(:title)
%h1= yield(:title)
%h1#title
= yield(:title)
- if content_for?(:subtitle)
%small= yield(:subtitle)
- if content_for?(:buttonbar)
%p
.btn-group
= yield(:buttonbar)
- if notice
.alert.alert-success
= notice

View File

@@ -0,0 +1,12 @@
%h3 Account details
%p
%strong Member since:
= member.created_at.to_s(:date)
%p
%strong Account type:
= member.account_type
account

View File

@@ -5,5 +5,5 @@
:size => defined?(size) ? size : 150, |
:default => :identicon }), |
:alt => '', |
:class => 'img-rounded img-responsive' ), |
:class => 'img-rounded img-responsive avatar' ), |
member_path(member)

View File

@@ -0,0 +1,9 @@
%h2 All about #{member.login_name}
- if member.bio.blank?
- if can? :edit, member
= link_to "Add a bio to complete your profile."
- else
#{member.login_name} hasn't written a bio yet.
- else
:growstuff_markdown
#{ strip_tags member.bio }

View File

@@ -0,0 +1,17 @@
- if twitter_auth || flickr_auth || member.show_email
%h4 Contact
- if twitter_auth
%p
= image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo'
=link_to twitter_auth.name, "http://twitter.com/#{twitter_auth.name}"
- if flickr_auth
%p
= 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
%p
Email:
= mail_to member.email

View File

@@ -0,0 +1,27 @@
%h2 #{member.login_name}'s gardens
.tabbable
%ul.nav.nav-tabs
- first_garden = true
- member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == member
%li= link_to 'New Garden', new_garden_path
.tab-content
- first_garden = true
- member.gardens.each do |g|
%div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"}
- first_garden = false
%div
:growstuff_markdown
#{ strip_tags g.description }
%h3 What's planted here?
- g.featured_plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true }
%p
= link_to "More about this garden...", url_for(g)

View File

@@ -0,0 +1,5 @@
- if member.latitude and member.longitude
%div#membermap
%p
See other members near
= link_to member.location, place_path(member.location)

View File

@@ -0,0 +1,23 @@
%h3 Activity
%ul
%li
- if member.plantings.count > 0
= link_to pluralize(member.plantings.count, "planting"), plantings_by_owner_path(:owner => member)
- else
0 plantings
%li
- if member.harvests.count > 0
= link_to pluralize(member.harvests.count, "harvest"), harvests_by_owner_path(:owner => member)
- else
0 harvests
%li
- if member.seeds.count > 0
= link_to pluralize(member.seeds.count, "seeds"), seeds_by_owner_path(:owner => member)
- else
0 seeds
%li
- if member.posts.count > 0
= link_to pluralize(member.posts.count, "post"), posts_by_author_path(:author => member)
- else
0 posts

View File

@@ -1,105 +1,26 @@
- content_for :title, "#{@member.login_name}"
- content_for :member_rss_login_name, "#{@member.login_name}"
- content_for :member_rss_slug, "#{@member.slug}"
- content_for :title, @member.login_name
- content_for :subtitle, @member.location
- content_for :buttonbar do
- if can? :update, @member
= link_to 'Edit profile', edit_member_registration_path, :class => 'btn btn-default'
- if @member == current_member && !@member.is_paid?
= link_to "Upgrade account", shop_path, :class => 'btn btn-default'
-if can? :create, Notification and current_member != @member
=link_to 'Send message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-default'
- content_for :member_rss_login_name, @member.login_name
- content_for :member_rss_slug, @member.slug
.row
.col-md-3
= render :partial => "members/avatar", :locals => { :member => @member }
-if can? :create, Notification and current_member != @member
%p
%br/
=link_to 'Send Message', new_notification_path(:recipient_id => @member.id), :class => 'btn btn-primary'
%p
%strong Member since:
= @member.created_at.to_s(:date)
%p
%strong Account type:
= @member.account_type
account
- if @member == current_member && !@member.is_paid?
= link_to "Upgrade", shop_path, :class => 'btn btn-primary btn-xs'
- if @twitter_auth || @flickr_auth || @member.show_email
%h4 Contact
- if @twitter_auth
%p
= image_tag "twitter_32.png", :size => "32x32", :alt => 'Twitter logo'
=link_to @twitter_auth.name, "http://twitter.com/#{@twitter_auth.name}"
- if @flickr_auth
%p
= 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
%p
Email:
= mail_to @member.email
- if @member.location.to_s != ''
%h4 Location
%p
= link_to image_tag("http://maps.google.com/maps/api/staticmap?size=200x200&maptype=roadmap&sensor=false&markers=color:green|label:A|#{@member.latitude},#{@member.longitude}&zoom=12", :alt => "Map showing #{@member.location}", :width => 200, :height => 200 ), place_path(@member.location)
%br/
= link_to @member.location, place_path(@member.location)
.col-md-9
%p
- if can? :update, @member
%p
= link_to 'Edit your profile', "edit", :class => 'btn btn-primary'
- if @member.bio
%h2 Bio
:growstuff_markdown
#{ strip_tags @member.bio }
%h2 Gardens
.tabbable
%ul.nav.nav-tabs
- first_garden = true
- @member.gardens.each do |g|
%li{:class => first_garden ? 'active' : '' }
- first_garden = false
= link_to g.name, "#garden#{g.id}", 'data-toggle' => 'tab'
- if current_member == @member
%li= link_to 'New Garden', '#garden_new', 'data-toggle' => 'tab'
.tab-content
- first_garden = true
- @member.gardens.each do |g|
%div{:class => ['tab-pane', first_garden ? 'active' : ''], :id => "garden#{g.id}"}
- first_garden = false
= render :partial => "map", :locals => { :member => @member }
= render :partial => "bio", :locals => { :member => @member }
= render :partial => "gardens", :locals => { :member => @member }
%div
:growstuff_markdown
#{ strip_tags g.description }
%h3 What's planted here?
- g.featured_plantings.each do |p|
= render :partial => "plantings/thumbnail", :locals => { :planting => p, :hide_description => true }
%p
= link_to "More about this garden...", url_for(g)
- if current_member == @member
%div{:class => 'tab-pane', :id => "garden_new"}
%h3 Create a new garden
= render 'gardens/form'
%h3 Seeds
%p
- if @member.seeds.count > 0
= link_to pluralize(@member.seeds.count, "variety"), seeds_path(:owner_id => @member.id)
- else
No seeds yet.
%h3 Posts
- if @member.posts.count > 0
- @member.posts.each do |post|
= render :partial => "posts/single", :locals => { :post => post, :subject => true }
- else
%p Nothing posted yet.
.col-md-3
= render :partial => "avatar", :locals => { :member => @member }
= render :partial => "account", :locals => { :member => @member }
= render :partial => "contact", :locals => { :member => @member, :twitter_auth => @twitter_auth, :flickr_auth => @flickr_auth }
= render :partial => "stats", :locals => { :member => @member }

View File

@@ -13,7 +13,7 @@
- if @sets and @sets.length > 0
%p
= form_tag(new_photo_path, :method => :get, :class => 'form-inline') do
= label_tag :set, "Choose a photo set:", :class => 'control-label'
= label_tag :set, "Choose a photo album:", :class => 'control-label'
= select_tag :set, options_for_select(@sets, @current_set), :class => 'input-large'
= hidden_field_tag :type, @type
= hidden_field_tag :id, @id
@@ -36,4 +36,3 @@
You must
=link_to "connect your account to Flickr", '/auth/flickr'
to add photos.

View File

@@ -1,4 +1,4 @@
%h1 Editing plant_part
- content_for :title, "Editing plant part"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 New plant_part
- content_for :title, "New plant part"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Editing product
- content_for :title, "Editing product"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing products
- content_for :title, "Listing products"
%table
%tr

View File

@@ -1,4 +1,4 @@
%h1 New product
- content_for :title, "New product"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Editing role
- content_for :title, "Editing role"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing roles
- content_for :title, "Listing roles"
- if can? :create, Role
%p= link_to 'New Role', new_role_path, :class => 'btn btn-primary'

View File

@@ -1,4 +1,4 @@
%h1 New role
- content_for :title, "New role"
= render 'form'

View File

@@ -1,4 +1,4 @@
%h1 Listing scientific_names
- content_for :title, "Listing scientific names"
- if can? :create, ScientificName
%p= link_to 'New Scientific name', new_scientific_name_path, :class => 'btn btn-primary'

View File

@@ -5,7 +5,7 @@
= @scientific_name.scientific_name
%p
%b Crop:
= @scientific_name.crop_id
= link_to @scientific_name.crop, @scientific_name.crop
= link_to 'Edit', edit_scientific_name_path(@scientific_name), :class => 'btn btn-default btn-xs'
\|

View File

@@ -1,4 +1,4 @@
- content_for :title, @owner ? "#{@owner}'s seeds" : "Everyone's seeds"
- content_for :title, @owner ? "#{@owner}'s seeds" : @crop ? "Everyone's #{@crop.name} seeds" : "Everyone's seeds"
%p
#{ENV['GROWSTUFF_SITE_NAME']} helps you track your seed
@@ -10,11 +10,11 @@
%p
- if @owner == current_member
= link_to 'Add seeds', new_seed_path, :class => 'btn btn-primary'
= link_to "View everyone's seeds", seeds_path, :class => 'btn'
= link_to "View everyone's seeds", seeds_path, :class => 'btn btn-default'
- else # everyone's seeds
= link_to 'Add seeds', new_seed_path, :class => 'btn btn-primary'
- if current_member
= link_to 'View your seeds', seeds_by_owner_path(:owner => current_member.slug), :class => 'btn'
= link_to 'View your seeds', seeds_by_owner_path(:owner => current_member.slug), :class => 'btn btn-default'
- else
= render :partial => 'shared/signin_signup', :locals => { :to => 'add seeds to your stash' }

View File

@@ -31,8 +31,12 @@ module Growstuff
config.active_record.default_timezone = :local
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}')]
I18n.default_locale = :en
# rails will fallback to config.i18n.default_locale translation
config.i18n.fallbacks = true
# rails will fallback to en, no matter what is set as config.i18n.default_locale
config.i18n.fallbacks = [:en]
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"

View File

@@ -86,3 +86,7 @@ Geocoder::Lookup::Test.add_stub(
# Unknown location
Geocoder::Lookup::Test.add_stub( "Tatooine", [])
Capybara.configure do |config|
config.always_include_port = true
end

View File

@@ -1,4 +0,0 @@
I18n.load_path += Dir[Rails.root.join('config', 'locales', '*.{rb,yml}')]
I18n.default_locale = :en

View File

@@ -2,77 +2,4 @@ ja:
home:
blurb:
intro: "%{site_name}はガーデナーのコミュニティです。"
perks: "翻訳中"
sign_up: "翻訳中"
already_html: "翻訳中"
sign_in_linktext: "翻訳中"
crops:
our_crops: "翻訳中"
recently_planted: "翻訳中"
recently_added: "翻訳中"
view_all: "翻訳中"
discuss:
discussion: "翻訳中"
forums: "翻訳中"
view_all: "翻訳中"
keep_in_touch:
keep_in_touch: "翻訳中"
twitter_html: "翻訳中"
twitter_linktext: "翻訳中"
blog_html: "翻訳中"
blog_linktext: "翻訳中"
newsletter_html: "翻訳中"
newsletter_linktext: "翻訳中"
members:
title: "翻訳中"
view_all: "翻訳中"
open:
open_source_title: "翻訳中"
open_source_body_html: "翻訳中"
why_linktext: "翻訳中"
github_linktext: "翻訳中"
open_data_title: "翻訳中"
open_data_body_html: "翻訳中"
creative_commons_linktext: "翻訳中"
wiki_linktext: "翻訳中"
api_docs_linktext: "翻訳中"
get_involved_title: "翻訳中"
get_involved_body_html: "翻訳中"
talk_linktext: "翻訳中"
wiki_linktext: "翻訳中"
support_title: "翻訳中"
support_body_html: "翻訳中"
ad_free_linktext: "翻訳中"
seeds:
title: "翻訳中"
owner: "翻訳中"
crop: "翻訳中"
description: "翻訳中"
trade_to: "翻訳中"
from: "翻訳中"
unspecified: "翻訳中"
details: "翻訳中"
view_all: "翻訳中"
stats:
message_html: "翻訳中"
member_linktext: "翻訳中"
number_crops_linktext: "翻訳中"
number_plantings_linktext: "翻訳中"
number_gardens_linktext: "翻訳中"
index:
welcome: "翻訳中"
plant: "翻訳中"
harvest: "翻訳中"
add_seeds: "翻訳中"
post: "翻訳中"
edit_profile: "翻訳中"

View File

@@ -19,6 +19,7 @@ Growstuff::Application.routes.draw do
resources :seeds
match '/seeds/owner/:owner' => 'seeds#index', :as => 'seeds_by_owner'
match '/seeds/crop/:crop' => 'seeds#index', :as => 'seeds_by_crop'
resources :harvests
match '/harvests/owner/:owner' => 'harvests#index', :as => 'harvests_by_owner'
@@ -28,6 +29,7 @@ Growstuff::Application.routes.draw do
match '/posts/author/:author' => 'posts#index', :as => 'posts_by_author'
resources :scientific_names
resources :alternate_names
match 'crops/wrangle' => 'crops#wrangle', :as => 'wrangle_crops'
match 'crops/hierarchy' => 'crops#hierarchy', :as => 'crops_hierarchy'

View File

@@ -0,0 +1,11 @@
class CreateAlternateNames < ActiveRecord::Migration
def change
create_table :alternate_names do |t|
t.string :name, :null => false
t.integer :crop_id, :null => false
t.integer :creator_id, :null => false
t.timestamps
end
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 => 20141002022459) do
ActiveRecord::Schema.define(:version => 20141018111015) do
create_table "account_types", :force => true do |t|
t.string "name", :null => false
@@ -29,6 +29,14 @@ ActiveRecord::Schema.define(:version => 20141002022459) do
t.datetime "updated_at", :null => false
end
create_table "alternate_names", :force => true do |t|
t.string "name", :null => false
t.integer "crop_id", :null => false
t.integer "creator_id", :null => false
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
t.string "provider", :null => false

View File

@@ -1,41 +1,41 @@
adoration tomato,,https://en.wikipedia.org/wiki/Adoration_%28Tomato%29,tomato,
alicante tomato,,https://en.wikipedia.org/wiki/Alicante_%28tomato%29,tomato,
Amish paste tomato,,http://en.wikipedia.org/wiki/Amish_Paste,tomato,
azoychka tomato,,https://en.wikipedia.org/wiki/Azoychka%28Tomato%29,tomato,
beefsteak tomato,,https://en.wikipedia.org/wiki/Beefsteak_(tomato),tomato,
better boy tomato,,https://en.wikipedia.org/wiki/Better_Boy,tomato,
big rainbow tomato,,https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato),tomato,
Blaby special tomato,,https://en.wikipedia.org/wiki/Blaby_Special_(Tomato),tomato,
black krim tomato,,https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29,tomato,
brandywine tomato,,https://en.wikipedia.org/wiki/Brandywine_(tomato),tomato,
campari tomato,,https://en.wikipedia.org/wiki/Campari_tomato,tomato,
Cherokee purple tomato,,https://en.wikipedia.org/wiki/Cherokee_purple,tomato,
adoration tomato,,https://en.wikipedia.org/wiki/Adoration_%28Tomato%29,tomato
alicante tomato,,https://en.wikipedia.org/wiki/Alicante_%28tomato%29,tomato
Amish paste tomato,,http://en.wikipedia.org/wiki/Amish_Paste,tomato
Aunt Ruby's German green tomato,,http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green,tomato
azoychka tomato,,https://en.wikipedia.org/wiki/Azoychka%28Tomato%29,tomato
beefsteak tomato,,https://en.wikipedia.org/wiki/Beefsteak_(tomato),tomato
better boy tomato,,https://en.wikipedia.org/wiki/Better_Boy,tomato
big rainbow tomato,,https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato),tomato
Blaby special tomato,,https://en.wikipedia.org/wiki/Blaby_Special_(Tomato),tomato
black krim tomato,,https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29,tomato
brandywine tomato,,https://en.wikipedia.org/wiki/Brandywine_(tomato),tomato
campari tomato,,https://en.wikipedia.org/wiki/Campari_tomato,tomato
celebrity tomato,,http://en.wikipedia.org/wiki/Celebrity_(tomato),tomato
Cherokee purple tomato,,https://en.wikipedia.org/wiki/Cherokee_purple,tomato
cherry tomato,Solanum lycopersicum var. cerasiforme,http://en.wikipedia.org/wiki/Cherry_tomato,tomato
currant tomato,solanum pimpinellifolium,https://en.wikipedia.org/wiki/Solanum_pimpinellifolium,
early girl tomato,,https://en.wikipedia.org/wiki/Early_Girl,tomato,
Fourth of July tomato,,https://en.wikipedia.org/wiki/Fourth_of_July_(tomato_variety),tomato,
garden peach tomato,,https://en.wikipedia.org/wiki/Garden_peach_tomato,tomato,
green zebra tomato,,https://en.wikipedia.org/wiki/Green_Zebra,tomato,
hillbilly tomato,,http://en.wikipedia.org/wiki/Hillbilly_(tomato),tomato,
jubilee tomato,,http://en.wikipedia.org/wiki/Jubilee_(tomato),tomato,
lillian's yellow tomato,,http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato),tomato,
Matt's wild cherry tomato,,http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry,tomato,
mortgage lifter tomato,,http://en.wikipedia.org/wiki/Mortgage_Lifter,tomato,
Mr. Stripey tomato,,http://en.wikipedia.org/wiki/Mr._Stripey,tomato,
Roma tomato,,http://en.wikipedia.org/wiki/Roma_tomato,tomato,
San Marzano tomato,,http://en.wikipedia.org/wiki/San_Marzano_tomato,tomato,
Santorini tomato,,http://en.wikipedia.org/wiki/Santorini_(tomato),tomato,
stupice tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,tomato,
tigerella tomato,,http://en.wikipedia.org/wiki/Tigerella,tomato,
tomaccio tomato,,http://en.wikipedia.org/wiki/Tomaccio_(tomato),tomato,
early girl tomato,,https://en.wikipedia.org/wiki/Early_Girl,tomato
Fourth of July tomato,,https://en.wikipedia.org/wiki/Fourth_of_July_(tomato_variety),tomato
garden peach tomato,,https://en.wikipedia.org/wiki/Garden_peach_tomato,tomato
grape tomato,,http://en.wikipedia.org/wiki/Grape_tomato,tomato
green zebra tomato,,https://en.wikipedia.org/wiki/Green_Zebra,tomato
Hanover tomato,,http://en.wikipedia.org/wiki/Hanover_tomato,tomato
hillbilly tomato,,http://en.wikipedia.org/wiki/Hillbilly_(tomato),tomato
jubilee tomato,,http://en.wikipedia.org/wiki/Jubilee_(tomato),tomato
lillian's yellow tomato,,http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato),tomato
marglobe tomato,,http://en.wikipedia.org/wiki/Marglobe,tomato
Matt's wild cherry tomato,,http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry,cherry tomato
mortgage lifter tomato,,http://en.wikipedia.org/wiki/Mortgage_Lifter,tomato
Mr. Stripey tomato,,http://en.wikipedia.org/wiki/Mr._Stripey,tomato
pear tomato,,http://en.wikipedia.org/wiki/Pear_tomato,tomato
Roma tomato,,http://en.wikipedia.org/wiki/Roma_tomato,tomato
San Marzano tomato,,http://en.wikipedia.org/wiki/San_Marzano_tomato,tomato
Santorini tomato,,http://en.wikipedia.org/wiki/Santorini_(tomato),cherry tomato
stupice tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,tomato
super sweet 100 tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,cherry tomato
three sisters tomato,,http://en.wikipedia.org/wiki/Three_Sisters_(tomato),tomato
tigerella tomato,,http://en.wikipedia.org/wiki/Tigerella,tomato
tomaccio tomato,,http://en.wikipedia.org/wiki/Tomaccio_(tomato),cherry tomato
tomberry,,http://en.wikipedia.org/wiki/Tomberry,tomato
traveller tomato,,http://en.wikipedia.org/wiki/Traveller_(tomato),tomato
three sisters tomato,,http://en.wikipedia.org/wiki/Three_Sisters_(tomato),tomato,
Hanover tomato,,http://en.wikipedia.org/wiki/Hanover_tomato,tomato,
celebrity tomato,,http://en.wikipedia.org/wiki/Celebrity_(tomato),tomato,
tomberry,,http://en.wikipedia.org/wiki/Tomberry,tomato,
super sweet 100 tomato,,http://en.wikipedia.org/wiki/Super_Sweet_100,tomato,
marglobe tomato,,http://en.wikipedia.org/wiki/Marglobe,tomato,
grape tomato,,http://en.wikipedia.org/wiki/Grape_tomato,tomato,
cherry tomato,,http://en.wikipedia.org/wiki/Cherry_tomato,tomato,
Aunt Ruby's German green tomato,,http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green,tomato,
white queen tomato,,http://en.wikipedia.org/wiki/White_Queen_tomato,tomato,
pear tomato,,http://en.wikipedia.org/wiki/Pear_tomato,tomato,
white queen tomato,,http://en.wikipedia.org/wiki/White_Queen_tomato,tomato
1 adoration tomato https://en.wikipedia.org/wiki/Adoration_%28Tomato%29 tomato
2 alicante tomato https://en.wikipedia.org/wiki/Alicante_%28tomato%29 tomato
3 Amish paste tomato http://en.wikipedia.org/wiki/Amish_Paste tomato
4 azoychka tomato Aunt Ruby's German green tomato https://en.wikipedia.org/wiki/Azoychka%28Tomato%29 http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green tomato
5 beefsteak tomato azoychka tomato https://en.wikipedia.org/wiki/Beefsteak_(tomato) https://en.wikipedia.org/wiki/Azoychka%28Tomato%29 tomato
6 better boy tomato beefsteak tomato https://en.wikipedia.org/wiki/Better_Boy https://en.wikipedia.org/wiki/Beefsteak_(tomato) tomato
7 big rainbow tomato better boy tomato https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato) https://en.wikipedia.org/wiki/Better_Boy tomato
8 Blaby special tomato big rainbow tomato https://en.wikipedia.org/wiki/Blaby_Special_(Tomato) https://en.wikipedia.org/wiki/Big_Rainbow_(Tomato) tomato
9 black krim tomato Blaby special tomato https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29 https://en.wikipedia.org/wiki/Blaby_Special_(Tomato) tomato
10 brandywine tomato black krim tomato https://en.wikipedia.org/wiki/Brandywine_(tomato) https://en.wikipedia.org/wiki/Black_Krim_%28tomato%29 tomato
11 campari tomato brandywine tomato https://en.wikipedia.org/wiki/Campari_tomato https://en.wikipedia.org/wiki/Brandywine_(tomato) tomato
12 Cherokee purple tomato campari tomato https://en.wikipedia.org/wiki/Cherokee_purple https://en.wikipedia.org/wiki/Campari_tomato tomato
13 celebrity tomato http://en.wikipedia.org/wiki/Celebrity_(tomato) tomato
14 Cherokee purple tomato https://en.wikipedia.org/wiki/Cherokee_purple tomato
15 cherry tomato Solanum lycopersicum var. cerasiforme http://en.wikipedia.org/wiki/Cherry_tomato tomato
16 currant tomato solanum pimpinellifolium https://en.wikipedia.org/wiki/Solanum_pimpinellifolium
17 early girl tomato https://en.wikipedia.org/wiki/Early_Girl tomato
18 Fourth of July tomato https://en.wikipedia.org/wiki/Fourth_of_July_(tomato_variety) tomato
19 garden peach tomato https://en.wikipedia.org/wiki/Garden_peach_tomato tomato
20 green zebra tomato grape tomato https://en.wikipedia.org/wiki/Green_Zebra http://en.wikipedia.org/wiki/Grape_tomato tomato
21 hillbilly tomato green zebra tomato http://en.wikipedia.org/wiki/Hillbilly_(tomato) https://en.wikipedia.org/wiki/Green_Zebra tomato
22 jubilee tomato Hanover tomato http://en.wikipedia.org/wiki/Jubilee_(tomato) http://en.wikipedia.org/wiki/Hanover_tomato tomato
23 lillian's yellow tomato hillbilly tomato http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato) http://en.wikipedia.org/wiki/Hillbilly_(tomato) tomato
24 Matt's wild cherry tomato jubilee tomato http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry http://en.wikipedia.org/wiki/Jubilee_(tomato) tomato
25 mortgage lifter tomato lillian's yellow tomato http://en.wikipedia.org/wiki/Mortgage_Lifter http://en.wikipedia.org/wiki/Lillian%27s_Yellow_(tomato) tomato
26 Mr. Stripey tomato marglobe tomato http://en.wikipedia.org/wiki/Mr._Stripey http://en.wikipedia.org/wiki/Marglobe tomato
27 Roma tomato Matt's wild cherry tomato http://en.wikipedia.org/wiki/Roma_tomato http://en.wikipedia.org/wiki/Matt%27s_Wild_Cherry tomato cherry tomato
28 San Marzano tomato mortgage lifter tomato http://en.wikipedia.org/wiki/San_Marzano_tomato http://en.wikipedia.org/wiki/Mortgage_Lifter tomato
29 Santorini tomato Mr. Stripey tomato http://en.wikipedia.org/wiki/Santorini_(tomato) http://en.wikipedia.org/wiki/Mr._Stripey tomato
30 stupice tomato pear tomato http://en.wikipedia.org/wiki/Super_Sweet_100 http://en.wikipedia.org/wiki/Pear_tomato tomato
31 tigerella tomato Roma tomato http://en.wikipedia.org/wiki/Tigerella http://en.wikipedia.org/wiki/Roma_tomato tomato
32 tomaccio tomato San Marzano tomato http://en.wikipedia.org/wiki/Tomaccio_(tomato) http://en.wikipedia.org/wiki/San_Marzano_tomato tomato
33 Santorini tomato http://en.wikipedia.org/wiki/Santorini_(tomato) cherry tomato
34 stupice tomato http://en.wikipedia.org/wiki/Super_Sweet_100 tomato
35 super sweet 100 tomato http://en.wikipedia.org/wiki/Super_Sweet_100 cherry tomato
36 three sisters tomato http://en.wikipedia.org/wiki/Three_Sisters_(tomato) tomato
37 tigerella tomato http://en.wikipedia.org/wiki/Tigerella tomato
38 tomaccio tomato http://en.wikipedia.org/wiki/Tomaccio_(tomato) cherry tomato
39 tomberry http://en.wikipedia.org/wiki/Tomberry tomato
40 traveller tomato http://en.wikipedia.org/wiki/Traveller_(tomato) tomato
41 three sisters tomato white queen tomato http://en.wikipedia.org/wiki/Three_Sisters_(tomato) http://en.wikipedia.org/wiki/White_Queen_tomato tomato
Hanover tomato http://en.wikipedia.org/wiki/Hanover_tomato tomato
celebrity tomato http://en.wikipedia.org/wiki/Celebrity_(tomato) tomato
tomberry http://en.wikipedia.org/wiki/Tomberry tomato
super sweet 100 tomato http://en.wikipedia.org/wiki/Super_Sweet_100 tomato
marglobe tomato http://en.wikipedia.org/wiki/Marglobe tomato
grape tomato http://en.wikipedia.org/wiki/Grape_tomato tomato
cherry tomato http://en.wikipedia.org/wiki/Cherry_tomato tomato
Aunt Ruby's German green tomato http://en.wikipedia.org/wiki/Aunt_Ruby%27s_German_Green tomato
white queen tomato http://en.wikipedia.org/wiki/White_Queen_tomato tomato
pear tomato http://en.wikipedia.org/wiki/Pear_tomato tomato

View File

@@ -17,17 +17,17 @@ describe MembersController do
end
describe "GET JSON index" do
it "does NOT provide JSON for members" do
it "provides JSON for members" do
get :index, :format => 'json'
response.should_not be_success
response.should be_success
end
end
describe "GET show" do
it "does NOT provide JSON for member profile" do
it "provides JSON for member profile" do
get :show, { :id => @member.id , :format => 'json' }
response.should_not be_success
response.should be_success
end
it "assigns @posts with the member's posts" do

View File

@@ -0,0 +1,14 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :alternate_name do
name "alternate name"
crop
creator
factory :alternate_eggplant do
association :crop, factory: :eggplant
name "aubergine"
end
end
end

View File

@@ -40,6 +40,9 @@ FactoryGirl.define do
name "popcorn"
end
factory :eggplant do
name "eggplant"
end
# This should have a name that is alphabetically earlier than :uppercase
# crop to ensure that the ordering tests work.

View File

@@ -0,0 +1,74 @@
require 'spec_helper'
feature "Alternate names" do
let!(:alternate_eggplant) { FactoryGirl.create(:alternate_eggplant) }
let(:crop) { alternate_eggplant.crop }
scenario "Display alternate names on crop page" do
visit crop_path(alternate_eggplant.crop)
expect(page.status_code).to equal 200
expect(page).to have_content alternate_eggplant.name
end
scenario "Index page for alternate names" do
visit alternate_names_path
expect(page).to have_content alternate_eggplant.name
end
context "User is a crop wrangler" do
let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) }
let(:member){crop_wranglers.first}
before :each do
login_as(member)
end
scenario "Crop wranglers can edit alternate names" do
visit crop_path(crop)
expect(page.status_code).to equal 200
expect(page).to have_content "CROP WRANGLER"
expect(page).to have_content alternate_eggplant.name
expect(page).to have_link "Edit", :href => edit_alternate_name_path(alternate_eggplant)
within('.alternate_names') { click_on "Edit" }
expect(page.status_code).to equal 200
expect(page).to have_css "option[value='#{crop.id}'][selected=selected]"
fill_in 'Name', with: "alternative aubergine"
click_on "Save"
expect(page.status_code).to equal 200
expect(page).to have_content "alternative aubergine"
expect(page).to have_content 'Alternate name was successfully updated'
end
scenario "Crop wranglers can delete alternate names" do
visit crop_path(alternate_eggplant.crop)
expect(page).to have_link "Delete",
href: alternate_name_path(alternate_eggplant)
within('.alternate_names') { click_on "Delete" }
expect(page.status_code).to equal 200
expect(page).to_not have_content alternate_eggplant.name
expect(page).to have_content 'Alternate name was successfully deleted'
end
scenario "Crop wranglers can add alternate names" do
visit crop_path(crop)
expect(page).to have_link "Add",
href: new_alternate_name_path(crop_id: crop.id)
within('.alternate_names') { click_on "Add" }
expect(page.status_code).to equal 200
expect(page).to have_css "option[value='#{crop.id}'][selected=selected]"
fill_in 'Name', with: "not an aubergine"
click_on "Save"
expect(page.status_code).to equal 200
expect(page).to have_content "not an aubergine"
expect(page).to have_content 'Alternate name was successfully created'
end
scenario "The show-alternate-name page works" do
visit alternate_name_path(alternate_eggplant)
expect(page.status_code).to equal 200
expect(page).to have_content alternate_eggplant.crop.name
end
end
end

View File

@@ -4,16 +4,13 @@ feature "crop wranglers" do
context "signed in member" do
let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) }
let(:member){crop_wranglers.first}
before :each do
visit root_path
click_link 'Sign in'
fill_in 'Login', with: member.login_name
fill_in 'Password', with: member.password
click_button 'Sign in'
page.should have_content member.login_name
background do
login_as(member)
end
scenario "crop wranglers are listed on the crop wrangler page" do
visit root_path
click_link 'Crop Wrangling'
within '.crop_wranglers' do

View File

@@ -0,0 +1,32 @@
require 'spec_helper'
feature "crop detail page" do
let(:crop) { FactoryGirl.create(:crop) }
context "signed in member" do
let(:member) { FactoryGirl.create(:member) }
background do
login_as(member)
end
context "action buttons" do
background do
visit crop_path(crop)
end
scenario "has a link to plant the crop" do
expect(page).to have_link "Plant this", :href => new_planting_path(:crop_id => crop.id)
end
scenario "has a link to harvest the crop" do
expect(page).to have_link "Harvest this", :href => new_harvest_path(:crop_id => crop.id)
end
scenario "has a link to add seeds" do
expect(page).to have_link "Add seeds to stash", :href => new_seed_path(:crop_id => crop.id)
end
end
end
end

View File

@@ -0,0 +1,149 @@
require 'spec_helper'
feature "member profile" do
context "signed out member" do
let(:member) { FactoryGirl.create(:member) }
scenario "basic details on member profile page" do
visit member_path(member)
expect(page).to have_css("h1", :text => member.login_name)
expect(page).to have_content member.bio
expect(page).to have_content "Member since: #{member.created_at.to_s(:date)}"
expect(page).to have_content "Account type: Free account"
expect(page).to have_content "#{member.login_name}'s gardens"
expect(page).to have_link "More about this garden...", :href => garden_path(member.gardens.first)
end
scenario "no bio" do
member.bio = nil
member.save
visit member_path(member)
expect(page).to have_content "hasn't written a bio yet"
end
scenario "gravatar" do
visit member_path(member)
expect(page).to have_css "img.avatar"
end
context "location" do
scenario "member has set location" do
london_member = FactoryGirl.create(:london_member)
visit member_path(london_member)
expect(page).to have_css("h1>small", :text => london_member.location)
expect(page).to have_css("#membermap")
expect(page).to have_content "See other members near #{london_member.location}"
end
scenario "member has not set location" do
visit member_path(member)
expect(page).not_to have_css("h1>small")
expect(page).not_to have_css("#membermap")
expect(page).not_to have_content "See other members near"
end
end
context "email privacy" do
scenario "public email address" do
public_member = FactoryGirl.create(:public_member)
visit member_path(public_member)
expect(page).to have_content public_member.email
end
scenario "private email address" do
visit member_path(member)
expect(page).not_to have_content member.email
end
end
context "email privacy" do
scenario "public email address" do
public_member = FactoryGirl.create(:public_member)
visit member_path(public_member)
expect(page).to have_content public_member.email
end
scenario "private email address" do
visit member_path(member)
expect(page).not_to have_content member.email
end
end
context "activity stats" do
scenario "with no activity" do
visit member_path(member)
expect(page).to have_content "Activity"
expect(page).to have_content "0 plantings"
expect(page).to have_content "0 harvests"
expect(page).to have_content "0 seeds"
expect(page).to have_content "0 posts"
end
scenario "with some activity" do
FactoryGirl.create_list(:planting, 2, :owner => member)
FactoryGirl.create_list(:harvest, 3, :owner => member)
FactoryGirl.create_list(:seed, 4, :owner => member)
FactoryGirl.create_list(:post, 5, :author => member)
visit member_path(member)
expect(page).to have_link "2 plantings", :href => plantings_by_owner_path(:owner => member)
expect(page).to have_link "3 harvests", :href => harvests_by_owner_path(:owner => member)
expect(page).to have_link "4 seeds", :href => seeds_by_owner_path(:owner => member)
expect(page).to have_link "5 posts", :href => posts_by_author_path(:author => member)
end
end
scenario "twitter link" do
twitter_auth = FactoryGirl.create(:authentication, :member => member)
visit member_path(member)
expect(page).to have_link twitter_auth.name, :href => "http://twitter.com/#{twitter_auth.name}"
end
scenario "flickr link" do
flickr_auth = FactoryGirl.create(:flickr_authentication, :member => member)
visit member_path(member)
expect(page).to have_link flickr_auth.name, :href => "http://flickr.com/photos/#{flickr_auth.uid}"
end
end
context "signed in member" do
let(:member) { FactoryGirl.create(:member) }
let(:other_member) { FactoryGirl.create(:member) }
background do
login_as(member)
end
context "your own profile page" do
background do
visit member_path(member)
end
scenario "has a link to create new garden" do
expect(page).to have_link "New Garden", :href => new_garden_path
end
scenario "has a button to edit profile" do
expect(page).to have_link "Edit profile", :href => edit_member_registration_path
end
scenario "has a button to upgrade account" do
expect(page).to have_link "Upgrade account", :href => shop_path
end
end
context "someone else's profile page" do
background do
visit member_path(other_member)
end
scenario "has a private message button" do
expect(page).to have_link "Send message", :href => new_notification_path(:recipient_id => other_member.id)
end
end
end
end

View File

@@ -0,0 +1,75 @@
require 'spec_helper'
feature "Scientific names" do
let!(:zea_mays) { FactoryGirl.create(:zea_mays) }
let(:crop) { zea_mays.crop }
scenario "Display scientific names on crop page" do
visit crop_path(zea_mays.crop)
expect(page.status_code).to equal 200
expect(page).to have_content zea_mays.scientific_name
end
scenario "Index page for scientific names" do
visit scientific_names_path
expect(page.status_code).to equal 200
expect(page).to have_content zea_mays.scientific_name
end
context "User is a crop wrangler" do
let!(:crop_wranglers) { FactoryGirl.create_list(:crop_wrangling_member, 3) }
let(:member){crop_wranglers.first}
before :each do
login_as(member)
end
scenario "Crop wranglers can edit scientific names" do
visit crop_path(crop)
expect(page.status_code).to equal 200
expect(page).to have_content "CROP WRANGLER"
expect(page).to have_content zea_mays.scientific_name
expect(page).to have_link "Edit", :href => edit_scientific_name_path(zea_mays)
within('.scientific_names') { click_on "Edit" }
expect(page.status_code).to equal 200
expect(page).to have_css "option[value='#{crop.id}'][selected=selected]"
fill_in 'Scientific name', with: "Zea mirabila"
click_on "Save"
expect(page).to have_content "Zea mirabila"
expect(page).to have_content 'Scientific name was successfully updated'
end
scenario "Crop wranglers can delete scientific names" do
visit crop_path(zea_mays.crop)
expect(page).to have_link "Delete",
href: scientific_name_path(zea_mays)
within('.scientific_names') { click_on "Delete" }
expect(page.status_code).to equal 200
expect(page).to_not have_content zea_mays.scientific_name
expect(page).to have_content 'Scientific name was successfully deleted'
end
scenario "Crop wranglers can add scientific names" do
visit crop_path(crop)
expect(page).to have_link "Add",
href: new_scientific_name_path(crop_id: crop.id)
within('.scientific_names') { click_on "Add" }
expect(page.status_code).to equal 200
expect(page).to have_css "option[value='#{crop.id}'][selected=selected]"
fill_in 'Scientific name', with: "Zea mirabila"
click_on "Save"
expect(page.status_code).to equal 200
expect(page).to have_content "Zea mirabila"
expect(page).to have_content 'Scientific name was successfully created'
end
scenario "The show-scientific-name page works" do
visit scientific_name_path(zea_mays)
expect(page.status_code).to equal 200
expect(page).to have_link zea_mays.crop.name,
href: crop_path(zea_mays.crop)
end
end
end

View File

@@ -0,0 +1,22 @@
require 'spec_helper'
describe AlternateName do
let(:an) { FactoryGirl.create(:alternate_eggplant) }
it 'should save 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
crop = an.crop
an2 = AlternateName.create(
:name => "really alternative tomato",
:crop_id => crop.id,
:creator_id => an.creator.id
)
crop.alternate_names << an2
expect(crop.alternate_names).to include an
expect(crop.alternate_names).to include an2
end
end

View File

@@ -39,16 +39,20 @@ describe Photo do
expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound
end
it 'they are no longer used by plantings' do
it 'they are used by plantings but not harvests' do
harvest.photos << photo
planting.photos << photo
planting.destroy # photo is now no longer used by anything
expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound
harvest.destroy # photo is now used by harvest but not planting
photo.destroy_if_unused
expect(lambda { photo.reload }).not_to raise_error ActiveRecord::RecordNotFound
end
it 'they are no longer used by harvests' do
it 'they are used by harvests but not plantings' do
harvest.photos << photo
harvest.destroy # photo is now no longer used by anything
expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound
planting.photos << photo
planting.destroy # photo is now used by harvest but not planting
photo.destroy_if_unused
expect(lambda { photo.reload }).not_to raise_error ActiveRecord::RecordNotFound
end
it 'they are no longer used by anything' do
@@ -59,11 +63,14 @@ describe Photo do
planting.destroy # photo is still used by harvest
photo.reload
expect(photo).to be_an_instance_of Photo
expect(photo.plantings.size).to eq 0
expect(photo.harvests.size).to eq 1
harvest.destroy # photo is now no longer used by anything
photo.reload
expect(photo.plantings.size).to eq 0
expect(photo.harvests.size).to eq 0
photo.destroy_if_unused
expect(lambda { photo.reload }).to raise_error ActiveRecord::RecordNotFound
end

View File

@@ -1,263 +0,0 @@
require 'spec_helper'
describe "crops/show" do
before(:each) do
controller.stub(:current_user) { nil }
@crop = FactoryGirl.create(:maize,
:scientific_names => [ FactoryGirl.create(:zea_mays) ]
)
assign(:crop, @crop)
@author = FactoryGirl.create(:member)
page = 1
per_page = 2
total_entries = 2
@posts = WillPaginate::Collection.create(page, per_page, total_entries) do |pager|
pager.replace([
@post1 = FactoryGirl.create(:post, :author => @author, :body => "Post it!" ),
@post2 = FactoryGirl.create(:post, :author => @author, :body => "Done!" )
])
end
end
context 'photos' do
before(:each) do
@planting = FactoryGirl.create(:planting, :crop => @crop)
@photo1 = FactoryGirl.create(:photo)
@photo2 = FactoryGirl.create(:photo)
@photo3 = FactoryGirl.create(:photo)
@planting.photos << [@photo1, @photo2, @photo3]
render
end
it 'shows 3 photos across the top of the page' do
assert_select "div.thumbnail>a>img", :count => 3
end
it 'links to the photo detail page' do
assert_select "a[href=#{photo_path(@photo1)}]"
end
it 'links to the photo owner' do
assert_select "a[href=#{member_path(@photo1.owner)}]"
end
end
context "map" do
it "has a map" do
render
assert_select("div#cropmap")
end
it "explains what's shown on the map" do
render
rendered.should contain "Only plantings by members who have set their locations are shown on this map"
end
it "shows a 'set your location' link to people who need to" do
@nowhere = FactoryGirl.create(:member)
sign_in @nowhere
controller.stub(:current_user) { @nowhere }
render
rendered.should contain "Set your location"
end
it "doesn't show 'set your location' to people who have one" do
@somewhere = FactoryGirl.create(:london_member)
sign_in @somewhere
controller.stub(:current_user) { @somewhere }
render
rendered.should_not contain "Set your location"
end
end
it "shows the wikipedia URL" do
render
assert_select("a[href=#{@crop.en_wikipedia_url}]", 'Wikipedia (English)')
end
it "shows the scientific name" do
render
rendered.should contain "Scientific names"
rendered.should contain "Zea mays"
end
context "seeds available for trade" do
before(:each) do
@owner1 = FactoryGirl.create(:london_member)
@owner2 = FactoryGirl.create(:member) # no location
@seed1 = FactoryGirl.create(:tradable_seed, :owner => @owner1, :crop => @crop)
@seed2 = FactoryGirl.create(:tradable_seed, :owner => @owner2, :crop => @crop)
render
end
it "shows a heading" do
rendered.should contain "Find seeds"
end
it "shows a list of people with seeds to trade" do
@crop.seeds.each do |seed|
assert_select "a[href=#{seed_path(seed)}]"
end
end
end
context "harvests" do
before(:each) do
@owner1 = FactoryGirl.create(:london_member)
@h1 = FactoryGirl.create(:harvest, :owner => @owner1, :crop => @crop)
@h2 = FactoryGirl.create(:harvest, :owner => @owner1, :crop => @crop)
render
end
it "shows a heading" do
rendered.should contain "Harvests"
end
it "shows a list of people who have harvested this crop" do
@crop.harvests.each do |harvest|
assert_select "a[href=#{harvest_path(harvest)}]"
end
end
end
context "no seeds available for trade" do
it "shows a heading" do
render
rendered.should contain "Find seeds"
end
it "suggests you trade seeds" do
render
rendered.should contain "There are no seeds available to trade."
end
end
context "has plantings" do
before(:each) do
@owner = FactoryGirl.create(:london_member)
@planting = FactoryGirl.create(:planting,
:crop => @crop,
:owner => @owner
)
@crop.reload # to pick up latest plantings_count
end
it "links to people who are growing this crop" do
render
rendered.should contain @owner.login_name
rendered.should contain @owner.location
end
end
context "has posts" do
it "links to posts" do
render
@posts.each do |p|
rendered.should contain p.author.login_name
rendered.should contain p.subject
rendered.should contain p.body
end
end
it "contains two gravatar icons" do
render
assert_select "img", :src => /gravatar\.com\/avatar/, :count => 2
end
end
context 'varieties' do
before(:each) do
@popcorn = FactoryGirl.create(:popcorn, :parent_id => @crop.id)
@ubercrop = FactoryGirl.create(:crop, :name => 'ubercrop')
@crop.parent_id = @ubercrop.id
@crop.save
render
end
it 'shows popcorn as a child variety' do
rendered.should contain @popcorn.name
end
it 'shows parent crop' do
rendered.should contain @ubercrop.name
end
end
it 'tells you to sign in/sign up' do
render
rendered.should contain 'Sign in or sign up to plant'
end
context 'logged in' do
before(:each) do
@member = FactoryGirl.create(:member)
sign_in @member
controller.stub(:current_user) { @member }
render
end
it "shows a plant this button" do
rendered.should contain "Plant this"
end
it "shows a harvest this button" do
rendered.should contain "Harvest this"
end
it "links to the right crop in the new planting link" do
assert_select("a[href=#{new_planting_path}?crop_id=#{@crop.id}]")
end
it "links to the right crop in the new harvest link" do
assert_select("a[href=#{new_harvest_path}?crop_id=#{@crop.id}]")
end
it { rendered.should contain "Nobody has planted this crop yet" }
it { rendered.should contain "Nobody has harvested this crop yet" }
context "should have a link to" do
before do
FactoryGirl.create(:planting, :crop => @crop)
FactoryGirl.create(:harvest, :crop => @crop)
@crop.reload
render
end
it "show all plantings by the crop link" do
assert_select("a[href=#{plantings_by_crop_path @crop}]")
end
it "show all harvests by the crop link" do
assert_select("a[href=#{harvests_by_crop_path @crop}]")
end
end
end
context "logged in and crop wrangler" do
before(:each) do
@member = FactoryGirl.create(:crop_wrangling_member)
sign_in @member
controller.stub(:current_user) { @member }
render
end
it "links to the edit crop form" do
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
end

View File

@@ -1,214 +0,0 @@
require 'spec_helper'
describe "members/show" do
before(:each) do
controller.stub(:current_user) { nil }
@member = FactoryGirl.create(:member)
@garden = FactoryGirl.create(:garden, :owner => @member)
end
context "the basics" do
before(:each) do
render
end
it "shows the bio" do
assert_select "h2", "Bio"
rendered.should contain @member.bio
end
it "shows account creation date" do
@time = @member.created_at
rendered.should contain "Member since"
rendered.should contain @time.strftime("%B %d, %Y")
end
it "shows account type" do
rendered.should contain "Free account"
end
it "contains a gravatar icon" do
assert_select "img", :src => /gravatar\.com\/avatar/
end
end
context 'no bio' do
before(:each) do
@member = FactoryGirl.create(:no_bio_member)
render
end
it "doesn't show the bio" do
rendered.should_not contain "Bio"
end
end
context 'twitter' do
context "no twitter" do
it "doesn't show twitter link" do
render
assert_select "a[href^=http://twitter.com/]", :count => 0
end
end
context 'has twitter' do
it "shows twitter link" do
@twitter_auth = FactoryGirl.create(:authentication, :member => @member)
render
assert_select "a", :href => "http://twitter.com/#{@twitter_auth.name}"
end
end
end
context 'flickr' do
context "no flickr" do
it "doesn't show flickr link" do
render
assert_select "a[href^=http://flickr.com/]", :count => 0
end
end
context 'has flickr' do
it "shows flickr link" do
@flickr_auth = FactoryGirl.create(:flickr_authentication, :member => @member)
render
assert_select "a", :href => "http://flickr.com/photos/#{@flickr_auth.uid}"
end
end
end
context "gardens and plantings" do
before(:each) do
@planting = FactoryGirl.create(:planting, :garden => @garden)
render
end
it "shows the auto-created garden" do
assert_select "li.active>a", :text => "Garden"
end
it 'shows the garden description' do
rendered.should contain "totally cool garden"
end
it 'renders markdown in the garden description' do
assert_select "strong", "totally"
end
it "shows the plantings in the garden" do
rendered.should contain @planting.crop.name
end
it "doesn't show the note about random plantings" do
rendered.should_not contain "Note: these are a random selection"
end
it "doesn't show the email address" do
rendered.should_not contain @member.email
end
it "does not contain a 'New Garden' link" do
assert_select "a[href=#garden_new]", false
end
it "does not contain a 'New Garden' tab" do
assert_select "#garden_new", false
end
end
context "signed in member" do
before(:each) do
sign_in @member
controller.stub(:current_user) { @member }
render
end
it "contains a 'New Garden' link" do
assert_select "a[href=#garden_new]", :text => "New Garden"
end
it "contains an edit settings button" do
rendered.should contain "Edit your profile"
end
it "asks you to upgrade your account" do
rendered.should contain "Upgrade"
end
it "contains no send message button" do
rendered.should_not contain "Send Message"
end
end
context "signed in as different member" do
before(:each) do
@member2 = FactoryGirl.create(:member)
sign_in @member2
controller.stub(:current_user) { @member2 }
render
end
it "does not contain a 'New Garden' link" do
assert_select "a[href=#garden_new]", false
end
it "does not contain a 'New Garden' tab" do
assert_select "#garden_new", false
end
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
before(:each) do
@member = FactoryGirl.create(:public_member)
render
end
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
before(:each) do
@member = FactoryGirl.create(:london_member)
render
end
it "shows the location" do
rendered.should contain @member.location
end
it "shows a map" do
assert_select "img", :src => /maps\.google\.com/
end
it 'includes a link to places page' do
assert_select 'a', :href => place_path(@member.location)
end
end
context "no location stated" do
before(:each) do
@member = FactoryGirl.create(:member)
render
end
it "doesn't have a location" do
@member.location.to_s.should eq ''
end
it "doesn't show the location" do
rendered.should_not contain "Location:"
end
it "doesn't show a map" do
assert_select "img[src*=maps]", false
end
end
end