From 0bc2ff25fe853c9e847624b25247ce0ee2ed334c Mon Sep 17 00:00:00 2001 From: Skud Date: Thu, 14 Feb 2013 15:25:15 +1100 Subject: [PATCH] Added roles, but haven't yet hooked them up to CanCan --- app/assets/javascripts/roles.js.coffee | 3 + app/controllers/roles_controller.rb | 83 +++++++++ app/helpers/roles_helper.rb | 2 + app/models/member.rb | 1 + app/models/role.rb | 4 + app/views/roles/_form.html.haml | 16 ++ app/views/roles/edit.html.haml | 7 + app/views/roles/index.html.haml | 21 +++ app/views/roles/new.html.haml | 5 + app/views/roles/show.html.haml | 12 ++ config/routes.rb | 4 +- db/migrate/20130214024117_create_roles.rb | 10 ++ .../20130214034838_add_members_roles_table.rb | 10 ++ db/schema.rb | 16 +- spec/controllers/roles_controller_spec.rb | 164 ++++++++++++++++++ spec/factories/roles.rb | 8 + spec/models/member_spec.rb | 12 ++ spec/models/role_spec.rb | 5 + spec/requests/roles_spec.rb | 11 ++ spec/routing/roles_routing_spec.rb | 35 ++++ spec/views/roles/edit.html.haml_spec.rb | 20 +++ spec/views/roles/index.html.haml_spec.rb | 23 +++ spec/views/roles/new.html.haml_spec.rb | 20 +++ spec/views/roles/show.html.haml_spec.rb | 17 ++ 24 files changed, 506 insertions(+), 3 deletions(-) create mode 100644 app/assets/javascripts/roles.js.coffee create mode 100644 app/controllers/roles_controller.rb create mode 100644 app/helpers/roles_helper.rb create mode 100644 app/models/role.rb create mode 100644 app/views/roles/_form.html.haml create mode 100644 app/views/roles/edit.html.haml create mode 100644 app/views/roles/index.html.haml create mode 100644 app/views/roles/new.html.haml create mode 100644 app/views/roles/show.html.haml create mode 100644 db/migrate/20130214024117_create_roles.rb create mode 100644 db/migrate/20130214034838_add_members_roles_table.rb create mode 100644 spec/controllers/roles_controller_spec.rb create mode 100644 spec/factories/roles.rb create mode 100644 spec/models/role_spec.rb create mode 100644 spec/requests/roles_spec.rb create mode 100644 spec/routing/roles_routing_spec.rb create mode 100644 spec/views/roles/edit.html.haml_spec.rb create mode 100644 spec/views/roles/index.html.haml_spec.rb create mode 100644 spec/views/roles/new.html.haml_spec.rb create mode 100644 spec/views/roles/show.html.haml_spec.rb diff --git a/app/assets/javascripts/roles.js.coffee b/app/assets/javascripts/roles.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/roles.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/ diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb new file mode 100644 index 000000000..239ed65fb --- /dev/null +++ b/app/controllers/roles_controller.rb @@ -0,0 +1,83 @@ +class RolesController < ApplicationController + # GET /roles + # GET /roles.json + def index + @roles = Role.all + + respond_to do |format| + format.html # index.html.erb + format.json { render json: @roles } + end + end + + # GET /roles/1 + # GET /roles/1.json + def show + @role = Role.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.json { render json: @role } + end + end + + # GET /roles/new + # GET /roles/new.json + def new + @role = Role.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @role } + end + end + + # GET /roles/1/edit + def edit + @role = Role.find(params[:id]) + end + + # POST /roles + # POST /roles.json + def create + @role = Role.new(params[:role]) + + respond_to do |format| + if @role.save + format.html { redirect_to @role, notice: 'Role was successfully created.' } + format.json { render json: @role, status: :created, location: @role } + else + format.html { render action: "new" } + format.json { render json: @role.errors, status: :unprocessable_entity } + end + end + end + + # PUT /roles/1 + # PUT /roles/1.json + def update + @role = Role.find(params[:id]) + + respond_to do |format| + if @role.update_attributes(params[:role]) + format.html { redirect_to @role, notice: 'Role was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @role.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /roles/1 + # DELETE /roles/1.json + def destroy + @role = Role.find(params[:id]) + @role.destroy + + respond_to do |format| + format.html { redirect_to roles_url } + format.json { head :no_content } + end + end +end diff --git a/app/helpers/roles_helper.rb b/app/helpers/roles_helper.rb new file mode 100644 index 000000000..6b6b6cc22 --- /dev/null +++ b/app/helpers/roles_helper.rb @@ -0,0 +1,2 @@ +module RolesHelper +end diff --git a/app/models/member.rb b/app/models/member.rb index 436288e3a..4054cfa73 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -6,6 +6,7 @@ class Member < ActiveRecord::Base has_many :comments, :foreign_key => 'author_id' has_many :gardens, :foreign_key => 'owner_id' has_many :forums, :foreign_key => 'owner_id' + has_and_belongs_to_many :roles # Include default devise modules. Others available are: # :token_authenticatable, :confirmable, diff --git a/app/models/role.rb b/app/models/role.rb new file mode 100644 index 000000000..62ece9943 --- /dev/null +++ b/app/models/role.rb @@ -0,0 +1,4 @@ +class Role < ActiveRecord::Base + attr_accessible :description, :name, :members + has_and_belongs_to_many :members +end diff --git a/app/views/roles/_form.html.haml b/app/views/roles/_form.html.haml new file mode 100644 index 000000000..954a2f6a0 --- /dev/null +++ b/app/views/roles/_form.html.haml @@ -0,0 +1,16 @@ += form_for @role do |f| + - if @role.errors.any? + #error_explanation + %h2= "#{pluralize(@role.errors.count, "error")} prohibited this role from being saved:" + %ul + - @role.errors.full_messages.each do |msg| + %li= msg + + .field + = f.label :name + = f.text_field :name + .field + = f.label :description + = f.text_area :description + .actions + = f.submit 'Save' diff --git a/app/views/roles/edit.html.haml b/app/views/roles/edit.html.haml new file mode 100644 index 000000000..427975d14 --- /dev/null +++ b/app/views/roles/edit.html.haml @@ -0,0 +1,7 @@ +%h1 Editing role + += render 'form' + += link_to 'Show', @role +\| += link_to 'Back', roles_path diff --git a/app/views/roles/index.html.haml b/app/views/roles/index.html.haml new file mode 100644 index 000000000..c503b1284 --- /dev/null +++ b/app/views/roles/index.html.haml @@ -0,0 +1,21 @@ +%h1 Listing roles + +%table + %tr + %th Name + %th Description + %th + %th + %th + + - @roles.each do |role| + %tr + %td= role.name + %td= role.description + %td= link_to 'Show', role + %td= link_to 'Edit', edit_role_path(role) + %td= link_to 'Destroy', role, method: :delete, data: { confirm: 'Are you sure?' } + +%br + += link_to 'New Role', new_role_path diff --git a/app/views/roles/new.html.haml b/app/views/roles/new.html.haml new file mode 100644 index 000000000..6e07588dd --- /dev/null +++ b/app/views/roles/new.html.haml @@ -0,0 +1,5 @@ +%h1 New role + += render 'form' + += link_to 'Back', roles_path diff --git a/app/views/roles/show.html.haml b/app/views/roles/show.html.haml new file mode 100644 index 000000000..7bd0488c7 --- /dev/null +++ b/app/views/roles/show.html.haml @@ -0,0 +1,12 @@ +%p#notice= notice + +%p + %b Name: + = @role.name +%p + %b Description: + = @role.description + += link_to 'Edit', edit_role_path(@role) +\| += link_to 'Back', roles_path diff --git a/config/routes.rb b/config/routes.rb index 4577680c5..8e19bc41b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,4 @@ Growstuff::Application.routes.draw do - resources :forums - devise_for :members, :controllers => { :registrations => "registrations" } @@ -11,6 +9,8 @@ Growstuff::Application.routes.draw do resources :crops resources :members resources :comments + resources :roles + resources :forums get "home/index" diff --git a/db/migrate/20130214024117_create_roles.rb b/db/migrate/20130214024117_create_roles.rb new file mode 100644 index 000000000..8ccaf5ca6 --- /dev/null +++ b/db/migrate/20130214024117_create_roles.rb @@ -0,0 +1,10 @@ +class CreateRoles < ActiveRecord::Migration + def change + create_table :roles do |t| + t.string :name, :null => false + t.text :description + + t.timestamps + end + end +end diff --git a/db/migrate/20130214034838_add_members_roles_table.rb b/db/migrate/20130214034838_add_members_roles_table.rb new file mode 100644 index 000000000..433b179f3 --- /dev/null +++ b/db/migrate/20130214034838_add_members_roles_table.rb @@ -0,0 +1,10 @@ +class AddMembersRolesTable < ActiveRecord::Migration + def change + create_table :members_roles do |t| + t.references :member + t.references :role + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 55fa11bd6..8f44ffbf2 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130213015708) do +ActiveRecord::Schema.define(:version => 20130214034838) do create_table "comments", :force => true do |t| t.integer "post_id", :limit => 255, :null => false @@ -87,6 +87,13 @@ ActiveRecord::Schema.define(:version => 20130213015708) do add_index "members", ["slug"], :name => "index_users_on_slug", :unique => true add_index "members", ["unlock_token"], :name => "index_users_on_unlock_token", :unique => true + create_table "members_roles", :force => true do |t| + t.integer "member_id" + t.integer "role_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "plantings", :force => true do |t| t.integer "garden_id", :null => false t.integer "crop_id", :null => false @@ -113,6 +120,13 @@ ActiveRecord::Schema.define(:version => 20130213015708) do add_index "posts", ["created_at", "author_id"], :name => "index_updates_on_created_at_and_user_id" add_index "posts", ["slug"], :name => "index_updates_on_slug", :unique => true + create_table "roles", :force => true do |t| + t.string "name", :null => false + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "scientific_names", :force => true do |t| t.string "scientific_name", :null => false t.integer "crop_id", :null => false diff --git a/spec/controllers/roles_controller_spec.rb b/spec/controllers/roles_controller_spec.rb new file mode 100644 index 000000000..99f6e345c --- /dev/null +++ b/spec/controllers/roles_controller_spec.rb @@ -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 RolesController do + + # This should return the minimal set of attributes required to create a valid + # Role. As you add validations to Role, be sure to + # update the return value of this method accordingly. + def valid_attributes + { "name" => "MyString" } + 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 + # RolesController. Be sure to keep this updated too. + def valid_session + {} + end + + describe "GET index" do + it "assigns all roles as @roles" do + role = Role.create! valid_attributes + get :index, {}, valid_session + assigns(:roles).should eq([role]) + end + end + + describe "GET show" do + it "assigns the requested role as @role" do + role = Role.create! valid_attributes + get :show, {:id => role.to_param}, valid_session + assigns(:role).should eq(role) + end + end + + describe "GET new" do + it "assigns a new role as @role" do + get :new, {}, valid_session + assigns(:role).should be_a_new(Role) + end + end + + describe "GET edit" do + it "assigns the requested role as @role" do + role = Role.create! valid_attributes + get :edit, {:id => role.to_param}, valid_session + assigns(:role).should eq(role) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Role" do + expect { + post :create, {:role => valid_attributes}, valid_session + }.to change(Role, :count).by(1) + end + + it "assigns a newly created role as @role" do + post :create, {:role => valid_attributes}, valid_session + assigns(:role).should be_a(Role) + assigns(:role).should be_persisted + end + + it "redirects to the created role" do + post :create, {:role => valid_attributes}, valid_session + response.should redirect_to(Role.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved role as @role" do + # Trigger the behavior that occurs when invalid params are submitted + Role.any_instance.stub(:save).and_return(false) + post :create, {:role => { "name" => "invalid value" }}, valid_session + assigns(:role).should be_a_new(Role) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Role.any_instance.stub(:save).and_return(false) + post :create, {:role => { "name" => "invalid value" }}, valid_session + response.should render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + it "updates the requested role" do + role = Role.create! valid_attributes + # Assuming there are no other roles in the database, this + # specifies that the Role created on the previous line + # receives the :update_attributes message with whatever params are + # submitted in the request. + Role.any_instance.should_receive(:update_attributes).with({ "name" => "MyString" }) + put :update, {:id => role.to_param, :role => { "name" => "MyString" }}, valid_session + end + + it "assigns the requested role as @role" do + role = Role.create! valid_attributes + put :update, {:id => role.to_param, :role => valid_attributes}, valid_session + assigns(:role).should eq(role) + end + + it "redirects to the role" do + role = Role.create! valid_attributes + put :update, {:id => role.to_param, :role => valid_attributes}, valid_session + response.should redirect_to(role) + end + end + + describe "with invalid params" do + it "assigns the role as @role" do + role = Role.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Role.any_instance.stub(:save).and_return(false) + put :update, {:id => role.to_param, :role => { "name" => "invalid value" }}, valid_session + assigns(:role).should eq(role) + end + + it "re-renders the 'edit' template" do + role = Role.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Role.any_instance.stub(:save).and_return(false) + put :update, {:id => role.to_param, :role => { "name" => "invalid value" }}, valid_session + response.should render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested role" do + role = Role.create! valid_attributes + expect { + delete :destroy, {:id => role.to_param}, valid_session + }.to change(Role, :count).by(-1) + end + + it "redirects to the roles list" do + role = Role.create! valid_attributes + delete :destroy, {:id => role.to_param}, valid_session + response.should redirect_to(roles_url) + end + end + +end diff --git a/spec/factories/roles.rb b/spec/factories/roles.rb new file mode 100644 index 000000000..8b413294e --- /dev/null +++ b/spec/factories/roles.rb @@ -0,0 +1,8 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :role do + name "Moderator" + description "These people moderate the forums" + end +end diff --git a/spec/models/member_spec.rb b/spec/models/member_spec.rb index 1f2f8ea41..57fa46ef6 100644 --- a/spec/models/member_spec.rb +++ b/spec/models/member_spec.rb @@ -90,4 +90,16 @@ describe 'member' do end end + context 'roles' do + before(:each) do + @member = FactoryGirl.create(:member) + @role = FactoryGirl.create(:role) + @member.roles << @role + end + + it 'has a role' do + @member.roles.first.should eq @role + end + end + end diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb new file mode 100644 index 000000000..b575576c3 --- /dev/null +++ b/spec/models/role_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Role do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/roles_spec.rb b/spec/requests/roles_spec.rb new file mode 100644 index 000000000..3ddd05451 --- /dev/null +++ b/spec/requests/roles_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Roles" do + describe "GET /roles" do + it "works! (now write some real specs)" do + # Run the generator again with the --webrat flag if you want to use webrat methods/matchers + get roles_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/roles_routing_spec.rb b/spec/routing/roles_routing_spec.rb new file mode 100644 index 000000000..4084a6e7e --- /dev/null +++ b/spec/routing/roles_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe RolesController do + describe "routing" do + + it "routes to #index" do + get("/roles").should route_to("roles#index") + end + + it "routes to #new" do + get("/roles/new").should route_to("roles#new") + end + + it "routes to #show" do + get("/roles/1").should route_to("roles#show", :id => "1") + end + + it "routes to #edit" do + get("/roles/1/edit").should route_to("roles#edit", :id => "1") + end + + it "routes to #create" do + post("/roles").should route_to("roles#create") + end + + it "routes to #update" do + put("/roles/1").should route_to("roles#update", :id => "1") + end + + it "routes to #destroy" do + delete("/roles/1").should route_to("roles#destroy", :id => "1") + end + + end +end diff --git a/spec/views/roles/edit.html.haml_spec.rb b/spec/views/roles/edit.html.haml_spec.rb new file mode 100644 index 000000000..2e2f66c7b --- /dev/null +++ b/spec/views/roles/edit.html.haml_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe "roles/edit" do + before(:each) do + @role = assign(:role, stub_model(Role, + :name => "MyString", + :description => "MyText" + )) + end + + it "renders the edit role form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => roles_path(@role), :method => "post" do + assert_select "input#role_name", :name => "role[name]" + assert_select "textarea#role_description", :name => "role[description]" + end + end +end diff --git a/spec/views/roles/index.html.haml_spec.rb b/spec/views/roles/index.html.haml_spec.rb new file mode 100644 index 000000000..508f29017 --- /dev/null +++ b/spec/views/roles/index.html.haml_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe "roles/index" do + before(:each) do + assign(:roles, [ + stub_model(Role, + :name => "Name", + :description => "MyText" + ), + stub_model(Role, + :name => "Name", + :description => "MyText" + ) + ]) + end + + it "renders a list of roles" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "tr>td", :text => "Name".to_s, :count => 2 + assert_select "tr>td", :text => "MyText".to_s, :count => 2 + end +end diff --git a/spec/views/roles/new.html.haml_spec.rb b/spec/views/roles/new.html.haml_spec.rb new file mode 100644 index 000000000..e15e14226 --- /dev/null +++ b/spec/views/roles/new.html.haml_spec.rb @@ -0,0 +1,20 @@ +require 'spec_helper' + +describe "roles/new" do + before(:each) do + assign(:role, stub_model(Role, + :name => "MyString", + :description => "MyText" + ).as_new_record) + end + + it "renders new role form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => roles_path, :method => "post" do + assert_select "input#role_name", :name => "role[name]" + assert_select "textarea#role_description", :name => "role[description]" + end + end +end diff --git a/spec/views/roles/show.html.haml_spec.rb b/spec/views/roles/show.html.haml_spec.rb new file mode 100644 index 000000000..389a5c8c3 --- /dev/null +++ b/spec/views/roles/show.html.haml_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe "roles/show" do + before(:each) do + @role = assign(:role, stub_model(Role, + :name => "Name", + :description => "MyText" + )) + end + + it "renders attributes in

" do + render + # Run the generator again with the --webrat flag if you want to use webrat matchers + rendered.should match(/Name/) + rendered.should match(/MyText/) + end +end