omega-tariffs-base 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/spec/lib/init.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'spec'
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'omega-tariffs-base'))
4
+
5
+ include UniqSysOmega::Tariffs
@@ -0,0 +1,9 @@
1
+ require 'mocha'
2
+ require 'timecop'
3
+ require File.expand_path(File.join(File.dirname(__FILE__), 'active_record_classes_stub'))
4
+
5
+ Spec::Runner.configure do |config|
6
+ config.mock_with :mocha
7
+ end
8
+
9
+ DOESNT_MATTER = nil
@@ -0,0 +1,287 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'init'))
2
+
3
+ describe "PacketFilterRepository" do
4
+ before do
5
+ PacketFilterRepository.reset
6
+ @now = Time.now
7
+ end
8
+
9
+ it "should return nothing for non-existent regions" do
10
+ # yet unregistered region ...
11
+ PacketFilterRepository.region_registered?(1, 2).should == false
12
+ PacketFilterRepository.region_paid?(1, 2).should == false
13
+ end
14
+
15
+ it "should register regions" do
16
+ # register region
17
+ PacketFilterRepository.register_region(1, 2, @now, 3600)
18
+
19
+ # registered but not yet paid region ...
20
+ PacketFilterRepository.region_registered?(1, 2).should == true
21
+ PacketFilterRepository.region_paid?(1, 2).should == false
22
+ end
23
+
24
+ it "should register and commit payments" do
25
+ # register region
26
+ PacketFilterRepository.register_region(1, 2, @now, 3600)
27
+
28
+ # pay for the region ...
29
+ PacketFilterRepository.pay_region(1, 2)
30
+
31
+ # registered and paid region ...
32
+ PacketFilterRepository.region_registered?(1, 2).should == true
33
+ PacketFilterRepository.region_paid?(1, 2).should == true
34
+ end
35
+
36
+ it "should return false for other regions when current is paid" do
37
+ # register region
38
+ PacketFilterRepository.register_region(1, 2, @now, 3600)
39
+
40
+ # pay for the region ...
41
+ PacketFilterRepository.pay_region(1, 2)
42
+
43
+ # this is not the region ...
44
+ PacketFilterRepository.region_registered?(1, 2, @now-1).should == false
45
+ PacketFilterRepository.region_paid?(1, 2, @now-1).should == false
46
+
47
+ # this is still the region ...
48
+ PacketFilterRepository.region_registered?(1, 2, @now+1).should == true
49
+ PacketFilterRepository.region_paid?(1, 2, @now+1).should == true
50
+ end
51
+
52
+ it "should report spanning regions" do
53
+ # register region
54
+ PacketFilterRepository.register_region(1, 2, @now, 3600)
55
+
56
+ # check spanning
57
+ PacketFilterRepository.region_spans?(1, 2, @now, 1000).should == false
58
+ PacketFilterRepository.region_spans?(1, 2, @now, 3599).should == false
59
+ PacketFilterRepository.region_spans?(1, 2, @now, 3600).should == true
60
+ PacketFilterRepository.region_spans?(1, 2, @now, 5000).should == true
61
+ end
62
+
63
+ it "should not end by default" do
64
+ PacketFilterRepository.should_end?(1, 2).should == false
65
+ end
66
+
67
+ it "should_end call should return true" do
68
+ PacketFilterRepository.set_should_end(1, 2, @now+60).should == true
69
+ end
70
+
71
+ it "should end when it's scheduled" do
72
+ PacketFilterRepository.set_should_end(1, 2, @now+60)
73
+ PacketFilterRepository.should_end?(1, 2).should == false
74
+ Timecop.freeze(@now + 60) { PacketFilterRepository.should_end?(1, 2).should == false }
75
+ Timecop.freeze(@now + 61) { PacketFilterRepository.should_end?(1, 2).should == true }
76
+ end
77
+
78
+ it "should not interfere with the other users and tariffs" do
79
+ PacketFilterRepository.set_should_end(1, 2, @now-1)
80
+ PacketFilterRepository.should_end?(1, 2).should == true
81
+ PacketFilterRepository.should_end?(1, 3).should == false
82
+ PacketFilterRepository.should_end?(8, 2).should == false
83
+ end
84
+ end
85
+
86
+ describe "PacketFilter" do
87
+ before do
88
+ @settings = stub()
89
+ @settings.expects(:price).returns(100)
90
+ @settings.expects(:length).returns(3600)
91
+ @filter = PacketFilter.new(@settings, 1)
92
+
93
+ FinTransaction.reset_transactions
94
+ PacketFilterRepository.reset
95
+ Login.set_login_balance(1, 0)
96
+ end
97
+
98
+ describe "start_permitted?" do
99
+ it "should permit login if I have got close to enough money" do
100
+ Login.set_login_balance(1, 100)
101
+ @filter.start_permitted?(2, 1).should == true
102
+ end
103
+
104
+ it "should permit login if I have got enough money" do
105
+ Login.set_login_balance(1, 101)
106
+ @filter.start_permitted?(2, 1).should == true
107
+ end
108
+
109
+ it "should permit login if I haven't got enough money" do
110
+ Login.set_login_balance(1, 99)
111
+ @filter.start_permitted?(2, 1).should == false
112
+ end
113
+ end
114
+
115
+ describe "permitted?" do
116
+ it "should permit work if I have got close to enough money" do
117
+ Login.set_login_balance(1, 100)
118
+ @filter.permitted?(2, 1).should == true
119
+ end
120
+
121
+ it "should permit work if I have got enough money" do
122
+ Login.set_login_balance(1, 101)
123
+ @filter.permitted?(2, 1).should == true
124
+ end
125
+
126
+ it "should permit work if I haven't got enough money" do
127
+ Login.set_login_balance(1, 99)
128
+ @filter.permitted?(2, 1).should == false
129
+ end
130
+ end
131
+
132
+ def make_single_activity_processed
133
+ activity = Activity.new
134
+ activity.created_at = Time.now
135
+ activity.login_id = 1
136
+ activity.amount = 3600
137
+
138
+ ft = FinTransaction.template
139
+ ft.club_id, ft.author_id, ft.src_account_id, ft.dst_account_id = 1, 2, 3, 4
140
+
141
+ @filter.process_activity(activity, ft)
142
+ end
143
+
144
+ describe "calculate_cost" do
145
+ it "should return the price of the region unless paid" do
146
+ @filter.calculate_cost(2, 1, Time.now, 10).should == 100
147
+ @filter.calculate_cost(2, 1, Time.now, 3599).should == 100
148
+ @filter.calculate_cost(2, 1, Time.now, 3600).should == 100
149
+ @filter.calculate_cost(2, 1, Time.now, 3601).should == 100
150
+ end
151
+
152
+ it "should return the zero price of the region if paid and Integer::MAX out of the region" do
153
+ Login.set_login_balance(1, 100)
154
+
155
+ make_single_activity_processed.should == true
156
+
157
+ @filter.calculate_cost(2, 1, Time.now, 10).should == 0
158
+ @filter.calculate_cost(2, 1, Time.now, 3599).should == 0
159
+ @filter.calculate_cost(2, 1, Time.now, 3600).should == Integer::MAX
160
+ @filter.calculate_cost(2, 1, Time.now, 3605).should == Integer::MAX
161
+ end
162
+ end
163
+
164
+ describe "process_activity" do
165
+ it "should return unsuccessful activity processing if no money" do
166
+ Login.set_login_balance(1, 99)
167
+ make_single_activity_processed.should == false
168
+ end
169
+ end
170
+
171
+ describe "packet life time" do
172
+ def actualize_balance!
173
+ Login.set_login_balance(1, Login.find(1).balance - FinTransaction.transactions.sum)
174
+ FinTransaction.reset_transactions
175
+ end
176
+
177
+ def do_several_activities(offsets=[0])
178
+ ft = FinTransaction.template
179
+ ft.club_id, ft.author_id, ft.src_account_id, ft.dst_account_id = 1, 2, 3, 4
180
+
181
+ offsets.each do |offset|
182
+ activity = Activity.new
183
+ activity.created_at = Time.now + offset
184
+ activity.login_id = 1
185
+ activity.amount = 30
186
+ @filter.process_activity(activity, ft).should == true
187
+ end
188
+ end
189
+
190
+ it "should allow the packet to be opened once, if there's exact amount of money on the account as needed" do
191
+ now = Time.now
192
+
193
+ Timecop.freeze(now) do
194
+ Login.set_login_balance(1, 100)
195
+
196
+ @filter.start_permitted?(2, 1).should == true
197
+ @filter.permitted?(2, 1).should == true
198
+
199
+ Login.find(1).balance.should == 100
200
+ do_several_activities [ 0, 30, 60 ]
201
+ actualize_balance!
202
+ Login.find(1).balance.should == 0
203
+ end
204
+
205
+ [ [now + 1, true, true], [now + 3598, true, true], [now + 3599, false, false], [now + 3699, false, false]].each do |variant|
206
+ Timecop.freeze(variant[0]) do
207
+ @filter.start_permitted?(2, 1).should == variant[1]
208
+ @filter.permitted?(2, 1).should == variant[2]
209
+ end
210
+ end
211
+ end
212
+
213
+ it "should allow the packet to be opened once even if there's slightly more money on the account than needed" do
214
+ now = Time.now
215
+
216
+ Timecop.freeze(now) do
217
+ Login.set_login_balance(1, 105)
218
+
219
+ @filter.start_permitted?(2, 1).should == true
220
+ @filter.permitted?(2, 1).should == true
221
+
222
+ Login.find(1).balance.should == 105
223
+ do_several_activities [ 0, 30, 60 ]
224
+ actualize_balance!
225
+ Login.find(1).balance.should == 5
226
+ end
227
+
228
+ [ [now + 1, true, true], [now + 3598, true, true], [now + 3599, false, false], [now + 3699, false, false]].each do |variant|
229
+ Timecop.freeze(variant[0]) do
230
+ @filter.start_permitted?(2, 1).should == variant[1]
231
+ @filter.permitted?(2, 1).should == variant[2]
232
+ end
233
+ end
234
+ end
235
+
236
+ it "should allow the packet to be opened twice if there is enough money, and the user should be charged twice" do
237
+ now = Time.now
238
+
239
+ Timecop.freeze(now) do
240
+ Login.set_login_balance(1, 205)
241
+
242
+ @filter.start_permitted?(2, 1).should == true
243
+ @filter.permitted?(2, 1).should == true
244
+
245
+ Login.find(1).balance.should == 205
246
+ do_several_activities [ 0, 30, 60 ]
247
+ actualize_balance!
248
+ Login.find(1).balance.should == 105
249
+ end
250
+
251
+ # check end of the single session
252
+ [ [now + 1, true], [now + 3600, true], [now + 3601, false], [now + 3699, false]].each do |variant|
253
+ Timecop.freeze(variant[0]) do
254
+ @filter.permitted?(2, 1).should == variant[1]
255
+ end
256
+ end
257
+
258
+ # check if start_permitted? resets permitted? flag
259
+ [ [now + 1, true, true], [now + 3599, true, true], [now + 3600, true, true], [now + 3699, true, true]].each do |variant|
260
+ Timecop.freeze(variant[0]) do
261
+ @filter.start_permitted?(2, 1).should == variant[1]
262
+ @filter.permitted?(2, 1).should == variant[2]
263
+ end
264
+ end
265
+
266
+ now += 3610
267
+
268
+ Timecop.freeze(now) do
269
+ @filter.start_permitted?(2, 1).should == true
270
+ @filter.permitted?(2, 1).should == true
271
+
272
+ Login.find(1).balance.should == 105
273
+ do_several_activities [ 0, 30, 60 ]
274
+ actualize_balance!
275
+ Login.find(1).balance.should == 5
276
+ end
277
+
278
+ # check if permitted? and start_permitted? are in the correct state
279
+ [ [now + 1, true, true], [now + 3598, true, true], [now + 3599, false, false], [now + 3699, false, false]].each do |variant|
280
+ Timecop.freeze(variant[0]) do
281
+ @filter.start_permitted?(2, 1).should == variant[1]
282
+ @filter.permitted?(2, 1).should == variant[2]
283
+ end
284
+ end
285
+ end
286
+ end
287
+ end
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'init'))
2
+
3
+ describe "RateFilter" do
4
+ RATE = 123
5
+
6
+ before do
7
+ settings = mock()
8
+ settings.expects(:rate).returns(RATE)
9
+ @filter = RateFilter.new(settings, 0)
10
+ end
11
+
12
+ it "should permit start" do
13
+ @filter.start_permitted?(1, 2, 3).should == true
14
+ end
15
+
16
+ it "should permit going on" do
17
+ @filter.permitted?(1, 2, 3).should == true
18
+ end
19
+
20
+ it "should calculate the correct amount" do
21
+ @filter.calculate_cost(1, 2, 3, 3600).should == RATE
22
+ end
23
+
24
+ it "should process activity correctly" do
25
+ activity = mock()
26
+ activity.expects(:amount).returns(3600)
27
+
28
+ ft = FinTransaction.template
29
+ ft.club_id, ft.author_id, ft.src_account_id, ft.dst_account_id = 1, 2, 3, 4
30
+
31
+ FinTransaction.any_instance.expects(:volume=).with(RATE)
32
+ FinTransaction.any_instance.expects(:valid?).returns(true)
33
+
34
+ @filter.process_activity(activity, ft).should == true
35
+ end
36
+ end
@@ -0,0 +1,250 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'lib', 'init'))
2
+
3
+ class RepeatingMockFilter1 < Filter
4
+ def calculate_cost(computer_id, login_id, started_at, amount, options={})
5
+ Rational(amount.to_i*100, 3600)
6
+ end
7
+
8
+ def process_activity(unprocessed_activity, ft, options={})
9
+ ft = ft.dup
10
+ ft.volume = Rational(unprocessed_activity.amount.to_i*100, 3600)
11
+ ft.save!
12
+ true
13
+ end
14
+ end
15
+
16
+ class RepeatingMockFilter2 < Filter
17
+ def calculate_cost(computer_id, login_id, started_at, amount, options={})
18
+ Rational(amount.to_i*200, 3600)
19
+ end
20
+
21
+ def process_activity(unprocessed_activity, ft, options={})
22
+ ft = ft.dup
23
+ ft.volume = Rational(unprocessed_activity.amount.to_i*200, 3600)
24
+ ft.save!
25
+ true
26
+ end
27
+ end
28
+
29
+ class RepeatingMockFilter3 < Filter
30
+ def calculate_cost(computer_id, login_id, started_at, amount, options={})
31
+ Rational(amount.to_i*300, 3600)
32
+ end
33
+
34
+ def process_activity(unprocessed_activity, ft, options={})
35
+ ft = ft.dup
36
+ ft.volume = Rational(unprocessed_activity.amount.to_i*300, 3600)
37
+ ft.save!
38
+ true
39
+ end
40
+ end
41
+
42
+ class RepeatingMockFilterWithOptionsExpectations < Filter
43
+ end
44
+
45
+
46
+ describe "RepeatingFilterPeriod" do
47
+ it "should not allow to create invalid period" do
48
+ lambda {
49
+ RepeatingFilterPeriod.new(Time.now, 300, 200, stub())
50
+ }.should raise_error
51
+ end
52
+
53
+ it "should allow valid period creation" do
54
+ RepeatingFilterPeriod.new(Time.now, 300, 300, stub())
55
+ RepeatingFilterPeriod.new(Time.now, 123, 200, stub())
56
+ end
57
+
58
+ it "should set filter value" do
59
+ filtah = stub()
60
+ RepeatingFilterPeriod.new(Time.now, 300, 300, filtah).filter.should == filtah
61
+ end
62
+
63
+ it "should delegate filter value when generating ranges" do
64
+ filtah, now = stub(), Time.now
65
+ periods = RepeatingFilterPeriod.new(now, 100, 200, filtah).generate_in_range(now-1, now + 410)
66
+ periods.each { |p| p.filter.should == filtah }
67
+ end
68
+
69
+ it "should recur correctly" do
70
+ test_start_time = Time.now
71
+
72
+ period = RepeatingFilterPeriod.new(test_start_time, 2*3600, 86400, stub())
73
+
74
+ # today
75
+ period.includes?(test_start_time).should == true
76
+ period.includes?(test_start_time+123).should == true
77
+ period.includes?(test_start_time+7199).should == true
78
+ period.includes?(test_start_time+7200).should == false
79
+ period.includes?(test_start_time+56124).should == false
80
+ period.includes?(test_start_time+86399).should == false
81
+
82
+ # tomorrow
83
+ period.includes?(test_start_time+86400).should == true
84
+ period.includes?(test_start_time+86400+123).should == true
85
+ period.includes?(test_start_time+86400+7199).should == true
86
+ period.includes?(test_start_time+86400+7200).should == false
87
+ period.includes?(test_start_time+86400+56124).should == false
88
+ period.includes?(test_start_time+86400+86399).should == false
89
+ end
90
+
91
+ it "should support === operator to behave exactly like includes?" do
92
+ period = RepeatingFilterPeriod.new(Time.now, 2*3600, 86400, stub())
93
+ period.expects(:includes?).with(1024).returns(:thats_what_include_returns)
94
+ (period === 1024).should == :thats_what_include_returns
95
+ end
96
+
97
+ it "should generate correct ranges array" do
98
+ test_start_time = Time.now
99
+
100
+ period = RepeatingFilterPeriod.new(test_start_time, 2*3600, 86400, stub())
101
+
102
+ ranges = period.generate_in_range(test_start_time, test_start_time+86400).map { |r| r.as_range }
103
+ ranges.should == [ (test_start_time.to_i ... test_start_time.to_i+2*3600) ]
104
+
105
+ ranges = period.generate_in_range(test_start_time, test_start_time+45000).map { |r| r.as_range }
106
+ ranges.should == [ (test_start_time.to_i ... test_start_time.to_i+2*3600) ]
107
+
108
+ ranges = period.generate_in_range(test_start_time, test_start_time+2*86400).map { |r| r.as_range }
109
+ ranges.should == [ (test_start_time.to_i ... test_start_time.to_i+2*3600), (test_start_time.to_i+86400 ... test_start_time.to_i+86400+2*3600) ]
110
+
111
+ ranges = period.generate_in_range(test_start_time, test_start_time+1024*86400).map { |r| r.as_range }
112
+ ranges.size.should == 1024
113
+ end
114
+
115
+ it "should return correct variant of the localized period" do
116
+ test_start_time = Time.now
117
+ period = RepeatingFilterPeriod.new(test_start_time, 2*3600, 86400, stub())
118
+ period.local_period(test_start_time+30.days+10.seconds).as_range.should ==
119
+ ((test_start_time+30*86400).to_i ... (test_start_time+2*3600+30*86400).to_i)
120
+ end
121
+ end
122
+
123
+ describe "SortableRange" do
124
+ it "should sort the correct way" do
125
+ r_1_3 = SortableRange.new(1, 3)
126
+ r_5_9 = SortableRange.new(5, 9)
127
+ r_16_18= SortableRange.new(16, 18)
128
+ [ r_5_9, r_1_3, r_16_18 ].sort.should == [ r_1_3, r_5_9, r_16_18 ]
129
+ end
130
+
131
+ it "should return corresponding Range object" do
132
+ SortableRange.new(10, 13).as_range.should == Range.new(10,13)
133
+ end
134
+
135
+ it "should have filter field" do
136
+ r = SortableRange.new(10, 13)
137
+ r.filter = 123
138
+ r.filter.should == 123
139
+ end
140
+ end
141
+
142
+ describe "RepeatingFilter" do
143
+ before do
144
+ now = Time.at(0)
145
+ @settings = Settings.new({
146
+ { :starts_at => now, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilter1", :settings => { :vasya => "pupkin" } },
147
+ { :starts_at => now+3600, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilter2", :settings => { :vasya => "vanin" } },
148
+ { :starts_at => now+7200, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilter3", :settings => { :vasya => "vanin" } }
149
+ })
150
+ @filter = RepeatingFilter.new(@settings, 0)
151
+ end
152
+
153
+ it "should not instantinate when periods are not cosistent" do
154
+ now = Time.at(0)
155
+ settings = Settings.new({
156
+ { :starts_at => now, :length => 100, :period => 300 } => { :klass => "RepeatingMockFilter1", :settings => { :vasya => "pupkin" } },
157
+ { :starts_at => now+100, :length => 100, :period => 300 } => { :klass => "RepeatingMockFilter2", :settings => { :vasya => "vanin" } }
158
+ })
159
+
160
+ lambda {
161
+ filter = RepeatingFilter.new(settings, 0)
162
+ }.should raise_error(Exception, /Inconsistent periods/)
163
+ end
164
+
165
+ it "should not instantinate when periods are intersecting" do
166
+ now = Time.at(0)
167
+ settings = Settings.new({
168
+ { :starts_at => now, :length => 95, :period => 301 } => { :klass => "RepeatingMockFilter1", :settings => { :vasya => "pupkin" } },
169
+ { :starts_at => now+100, :length => 100, :period => 300 } => { :klass => "RepeatingMockFilter2", :settings => { :vasya => "vanin" } },
170
+ { :starts_at => now+200, :length => 100, :period => 300 } => { :klass => "RepeatingMockFilter3", :settings => { :vasya => "vanin" } },
171
+ })
172
+
173
+ lambda {
174
+ filter = RepeatingFilter.new(settings, 0)
175
+ }.should raise_error(Exception, /Intersectings periods/)
176
+ end
177
+
178
+ it "should calculate cost correctly" do
179
+ @filter.calculate_cost(1, 2, Time.at(0), 3600).should == 100
180
+ @filter.calculate_cost(1, 2, Time.at(3600), 3600).should == 200
181
+ @filter.calculate_cost(1, 2, Time.at(7200), 3600).should == 300
182
+
183
+ @filter.calculate_cost(1, 2, Time.at(0), 7*24*3600).should == 33600
184
+ @filter.calculate_cost(1, 2, Time.at(3600+1800), 7*24*3600).should == 33600
185
+
186
+ @filter.calculate_cost(1, 2, Time.at(3600+1800), 3600+1800).should == 400
187
+ end
188
+
189
+ it "should process activities correctly spanning them" do
190
+ unprocessed_activity = Activity.new
191
+ unprocessed_activity.expects(:created_at).returns(Time.at(0)).at_least_once
192
+ unprocessed_activity.expects(:amount).returns(7*24*3600).at_least_once
193
+
194
+ ft = FinTransaction.template
195
+ ft.author_id = 1
196
+ ft.club_id = 2
197
+
198
+ FinTransaction.reset_transactions
199
+ @filter.process_activity(unprocessed_activity, ft).should == true
200
+ FinTransaction.transactions.inject(&:+).should == 33600
201
+ end
202
+
203
+ it "should process activities correctly spanning them (strict check)" do
204
+ unprocessed_activity = Activity.new
205
+ unprocessed_activity.expects(:created_at).returns(Time.at(0)).at_least_once
206
+ unprocessed_activity.expects(:amount).returns(3600*4+1800).at_least_once
207
+
208
+ ft = FinTransaction.template
209
+ ft.author_id = 1
210
+ ft.club_id = 2
211
+
212
+ FinTransaction.reset_transactions
213
+ @filter.process_activity(unprocessed_activity, ft).should == true
214
+ FinTransaction.transactions.should == [ 100, 200, 300, 100, 100 ]
215
+ end
216
+
217
+ it "should pass on the options to the underlying filter and add its own" do
218
+ doesnt_matter = nil
219
+ now = Time.at(0)
220
+ settings = Settings.new({
221
+ { :starts_at => now, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilterWithOptionsExpectations", :settings => { :vasya => "pupkin" } },
222
+ { :starts_at => now+3600, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilter2", :settings => { :vasya => "vanin" } },
223
+ { :starts_at => now+7200, :length => 3600, :period => 10800 } => { :klass => "RepeatingMockFilter3", :settings => { :vasya => "vanin" } }
224
+ })
225
+
226
+ filter = RepeatingFilter.new(settings, 0)
227
+
228
+ [ 0, 3600*3 ].each do |offset|
229
+ RepeatingMockFilterWithOptionsExpectations.any_instance.tap do |it|
230
+ it.expects(:calculate_cost).with(anything, anything, anything, anything, equals({:my => :options, :period => (0+offset...3600+offset)})).returns(0)
231
+ it.expects(:start_permitted?).with(anything, anything, equals({:my => :options, :period => (0+offset...3600+offset)})).returns(true)
232
+ it.expects(:permitted?).with(anything, anything, equals({:my => :options, :period => (0+offset...3600+offset)})).returns(true)
233
+ it.expects(:process_activity).with(anything, anything, equals({:my => :options, :period => (0+offset...3600+offset)})).returns(true)
234
+ end
235
+
236
+ Timecop.freeze(now + offset) do
237
+ ft_doesnt_matter = stub_everything()
238
+
239
+ activity_doesnt_matter = Activity.new
240
+ activity_doesnt_matter.stubs(:created_at).returns(Time.now + 30.seconds).at_least_once
241
+ activity_doesnt_matter.stubs(:amount).returns(3600).at_least_once
242
+
243
+ filter.calculate_cost(doesnt_matter, doesnt_matter, Time.now + 30.seconds, 3600, { :my => :options })
244
+ filter.start_permitted?(doesnt_matter, doesnt_matter, { :my => :options })
245
+ filter.permitted?(doesnt_matter, doesnt_matter, { :my => :options })
246
+ filter.process_activity(activity_doesnt_matter, ft_doesnt_matter, { :my => :options })
247
+ end
248
+ end
249
+ end
250
+ end