diff options
author | Wei Xie <xieconnect@gmail.com> | 2010-06-06 10:14:09 +0800 |
---|---|---|
committer | Hans de Graaff <hans@degraaff.org> | 2010-07-25 09:08:51 +0200 |
commit | 854029152445e65fa67a59d49721801a8ee654df (patch) | |
tree | 4f489226a6e7e45ed8246f55b6b031a7246b2854 | |
parent | import User data from db:seed (diff) | |
download | council-webapp-854029152445e65fa67a59d49721801a8ee654df.tar.gz council-webapp-854029152445e65fa67a59d49721801a8ee654df.tar.bz2 council-webapp-854029152445e65fa67a59d49721801a8ee654df.zip |
Agenda implemented and tested
-rw-r--r-- | app/controllers/agendas_controller.rb | 7 | ||||
-rw-r--r-- | app/models/agenda.rb | 27 | ||||
-rw-r--r-- | app/views/taglibs/auto/rapid/cards.dryml | 11 | ||||
-rw-r--r-- | app/views/taglibs/auto/rapid/forms.dryml | 12 | ||||
-rw-r--r-- | app/views/taglibs/auto/rapid/pages.dryml | 123 | ||||
-rw-r--r-- | db/migrate/20100606022209_create_agendas.rb | 18 | ||||
-rw-r--r-- | db/seeds.rb | 21 | ||||
-rw-r--r-- | features/agenda.feature | 44 | ||||
-rw-r--r-- | features/step_definitions/agenda_steps.rb | 15 | ||||
-rw-r--r-- | features/step_definitions/user_steps.rb | 12 | ||||
-rw-r--r-- | features/support/helper.rb | 15 | ||||
-rw-r--r-- | lib/permission.rb | 16 | ||||
-rw-r--r-- | spec/fixtures/agendas.yml | 18 | ||||
-rw-r--r-- | spec/models/agenda_spec.rb | 27 |
14 files changed, 366 insertions, 0 deletions
diff --git a/app/controllers/agendas_controller.rb b/app/controllers/agendas_controller.rb new file mode 100644 index 0000000..438fff7 --- /dev/null +++ b/app/controllers/agendas_controller.rb @@ -0,0 +1,7 @@ +class AgendasController < ApplicationController + + hobo_model_controller + + auto_actions :all + +end diff --git a/app/models/agenda.rb b/app/models/agenda.rb new file mode 100644 index 0000000..057fc7e --- /dev/null +++ b/app/models/agenda.rb @@ -0,0 +1,27 @@ +require 'permission' + +class Agenda < ActiveRecord::Base + + hobo_model # Don't put anything above this + + fields do + name :string, :required + description :text + timestamps + end + + belongs_to :owner, :class_name => 'User', :creator => true + + validates_presence_of :owner + + # --- Permissions --- # + never_show :owner + + multi_permission(:create, :update, :destroy) do + permitted_for_roles(:admin, :council_member) + end + + def view_permitted?(field) + true + end +end diff --git a/app/views/taglibs/auto/rapid/cards.dryml b/app/views/taglibs/auto/rapid/cards.dryml index 38c8c7f..4186cdc 100644 --- a/app/views/taglibs/auto/rapid/cards.dryml +++ b/app/views/taglibs/auto/rapid/cards.dryml @@ -1,5 +1,16 @@ <!-- AUTOMATICALLY GENERATED FILE - DO NOT EDIT --> +<def tag="card" for="Agenda"> + <card class="agenda" param="default" merge> + <header: param> + <h4 param="heading"><a><name/></a></h4> + </header:> + <body: param> + <a:owner param="creator-link"/> + </body:> + </card> +</def> + <def tag="card" for="Question"> <card class="question" param="default" merge> <header: param> diff --git a/app/views/taglibs/auto/rapid/forms.dryml b/app/views/taglibs/auto/rapid/forms.dryml index a359af6..c57f7b6 100644 --- a/app/views/taglibs/auto/rapid/forms.dryml +++ b/app/views/taglibs/auto/rapid/forms.dryml @@ -1,5 +1,17 @@ <!-- AUTOMATICALLY GENERATED FILE - DO NOT EDIT --> +<def tag="form" for="Agenda"> + <form merge param="default"> + <error-messages param/> + <field-list fields="name, description" param/> + <div param="actions"> + <submit label="#{ht 'agendas.actions.save', :default=>['Save']}" param/><or-cancel param="cancel"/> + </div> + </form> +</def> + + + <def tag="form" for="Question"> <form merge param="default"> <error-messages param/> diff --git a/app/views/taglibs/auto/rapid/pages.dryml b/app/views/taglibs/auto/rapid/pages.dryml index ad1eee4..5b4a00a 100644 --- a/app/views/taglibs/auto/rapid/pages.dryml +++ b/app/views/taglibs/auto/rapid/pages.dryml @@ -5,6 +5,7 @@ <def tag="main-nav"> <navigation class="main-nav" merge-attrs param="default"> <nav-item href="#{base_url}/">Home</nav-item> + <nav-item with="&Agenda"><ht key="agendas.nav_item">Agendas</ht></nav-item> <nav-item with="&Question"><ht key="questions.nav_item">Questions</ht></nav-item> </navigation> </def> @@ -12,6 +13,128 @@ +<!-- ====== Agenda Pages ====== --> + +<def tag="index-page" for="Agenda"> + <page merge title="#{ht 'agendas.index.title', :default=>['Agendas'] }"> + <body: class="index-page agenda" param/> + + <content: param> + <header param="content-header"> + <h2 param="heading"> + <ht key="agendas.index.heading"> + Agendas + </ht> + </h2> + + <p param="count" if> + <ht key="agendas.collection.count" count="&this.size"> + There <count prefix="are"/> + </ht> + </p> + </header> + + <section param="content-body"> + <a action="new" to="&model" param="new-link"> + <ht key="agendas.actions.new">New Agenda</ht> + </a> + + <page-nav param="top-page-nav"/> + + <collection param/> + + <page-nav param="bottom-page-nav"/> + + + </section> + </content:> + </page> +</def> + + +<def tag="new-page" for="Agenda"> + <page merge title="#{ht 'agendas.new.title', :default=>[' New Agenda'] }"> + <body: class="new-page agenda" param/> + + <content: param> + <section param="content-header"> + <h2 param="heading"> + <ht key="agendas.new.heading"> + New Agenda + </ht> + </h2> + </section> + + <section param="content-body"> + <form param> + <submit: label="#{ht 'agendas.actions.create', :default=>['Create Agenda']}"/> + </form> + </section> + </content:> + </page> +</def> + + +<def tag="show-page" for="Agenda"> + <page merge title="#{ht 'agendas.show.title', :default=>['Agenda'] }"> + + <body: class="show-page agenda" param/> + + <content: param> + <header param="content-header"> + <h2 param="heading"> + <ht key="agendas.show.heading" name="&this.respond_to?(:name) ? this.name : ''"> + <name/> + </ht> + </h2> + + <record-flags fields="" param/> + + <a:owner param="creator-link"/> + + <a action="edit" if="&can_edit?" param="edit-link"> + <ht key="agendas.actions.edit" name="&this.respond_to?(:name) ? this.name : ''"> + Edit Agenda + </ht> + </a> + </header> + + <section param="content-body"> + <view:description param="description"/> + </section> + </content:> + + </page> +</def> + + +<def tag="edit-page" for="Agenda"> + <page merge title="#{ht 'agendas.edit.title', :default=>['Edit Agenda'] }"> + + <body: class="edit-page agenda" param/> + + <content:> + <section param="content-header"> + <h2 param="heading"> + <ht key="agendas.edit.heading" name="&this.respond_to?(:name) ? this.name : ''"> + Edit <type-name/> + </ht> + </h2> + <delete-button label="#{ht 'agendas.actions.delete', :default=>['Remove This Agenda']}" param/> + </section> + + <section param="content-body"> + <form param/> + </section> + </content:> + + </page> +</def> + + + + + <!-- ====== Question Pages ====== --> <def tag="index-page" for="Question"> diff --git a/db/migrate/20100606022209_create_agendas.rb b/db/migrate/20100606022209_create_agendas.rb new file mode 100644 index 0000000..14a878d --- /dev/null +++ b/db/migrate/20100606022209_create_agendas.rb @@ -0,0 +1,18 @@ +class CreateAgendas < ActiveRecord::Migration + def self.up + create_table :agendas do |t| + t.string :name + t.text :description + t.datetime :start_at + t.datetime :end_at + t.datetime :created_at + t.datetime :updated_at + t.integer :owner_id + end + add_index :agendas, [:owner_id] + end + + def self.down + drop_table :agendas + end +end diff --git a/db/seeds.rb b/db/seeds.rb index 5882a4b..cd12661 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -31,3 +31,24 @@ users = User.create([ :password => 'developer', :password_confirmation => 'developer'} ]) + +puts 'adding agendas...' +agendas = Agenda.create([ + { :name => 'Go to the Zoo', + :description => 'Disneyland', + :start_at => 15.days.from_now, + :end_at => 16.days.from_now, + :owner_id => users[1].id}, + + { :name => 'hosting a party', + :description => 'HIT', + :start_at => 15.days.from_now, + :end_at => 16.days.from_now, + :owner_id => users[1].id}, + + { :name => 'agenda_test_name', + :description => 'agenda_test_description', + :start_at => 15.days.from_now, + :end_at => 16.days.from_now, + :owner_id => users[1].id} +]) diff --git a/features/agenda.feature b/features/agenda.feature new file mode 100644 index 0000000..2969dc0 --- /dev/null +++ b/features/agenda.feature @@ -0,0 +1,44 @@ +Feature: Basic Agenda Creation + As a council member + I want to use the webapp to create agendas + in order to make my life easier + + Background: + Given agenda "agenda_test_name" exists + + Scenario: Guest operations + When I am on the home page + And I follow "Agendas" + And I follow "agenda_test_name" + Then I should see "agenda_test_name" + And I should not see "Edit Agenda" + + Scenario: Council member creates agenda + Given I visit agendas as a council member + When I follow "New Agenda" + And I fill in "agenda_name" with "another_agenda_name" + And I press "Create Agenda" + Then I should see "created successfully" + When I go to the home page + And I follow "Agendas" + Then I should see "another_agenda_name" + + Scenario: Council member edits agenda + Given I visit agendas as a council member + When I follow "agenda_test_name" + And I follow "Edit Agenda" + And I fill in "agenda_name" with "agenda_name_modified" + And I press "Save" + Then I should see "were saved" + When I go to the home page + And I follow "Agendas" + Then I should see "agenda_name_modified" + + Scenario: Council member deletes agenda + Given I visit agendas as a council member + When I follow "agenda_test_name" + And I follow "Edit Agenda" + And I press "Remove This Agenda" + Then I should see "was deleted" + When I go to the home page + Then I should not see "agenda_modified" diff --git a/features/step_definitions/agenda_steps.rb b/features/step_definitions/agenda_steps.rb new file mode 100644 index 0000000..94a6248 --- /dev/null +++ b/features/step_definitions/agenda_steps.rb @@ -0,0 +1,15 @@ +# agenda creation testing is already covered in other steps. +# let's speed up the test by directly modifying the Model +Given /^agenda "([^\"]*)" exists$/ do |agenda_name| + @agenda = agendas(:agenda_one) + if @agenda.name != agenda_name + @agenda.update_attributes(:name => agenda_name) + end +end + +# avoid repetition in agenda.features +Given /^I visit agendas as a (.+)$/ do |user| + Given "I am logged in as a #{user}" + And 'I am on the home page' + When 'I follow "Agendas"' +end diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb new file mode 100644 index 0000000..1b4c321 --- /dev/null +++ b/features/step_definitions/user_steps.rb @@ -0,0 +1,12 @@ +Given /^I am a visitor$/ do + When 'I am on the home page' + Then 'I should not see "Logged in as"' +end + +Given /^I am logged in as a (.+)$/ do |user| + @user = login_as(user.gsub(/\s/, '_').to_sym) + visit user_login_path + When %Q{I fill in "login" with "#{@user.email_address}"} + And 'I fill in "password" with "kktest3"' + And 'I press "Log in"' +end diff --git a/features/support/helper.rb b/features/support/helper.rb new file mode 100644 index 0000000..f58b53d --- /dev/null +++ b/features/support/helper.rb @@ -0,0 +1,15 @@ +# helper for feature test + +# helper method for user steps +def login_as(role) + user = User.create!( + :name => 'kktest3', + :login => 'kktest3@kktest3.com', + :password => 'kktest3', + :password_confirmation => 'kktest3', + :role => :developer # will be ignored + ) + user.role = role + user.save! + user +end diff --git a/lib/permission.rb b/lib/permission.rb new file mode 100644 index 0000000..9a68a8e --- /dev/null +++ b/lib/permission.rb @@ -0,0 +1,16 @@ +# methods one_permission and multi_permission are originally authored by ahenobarbi. +# Refer to http://github.com/ahenobarbi/Gentoo-Recruiters-App/blob/master/lib/permissions/set.rb + +def one_permission(permission, &block) + define_method("#{permission.to_s}_permitted?", &block) +end + +def multi_permission(*permission_list, &block) + permission_list.flatten.each do |target| + one_permission(target, &block) + end +end + +def permitted_for_roles(*roles) + acting_user.signed_up? and roles.flatten.include?(acting_user.role.to_sym) +end diff --git a/spec/fixtures/agendas.yml b/spec/fixtures/agendas.yml new file mode 100644 index 0000000..141c7cb --- /dev/null +++ b/spec/fixtures/agendas.yml @@ -0,0 +1,18 @@ +agenda_one: + name: Go to the Zoo + description: Disneyland + start_at: <%= 15.days.from_now %> + end_at: <%= 16.days.from_now %> + owner: council_member +agenda_two: + name: hosting a party + description: HIT + start_at: <%= 15.days.from_now %> + end_at: <%= 16.days.from_now %> + owner: council_member +agenda_test_name: + name: agenda_test_name + description: agenda_test_description + start_at: <%= 15.days.from_now %> + end_at: <%= 16.days.from_now %> + owner: council_member diff --git a/spec/models/agenda_spec.rb b/spec/models/agenda_spec.rb new file mode 100644 index 0000000..56f866b --- /dev/null +++ b/spec/models/agenda_spec.rb @@ -0,0 +1,27 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') + +describe Agenda do + before(:each) do + @agenda = agendas(:agenda_one) + end + + it "should allow guest to view" do + @agenda.should be_viewable_by(users(:guest)) + end + + it "should allow council member to create" do + Agenda.new( + :name => 'agenda3', + :description => 'agenda 3' + ).should be_creatable_by(users(:council_member)) + end + + it "should not allow guest to update" do + @agenda.should_not be_updatable_by(users(:guest)) + end + + it "should allow council member to edit" do + agenda = agendas(:agenda_one) + agenda.should be_updatable_by(users(:council_member)) + end +end |