diff --git a/Gemfile b/Gemfile index 6f6c5a2..c93203d 100644 --- a/Gemfile +++ b/Gemfile @@ -9,7 +9,7 @@ gem 'rails', '3.1.1' gem 'mysql2' gem 'devise', '~> 1.4.5' gem 'cancan', '~> 1.6.5' -# gem "meta_where", "~> 1.0" # squeel ? +gem "squeel", "~> 0.9.3" gem 'sentient_user', '~> 0.3.2' gem 'active_scaffold', '~> 3.1.0', :git => 'https://github.com/activescaffold/active_scaffold.git' # :path => '/home/clyfe/dev/active_scaffold' gem 'pjax_rails', '~> 0.1.10' diff --git a/Gemfile.lock b/Gemfile.lock index cba9cce..f81af98 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,9 +6,9 @@ GIT GIT remote: https://github.com/activescaffold/active_scaffold.git - revision: 75abf52219da6015e76a9bd9115f80134a384d69 + revision: 7ece16b812891b155818ba466c4490b631bccffb specs: - active_scaffold (3.1.11) + active_scaffold (3.1.13) rails (~> 3.1.0) GEM @@ -62,7 +62,7 @@ GEM rack-test (>= 0.5.4) selenium-webdriver (~> 2.0) xpath (~> 0.1.4) - childprocess (0.2.3) + childprocess (0.2.4) ffi (~> 1.0.6) chunky_png (1.2.5) coffee-rails (3.1.1) @@ -71,13 +71,13 @@ GEM coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.1.3) - compass (0.12.alpha.2) + coffee-script-source (1.2.0) + compass (0.12.alpha.3) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) daemons (1.0.10) - dalli (1.1.3) + dalli (1.1.4) database_cleaner (0.6.7) devise (1.4.9) bcrypt-ruby (~> 3.0) @@ -85,7 +85,7 @@ GEM warden (~> 1.0.3) diff-lcs (1.1.3) erubis (2.7.0) - execjs (1.2.9) + execjs (1.2.13) multi_json (~> 1.0) factory_girl (2.3.2) activesupport @@ -97,20 +97,21 @@ GEM ffi (1.0.11) fssm (0.2.7) gem_plugin (0.2.3) - guard (0.8.8) + guard (0.9.4) + ffi (>= 0.5.0) thor (~> 0.14.6) guard-rspec (0.4.5) guard (>= 0.4.0) guard-spork (0.3.2) guard (>= 0.8.4) spork (>= 0.8.4) - highline (1.6.8) + highline (1.6.9) hike (1.2.1) i18n (0.6.0) jquery-rails (1.0.19) railties (~> 3.0) thor (~> 0.14) - json (1.6.2) + json (1.6.4) libnotify (0.5.9) libv8 (3.3.10.4) mail (2.3.0) @@ -123,7 +124,7 @@ GEM daemons (~> 1.0.10) gem_plugin (~> 0.2.3) multi_json (1.0.4) - mysql2 (0.3.10) + mysql2 (0.3.11) net-scp (1.0.4) net-ssh (>= 1.99.1) net-sftp (2.0.5) @@ -138,6 +139,8 @@ GEM orm_adapter (0.0.5) pjax_rails (0.1.10) jquery-rails + polyamorous (0.5.0) + activerecord (~> 3.0) polyglot (0.3.3) rack (1.3.5) rack-cache (1.1) @@ -169,7 +172,7 @@ GEM rb-fsevent (0.4.3.1) rb-inotify (0.8.8) ffi (>= 0.5.0) - rdoc (3.11) + rdoc (3.12) json (~> 1.4) rspec (2.6.0) rspec-core (~> 2.6.0) @@ -185,13 +188,13 @@ GEM railties (~> 3.0) rspec (~> 2.6.0) rubyzip (0.9.5) - sass (3.1.11) + sass (3.1.12) sass-rails (3.1.5) actionpack (~> 3.1.0) railties (~> 3.1.0) sass (~> 3.1.10) tilt (~> 1.3.2) - selenium-webdriver (2.14.0) + selenium-webdriver (2.15.0) childprocess (>= 0.2.1) ffi (~> 1.0.9) multi_json (~> 1.0.4) @@ -202,6 +205,10 @@ GEM hike (~> 1.2) rack (~> 1.0) tilt (!= 1.3.0, ~> 1.1) + squeel (0.9.3) + activerecord (~> 3.0) + activesupport (~> 3.0) + polyamorous (~> 0.5.0) therubyracer (0.9.9) libv8 (~> 3.3.10) thor (0.14.6) @@ -210,7 +217,7 @@ GEM polyglot polyglot (>= 0.3.1) tzinfo (0.3.31) - uglifier (1.1.0) + uglifier (1.2.1) execjs (>= 0.3.0) multi_json (>= 1.0.2) warden (1.0.6) @@ -251,6 +258,7 @@ DEPENDENCIES sass-rails (~> 3.1.0) sentient_user (~> 0.3.2) spork (~> 0.9.0.rc) + squeel (~> 0.9.3) therubyracer uglifier validates_hostname (~> 1.0.0)! diff --git a/app/assets/stylesheets/overrides.css.erb b/app/assets/stylesheets/overrides.css.erb index 6094dfe..959c3b9 100644 --- a/app/assets/stylesheets/overrides.css.erb +++ b/app/assets/stylesheets/overrides.css.erb @@ -14,6 +14,11 @@ text-shadow: none; } +#main .block .content .active-scaffold th p { + font: bold 11px arial, sans-serif; + text-shadow: none; +} + body.errors #main .inner { margin-top: 15px; } diff --git a/app/controllers/domains_controller.rb b/app/controllers/domains_controller.rb index d705d09..161b3a8 100644 --- a/app/controllers/domains_controller.rb +++ b/app/controllers/domains_controller.rb @@ -2,15 +2,16 @@ class DomainsController < ApplicationController active_scaffold :domain do |conf| conf.columns = [:name, :ip, :records, :soa_record, :ns_records] - conf.list.columns = [:name, :records] + conf.list.columns = [:name, :records, :permissions] conf.create.columns = [:name, :ip, :soa_record, :ns_records] conf.update.columns = [:name, :soa_record] conf.columns[:name].description = 'Ex. "domain.com"' conf.columns[:ip].description = 'Ex. "10.10.5.12", optional IP to associate your domain with' conf.columns[:ns_records].show_blank_record = false + conf.columns[:permissions].label = 'Sharing' conf.actions.exclude :show conf.list.sorting = {:name => :asc} - conf.create.link.label = "Add Domain" + conf.create.link.label = 'Add Domain' # conf.columns[:records].label = 'All Records' end @@ -21,6 +22,12 @@ class DomainsController < ApplicationController super @record.setup(current_user.email) end + + def new_model + record = super + record.user_id = current_user.id + record + end def before_create_save(record) record.type = 'NATIVE' diff --git a/app/controllers/permissions_controller.rb b/app/controllers/permissions_controller.rb new file mode 100644 index 0000000..75d2751 --- /dev/null +++ b/app/controllers/permissions_controller.rb @@ -0,0 +1,12 @@ +class PermissionsController < ApplicationController + active_scaffold :permission do |conf| + conf.actions.exclude :show + conf.columns = [:domain, :user, :user_email] + conf.list.columns = [:domain, :user, :user_email] + conf.create.columns = [:domain, :user_email] + conf.update.columns = [:domain, :user_email] + conf.columns[:user_email].form_ui = :virtual + conf.columns[:user_email].description = 'user\'s email address, to share with. Ex. jhon.doe@domain.com' + end + before_filter :ensure_nested_under_domain +end \ No newline at end of file diff --git a/app/helpers/permissions_helper.rb b/app/helpers/permissions_helper.rb new file mode 100644 index 0000000..88361be --- /dev/null +++ b/app/helpers/permissions_helper.rb @@ -0,0 +1,2 @@ +module PermissionsHelper +end \ No newline at end of file diff --git a/app/models/ability.rb b/app/models/ability.rb index 1d15d8a..8bcadc9 100644 --- a/app/models/ability.rb +++ b/app/models/ability.rb @@ -17,6 +17,12 @@ class Ability # can manage his hosts can :manage, A, :user_id => user.id #, :domain => {:name => Settings.host_domains} + # can manage permissions for his domains + can :manage, Permission, :domain => {:user_id => user.id} + + # can manage shared domains and records + can :manage, Domain, :permissions.outer => {:user_id => user.id} + can :manage, Record, :domain => {:permissions.outer => {:user_id => user.id}} end # See the wiki for details: https://github.com/ryanb/cancan/wiki/Defining-Abilities diff --git a/app/models/domain.rb b/app/models/domain.rb index 77df24f..d890106 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -9,6 +9,7 @@ class Domain < ActiveRecord::Base belongs_to :user, :inverse_of => :domain has_many :records, :inverse_of => :domain, :dependent => :destroy + has_many :permissions, :inverse_of => :domain, :dependent => :destroy cattr_reader :types @@types = ['NATIVE', 'MASTER', 'SLAVE', 'SUPERSLAVE'] diff --git a/app/models/permission.rb b/app/models/permission.rb new file mode 100644 index 0000000..c90a726 --- /dev/null +++ b/app/models/permission.rb @@ -0,0 +1,30 @@ +class Permission < ActiveRecord::Base + belongs_to :domain, :inverse_of => :permissions + belongs_to :user, :inverse_of => :permissions + + validates :domain_id, :presence => true + validates :user_id, :presence => true, :uniqueness => { + :scope => :domain_id, + :message => "already is permitted" + } + validates :user, :presence => { + :if => lambda {@user_email.present?}, + :message => "with given email was not found" + } + validate do + errors[:user] = 'cannot be yourself' if user_id == domain.user_id + end + + def user_email + @user_email || user.try(:email) + end + + def user_email=(email) + @user_email = email + self.user = User.find_by_email(email) + end + + def to_label + user.try(:email) || @user_email || '-' + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 0b6f1ad..3c64845 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,6 +18,7 @@ class User < ActiveRecord::Base has_many :domains, :inverse_of => :user, :dependent => :destroy has_many :records, :inverse_of => :user, :dependent => :destroy + has_many :permissions, :inverse_of => :user, :dependent => :destroy def name "#{first_name} #{last_name}" diff --git a/app/views/domains/_list_record_columns.html.erb b/app/views/domains/_list_record_columns.html.erb index e020c50..d9f80a1 100644 --- a/app/views/domains/_list_record_columns.html.erb +++ b/app/views/domains/_list_record_columns.html.erb @@ -9,9 +9,9 @@ <% column_value = 'Manage All Records (0)' if column_value == '-' %> <%= authorized ? render_list_column(column_value, column, record) : column_value %> - <% elsif column.name == :ns_records %> + <% elsif column.name == :permissions %> - <% column_value = 'Manage NS Records (0)' if column_value == '-' %> + <% column_value = 'Permissions (0)' if column_value == '-' %> <%= authorized ? render_list_column(column_value, column, record) : column_value %> <% else %> diff --git a/config/initializers/cancan.rb b/config/initializers/cancan.rb new file mode 100644 index 0000000..95b0b6c --- /dev/null +++ b/config/initializers/cancan.rb @@ -0,0 +1,73 @@ +# tweaks to allow Squeel Join + +module CanCan + + module ModelAdapters + class ActiveRecordAdapter < AbstractAdapter + + def tableized_conditions(conditions, model_class = @model_class) + return conditions unless conditions.kind_of? Hash + conditions.inject({}) do |result_hash, (name, value)| + reflection_name = name.kind_of?(Symbol) ? name : name._name # Squeel compatibility + if value.kind_of? Hash + reflection = model_class.reflect_on_association(reflection_name) + association_class = reflection.class_name.constantize + name = reflection.table_name.to_sym + value = tableized_conditions(value, association_class) + end + result_hash[name] = value + result_hash + end + end + + private + + # override to fix overwrites + # do not write existing hashes using empty hashes + def merge_joins(base, add) + add.each do |name, nested| + if base[name].is_a?(Hash) && nested.present? + merge_joins(base[name], nested) + elsif !base[name].is_a?(Hash) || nested.present? + base[name] = nested + end + end + end + + end + end + + class Rule + # allow Squeel Join + def matches_conditions_hash?(subject, conditions = @conditions) + if conditions.empty? + true + else + if model_adapter(subject).override_conditions_hash_matching? subject, conditions + model_adapter(subject).matches_conditions_hash? subject, conditions + else + conditions.all? do |name, value| + if model_adapter(subject).override_condition_matching? subject, name, value + model_adapter(subject).matches_condition? subject, name, value + else + method_name = name.kind_of?(Symbol) ? name : name._name # Squeel compatibility + attribute = subject.send(method_name) + if value.kind_of?(Hash) + if attribute.kind_of? Array + attribute.any? { |element| matches_conditions_hash? element, value } + else + !attribute.nil? && matches_conditions_hash?(attribute, value) + end + elsif value.kind_of?(Array) || value.kind_of?(Range) + value.include? attribute + else + attribute == value + end + end + end + end + end + end + end + +end diff --git a/config/initializers/squeel.rb b/config/initializers/squeel.rb new file mode 100644 index 0000000..47b926e --- /dev/null +++ b/config/initializers/squeel.rb @@ -0,0 +1,12 @@ +Squeel.configure do |config| + # To load hash extensions (to allow for AND (&), OR (|), and NOT (-) against + # hashes of conditions) + config.load_core_extensions :hash + + # To load symbol extensions (for a subset of the old MetaWhere functionality, + # via ARel predicate methods on Symbols: :name.matches, etc) + # config.load_core_extensions :symbol + + # To load both hash and symbol extensions + config.load_core_extensions :hash, :symbol +end diff --git a/config/routes.rb b/config/routes.rb index a369373..df9afea 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -49,6 +49,10 @@ Entrydns::Application.routes.draw do resources :srvs do as_routes end + + resources :permissions do + as_routes + end get '/dashboard', :to => 'dashboard#index', :as => :dashboard diff --git a/db/migrate/20111129180907_create_permissions.rb b/db/migrate/20111129180907_create_permissions.rb new file mode 100644 index 0000000..a322c33 --- /dev/null +++ b/db/migrate/20111129180907_create_permissions.rb @@ -0,0 +1,12 @@ +class CreatePermissions < ActiveRecord::Migration + def change + create_table :permissions do |t| + t.references :domain # the domain to whom permission is being given + t.references :user # the user permitted to manage + + t.timestamps + end + add_index :permissions, :domain_id + add_index :permissions, :user_id + end +end diff --git a/spec/controllers/permissions_controller_spec.rb b/spec/controllers/permissions_controller_spec.rb new file mode 100644 index 0000000..aab7557 --- /dev/null +++ b/spec/controllers/permissions_controller_spec.rb @@ -0,0 +1,157 @@ +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 PermissionsController do + + # This should return the minimal set of attributes required to create a valid + # Permission. As you add validations to Permission, be sure to + # update the return value of this method accordingly. + def valid_attributes + {} + end + + describe "GET index" do + it "assigns all permissions as @permissions" do + permission = Permission.create! valid_attributes + get :index + assigns(:permissions).should eq([permission]) + end + end + + describe "GET show" do + it "assigns the requested permission as @permission" do + permission = Permission.create! valid_attributes + get :show, :id => permission.id.to_s + assigns(:permission).should eq(permission) + end + end + + describe "GET new" do + it "assigns a new permission as @permission" do + get :new + assigns(:permission).should be_a_new(Permission) + end + end + + describe "GET edit" do + it "assigns the requested permission as @permission" do + permission = Permission.create! valid_attributes + get :edit, :id => permission.id.to_s + assigns(:permission).should eq(permission) + end + end + + describe "POST create" do + describe "with valid params" do + it "creates a new Permission" do + expect { + post :create, :permission => valid_attributes + }.to change(Permission, :count).by(1) + end + + it "assigns a newly created permission as @permission" do + post :create, :permission => valid_attributes + assigns(:permission).should be_a(Permission) + assigns(:permission).should be_persisted + end + + it "redirects to the created permission" do + post :create, :permission => valid_attributes + response.should redirect_to(Permission.last) + end + end + + describe "with invalid params" do + it "assigns a newly created but unsaved permission as @permission" do + # Trigger the behavior that occurs when invalid params are submitted + Permission.any_instance.stub(:save).and_return(false) + post :create, :permission => {} + assigns(:permission).should be_a_new(Permission) + end + + it "re-renders the 'new' template" do + # Trigger the behavior that occurs when invalid params are submitted + Permission.any_instance.stub(:save).and_return(false) + post :create, :permission => {} + response.should render_template("new") + end + end + end + + describe "PUT update" do + describe "with valid params" do + it "updates the requested permission" do + permission = Permission.create! valid_attributes + # Assuming there are no other permissions in the database, this + # specifies that the Permission created on the previous line + # receives the :update_attributes message with whatever params are + # submitted in the request. + Permission.any_instance.should_receive(:update_attributes).with({'these' => 'params'}) + put :update, :id => permission.id, :permission => {'these' => 'params'} + end + + it "assigns the requested permission as @permission" do + permission = Permission.create! valid_attributes + put :update, :id => permission.id, :permission => valid_attributes + assigns(:permission).should eq(permission) + end + + it "redirects to the permission" do + permission = Permission.create! valid_attributes + put :update, :id => permission.id, :permission => valid_attributes + response.should redirect_to(permission) + end + end + + describe "with invalid params" do + it "assigns the permission as @permission" do + permission = Permission.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Permission.any_instance.stub(:save).and_return(false) + put :update, :id => permission.id.to_s, :permission => {} + assigns(:permission).should eq(permission) + end + + it "re-renders the 'edit' template" do + permission = Permission.create! valid_attributes + # Trigger the behavior that occurs when invalid params are submitted + Permission.any_instance.stub(:save).and_return(false) + put :update, :id => permission.id.to_s, :permission => {} + response.should render_template("edit") + end + end + end + + describe "DELETE destroy" do + it "destroys the requested permission" do + permission = Permission.create! valid_attributes + expect { + delete :destroy, :id => permission.id.to_s + }.to change(Permission, :count).by(-1) + end + + it "redirects to the permissions list" do + permission = Permission.create! valid_attributes + delete :destroy, :id => permission.id.to_s + response.should redirect_to(permissions_url) + end + end + +end diff --git a/spec/factories.rb b/spec/factories.rb index b59b1ae..f004af9 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -33,4 +33,7 @@ FactoryGirl.define do content {Faker::Internet.ip_v4_address} end + factory :permission do + end + end diff --git a/spec/helpers/permissions_helper_spec.rb b/spec/helpers/permissions_helper_spec.rb new file mode 100644 index 0000000..29d9dbc --- /dev/null +++ b/spec/helpers/permissions_helper_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +# Specs in this file have access to a helper object that includes +# the PermissionsHelper. For example: +# +# describe PermissionsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# helper.concat_strings("this","that").should == "this that" +# end +# end +# end +describe PermissionsHelper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 4a7c6a8..c5179f8 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -5,23 +5,42 @@ require 'spec_helper' describe Ability do include_context "data" - it "allows me to manage my domains and their records, and my hosts" do - ability.should be_able_to(:manage, domain) - ability.should be_able_to(:manage, a_record) - ability.should be_able_to(:manage, soa_record) - ability.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent - ability.should be_able_to(:manage, host_a_record) - end + context "basic" do + it "allows me to manage my domains and their records, and my hosts" do + ability.should be_able_to(:manage, domain) + ability.should be_able_to(:manage, a_record) + ability.should be_able_to(:manage, soa_record) + ability.should_not be_able_to(:delete, soa_record) # SOA deleted only via parent + ability.should be_able_to(:manage, host_a_record) + end + + it "denies other user to manage my domains and their records, and my hosts" do + other_user_ability.should_not be_able_to(:manage, domain) + other_user_ability.should_not be_able_to(:manage, a_record) + other_user_ability.should_not be_able_to(:manage, soa_record) + other_user_ability.should_not be_able_to(:manage, host_a_record) + end - it "denies other user to manage my domains and their records" do - other_user_ability.should_not be_able_to(:manage, domain) - other_user_ability.should_not be_able_to(:manage, a_record) - other_user_ability.should_not be_able_to(:manage, soa_record) - other_user_ability.should_not be_able_to(:manage, host_a_record) + it "allows admin to manage other user's hosts" do + admin_ability.should be_able_to(:manage, host_a_record) + end end - it "allows admin to manage other user's hosts" do - admin_ability.should be_able_to(:manage, host_a_record) + context "permission" do + it "allows other user to manage user's domains and records, if permitted" do + permission # ensure permission to domain + other_user_ability.should be_able_to(:manage, domain) + other_user_ability.should be_able_to(:manage, a_record) + other_user_ability.should be_able_to(:manage, soa_record) + end + + it "allows me to manage my domain's permissions" do + ability.should be_able_to(:manage, permission) + end + + it "denies other user to manage my domain's permissions" do + other_user_ability.should_not be_able_to(:manage, permission) + end end end diff --git a/spec/models/permission_spec.rb b/spec/models/permission_spec.rb new file mode 100644 index 0000000..60a4277 --- /dev/null +++ b/spec/models/permission_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Permission do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/permissions_spec.rb b/spec/requests/permissions_spec.rb new file mode 100644 index 0000000..bea18a2 --- /dev/null +++ b/spec/requests/permissions_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "Permissions" do + describe "GET /permissions" 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 permissions_path + response.status.should be(200) + end + end +end diff --git a/spec/routing/permissions_routing_spec.rb b/spec/routing/permissions_routing_spec.rb new file mode 100644 index 0000000..287f501 --- /dev/null +++ b/spec/routing/permissions_routing_spec.rb @@ -0,0 +1,35 @@ +require "spec_helper" + +describe PermissionsController do + describe "routing" do + + it "routes to #index" do + get("/permissions").should route_to("permissions#index") + end + + it "routes to #new" do + get("/permissions/new").should route_to("permissions#new") + end + + it "routes to #show" do + get("/permissions/1").should route_to("permissions#show", :id => "1") + end + + it "routes to #edit" do + get("/permissions/1/edit").should route_to("permissions#edit", :id => "1") + end + + it "routes to #create" do + post("/permissions").should route_to("permissions#create") + end + + it "routes to #update" do + put("/permissions/1").should route_to("permissions#update", :id => "1") + end + + it "routes to #destroy" do + delete("/permissions/1").should route_to("permissions#destroy", :id => "1") + end + + end +end diff --git a/spec/support/shared_context/data.rb b/spec/support/shared_context/data.rb index 03586f3..7eac278 100644 --- a/spec/support/shared_context/data.rb +++ b/spec/support/shared_context/data.rb @@ -2,6 +2,7 @@ shared_context "data" do let(:user){create(:user)} let(:ability){Ability.new(:user => user)} + let(:other_user){create(:user)} let(:other_user_ability){Ability.new(:user => other_user)} @@ -36,5 +37,7 @@ shared_context "data" do domain } let(:host_a_record){create(:a, :content => '127.0.0.1', :domain => host_domain, :user => user)} + + let(:permission) {create(:permission, :domain => domain, :user => other_user)} end diff --git a/spec/views/permissions/edit.html.erb_spec.rb b/spec/views/permissions/edit.html.erb_spec.rb new file mode 100644 index 0000000..885f4fb --- /dev/null +++ b/spec/views/permissions/edit.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "permissions/edit.html.erb" do + before(:each) do + @permission = assign(:permission, stub_model(Permission)) + end + + it "renders the edit permission form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => permissions_path(@permission), :method => "post" do + end + end +end diff --git a/spec/views/permissions/index.html.erb_spec.rb b/spec/views/permissions/index.html.erb_spec.rb new file mode 100644 index 0000000..69d8b18 --- /dev/null +++ b/spec/views/permissions/index.html.erb_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe "permissions/index.html.erb" do + before(:each) do + assign(:permissions, [ + stub_model(Permission), + stub_model(Permission) + ]) + end + + it "renders a list of permissions" do + render + end +end diff --git a/spec/views/permissions/new.html.erb_spec.rb b/spec/views/permissions/new.html.erb_spec.rb new file mode 100644 index 0000000..6681f59 --- /dev/null +++ b/spec/views/permissions/new.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "permissions/new.html.erb" do + before(:each) do + assign(:permission, stub_model(Permission).as_new_record) + end + + it "renders new permission form" do + render + + # Run the generator again with the --webrat flag if you want to use webrat matchers + assert_select "form", :action => permissions_path, :method => "post" do + end + end +end diff --git a/spec/views/permissions/show.html.erb_spec.rb b/spec/views/permissions/show.html.erb_spec.rb new file mode 100644 index 0000000..e976633 --- /dev/null +++ b/spec/views/permissions/show.html.erb_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe "permissions/show.html.erb" do + before(:each) do + @permission = assign(:permission, stub_model(Permission)) + end + + it "renders attributes in

" do + render + end +end