facebook_ads 0.1.11 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.approvals +0 -0
  3. data/.coveralls.yml +1 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +13 -1
  6. data/.rubocop_todo.yml +16 -0
  7. data/.travis.yml +3 -1
  8. data/CHANGELOG.md +5 -0
  9. data/Gemfile +10 -7
  10. data/Gemfile.lock +56 -19
  11. data/LICENSE.md +22 -0
  12. data/README.md +8 -0
  13. data/facebook_ads.gemspec +2 -2
  14. data/lib/facebook_ads/ad.rb +2 -2
  15. data/lib/facebook_ads/ad_account.rb +52 -19
  16. data/lib/facebook_ads/ad_audience.rb +1 -1
  17. data/lib/facebook_ads/ad_campaign.rb +47 -5
  18. data/lib/facebook_ads/ad_creative.rb +4 -4
  19. data/lib/facebook_ads/ad_exception.rb +7 -1
  20. data/lib/facebook_ads/ad_image.rb +6 -2
  21. data/lib/facebook_ads/ad_insight.rb +1 -1
  22. data/lib/facebook_ads/ad_product.rb +1 -1
  23. data/lib/facebook_ads/ad_product_catalog.rb +1 -1
  24. data/lib/facebook_ads/ad_product_feed.rb +1 -1
  25. data/lib/facebook_ads/ad_product_set.rb +1 -1
  26. data/lib/facebook_ads/ad_set.rb +5 -5
  27. data/lib/facebook_ads/ad_targeting.rb +3 -3
  28. data/lib/facebook_ads/base.rb +10 -9
  29. data/spec/facebook_ads/ad_account_spec.rb +93 -0
  30. data/spec/facebook_ads/ad_campaign_spec.rb +19 -0
  31. data/spec/facebook_ads/ad_creative_spec.rb +4 -0
  32. data/spec/facebook_ads/ad_image_spec.rb +4 -0
  33. data/spec/facebook_ads/ad_insight_spec.rb +4 -0
  34. data/spec/facebook_ads/ad_product_catalog_spec.rb +27 -0
  35. data/spec/facebook_ads/ad_product_feed_spec.rb +4 -0
  36. data/spec/facebook_ads/ad_product_set_spec.rb +4 -0
  37. data/spec/facebook_ads/ad_product_spec.rb +21 -0
  38. data/spec/facebook_ads/ad_set_spec.rb +47 -0
  39. data/spec/facebook_ads/ad_spec.rb +4 -0
  40. data/spec/facebook_ads/ad_targeting_spec.rb +4 -0
  41. data/spec/facebook_ads/facebook_ads_spec.rb +15 -0
  42. data/spec/fixtures/approvals/facebookads_adaccount/ad_campaigns/lists_campaigns.approved.json +15 -0
  43. data/spec/fixtures/approvals/facebookads_adaccount/ad_creatives/lists_creatives.approved.json +1047 -0
  44. data/spec/fixtures/approvals/facebookads_adaccount/ad_images/lists_images.approved.json +11 -0
  45. data/spec/fixtures/approvals/facebookads_adaccount/ad_sets/lists_ad_sets.approved.json +3 -0
  46. data/spec/fixtures/approvals/facebookads_adaccount/ads/lists_ads.approved.json +3 -0
  47. data/spec/fixtures/approvals/facebookads_adaccount/all/lists_all_accounts.approved.json +92 -0
  48. data/spec/fixtures/approvals/facebookads_adaccount/create_ad_campaign/creates_a_new_ad_campaign.approved.json +13 -0
  49. data/spec/fixtures/approvals/facebookads_adaccount/create_ad_images/creates_an_image.approved.json +11 -0
  50. data/spec/fixtures/approvals/facebookads_adaccount/find_by/finds_a_specific_account.approved.json +9 -0
  51. data/spec/fixtures/approvals/facebookads_adaccount/reach_estimate/estimates_the_reach_of_a_targeting_spec.approved.json +358 -0
  52. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_campaigns/lists_campaigns.yml +56 -0
  53. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_creatives/lists_creatives.yml +91 -0
  54. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_images/lists_images.yml +56 -0
  55. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ad_sets/lists_ad_sets.yml +56 -0
  56. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_ads/lists_ads.yml +56 -0
  57. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_all/lists_all_accounts.yml +58 -0
  58. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_campaign/creates_a_new_ad_campaign.yml +115 -0
  59. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_create_ad_images/creates_an_image.yml +2865 -0
  60. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_find_by/finds_a_specific_account.yml +58 -0
  61. data/spec/fixtures/cassettes/FacebookAds_AdAccount/_reach_estimate/estimates_the_reach_of_a_targeting_spec.yml +56 -0
  62. data/spec/fixtures/cassettes/FacebookAds_AdCampaign/_destroy/creates_a_new_ad_campaign.yml +164 -0
  63. data/spec/spec_helper.rb +7 -0
  64. data/spec/support/approvals.rb +10 -0
  65. data/spec/support/facebook_ads.rb +4 -0
  66. data/spec/support/rest_client.rb +13 -0
  67. data/spec/support/vcr.rb +16 -0
  68. metadata +47 -29
  69. data/test/ad_account_test.rb +0 -27
  70. data/test/ad_campaign_test.rb +0 -32
  71. data/test/ad_creative_test.rb +0 -7
  72. data/test/ad_image_test.rb +0 -27
  73. data/test/ad_insight_test.rb +0 -7
  74. data/test/ad_product_catalog_test.rb +0 -28
  75. data/test/ad_product_feed_test.rb +0 -7
  76. data/test/ad_product_set_test.rb +0 -7
  77. data/test/ad_product_test.rb +0 -22
  78. data/test/ad_set_test.rb +0 -48
  79. data/test/ad_targeting_test.rb +0 -7
  80. data/test/ad_test.rb +0 -7
  81. data/test/facebook_ads_test.rb +0 -8
  82. data/test/test_helper.rb +0 -64
  83. data/test/vcr_cassettes/AdAccountTest-test_all.yml +0 -70
  84. data/test/vcr_cassettes/AdAccountTest-test_applications.yml +0 -130
  85. data/test/vcr_cassettes/AdAccountTest-test_find_by.yml +0 -71
  86. data/test/vcr_cassettes/AdCampaignTest-test_create.yml +0 -295
  87. data/test/vcr_cassettes/AdCampaignTest-test_list.yml +0 -133
  88. data/test/vcr_cassettes/AdImageTest-test_create.yml +0 -2963
  89. data/test/vcr_cassettes/AdImageTest-test_list.yml +0 -137
  90. data/test/vcr_cassettes/AdProductCatalogTest-test_all.yml +0 -60
  91. data/test/vcr_cassettes/AdProductCatalogTest-test_create.yml +0 -256
  92. data/test/vcr_cassettes/AdProductTest-test_list.yml +0 -130
  93. data/test/vcr_cassettes/AdSetTest-test_create.yml +0 -189
  94. data/test/vcr_cassettes/AdSetTest-test_destroy.yml +0 -124
  95. data/test/vcr_cassettes/AdSetTest-test_update.yml +0 -134
