neuron-client 0.2.6 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
-