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
@@ -0,0 +1,155 @@
1
+ module Neuron
2
+ module Client
3
+ describe Zone do
4
+ before(:each) do
5
+ @datetime = "2011-11-11T11:11:11Z"
6
+ @minimal_attributes = {
7
+ 'ad_links' => nil,
8
+ 'name' => nil,
9
+ 'response_type' => nil,
10
+ 'template_slug' => nil,
11
+ 'mute' => nil,
12
+ 'autoplay' => nil,
13
+ 'channel' => nil,
14
+ 'expand' => nil,
15
+ 'text_overlay' => nil,
16
+ 'nami_feed_url' => nil,
17
+ }
18
+ end
19
+ context "when connected to the admin server" do
20
+ before(:each) do
21
+ @connection = stub(:connection)
22
+ API.stub(:default_api).and_return(stub(:default_api, :connection => @connection, :connection_type => :admin, :validate? => true))
23
+ end
24
+
25
+ describe "all" do
26
+ before(:each) do
27
+ @response = [{'zone' => {'id' => 'zone1', 'name' => nil}}]
28
+ end
29
+ it "returns a list of Zones" do
30
+ @connection.stub(:get).and_return(@response)
31
+ zones = Zone.all
32
+ zones.should be_a(Array)
33
+ zones.length.should be > 0
34
+ zones.first.should be_a(Zone)
35
+ end
36
+
37
+ it "makes a get call" do
38
+ @connection.should_receive(:get).with("zones").once.and_return(@response)
39
+ Zone.all
40
+ end
41
+ end
42
+
43
+ describe "find" do
44
+ before(:each) do
45
+ @response = {'zone' => @minimal_attributes.merge(
46
+ 'id' => 'zone1',
47
+ 'name' => "Zone 1",
48
+ 'response_type' => 'Redirect',
49
+ 'ad_links' => {},
50
+ 'created_at' => @datetime,
51
+ 'updated_at' => @datetime
52
+ )}
53
+ end
54
+
55
+ it "returns a Zone" do
56
+ @connection.stub(:get).with("zones/zone1").and_return(@response)
57
+ zone = Zone.find("zone1")
58
+ zone.should be_a(Zone)
59
+ end
60
+
61
+ it "makes a get call" do
62
+ @connection.should_receive(:get).with("zones/zone1").once.and_return(@response)
63
+ Zone.find("zone1")
64
+ end
65
+ end
66
+
67
+ describe "create" do
68
+ before(:each) do
69
+ @attrs = @minimal_attributes.merge(
70
+ 'name' => "Zone 1",
71
+ 'response_type' => 'Redirect',
72
+ 'ad_links' => {}
73
+ )
74
+ @response = {'zone' => @attrs.merge(
75
+ 'id' => "zone1",
76
+ 'created_at' => @datetime,
77
+ 'updated_at' => @datetime
78
+ )}
79
+ end
80
+
81
+ it "posts json" do
82
+ @connection.should_receive(:post).with("zones", {'zone' => @attrs}).once.and_return(@response)
83
+ Zone.create(@attrs)
84
+ end
85
+
86
+ it "returns the created Ad" do
87
+ @connection.should_receive(:post).and_return(@response)
88
+ zone = Zone.create(@attrs)
89
+ zone.id.should == "zone1"
90
+ zone.name.should == "Zone 1"
91
+ end
92
+ end
93
+
94
+ describe "update_attributes" do
95
+ it "makes a put call" do
96
+ attrs = @minimal_attributes.merge(
97
+ 'id' => 'zone1',
98
+ 'name' => 'Zone 1',
99
+ 'response_type' => 'Redirect',
100
+ 'ad_links' => {})
101
+ zone = Zone.new(attrs)
102
+ updated_attrs = attrs.merge('name' => 'Zone 2')
103
+ @connection.should_receive(:put).with("zones/zone1", {'zone' => updated_attrs}).and_return({'zone' => updated_attrs})
104
+ zone.update_attributes('name' => "Zone 2")
105
+ end
106
+ end
107
+
108
+ describe "unlink(ad_id)" do
109
+ it "should call the expected method and return the expected results" do
110
+ zone = Zone.new(@minimal_attributes.merge('id' => 'z99'))
111
+ @connection.should_receive(:delete).with('zones/z99/ads/7').and_return('return_value')
112
+
113
+ zone.unlink(7).should == 'return_value'
114
+ end
115
+ end
116
+ end
117
+ context "when connected to the membase server" do
118
+ before(:each) do
119
+ @connection = stub(:connection)
120
+ API.stub(:default_api).and_return(stub(:default_api, :connection => @connection, :connection_type => :membase, :validate? => true))
121
+ end
122
+ describe "Zone.find" do
123
+ context "when connection.get returns a value" do
124
+ it "should call the expected methods and return the expected result" do
125
+ conn = MembaseConnection.new("example.com:11211")
126
+ Zone.stub(:connection).and_return(conn)
127
+ attrs = @minimal_attributes.merge(
128
+ 'id' => 'zone7',
129
+ 'response_type' => 'Redirect',
130
+ 'ad_links' => {},
131
+ 'created_at' => @datetime,
132
+ 'updated_at' => @datetime
133
+ )
134
+ conn.stub(:get).with('Zone:zone7').and_return({'zone' => attrs}.to_json)
135
+ z = stub(:zone)
136
+ Zone.should_receive(:new).with(attrs).and_return(z)
137
+
138
+ Zone.find("zone7").should == z
139
+ end
140
+ end
141
+ context "when connection.get returns nil" do
142
+ it "should call the expected methods and return nil" do
143
+ conn = MembaseConnection.new("example.com:11211")
144
+ Zone.stub(:connection).and_return(conn)
145
+ conn.stub(:get).with('Zone:zone7').and_return(nil)
146
+
147
+ Zone.find("zone7").should be_nil
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,515 @@
1
+ require 'json-schema'
2
+
3
+ module Neuron
4
+ module Schema
5
+ describe Ad do
6
+ before(:each) do
7
+ @timezone = "Central Time (US & Canada)"
8
+ @datetime = "2011-11-11T11:11:11Z"
9
+ @monkey_wrench = {"monkey_wrench" => {"id" => 42, "name" => "a"}}
10
+ @monkey_wrenches = [
11
+ {"monkey_wrench" => {"id" => 1, "name" => "a"}},
12
+ {"monkey_wrench" => {"id" => 2, "name" => "b"}},
13
+ {"monkey_wrench" => {"id" => 3, "name" => "c"}}
14
+ ]
15
+ end
16
+
17
+ def validate(data, opts={})
18
+ schema = opts[:against] || raise("You forgot to specify the schema!")
19
+ JSON::Validator.validate!(schema, data)
20
+ end
21
+
22
+ def invalidate(data, opts={})
23
+ schema = opts[:against] || raise("You forgot to specify the schema!")
24
+ JSON::Validator.validate(schema, data).should be_false
25
+ end
26
+
27
+ describe "index" do
28
+ it "should approve an example list of ads" do
29
+ validate(
30
+ [{"ad" => {"id" => 42, "name" => "fred"}},
31
+ {"ad" => {"id" => 82, "name" => "carl"}},
32
+ {"ad" => {"id" => 246, "name" => "gus"}}
33
+ ],
34
+ :against => Ad::SCHEMA.index)
35
+ end
36
+
37
+ it "should approve an empty list" do
38
+ validate([], :against => Ad::SCHEMA.index)
39
+ end
40
+
41
+ it "should not approve an example ad outside of a list" do
42
+ invalidate(
43
+ {"ad" => {"id" => 42, "name" => "fred"}},
44
+ :against => Ad::SCHEMA.index)
45
+ end
46
+
47
+ it "should not approve an example list of monkey wrenches" do
48
+ invalidate(@monkey_wrenches, :against => Ad::SCHEMA.index)
49
+ end
50
+ end
51
+
52
+ describe "create" do
53
+ it "should approve an example redirect ad" do
54
+ validate({"ad" => {
55
+ "name" => "example_redirect_ad",
56
+ "approved" => "Yes",
57
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
58
+ "overall_cap" => 50_000_000,
59
+ "start_datetime" => @datetime,
60
+ "end_datetime" => nil,
61
+ "time_zone" => @timezone,
62
+ "day_partitions" => nil,
63
+ "daily_cap" => 1_000_000,
64
+ "ideal_impressions_per_hour" => nil,
65
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
66
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
67
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
68
+ "pixel_ids" => [82,246,9000],
69
+ "response_type" => "Redirect",
70
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$"
71
+ }}, :against => Ad::SCHEMA.create)
72
+ end
73
+
74
+ it "should approve an example video ad" do
75
+ validate({"ad" => {
76
+ "name" => "example_video_ad",
77
+ "approved" => "Yes",
78
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
79
+ "overall_cap" => 50_000_000,
80
+ "start_datetime" => @datetime,
81
+ "end_datetime" => nil,
82
+ "time_zone" => @timezone,
83
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
84
+ "daily_cap" => 1_000_000,
85
+ "ideal_impressions_per_hour" => nil,
86
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
87
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
88
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
89
+ "pixel_ids" => [82,246,9000],
90
+ "response_type" => "VideoAd",
91
+ "video_flv_url" => "http://cdn.example.com/content/campaigns/mortgage_backed_security/safe_bet.flv",
92
+ "clickthru_url" => "http://bank.example.com/",
93
+ "companion_ad_html" => '<a href="$click_url$">Invest in your future!</a>',
94
+ "social_urls" => {"youtube" => "http://www.youtube.com/watch?v=oHg5SJYRHA0"},
95
+ "vast_tracker_urls" => {"impression" => ["http://clickthru.example.com/thingy", "http://3rdparty.example.com/thingy"],
96
+ "clickTracking" => [],
97
+ "firstQuartile" => [],
98
+ "midpoint" => ["http://clickthru.example.com/thingy2"],
99
+ "thirdQuartile" => [],
100
+ "complete" => []}
101
+ }}, :against => Ad::SCHEMA.create)
102
+ end
103
+
104
+ it "should approve an example vast network ad" do
105
+ validate({"ad" => {
106
+ "name" => "example_vast_ad",
107
+ "approved" => "Yes",
108
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
109
+ "overall_cap" => 50_000_000,
110
+ "start_datetime" => @datetime,
111
+ "end_datetime" => nil,
112
+ "time_zone" => @timezone,
113
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
114
+ "daily_cap" => 1_000_000,
115
+ "ideal_impressions_per_hour" => nil,
116
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
117
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
118
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
119
+ "pixel_ids" => [82,246,9000],
120
+ "response_type" => "VastNetwork",
121
+ "vast_url" => "http://vast.example.com/1234/"
122
+ }}, :against => Ad::SCHEMA.create)
123
+ end
124
+
125
+ it "should approve an example acudeo network ad" do
126
+ validate({"ad" => {
127
+ "name" => "example_acudeo_ad",
128
+ "approved" => "Yes",
129
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
130
+ "overall_cap" => 50_000_000,
131
+ "start_datetime" => @datetime,
132
+ "end_datetime" => nil,
133
+ "time_zone" => @timezone,
134
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
135
+ "daily_cap" => 1_000_000,
136
+ "ideal_impressions_per_hour" => nil,
137
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
138
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
139
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
140
+ "pixel_ids" => [82,246,9000],
141
+ "response_type" => "AcudeoNetwork",
142
+ "acudeo_program_id" => "abc123"
143
+ }}, :against => Ad::SCHEMA.create)
144
+ end
145
+
146
+ it "should not approve an ad with missing information" do
147
+ invalidate({"ad" => {
148
+ "name" => "example_redirect_ad",
149
+ #"approved" => "Yes",
150
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
151
+ "overall_cap" => 50_000_000,
152
+ "start_datetime" => @datetime,
153
+ "end_datetime" => nil,
154
+ "time_zone" => @timezone,
155
+ "day_partitions" => nil,
156
+ "daily_cap" => 1_000_000,
157
+ "ideal_impressions_per_hour" => nil,
158
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
159
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
160
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
161
+ "pixel_ids" => [82,246,9000],
162
+ "response_type" => "Redirect",
163
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$"
164
+ }}, :against => Ad::SCHEMA.create)
165
+ end
166
+
167
+ it "should not approve an ad with extra information" do
168
+ invalidate({"ad" => {
169
+ "name" => "example_redirect_ad",
170
+ "approved" => "Yes",
171
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
172
+ "overall_cap" => 50_000_000,
173
+ "start_datetime" => @datetime,
174
+ "end_datetime" => nil,
175
+ "time_zone" => @timezone,
176
+ "day_partitions" => nil,
177
+ "daily_cap" => 1_000_000,
178
+ "ideal_impressions_per_hour" => nil,
179
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
180
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
181
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
182
+ "pixel_ids" => [82,246,9000],
183
+ "response_type" => "Redirect",
184
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
185
+ "companion_ad_html" => '<a href="http://example.com/">clickme</a>' #extra
186
+ }}, :against => Ad::SCHEMA.create)
187
+ end
188
+
189
+ it "should not approve a monkey wrench" do
190
+ invalidate(@monkey_wrench, :against => Ad::SCHEMA.create)
191
+ end
192
+ end
193
+
194
+ describe "show" do
195
+ it "should approve an example redirect ad" do
196
+ validate({"ad" => {
197
+ "name" => "example_redirect_ad",
198
+ "approved" => "Yes",
199
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
200
+ "overall_cap" => 50_000_000,
201
+ "start_datetime" => @datetime,
202
+ "end_datetime" => nil,
203
+ "time_zone" => @timezone,
204
+ "day_partitions" => nil,
205
+ "daily_cap" => 1_000_000,
206
+ "ideal_impressions_per_hour" => nil,
207
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
208
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
209
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
210
+ "pixel_ids" => [82,246,9000],
211
+ "response_type" => "Redirect",
212
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
213
+ "today_impressed" => 0,
214
+ "total_impressed" => 0,
215
+ "created_at" => @datetime,
216
+ "updated_at" => @datetime,
217
+ "id" => 1
218
+ }}, :against => Ad::SCHEMA.show)
219
+ end
220
+
221
+ it "should approve an example video ad" do
222
+ validate({"ad" => {
223
+ "name" => "example_video_ad",
224
+ "approved" => "Yes",
225
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
226
+ "overall_cap" => 50_000_000,
227
+ "start_datetime" => @datetime,
228
+ "end_datetime" => nil,
229
+ "time_zone" => @timezone,
230
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
231
+ "daily_cap" => 1_000_000,
232
+ "ideal_impressions_per_hour" => nil,
233
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
234
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
235
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
236
+ "pixel_ids" => [82,246,9000],
237
+ "response_type" => "VideoAd",
238
+ "video_flv_url" => "http://cdn.example.com/content/campaigns/mortgage_backed_security/safe_bet.flv",
239
+ "clickthru_url" => "http://bank.example.com/",
240
+ "companion_ad_html" => '<a href="$click_url$">Invest in your future!</a>',
241
+ "social_urls" => {"youtube" => "http://www.youtube.com/watch?v=oHg5SJYRHA0"},
242
+ "vast_tracker_urls" => {"impression" => ["http://clickthru.example.com/thingy", "http://3rdparty.example.com/thingy"],
243
+ "clickTracking" => [],
244
+ "firstQuartile" => [],
245
+ "midpoint" => ["http://clickthru.example.com/thingy2"],
246
+ "thirdQuartile" => [],
247
+ "complete" => []},
248
+ "today_impressed" => 0,
249
+ "total_impressed" => 0,
250
+ "created_at" => @datetime,
251
+ "updated_at" => @datetime,
252
+ "id" => 1
253
+ }}, :against => Ad::SCHEMA.show)
254
+ end
255
+
256
+ it "should approve an example vast network ad" do
257
+ validate({"ad" => {
258
+ "name" => "example_vast_ad",
259
+ "approved" => "Yes",
260
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
261
+ "overall_cap" => 50_000_000,
262
+ "start_datetime" => @datetime,
263
+ "end_datetime" => nil,
264
+ "time_zone" => @timezone,
265
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
266
+ "daily_cap" => 1_000_000,
267
+ "ideal_impressions_per_hour" => nil,
268
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
269
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
270
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
271
+ "pixel_ids" => [82,246,9000],
272
+ "response_type" => "VastNetwork",
273
+ "vast_url" => "http://vast.example.com/1234/",
274
+ "today_impressed" => 0,
275
+ "total_impressed" => 0,
276
+ "created_at" => @datetime,
277
+ "updated_at" => @datetime,
278
+ "id" => 1
279
+ }}, :against => Ad::SCHEMA.show)
280
+ end
281
+
282
+ it "should approve an example acudeo network ad" do
283
+ validate({"ad" => {
284
+ "name" => "example_acudeo_ad",
285
+ "approved" => "Yes",
286
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
287
+ "overall_cap" => 50_000_000,
288
+ "start_datetime" => @datetime,
289
+ "end_datetime" => nil,
290
+ "time_zone" => @timezone,
291
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
292
+ "daily_cap" => 1_000_000,
293
+ "ideal_impressions_per_hour" => nil,
294
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
295
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
296
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
297
+ "pixel_ids" => [82,246,9000],
298
+ "response_type" => "AcudeoNetwork",
299
+ "acudeo_program_id" => "abc123",
300
+ "today_impressed" => 0,
301
+ "total_impressed" => 0,
302
+ "created_at" => @datetime,
303
+ "updated_at" => @datetime,
304
+ "id" => 1
305
+ }}, :against => Ad::SCHEMA.show)
306
+ end
307
+
308
+ it "should not approve an ad with missing information" do
309
+ invalidate({"ad" => {
310
+ #"name" => "example_redirect_ad",
311
+ "approved" => "Yes",
312
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
313
+ "overall_cap" => 50_000_000,
314
+ "start_datetime" => @datetime,
315
+ "end_datetime" => nil,
316
+ "time_zone" => @timezone,
317
+ "day_partitions" => nil,
318
+ "daily_cap" => 1_000_000,
319
+ "ideal_impressions_per_hour" => nil,
320
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
321
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
322
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
323
+ "pixel_ids" => [82,246,9000],
324
+ "response_type" => "Redirect",
325
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
326
+ "today_impressed" => 0,
327
+ "total_impressed" => 0,
328
+ "created_at" => @datetime,
329
+ "updated_at" => @datetime,
330
+ "id" => 1
331
+ }}, :against => Ad::SCHEMA.show)
332
+ end
333
+
334
+ it "should not approve an ad with extra information" do
335
+ invalidate({"ad" => {
336
+ "name" => "example_redirect_ad",
337
+ "approved" => "Yes",
338
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
339
+ "overall_cap" => 50_000_000,
340
+ "start_datetime" => @datetime,
341
+ "end_datetime" => nil,
342
+ "time_zone" => @timezone,
343
+ "day_partitions" => nil,
344
+ "daily_cap" => 1_000_000,
345
+ "ideal_impressions_per_hour" => nil,
346
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
347
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
348
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
349
+ "pixel_ids" => [82,246,9000],
350
+ "response_type" => "Redirect",
351
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
352
+ "today_impressed" => 0,
353
+ "total_impressed" => 0,
354
+ "created_at" => @datetime,
355
+ "updated_at" => @datetime,
356
+ "id" => 1,
357
+ "companion_ad_html" => '<a href="http://example.com/">clickme</a>' #extra
358
+ }}, :against => Ad::SCHEMA.show)
359
+ end
360
+
361
+ it "should not approve a monkey wrench" do
362
+ invalidate(@monkey_wrench, :against => Ad::SCHEMA.show)
363
+ end
364
+ end
365
+
366
+ describe "update" do
367
+ it "should approve an example redirect ad" do
368
+ validate({"ad" => {
369
+ "name" => "example_redirect_ad",
370
+ "approved" => "Yes",
371
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
372
+ "overall_cap" => 50_000_000,
373
+ "start_datetime" => @datetime,
374
+ "end_datetime" => nil,
375
+ "time_zone" => @timezone,
376
+ "day_partitions" => nil,
377
+ "daily_cap" => 1_000_000,
378
+ "ideal_impressions_per_hour" => nil,
379
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
380
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
381
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
382
+ "pixel_ids" => [82,246,9000],
383
+ "response_type" => "Redirect",
384
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
385
+ "id" => 1
386
+ }}, :against => Ad::SCHEMA.update)
387
+ end
388
+
389
+ it "should approve an example video ad" do
390
+ validate({"ad" => {
391
+ "name" => "example_video_ad",
392
+ "approved" => "Yes",
393
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
394
+ "overall_cap" => 50_000_000,
395
+ "start_datetime" => @datetime,
396
+ "end_datetime" => nil,
397
+ "time_zone" => @timezone,
398
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
399
+ "daily_cap" => 1_000_000,
400
+ "ideal_impressions_per_hour" => nil,
401
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
402
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
403
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
404
+ "pixel_ids" => [82,246,9000],
405
+ "response_type" => "VideoAd",
406
+ "video_flv_url" => "http://cdn.example.com/content/campaigns/mortgage_backed_security/safe_bet.flv",
407
+ "clickthru_url" => "http://bank.example.com/",
408
+ "companion_ad_html" => '<a href="$click_url$">Invest in your future!</a>',
409
+ "social_urls" => {"youtube" => "http://www.youtube.com/watch?v=oHg5SJYRHA0"},
410
+ "vast_tracker_urls" => {"impression" => ["http://clickthru.example.com/thingy", "http://3rdparty.example.com/thingy"],
411
+ "clickTracking" => [],
412
+ "firstQuartile" => [],
413
+ "midpoint" => ["http://clickthru.example.com/thingy2"],
414
+ "thirdQuartile" => [],
415
+ "complete" => []},
416
+ "id" => 1
417
+ }}, :against => Ad::SCHEMA.update)
418
+ end
419
+
420
+ it "should approve an example vast network ad" do
421
+ validate({"ad" => {
422
+ "name" => "example_vast_ad",
423
+ "approved" => "Yes",
424
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
425
+ "overall_cap" => 50_000_000,
426
+ "start_datetime" => @datetime,
427
+ "end_datetime" => nil,
428
+ "time_zone" => @timezone,
429
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
430
+ "daily_cap" => 1_000_000,
431
+ "ideal_impressions_per_hour" => nil,
432
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
433
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
434
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
435
+ "pixel_ids" => [82,246,9000],
436
+ "response_type" => "VastNetwork",
437
+ "vast_url" => "http://vast.example.com/1234/",
438
+ "id" => 1
439
+ }}, :against => Ad::SCHEMA.update)
440
+ end
441
+
442
+ it "should approve an example acudeo network ad" do
443
+ validate({"ad" => {
444
+ "name" => "example_acudeo_ad",
445
+ "approved" => "Yes",
446
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
447
+ "overall_cap" => 50_000_000,
448
+ "start_datetime" => @datetime,
449
+ "end_datetime" => nil,
450
+ "time_zone" => @timezone,
451
+ "day_partitions" => "FFFFFTTTTTTTTTTTTTTFFFFF" * 7,
452
+ "daily_cap" => 1_000_000,
453
+ "ideal_impressions_per_hour" => nil,
454
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
455
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
456
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
457
+ "pixel_ids" => [82,246,9000],
458
+ "response_type" => "AcudeoNetwork",
459
+ "acudeo_program_id" => "abc123",
460
+ "id" => 1
461
+ }}, :against => Ad::SCHEMA.update)
462
+ end
463
+
464
+ it "should not approve an ad with missing id" do
465
+ invalidate({"ad" => {
466
+ "name" => "example_redirect_ad",
467
+ "approved" => "Yes",
468
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
469
+ "overall_cap" => 50_000_000,
470
+ "start_datetime" => @datetime,
471
+ "end_datetime" => nil,
472
+ "time_zone" => @timezone,
473
+ "day_partitions" => nil,
474
+ "daily_cap" => 1_000_000,
475
+ "ideal_impressions_per_hour" => nil,
476
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
477
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
478
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
479
+ "pixel_ids" => [82,246,9000],
480
+ "response_type" => "Redirect",
481
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
482
+ #"id" => 1
483
+ }}, :against => Ad::SCHEMA.update)
484
+ end
485
+
486
+ it "should not approve an ad with extra information" do
487
+ invalidate({"ad" => {
488
+ "name" => "example_redirect_ad",
489
+ "approved" => "Yes",
490
+ "frequency_cap" => {"limit" => 3, "window" => "Hour"},
491
+ "overall_cap" => 50_000_000,
492
+ "start_datetime" => @datetime,
493
+ "end_datetime" => nil,
494
+ "time_zone" => @timezone,
495
+ "day_partitions" => nil,
496
+ "daily_cap" => 1_000_000,
497
+ "ideal_impressions_per_hour" => nil,
498
+ "zone_links" => {"zoneA" => {"weight" => 1.5, "priority" => 1},
499
+ "zoneB" => {"weight" => 2.5, "priority" => 1}},
500
+ "geo_target_netacuity_ids" => {"COUNTRY" => [1, 2]},
501
+ "pixel_ids" => [82,246,9000],
502
+ "response_type" => "Redirect",
503
+ "redirect_url" => "http://www.example.com/$zone_id$?$cachebuster$",
504
+ "id" => 1,
505
+ "companion_ad_html" => '<a href="http://example.com/">clickme</a>' #extra
506
+ }}, :against => Ad::SCHEMA.update)
507
+ end
508
+
509
+ it "should not approve a monkey wrench" do
510
+ invalidate(@monkey_wrench, :against => Ad::SCHEMA.update)
511
+ end
512
+ end
513
+ end
514
+ end
515
+ end