zuck 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +13 -5
  2. data/CHANGELOG.markdown +9 -0
  3. data/README.markdown +7 -1
  4. data/VERSION +1 -1
  5. data/lib/zuck/facebook/ad_creative.rb +0 -3
  6. data/lib/zuck/facebook/ad_group.rb +7 -7
  7. data/lib/zuck/facebook/targeting_spec.rb +0 -1
  8. data/lib/zuck.rb +6 -0
  9. data/spec/fixtures/a_single_account.yml +31 -111
  10. data/spec/fixtures/a_single_campaign.yml +11 -57
  11. data/spec/fixtures/a_single_group.yml +13 -62
  12. data/spec/fixtures/ad_interest_search_disney.yml +19 -19
  13. data/spec/fixtures/ad_interest_search_moviepilot.yml +15 -18
  14. data/spec/fixtures/ad_interest_search_nonexistant.yml +11 -11
  15. data/spec/fixtures/create_a_creative.yml +48 -0
  16. data/spec/fixtures/create_ad_campaign.yml +44 -226
  17. data/spec/fixtures/create_ad_group.yml +13 -155
  18. data/spec/fixtures/create_ad_set.yml +11 -57
  19. data/spec/fixtures/delete_ad_group.yml +10 -55
  20. data/spec/fixtures/delete_ad_set.yml +48 -0
  21. data/spec/fixtures/delete_campaign.yml +93 -0
  22. data/spec/fixtures/delete_creative.yml +48 -0
  23. data/spec/fixtures/find_a_single_group_and_update_it.yml +84 -110
  24. data/spec/fixtures/list_of_ad_accounts.yml +10 -57
  25. data/spec/fixtures/list_of_ad_campaigns.yml +10 -57
  26. data/spec/fixtures/list_of_ad_creatives.yml +9 -56
  27. data/spec/fixtures/list_of_ad_groups.yml +10 -57
  28. data/spec/fixtures/list_of_all_ad_creatives_of_account.yml +10 -57
  29. data/spec/fixtures/reach_for_invalid_interest.yml +28 -31
  30. data/spec/fixtures/reach_for_valid_keywords.yml +13 -13
  31. data/spec/fixtures/reach_for_valid_keywords_male_young.yml +13 -13
  32. data/spec/lib/zuck/facebook/ad_interest_spec.rb +1 -1
  33. data/spec/lib/zuck/facebook/targeting_spec_spec.rb +3 -3
  34. data/spec/lib/zuck_spec.rb +125 -86
  35. data/spec/spec_helper.rb +14 -0
  36. data/test_access_token +1 -1
  37. data/zuck.gemspec +7 -3
  38. metadata +49 -45
@@ -2,56 +2,121 @@ require 'spec_helper'
2
2
 
3
3
  describe Zuck::FbObject do
4
4
 
5
- before(:all) do
5
+ before(:all) {
6
+ puts "Koala version: #{Koala.config.api_version}"
6
7
  Zuck.graph = Koala::Facebook::API.new(test_access_token)
7
- end
8
+ }
8
9
 
9
- let(:graph) { Zuck.graph }
10
- let(:account) { Zuck::AdAccount.new(graph, {id: "act_10150585630710217"}) }
11
- let(:campaign){ Zuck::AdCampaign.new(graph, {id: "6021499361751"}, account) }
12
- let(:group) { Zuck::AdGroup.new(graph, {id: "6010889169151"}, campaign)}
13
- let(:creative){ Zuck::AdCreative.new(graph, {id: "6021396606151"}, group) }
14
- let(:set) { Zuck::AdSet.new(graph, {id: "6021525283751"}, account) }
15
10
 
11
+ let(:graph) { Zuck.graph }
12
+ let(:account_id) { "act_367106653" }
13
+ let(:account) { Zuck::AdAccount.new(graph, {id: account_id}) }
16
14
 
17
- describe "read only objects" do
18
- it "can't be created" do
19
- expect{
20
- Zuck::AdCreative.create(:x, {}, :y)
21
- }.to raise_error(Zuck::Error::ReadOnly)
22
- end
15
+ describe "talking to facebook" do
16
+ act_campaign = nil
17
+ campaign = nil
18
+ creative = nil
19
+ group = nil
20
+ set = nil
23
21
 