@@ -2,9 +2,51 @@ module FacebookAds
2
2
  # An ad campaign has many ad sets and belongs to an ad account.
3
3
  # https://developers.facebook.com/docs/marketing-api/reference/ad-campaign-group
4
4
  class AdCampaign < Base
5
- FIELDS = %w(id account_id buying_type can_use_spend_cap configured_status created_time effective_status name objective start_time stop_time updated_time spend_cap).freeze
6
- STATUSES = %w(ACTIVE PAUSED DELETED PENDING_REVIEW DISAPPROVED PREAPPROVED PENDING_BILLING_INFO CAMPAIGN_PAUSED ARCHIVED ADSET_PAUSED).freeze
7
- OBJECTIVES = %w(CONVERSIONS MOBILE_APP_INSTALLS).freeze
5
+ FIELDS = %w[
6
+ id
7
+ account_id
8
+ buying_type
9
+ can_use_spend_cap
10
+ configured_status
11
+ created_time
12
+ effective_status
13
+ name
14
+ objective
15
+ start_time
16
+ stop_time
17
+ updated_time spend_cap
18
+ ].freeze
19
+
20
+ STATUSES = %w[
21
+ ACTIVE PAUSED
22
+ DELETED
23
+ PENDING_REVIEW
24
+ DISAPPROVED
25
+ PREAPPROVED
26
+ PENDING_BILLING_INFO
27
+ CAMPAIGN_PAUSED
28
+ ARCHIVED
29
+ ADSET_PAUSED
30
+ ].freeze
31
+
32
+ OBJECTIVES = %w[
33
+ BRAND_AWARENESS
34
+ CANVAS_APP_ENGAGEMENT
35
+ CANVAS_APP_INSTALLS
36
+ EVENT_RESPONSES
37
+ LEAD_GENERATION
38
+ LOCAL_AWARENESS
39
+ MOBILE_APP_ENGAGEMENT
40
+ MOBILE_APP_INSTALLS
41
+ NONE
42
+ OFFER_CLAIMS
43
+ PAGE_LIKES
44
+ POST_ENGAGEMENT
45
+ LINK_CLICKS
46
+ CONVERSIONS
47
+ VIDEO_VIEWS
48
+ PRODUCT_CATALOG_SALES
49
+ ].freeze
8
50
 
