governor 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -7
- data/Gemfile.lock +1 -1
- data/README.markdown +4 -5
- data/VERSION +1 -1
- data/app/controllers/governor/articles_controller.rb +3 -2
- data/app/helpers/governor_helper.rb +8 -4
- data/app/views/governor/articles/_article.html.erb +1 -1
- data/app/views/governor/articles/edit.html.erb +1 -1
- data/app/views/governor/articles/index.html.erb +1 -1
- data/app/views/governor/articles/new.html.erb +1 -1
- data/app/views/governor/articles/show.html.erb +6 -4
- data/governor.gemspec +6 -2
- data/lib/generators/governor/templates/governor.rb +25 -11
- data/lib/governor.rb +4 -12
- data/lib/governor/article.rb +3 -0
- data/lib/governor/controllers/helpers.rb +11 -15
- data/lib/governor/formatters.rb +1 -1
- data/lib/governor/plugin.rb +22 -1
- data/lib/governor/plugin_manager.rb +5 -7
- data/lib/governor/rails/routes.rb +9 -1
- data/spec/action_dispatch/routing/mapper_spec.rb +28 -0
- data/spec/controllers/governor/articles_controller_spec.rb +84 -26
- data/spec/governor/plugin_manager_spec.rb +21 -1
- data/spec/governor/plugin_spec.rb +11 -0
- data/spec/governor_spec.rb +9 -12
- data/spec/rails_app/Gemfile.lock +1 -1
- data/spec/rails_app/app/views/layouts/application.html.erb +8 -0
- data/spec/spec_helper.rb +15 -0
- metadata +9 -5
data/Gemfile
CHANGED
@@ -15,10 +15,4 @@ group :development, :test do
|
|
15
15
|
gem 'devise'
|
16
16
|
gem 'governor', :path => './'
|
17
17
|
gem 'dynamic_form'
|
18
|
-
end
|
19
|
-
# group :development do
|
20
|
-
# gem "rspec", "~> 2.3.0"
|
21
|
-
# gem "bundler", "~> 1.0.0"
|
22
|
-
# gem "jeweler", "~> 1.5.2"
|
23
|
-
# gem "rcov", ">= 0"
|
24
|
-
# end
|
18
|
+
end
|
data/Gemfile.lock
CHANGED
data/README.markdown
CHANGED
@@ -12,13 +12,8 @@ try the specs, they're fresh!
|
|
12
12
|
Dependencies
|
13
13
|
------------
|
14
14
|
|
15
|
-
Some day, Governor will be somewhat independent, but for now, there are some
|
16
|
-
explicit and implicit dependencies. There's the obvious hard dependency on
|
17
|
-
Rails, but the following implicit dependencies exist at the moment:
|
18
|
-
|
19
15
|
* ActiveRecord
|
20
16
|
* [will_paginate](https://github.com/mislav/will_paginate)
|
21
|
-
* [Devise](https://github.com/plataformatec/devise)
|
22
17
|
|
23
18
|
At some point (at least by v1.0), these dependencies will be removed. Sorry
|
24
19
|
about the meantime.
|
@@ -52,6 +47,10 @@ Now that you have an article model and a set of routes, you're ready to plug
|
|
52
47
|
it into your app. I'd recommend running `rake routes` to see what routes have
|
53
48
|
been added, as they depend on the model name you chose.
|
54
49
|
|
50
|
+
The Governor initialization will check if Devise is installed, and will try to
|
51
|
+
Do The Right Thing if it is. If not, it'll yell at you, so be sure to set up
|
52
|
+
your authorization rules in this file.
|
53
|
+
|
55
54
|
Authentication/Authorization
|
56
55
|
----------------------------
|
57
56
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -3,6 +3,7 @@ class Governor::ArticlesController < ApplicationController
|
|
3
3
|
before_filter :init_resource, :only => [:show, :edit, :update, :destroy]
|
4
4
|
before_filter :authorize_governor!, :only => [:new, :edit, :create, :update, :destroy]
|
5
5
|
helper :governor
|
6
|
+
|
6
7
|
helper Governor::Controllers::Helpers
|
7
8
|
|
8
9
|
# GET /articles
|
@@ -43,7 +44,7 @@ class Governor::ArticlesController < ApplicationController
|
|
43
44
|
# POST /articles.xml
|
44
45
|
def create
|
45
46
|
set_resource model_class.new(params[mapping.singular])
|
46
|
-
resource.author =
|
47
|
+
resource.author = the_governor
|
47
48
|
|
48
49
|
respond_to do |format|
|
49
50
|
if resource.save
|
@@ -78,7 +79,7 @@ class Governor::ArticlesController < ApplicationController
|
|
78
79
|
resource.destroy
|
79
80
|
|
80
81
|
respond_to do |format|
|
81
|
-
format.html { redirect_to(
|
82
|
+
format.html { redirect_to(polymorphic_path(mapping.plural)) }
|
82
83
|
format.xml { head :ok }
|
83
84
|
end
|
84
85
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
module GovernorHelper
|
2
2
|
@@months = %w(January February March April May June July August September October November December)
|
3
3
|
|
4
|
+
Governor::PluginManager.plugins.map{|p| p.helpers }.flatten.each do |mod|
|
5
|
+
include mod.constantize # FIXME this feels pretty dirty, there has to be a better way
|
6
|
+
end
|
7
|
+
|
4
8
|
def render_plugin_partial(where, options = {})
|
5
|
-
output =
|
6
|
-
Governor::PluginManager.
|
7
|
-
opts = options.merge( {:
|
9
|
+
output = ''
|
10
|
+
Governor::PluginManager.plugins.map{|p| p.partial_for(where) }.compact.each do |partial|
|
11
|
+
opts = options.merge( {:partial => "governor/#{partial}"} )
|
8
12
|
output << render(opts)
|
9
13
|
end
|
10
|
-
return output
|
14
|
+
return output.html_safe
|
11
15
|
end
|
12
16
|
|
13
17
|
def get_date_label
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class='subtitle'>
|
3
3
|
<div class='desc'>
|
4
4
|
<%= resource.description %>
|
5
|
-
|
5
|
+
<%= render_plugin_partial(:after_article_description, :locals => {:article => resource}) %>
|
6
6
|
</div>
|
7
7
|
<div class='date'>
|
8
8
|
posted <%= show_time_ago resource.created_at %>
|
@@ -2,10 +2,12 @@
|
|
2
2
|
<div class="articles">
|
3
3
|
<%= render resource %>
|
4
4
|
</div>
|
5
|
-
|
5
|
+
<%= render_plugin_partial(:after_article_whole, :locals => {:article => resource}) %>
|
6
6
|
</div>
|
7
|
-
<%= link_to 'Back',
|
7
|
+
<%= link_to 'Back', polymorphic_path(mapping.plural) %>
|
8
8
|
<% if governor_authorized?(:edit, resource) %>
|
9
|
-
| <%= link_to 'Edit',
|
10
|
-
| <%= link_to 'Delete', resource, :method => :delete %>
|
9
|
+
| <%= link_to 'Edit', polymorphic_path(resource, :action => :edit) %>
|
11
10
|
<% end %>
|
11
|
+
<% if governor_authorized?(:destroy, resource) %>
|
12
|
+
| <%= link_to 'Delete', resource, :method => :delete %>
|
13
|
+
<% end %>
|
data/governor.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{governor}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Liam Morley"]
|
12
|
-
s.date = %q{2011-04-
|
12
|
+
s.date = %q{2011-04-10}
|
13
13
|
s.description = %q{Because Blogojevich would be too tough to remember. It's a pluggable blogging system for Rails 3.}
|
14
14
|
s.email = %q{liam@carpeliam.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -53,9 +53,11 @@ Gem::Specification.new do |s|
|
|
53
53
|
"lib/governor/rails/routes.rb",
|
54
54
|
"lib/tasks/.gitkeep",
|
55
55
|
"script/rails",
|
56
|
+
"spec/action_dispatch/routing/mapper_spec.rb",
|
56
57
|
"spec/controllers/governor/articles_controller_spec.rb",
|
57
58
|
"spec/governor/article_spec.rb",
|
58
59
|
"spec/governor/plugin_manager_spec.rb",
|
60
|
+
"spec/governor/plugin_spec.rb",
|
59
61
|
"spec/governor_spec.rb",
|
60
62
|
"spec/rails_app/.gitignore",
|
61
63
|
"spec/rails_app/Gemfile",
|
@@ -117,9 +119,11 @@ Gem::Specification.new do |s|
|
|
117
119
|
s.rubygems_version = %q{1.3.7}
|
118
120
|
s.summary = %q{A pluggable blogging system for Rails 3.}
|
119
121
|
s.test_files = [
|
122
|
+
"spec/action_dispatch/routing/mapper_spec.rb",
|
120
123
|
"spec/controllers/governor/articles_controller_spec.rb",
|
121
124
|
"spec/governor/article_spec.rb",
|
122
125
|
"spec/governor/plugin_manager_spec.rb",
|
126
|
+
"spec/governor/plugin_spec.rb",
|
123
127
|
"spec/governor_spec.rb",
|
124
128
|
"spec/rails_app/app/controllers/application_controller.rb",
|
125
129
|
"spec/rails_app/app/controllers/home_controller.rb",
|
@@ -1,22 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
# Any code below will be evaluated/executed within the scope of the caller.
|
2
|
+
|
3
|
+
# How to reference the author of an article
|
4
|
+
Governor.author = Proc.new do
|
5
|
+
if respond_to?(:current_user)
|
6
|
+
current_user
|
4
7
|
else
|
5
|
-
raise "Set up
|
8
|
+
raise "Set up Governor.author in #{File.expand_path(__FILE__)}"
|
6
9
|
end
|
7
10
|
end
|
8
11
|
|
9
|
-
|
12
|
+
# Rules for authorizing a particular action on a particular article
|
13
|
+
Governor.authorize_if do |action, article|
|
10
14
|
case action.to_sym
|
11
15
|
when :new, :create
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
if respond_to?(:user_signed_in?)
|
17
|
+
user_signed_in?
|
18
|
+
else
|
19
|
+
raise "Set up Governor.authorize_if in #{File.expand_path(__FILE__)}"
|
20
|
+
end
|
17
21
|
when :edit, :update, :destroy
|
18
|
-
article.author ==
|
22
|
+
article.author == instance_eval(&Governor.author)
|
19
23
|
else
|
20
24
|
raise ArgumentError.new('action must be new, create, edit, update, or destroy')
|
21
25
|
end
|
22
26
|
end
|
27
|
+
|
28
|
+
# What should Governor do if someone tries to do something they weren't
|
29
|
+
# authorized to do?
|
30
|
+
Governor.if_not_allowed do
|
31
|
+
if respond_to?(Devise)
|
32
|
+
send("authenticate_#{Devise.default_scope}!")
|
33
|
+
else
|
34
|
+
raise ArgumentError.new("Set up Governor.if_not_allowed in #{File.expand_path(__FILE__)}")
|
35
|
+
end
|
36
|
+
end
|
data/lib/governor.rb
CHANGED
@@ -6,27 +6,19 @@ require 'governor/mapping'
|
|
6
6
|
|
7
7
|
require 'governor/controllers/helpers'
|
8
8
|
|
9
|
-
require 'rails'
|
10
9
|
require 'governor/rails'
|
11
10
|
|
12
11
|
|
13
12
|
module Governor
|
14
13
|
|
15
|
-
|
14
|
+
mattr_reader :resources, :authorization_rules, :default_resource
|
15
|
+
mattr_accessor :if_not_allowed, :author
|
16
16
|
@@resources = {}
|
17
17
|
def self.map(resource, options = {})
|
18
|
-
self.resources[resource] = Governor::Mapping.new(resource, options)
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.setup
|
22
|
-
yield self
|
18
|
+
@@default_resource ||= self.resources[resource] = Governor::Mapping.new(resource, options)
|
23
19
|
end
|
24
20
|
|
25
21
|
def self.authorize_if(&blk)
|
26
|
-
@@
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.authorized?(actor, action, article=nil)
|
30
|
-
@@authz_rules.call(actor, action, article)
|
22
|
+
@@authorization_rules = blk
|
31
23
|
end
|
32
24
|
end
|
data/lib/governor/article.rb
CHANGED
@@ -2,6 +2,9 @@ module Governor
|
|
2
2
|
module Article
|
3
3
|
def self.included(base)
|
4
4
|
base.belongs_to :author, :polymorphic => true
|
5
|
+
Governor::PluginManager.resources(:child_resources).each_key do |resource|
|
6
|
+
base.has_many resource
|
7
|
+
end
|
5
8
|
|
6
9
|
def base.find_all_by_date(year, month = nil, day = nil, page = 1)
|
7
10
|
from, to = self.time_delta(year, month, day)
|
@@ -1,18 +1,6 @@
|
|
1
1
|
module Governor
|
2
2
|
module Controllers
|
3
3
|
module Helpers
|
4
|
-
def resources_url
|
5
|
-
url_for :controller => mapping.controller, :governor_mapping => params[:governor_mapping], :action => 'index'
|
6
|
-
end
|
7
|
-
|
8
|
-
def new_resource_url
|
9
|
-
url_for :controller => mapping.controller, :governor_mapping => params[:governor_mapping], :action => 'new'
|
10
|
-
end
|
11
|
-
|
12
|
-
def edit_resource_url(resource)
|
13
|
-
url_for :controller => mapping.controller, :governor_mapping => params[:governor_mapping], :action => 'edit', :id => resource.id
|
14
|
-
end
|
15
|
-
|
16
4
|
def resource
|
17
5
|
instance_variable_get("@#{mapping.singular}")
|
18
6
|
end
|
@@ -43,19 +31,27 @@ module Governor
|
|
43
31
|
end
|
44
32
|
|
45
33
|
def init_resource
|
46
|
-
set_resource model_class.find(params[:id])
|
34
|
+
set_resource model_class.find(params["#{mapping.singular}_id"] || params[:id])
|
35
|
+
end
|
36
|
+
|
37
|
+
def the_governor
|
38
|
+
instance_eval(&Governor.author)
|
39
|
+
end
|
40
|
+
|
41
|
+
def governor_logged_in?
|
42
|
+
the_governor.present?
|
47
43
|
end
|
48
44
|
|
49
45
|
def authorize_governor!
|
50
46
|
if defined?(resource)
|
51
47
|
redirect_to root_path unless governor_authorized?(action_name, resource)
|
52
48
|
else
|
53
|
-
|
49
|
+
instance_eval(&Governor.if_not_allowed) unless governor_authorized?(action_name)
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
57
53
|
def governor_authorized?(action, article=nil)
|
58
|
-
|
54
|
+
instance_exec(action, article, &Governor.authorization_rules)
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
data/lib/governor/formatters.rb
CHANGED
data/lib/governor/plugin.rb
CHANGED
@@ -1,13 +1,34 @@
|
|
1
1
|
module Governor
|
2
2
|
class Plugin
|
3
|
-
attr_reader :name, :migrations
|
3
|
+
attr_reader :name, :migrations, :resources, :helpers
|
4
4
|
def initialize(name)
|
5
5
|
@name = name
|
6
6
|
@migrations = []
|
7
|
+
@helpers = []
|
8
|
+
@resources = {}
|
9
|
+
@partials = {}
|
7
10
|
end
|
8
11
|
|
9
12
|
def add_migration(path)
|
10
13
|
@migrations << path
|
11
14
|
end
|
15
|
+
|
16
|
+
def add_child_resource(name, options={}, &block)
|
17
|
+
options[:block] = block if block_given?
|
18
|
+
@resources[:child_resources] ||= {}
|
19
|
+
@resources[:child_resources][name] = options
|
20
|
+
end
|
21
|
+
|
22
|
+
def register_partial(type, path)
|
23
|
+
@partials[type.to_sym] = path
|
24
|
+
end
|
25
|
+
|
26
|
+
def partial_for(type)
|
27
|
+
@partials[type.to_sym]
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_helper(mod)
|
31
|
+
@helpers << mod
|
32
|
+
end
|
12
33
|
end
|
13
34
|
end
|
@@ -4,16 +4,14 @@ module Governor
|
|
4
4
|
cattr_reader :view_hooks
|
5
5
|
|
6
6
|
class << self
|
7
|
-
@@
|
7
|
+
@@plugins = []
|
8
8
|
|
9
|
-
def register(
|
10
|
-
@@plugins
|
11
|
-
@@plugins << plugin
|
9
|
+
def register(*plugins)
|
10
|
+
@@plugins += plugins
|
12
11
|
end
|
13
12
|
|
14
|
-
def
|
15
|
-
@@
|
16
|
-
@@view_hooks[where] << partial_path
|
13
|
+
def resources(name)
|
14
|
+
@@plugins.map{|p| p.resources[name] }.compact.reduce({}, :merge)
|
17
15
|
end
|
18
16
|
end
|
19
17
|
end
|
@@ -5,7 +5,15 @@ module ActionDispatch::Routing
|
|
5
5
|
resources.map!(&:to_sym)
|
6
6
|
resources.each do |resource|
|
7
7
|
mapping = Governor.map(resource, options)
|
8
|
-
resources mapping.resource, :controller => mapping.controller, :governor_mapping => resource
|
8
|
+
resources mapping.resource, :controller => mapping.controller, :governor_mapping => resource do
|
9
|
+
Governor::PluginManager.resources(:child_resources).each_pair do |child_resource, options|
|
10
|
+
options = {:module => :governor}.merge options
|
11
|
+
block = options.delete :block
|
12
|
+
resources(child_resource, options) do
|
13
|
+
instance_eval(&block) if block.present?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
9
17
|
end
|
10
18
|
end
|
11
19
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ActionDispatch::Routing
|
4
|
+
|
5
|
+
describe Mapper do
|
6
|
+
context "#governate" do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@plugin = Governor::Plugin.new('test')
|
10
|
+
@plugin.add_child_resource('test', :some_option => 'value')
|
11
|
+
Governor::PluginManager.register @plugin
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't alter a plugin's options" do
|
15
|
+
Rails.application.reload_routes!
|
16
|
+
|
17
|
+
@plugin.resources[:child_resources].should == {'test' => {:some_option => 'value'}}
|
18
|
+
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
# reload routes to undo what we've done
|
22
|
+
Governor::PluginManager.remove_plugin(@plugin).should == @plugin
|
23
|
+
Rails.application.reload_routes!
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -9,55 +9,113 @@ module Governor
|
|
9
9
|
@article = Factory(:article, :author => @user)
|
10
10
|
end
|
11
11
|
context "#index" do
|
12
|
-
it "
|
12
|
+
it "renders the articles page" do
|
13
13
|
get :index, :governor_mapping => :articles
|
14
14
|
assigns[:articles].should == [@article]
|
15
|
+
response.should render_template(:index)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
context "#new" do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
context "when signed out" do
|
21
|
+
it "redirects back to the front page" do
|
22
|
+
get :new, :governor_mapping => :articles
|
23
|
+
response.should redirect_to(root_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when signed in" do
|
28
|
+
before(:each) { sign_in @user }
|
29
|
+
|
30
|
+
it "renders the new article page" do
|
31
|
+
get :new, :governor_mapping => :articles
|
32
|
+
assigns[:article].should be_a ::Article
|
33
|
+
assigns[:article].attributes.should == ::Article.new.attributes
|
34
|
+
response.should render_template(:new)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "#show" do
|
40
|
+
it "renders the right article" do
|
41
|
+
get :show, :governor_mapping => :articles, :id => @article.id
|
42
|
+
assigns[:article].should == @article
|
43
|
+
response.should render_template(:show)
|
24
44
|
end
|
25
45
|
end
|
26
46
|
|
27
|
-
|
28
|
-
context "
|
29
|
-
it "
|
30
|
-
get
|
47
|
+
context "#edit" do
|
48
|
+
context "when signed out" do
|
49
|
+
it "redirects back to the front page" do
|
50
|
+
get :edit, :governor_mapping => :articles, :id => @article.id
|
51
|
+
response.should redirect_to(root_path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when signed in" do
|
56
|
+
before(:each) { sign_in @user }
|
57
|
+
it "renders the edit page" do
|
58
|
+
get :edit, :governor_mapping => :articles, :id => @article.id
|
31
59
|
assigns[:article].should == @article
|
60
|
+
response.should render_template(:edit)
|
32
61
|
end
|
33
62
|
end
|
34
63
|
end
|
35
64
|
|
36
65
|
context "#create" do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
66
|
+
context "when signed out" do
|
67
|
+
it "redirects back to the front page" do
|
68
|
+
post :create, :governor_mapping => :articles
|
69
|
+
response.should redirect_to(root_path)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when signed in" do
|
74
|
+
before(:each) { sign_in @user }
|
75
|
+
it "creates a new article and redirects to its page" do
|
76
|
+
post :create, :governor_mapping => :articles
|
77
|
+
assigns[:article].should be_a ::Article
|
78
|
+
assigns[:article].should_not be_a_new_record
|
79
|
+
assigns[:article].author.should == @user
|
80
|
+
response.should redirect_to(assigns[:article])
|
81
|
+
end
|
43
82
|
end
|
44
83
|
end
|
45
84
|
|
46
85
|
context "#update" do
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
86
|
+
context "when signed out" do
|
87
|
+
it "redirects back to the front page" do
|
88
|
+
put :update, :governor_mapping => :articles, :id => @article.id, :article => {:title => 'I am awesome, you are awesome'}
|
89
|
+
response.should redirect_to(root_path)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when signed in" do
|
94
|
+
before(:each) { sign_in @user }
|
95
|
+
it "updates the article" do
|
96
|
+
put :update, :governor_mapping => :articles, :id => @article.id, :article => {:title => 'I am awesome, you are awesome'}
|
97
|
+
assigns[:article].title.should == 'I am awesome, you are awesome'
|
98
|
+
end
|
51
99
|
end
|
52
100
|
end
|
53
101
|
|
54
102
|
context "#destroy" do
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
103
|
+
context "when signed out" do
|
104
|
+
it "redirects back to the front page" do
|
105
|
+
delete :destroy, :governor_mapping => :articles, :id => @article.id
|
106
|
+
response.should redirect_to(root_path)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when signed in" do
|
111
|
+
before(:each) { sign_in @user }
|
112
|
+
it "deletes the article" do
|
113
|
+
delete :destroy, :governor_mapping => :articles, :id => @article.id
|
114
|
+
assigns[:article].should == @article
|
115
|
+
assigns[:article].should be_destroyed
|
116
|
+
::Article.count.should == 0
|
117
|
+
response.should redirect_to(articles_path)
|
118
|
+
end
|
61
119
|
end
|
62
120
|
end
|
63
121
|
end
|
@@ -2,10 +2,30 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Governor
|
4
4
|
describe PluginManager do
|
5
|
+
before do
|
6
|
+
@plugins = Governor::PluginManager.plugins
|
7
|
+
end
|
8
|
+
|
5
9
|
it "should keep track of plugins I've added" do
|
6
|
-
plugin = Plugin.new('
|
10
|
+
plugin = Plugin.new('test 1')
|
7
11
|
PluginManager.register plugin
|
8
12
|
PluginManager.plugins.should include plugin
|
9
13
|
end
|
14
|
+
|
15
|
+
it "collects resources for plugins" do
|
16
|
+
plugin1 = Plugin.new('test 1')
|
17
|
+
plugin1.add_child_resource(:moneys)
|
18
|
+
plugin2 = Plugin.new('test 2')
|
19
|
+
plugin2.add_child_resource(:powers, :module => :illinois)
|
20
|
+
PluginManager.register plugin1, plugin2
|
21
|
+
PluginManager.resources(:child_resources).should == {:moneys => {}, :powers => {:module => :illinois}}
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
remove_plugins = Governor::PluginManager.plugins - @plugins
|
26
|
+
remove_plugins.each do |plugin|
|
27
|
+
Governor::PluginManager.remove_plugin(plugin).should == plugin
|
28
|
+
end
|
29
|
+
end
|
10
30
|
end
|
11
31
|
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Governor
|
4
|
+
describe Plugin do
|
5
|
+
before(:each) {@plugin = Plugin.new('test')}
|
6
|
+
it "collects child resources" do
|
7
|
+
@plugin.add_child_resource('tests', :controller => 'governor/tests')
|
8
|
+
@plugin.resources.should == {:child_resources => {'tests' => {:controller => 'governor/tests'}}}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/spec/governor_spec.rb
CHANGED
@@ -8,33 +8,30 @@ class FakeArticle < ActiveRecord::Base
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
# we're going to need 'self' later
|
12
|
-
GOVERNOR_SPEC = self
|
13
|
-
|
14
11
|
describe Governor do
|
15
12
|
context "authorization" do
|
16
13
|
|
17
14
|
%w(new create).each do |action|
|
18
15
|
it "should make sure a user is logged in when going to the #{action} page" do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
self.expects(:user_signed_in?).returns false
|
17
|
+
instance_exec(action, &Governor.authorization_rules).should be_false
|
18
|
+
self.expects(:user_signed_in?).returns true
|
19
|
+
instance_exec(action, &Governor.authorization_rules).should be_true
|
23
20
|
end
|
24
21
|
end
|
25
22
|
|
26
23
|
%w(edit update destroy).each do |action|
|
27
24
|
it "should make sure the current user is the author when going to the #{action} page" do
|
28
25
|
article = FakeArticle.new
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
26
|
+
self.expects(:current_user).returns('milorad')
|
27
|
+
instance_exec(action, article, &Governor.authorization_rules).should be_false
|
28
|
+
self.expects(:current_user).returns('Rod')
|
29
|
+
instance_exec(action, article, &Governor.authorization_rules).should be_true
|
33
30
|
end
|
34
31
|
end
|
35
32
|
|
36
33
|
it "should raise an exception if any other action is requested" do
|
37
|
-
lambda{
|
34
|
+
lambda{instance_exec('some other action', &Governor.authorization_rules)}.should raise_error
|
38
35
|
end
|
39
36
|
end
|
40
37
|
end
|
data/spec/rails_app/Gemfile.lock
CHANGED
@@ -7,6 +7,14 @@
|
|
7
7
|
<%= csrf_meta_tag %>
|
8
8
|
</head>
|
9
9
|
<body>
|
10
|
+
<% if user_signed_in? %>
|
11
|
+
<%= link_to 'new article', new_article_path %> |
|
12
|
+
<%= link_to 'sign out', destroy_user_session_path %>
|
13
|
+
<% else %>
|
14
|
+
<%= link_to 'sign in', new_user_session_path %> |
|
15
|
+
<%= link_to 'sign up', new_user_registration_path %>
|
16
|
+
<% end %>
|
17
|
+
| <%= link_to 'articles', articles_path %>
|
10
18
|
|
11
19
|
<%= yield %>
|
12
20
|
|
data/spec/spec_helper.rb
CHANGED
@@ -18,4 +18,19 @@ Rspec.configure do |config|
|
|
18
18
|
config.mock_with :mocha
|
19
19
|
|
20
20
|
config.use_transactional_fixtures = true
|
21
|
+
end
|
22
|
+
|
23
|
+
# for removing plugins added in a test to make sure they don't bleed over
|
24
|
+
module Governor
|
25
|
+
class PluginManager
|
26
|
+
def self.remove_plugin(plugin_or_name)
|
27
|
+
case plugin_or_name
|
28
|
+
when Plugin then return @@plugins.delete(plugin_or_name)
|
29
|
+
else # Plugin Name
|
30
|
+
@@plugins.each do |plugin|
|
31
|
+
return @@plugins.delete(plugin) if plugin.name == plugin_or_name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
21
36
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: governor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Liam Morley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-04-
|
18
|
+
date: 2011-04-10 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -243,9 +243,11 @@ files:
|
|
243
243
|
- lib/governor/rails/routes.rb
|
244
244
|
- lib/tasks/.gitkeep
|
245
245
|
- script/rails
|
246
|
+
- spec/action_dispatch/routing/mapper_spec.rb
|
246
247
|
- spec/controllers/governor/articles_controller_spec.rb
|
247
248
|
- spec/governor/article_spec.rb
|
248
249
|
- spec/governor/plugin_manager_spec.rb
|
250
|
+
- spec/governor/plugin_spec.rb
|
249
251
|
- spec/governor_spec.rb
|
250
252
|
- spec/rails_app/.gitignore
|
251
253
|
- spec/rails_app/Gemfile
|
@@ -335,9 +337,11 @@ signing_key:
|
|
335
337
|
specification_version: 3
|
336
338
|
summary: A pluggable blogging system for Rails 3.
|
337
339
|
test_files:
|
340
|
+
- spec/action_dispatch/routing/mapper_spec.rb
|
338
341
|
- spec/controllers/governor/articles_controller_spec.rb
|
339
342
|
- spec/governor/article_spec.rb
|
340
343
|
- spec/governor/plugin_manager_spec.rb
|
344
|
+
- spec/governor/plugin_spec.rb
|
341
345
|
- spec/governor_spec.rb
|
342
346
|
- spec/rails_app/app/controllers/application_controller.rb
|
343
347
|
- spec/rails_app/app/controllers/home_controller.rb
|