neuron-client 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/README.md +11 -8
  2. data/lib/neuron-client/api.rb +5 -0
  3. data/lib/neuron-client/model/ad.rb +142 -0
  4. data/lib/neuron-client/model/ad_calculations.rb +325 -0
  5. data/lib/neuron-client/model/ad_zone.rb +45 -0
  6. data/lib/neuron-client/model/base.rb +233 -18
  7. data/lib/neuron-client/model/blocked_referer.rb +20 -0
  8. data/lib/neuron-client/model/blocked_user_agent.rb +21 -0
  9. data/lib/neuron-client/model/geo_target.rb +36 -0
  10. data/lib/neuron-client/model/pixel.rb +22 -0
  11. data/lib/neuron-client/model/report.rb +35 -0
  12. data/lib/neuron-client/model/s3_file.rb +30 -0
  13. data/lib/neuron-client/model/zone.rb +64 -0
  14. data/lib/neuron-client/model/zone_calculations.rb +37 -0
  15. data/lib/neuron-client/schema/ad.rb +406 -0
  16. data/lib/neuron-client/schema/ad_zone.rb +49 -0
  17. data/lib/neuron-client/schema/blocked_referer.rb +52 -0
  18. data/lib/neuron-client/schema/blocked_user_agent.rb +64 -0
  19. data/lib/neuron-client/schema/common.rb +220 -0
  20. data/lib/neuron-client/schema/event.rb +17 -0
  21. data/lib/neuron-client/schema/geo_target.rb +33 -0
  22. data/lib/neuron-client/schema/pixel.rb +39 -0
  23. data/lib/neuron-client/schema/report.rb +59 -0
  24. data/lib/neuron-client/schema/s3_file.rb +87 -0
  25. data/lib/neuron-client/schema/zone.rb +214 -0
  26. data/lib/neuron-client/version.rb +1 -1
  27. data/lib/neuron-client.rb +24 -59
  28. data/neuron-client.gemspec +3 -0
  29. data/spec/lib/admin_connection_spec.rb +234 -0
  30. data/spec/lib/api_spec.rb +41 -63
  31. data/spec/lib/model/ad_calculations_spec.rb +1146 -0
  32. data/spec/lib/model/ad_spec.rb +253 -0
  33. data/spec/lib/model/ad_zone_spec.rb +15 -0
  34. data/spec/lib/model/base_spec.rb +5 -83
  35. data/spec/lib/model/blocked_referer_spec.rb +36 -0
  36. data/spec/lib/model/blocked_user_agent_spec.rb +36 -0
  37. data/spec/lib/model/geo_target_spec.rb +28 -0
  38. data/spec/lib/model/pixel_spec.rb +36 -0
  39. data/spec/lib/model/report_spec.rb +17 -0
  40. data/spec/lib/{s3_file_spec.rb → model/s3_file_spec.rb} +6 -5
  41. data/spec/lib/model/zone_calculations_spec.rb +49 -0
  42. data/spec/lib/model/zone_spec.rb +155 -0
  43. data/spec/lib/schema/ad_spec.rb +515 -0
  44. data/spec/lib/schema/ad_zone_spec.rb +149 -0
  45. data/spec/lib/schema/blocked_referer_spec.rb +136 -0
  46. data/spec/lib/schema/blocked_user_agent_spec.rb +147 -0
  47. data/spec/lib/schema/geo_target_spec.rb +92 -0
  48. data/spec/lib/schema/pixel_spec.rb +125 -0
  49. data/spec/lib/schema/report_spec.rb +129 -0
  50. data/spec/lib/schema/s3_file_spec.rb +164 -0
  51. data/spec/lib/schema/zone_spec.rb +243 -0
  52. data/spec/spec_helper.rb +2 -1
  53. metadata +141 -121
  54. data/lib/neuron-client/model/admin/ad.rb +0 -22
  55. data/lib/neuron-client/model/admin/ad_zone.rb +0 -15
  56. data/lib/neuron-client/model/admin/base.rb +0 -91
  57. data/lib/neuron-client/model/admin/blocked_referer.rb +0 -12
  58. data/lib/neuron-client/model/admin/blocked_user_agent.rb +0 -12
  59. data/lib/neuron-client/model/admin/geo_target.rb +0 -16
  60. data/lib/neuron-client/model/admin/pixel.rb +0 -12
  61. data/lib/neuron-client/model/admin/report.rb +0 -15
  62. data/lib/neuron-client/model/admin/s3_file.rb +0 -12
  63. data/lib/neuron-client/model/admin/zone.rb +0 -15
  64. data/lib/neuron-client/model/common/ad.rb +0 -42
  65. data/lib/neuron-client/model/common/ad_calculations.rb +0 -329
  66. data/lib/neuron-client/model/common/ad_zone.rb +0 -17
  67. data/lib/neuron-client/model/common/base.rb +0 -67
  68. data/lib/neuron-client/model/common/blocked_referer.rb +0 -16
  69. data/lib/neuron-client/model/common/blocked_user_agent.rb +0 -16
  70. data/lib/neuron-client/model/common/geo_target.rb +0 -16
  71. data/lib/neuron-client/model/common/pixel.rb +0 -18
  72. data/lib/neuron-client/model/common/report.rb +0 -21
  73. data/lib/neuron-client/model/common/s3_file.rb +0 -16
  74. data/lib/neuron-client/model/common/zone.rb +0 -22
  75. data/lib/neuron-client/model/common/zone_calculations.rb +0 -41
  76. data/lib/neuron-client/model/membase/ad.rb +0 -49
  77. data/lib/neuron-client/model/membase/ad_zone.rb +0 -11
  78. data/lib/neuron-client/model/membase/blocked_referer.rb +0 -20
  79. data/lib/neuron-client/model/membase/blocked_user_agent.rb +0 -20
  80. data/lib/neuron-client/model/membase/geo_target.rb +0 -11
  81. data/lib/neuron-client/model/membase/pixel.rb +0 -22
  82. data/lib/neuron-client/model/membase/report.rb +0 -11
  83. data/lib/neuron-client/model/membase/s3_file.rb +0 -11
  84. data/lib/neuron-client/model/membase/zone.rb +0 -30
  85. data/lib/neuron-client/model/models.rb +0 -15
  86. data/spec/lib/model/admin/ad_spec.rb +0 -34
  87. data/spec/lib/model/admin/ad_zone_spec.rb +0 -19
  88. data/spec/lib/model/admin/base_spec.rb +0 -11
  89. data/spec/lib/model/admin/blocked_referer_spec.rb +0 -11
  90. data/spec/lib/model/admin/blocked_user_agent_spec.rb +0 -11
  91. data/spec/lib/model/admin/geo_target_spec.rb +0 -30
  92. data/spec/lib/model/admin/report_spec.rb +0 -21
  93. data/spec/lib/model/admin/s3_spec.rb +0 -11
  94. data/spec/lib/model/admin/zone_spec.rb +0 -21
  95. data/spec/lib/model/common/ad_calculations_spec.rb +0 -1151
  96. data/spec/lib/model/common/ad_spec.rb +0 -11
  97. data/spec/lib/model/common/ad_zone_spec.rb +0 -11
  98. data/spec/lib/model/common/base_spec.rb +0 -11
  99. data/spec/lib/model/common/blocked_referer_spec.rb +0 -11
  100. data/spec/lib/model/common/blocked_user_agent_spec.rb +0 -11
  101. data/spec/lib/model/common/geo_target_spec.rb +0 -11
  102. data/spec/lib/model/common/report_spec.rb +0 -11
  103. data/spec/lib/model/common/s3_spec.rb +0 -11
  104. data/spec/lib/model/common/zone_calculations_spec.rb +0 -54
  105. data/spec/lib/model/common/zone_spec.rb +0 -11
  106. data/spec/lib/model/membase/ad_spec.rb +0 -54
  107. data/spec/lib/model/membase/ad_zone_spec.rb +0 -11
  108. data/spec/lib/model/membase/base_spec.rb +0 -11
  109. data/spec/lib/model/membase/blocked_referer_spec.rb +0 -34
  110. data/spec/lib/model/membase/blocked_user_agent_spec.rb +0 -34
  111. data/spec/lib/model/membase/geo_target_spec.rb +0 -11
  112. data/spec/lib/model/membase/pixel_spec.rb +0 -34
  113. data/spec/lib/model/membase/report_spec.rb +0 -11
  114. data/spec/lib/model/membase/s3_spec.rb +0 -11
  115. data/spec/lib/model/membase/zone_spec.rb +0 -32
  116. data/spec/lib/old_spec.rb +0 -437
