be_taskable 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,309 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'BeTaskable::Taskable' do
4
+
5
+ let(:task) { double.as_null_object }
6
+ let(:assignee) { double.as_null_object }
7
+ let(:taskable) { Taskable.new }
8
+ let(:resolver) { double.as_null_object }
9
+
10
+ before do
11
+ taskable.stub(:task_resolver_for_action).and_return(resolver)
12
+ resolver.stub(:assignees_for_task).and_return([])
13
+ end
14
+
15
+ describe '#_task_resolver_name_for_action' do
16
+
17
+ it "responds to _task_resolver_name_for_action" do
18
+ expect(Taskable).to respond_to('_task_resolver_name_for_action')
19
+ end
20
+
21
+ it "returns the right name" do
22
+ res = Taskable._task_resolver_name_for_action('publish')
23
+ expect(res).to eq('TaskablePublishTaskResolver')
24
+ end
25
+
26
+ it "returns the right name for underscored actions" do
27
+ res = Taskable._task_resolver_name_for_action('publish_something')
28
+ expect(res).to eq('TaskablePublishSomethingTaskResolver')
29
+ end
30
+ end
31
+
32
+ describe '#_task_resolver_for_action' do
33
+
34
+ it "throws if it cannot find the resolver" do
35
+ expect{ Taskable._task_resolver_for_action('update') }.to raise_error
36
+ end
37
+
38
+ it "returns the resolver" do
39
+ res = Taskable._task_resolver_for_action('publish')
40
+ expect(res).to be_instance_of(TaskablePublishTaskResolver)
41
+ end
42
+ end
43
+
44
+ it "responds to taskable?" do
45
+ expect(taskable).to be_taskable
46
+ end
47
+
48
+ describe ".task_resolver_for_action" do
49
+ it "asks the class" do
50
+ taskable.unstub(:task_resolver_for_action)
51
+ action = 'publish'
52
+ Taskable.should_receive(:_task_resolver_for_action).with(action)
53
+ taskable.task_resolver_for_action(action)
54
+ end
55
+ end
56
+
57
+ describe ".tasks" do
58
+ it "responds to tasks" do
59
+ expect(taskable).to respond_to('tasks')
60
+ end
61
+
62
+ it "finds the tasks" do
63
+ taskable.save
64
+ taskable.tasks.create
65
+ taskable.tasks.create
66
+ expect(taskable.tasks.size).to eq(2)
67
+ end
68
+ end
69
+
70
+ describe ".create_task_for_action" do
71
+
72
+ before do
73
+ taskable.save
74
+ end
75
+
76
+ it "raises if it cannot find the resolver" do
77
+ taskable.unstub(:task_resolver_for_action)
78
+ expect{ taskable.create_task_for_action('view') }.to raise_error
79
+ end
80
+
81
+ it "raises if the taskable is not saved" do
82
+ taskable = Taskable.new
83
+ expect{ taskable.create_task_for_action('publish') }.to raise_error(ActiveRecord::RecordNotSaved)
84
+ end
85
+
86
+ it "creates a task" do
87
+ task = taskable.create_task_for_action('publish')
88
+ expect(taskable.tasks.size).to eq(1)
89
+ end
90
+
91
+ it "creates a different task everytime" do
92
+ task1 = taskable.create_task_for_action('publish')
93
+ task2 = taskable.create_task_for_action('publish')
94
+ expect(taskable.tasks.size).to eq(2)
95
+ end
96
+
97
+ it "has the right taskable" do
98
+ task = taskable.create_task_for_action('publish')
99
+ expect(task.taskable).to eq(taskable)
100
+ end
101
+
102
+ it "returns the task with the right action" do
103
+ task = taskable.create_task_for_action('publish')
104
+ expect(task.action).to eq('publish')
105
+ end
106
+
107
+ it "calls task.refresh" do
108
+ task = double.as_null_object
109
+ task.should_receive(:refresh)
110
+ taskable.tasks.stub(:create).and_return(task)
111
+ task = taskable.create_task_for_action('publish')
112
+ end
113
+
114
+ it "calls task.on_creation" do
115
+ task = double.as_null_object
116
+ task.should_receive(:on_creation)
117
+ taskable.tasks.stub(:create).and_return(task)
118
+ task = taskable.create_task_for_action('publish')
119
+ end
120
+ end
121
+
122
+ describe ".create_or_refresh_task_for_action" do
123
+ it "uses an existing task if possible" do
124
+ taskable.save
125
+ taskable.create_task_for_action('publish')
126
+ taskable.should_not_receive(:create_task_for_action)
127
+ taskable.create_or_refresh_task_for_action('publish')
128
+ end
129
+
130
+ it "creates a new task if not there" do
131
+ taskable.should_receive(:create_task_for_action)
132
+ taskable.create_or_refresh_task_for_action('publish')
133
+ end
134
+ end
135
+
136
+ describe ".tasks_for_action" do
137
+ it "responds to tasks_for_action" do
138
+ expect(taskable).to respond_to('tasks_for_action')
139
+ end
140
+
141
+ it "finds the tasks" do
142
+ taskable.save
143
+ task1 = taskable.tasks.create(action: 'create')
144
+ task2 = taskable.tasks.create(action: 'update')
145
+
146
+ expect(taskable.tasks_for_action('create')).to eq([task1])
147
+ end
148
+ end
149
+
150
+ describe ".last_task_for_action" do
151
+ it "responds to last_task_for_action" do
152
+ expect(taskable).to respond_to('last_task_for_action')
153
+ end
154
+
155
+ it "finds the task" do
156
+ taskable.save
157
+ task1 = taskable.tasks.create(taskable: taskable, action: 'create')
158
+ task2 = taskable.tasks.create(taskable: taskable, action: 'update')
159
+
160
+ res = taskable.last_task_for_action('create')
161
+ expect(res).to eq(task1)
162
+ end
163
+
164
+ it "returns nil if it cannot find the task" do
165
+ res = taskable.last_task_for_action('create')
166
+ expect(res).to be_nil
167
+ end
168
+ end
169
+
170
+ describe ".task_assignments" do
171
+ it "responds to task_assignments" do
172
+ expect(taskable).to respond_to('task_assignments')
173
+ end
174
+
175
+ it "finds the assignments" do
176
+ taskable.save
177
+ task1 = taskable.tasks.create(taskable: taskable, action: 'create')
178
+ task2 = taskable.tasks.create(taskable: taskable, action: 'update')
179
+ task1.assignments.create
180
+ task2.assignments.create
181
+ expect(taskable.task_assignments.size).to eq(2)
182
+ end
183
+ end
184
+
185
+ describe ".task_assignments_for_action" do
186
+ it "responds to task_assignments_for_action" do
187
+ expect(taskable).to respond_to('task_assignments_for_action')
188
+ end
189
+
190
+ it "finds the assignments" do
191
+ taskable.save
192
+ task1 = taskable.tasks.create(action: 'publish')
193
+ task2 = taskable.tasks.create(action: 'submit')
194
+ task1.assignments.create
195
+ task2.assignments.create
196
+ res = taskable.task_assignments_for_action('publish')
197
+ expect(res.size).to eq(1)
198
+ end
199
+
200
+ it "returns an empty array if if cannot find the task" do
201
+ res = taskable.task_assignments_for_action('review')
202
+ expect(res).to be_empty
203
+ end
204
+ end
205
+
206
+ describe ".task_assignment_for" do
207
+ it "requires an assignee" do
208
+ expect{ taskable.task_assignment_for('publish') }.to raise_error(ArgumentError)
209
+ end
210
+
211
+ it "calls assignment_for on task" do
212
+ task.should_receive(:assignment_for).with(assignee)
213
+ taskable.stub(:last_task_for_action).and_return(task)
214
+ taskable.task_assignment_for('publish', assignee)
215
+ end
216
+
217
+ it "returns nil if if cannot find the task" do
218
+ res = taskable.task_assignment_for('publish', assignee)
219
+ expect(res).to be_nil
220
+ end
221
+ end
222
+
223
+ describe ".complete_task_for_action" do
224
+
225
+ it "requires an action" do
226
+ expect{ taskable.complete_task_for_action }.to raise_error(ArgumentError)
227
+ end
228
+
229
+ it "calls complete! on the task" do
230
+ task = double.as_null_object
231
+ task.should_receive(:complete!)
232
+ taskable.stub(:last_task_for_action).and_return(task)
233
+ taskable.complete_task_for_action('publish')
234
+ end
235
+
236
+ it "return true" do
237
+ task = double.as_null_object
238
+ task.stub(:complete!).and_return(true)
239
+ taskable.stub(:last_task_for_action).and_return(task)
240
+ res = taskable.complete_task_for_action('publish')
241
+ expect(res).to be_true
242
+ end
243
+
244
+ it "returns false if it cannot find the task" do
245
+ res = taskable.complete_task_for_action('publish')
246
+ expect(res).to be_false
247
+ end
248
+ end
249
+
250
+ describe ".complete_task_for" do
251
+
252
+ it "requires an assignee" do
253
+ expect{ taskable.complete_task_for('publish') }.to raise_error(ArgumentError)
254
+ end
255
+
256
+ it "calls complete_by on task" do
257
+ task.should_receive(:complete_by).with(assignee)
258
+ taskable.stub(:last_task_for_action).and_return(task)
259
+ taskable.complete_task_for('publish', assignee)
260
+ end
261
+
262
+ it "returns true" do
263
+ task.stub(:complete_by).and_return(true)
264
+ taskable.stub(:last_task_for_action).and_return(task)
265
+ res = taskable.complete_task_for('publish', assignee)
266
+ expect(res).to be_true
267
+ end
268
+
269
+ it "returns false if it cannot find the task" do
270
+ res = taskable.complete_task_for('publish', assignee)
271
+ expect(res).to be_false
272
+ end
273
+ end
274
+
275
+ describe ".complete_tasks_for_action" do
276
+ it "returns false if it cannot find any tasks" do
277
+ res = taskable.complete_tasks_for_action('review')
278
+ expect(res).to be_false
279
+ end
280
+
281
+ it "sends complete! to all tasks" do
282
+ task1 = double.as_null_object
283
+ task2 = double.as_null_object
284
+ task1.should_receive(:complete!)
285
+ task2.should_receive(:complete!)
286
+ tasks = [task1, task2]
287
+ taskable.stub(:current_tasks_for_action).and_return(tasks)
288
+ res = taskable.complete_tasks_for_action('review')
289
+ end
290
+ end
291
+
292
+ describe ".expire_tasks_for_action" do
293
+ it "returns false if it cannot find any tasks" do
294
+ res = taskable.expire_tasks_for_action('review')
295
+ expect(res).to be_false
296
+ end
297
+
298
+ it "sends expire to all tasks" do
299
+ task1 = double.as_null_object
300
+ task2 = double.as_null_object
301
+ task1.should_receive(:expire)
302
+ task2.should_receive(:expire)
303
+ tasks = [task1, task2]
304
+ taskable.stub(:current_tasks_for_action).and_return(tasks)
305
+ res = taskable.expire_tasks_for_action('review')
306
+ end
307
+ end
308
+
309
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ describe 'BeTaskable::Tasker' do
4
+
5
+ let(:user) { User.new }
6
+ let(:task) { BeTaskable::Task.new }
7
+
8
+ it "responds to tasker?" do
9
+ expect(user).to be_tasker
10
+ end
11
+
12
+ it "responds to task_assignments" do
13
+ expect(user).to respond_to(:task_assignments)
14
+ end
15
+
16
+ it "has task assignments" do
17
+ user.save
18
+ task.save
19
+ assignment = BeTaskable::TaskAssignment.create(task: task, assignee: user)
20
+
21
+ expect(user.task_assignments.size).to eq(1)
22
+ end
23
+
24
+ end
data/spec/database.yml ADDED
@@ -0,0 +1,19 @@
1
+ sqlite3:
2
+ adapter: sqlite3
3
+ database: be_taskable.sqlite3
4
+
5
+ mysql:
6
+ adapter: mysql2
7
+ hostname: localhost
8
+ username: root
9
+ password:
10
+ database: be_taskable
11
+ charset: utf8
12
+
13
+ postgresql:
14
+ adapter: postgresql
15
+ hostname: localhost
16
+ username: postgres
17
+ password:
18
+ database: be_taskable
19
+ encoding: utf8
data/spec/models.rb ADDED
@@ -0,0 +1,38 @@
1
+ class User < ActiveRecord::Base
2
+ be_tasker
3
+ end
4
+
5
+ class Taskable < ActiveRecord::Base
6
+ be_taskable
7
+ end
8
+
9
+ class TaskablePublishTaskResolver < BeTaskable::TaskResolver
10
+ end
11
+
12
+ class TaskableReviewTaskResolver < BeTaskable::TaskResolver
13
+
14
+ def consensus?(assignments)
15
+ false
16
+ end
17
+
18
+ def assignees_for_task(task)
19
+ []
20
+ end
21
+
22
+ def due_date_for_assignment(assignment)
23
+ DateTime.now + 10.days
24
+ end
25
+
26
+ def label_for_task(task)
27
+ "Task label #{task.id}"
28
+ end
29
+
30
+ def label_for_assignment(assignment)
31
+ "Assignment label #{assignment.id}"
32
+ end
33
+
34
+ def url_for_assignment(assignment)
35
+ "Assignment url #{assignment.id}"
36
+ end
37
+
38
+ end
data/spec/schema.rb ADDED
@@ -0,0 +1,37 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+
3
+ create_table 'users', force: true do |t|
4
+ t.timestamps
5
+ end
6
+
7
+ create_table 'taskables', force: true do |t|
8
+ t.timestamps
9
+ end
10
+
11
+ create_table 'be_taskable_tasks', force: true do |t|
12
+ t.string :action
13
+ t.string :state
14
+ t.integer :taskable_id
15
+ t.string :taskable_type
16
+ t.string :label
17
+ t.datetime :completed_at
18
+ t.datetime :expired_at
19
+ t.timestamps
20
+ end
21
+
22
+ create_table 'be_taskable_task_assignments', force: true do |t|
23
+ t.integer :task_id
24
+ t.integer :assignee_id
25
+ t.string :assignee_type
26
+ t.string :label
27
+ t.string :url
28
+ t.boolean :confirmed
29
+ t.boolean :enacted
30
+ t.datetime :visible_at
31
+ t.datetime :complete_by
32
+ t.datetime :completed_at
33
+ t.datetime :expired_at
34
+ t.timestamps
35
+ end
36
+
37
+ end
@@ -0,0 +1,96 @@
1
+ # $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ # $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ # require 'gbg_tasks'
4
+
5
+ $LOAD_PATH << "." unless $LOAD_PATH.include?(".")
6
+ require 'logger'
7
+ require 'database_cleaner'
8
+ require 'active_record'
9
+ require 'action_view'
10
+ require 'action_controller'
11
+ require 'rspec/rails'
12
+ require 'rspec-steps'
13
+
14
+ # Make sure the right version of bundler is loaded
15
+ begin
16
+ require "rubygems"
17
+ require "bundler"
18
+
19
+ if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.5")
20
+ raise RuntimeError, "Your bundler version is too old. Run `gem install bundler` to upgrade."
21
+ end
22
+
23
+ # Set up load paths for all bundled gems
24
+ Bundler.setup
25
+ rescue Bundler::GemNotFound
26
+ raise RuntimeError, "Bundler couldn't find some gems. Did you run \`bundlee install\`?"
27
+ end
28
+
29
+ Bundler.require
30
+ require File.expand_path('../../lib/be_taskable', __FILE__)
31
+
32
+ # set adapter to use, default is sqlite3
33
+ # to use an alternative adapter run => rake spec DB='postgresql'
34
+ db_name = ENV['DB'] || 'sqlite3'
35
+ database_yml = File.expand_path('../database.yml', __FILE__)
36
+
37
+ # Load the data
38
+ if File.exists?(database_yml)
39
+ active_record_configuration = YAML.load_file(database_yml)
40
+
41
+ ActiveRecord::Base.configurations = active_record_configuration
42
+ config = ActiveRecord::Base.configurations[db_name]
43
+
44
+ begin
45
+ ActiveRecord::Base.establish_connection(db_name)
46
+ ActiveRecord::Base.connection
47
+ rescue
48
+ case db_name
49
+ when /mysql/
50
+ ActiveRecord::Base.establish_connection(config.merge('database' => nil))
51
+ ActiveRecord::Base.connection.create_database(config['database'], {:charset => 'utf8', :collation => 'utf8_unicode_ci'})
52
+ when 'postgresql'
53
+ ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public'))
54
+ ActiveRecord::Base.connection.create_database(config['database'], config.merge('encoding' => 'utf8'))
55
+ end
56
+
57
+ ActiveRecord::Base.establish_connection(config)
58
+ end
59
+
60
+ ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), "debug.log"))
61
+ ActiveRecord::Base.default_timezone = :utc
62
+
63
+ ActiveRecord::Base.silence do
64
+ ActiveRecord::Migration.verbose = false
65
+
66
+ load(File.dirname(__FILE__) + '/schema.rb')
67
+ load(File.dirname(__FILE__) + '/models.rb')
68
+ end
69
+
70
+ else
71
+ raise "Please create #{database_yml} first to configure your database. Take a look at: #{database_yml}.sample"
72
+ end
73
+
74
+ RSpec.configure do |config|
75
+ config.treat_symbols_as_metadata_keys_with_true_values = true
76
+ config.fail_fast = true
77
+
78
+ # Run specs in random order to surface order dependencies. If you find an
79
+ # order dependency and want to debug it, you can fix the order by providing
80
+ # the seed, which is printed after each run.
81
+ # --seed 1234
82
+ # config.order = "random"
83
+
84
+ config.before :suite do
85
+ DatabaseCleaner.strategy = :deletion
86
+ end
87
+
88
+ config.before(:each) do
89
+ DatabaseCleaner.start
90
+ end
91
+
92
+ config.after(:each) do
93
+ DatabaseCleaner.clean
94
+ end
95
+
96
+ end