Merge pull request #25 from pozorvlak/story67cropindex2

Story67cropindex2
This commit is contained in:
Skud
2012-10-03 13:03:37 -07:00
40 changed files with 585 additions and 79 deletions

View File

@@ -9,8 +9,9 @@ gem 'haml'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'sqlite3'
group :production do
gem 'pg'
end
# Gems used only for assets and not required
# in production environments by default.
@@ -59,6 +60,8 @@ gem 'cape'
gem 'diff-lcs'
group :development, :test do
gem 'sqlite3'
gem 'haml-rails'
gem 'rspec-rails'
gem 'webrat'
gem 'watchr'

View File

@@ -65,6 +65,11 @@ GEM
fastthread (1.0.7)
fssm (0.2.9)
haml (3.1.7)
haml-rails (0.3.5)
actionpack (>= 3.1, < 4.1)
activesupport (>= 3.1, < 4.1)
haml (~> 3.1)
railties (>= 3.1, < 4.1)
highline (1.6.14)
hike (1.2.1)
i18n (0.6.1)
@@ -95,6 +100,7 @@ GEM
fastthread (>= 1.0.1)
rack
rake (>= 0.8.1)
pg (0.14.1)
polyglot (0.3.3)
rack (1.4.1)
rack-cache (1.2)
@@ -184,8 +190,10 @@ DEPENDENCIES
devise
diff-lcs
haml
haml-rails
jquery-rails
passenger
pg
rails (= 3.2.8)
rake
rspec-rails

View File

@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/

View File

@@ -0,0 +1,83 @@
class CropsController < ApplicationController
# GET /crops
# GET /crops.json
def index
@crops = Crop.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @crops }
end
end
# GET /crops/1
# GET /crops/1.json
def show
@crop = Crop.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @crop }
end
end
# GET /crops/new
# GET /crops/new.json
def new
@crop = Crop.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @crop }
end
end
# GET /crops/1/edit
def edit
@crop = Crop.find(params[:id])
end
# POST /crops
# POST /crops.json
def create
@crop = Crop.new(params[:crop])
respond_to do |format|
if @crop.save
format.html { redirect_to @crop, notice: 'Crop was successfully created.' }
format.json { render json: @crop, status: :created, location: @crop }
else
format.html { render action: "new" }
format.json { render json: @crop.errors, status: :unprocessable_entity }
end
end
end
# PUT /crops/1
# PUT /crops/1.json
def update
@crop = Crop.find(params[:id])
respond_to do |format|
if @crop.update_attributes(params[:crop])
format.html { redirect_to @crop, notice: 'Crop was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @crop.errors, status: :unprocessable_entity }
end
end
end
# DELETE /crops/1
# DELETE /crops/1.json
def destroy
@crop = Crop.find(params[:id])
@crop.destroy
respond_to do |format|
format.html { redirect_to crops_url }
format.json { head :no_content }
end
end
end

View File

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

3
app/models/crop.rb Normal file
View File

@@ -0,0 +1,3 @@
class Crop < ActiveRecord::Base
attr_accessible :en_wikipedia_url, :system_name
end

View File

@@ -0,0 +1,16 @@
= form_for @crop do |f|
- if @crop.errors.any?
#error_explanation
%h3= "#{pluralize(@crop.errors.count, "error")} prohibited this crop from being saved:"
%ul
- @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'

View File

@@ -0,0 +1,7 @@
- content_for :title, "Editing crop"
= render 'form'
= link_to 'Show', @crop
\|
= link_to 'Back', crops_path

View File

@@ -0,0 +1,10 @@
- content_for :title, "Crops"
%ul
- @crops.each do |crop|
%li
= link_to crop.system_name, crop
%br
= link_to 'New Crop', new_crop_path

View File

@@ -0,0 +1,5 @@
- content_for :title, "New crop"
= render 'form'
= link_to 'Back', crops_path

View File

@@ -0,0 +1,10 @@
- content_for :title, @crop.system_name
%p
%b More information:
= link_to @crop.en_wikipedia_url, @crop.en_wikipedia_url
%ul.link-list
%li= link_to 'Edit', edit_crop_path(@crop)
%li= link_to 'Destroy', @crop, method: :delete, data: { confirm: 'Are you sure?' }
%li= link_to 'Back', crops_path

View File

@@ -1,4 +1,4 @@
%h2 Resend confirmation instructions
- content_for :title, "Resend confirmation instructions"
= form_for(resource, :as => resource_name, :url => confirmation_path(resource_name), :html => { :method => :post }) do |f|
= devise_error_messages!

View File

@@ -1,4 +1,4 @@
%h2 Change your password
- content_for :title, "Change your password"
- form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put }) do |f|
= devise_error_messages!