24
- it "can't be saved" do
25
- expect{
26
- creative.save
27
- }.to raise_error(Zuck::Error::ReadOnly)
28
- end
22
+ context "creating" do
29
23
 
30
- it "can't be destroyed" do
31
- expect{
32
- creative.destroy
33
- }.to raise_error(Zuck::Error::ReadOnly)
24
+ it "an ad campaign via an existing ad account" do
25
+ VCR.use_cassette('create_ad_campaign') do
26
+ o = {
27
+ daily_budget: 1000,
28
+ name: "bloody campaign (via account)"
29
+ }
30
+ explain_error {
31
+ act_campaign = account.create_ad_campaign(o)
32
+ act_campaign.name.should == "bloody campaign (via account)"
33
+ }
34
+ end
35
+ end
36
+
37
+
38
+ it "an ad campaign" do
39
+ VCR.use_cassette('create_ad_campaign') do
40
+ o = {
41
+ objective: 'NONE',
42
+ name: "bloody campaign",
43
+ campaign_group_status: 'PAUSED'
44
+ }
45
+ explain_error {
46
+ campaign = Zuck::AdCampaign.create(graph, o, account)
47
+ campaign.name.should == "bloody campaign"
48
+ }
49
+ end
50
+ end
51
+
52
+ it "an ad set" do
53
+ VCR.use_cassette('create_ad_set') do
54
+ o = {
55
+ bid_type: 'CPC',
56
+ bid_info: "{'CLICKS': 1}",
57
+ name: 'bloody ad set',
58
+ campaign_status: 'PAUSED',
59
+ daily_budget: 100,
60
+ targeting: "{'geo_locations':{'countries':['US','GB']}}",
61
+ campaign_group_id: campaign.id
62
+ }
63
+ explain_error {
64
+ set = Zuck::AdSet.create(graph, o, account)
65
+ set.name.should == 'bloody ad set'
66
+ }
67
+ end
68
+ end
69
+
70
+ it "a creative by uploading an image" do
71
+ VCR.use_cassette('create a creative') do
72
+ o = {
73
+ title: 'bloody title',
74
+ body: 'bloody body',
75
+ object_url: 'http://moviepilot.com/',
76
+ image_url: 'http://images-cdn.moviepilot.com/image/upload/c_fill,h_246,w_470/v1427727623/moviepilot.jpg'
77
+ }
78
+ explain_error {
79
+ creative = Zuck::AdCreative.create(graph, o, account)
80
+ creative.id.should_not == nil
81
+ }
82
+ end
83
+ end
84
+
85
+
86
+ it "an ad group via an existing ad campaign" do
87
+ VCR.use_cassette('create_ad_group') do
88
+ o = {
89
+ name: "Rap like me",
90
+ # targeting: '{"geo_locations": {"countries":["US"]}}',
91
+ objective: 'WEBSITE_CLICKS',
92
+ creative: '{"creative_id": '+creative.id+'}'
93
+ }
94
+ explain_error {
95
+ group = set.create_ad_group(o)
96
+ group.name.should == "Rap like me"
97
+ group['bid_type'].should == 'CPC'
98
+ }
99
+ end
100
+ end
34
101
  end
35
- end
36
102
 
37
- describe "talking to facebook" do
38
103
  context "reading" do
39
104
 
40
105
  it "a list of ad accounts" do
41
106
  VCR.use_cassette('list_of_ad_accounts') do
42
- Zuck::AdAccount.all.should have(2).items
107
+ Zuck::AdAccount.all.should have_at_least(1).items
43
108
  end
44
109
  end
45
110
 
46
111
  it "a list of ad campaigns" do
47
112
  VCR.use_cassette('list_of_ad_campaigns') do
48
- account.ad_campaigns.should have(24).items
113
+ account.ad_campaigns.should have_at_least(2).items
49
114
  end
50
115
  end
51
116
 
52
117
  it "a list of ad groups" do
53
118
  VCR.use_cassette('list_of_ad_groups') do
54
- campaign.ad_groups.should have(4).item
119
+ campaign.ad_groups.should have_at_least(1).item
55
120
  end
56
121
  end