@@ -1,1151 +0,0 @@
1
- module Neuron
2
- module Client
3
- module Model
4
- module Common
5
-
6
- class FakeAd
7
- include AdCalculations
8
- attr_accessor :start_datetime, :end_datetime, :time_zone, :day_partitions,
9
- :daily_cap, :overall_cap, :ideal_impressions_per_hour, :total_impressed,
10
- :today_impressed
11
- def initialize(opts={})
12
- opts.each { |sym, value| self.send("#{sym}=", value) }
13
- self.time_zone ||= "Beijing"
14
- self.total_impressed ||= 0
15
- self.today_impressed ||= 0
16
- end
17
- end
18
-
19
- describe AdCalculations do
20
- context "given an Ad with date range Sat, 01 Jan 2011, 00:00 -> Tue, 01 Feb 2011, 12:00; Beijing time; Day parted for 9:00 - 17:00, M-F; Daily cap of 10; Overall cap of 100; total_impressed of 50; today_impressed of 5" do
21
- before(:each) do
22
- @time_zone = "Beijing"
23
- Time.zone = @time_zone
24
- Chronic.time_class = Time.zone
25
- @ad = FakeAd.new(
26
- :start_datetime => Chronic.parse("2011-01-01 00:00"),
27
- :end_datetime => Chronic.parse("2011-02-01 12:00"),
28
- :time_zone => "Beijing",
29
- :day_partitions => "F"*24 + ("F"*9 + "T"*8 + "F"*7)*5 + "F"*24,
30
- :daily_cap => 10,
31
- :overall_cap => 100,
32
- :ideal_impressions_per_hour => nil,
33
- :total_impressed => 50,
34
- :today_impressed => 5
35
- )
36
- end
37
- it "should be inactive on December 10th, 2010" do
38
- Timecop.freeze(Chronic.parse("2010-12-10")) do
39
- @ad.active?.should be_false
40
- end
41
- end
42
- it "should be inactive on January 1st, 2011" do
43
- Timecop.freeze(Chronic.parse("2011-01-01 10:00")) do
44
- @ad.active?.should be_false
45
- end
46
- end
47
- it "should be inactive on January 3rd, 2011 at 5:00 AM" do
48
- Timecop.freeze(Chronic.parse("2011-01-03 05:00")) do
49
- @ad.active?.should be_false
50
- end
51
- end
52
- context "on January 3rd, 2011 at 10:00 AM" do
53
- before(:each) { Timecop.freeze(Chronic.parse("2011-01-03 10:00")) }
54
- after(:each) { Timecop.return }
55
- it "should be active" do
56
- @ad.active?.should be_true
57
- end
58
- it "should have a pressure of 10/7" do
59
- @ad.pressure.should == 10 / 7.0
60
- end
61
- end
62
- context "on January 3rd, 2011 at 16:00" do
63
- before(:each) { Timecop.freeze(Chronic.parse("2011-1-3 16:00")) }
64
- after(:each) { Timecop.return }
65
- it "should be active" do
66
- @ad.active?.should be_true
67
- end
68
- it "should have a pressure of 10/1" do
69
- @ad.pressure.should == 10
70
- end
71
- end
72
- context "on January 27th, 2011 at 16:00" do
73
- before(:each) { Timecop.freeze(Chronic.parse("2011-1-27 16:00")) }
74
- after(:each) { Timecop.return }
75
- it "should be active" do
76
- @ad.active?.should be_true
77
- end
78
- it "should have a pressure of 50/20" do
79
- @ad.pressure.should == 50 / 20.0
80
- end
81
- end
82
- it "should be inactive on February 1st, 2011 at 13:00" do
83
- Timecop.freeze(Chronic.parse("2011-2-1 13:00")) do
84
- @ad.active?.should be_false
85
- end
86
- end
87
- end
88
-
89
- describe ".active?" do
90
- it "should call calculate_active?" do
91
- @ad = FakeAd.new
92
- @ad.should_receive(:calculate_active?).and_return(:result)
93
-
94
- @ad.active?.should == :result
95
- end
96
- end
97
-
98
- describe ".pressure" do
99
- it "should call calculate_pressure" do
100
- @ad = FakeAd.new
101
- @ad.should_receive(:calculate_pressure).and_return(:result)
102
-
103
- @ad.pressure.should == :result
104
- end
105
- end
106
-
107
- describe ".calculate_active?(time, total_impressed, today_impressed)" do
108
- it "should have specs"
109
- end
110
-
111
- describe ".calculate_pressure(time, total_impressed, today_impressed, active=nil)" do
112
- it "should have some specs related to when 'active' is passed in"
113
- context "when daily_cap is present" do
114
- context "and daily_cap precludes overall_cap from being met" do
115
- it "should calculate the overall pressure" do
116
- ad = FakeAd.new(:daily_cap => 10)
117
- ad.stub(:daily_cap_precludes_overall_cap?).and_return(true)
118
- ad.should_receive(:calculate_overall_pressure)
119
- ad.should_not_receive(:calculate_today_pressure)
120
-
121
- ad.calculate_pressure(Time.now, 50, 5)
122
- end
123
- end
124
- context "and daily_cap does not preclude the overall_cap from being met" do
125
- it "should calculate the pressure for just today" do
126
- ad = FakeAd.new(:daily_cap => 10)
127
- ad.stub(:daily_cap_precludes_overall_cap?).and_return(false)
128
- ad.should_not_receive(:calculate_overall_pressure)
129
- ad.should_receive(:calculate_today_pressure)
130
-
131
- ad.calculate_pressure(Time.now, 50, 5)
132
- end
133
- end
134
- end
135
- context "when daily_cap is not present" do
136
- context "when overall_cap is blank or end_datetime is blank" do
137
- it "should use the ideal_impressions_per_hour" do
138
- ad = FakeAd.new(:overall_cap => 100, :ideal_impressions_per_hour => 99.9)
139
- ad.should_not_receive(:calculate_overall_pressure)
140
- ad.should_not_receive(:calculate_today_pressure)
141
-
142
- ad.calculate_pressure(Time.now, 50, 5).should == 99.9
143
- end
144
- end
145
- context "when overall_cap is not blank and end_datetime is not blank" do
146
- it "should calculate the overall pressure" do
147
- ad = FakeAd.new(:overall_cap => 100, :end_datetime => Time.now + 1.month)
148
- ad.should_receive(:calculate_overall_pressure)
149
- ad.should_not_receive(:calculate_today_pressure)
150
-
151
- ad.calculate_pressure(Time.now, 50, 5)
152
- end
153
- end
154
- end
155
- end
156
-
157
-
158
- describe ".start_in_time_zone" do
159
- it "should return start_datetime, time zone adjusted" do
160
- result = FakeAd.new(
161
- :start_datetime => Time.utc(2011, 2, 1, 1, 59),
162
- :time_zone => 'Eastern Time (US & Canada)'
163
- ).send(:start_in_time_zone)
164
- formatted_result = "#{result.time.strftime('%a, %d %b %Y %H:%M:%S')} #{result.zone} #{result.formatted_offset}"
165
-
166
- formatted_result.should == "Mon, 31 Jan 2011 20:59:00 EST -05:00"
167
- end
168
- end
169
-
170
- describe ".end_in_time_zone" do
171
- context "when end_datetime is present" do
172
- it "should return end_datetime, time zone adjusted" do
173
- result = FakeAd.new(
174
- :end_datetime => Time.utc(2011, 2, 1, 1, 59),
175
- :time_zone => 'Eastern Time (US & Canada)'
176
- ).send(:end_in_time_zone)
177
- formatted_result = "#{result.time.strftime('%a, %d %b %Y %H:%M:%S')} #{result.zone} #{result.formatted_offset}"
178
-
179
- formatted_result.should == "Mon, 31 Jan 2011 20:59:00 EST -05:00"
180
- end
181
- end
182
- context "when end_datetime is not present" do
183
- it "should return nil" do
184
- FakeAd.new(:end_datetime => nil).send(:end_in_time_zone).should be_nil
185
- end
186
- end
187
- end
188
-
189
- describe ".daily_capped?" do
190
- it "should be false when daily_cap is nil" do
191
- FakeAd.new(:daily_cap => nil).send(:daily_capped?).should be_false
192
- end
193
- it "should be true when daily_cap is a positive integer > zero" do
194
- FakeAd.new(:daily_cap => 42).send(:daily_capped?).should be_true
195
- end
196
- end
197
-
198
- describe ".overall_capped?" do
199
- it "should be false when overall_cap is nil" do
200
- FakeAd.new(:overall_cap => nil).send(:overall_capped?).should be_false
201
- end
202
- it "should be true when overall_cap is a positive integer > zero" do
203
- FakeAd.new(:overall_cap => 42).send(:overall_capped?).should be_true
204
- end
205
- end
206
-
207
- describe ".partitioned?" do
208
- it "should be false when day_partitions is nil" do
209
- FakeAd.new(:day_partitions => nil).send(:partitioned?).should be_false
210
- end
211
- it "should be true when day_partitions is 168 character string of Ts and Fs." do
212
- p = ("T"*100 + "F"*68).split('').shuffle.join
213
- FakeAd.new(:day_partitions => p).send(:partitioned?).should be_true
214
- end
215
- end
216
-
217
- def within_date_range
218
- FakeAd.new(:start_datetime => @start, :end_datetime => @end).send(:within_date_range?, @now)
219
- end
220
-
221
- describe ".within_date_range?(date)" do
222
- before(:all) do
223
- @now = Time.now
224
- end
225
- context "when ad has no start date" do
226
- context "when ad has no end date" do
227
- it "should return true" do
228
- @start = nil
229
- @end = nil
230
- within_date_range.should be_true
231
- end
232
- end
233
- context "when before ad's end date" do
234
- it "should return true" do
235
- @start = nil
236
- @end = @now + 1.day
237
- within_date_range.should be_true
238
- end
239
- end
240
- context "when on or beyond ad's end date" do
241
- it "should return false" do
242
- @start = nil
243
- @end = @now
244
- within_date_range.should be_false
245
- @end = @now - 1.day
246
- within_date_range.should be_false
247
- end
248
- end
249
- end
250
- context "when before ad's start date" do
251
- context "when ad has no end date" do
252
- it "should return false" do
253
- @start = @now + 1.day
254
- @end = nil
255
- within_date_range.should be_false
256
- end
257
- end
258
- context "when before ad's end date" do
259
- it "should return false" do
260
- @start = @now + 1.day
261
- @end = @start + 1.day
262
- within_date_range.should be_false
263
- end
264
- end
265
- end
266
- context "when on or beyond ad's start date" do
267
- context "when ad has no end date" do
268
- it "should return true" do
269
- @start = @now
270
- @end = nil
271
- within_date_range.should be_true
272
- @start = @now - 1.day
273
- within_date_range.should be_true
274
- end
275
- end
276
- context "when before ad's end date" do
277
- it "should return true" do
278
- @start = @now
279
- @end = @now + 1.day
280
- within_date_range.should be_true
281
- @start = @now - 1.day
282
- within_date_range.should be_true
283
- end
284
- end
285
- context "when on or beyond ad's end date" do
286
- it "should return false" do
287
- @start = @now
288
- @end = @now
289
- within_date_range.should be_false
290
- @start = @now - 2.days
291
- @end = @now
292
- within_date_range.should be_false
293
- @end = @now - 1.day
294
- within_date_range.should be_false
295
- end
296
- end
297
- end
298
- end
299
-
300
- describe ".partitioned_hour?(time)" do
301
- context "when day partitions exist" do
302
- before(:all) do
303
- @ad = FakeAd.new(:day_partitions => [
304
- "TTTTTTTTTTFTTTTTTTTTTTTT", # Sunday
305
- "TTTTTTTTTTTTTTTFTTTTTTTT", # Monday
306
- "FTTTTTTTTTTTTTTTTTTTTTTT", # Tuesday
307
- "TTTTTFTTTTTTTTTTTTTTTTTT", # Wednesday
308
- "TTTTTTTTTTTTTTTTTTTTFTTT", # Thursday
309
- "TTTTTTTTTTTTTTTTTTTTTTTF", # Friday
310
- "TTTTTTTTTTTTFTTTTTTTTTTT" # Saturday
311
- ].join)
312
- end
313
- context "when on Sunday" do
314
- context "when on day partition" do
315
- it "should return true" do
316
- time = Chronic.parse('Sunday @ 9 am')
317
- @ad.send(:partitioned_hour?, time).should be_true
318
- end
319
- end
320
- context "when not on day partition" do
321
- it "should return false" do
322
- time = Chronic.parse('Sunday @ 10 am')
323
- @ad.send(:partitioned_hour?, time).should be_false
324
- end
325
- end
326
- end
327
- context "when on Monday" do
328
- context "when on day partition" do
329
- it "should return true" do
330
- time = Chronic.parse('Monday @ 2 pm')
331
- @ad.send(:partitioned_hour?, time).should be_true
332
- end
333
- end
334
- context "when not on day partition" do
335
- it "should return false" do
336
- time = Chronic.parse('Monday @ 3 pm')
337
- @ad.send(:partitioned_hour?, time).should be_false
338
- end
339
- end
340
- end
341
- context "when on Friday" do
342
- context "when on day partition" do
343
- it "should return true" do
344
- time = Chronic.parse('Friday @ 10 pm')
345
- @ad.send(:partitioned_hour?, time).should be_true
346
- end
347
- end
348
- context "when not on day partition" do
349
- it "should return false" do
350
- time = Chronic.parse('Friday @ 11 pm')
351
- @ad.send(:partitioned_hour?, time).should be_false
352
- end
353
- end
354
- end
355
- context "when on Saturday" do
356
- context "when on day partition" do
357
- it "should return true" do
358
- time = Chronic.parse('Saturday @ 1 pm')
359
- @ad.send(:partitioned_hour?, time).should be_true
360
- end
361
- end
362
- context "when not on day partition" do
363
- it "should return false" do
364
- time = Chronic.parse('Saturday @ 12 pm')
365
- @ad.send(:partitioned_hour?, time).should be_false
366
- end
367
- end
368
- end
369
- end
370
- end
371
-
372
- def partitioned_day?(time)
373
- nine_to_five = "F"*9 + "T"*8 + "F"*7
374
- no_hours = "F" * 24
375
- ad = FakeAd.new(:day_partitions => [nine_to_five, nine_to_five, no_hours, nine_to_five, nine_to_five, nine_to_five, no_hours].join)
376
- ad.send(:partitioned_day?, time)
377
- end
378
- describe ".partitioned_day?(time)" do
379
- context "when ad is partitioned from 9-5, every day of the week except Tuesday and Saturday" do
380
- it "should return true on Sunday @ 5 am" do
381
- partitioned_day?( Chronic.parse('Sunday @ 5 am') ).should be_true
382
- end
383
- it "should return true on Sunday @ 10 am" do
384
- partitioned_day?( Chronic.parse('Sunday @ 10 am') ).should be_true
385
- end
386
- it "should return true on Sunday @ 10 pm" do
387
- partitioned_day?( Chronic.parse('Sunday @ 10 pm') ).should be_true
388
- end
389
- it "should return true on Monday @ 5 am" do
390
- partitioned_day?( Chronic.parse('Monday @ 5 am') ).should be_true
391
- end
392
- it "should return false on Tuesday @ 5 am" do
393
- partitioned_day?( Chronic.parse('Tuesday @ 5 am') ).should be_false
394
- end
395
- it "should return false on Tuesday @ 10 am" do
396
- partitioned_day?( Chronic.parse('Tuesday @ 10 am') ).should be_false
397
- end
398
- it "should return true on Wednesday @ 5 am" do
399
- partitioned_day?( Chronic.parse('Wednesday @ 5 am') ).should be_true
400
- end
401
- it "should return true on Thursday @ 5 am" do
402
- partitioned_day?( Chronic.parse('Thursday @ 5 am') ).should be_true
403
- end
404
- it "should return true on Friday @ 5 am" do
405
- partitioned_day?( Chronic.parse('Friday @ 5 am') ).should be_true
406
- end
407
- it "should return false on Saturday @ 5 am" do
408
- partitioned_day?( Chronic.parse('Saturday @ 5 am') ).should be_false
409
- end
410
- end
411
- end
412
-
413
- describe ".cap_met?(total_impressed, today_impressed)" do
414
- context "when not daily capped" do
415
- context "and not overall capped" do
416
- it "should return false" do
417
- FakeAd.new(:daily_cap => nil, :overall_cap => nil).send(:cap_met?, 10, 10).should be_false
418
- end
419
- end
420
- context "and overall cap is 10" do
421
- before(:each) do
422
- @ad = FakeAd.new(:daily_cap => nil, :overall_cap => 10)
423
- end
424
- context "and total_impressed = 9" do
425
- it "should return false" do
426
- @ad.send(:cap_met?, 9, 0).should be_false
427
- end
428
- end
429
- context "and total_impressed = 10" do
430
- it "should return true" do
431
- @ad.send(:cap_met?, 10, 0).should be_true
432
- end
433
- end
434
- context "and total_impressed = 11" do
435
- it "should return true" do
436
- @ad.send(:cap_met?, 11, 0).should be_true
437
- end
438
- end
439
- end
440
- end
441
- context "when daily cap is 10" do
442
- context "and not overall capped" do
443
- before(:each) do
444
- @ad = FakeAd.new(:daily_cap => 10, :overall_cap => nil)
445
- end
446
- context "and today_impressed = 9" do
447
- it "should return false" do
448
- @ad.send(:cap_met?, 0, 9).should be_false
449
- end
450
- end
451
- context "and today_impressed = 10" do
452
- it "should return true" do
453
- @ad.send(:cap_met?, 0, 10).should be_true
454
- end
455
- end
456
- context "and today_impressed = 11" do
457
- it "should return true" do
458
- @ad.send(:cap_met?, 0, 11).should be_true
459
- end
460
- end
461
- end
462
- context "and overall cap is 100" do
463
- before(:each) do
464
- @ad = FakeAd.new(:daily_cap => 10, :overall_cap => 100)
465
- end
466
- context "and total < 100, today < 10" do
467
- it "should return false" do
468
- @ad.send(:cap_met?, 99, 9).should be_false
469
- end
470
- end
471
- context "and total < 100, today = 10" do
472
- it "should return true" do
473
- @ad.send(:cap_met?, 99, 10).should be_true
474
- end
475
- end
476
- context "and total = 100, today < 10" do
477
- it "should return true" do
478
- @ad.send(:cap_met?, 100, 9).should be_true
479
- end
480
- end
481
- context "and total = 100, today = 10" do
482
- it "should return true" do
483
- @ad.send(:cap_met?, 100, 10).should be_true
484
- end
485
- end
486
- end
487
- end
488
- end
489
-
490
- def precluded
491
- @time = Time.now
492
- @total = 500
493
- @today = 100
494
- ad = FakeAd.new(:daily_cap => @daily_cap, :overall_cap => @overall_cap, :end_datetime => @end_datetime)
495
- ad.stub(:remaining_impressions_via_daily_cap).with(@time, @today).and_return(@remaining_via_daily_cap)
496
- ad.stub(:remaining_impressions_via_overall_cap).with(@total).and_return(@remaining_via_overall_cap)
497
- ad.send(:daily_cap_precludes_overall_cap?, @time, @total, @today)
498
- end
499
- describe ".daily_cap_precludes_overall_cap?(time, total_impressed, today_impressed)" do
500
- context "when ad has no daily cap" do
501
- it "should return false" do
502
- @daily_cap = nil
503
- @overall_cap = 1
504
- precluded.should be_false
505
- end
506
- end
507
- context "when ad has no overall cap" do
508
- it "should return false" do
509
- @daily_cap = 1
510
- @overall_cap = nil
511
- precluded.should be_false
512
- end
513
- end
514
- context "when ad has no end date/time" do
515
- it "should return false" do
516
- @daily_cap = 1
517
- @overall_cap = 1
518
- @end_datetime = nil
519
- precluded.should be_false
520
- end
521
- end
522
- context "when ad's daily cap is 10, overall cap is 100, and end datetime is present" do
523
- before(:each) { @daily_cap = 10; @overall_cap = 100; @end_datetime = Time.now + 10.days }
524
- context "when remaining_impressions_via_daily_cap < remaining_impressions_via_overall_cap" do
525
- it "returns true" do
526
- @remaining_via_daily_cap = 1
527
- @remaining_via_overall_cap = 2
528
- precluded.should be_true
529
- end
530
- end
531
- context "when remaining_impressions_via_daily_cap = remaining_impressions_via_overall_cap" do
532
- it "returns false" do
533
- @remaining_via_daily_cap = 1
534
- @remaining_via_overall_cap = 1
535
- precluded.should be_false
536
- end
537
- end
538
- context "when remaining_impressions_via_daily_cap > remaining_impressions_via_overall_cap" do
539
- it "returns false" do
540
- @remaining_via_daily_cap = 2
541
- @remaining_via_overall_cap = 1
542
- precluded.should be_false
543
- end
544
- end
545
- end
546
- end
547
-
548
- describe ".remaining_impressions_via_overall_cap(total_impressed)" do
549
- context "when overall_cap = 100" do
550
- before(:each) { @ad = FakeAd.new(:overall_cap => 100) }
551
- context "when total_impressed = 0" do
552
- it "returns 100" do
553
- @ad.send(:remaining_impressions_via_overall_cap, 0).should == 100
554
- end
555
- end
556
- context "when total_impressed = 99" do
557
- it "returns 1" do
558
- @ad.send(:remaining_impressions_via_overall_cap, 99).should == 1
559
- end
560
- end
561
- context "when total_impressed = 100" do
562
- it "returns 0" do
563
- @ad.send(:remaining_impressions_via_overall_cap, 100).should == 0
564
- end
565
- end
566
- context "when total_impressed = 101" do
567
- it "returns 0" do
568
- @ad.send(:remaining_impressions_via_overall_cap, 101).should == 0
569
- end
570
- end
571
- end
572
- end
573
-
574
- describe ".remaining_impressions_today(today_impressed)" do
575
- context "when daily_cap = 100" do
576
- before(:each) { @ad = FakeAd.new(:daily_cap => 100) }
577
- context "when today_impressed = 0" do
578
- it "returns 100" do
579
- @ad.send(:remaining_impressions_today, 0).should == 100
580
- end
581
- end
582
- context "when today_impressed = 99" do
583
- it "returns 1" do
584
- @ad.send(:remaining_impressions_today, 99).should == 1
585
- end
586
- end
587
- context "when today_impressed = 100" do
588
- it "returns 0" do
589
- @ad.send(:remaining_impressions_today, 100).should == 0
590
- end
591
- end
592
- context "when today_impressed = 101" do
593
- it "returns 0" do
594
- @ad.send(:remaining_impressions_today, 101).should == 0
595
- end
596
- end
597
- end
598
- end
599
-
600
- describe ".remaining_impressions_via_daily_cap(time, today_impressed)" do
601
- context "when daily_cap is 100, ad has 5 days remaining (including today), and 30 remaining impressions today" do
602
- it "returns 430" do
603
- ad = FakeAd.new(:daily_cap => 100)
604
- ad.stub(:remaining_days).with(:time).and_return(5)
605
- ad.stub(:remaining_impressions_today).with(:today_impressed).and_return(30)
606
-
607
- ad.send(:remaining_impressions_via_daily_cap, :time, :today_impressed).should == 430
608
- end
609
- end
610
- end
611
-
612
- describe ".calculate_today_pressure(time, today_impressed)" do
613
- context "when there are 3 hours and 12 impressions remaining today" do
614
- it "should return a pressure of 8 (impressions/hr)" do
615
- ad = FakeAd.new
616
- ad.stub(:remaining_hours_today).with(:time).and_return(3)
617
- ad.stub(:remaining_impressions_today).with(:today_impressed).and_return(12)
618
-
619
- ad.send(:calculate_today_pressure, :time, :today_impressed).should == 8
620
- end
621
- end
622
- context "when there are 0 hours and 12 impressions remaining today" do
623
- it "should return a pressure of 0 (impressions/hr)" do
624
- ad = FakeAd.new
625
- ad.stub(:remaining_hours_today).with(:time).and_return(0)
626
- ad.stub(:remaining_impressions_today).with(:today_impressed).and_return(12)
627
-
628
- ad.send(:calculate_today_pressure, :time, :today_impressed).should == 0
629
- end
630
- end
631
- end
632
-
633
- describe ".calculate_overall_pressure(time, total_impressed)" do
634
- context "when there are 3 hours and 12 impressions remaining overall" do
635
- it "should return a pressure of 4 (impressions/hr)" do
636
- ad = FakeAd.new
637
- ad.stub(:remaining_hours).with(:time).and_return(3)
638
- ad.stub(:remaining_impressions_via_overall_cap).with(:total_impressed).and_return(12)
639
-
640
- ad.send(:calculate_overall_pressure, :time, :total_impressed).should == 4
641
- end
642
- end
643
- context "when there are 0 hours and 12 impressions remaining overall" do
644
- it "should return a pressure of 0 (impressions/hr)" do
645
- ad = FakeAd.new
646
- ad.stub(:remaining_hours).with(:time).and_return(0)
647
- ad.stub(:remaining_impressions_via_overall_cap).with(:total_impressed).and_return(12)
648
-
649
- ad.send(:calculate_overall_pressure, :time, :total_impressed).should == 0
650
- end
651
- end
652
- end
653
-
654
- def remaining_days(time)
655
- FakeAd.new(
656
- :start_datetime => @start,
657
- :end_datetime => @end,
658
- :day_partitions => @day_partitions).send(:remaining_days, time.in_time_zone("Beijing"))
659
- end
660
- describe ".remaining_days(time)" do
661
- context "when time is on or after ad's end_datetime" do
662
- it "should return zero" do
663
- @start = nil
664
- @end = Time.at(1234567890)
665
- remaining_days(@end).should == 0
666
- remaining_days(@end + 1.day).should == 0
667
- end
668
- end
669
- context "when time is before ad's end_datetime" do
670
- context "and ad is not day-partitioned" do
671
- before(:each) { @day_partitions = nil }
672
- context "and time is before ad's start_datetime" do
673
- it "returns the number of days between the ad's start and end, including partial days on either end" do
674
- @start = Time.parse("2011-11-11 11:11 +08:00")
675
- @end = @start + 2.days
676
- remaining_days(@start - 1.week).should == 3
677
- end
678
- end
679
- context "and time is after the ad's start_datetime" do
680
- it "should return the number of days between the given time and the ad's end" do
681
- @start = Time.parse("2011-11-11 11:11 +08:00")
682
- @time = @start + 1.day
683
- @end = @time + 1.day
684
- remaining_days(@time).should == 2
685
- end
686
- context "and the ad's end occurs at midnight" do
687
- it "should return the number of days between the given time and the ad's end, not counting the morning of the final date" do
688
- @start = Time.parse("2011-11-11 11:11 +08:00")
689
- @time = @start + 1.day
690
- @end = @time.end_of_day + 1.day
691
- remaining_days(@time).should == 2
692
- end
693
- end
694
- context "and the time is on the same day as the ad's end" do
695
- it "should return one" do
696
- @start = Time.parse("2011-11-11 11:11 +08:00")
697
- @time = @start + 1.day
698
- @end = @time + 1.hour
699
- remaining_days(@time).should == 1
700
- end
701
- end
702
- context "and the ad's end is at midnight the night after the given time" do
703
- it "should return one" do
704
- @start = Time.parse("2011-11-11 11:11 +08:00")
705
- @time = @start + 1.day
706
- @end = @time.end_of_day
707
- remaining_days(@time).should == 1
708
- end
709
- end
710
- end
711
- end
712
- context "when ad is partitioned with the first 12 hours of each weekday active, and the last 12 and the whole weekend inactive" do
713
- before(:all) do
714
- @time_zone = "Beijing"
715
- Time.zone = @time_zone
716
- Chronic.time_class = Time.zone
717
- @day_partitions = "F"*24 + ("T"*12 + "F"*12) * 5 + "F"*24
718
- end
719
- context "when time is before ad's start_datetime, and date range is from Monday @ 9:30am to Friday @ 6pm" do
720
- it "should return 5 days" do
721
- @start = Chronic.parse("Monday @ 9:30am")
722
- @end = Chronic.parse("Monday @ 6pm") + 4.days #Friday
723
- remaining_days(Chronic.parse("1 month ago")).should == 5
724
- end
725
- end
726
- context "when time is before ad's start_datetime, and date range is from Monday @ 6pm to Friday @ 9:30am" do
727
- it "should return 4 days" do
728
- @start = Chronic.parse("Monday @ 6pm")
729
- @end = Chronic.parse("Monday @ 9:30am") + 4.days #Friday
730
- remaining_days(Chronic.parse("1 month ago")).should == 4
731
- end
732
- end
733
- context "when time is before ad's start_datetime, and date range is from Monday @ 6pm to Friday morning @ 12am" do
734
- it "should return 4 days" do
735
- @start = Chronic.parse("Monday @ 6pm")
736
- @end = Chronic.parse("Monday @ 12am") + 4.days #Friday
737
- remaining_days(Chronic.parse("1 month ago")).should == 3
738
- end
739
- end
740
- context "when time is before ad's start_datetime, and date range is from Monday @ 6pm to Three Mondays later @ 6am" do
741
- it "should return 15 hours" do
742
- @start = Chronic.parse("Monday @ 6pm")
743
- @end = Chronic.parse("Monday @ 6am") + 3.weeks
744
- remaining_days(Chronic.parse("1 month ago")).should == 15
745
- end
746
- end
747
- context "when the date range is really long" do
748
- it "should not take a long time to compute" do
749
- @start = Chronic.parse "2010-01-01 1am"
750
- @end = Chronic.parse "2020-01-07 5am"
751
- started = Time.now.to_f
752
- remaining_days(Chronic.parse("2009-12-31 11pm")).should == 2613
753
- finished = Time.now.to_f
754
- (finished - started).should > 0.0
755
- (finished - started).should < 0.1
756
- end
757
- end
758
- end
759
- end
760
- end
761
-
762
- describe ".remaining_hours(time)" do
763
- context "when time is on or after ad's end_datetime" do
764
- it "should return zero" do
765
- @end = Time.at(1234567890)
766
- a = FakeAd.new(:end_datetime => @end)
767
- a.send(:remaining_hours, @end).should == 0
768
- a.send(:remaining_hours, @end + 1.day).should == 0
769
- end
770
- end
771
- context "when time is before ad's end_datetime" do
772
- context "when ad is not day-partitioned" do
773
- context "when time is before ad's start_datetime" do
774
- it "returns the number of hours between the ad's start and end" do
775
- @end = Time.at(1234567890)
776
- a = FakeAd.new(:start_datetime => @end - 3.days, :end_datetime => @end, :day_partitions => nil)
777
- a.send(:remaining_hours, @end - 5.days).should == 24*3
778
- end
779
- end
780
- context "when time is after the ad's start_datetime" do
781
- it "should return the number of hours between the given time and the ad's end" do
782
- @end = Time.at(1234567890)
783
- a = FakeAd.new(:start_datetime => @end - 5.days, :end_datetime => @end, :day_partitions => nil)
784
- a.send(:remaining_hours, @end - 3.days).should == 24*3
785
- end
786
- end
787
- end
788
- context "when ad is partitioned with the first 12 hours of each day active, and the last 12 inactive" do
789
- before(:all) do
790
- @time_zone = "Beijing"
791
- Time.zone = @time_zone
792
- Chronic.time_class = Time.zone
793
- @day_partitions = ("T"*12 + "F"*12) * 7
794
- end
795
- context "when time is before ad's start_datetime, and date range is from Monday @ 9:30am to Friday @ 6pm" do
796
- it "should return 50.5 hours" do
797
- a = FakeAd.new(:start_datetime => Chronic.parse("Monday @ 9:30am"),
798
- :end_datetime => Chronic.parse("Monday @ 6pm") + 4.days,
799
- :day_partitions => @day_partitions)
800
- a.send(:remaining_hours, Chronic.parse("1 month ago")).should == 50.5
801
- end
802
- end
803
- context "when time is before ad's start_datetime, and date range is from Monday @ 6pm to Friday @ 9:30am" do
804
- it "should return 45.5 hours" do
805
- a = FakeAd.new(:start_datetime => Chronic.parse("Monday @ 6pm"),
806
- :end_datetime => Chronic.parse("Monday @ 9:30am") + 4.days,
807
- :day_partitions => @day_partitions)
808
- a.send(:remaining_hours, Chronic.parse("1 month ago")).should == 45.5
809
- end
810
- end
811
- context "when time is before ad's start_datetime, and date range is from Monday @ 6pm to Three Mondays later @ 6am" do
812
- it "should return 246 (12 * 7 * 3 - 6) hours" do
813
- a = FakeAd.new(:start_datetime => Chronic.parse("Monday @ 6pm"),
814
- :end_datetime => Chronic.parse("Monday @ 6am") + 3.weeks,
815
- :day_partitions => @day_partitions)
816
- a.send(:remaining_hours, Chronic.parse("1 month ago")).should == 12 * 7 * 3 - 6
817
- end
818
- end
819
- context "when the date range is really long" do
820
- it "should not take a long time to compute" do
821
- a = FakeAd.new(:start_datetime => Chronic.parse("2010-01-01 1am"),
822
- :end_datetime => Chronic.parse("2020-01-07 5am"),
823
- :day_partitions => @day_partitions)
824
- started = Time.now.to_f
825
- a.send(:remaining_hours, Chronic.parse("2009-12-31 11pm")).should == 43900
826
- finished = Time.now.to_f
827
- (finished - started).should > 0.0
828
- (finished - started).should < 0.1
829
- end
830
- end
831
- end
832
- end
833
- end
834
-
835
- def remaining_hours_today(time)
836
- @ad = FakeAd.new(
837
- :start_datetime => @start,
838
- :end_datetime => @end,
839
- :day_partitions => @day_partitions)
840
- @ad.send(:remaining_hours_today, time.in_time_zone(@time_zone))
841
- end
842
- describe ".remaining_hours_today(time)" do
843
- before(:all) do
844
- @time_zone = "Beijing"
845
- Time.zone = @time_zone
846
- Chronic.time_class = Time.zone
847
- end
848
- context "when ad is not day-partitioned" do
849
- before(:all) { @day_partitions = nil}
850
- context "when ad's start and end date/time are the same day" do
851
- before(:all) do
852
- @start = Chronic.parse('tomorrow @ 9am')
853
- @end = Chronic.parse('tomorrow @ 5pm')
854
- end
855
- context "when the given time is on a different day" do
856
- it "should return zero" do
857
- remaining_hours_today(@start - 2.days).should == 0
858
- remaining_hours_today(@end - 2.days).should == 0
859
- end
860
- end
861
- context "when the given time is on the same day, but before the start" do
862
- it "should return the full number of hours of the ad's range" do
863
- remaining_hours_today(@start - 5.hours).should == 8
864
- end
865
- end
866
- context 'when the given time is on the same day, within the date range' do
867
- it "should return the hours between the given time and the end" do
868
- remaining_hours_today(Chronic.parse('tomorrow @ noon')).should == 5
869
- end
870
- end
871
- context "when the given time is on the same day, but after the end" do
872
- it "should return zero" do
873
- remaining_hours_today(@end + 1.hour).should == 0
874
- end
875
- end
876
- end
877
- context "when the given time is at least 24 hours before the start time" do
878
- it "should return zero" do
879
- @start = Time.at(1234567890)
880
- @end = @start + 1.month
881
- remaining_hours_today(@start - 1.day).should == 0
882
- end
883
- end
884
- context "when the given time is at least 24 hours after the end time" do
885
- it "should return zero" do
886
- @start = Time.at(1234567890)
887
- @end = @start + 1.month
888
- remaining_hours_today(@end + 1.day).should == 0
889
- end
890
- end
891
- context "when the given time is after the the start_time" do
892
- context "and at least 24 hours before the end time" do
893
- it "should return the hours from the given time to midnight of that night" do
894
- @start = Chronic.parse("yesterday @ 3am")
895
- @time = Chronic.parse("today @ 8pm")
896
- @end = @time + 1.day
897
- remaining_hours_today(@time).should == 4
898
- end
899
- end
900
- context "and the ad's end comes before midnight of the given time" do
901
- context "and the given time is before the end time" do
902
- it "should return the hours between the given time and the end time" do
903
- @start = Chronic.parse("yesterday @ 3am")
904
- @time = Chronic.parse("today @ 8pm")
905
- @end = @time + 2.hours
906
- remaining_hours_today(@time).should == 2
907
- end
908
- end
909
- context "and the given time is after the end time" do
910
- it "should return zero" do
911
- @start = Chronic.parse("yesterday @ 3am")
912
- @time = Chronic.parse("today @ 8pm")
913
- @end = @time - 2.hours
914
- remaining_hours_today(@time).should == 0
915
- end
916
- end
917
- context "and the given time matches the end time" do
918
- it "should return zero" do
919
- @start = Chronic.parse("yesterday @ 3am")
920
- @time = Chronic.parse("today @ 8pm")
921
- @end = @time
922
- remaining_hours_today(@time).should == 0
923
- end
924
- end
925
- end
926
- end
927
- end
928
- context "when ad is partitioned with the first 12 hours of each day active, and the last 12 inactive" do
929
- before(:all) { @day_partitions = ("T"*12 + "F"*12) * 7}
930
- context "when ad's start and end date/time are the same day" do
931
- before(:all) do
932
- @start = Chronic.parse('tomorrow @ 9am')
933
- @end = Chronic.parse('tomorrow @ 5pm')
934
- end
935
- context "when the given time is on a different day" do
936
- it "should return zero" do
937
- remaining_hours_today(@start - 2.days).should == 0
938
- remaining_hours_today(@end - 2.days).should == 0
939
- end
940
- end
941
- context "when the given time is on the same day, but before the start" do
942
- it "should return the full number of hours of the ad's range" do
943
- remaining_hours_today(@start - 5.hours).should == 3
944
- end
945
- end
946
- context 'when the given time is on the same day, within the date range' do
947
- it "should return the hours between the given time and the end" do
948
- remaining_hours_today(Chronic.parse('tomorrow @ 11am')).should == 1
949
- end
950
- end
951
- context "when the given time is on the same day, but after the end" do
952
- it "should return zero" do
953
- remaining_hours_today(@end + 1.hour).should == 0
954
- end
955
- end
956
- end
957
- context "when the given time is at least 24 hours before the start time" do
958
- it "should return zero" do
959
- @start = Time.at(1234567890)
960
- @end = @start + 1.month
961
- remaining_hours_today(@start - 1.day).should == 0
962
- end
963
- end
964
- context "when the given time is at least 24 hours after the end time" do
965
- it "should return zero" do
966
- @start = Time.at(1234567890)
967
- @end = @start + 1.month
968
- remaining_hours_today(@end + 1.day).should == 0
969
- end
970
- end
971
- context "when the given time is after the the start_time" do
972
- context "and at least 24 hours before the end time" do
973
- it "should return the hours from the given time to midnight of that night" do
974
- @start = Chronic.parse("yesterday @ 3am")
975
- @time = Chronic.parse("today @ 7am")
976
- @end = @time + 1.day
977
- remaining_hours_today(@time).should == 5 #day part ends at noon
978
- end
979
- end
980
- context "and the ad's end comes before midnight of the given time" do
981
- context "and the given time is before the end time" do
982
- it "should return the hours between the given time and the end time" do
983
- @start = Chronic.parse("yesterday @ 3am")
984
- @time = Chronic.parse("today @ 10:30am")
985
- @end = @time + 2.hours
986
- remaining_hours_today(@time).should == 1.5 #day part ends at noon
987
- end
988
- end
989
- context "and the given time is after the end time" do
990
- it "should return zero" do
991
- @start = Chronic.parse("yesterday @ 3am")
992
- @time = Chronic.parse("today @ 7am")
993
- @end = @time - 2.hours
994
- remaining_hours_today(@time).should == 0
995
- end
996
- end
997
- context "and the given time matches the end time" do
998
- it "should return zero" do
999
- @start = Chronic.parse("yesterday @ 3am")
1000
- @time = Chronic.parse("today @ 7am")
1001
- @end = @time
1002
- remaining_hours_today(@time).should == 0
1003
- end
1004
- end
1005
- end
1006
- end
1007
- end
1008
- end
1009
-
1010
- def beginning_of_week(time)
1011
- FakeAd.new.send(:beginning_of_week, time)
1012
- end
1013
- describe ".beginning_of_week(time)" do
1014
- context "time is on sunday morning at midnight" do
1015
- it "should return an equivalent time" do
1016
- time = Chronic.parse("Sunday @ 00:00")
1017
- beginning_of_week(time).should == time
1018
- end
1019
- end
1020
- context "time is on sunday at noon" do
1021
- it "should return a time 12 hours before" do
1022
- time = Chronic.parse("Sunday @ noon")
1023
- beginning_of_week(time).should == time - 12.hours
1024
- end
1025
- end
1026
- context "time is on monday at noon" do
1027
- it "should return a time 12 hours and one day before" do
1028
- time = Chronic.parse("Monday @ noon")
1029
- beginning_of_week(time).should == time - (12.hours + 1.day)
1030
- end
1031
- end
1032
- context "time is on tuesday at noon" do
1033
- it "should return a time 12 hours and two days before" do
1034
- time = Chronic.parse("Tuesday @ noon")
1035
- beginning_of_week(time).should == time - (12.hours + 2.day)
1036
- end
1037
- end
1038
- context "time is on wednesday at noon" do
1039
- it "should return a time 12 hours and three days before" do
1040
- time = Chronic.parse("Wednesday @ noon")
1041
- beginning_of_week(time).should == time - (12.hours + 3.day)
1042
- end
1043
- end
1044
- context "time is on thursday at noon" do
1045
- it "should return a time 12 hours and four days before" do
1046
- time = Chronic.parse("Thursday @ noon")
1047
- beginning_of_week(time).should == time - (12.hours + 4.day)
1048
- end
1049
- end
1050
- context "time is on friday at noon" do
1051
- it "should return a time 12 hours and five days before" do
1052
- time = Chronic.parse("Friday @ noon")
1053
- beginning_of_week(time).should == time - (12.hours + 5.day)
1054
- end
1055
- end
1056
- context "time is on saturday at noon" do
1057
- it "should return a time 12 hours and six days before" do
1058
- time = Chronic.parse("Saturday @ noon")
1059
- beginning_of_week(time).should == time - (12.hours + 6.day)
1060
- end
1061
- end
1062
- end
1063
-
1064
- def beginning_of_hour(time)
1065
- FakeAd.new.send(:beginning_of_hour, time)
1066
- end
1067
- describe ".beginning_of_hour(time)" do
1068
- before(:all) { @one_pm = Chronic.parse('1:00pm')}
1069
- context "at 1:00 pm" do
1070
- it "should return 1:00 pm" do
1071
- beginning_of_hour(@one_pm).should == @one_pm
1072
- end
1073
- end
1074
- context "at 1:01 pm" do
1075
- it "should return 1:00 pm" do
1076
- beginning_of_hour(@one_pm + 1.minute).should == @one_pm
1077
- end
1078
- end
1079
- context "at 1:59:59.9 pm" do
1080
- it "should return 1:00 pm" do
1081
- beginning_of_hour(@one_pm + 59.minutes + 59.9.seconds).should == @one_pm
1082
- end
1083
- end
1084
- end
1085
-
1086
- def partitioned_hours(beginning, ending)
1087
- FakeAd.new(:day_partitions => @day_partitions).send(:partitioned_hours, beginning, ending)
1088
- end
1089
- describe ".partitioned_hours(beginning, ending)" do
1090
- before(:all) do
1091
- @time_zone = "Beijing"
1092
- Time.zone = @time_zone
1093
- Chronic.time_class = Time.zone
1094
- end
1095
- context "when ad is partitioned, active first 12 hours of every week day, inactive the last 12 hours and weekends" do
1096
- before(:all) { @day_partitions = "F"*24 + ("T"*12 + "F"*12)*5 + "F"*24 }
1097
- context "and beginning after ending" do
1098
- it "should return zero" do
1099
- partitioned_hours(Time.now, Time.now - 1.day).should == 0
1100
- end
1101
- end
1102
- context "and beginning and ending are in the same hour" do
1103
- context "and that hour is an active partition" do
1104
- it "should return the time (in hours) from beginning to ending" do
1105
- @start = Chronic.parse("Monday @ 9:10am")
1106
- @end = Chronic.parse("Monday @ 9:50am")
1107
- partitioned_hours(@start, @end).should == 40/60.0
1108
- end
1109
- end
1110
- context "and that hour is an inactive partition" do
1111
- it "should return zero" do
1112
- @start = Chronic.parse("Monday @ 9:10pm")
1113
- @end = Chronic.parse("Monday @ 9:50pm")
1114
- partitioned_hours(@start, @end).should == 0
1115
- end
1116
- end
1117
- end
1118
- it "should have more specs"
1119
- end
1120
- end
1121
-
1122
- describe ".partitioned_days(beginning, ending)" do
1123
- it "should have specs"
1124
- end
1125
-
1126
- describe ".each_day(beginning, ending)" do
1127
- it "should have specs"
1128
- end
1129
-
1130
- describe ".each_hour(beginning, ending)" do
1131
- it "should have specs"
1132
- end
1133
-
1134
- describe ".actual_hours(beginning, ending)" do
1135
- it "should have specs"
1136
- end
1137
-
1138
- describe ".days_per_week" do
1139
- it "should have specs"
1140
- end
1141
-
1142
- describe ".hours_per_week" do
1143
- it "should have specs"
1144
- end
1145
-
1146
- end
1147
- end
1148
- end
1149
- end
1150
- end
1151
-