View File

@@ -1,4 +1,4 @@
%h2 Forgot your password?
- content_for :title, "Forgot your password?"
= form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :post }) do |f|
= devise_error_messages!

View File

@@ -1,6 +1,4 @@
%h2
Edit
= resource_name.to_s.humanize
- content_for :title, "Edit " + resource_name.to_s.humanize
= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => { :method => :put }) do |f|
= devise_error_messages!

View File

@@ -1,4 +1,4 @@
%h2 Sign up
- content_for :title, "Sign up"
= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
= devise_error_messages!

View File

@@ -1,4 +1,4 @@
%h2 Sign in
- content_for :title, "Sign in"
= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
%div

View File

@@ -1,4 +1,4 @@
%h2 Resend unlock instructions
- content_for :title, "Resend unlock instructions"
= form_for(resource, :as => resource_name, :url => unlock_path(resource_name), :html => { :method => :post }) do |f|
= devise_error_messages!

View File

@@ -1,3 +1,5 @@
%p
Growstuff is a community of food gardeners working together to build an open source platform to track, share, and discuss edible gardens and sustainable lifestyles. You can join us right now and be part of growing our website, from seed to harvest. We welcome you regardless of your experience, and invite you to be part of our development process.
%p
= link_to "Crops", crops_path

View File

@@ -3,7 +3,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href='http://fonts.googleapis.com/css?family=Sevillana' rel='stylesheet' type='text/css'>
%title
= content_for?(:title) ? yield(:title) : "Growstuff"
= content_for?(:title) ? yield(:title) + " - Growstuff" : "Growstuff"
= stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "application"
= csrf_meta_tags

View File

@@ -4,11 +4,13 @@
= render :partial => "layouts/header"
.row
.ten.columns
- if content_for?(:title)
%h2=yield(:title)
- if notice
%p.notice
%div.alert-box.success
= notice
- if alert
%p.alert
%div.alert-box.alert
= alert
= yield
= render :partial => "layouts/footer"

View File

@@ -61,5 +61,10 @@ module Growstuff
# Don't try to connect to the database when precompiling assets
config.assets.initialize_on_precompile = false
config.generators do |g|
g.template_engine :haml
g.stylesheets false
end
end
end

View File

@@ -1,25 +1,20 @@
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
development:
adapter: sqlite3
database: db/development.sqlite3
database: db/growstuff_dev.sqlite3
pool: 5
timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
adapter: sqlite3
database: db/test.sqlite3
database: db/growstuff_test.sqlite3
pool: 5
timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
adapter: postgresql
database: growstuff_prod
pool: 5
timeout: 5000
username: growstuff
host: localhost
password: <% begin IO.read("/home/deploy/.db_password") rescue "" end %>

View File

@@ -1,4 +1,6 @@
Growstuff::Application.routes.draw do
resources :crops
devise_for :users
get "home/index"

View File

@@ -0,0 +1,10 @@
class CreateCrops < ActiveRecord::Migration
def change
create_table :crops do |t|
t.string :system_name
t.string :en_wikipedia_url
t.timestamps
end
end
end