57
122
 
@@ -65,7 +130,7 @@ describe Zuck::FbObject do
65
130
  g = graph
66
131
  Zuck::AdAccount.should_receive(:all).and_return([account])
67
132
  VCR.use_cassette('list_of_all_ad_creatives_of_account') do
68
- Zuck::AdCreative.all(g).should have(13).items
133
+ Zuck::AdCreative.all(g).should have_at_least(1).items
69
134
  end
70
135
  end
71
136
 
@@ -73,97 +138,71 @@ describe Zuck::FbObject do
73
138
 
74
139
  it "campaign with the correct type" do
75
140
  VCR.use_cassette('a_single_campaign') do
76
- c = Zuck::AdCampaign.find(6021496142951, graph)
141
+ c = Zuck::AdCampaign.find(campaign.id, graph)
142
+ c.buying_type.should == "AUCTION"
77
143
  end
78
144
  end
79
145
 
80
146
  it "account with the correct type" do
81
147
  VCR.use_cassette('a_single_account') do
82
- c = Zuck::AdAccount.find('act_10150585630710217', graph)
148
+ c = Zuck::AdAccount.find(account_id, graph)
149
+ c.account_id.should == account_id[4..-1]
150
+ c.account_status.should == 1
83
151
  end
84
152
  end
85
153
 
86
154
  it "when expecting an ad group but the id belongs to a campaign" do
87
155
  VCR.use_cassette('a_single_group') do
88
156
  expect{
89
- c = Zuck::AdGroup.find(6010889111951, graph)
157
+ Zuck::AdGroup.find(campaign.id, graph)
90
158
  }.to raise_error(Koala::Facebook::ClientError)
91
159
  end
92
160
  end
93
161
 
94
162
  it "and saving it" do
95
163
  VCR.use_cassette('find_a_single_group_and_update_it') do
96
- group = Zuck::AdGroup.find(6021525861551, graph)
97
- group.name = "My old name"
98
- group.save
99
- group.name.should == "My old name"
100
- group.name = "My new name"
101
- group.save
102
- group.name.should == "My new name"
103
- group.reload
104
- group.name.should == "My new name"
164
+ explain_error {
165
+ found_group = Zuck::AdGroup.find(group.id, graph)
166
+ found_group.name = "My old name"
167
+ found_group.save
168
+ found_group.name.should == "My old name"
169
+ found_group.name = "My new name"
170
+ found_group.save
171
+ found_group.name.should == "My new name"
172
+ found_group.reload
173
+ found_group.name.should == "My new name"
174
+ }
105
175
  end
106
176
  end
107
177
 
108
178
  end
109
179
  end
110
180
 
111
-
112
- context "creating" do
113
- it "an ad set" do
114
- VCR.use_cassette('create_ad_set') do
115
- o = {
116
- name: 'test ad set',
117
- campaign_status: 'PAUSED',
118
- daily_budget: 100,
119
- targeting: "{'geo_locations':{'countries':['US','GB']}}",
120
- campaign_group_id: campaign.id
121
- }
122
- ad_set = Zuck::AdSet.create(graph, o, account)
123
- ad_set.name.should == 'test ad set'
124
- end
125
- end
126
-
127
- it "an ad campaign" do
128
- VCR.use_cassette('create_ad_campaign') do
129
- o = {objective: 'NONE', name: "bloody", campaign_group_status: 'PAUSED' }
130
- campaign = Zuck::AdCampaign.create(graph, o, account)
131
- campaign.name.should == "bloody"
181
+ context "deleting" do
182
+ it "an ad group" do
183
+ VCR.use_cassette('delete_ad_group') do
184
+ group.destroy.should be_true
132
185
  end
133
186
  end
134
187
 
135
- it "an ad campaign via an existing ad account" do
136
- VCR.use_cassette('create_ad_campaign') do
137
- o = {daily_budget: 1000, name: "bloody" }
138
- campaign = account.create_ad_campaign(o)
139
- campaign.name.should == "bloody"
188
+ it "an ad set" do
189
+ VCR.use_cassette('delete_ad_set') do
190
+ set.destroy.should be_true
140
191
  end
141
192
  end
142
193
 