9
51
  # belongs_to ad_account
10
52
 
@@ -19,8 +61,8 @@ module FacebookAds
19
61
  end
20
62
 
21
63
  def create_ad_set(name:, promoted_object:, targeting:, daily_budget:, optimization_goal:, billing_event: 'IMPRESSIONS', status: 'ACTIVE', is_autobid: true)
22
- raise Exception, "Optimization goal must be one of: #{AdSet::OPTIMIZATION_GOALS.to_sentence}" unless AdSet::OPTIMIZATION_GOALS.include?(optimization_goal)
23
- raise Exception, "Billing event must be one of: #{AdSet::BILLING_EVENTS.to_sentence}" unless AdSet::BILLING_EVENTS.include?(billing_event)
64
+ raise Exception, "Optimization goal must be one of: #{AdSet::OPTIMIZATION_GOALS.join(', ')}" unless AdSet::OPTIMIZATION_GOALS.include?(optimization_goal)
65
+ raise Exception, "Billing event must be one of: #{AdSet::BILLING_EVENTS.join(', ')}" unless AdSet::BILLING_EVENTS.include?(billing_event)
24
66
 
25
67
  if targeting.is_a?(Hash)
26
68
  # NOP
@@ -2,8 +2,8 @@ module FacebookAds
2
2
  # Ad ad creative has many ad images and belongs to an ad account.
3
3
  # https://developers.facebook.com/docs/marketing-api/reference/ad-creative
4
4
  class AdCreative < Base
5
- FIELDS = %w(id name object_story_id object_story_spec object_type thumbnail_url run_status).freeze
6
- CALL_TO_ACTION_TYPES = %w(SHOP_NOW INSTALL_MOBILE_APP USE_MOBILE_APP SIGN_UP DOWNLOAD BUY_NOW).freeze
5
+ FIELDS = %w[id name object_story_id object_story_spec object_type thumbnail_url run_status].freeze
6
+ CALL_TO_ACTION_TYPES = %w[SHOP_NOW INSTALL_MOBILE_APP USE_MOBILE_APP SIGN_UP DOWNLOAD BUY_NOW].freeze
7
7
 
8
8
  class << self