View File

@@ -0,0 +1,15 @@
class RequireSystemNameForCrops < ActiveRecord::Migration
def up
change_table :crops do |t|
t.index :system_name
t.change :system_name, :string, :null => false
end
end
def down
change_table :crops do |t|
t.change :system_name, :string, :null => true
t.remove_index :system_name
end
end
end

View File

@@ -11,7 +11,16 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120903112806) do
ActiveRecord::Schema.define(:version => 20121003190731) do
create_table "crops", :force => true do |t|
t.string "system_name", :null => false
t.string "en_wikipedia_url"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
add_index "crops", ["system_name"], :name => "index_crops_on_system_name"
create_table "users", :force => true do |t|
t.string "email", :default => "", :null => false

View File

@@ -0,0 +1,164 @@
require 'spec_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to specify the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
#
# Compared to earlier versions of this generator, there is very limited use of
# stubs and message expectations in this spec. Stubs are only used when there
# is no simpler way to get a handle on the object needed for the example.
# Message expectations are only used when there is no simpler way to specify
# that an instance is receiving a specific message.
describe CropsController do
# This should return the minimal set of attributes required to create a valid
# Crop. As you add validations to Crop, be sure to
# update the return value of this method accordingly.
def valid_attributes
{ :system_name => "Tomato" }
end
# This should return the minimal set of values that should be in the session
# in order to pass any filters (e.g. authentication) defined in
# CropsController. Be sure to keep this updated too.
def valid_session
{}
end
describe "GET index" do
it "assigns all crops as @crops" do
crop = Crop.create! valid_attributes
get :index, {}, valid_session
assigns(:crops).should eq([crop])
end
end
describe "GET show" do
it "assigns the requested crop as @crop" do
crop = Crop.create! valid_attributes
get :show, {:id => crop.to_param}, valid_session
assigns(:crop).should eq(crop)
end
end
describe "GET new" do
it "assigns a new crop as @crop" do
get :new, {}, valid_session
assigns(:crop).should be_a_new(Crop)
end
end
describe "GET edit" do
it "assigns the requested crop as @crop" do
crop = Crop.create! valid_attributes
get :edit, {:id => crop.to_param}, valid_session
assigns(:crop).should eq(crop)
end
end
describe "POST create" do
describe "with valid params" do
it "creates a new Crop" do
expect {
post :create, {:crop => valid_attributes}, valid_session
}.to change(Crop, :count).by(1)
end
it "assigns a newly created crop as @crop" do
post :create, {:crop => valid_attributes}, valid_session
assigns(:crop).should be_a(Crop)
assigns(:crop).should be_persisted
end
it "redirects to the created crop" do
post :create, {:crop => valid_attributes}, valid_session
response.should redirect_to(Crop.last)
end
end
describe "with invalid params" do
it "assigns a newly created but unsaved crop as @crop" do
# Trigger the behavior that occurs when invalid params are submitted
Crop.any_instance.stub(:save).and_return(false)
post :create, {:crop => {}}, valid_session
assigns(:crop).should be_a_new(Crop)
end
it "re-renders the 'new' template" do
# Trigger the behavior that occurs when invalid params are submitted
Crop.any_instance.stub(:save).and_return(false)
post :create, {:crop => {}}, valid_session
response.should render_template("new")
end
end
end
describe "PUT update" do
describe "with valid params" do
it "updates the requested crop" do
crop = Crop.create! valid_attributes
# Assuming there are no other crops in the database, this
# specifies that the Crop created on the previous line
# receives the :update_attributes message with whatever params are
# submitted in the request.
Crop.any_instance.should_receive(:update_attributes).with({'these' => 'params'})
put :update, {:id => crop.to_param, :crop => {'these' => 'params'}}, valid_session
end
it "assigns the requested crop as @crop" do
crop = Crop.create! valid_attributes
put :update, {:id => crop.to_param, :crop => valid_attributes}, valid_session
assigns(:crop).should eq(crop)
end
it "redirects to the crop" do
crop = Crop.create! valid_attributes
put :update, {:id => crop.to_param, :crop => valid_attributes}, valid_session
response.should redirect_to(crop)
end
end
describe "with invalid params" do
it "assigns the crop as @crop" do
crop = Crop.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Crop.any_instance.stub(:save).and_return(false)
put :update, {:id => crop.to_param, :crop => {}}, valid_session
assigns(:crop).should eq(crop)
end
it "re-renders the 'edit' template" do
crop = Crop.create! valid_attributes
# Trigger the behavior that occurs when invalid params are submitted
Crop.any_instance.stub(:save).and_return(false)
put :update, {:id => crop.to_param, :crop => {}}, valid_session
response.should render_template("edit")
end
end
end
describe "DELETE destroy" do
it "destroys the requested crop" do
crop = Crop.create! valid_attributes
expect {
delete :destroy, {:id => crop.to_param}, valid_session
}.to change(Crop, :count).by(-1)
end
it "redirects to the crops list" do
crop = Crop.create! valid_attributes
delete :destroy, {:id => crop.to_param}, valid_session
response.should redirect_to(crops_url)
end
end
end