143
- it "an ad group via an existing ad campaign" do
144
- VCR.use_cassette('create_ad_group') do
145
- o = {
146
- bid_type: 'CPC',
147
- bid_info: '{"CLICKS": 1}',
148
- name: "Rap like me",
149
- targeting: '{"geo_locations": {"countries":["US"]}}',
150
- objective: 'WEBSITE_CLICKS',
151
- creative: '{"creative_id": "6021396606151"}'
152
- }
153
- group = set.create_ad_group(o)
154
- group.name.should == "Rap like me"
155
- group.bid_type.should == 'CPC'
194
+ it "a creative" do
195
+ VCR.use_cassette('delete_creative') do
196
+ creative.destroy.should be_true
156
197
  end
157
198
  end
158
- end
159
199
 
160
- context "deleting" do
161
- it "an ad group" do
162
- VCR.use_cassette('delete_ad_group') do
163
- group.destroy.should be_true
200
+ it "a campaign" do
201
+ VCR.use_cassette('delete_campaign') do
202
+ campaign.destroy.should be_true
203
+ act_campaign.destroy.should be_true
164
204
  end
165
205
  end
166
206
  end
167
-
168
207
  end
169
208
  end
data/spec/spec_helper.rb CHANGED
@@ -44,4 +44,18 @@ def test_access_token
44
44
  @test_access_token ||= File.read("test_access_token")
45
45
  end
46
46
 
47
+ def explain_error(&block)
48
+ raise "missing code block" unless block_given?
49
+
50
+ begin
51
+ block.call
52
+ rescue Koala::Facebook::APIError => e
53
+ puts "=== Facebook API Error ===================================="
54
+ body = JSON.parse e.response_body
55
+ body['error'].each { |k, v| printf("%-20s %s\n", k+":", v) }
56
+ puts "==========================================================="
57
+ raise e
58
+ end
59
+ end
60
+
47
61
  require File.expand_path("../../lib/zuck", __FILE__)
data/test_access_token CHANGED
@@ -1 +1 @@
1
- CAAEvJ5vzhl8BAICOwypV5nYnYWXhBq1eskHA7rKyrz9fXcAvKRXDWVZAaG7FpQ21qTXeCtGZCR7iu1dtZCqZCZBZCQbefKrMOnZAibDZAiQKiX0s22PgtKuCoQK4LDVimREnqkGdoLMyB4zgT3A6ZAU7pn6wc2mTzZBWVbkr71bZBJKjhyeb4V58TkMsUbN9SQer3ZCRRtWTxqNFTUwHuv51RoVsI7LNw0mCr5gZD
1
+ FAKEACCESSTOKEN
data/zuck.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: zuck 2.0.0 ruby lib
5
+ # stub: zuck 2.1.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "zuck"
9
- s.version = "2.0.0"
9
+ s.version = "2.1.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Jannis Hermanns"]
14
- s.date = "2015-01-09"
14
+ s.date = "2015-04-15"
15
15
  s.description = "This gem allows to easily access facebook's ads api in ruby. See https://developers.facebook.com/docs/reference/ads-api/"
16
16
  s.email = "jannis@gmail.com"
17
17
  s.extra_rdoc_files = [
@@ -55,10 +55,14 @@ Gem::Specification.new do |s|
55
55
  "spec/fixtures/ad_interest_search_disney.yml",
56
56
  "spec/fixtures/ad_interest_search_moviepilot.yml",
57
57
  "spec/fixtures/ad_interest_search_nonexistant.yml",
58
+ "spec/fixtures/create_a_creative.yml",
58
59
  "spec/fixtures/create_ad_campaign.yml",
59
60
  "spec/fixtures/create_ad_group.yml",
60
61
  "spec/fixtures/create_ad_set.yml",
61
62
  "spec/fixtures/delete_ad_group.yml",
63
+ "spec/fixtures/delete_ad_set.yml",
64
+ "spec/fixtures/delete_campaign.yml",
65
+ "spec/fixtures/delete_creative.yml",
62
66
  "spec/fixtures/find_a_single_group_and_update_it.yml",
63
67
  "spec/fixtures/list_of_ad_accounts.yml",
64
68
  "spec/fixtures/list_of_ad_campaigns.yml",