9
9
  def photo(name:, page_id:, instagram_actor_id: nil, message:, link:, link_title:, image_hash:, call_to_action_type:)
@@ -54,7 +54,6 @@ module FacebookAds
54
54
  }
55
55
  }
56
56
 
57
-
58
57
  {
59
58
  name: name,
60
59
  object_story_spec: object_story_spec.to_json
@@ -62,7 +61,8 @@ module FacebookAds
62
61
  end
63
62
 
64
63
  def product_set(name:, page_id:, link:, message:, headline:, description:, product_set_id:)
65
- { name: name,
64
+ {
65
+ name: name,
66
66
  object_story_spec: {
67
67
  page_id: page_id,
68
68
  template_data: {
@@ -1,5 +1,11 @@
1
1
  module FacebookAds
2
2
  class AdException < StandardError
3
- attr_accessor :code, :title, :message
3
+ attr_reader :code, :title, :message
4
+
5
+ def initialize(code:, title:, message:)
6
+ @code = code
7
+ @title = title
8
+ @message = message
9
+ end
4
10
  end
5
11
  end
@@ -3,7 +3,7 @@ module FacebookAds
3
3
  # An image will always produce the same hash.
4
4
  # https://developers.facebook.com/docs/marketing-api/reference/ad-image
5
5
  class AdImage < Base
6
- FIELDS = %w(id hash account_id name permalink_url original_width original_height).freeze
6
+ FIELDS = %w[id hash account_id name permalink_url original_width original_height].freeze
7
7
 
8
8
  class << self
9
9
  def find(_id)
@@ -11,6 +11,10 @@ module FacebookAds
11
11
  end
12
12
  end
13
13
 
14
+ # @TODO:
15
+ # You are setting a key that conflicts with a built-in method FacebookAds::AdImage#hash defined in Hash.
16
+ # This can cause unexpected behavior when accessing the key via as a property.
17
+ # You can still access the key via the #[] method.
14
18
  def hash
15
19
  self[:hash]
16
20
  end
@@ -20,7 +24,7 @@ module FacebookAds
20
24
  end
21
25
 
22
26
  def destroy
23
- super(path: "/act_#{account_id}/adimages", query: { hash: hash })
27
+ super(path: "/act_#{account_id}/adimages", query: { hash: self[:hash] })
24
28
  end
25
29
  end
26
30
  end
@@ -4,7 +4,7 @@ module FacebookAds
4
4
  # https://developers.facebook.com/docs/marketing-api/insights/overview
5
5
  # https://developers.facebook.com/docs/marketing-api/insights/fields/v2.8
6
6
  class AdInsight < Base
7
- FIELDS = %w(account_id campaign_id adset_id ad_id objective impressions unique_actions cost_per_unique_action_type clicks cpc cpm cpp ctr spend reach relevance_score).freeze
7
+ FIELDS = %w[account_id campaign_id adset_id ad_id objective impressions unique_actions cost_per_unique_action_type clicks cpc cpm cpp ctr spend reach relevance_score].freeze
8
8
 
9
9
  class << self
10
10
  def find(_id)
@@ -1,6 +1,6 @@
1
1
  module FacebookAds
2
2
  # https://developers.facebook.com/docs/marketing-api/reference/product-item
3
3
  class AdProduct < Base
4
- FIELDS = %w(id retailer_id name description brand category currency price image_url url).freeze
4
+ FIELDS = %w[id retailer_id name description brand category currency price image_url url].freeze
5
5
  end
6
6
  end
@@ -1,7 +1,7 @@
1
1
  module FacebookAds
2
2
  # https://developers.facebook.com/docs/marketing-api/reference/product-catalog
3
3
  class AdProductCatalog < Base
4
- FIELDS = %w(id name vertical product_count feed_count).freeze
4
+ FIELDS = %w[id name vertical product_count feed_count].freeze
5
5
 
6
6
  class << self
7
7
  def all(query = {})
@@ -1,6 +1,6 @@
1
1
  module FacebookAds
2
2
  # https://developers.facebook.com/docs/marketing-api/reference/product-feed
3
3
  class AdProductFeed < Base
4
- FIELDS = %w(id country created_time default_currency deletion_enabled delimiter encoding file_name latest_upload name product_count quoted_fields_mode schedule).freeze
4
+ FIELDS = %w[id country created_time default_currency deletion_enabled delimiter encoding file_name latest_upload name product_count quoted_fields_mode schedule].freeze
5
5
  end
6
6
  end
@@ -1,6 +1,6 @@
1
1
  module FacebookAds
2
2
  # https://developers.facebook.com/docs/marketing-api/reference/product-set
3
3
  class AdProductSet < Base
4
- FIELDS = %w(id auto_creation_url filter name product_catalog product_count).freeze
4
+ FIELDS = %w[id auto_creation_url filter name product_catalog product_count].freeze
5
5
  end
6
6
  end
@@ -20,7 +20,7 @@ module FacebookAds
20
20
  # ).freeze
21
21
 
22
22
  # Fields we might actually care about:
23
- FIELDS = %w(
23
+ FIELDS = %w[
24
24
  id account_id campaign_id
25
25
  name
26
26
  status configured_status effective_status
@@ -29,11 +29,11 @@ module FacebookAds
29
29
  promoted_object
30
30
  targeting
31
31
  created_time updated_time
32
- ).freeze
32
+ ].freeze
33
33
 
34
- STATUSES = %w(ACTIVE PAUSED DELETED PENDING_REVIEW DISAPPROVED PREAPPROVED PENDING_BILLING_INFO CAMPAIGN_PAUSED ARCHIVED ADSET_PAUSED).freeze
35
- BILLING_EVENTS = %w(APP_INSTALLS IMPRESSIONS).freeze
36
- OPTIMIZATION_GOALS = %w(APP_INSTALLS OFFSITE_CONVERSIONS).freeze
34
+ STATUSES = %w[ACTIVE PAUSED DELETED PENDING_REVIEW DISAPPROVED PREAPPROVED PENDING_BILLING_INFO CAMPAIGN_PAUSED ARCHIVED ADSET_PAUSED].freeze
35
+ BILLING_EVENTS = %w[APP_INSTALLS IMPRESSIONS].freeze
36
+ OPTIMIZATION_GOALS = %w[APP_INSTALLS OFFSITE_CONVERSIONS].freeze
37
37
 
38
38
  # belongs_to ad_account
39
39
 
@@ -7,8 +7,8 @@ module FacebookAds
7
7
  ANDROID_OS = 'Android'.freeze
8
8
  APPLE_OS = 'iOS'.freeze
9
9
  OSES = [ANDROID_OS, APPLE_OS].freeze
10
- ANDROID_DEVICES = %w(Android_Smartphone Android_Tablet).freeze
11
- APPLE_DEVICES = %w(iPhone iPad iPod).freeze
10
+ ANDROID_DEVICES = %w[Android_Smartphone Android_Tablet].freeze
11
+ APPLE_DEVICES = %w[iPhone iPad iPod].freeze
12
12
  DEVICES = ANDROID_DEVICES + APPLE_DEVICES
13
13
  INSTALLED = 'installed'.freeze
14
14
  NOT_INSTALLED = 'not_installed'.freeze
@@ -53,7 +53,7 @@ module FacebookAds
53
53
  user_os: user_os,
54
54
  user_device: user_device,
55
55
  app_install_state: app_install_state
56
- }.compact
56
+ }.reject { |_k, v| v.nil? }
57
57
  end
58
58
  end
59
59
  end
@@ -11,7 +11,7 @@ module FacebookAds
11
11
  uri = "#{FacebookAds.base_uri}#{path}?" + build_nested_query(query)
12
12
  FacebookAds.logger.debug "GET #{uri}"
13
13
  response = begin
14
- RestClient.get(uri)
14
+ RestClient.get(uri, accept: :json, accept_encoding: :identity)
15
15
  rescue RestClient::Exception => e
16
16
  exception(:get, path, e)
17
17
  end
@@ -75,6 +75,7 @@ module FacebookAds
75
75
 
76
76
  hash.each_pair do |key, value|
77
77
  # https://github.com/intridea/hashie/blob/master/lib/hashie/mash.rb#L111
78
+ # key = '_hash' if key == 'hash'
78
79
  object.custom_writer(key, value, false)
79
80
  end
80
81
 
@@ -137,15 +138,15 @@ module FacebookAds
137
138
  begin
138
139
  if (error = JSON.parse(response)['error']).nil?
139
140
  response
141
+ elsif error['error_subcode'].nil? || error['error_user_title'].nil? || error['error_user_msg'].nil?
142
+ "#{error['type']} / #{error['code']}: #{error['message']}"
140
143
  else
141
- if error['error_subcode'].nil? ||
142
- error['error_user_title'].nil? ||
143
- error['error_user_msg'].nil?
144
- "#{error['type']} / #{error['code']}: #{error['message']}"
145
- else
146
- exception = AdException.new(code: error['error_subcode'], title: error['error_user_title'], message: error['error_user_msg'])
147
- "#{error['error_subcode']} / #{error['error_user_title']}: #{error['error_user_msg']}"
148
- end
144
+ exception = AdException.new(
145
+ code: error['error_subcode'],
146
+ title: error['error_user_title'],
147
+ message: error['error_user_msg']
148
+ )
149
+ "#{exception.code} / #{exception.title}: #{exception.message}"
149
150
  end
150
151
  rescue JSON::ParserError
151
152
  response
@@ -0,0 +1,93 @@
1
+ require 'spec_helper'
2
+
3
+ # FACEBOOK_ACCESS_TOKEN=... rspec spec/facebook_ads/ad_account_spec.rb
4
+ describe FacebookAds::AdAccount do
5
+ let(:account) do
6
+ FacebookAds::AdAccount.new(
7
+ id: 'act_10152335766987003',
8
+ account_id: '10152335766987003',
9
+ account_status: 1,
10
+ age: 466.0,
11
+ created_time: '2014-10-24T14:38:31-0700',
12
+ currency: 'USD',
13
+ name: 'Chris Estreich'
14
+ )
15
+ end
16
+
17
+ describe '#all' do
18
+ it 'lists all accounts', :vcr do
19
+ accounts = FacebookAds::AdAccount.all
20
+ verify(format: :json) { JSON.dump(accounts) }
21
+ end
22
+ end
23
+
24
+ describe '#find_by' do
25
+ it 'finds a specific account', :vcr do
26
+ account = FacebookAds::AdAccount.find_by(name: 'iOS')
27
+ verify(format: :json) { JSON.dump(account) }
28
+ end
29
+ end
30
+
31
+ describe '.ad_campaigns' do
32
+ it 'lists campaigns', :vcr do
33
+ ad_campaigns = account.ad_campaigns
34
+ verify(format: :json) { JSON.dump(ad_campaigns) }
35
+ end
36
+ end
37
+
38
+ describe '.create_ad_campaign' do
39
+ it 'creates a new ad campaign', :vcr do
40
+ ad_campaign = account.create_ad_campaign(name: 'Test', objective: 'MOBILE_APP_INSTALLS')
41
+ verify(format: :json) { JSON.dump(ad_campaign) }
42
+ end
43
+ end
44
+
45
+ describe '.ad_images' do
46
+ it 'lists images', :vcr do
47
+ ad_images = account.ad_images(hashes: %w[d8fc613662fb5ef6cf5fb9d1fe779315])
48
+ verify(format: :json) { JSON.dump(ad_images) }
49
+ expect(ad_images.first.hash).to eq('d8fc613662fb5ef6cf5fb9d1fe779315')
50
+ end
51
+ end
52
+
53
+ describe '.create_ad_images' do
54
+ it 'creates an image', :vcr do
55
+ ad_images = account.create_ad_images(['https://img0.etsystatic.com/108/1/13006112/il_570xN.1047856494_l2gp.jpg'])
56
+ verify(format: :json) { JSON.dump(ad_images) }
57
+ expect(ad_images.first.hash).to eq('d8fc613662fb5ef6cf5fb9d1fe779315')
58
+ end
59
+ end
60
+
61
+ describe '.ad_creatives' do
62
+ it 'lists creatives', :vcr do
63
+ ad_creatives = account.ad_creatives
64
+ verify(format: :json) { JSON.dump(ad_creatives) }
65
+ end
66
+ end
67
+
68
+ describe '.ad_sets' do
69
+ it 'lists ad sets', :vcr do
70
+ ad_sets = account.ad_sets
71
+ verify(format: :json) { JSON.dump(ad_sets) }
72
+ end
73
+ end
74
+
75
+ describe '.ads' do
76
+ it 'lists ads', :vcr do
77
+ ads = account.ads
78
+ verify(format: :json) { JSON.dump(ads) }
79
+ end
80
+ end
81
+
82
+ describe '.reach_estimate' do
83
+ it 'estimates the reach of a targeting spec', :vcr do
84
+ targeting = FacebookAds::AdTargeting.new
85
+ targeting.genders = [FacebookAds::AdTargeting::WOMEN]
86
+ targeting.age_min = 18
87
+ targeting.age_max = 20
88
+ targeting.countries = ['US']
89
+ reach = account.reach_estimate(targeting: targeting, optimization_goal: 'OFFSITE_CONVERSIONS')
90
+ verify(format: :json) { JSON.dump(reach) }
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ # FACEBOOK_ACCESS_TOKEN=... rspec spec/facebook_ads/ad_campaign_spec.rb
4
+ describe FacebookAds::AdCampaign do
5
+ xdescribe '.ad_sets' do
6
+ end
7
+
8
+ xdescribe '.create_ad_set' do
9
+ end
10
+
11
+ describe '.destroy' do
12
+ it 'creates a new ad campaign', :vcr do
13
+ ad_campaign = FacebookAds::AdCampaign.find('6076262142242')
14
+ expect(ad_campaign.destroy).to be(true)
15
+ ad_campaign = FacebookAds::AdCampaign.find(ad_campaign.id)
16
+ expect(ad_campaign.effective_status).to eq('DELETED')
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdCreative do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdImage do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdInsight do
4
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdProductCatalog do
4
+ # def test_all
5
+ # vcr do
6
+ # catalog = FacebookAds::AdProductCatalog.all.first
7
+ # assert_equal '197871307315718', catalog.id
8
+ # assert_equal 'Test', catalog.name
9
+ # assert_equal 'commerce', catalog.vertical
10
+ # assert_equal 1, catalog.product_count
11
+ # assert_equal 1, catalog.feed_count
12
+ # end
13
+ # end
14
+ #
15
+ # def test_create
16
+ # vcr do
17
+ # catalog = FacebookAds::AdProductCatalog.create(name: 'Foo Bar')
18
+ # assert_equal 'Foo Bar', catalog.name
19
+ # assert_equal 'commerce', catalog.vertical
20
+ # assert_equal 0, catalog.product_count
21
+ # assert_equal 0, catalog.feed_count
22
+ # catalog = FacebookAds::AdProductCatalog.find(catalog.id)
23
+ # assert_equal true, catalog.destroy
24
+ # assert_nil FacebookAds::AdProductCatalog.find_by(name: 'Foo Bar')
25
+ # end
26
+ # end
27
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdProductFeed do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe FacebookAds::AdProductSet do
4
+ end