View File

@@ -0,0 +1,15 @@
require 'spec_helper'
# Specs in this file have access to a helper object that includes
# the CropsHelper. For example:
#
# describe CropsHelper do
# describe "string concat" do
# it "concats two strings with spaces" do
# helper.concat_strings("this","that").should == "this that"
# end
# end
# end
describe CropsHelper do
pending "add some examples to (or delete) #{__FILE__}"
end

29
spec/models/crop_spec.rb Normal file
View File

@@ -0,0 +1,29 @@
require 'spec_helper'
describe Crop do
context 'all fields present' do
before(:each) do
@crop = Crop.new
@crop.system_name = "Tomato"
@crop.en_wikipedia_url = "http://en.wikipedia.org/wiki/Tomato"
end
it 'should save a basic crop' do
@crop.save.should be_true
end
it 'should be fetchable from the database' do
@crop.save
@crop2 = Crop.find_by_system_name('Tomato')
@crop2.en_wikipedia_url.should == "http://en.wikipedia.org/wiki/Tomato"
end
end
context 'invalid data' do
it 'should not save a crop without a system name' do
@crop = Crop.new
expect { @crop.save }.to raise_error ActiveRecord::StatementInvalid
end
end
end

View File

@@ -0,0 +1,35 @@
require "spec_helper"
describe CropsController do
describe "routing" do
it "routes to #index" do
get("/crops").should route_to("crops#index")
end
it "routes to #new" do
get("/crops/new").should route_to("crops#new")
end
it "routes to #show" do
get("/crops/1").should route_to("crops#show", :id => "1")
end
it "routes to #edit" do
get("/crops/1/edit").should route_to("crops#edit", :id => "1")
end
it "routes to #create" do
post("/crops").should route_to("crops#create")
end
it "routes to #update" do
put("/crops/1").should route_to("crops#update", :id => "1")
end
it "routes to #destroy" do
delete("/crops/1").should route_to("crops#destroy", :id => "1")
end
end
end

View File

@@ -0,0 +1,20 @@
require 'spec_helper'
describe "crops/edit" do
before(:each) do
@crop = assign(:crop, stub_model(Crop,
:system_name => "MyString",
:en_wikipedia_url => "MyString"
))
end
it "renders the edit 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(@crop), :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]"
end
end
end

View File

