newbamboo-modmonkey_client 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-11-11
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/Manifest.txt ADDED
@@ -0,0 +1,16 @@
1
+ History.txt
2
+ Manifest.txt
3
+ PostInstall.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/modmonkey_client.rb
7
+ lib/modmonkey_client/mod_monkey.rb
8
+ lib/modmonkey_client/profile.rb
9
+ lib/modmonkey_client/item.rb
10
+ lib/modmonkey_client/moderatables.rb
11
+ script/console
12
+ script/destroy
13
+ script/generate
14
+ spec/spec.opts
15
+ spec/spec_helper.rb
16
+ tasks/rspec.rake
data/PostInstall.txt ADDED
@@ -0,0 +1,7 @@
1
+
2
+ For more information on modmonkey_client, see http://modmonkey_client.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.txt ADDED
@@ -0,0 +1,198 @@
1
+ There is a ruby gem which handles a lot of stuff for you
2
+
3
+ General principles
4
+ ---
5
+
6
+ items and profiles which have corresponding things on the server
7
+
8
+ Models
9
+ ---
10
+
11
+ Item
12
+ ---
13
+
14
+ database fields
15
+
16
+ <pre>
17
+ class AddImages < ActiveRecord::Migration
18
+ def self.up
19
+ create_table :test_images do |t|
20
+ t.string :photo_file_name
21
+ t.string :mm_key
22
+ t.string :mm_approved
23
+ t.string :mm_id
24
+ t.string :test_user_id
25
+ end
26
+ end
27
+
28
+ def self.down
29
+ drop_table :test_images
30
+ end
31
+ end
32
+ </pre>
33
+
34
+ Adding moderation to the model
35
+
36
+ <pre>
37
+ class Comment < ActiveRecord::Base
38
+ extend ModMonkey::Item::ActMethods
39
+ make_moderatable :content_type=>'text',
40
+ :profile_info => {
41
+ :identifier => lambda{|obj| obj.test_user.email},
42
+ :profile_url => lambda{|obj| SITE_URL+"/test_users/#{obj.test_user.id}"}
43
+ },
44
+ :item_url => lambda{|obj| SITE_URL+"/test_comments/#{obj.id}"},
45
+ :editable_attrs => [:body]
46
+
47
+ def mm_content
48
+ { :body => self.body }
49
+ end
50
+ end
51
+ </pre>
52
+
53
+ optional attrs and methods
54
+
55
+ * content_type
56
+ * mm_content
57
+ * editable_attrs
58
+ * item_url
59
+ * profile_url
60
+ * asset_url
61
+
62
+ Specifying these values can be done via: lambdas, symbols or variables
63
+
64
+
65
+ callbacks created automatically for the following:
66
+
67
+ * create
68
+ * adds item to queue
69
+ * update
70
+ * updates item in queue
71
+ * delete
72
+ * removes item from queue
73
+
74
+ Though these are automatic, it is usually necessary to think about how failure is handled. Section on this in "Maintenance".
75
+
76
+ assumptions about moderated content and applying decisions
77
+ ---
78
+
79
+ The default behaviour is to switch mm_approved on or off with a modified find. However this could be overridden to destroy the objects completely, or do some other strategy.
80
+
81
+ added methods
82
+ ---
83
+
84
+ * reject
85
+ * approve
86
+
87
+ usually necessary to apply callbacks to these to cover:
88
+
89
+ * cascading
90
+ * banning user
91
+ * emailing notifications
92
+
93
+ ---
94
+
95
+ Profile
96
+ ---
97
+
98
+ database fields
99
+
100
+ <pre>
101
+ class CreateTestUsers < ActiveRecord::Migration
102
+ def self.up
103
+ create_table :test_users do |t|
104
+ t.string :email
105
+ t.boolean :banned
106
+
107
+ t.timestamps
108
+ end
109
+ end
110
+
111
+ def self.down
112
+ drop_table :test_users
113
+ end
114
+ end
115
+ </pre>
116
+
117
+ Adding moderatble functionality
118
+ ---
119
+
120
+ <pre>
121
+ class User < ActiveRecord::Base
122
+ extend ModMonkey::Profile::ActMethods
123
+ make_moderatable
124
+ end
125
+ </pre>
126
+
127
+ methods called via the options given:
128
+
129
+ * ban
130
+ * unban
131
+
132
+ usually necessary to apply callbacks to these to cover:
133
+
134
+ * cascading
135
+ * banning user
136
+ * emailing notifications
137
+
138
+ ---
139
+
140
+ Controllers
141
+ ---
142
+
143
+ SECURITY
144
+
145
+ implementation - AOP
146
+
147
+ Items
148
+ ---
149
+
150
+ <pre>
151
+ class TestImagesController < ApplicationController
152
+ extend ModMonkey::ControllerActMethods
153
+ make_moderatable
154
+ end
155
+ </pre>
156
+
157
+ mm_update
158
+
159
+ update action applies decision etc
160
+
161
+ Flags
162
+ ---
163
+
164
+ Method which can be posted to to add a flag to the item in the queue. Can have an optional reason, if UI supports this.
165
+
166
+ ---
167
+
168
+ Profile
169
+ ---
170
+
171
+ <pre>
172
+ class TestUsersController < ApplicationController
173
+ extend ModMonkey::ProfileControllerActMethods
174
+ make_moderatable
175
+ end
176
+ </pre>
177
+
178
+ mm\_profile\_update checks permission and calls apply\_mod\_monkey\_params
179
+
180
+ all the callbacks for banning etc
181
+
182
+ - doesn't do cascading on the users content on this side, but does on the server ?
183
+
184
+ ---
185
+
186
+ Routes
187
+ ---
188
+
189
+ items which are moderated need to have a flags resource which can be posted to -
190
+ often helpful to have a helper in views
191
+
192
+ Gotchas
193
+ ---
194
+
195
+ * login_required
196
+
197
+ Rake tasks
198
+ ---
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 2
3
+ :major: 0
4
+ :minor: 0
@@ -0,0 +1,20 @@
1
+ $:.unshift(File.expand_path(File.dirname(__FILE__))) unless
2
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ begin
5
+ require 'rest_client'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ gem 'rest-client'
9
+ require 'rest_client'
10
+ end
11
+
12
+ require 'modmonkey_client/mod_monkey'
13
+ require 'modmonkey_client/item.rb'
14
+ require 'modmonkey_client/profile.rb'
15
+ require 'modmonkey_client/moderatables.rb'
16
+ # require 'modmonkey_client/hasher.rb'
17
+ # require 'modmonkey_client/rest_client_extensions.rb'
18
+ # require 'modmonkey_client/config.rb'
19
+
20
+
@@ -0,0 +1,175 @@
1
+ module ModMonkey
2
+ module Item
3
+ module ActMethods
4
+
5
+ attr_accessor :mm_attr_store
6
+ attr_accessor :editable_attrs
7
+ attr_accessor :mandatory_keys
8
+ attr_accessor :optional_keys
9
+
10
+ def make_moderatable(options={}, &block)
11
+ self.mandatory_keys = [:content_type, :profile_info, :item_url]
12
+ self.optional_keys = [:asset_url, :context_url, :content_description]
13
+
14
+ # Process passed in options
15
+ # These 'dynamic methods' are stored either as a lambda, proc, symbol for method, or ordinary variable
16
+ validate_keys(options)
17
+
18
+ self.editable_attrs = options[:editable_attrs] || []
19
+ self.mm_attr_store = options.select{|k,v| (mandatory_keys+optional_keys).include? k }
20
+
21
+ unless included_modules.include?(Moderatable)
22
+ before_create :set_default_approval_status
23
+ after_create :create_mm_item
24
+ after_update :update_mm_item
25
+ after_destroy :destroy_mm_item
26
+ attr_accessor :mm_update
27
+ named_scope :approved, :conditions => {:mm_approved => true}
28
+ include Moderatable
29
+ ModMonkey::Moderatables.add(self)
30
+ end
31
+ end
32
+
33
+ def validate_keys(options)
34
+ unless (options.keys | self.mandatory_keys) == options.keys
35
+ raise ArgumentError, "make_moderatable needs the following mandatory keys: #{(mandatory_keys).join(', ')}"
36
+ end
37
+ if options[:profile_info] &&
38
+ !options[:profile_info].is_a?(Symbol) &&
39
+ options[:profile_info][:profile_url].blank?
40
+ raise ArgumentError, "make_moderatable needs the profile_url to be specified"
41
+ end
42
+ end
43
+
44
+ def find(*args)
45
+ with_scope :find=>{:conditions=>"#{self.to_s.tableize}.mm_approved=1"} do
46
+ super
47
+ end
48
+ end
49
+
50
+ def find_unmoderated()
51
+ find(:all, :conditions => "mm_id is null")
52
+ end
53
+
54
+ def resource_url
55
+ # File.join(::ModMonkey::Config.api_domain, 'accounts', ::ModMonkey::Config.api_key, "items")
56
+ File.join(MM_API_DOMAIN, 'accounts', MM_API_KEY, "items")
57
+ end
58
+
59
+ def default_content_description
60
+ self.to_s.humanize
61
+ end
62
+
63
+ end
64
+
65
+ module Moderatable
66
+ attr_accessor :mm_item
67
+
68
+
69
+
70
+ # mod monkey
71
+ def apply_mod_monkey_params( params )
72
+ apply_decision(params)
73
+ update_content(params)
74
+ self.save!
75
+ end
76
+
77
+ # mod monkey callbacks
78
+ def reject
79
+ self.mm_approved = false
80
+ self.save
81
+ end
82
+ def approve
83
+ self.mm_approved = true
84
+ self.save
85
+ end
86
+
87
+ def flag(params={})
88
+ flag = Hash.from_xml(RestClient::Resource.new(self.class.resource_url+"/#{self.mm_id}/flags").post(params))
89
+ end
90
+
91
+ def mm_attrs
92
+ # Evaluate each attribute and return the hash
93
+ attrs = {}
94
+ self.class.mm_attr_store.each do |attr_name,value|
95
+ evaluated_value = evaluate_value(value)
96
+ attrs[attr_name] = evaluated_value
97
+ end
98
+ attrs
99
+ end
100
+
101
+ def evaluate_value(value)
102
+ if value.respond_to?(:call) then value.call(self)
103
+ elsif value.is_a?(Symbol) && self.respond_to?(value) then self.send(value)
104
+ elsif value.is_a?(Hash) then
105
+ new_hash = {}
106
+ value.each {|k,v| new_hash[k] = evaluate_value(v)}
107
+ new_hash
108
+ else value
109
+ end
110
+ end
111
+
112
+ def mm_content
113
+ raise NotImplementedError, 'the method mm_content needs to be implemented in the including class'
114
+ end
115
+
116
+ def add_to_queue
117
+ create_mm_item
118
+ end
119
+
120
+ def moderated?
121
+ !self.mm_id.blank?
122
+ end
123
+
124
+ protected
125
+
126
+ def set_default_approval_status
127
+ self.mm_approved = true
128
+ end
129
+
130
+ # mod monkey
131
+ def apply_decision(mm_item)
132
+ case mm_item['decision']
133
+ when 'rejected'
134
+ self.reject
135
+ when 'approved'
136
+ self.approve
137
+ end
138
+ end
139
+
140
+ def update_content(mm_item)
141
+ evaluate_value(self.class.editable_attrs).each do |attr|
142
+ self.write_attribute( attr, mm_item[ attr.to_s ] )
143
+ end
144
+ end
145
+
146
+ # mod monkey
147
+ def create_mm_item
148
+ begin
149
+ attrs_for_create = {:item => self.mm_attrs.merge(self.mm_content)}
150
+ self.mm_item = Hash.from_xml(RestClient::Resource.new(self.class.resource_url).post(attrs_for_create))['item']
151
+ self.mm_id = self.mm_item['id']
152
+ self.mm_key = self.mm_item['item_key']
153
+ self.save
154
+ rescue Exception => e
155
+ logger.info("#{e.inspect}, backtrace: #{e.backtrace.join("\n")} - #{mm_item.inspect} with #{attrs_for_create.inspect}")
156
+ end
157
+ end
158
+
159
+ def update_mm_item
160
+ true
161
+ end
162
+
163
+ def destroy_mm_item
164
+ RestClient::Resource.new(self.mm_item_url).delete if self.moderated?
165
+ end
166
+
167
+ protected
168
+
169
+ def mm_item_url
170
+ self.class.resource_url + "/#{self.mm_id}"
171
+ end
172
+
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,134 @@
1
+ raise %q(Please define the following constants in your environment:
2
+ MM_API_DOMAIN
3
+ SITE_URL
4
+ MM_API_KEY
5
+ SITE_HOSTNAME
6
+ ) unless (defined?(MM_API_DOMAIN) &&
7
+ defined?(SITE_URL) &&
8
+ defined?(MM_API_KEY) &&
9
+ defined?(SITE_HOSTNAME))
10
+
11
+ module ModMonkey
12
+
13
+ APPROVAL_STATES = {
14
+ 'APPROVED' => 'approved',
15
+ 'REJECTED' => 'rejected'
16
+ }
17
+
18
+ ITEMS_RESOURCE_URL = File.join(MM_API_DOMAIN, 'accounts', MM_API_KEY, "items")
19
+
20
+ module ControllerActMethods
21
+ def make_moderatable(options={}, &block)
22
+ unless included_modules.include?(MonkeyController)
23
+ if defined?(Merb)
24
+ before :mm_update, :only => [:update]
25
+ provides :xml, :only => [:update]
26
+ include MerbMonkeyController
27
+ else
28
+ before_filter :mm_update, :only => [:update]
29
+ include MonkeyController
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ module ProfileControllerActMethods
36
+ def make_moderatable(options={}, &block)
37
+ unless included_modules.include?(MonkeyProfileController)
38
+ if defined?(Merb)
39
+ before :mm_profile_update, :only => [:update]
40
+ provides :xml, :only => [:update]
41
+ include MerbMonkeyProfileController
42
+ else
43
+ before_filter :mm_profile_update, :only => [:update]
44
+ include MonkeyProfileController
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ ###### RAILS
51
+
52
+ module MonkeyProfileController
53
+ private
54
+
55
+ # this method is called before any update actions in your controllers
56
+ def mm_profile_update
57
+ if params[:mod_monkey_profile]
58
+ #@test_user = TestUser.find_by_mm_id(params[:mod_monkey_profile][:id])
59
+ @test_user = TestUser.find(params[:id])
60
+ raise ActiveRecord::RecordNotFound if @test_user.nil?
61
+ @test_user.apply_mod_monkey_params(params[:mod_monkey_profile])
62
+ render :xml => @test_user.to_xml and return false
63
+ end
64
+ end
65
+ end
66
+
67
+ module MonkeyController
68
+ def flag
69
+ klass = self.controller_name.singularize.camelize.constantize
70
+ @obj = klass.find(params[:id])
71
+ # we might want to pass in some more args
72
+ @obj.flag(params[:flag])
73
+ redirect_to :back
74
+ end
75
+
76
+ # this method is called before any update actions in your controllers
77
+ def mm_update
78
+ if params[:mod_monkey_item]
79
+ klass = self.controller_name.singularize.camelize.constantize
80
+ @obj = klass.find_by_mm_id_and_mm_key(params[:mod_monkey_item][:id], params[:mod_monkey_item][:item_key])
81
+ @obj.apply_mod_monkey_params( params[:mod_monkey_item] )
82
+ render :xml => @obj.to_xml and return false
83
+ end
84
+ end
85
+ end
86
+
87
+ ############ MERB STUFF
88
+
89
+ module MerbMonkeyProfileController
90
+
91
+ def self.included(base)
92
+ base.show_action(:mm_profile_update)
93
+ end
94
+
95
+ # this method is called before any update actions in your controllers
96
+ def mm_profile_update
97
+ if params[:mod_monkey_profile]
98
+ klass = self.controller_name.singularize.camelize.constantize
99
+ @obj = klass.find(params[:id])
100
+ @obj.apply_mod_monkey_params(params[:mod_monkey_profile])
101
+ render @obj.to_xml and throw :halt
102
+ end
103
+ end
104
+ end
105
+
106
+ module MerbMonkeyController
107
+ def self.included(base)
108
+ base.show_action("flag", "mm_update")
109
+ end
110
+
111
+ def mm_update
112
+ if params[:mod_monkey_item]
113
+ klass = self.controller_name.singularize.camelize.constantize
114
+ @obj = klass.find_by_mm_id_and_mm_key(params[:mod_monkey_item][:id], params[:mod_monkey_item][:item_key])
115
+ @obj.apply_mod_monkey_params( params[:mod_monkey_item] )
116
+ render @obj.to_xml and throw :halt
117
+ end
118
+ end
119
+
120
+ def flag
121
+ klass = self.controller_name.singularize.camelize.constantize
122
+ @obj = klass.find(params[:id])
123
+ # we might want to pass in some more args
124
+ @obj.flag(params[:flag])
125
+ if defined?(MerbHasFlash)
126
+ flash[:notice] = MM_FLAG_NOTICE
127
+ redirect "/"
128
+ else
129
+ redirect "/", :message => {:notice => MM_FLAG_NOTICE}
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,15 @@
1
+ module ModMonkey
2
+ class Moderatables
3
+
4
+ @@moderatables = []
5
+
6
+ def self.add(klass)
7
+ @@moderatables << klass unless @@moderatables.include?(klass)
8
+ end
9
+
10
+ def self.moderatables
11
+ @@moderatables
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,82 @@
1
+ module ModMonkey
2
+ module Profile
3
+
4
+ BANNED_STATES = {
5
+ 'BANNED' => 'banned',
6
+ 'UNBANNED' => 'unbanned'
7
+ }
8
+
9
+ module ActMethods
10
+
11
+ attr_accessor :mm_attr_store
12
+ attr_accessor :editable_attrs
13
+
14
+ def make_moderatable(options={}, &block)
15
+
16
+ # Process passed in options
17
+ # These 'dynamic methods' are stored either as a lambda, proc, symbol for method, or ordinary variable
18
+ # mm_attr_keys = [:content_type, :profile_info, :item_url]
19
+ # raise ArgumentError, "make_moderatable needs the following mandatory keys: #{(mm_attr_keys).join(', ')}" unless (options.keys | mm_attr_keys) == options.keys
20
+ # self.editable_attrs = options[:editable_attrs] || []
21
+ # self.mm_attr_store = options.select{|k,v| mm_attr_keys.include? k }
22
+ #
23
+ unless included_modules.include?(Moderatable)
24
+ # before_create :set_default_approval_status
25
+ # after_create :create_mm_item
26
+ # after_update :update_mm_item
27
+ # after_destroy :destroy_mm_item
28
+ # attr_accessor :mm_update
29
+ # named_scope :approved, :conditions => {:mm_approved => true}
30
+ include Moderatable
31
+ # def self.find(*args)
32
+ # with_scope :find=>{:conditions=>"#{self.to_s.tableize}.mm_approved=1"} do
33
+ # super
34
+ # end
35
+ # end
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ module Moderatable
42
+
43
+ # mod monkey
44
+ def apply_mod_monkey_params( params )
45
+ apply_decision(params)
46
+ self.save!
47
+ end
48
+
49
+ # mod monkey callbacks
50
+ def ban
51
+ self.mm_banned = true
52
+ self.save
53
+ end
54
+
55
+ def unban
56
+ self.mm_banned = false
57
+ self.save
58
+ end
59
+
60
+ private
61
+
62
+ # mod monkey
63
+ def apply_decision(mm_item)
64
+ case mm_item['status']
65
+ when BANNED_STATES['BANNED']
66
+ self.ban
67
+ when BANNED_STATES['UNBANNED']
68
+ self.unban
69
+ end
70
+ end
71
+
72
+ def update_mm_item
73
+ true
74
+ end
75
+
76
+ def destroy_mm_item
77
+ true
78
+ end
79
+
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class ModeratableController < ActionController::Base
4
+
5
+ extend ModMonkey::ControllerActMethods
6
+ make_moderatable
7
+
8
+ end
9
+
10
+ describe ModeratableController do
11
+
12
+ before :each do
13
+ @controller = ModeratableController.new
14
+ end
15
+
16
+ it "should have an update method" do
17
+ pending
18
+ @controller.should be_respond_to('update')
19
+ end
20
+
21
+ end
@@ -0,0 +1,149 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe TestComment do
4
+
5
+ describe "making our model moderatable" do
6
+
7
+ before(:each) do
8
+ @test_user = TestUser.create!()
9
+ @default_options = {
10
+ :content_type => 'text',
11
+ :profile_info => {
12
+ :email => "fsdfs@fdsaf.com",
13
+ :profile_url => "localhost:3000/users/1"
14
+ },
15
+ :item_url => '/jello',
16
+ :editable_attrs => [:body] }
17
+ end
18
+
19
+ [:content_type, :profile_info, :item_url].each do |key|
20
+
21
+ it "should require #{key}" do
22
+ $key = key
23
+ $default_options = @default_options
24
+ lambda {
25
+ class TestComment
26
+ make_moderatable $default_options.reject{|k,v|k==$key}
27
+ end
28
+ }.should raise_error(ArgumentError)
29
+ end
30
+
31
+ it "should accept #{key} as a proc with instance as param" do
32
+ $key = key
33
+ $default_options = @default_options
34
+ class TestComment
35
+ make_moderatable $default_options.merge({ $key => Proc.new {|obj| obj.object_id } })
36
+ end
37
+ comment = TestComment.new
38
+ comment.mm_attrs[key].should == comment.object_id
39
+ end
40
+
41
+ it "should accept #{key} as a lambda with instance as param" do
42
+ $key = key
43
+ $default_options = @default_options
44
+ class TestComment
45
+ make_moderatable $default_options.merge({ $key => lambda {|obj| obj.object_id } })
46
+ end
47
+ comment = TestComment.new
48
+ comment.mm_attrs[key].should == comment.object_id
49
+ end
50
+
51
+ it "should accept #{key} as a method name and be able to call it" do
52
+ $key = key
53
+ $default_options = @default_options
54
+ class TestComment
55
+ make_moderatable $default_options.merge({ $key => :test_method })
56
+ def test_method; 'wassup'; end
57
+ end
58
+ comment = TestComment.new
59
+ comment.mm_attrs[key].should == 'wassup'
60
+ end
61
+
62
+ end
63
+
64
+ it "should include the profile url" do
65
+ $default_options = @default_options
66
+ lambda {
67
+ $default_options[:profile_info][:profile_url] = nil
68
+ class TestComment
69
+ make_moderatable $default_options
70
+ end
71
+ }.should raise_error(ArgumentError)
72
+ end
73
+
74
+ it "should save editable_attrs as empty array by default" do
75
+ $default_options = @default_options
76
+ class TestComment
77
+ make_moderatable $default_options.reject{|k,v| k == :editable_attrs}
78
+ end
79
+ TestComment.editable_attrs.should == []
80
+ end
81
+
82
+ it "should return editable_attrs correctly" do
83
+ $default_options = @default_options
84
+ class TestComment
85
+ make_moderatable $default_options
86
+ end
87
+ TestComment.editable_attrs.should == [:body]
88
+ end
89
+
90
+ describe 'getting the mm attributes' do
91
+
92
+ before :each do
93
+ class TestComment
94
+ make_moderatable :content_type => lambda{|obj| "#{obj.object_id} hello"},
95
+ :profile_info => {
96
+ :email => lambda{|obj| obj.test_user.email},
97
+ :profile_url => lambda{|obj| "localhost:3000/users/#{obj.test_user.id}"},
98
+ },
99
+ :item_url => lambda{|obj| "comments/#{obj.object_id}"},
100
+ :editable_attrs => [:body, :name]
101
+ def mm_content
102
+ {:body => 'wassup', :name => 'yo'}
103
+ end
104
+ end
105
+ @comment = TestComment.new(:test_user => @test_user)
106
+ end
107
+
108
+ it 'should return the dynamically generated attributes' do
109
+ @comment.mm_attrs.should == {
110
+ :content_type => "#{@comment.object_id} hello",
111
+ :profile_info => {
112
+ :email => @comment.test_user.email,
113
+ :profile_url => "localhost:3000/users/#{@test_user.id}"
114
+ },
115
+ :item_url => "comments/#{@comment.object_id}"}
116
+ end
117
+
118
+ it 'should return the content' do
119
+ @comment.mm_content.should == {:body => 'wassup', :name => 'yo'}
120
+ end
121
+
122
+ end
123
+
124
+ describe "destroying" do
125
+ before( :each ) do
126
+ @comment = TestComment.new(:title=>'foo', :test_user=>@test_user)
127
+ @comment.stub!(:create_mm_item).and_return(true)
128
+ @comment.stub!(:moderated?).and_return(true)
129
+ @comment.save
130
+ @mocked_resource = mock('resource')
131
+ end
132
+
133
+ it "should fire a callback when destroyed" do
134
+ @mocked_resource.should_receive(:delete)
135
+ RestClient::Resource.should_receive(:new).and_return(@mocked_resource)
136
+ @comment.destroy
137
+ end
138
+
139
+ it "should use the method " do
140
+ @comment.should_receive(:mm_item_url).and_return('my_url')
141
+ @mocked_resource.stub!(:delete)
142
+ RestClient::Resource.stub!(:new).with('my_url').and_return(@mocked_resource)
143
+ @comment.destroy
144
+ end
145
+ end
146
+ end
147
+
148
+ end
149
+
@@ -0,0 +1,14 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require 'ostruct'
3
+
4
+ describe ModMonkey::Moderatables do
5
+
6
+ describe "adding all moderatable class" do
7
+
8
+ it "should return moderatables" do
9
+ ModMonkey::Moderatables.moderatables.should == [TestComment]
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ class ModeratableController < ActionController::Base
4
+
5
+ extend ModMonkey::ProfileControllerActMethods
6
+ make_moderatable
7
+
8
+ end
9
+
10
+ describe ModeratableController do
11
+
12
+ it "should have an update method" do
13
+ pending
14
+ put :update
15
+ response.should be_success
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,20 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe TestUser do
4
+
5
+ describe "making our profile moderatable" do
6
+
7
+ before(:each) do
8
+ @user = TestUser.new
9
+ end
10
+
11
+ it "should have the apply_mod_monkey_params method" do
12
+ pending
13
+ @user.should be_respond_to(:apply_mod_monkey_params)
14
+ end
15
+
16
+
17
+ end
18
+
19
+ end
20
+
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format=specdoc
@@ -0,0 +1,60 @@
1
+ MM_API_DOMAIN = "http://localhost:3002"
2
+ SITE_URL = "http://localhost:3001"
3
+ MM_API_KEY = "public"
4
+ MM_PRIOVATE_KEY = "private"
5
+ SITE_HOSTNAME = "localhost"
6
+
7
+ begin
8
+ require 'spec'
9
+ rescue LoadError
10
+ require 'rubygems'
11
+ gem 'rspec'
12
+ require 'spec'
13
+ end
14
+
15
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
16
+
17
+ require 'rubygems'
18
+ require 'activerecord'
19
+ require 'action_controller'
20
+ require 'mocha'
21
+
22
+ ActiveRecord::Base.establish_connection({
23
+ :adapter => 'sqlite3',
24
+ :database => ':memory:'
25
+ })
26
+
27
+ # define a migration
28
+ class TestSchema < ActiveRecord::Migration
29
+ def self.up
30
+ create_table :test_comments do |t|
31
+ t.string :title
32
+ t.integer :test_user_id
33
+ t.string :mm_key
34
+ t.string :mm_approved
35
+ t.string :mm_id
36
+ t.timestamps
37
+ end
38
+
39
+ create_table :test_users do |t|
40
+ t.text :name
41
+ t.string :email
42
+ t.boolean :banned
43
+ t.timestamps
44
+ end
45
+ end
46
+
47
+ def self.down
48
+ drop_table :test_users
49
+ drop_table :test_comments
50
+ end
51
+ end
52
+
53
+ ActiveRecord::Base.connection # this creates the DB
54
+ # run the migration
55
+ TestSchema.migrate(:up)
56
+
57
+ require 'modmonkey_client'
58
+ require 'spec/test_comment'
59
+ require 'spec/test_user'
60
+
@@ -0,0 +1,17 @@
1
+ class TestComment < ActiveRecord::Base
2
+ belongs_to :test_user
3
+
4
+ extend ModMonkey::Item::ActMethods
5
+ make_moderatable :content_type=>'text',
6
+ :profile_info => {
7
+ :email => lambda{|obj| obj.test_user.email},
8
+ :profile_url => lambda{|obj| SITE_URL+"/test_users/#{obj.test_user.id}"}
9
+ },
10
+ :item_url => lambda{|obj| SITE_URL+"/test_comments/#{obj.id}"},
11
+ :editable_attrs => [:body]
12
+
13
+ def mm_content
14
+ { :body => self.body }
15
+ end
16
+
17
+ end
data/spec/test_user.rb ADDED
@@ -0,0 +1,3 @@
1
+ class TestUser < ActiveRecord::Base
2
+ has_many :test_comments
3
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: newbamboo-modmonkey_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - New Bamboo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-31 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: me@mloughran.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - History.txt
26
+ - Manifest.txt
27
+ - PostInstall.txt
28
+ - README.txt
29
+ - VERSION.yml
30
+ - lib/modmonkey_client
31
+ - lib/modmonkey_client/item.rb
32
+ - lib/modmonkey_client/mod_monkey.rb
33
+ - lib/modmonkey_client/moderatables.rb
34
+ - lib/modmonkey_client/profile.rb
35
+ - lib/modmonkey_client.rb
36
+ - spec/modmonkey_client
37
+ - spec/modmonkey_client/item_controller_spec.rb
38
+ - spec/modmonkey_client/item_model_spec.rb
39
+ - spec/modmonkey_client/moderatables_spec.rb
40
+ - spec/modmonkey_client/profile_controller_spec.rb
41
+ - spec/modmonkey_client/profile_model_spec.rb
42
+ - spec/spec.opts
43
+ - spec/spec_helper.rb
44
+ - spec/test_comment.rb
45
+ - spec/test_user.rb
46
+ has_rdoc: false
47
+ homepage: http://github.com/newbamboo/modmonkey_client
48
+ licenses:
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --inline-source
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Client gem for modmonkey
74
+ test_files: []
75
+