Browse files

Add Competitions

  • Loading branch information...
1 parent 4b0cb89 commit fa1752a067377ec134720c2df5c95e0563267cc0 @dirksiemers committed Jun 8, 2012
View
2 Guardfile
@@ -21,7 +21,7 @@ guard 'rspec', :version => 2, :all_after_pass => false, :cli => '--drb' do
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
- #watch('config/routes.rb') { "spec/routing" }
+ watch('config/routes.rb') { "spec" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara request specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
View
3 app/assets/javascripts/competitions.js.coffee
@@ -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
3 app/assets/stylesheets/competitions.css.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the Competitions controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
View
12 app/assets/stylesheets/custom.css.scss
@@ -240,4 +240,16 @@ aside {
height: 100px;
margin-bottom: 5px;
}
+}
+
+/* competitions */
+
+.competitions {
+ list-style: none;
+ margin: 10px 0 0 0;
+
+ li {
+ padding: 10px 0;
+ border-top: 1px solid #e8e8e8;
+ }
}
View
60 app/controllers/competitions_controller.rb
@@ -0,0 +1,60 @@
+class CompetitionsController < ApplicationController
+ before_filter :signed_in_user, except: [:index, :show]
+ before_filter :admin_user, except: [:index, :show]
+
+ def index
+ @competitions = Competition.paginate(page: params[:page])
+ end
+
+ def show
+ @competition = Competition.find(params[:id])
+ end
+
+ def new
+ @competition = Competition.new
+ end
+
+ def create
+ @competition = Competition.new(params[:competition])
+ if @competition.save
+ flash[:success] = "Successfully created a new Competition!"
+ redirect_to @competition
+ else
+ render 'new'
+ end
+ end
+
+ def edit
+ @competition = Competition.find(params[:id])
+ end
+
+ def update
+ @competition = Competition.find(params[:id])
+ if @competition.update_attributes(params[:competition])
+ flash[:success] = "Competition updated"
+ redirect_to @competition
+ else
+ render 'edit'
+ end
+ end
+
+ def destroy
+ Competition.find(params[:id]).destroy
+ flash[:success] = "Competition destroyed."
+ redirect_to competitions_path
+ end
+
+ private
+
+ def signed_in_user
+ unless signed_in?
+ store_location
+ redirect_to signin_path, notice: "Please sign in."
+ end
+ end
+
+ def admin_user
+ redirect_to(root_path) unless current_user.admin?
+ end
+
+end
View
2 app/helpers/competitions_helper.rb
@@ -0,0 +1,2 @@
+module CompetitionsHelper
+end
View
5 app/models/competition.rb
@@ -0,0 +1,5 @@
+class Competition < ActiveRecord::Base
+ attr_accessible :name
+
+ validates :name, presence: true, length: { maximum: 50 }, uniqueness: { case_sensitive: false }
+end
View
7 app/views/competitions/_competition.html.erb
@@ -0,0 +1,7 @@
+<li>
+ <%= link_to competition.name, competition %>
+ <% if signed_in? && current_user.admin? %>
+ | <%= link_to "edit", edit_competition_path(competition) %>,
+ <%= link_to "delete", competition, method: :delete, confirm: "You sure?" %>
+ <% end %>
+</li>
View
4 app/views/competitions/_fields.html.erb
@@ -0,0 +1,4 @@
+<%= render 'shared/error_messages', object: f.object %>
+
+<%= f.label :name %>
+<%= f.text_field :name %>
View
11 app/views/competitions/edit.html.erb
@@ -0,0 +1,11 @@
+<% provide(:title, "Edit Competition") %>
+<h1>Update Competition</h1>
+
+<div class="row">
+ <div class="span6 offset3">
+ <%= form_for(@competition) do |f| %>
+ <%= render 'fields', f: f %>
+ <%= f.submit "Save changes", class: "btn btn-large btn-primary" %>
+ <% end %>
+ </div>
+</div>
View
22 app/views/competitions/index.html.erb
@@ -0,0 +1,22 @@
+<% provide(:title, 'All Competitions') %>
+<div class="row">
+ <aside class="span4">
+ <section>
+ <h1>All Competitions</h1>
+ </section>
+ <% if signed_in? && current_user.admin? %>
+ <section>
+ <%= link_to "Create new Competition", new_competition_path, class: "btn btn-large btn-primary" %>
+ </section>
+ <% end %>
+ </aside>
+ <div class="span8">
+ <% if @competitions.any? %>
+ <h3>Competitions (<%= @competitions.count %>)</h3>
+ <ol class="competitions">
+ <%= render @competitions %>
+ </ol>
+ <%= will_paginate @competitions %>
+ <% end %>
+ </div>
+</div>
View
11 app/views/competitions/new.html.erb
@@ -0,0 +1,11 @@
+<% provide(:title, 'New Competition') %>
+<h1>New Competition</h1>
+
+<div class="row">
+ <div class="span6 offset3">
+ <%= form_for(@competition) do |f| %>
+ <%= render 'fields', f: f %>
+ <%= f.submit "Create", class: "btn btn-large btn-primary" %>
+ <% end %>
+ </div>
+</div>
View
12 app/views/competitions/show.html.erb
@@ -0,0 +1,12 @@
+<% provide(:title, @competition.name) %>
+<div class="row">
+ <aside class="span4">
+ <section>
+ <h1>
+ <%= @competition.name %>
+ </h1>
+ </section>
+ </aside>
+ <div class="span8">
+ </div>
+</div>
View
1 app/views/layouts/_header.html.erb
@@ -6,6 +6,7 @@
<ul class="nav pull-right">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Help", help_path %></li>
+ <li><%= link_to "Competitions", competitions_path %></li>
<% if signed_in? %>
<li><%= link_to "Users", users_path %></li>
<li id="fat-menu" class="dropdown">
View
3 app/views/static_pages/home.html.erb
@@ -26,8 +26,7 @@
sample application.
</h2>
- <%= link_to "Sign up now!", signup_path,
- class: "btn btn-large btn-primary" %>
+ <%= link_to "Sign up now!", signup_path, class: "btn btn-large btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "Rails"), 'http://rubyonrails.org/' %>
View
1 config/routes.rb
@@ -8,6 +8,7 @@
resources :sessions, only: [:new, :create, :destroy]
resources :microposts, only: [:create, :destroy]
resources :relationships, only: [:create, :destroy]
+ resources :competitions
root to: 'static_pages#home'
View
10 db/migrate/20120607100311_create_competitions.rb
@@ -0,0 +1,10 @@
+class CreateCompetitions < ActiveRecord::Migration
+ def change
+ create_table :competitions do |t|
+ t.string :name
+ t.string :logo
+
+ t.timestamps
+ end
+ end
+end
View
9 db/schema.rb
@@ -11,7 +11,14 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120606142445) do
+ActiveRecord::Schema.define(:version => 20120607100311) do
+
+ create_table "competitions", :force => true do |t|
+ t.string "name"
+ t.string "logo"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
create_table "microposts", :force => true do |t|
t.string "content"
View
4 spec/factories.rb
@@ -14,4 +14,8 @@
content "Lorem ipsum"
user
end
+
+ factory :competition do
+ sequence(:name) { |n| "Championship #{n}" }
+ end
end
View
28 spec/models/competition_spec.rb
@@ -0,0 +1,28 @@
+require 'spec_helper'
+
+describe Micropost do
+
+ let(:competition) { FactoryGirl.create(:competition) }
+ before { @competition = Competition.new(name: "EM 2012") }
+
+ subject { @competition }
+
+ it { should respond_to(:name) }
+ it { should be_valid }
+
+ describe "with blank name" do
+ before { @competition.name = " " }
+ it { should_not be_valid }
+ end
+
+ describe "when name is already taken" do
+ before do
+ competition_with_same_name = @competition.dup
+ competition_with_same_name.name = @competition.name.upcase
+ competition_with_same_name.save
+ end
+
+ it { should_not be_valid }
+ end
+
+end
View
51 spec/requests/authentication_pages_spec.rb
@@ -133,6 +133,57 @@
end
end
+ describe "in the Competitions controller" do
+
+ let(:competition) { FactoryGirl.create(:competition) }
+
+ describe "visiting the competition index" do
+ before { visit competitions_path }
+ it { should have_selector('title', text: 'All Competitions') }
+ end
+
+ describe "visiting the show page" do
+ before { visit competition_path(competition) }
+ it { should have_selector('title', text: competition.name) }
+ end
+
+ describe "visiting the edit page" do
+ before { visit edit_competition_path(competition) }
+ it { should have_selector('title', text: 'Sign in') }
+ end
+
+ describe "submitting to the update action" do
+ before { put competition_path(competition) }
+ specify { response.should redirect_to(signin_path) }
+ end
+
+ describe "submitting to the create action" do
+ before { post competitions_path }
+ specify { response.should redirect_to(signin_path) }
+ end
+
+ describe "submitting to the destroy action" do
+ before { delete competition_path(competition) }
+ specify { response.should redirect_to(signin_path) }
+ end
+
+ describe "as non-admin user" do
+ let(:non_admin) { FactoryGirl.create(:user) }
+
+ before { sign_in non_admin }
+
+ describe "submitting to the create action" do
+ before { post competitions_path }
+ specify { response.should redirect_to(root_path) }
+ end
+
+ describe "submitting a DELETE request to the Competitions#destroy action" do
+ before { delete competition_path(FactoryGirl.create(:competition)) }
+ specify { response.should redirect_to(root_path) }
+ end
+ end
+ end
+
end
describe "as wrong user" do
View
109 spec/requests/competition_pages_spec.rb
@@ -0,0 +1,109 @@
+require 'spec_helper'
+
+describe "Competition pages" do
+
+ subject { page }
+
+ describe "create" do
+
+ let(:user) { FactoryGirl.create(:user) }
+
+ before(:each) do
+ sign_in user
+ visit competitions_path
+ end
+
+ let(:submit) { "Create" }
+
+ it { should_not have_link('Create new Competition') }
+
+ describe "as an admin user" do
+ let(:admin) { FactoryGirl.create(:admin) }
+ before do
+ sign_in admin
+ visit competitions_path
+ end
+
+ before { click_link('Create new Competition') }
+
+ describe "with invalid information" do
+ it "should not create a competition" do
+ expect { click_button submit }.not_to change(Competition, :count)
+ end
+ describe "after submission" do
+ before { click_button submit }
+
+ it { should have_selector('title', text: 'New Competition') }
+ it { should have_content('error') }
+ end
+ end
+
+ describe "with valid information" do
+ before do
+ fill_in "Name", with: "WM 2018"
+ end
+
+ it "should create a competition" do
+ expect { click_button submit }.to change(Competition, :count).by(1)
+ end
+ describe "after saving the user" do
+ before { click_button submit }
+ let(:competition) { Competition.find_by_name('WM 2018') }
+
+ it { should have_selector('title', text: competition.name) }
+ it { should have_selector('div.alert.alert-success', text: 'Successfully created a new Competition!') }
+ end
+ end
+ end
+ end
+
+ describe "index" do
+ let(:competition) { FactoryGirl.create(:competition) }
+
+ before(:all) { 31.times { FactoryGirl.create(:competition) } }
+ after(:all) { Competition.delete_all }
+
+ before { visit competitions_path }
+
+ it { should have_selector('title', text: 'All Competitions') }
+ it { should have_selector('h1', text: 'All Competitions') }
+
+ describe "pagination" do
+
+ it { should have_selector('div.pagination') }
+
+ it "should list each competition" do
+ Competition.paginate(page: 1).each do |competition|
+ page.should have_selector('li', text: competition.name)
+ end
+ end
+ end
+
+ describe "delete links" do
+
+ let(:user) { FactoryGirl.create(:user) }
+
+ before(:each) do
+ sign_in user
+ visit competitions_path
+ end
+
+ it { should_not have_link('delete') }
+
+ describe "as an admin user" do
+ let(:admin) { FactoryGirl.create(:admin) }
+ before do
+ sign_in admin
+ visit competitions_path
+ end
+
+ it { should have_link('delete', href: competition_path(Competition.first)) }
+ it "should be able to delete a competition" do
+ expect { click_link('delete') }.to change(Competition, :count).by(-1)
+ end
+ end
+ end
+
+ end
+
+end

0 comments on commit fa1752a

Please sign in to comment.