@@ -0,0 +1,23 @@
require 'spec_helper'
describe "crops/index" do
before(:each) do
assign(:crops, [
stub_model(Crop,
:system_name => "Maize",
:en_wikipedia_url => "http://en.wikipedia.org/wiki/Maize"
),
stub_model(Crop,
:system_name => "Tomato",
:en_wikipedia_url => "http://en.wikipedia.org/wiki/Tomato"
)
])
end
it "renders a list of crops" do
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
assert_select "a", :text => "Maize"
assert_select "a", :text => "Tomato"
end
end

View File

@@ -0,0 +1,20 @@
require 'spec_helper'
describe "crops/new" do
before(:each) do
assign(:crop, stub_model(Crop,
:system_name => "MyString",
:en_wikipedia_url => "MyString"
).as_new_record)
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]"
end
end
end

View File

@@ -0,0 +1,16 @@
require 'spec_helper'
describe "crops/show" do
before(:each) do
@crop = assign(:crop, stub_model(Crop,
:system_name => "System Name",
:en_wikipedia_url => "En Wikipedia Url"
))
end
it "renders attributes in <p>" do
render
# Run the generator again with the --webrat flag if you want to use webrat matchers
rendered.should match(/En Wikipedia Url/)
end
end

View File

@@ -8,7 +8,7 @@ describe 'devise/confirmations/new.html.haml', :type => "view" do
render
end
it 'should have a Resend button' do
rendered.should contain "Resend confirmation instructions"
it 'should contain an Email field' do
rendered.should contain "Email"
end
end

View File

@@ -12,7 +12,6 @@ describe 'devise/unlocks/new.html.haml', :type => "view" do
end
it 'should have some fields' do
rendered.should contain 'Resend unlock instructions'
rendered.should contain 'Email'
end
end

View File

@@ -1,54 +1,17 @@
require 'spec_helper'
describe 'home/index.html.haml', :type => "view" do
context "when not logged in" do
before(:each) do
view.stub(:user_signed_in).and_return(false)
view.stub(:current_user).and_return(nil)
render
end
it 'shows the homepage' do
rendered.should contain 'Growstuff'
end
it 'should have signup/login links' do
rendered.should contain 'Sign up'
rendered.should contain 'Log in'
end
it 'should have description' do
render
rendered.should contain 'Growstuff is a community of food gardeners'
rendered.should contain 'We welcome you regardless of your experience, and invite you to be part of our development process.'
end
before(:each) do
render
end
context "logged in" do
before(:each) do
@user = User.create(:email => "growstuff@example.com", :password => "irrelevant")
@user.confirm!
sign_in @user
render
end
it 'should show username' do
rendered.should contain 'You are signed in as'
rendered.should contain 'growstuff@example.com'
end
it 'should show logout link' do
rendered.should contain 'Log out'
end
it 'should have description' do
render
rendered.should contain 'Growstuff is a community of food gardeners'
rendered.should contain 'We welcome you regardless of your experience, and invite you to be part of our development process.'
end
it 'links to the crops page' do
rendered.should contain 'Crops'
end
it 'should have description' do
render
rendered.should contain 'Growstuff is a community of food gardeners'
rendered.should contain 'We welcome you regardless of your experience, and invite you to be part of our development process.'
end
end

View File

@@ -1,8 +1,42 @@
require 'spec_helper'
describe 'layouts/application.html.haml', :type => "view" do
it 'should have links in footer' do
render
rendered.should contain 'About'
context "when not logged in" do
before(:each) do
view.stub(:user_signed_in).and_return(false)
view.stub(:current_user).and_return(nil)
render
end
it 'shows the title' do
rendered.should contain 'Growstuff'
end
it 'should have signup/login links' do
rendered.should contain 'Sign up'
rendered.should contain 'Log in'
end
end
context "logged in" do
before(:each) do
@user = User.create(:email => "growstuff@example.com", :password => "irrelevant")
@user.confirm!
sign_in @user
render
end
it 'should show username' do
rendered.should contain 'You are signed in as'
rendered.should contain 'growstuff@example.com'
end
it 'should show logout link' do
rendered.should contain 'Log out'
end
end
end