eucalyptus 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f17283339eb29832b6ca29b810539783b67fbca8
4
- data.tar.gz: 1eb136e165e2182ebe8db581e69b8e2868515ecd
3
+ metadata.gz: 485cdd5a1ab888a49685773e0de56b702817ef92
4
+ data.tar.gz: d18f3e3a800a663772619b8fba0c1a437bd7fb4a
5
5
  SHA512:
6
- metadata.gz: 72390b8cf41162495cd09cf4bdcde01a62e53d283605f40b9d367859311894dab7033d6f5e3169e6eb5c2ed28dbb003ab853a68d10e40fd04a12e705c8241982
7
- data.tar.gz: d0d7836fc079ddf6f1422e99c8032a213e915ac20da0203aab3f1e18c4430100113de8683c9eb1a1b057c926a12382c7dc3fc187d797322515be686af1693e73
6
+ metadata.gz: f699c5496d353681f5b8e6ae49a648f591fc5b8c357ae2791d0fa8c3a92ad42d90a235c146143157d68a8bd16a0644cadc9ed6052300c6c2bd4d58a057eabc64
7
+ data.tar.gz: 4a6946e771678ce08a2b542e1ebe31eeecfdbde241afe13ef39848d3b83178e2b82c0f7c94fd9796f51d2b3245fe598944743be2c8d572ccefbcbf0fc154b117
data/Gemfile CHANGED
@@ -11,7 +11,6 @@ group :development do
11
11
  gem "rdoc", "~> 3.12"
12
12
  gem "bundler", "~> 1.0"
13
13
  gem "jeweler", "~> 2.0.1"
14
- gem "simplecov", ">= 0"
15
14
  gem "pry"
16
15
  gem 'dotenv'
17
16
  gem 'webmock'
data/Gemfile.lock CHANGED
@@ -9,7 +9,6 @@ GEM
9
9
  descendants_tracker (0.0.4)
10
10
  thread_safe (~> 0.3, >= 0.3.1)
11
11
  diff-lcs (1.2.5)
12
- docile (1.1.5)
13
12
  dotenv (2.0.1)
14
13
  faraday (0.9.1)
15
14
  multipart-post (>= 1.2, < 3)
@@ -74,11 +73,6 @@ GEM
74
73
  rspec-support (~> 3.3.0)
75
74
  rspec-support (3.3.0)
76
75
  safe_yaml (1.0.4)
77
- simplecov (0.10.0)
78
- docile (~> 1.1.0)
79
- json (~> 1.8)
80
- simplecov-html (~> 0.10.0)
81
- simplecov-html (0.10.0)
82
76
  slop (3.6.0)
83
77
  thread_safe (0.3.5)
84
78
  vcr (2.9.2)
@@ -97,6 +91,5 @@ DEPENDENCIES
97
91
  pry
98
92
  rdoc (~> 3.12)
99
93
  rspec
100
- simplecov
101
94
  vcr
102
95
  webmock
data/README.md CHANGED
@@ -33,8 +33,8 @@ campaign.name
33
33
  account_ads = account.ads
34
34
  campaign_ads = campaign.ads
35
35
 
36
- stats = campaign.report_stats
37
- stats.cpa
36
+ insights = campaign.insights
37
+ insights.cpa
38
38
 
39
39
  ads = Add.all
40
40
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/eucalyptus.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: eucalyptus 0.1.0 ruby lib
5
+ # stub: eucalyptus 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "eucalyptus"
9
- s.version = "0.1.0"
9
+ s.version = "0.2.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 = ["Oguz Huner"]
14
- s.date = "2015-06-16"
14
+ s.date = "2015-06-22"
15
15
  s.description = "An easy interface and abstraction to the Facebook Ads API"
16
16
  s.email = "oguzcanhuner@gmail.com"
17
17
  s.extra_rdoc_files = [
@@ -20,7 +20,6 @@ Gem::Specification.new do |s|
20
20
  ]
21
21
  s.files = [
22
22
  ".document",
23
- ".env",
24
23
  ".rspec",
25
24
  "Gemfile",
26
25
  "Gemfile.lock",
@@ -29,20 +28,21 @@ Gem::Specification.new do |s|
29
28
  "Rakefile",
30
29
  "VERSION",
31
30
  "eucalyptus.gemspec",
32
- "fixtures/vcr_cassettes/account_ad_sets.yml",
33
- "fixtures/vcr_cassettes/account_ads.yml",
34
- "fixtures/vcr_cassettes/account_campaigns.yml",
35
- "fixtures/vcr_cassettes/test2.yml",
36
31
  "lib/eucalyptus.rb",
37
32
  "lib/eucalyptus/account.rb",
38
33
  "lib/eucalyptus/ad.rb",
39
34
  "lib/eucalyptus/ad_set.rb",
40
35
  "lib/eucalyptus/campaign.rb",
41
36
  "lib/eucalyptus/custom_audience.rb",
37
+ "lib/eucalyptus/insight.rb",
42
38
  "lib/eucalyptus/resource.rb",
43
39
  "lib/eucalyptus/response.rb",
44
40
  "spec/eucalyptus/account_spec.rb",
41
+ "spec/eucalyptus/ad_set_spec.rb",
42
+ "spec/eucalyptus/ad_spec.rb",
43
+ "spec/eucalyptus/campaign_spec.rb",
45
44
  "spec/eucalyptus/custom_audience_spec.rb",
45
+ "spec/eucalyptus/insight_spec.rb",
46
46
  "spec/eucalyptus/resource_spec.rb",
47
47
  "spec/eucalyptus_spec.rb",
48
48
  "spec/spec_helper.rb"
@@ -62,7 +62,6 @@ Gem::Specification.new do |s|
62
62
  s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
63
63
  s.add_development_dependency(%q<bundler>, ["~> 1.0"])
64
64
  s.add_development_dependency(%q<jeweler>, ["~> 2.0.1"])
65
- s.add_development_dependency(%q<simplecov>, [">= 0"])
66
65
  s.add_development_dependency(%q<pry>, [">= 0"])
67
66
  s.add_development_dependency(%q<dotenv>, [">= 0"])
68
67
  s.add_development_dependency(%q<webmock>, [">= 0"])
@@ -73,7 +72,6 @@ Gem::Specification.new do |s|
73
72
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
74
73
  s.add_dependency(%q<bundler>, ["~> 1.0"])
75
74
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
76
- s.add_dependency(%q<simplecov>, [">= 0"])
77
75
  s.add_dependency(%q<pry>, [">= 0"])
78
76
  s.add_dependency(%q<dotenv>, [">= 0"])
79
77
  s.add_dependency(%q<webmock>, [">= 0"])
@@ -85,7 +83,6 @@ Gem::Specification.new do |s|
85
83
  s.add_dependency(%q<rdoc>, ["~> 3.12"])
86
84
  s.add_dependency(%q<bundler>, ["~> 1.0"])
87
85
  s.add_dependency(%q<jeweler>, ["~> 2.0.1"])
88
- s.add_dependency(%q<simplecov>, [">= 0"])
89
86
  s.add_dependency(%q<pry>, [">= 0"])
90
87
  s.add_dependency(%q<dotenv>, [">= 0"])
91
88
  s.add_dependency(%q<webmock>, [">= 0"])
@@ -2,18 +2,60 @@ require_relative 'resource'
2
2
 
3
3
  module Eucalyptus
4
4
  class Account < Resource
5
+ def self.known_fields
6
+ [
7
+ :account_status,
8
+ :age,
9
+ :agency_client_declaration,
10
+ :amount_spent,
11
+ :balance,
12
+ :business,
13
+ :business_city,
14
+ :business_country_code,
15
+ :business_name,
16
+ :business_street,
17
+ :business_street2,
18
+ :business_zip,
19
+ :capabilities,
20
+ :created_time,
21
+ :currency,
22
+ :daily_spend_limit,
23
+ :end_advertiser,
24
+ :funding_source,
25
+ :funding_source_details,
26
+ :is_personal,
27
+ :media_agency,
28
+ :name,
29
+ :offsite_pixels_tos_accepted,
30
+ :partner,
31
+ :rf_spec,
32
+ :spend_cap,
33
+ :tax_id_status,
34
+ :timezone_id,
35
+ :timezone_name,
36
+ :timezone_offset_hours_utc,
37
+ :tos_accepted,
38
+ :users
39
+ ]
40
+ end
41
+
5
42
  def self.api_path
6
43
  "adaccounts"
7
44
  end
8
45
 
46
+
9
47
  # 'me' is a facebook helper which refers to the user who created the access token
48
+ #
49
+ # there is no object which abstracts this, which is why we're using a generic
50
+ # open struct that can response to id
10
51
  def self.parent
11
52
  OpenStruct.new(id: "me")
12
53
  end
13
54
 
14
- # associations
55
+ # ASSOCIATOINS
15
56
  def ads; Ad.all(parent: self); end
16
57
  def ad_sets; AdSet.all(parent: self); end
17
58
  def campaigns; Campaign.all(parent: self); end
59
+ def insights; Insight.all(parent: self); end
18
60
  end
19
61
  end
data/lib/eucalyptus/ad.rb CHANGED
@@ -2,6 +2,25 @@ require_relative 'resource'
2
2
 
3
3
  module Eucalyptus
4
4
  class Ad < Resource
5
+ def self.known_fields
6
+ [
7
+ :name,
8
+ :adgroup_status,
9
+ :bid_info,
10
+ :conversion_specs,
11
+ :campaign_id,
12
+ :creative,
13
+ :engagement_audiences,
14
+ :execution_options,
15
+ :redownload,
16
+ :tracking_specs,
17
+ :social_prefs
18
+ ]
19
+ end
20
+
21
+ def ad_set; AdSet.find(self.campaign_id); end
22
+ def insights; Insight.all(parent: self); end
23
+
5
24
  def self.api_path
6
25
  "adgroups"
7
26
  end
@@ -2,6 +2,32 @@ require_relative 'resource'
2
2
 
3
3
  module Eucalyptus
4
4
  class AdSet < Resource
5
+ def self.known_fields
6
+ [
7
+ :account_id,
8
+ :bid_info,
9
+ :bid_type,
10
+ :campaign_group_id,
11
+ :campaign_status,
12
+ :created_time,
13
+ :creative_sequence,
14
+ :daily_budget,
15
+ :end_time,
16
+ :is_autobid,
17
+ :lifetime_budget,
18
+ :name,
19
+ :promoted_object,
20
+ :rf_prediction_id,
21
+ :start_time,
22
+ :targeting,
23
+ :updated_time
24
+ ]
25
+ end
26
+
27
+ def campaign; Campaign.find(self.campaign_group_id); end
28
+ def ads; Ad.all(parent: self); end
29
+ def insights; Insight.all(parent: self); end
30
+
5
31
  def self.api_path
6
32
  "adcampaigns"
7
33
  end
@@ -2,8 +2,22 @@ require_relative 'resource'
2
2
 
3
3
  module Eucalyptus
4
4
  class Campaign < Resource
5
+ def self.known_fields
6
+ [
7
+ :buying_type,
8
+ :campaign_group_status,
9
+ :name,
10
+ :objective,
11
+ :spend_cap
12
+ ]
13
+ end
14
+
5
15
  def self.api_path
6
16
  "adcampaign_groups"
7
17
  end
18
+
19
+ def ads; Ad.all(parent: self); end
20
+ def ad_sets; AdSet.all(parent: self); end
21
+ def insights; Insight.all(parent: self); end
8
22
  end
9
23
  end
@@ -5,5 +5,9 @@ module Eucalyptus
5
5
  def self.api_path
6
6
  "customaudiences"
7
7
  end
8
+
9
+ def self.known_fields
10
+ [:name, :description]
11
+ end
8
12
  end
9
13
  end
@@ -0,0 +1,43 @@
1
+ require_relative 'resource'
2
+
3
+ module Eucalyptus
4
+ class Insight < Resource
5
+ def self.known_fields
6
+ [
7
+ :actions_per_impression,
8
+ :call_to_action_clicks,
9
+ :clicks,
10
+ :unique_clicks,
11
+ :cost_per_total_action,
12
+ :cpc,
13
+ :cost_per_unique_click,
14
+ :cpm,
15
+ :cpp,
16
+ :ctr,
17
+ :website_ctr,
18
+ :unique_ctr,
19
+ :frequency,
20
+ :impressions,
21
+ :reach,
22
+ :relevance_score,
23
+ :roas,
24
+ :social_clicks,
25
+ :unique_social_clicks,
26
+ :social_impressions,
27
+ :social_reach,
28
+ :spend,
29
+ :total_action_value,
30
+ :total_actions,
31
+ :total_unique_actions
32
+ ]
33
+ end
34
+
35
+ def self.find
36
+ raise "An insight can only be used as part of a combined call. Try Insight.all"
37
+ end
38
+
39
+ def self.api_path
40
+ 'insights'
41
+ end
42
+ end
43
+ end
@@ -1,20 +1,28 @@
1
1
  module Eucalyptus
2
2
  class Resource
3
3
  def self.api_path
4
- raise "You must implement this method"
4
+ raise "You must implement #{__method__.to_s}"
5
+ end
6
+
7
+ def self.known_fields
8
+ raise "You must implement #{__method__.to_s}"
5
9
  end
6
10
 
7
11
  def self.parent
8
12
  Account.all.last
9
13
  end
10
14
 
11
- def self.find(id, graph: Eucalyptus.graph)
12
- response = graph.get_object(id)
15
+ def self.find(id, fields: [], graph: Eucalyptus.graph)
16
+ fields.concat(self.known_fields).uniq
17
+
18
+ response = graph.get_object(id, fields: fields)
13
19
  self.new(response)
14
20
  end
15
21
 
16
- def self.all(graph: Eucalyptus.graph, parent: self.parent)
17
- response = graph.get_connection(parent.id, api_path)
22
+ def self.all(graph: Eucalyptus.graph, parent: self.parent, fields: [])
23
+ fields.concat(self.known_fields).uniq
24
+
25
+ response = graph.get_connection(parent.id, api_path, fields: fields)
18
26
  response.collect{ |res| self.new(res) }
19
27
  end
20
28
 
@@ -25,5 +33,9 @@ module Eucalyptus
25
33
  def method_missing(method_sym, *args, &block)
26
34
  @response.send(method_sym)
27
35
  end
36
+
37
+ def respond_to?(method_sym, include_private = false)
38
+ @response.respond_to?(method_sym)
39
+ end
28
40
  end
29
41
  end
@@ -7,9 +7,18 @@ describe Eucalyptus::Account do
7
7
  end
8
8
  end
9
9
 
10
- describe '#ads' do
11
- let(:account) { Eucalyptus::Account.all.last }
10
+ let(:account) { Eucalyptus::Account.all.last }
11
+
12
+ describe '#insights' do
13
+ it 'returns an array of insights for the account' do
14
+ VCR.use_cassette("resource_insights") do
15
+ expect(account.insights).to be_a Array
16
+ expect(account.insights.first).to be_a Eucalyptus::Insight
17
+ end
18
+ end
19
+ end
12
20
 
21
+ describe '#ads' do
13
22
  it 'returns a collection of Ad objects which belong to the account' do
14
23
  VCR.use_cassette("account_ads") do
15
24
  expect(account.ads).to be_a Array
@@ -19,26 +28,20 @@ describe Eucalyptus::Account do
19
28
  end
20
29
 
21
30
  describe '#ad_sets' do
22
- let(:account) { Eucalyptus::Account.all.last }
23
-
24
31
  it 'returns a collection of AdSet objects which belong to the account' do
25
32
  VCR.use_cassette("account_ad_sets") do
26
33
  expect(account.ad_sets).to be_a Array
27
34
  expect(account.ad_sets.first).to be_a Eucalyptus::AdSet
28
35
  end
29
36
  end
30
-
31
37
  end
32
38
 
33
39
  describe '#campaigns' do
34
- let(:account) { Eucalyptus::Account.all.last }
35
-
36
40
  it 'returns a collection of AdSet objects which belong to the account' do
37
41
  VCR.use_cassette("account_campaigns") do
38
42
  expect(account.campaigns).to be_a Array
39
43
  expect(account.campaigns.first).to be_a Eucalyptus::Campaign
40
44
  end
41
45
  end
42
-
43
46
  end
44
47
  end
@@ -0,0 +1,47 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Eucalyptus::AdSet do
4
+ before do
5
+ Eucalyptus.configure do |config|
6
+ config.access_token = ENV["ACCESS_TOKEN"]
7
+ end
8
+ end
9
+
10
+ let(:ad_set) { Eucalyptus::AdSet.all.first }
11
+
12
+ describe '#insights' do
13
+ it 'returns an array of insights for the account' do
14
+ VCR.use_cassette("ad_set_insights") do
15
+ active_ad_set = Eucalyptus::AdSet.all.find{|ad_set| ad_set.campaign_status == "ACTIVE"}
16
+ expect(active_ad_set.insights).to be_a Array
17
+ expect(active_ad_set.insights.first).to be_a Eucalyptus::Insight
18
+ end
19
+ end
20
+ end
21
+
22
+ describe '#campaign' do
23
+ it 'returns the parent campaign for an ad_set' do
24
+ VCR.use_cassette("ad_set_campaign") do
25
+ expect(ad_set.campaign).to be_a Eucalyptus::Campaign
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#ads' do
31
+ it 'returns a collection of Ad objects which belong to the ad_set' do
32
+ VCR.use_cassette("ad_set_ads") do
33
+ expect(ad_set.ads).to be_a Array
34
+ expect(ad_set.ads.first).to be_a Eucalyptus::Ad
35
+ end
36
+ end
37
+ end
38
+
39
+ describe 'returning known fields' do
40
+ it 'returns an object which responds to available fields' do
41
+ VCR.use_cassette("ad_set") do
42
+ expect(ad_set).to respond_to :name
43
+ expect(ad_set).to respond_to :bid_type
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Eucalyptus::Ad do
4
+ before do
5
+ Eucalyptus.configure do |config|
6
+ config.access_token = ENV["ACCESS_TOKEN"]
7
+ end
8
+ end
9
+
10
+ let(:ad) { Eucalyptus::Ad.all.last }
11
+
12
+ describe '#insights' do
13
+ it 'returns an array of insights for the account' do
14
+ VCR.use_cassette("ad_set_insights") do
15
+ active_ad = Eucalyptus::Ad.all.find{|ad| ad.adgroup_status == "ACTIVE"}
16
+ expect(active_ad.insights).to be_a Array
17
+ expect(active_ad.insights.first).to be_a Eucalyptus::Insight
18
+ end
19
+ end
20
+ end
21
+
22
+ describe '#ad_set' do
23
+ it 'returns the parent ad_set for this ad' do
24
+ VCR.use_cassette("ad_adset") do
25
+ expect(ad.ad_set).to be_a Eucalyptus::AdSet
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'returning known fields' do
31
+
32
+ it 'returns an object which responds to available fields' do
33
+ VCR.use_cassette("ad") do
34
+ expect(ad).to respond_to :name
35
+ expect(ad).to respond_to :adgroup_status
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Eucalyptus::Campaign do
4
+ before do
5
+ Eucalyptus.configure do |config|
6
+ config.access_token = ENV["ACCESS_TOKEN"]
7
+ end
8
+ end
9
+
10
+ let(:campaign) { Eucalyptus::Campaign.all.last }
11
+
12
+ describe '#insights' do
13
+ it 'returns an array of insights for the account' do
14
+ VCR.use_cassette("campaign_insights") do
15
+ expect(campaign.insights).to be_a Array
16
+ expect(campaign.insights.first).to be_a Eucalyptus::Insight
17
+ end
18
+ end
19
+ end
20
+
21
+ describe '#ads' do
22
+ it 'returns a collection of Ad objects which belong to the campaign' do
23
+ VCR.use_cassette("campaign_ads") do
24
+ expect(campaign.ads).to be_a Array
25
+ expect(campaign.ads.first).to be_a Eucalyptus::Ad
26
+ end
27
+ end
28
+ end
29
+
30
+ describe '#ad_sets' do
31
+ it 'returns a collection of Ad objects which belong to the campaign' do
32
+ VCR.use_cassette("campaign_ad_sets") do
33
+ expect(campaign.ad_sets).to be_a Array
34
+ expect(campaign.ad_sets.first).to be_a Eucalyptus::AdSet
35
+ end
36
+ end
37
+ end
38
+
39
+ describe 'returning known fields' do
40
+ it 'returns an object which responds to available fields' do
41
+ VCR.use_cassette("campaign") do
42
+ expect(campaign).to respond_to :name
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe Eucalyptus::Insight do
4
+ before do
5
+ Eucalyptus.configure do |config|
6
+ config.access_token = ENV["ACCESS_TOKEN"]
7
+ end
8
+ end
9
+
10
+ describe '.known_fields' do
11
+ it 'returns an object which responds to available fields' do
12
+ VCR.use_cassette('account_insights') do
13
+ account = Eucalyptus::Account.all.last
14
+ insights = account.insights.first
15
+
16
+ expect(insights).to respond_to :clicks
17
+ expect(insights).to respond_to :cpc
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,8 +1,14 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
2
 
3
3
  describe Eucalyptus::Resource do
4
+ before do
5
+ Eucalyptus.configure do |config|
6
+ config.access_token = ENV["ACCESS_TOKEN"]
7
+ end
8
+ end
4
9
 
5
10
  context "given a class which inherits from Eucalyptus::Resource" do
11
+
6
12
  describe ".find" do
7
13
  let(:graph) { double(:graph, get_object: { "id" => "123" }) }
8
14
 
@@ -14,6 +20,35 @@ describe Eucalyptus::Resource do
14
20
  audience = Eucalyptus::CustomAudience.find(123, graph: graph)
15
21
  expect(audience.id).to eql "123"
16
22
  end
23
+
24
+ context 'when the target class has defined valid known fields' do
25
+ before do
26
+ expect(Eucalyptus::CustomAudience.known_fields).to include :name
27
+ end
28
+
29
+ it 'returns an object which responds to those fields' do
30
+ VCR.use_cassette("custom_audience") do
31
+ audience = Eucalyptus::CustomAudience.find(6025480500671)
32
+ expect(audience).to respond_to :name
33
+ end
34
+ end
35
+
36
+ it 'returns an object which doesnt respond to unkown fields' do
37
+ VCR.use_cassette("custom_audience") do
38
+ audience = Eucalyptus::CustomAudience.find(6025480500671)
39
+ expect(audience).to_not respond_to :random_method
40
+ end
41
+ end
42
+
43
+ it 'accepts extra fields' do
44
+ graph = double(:graph)
45
+ expect(graph).to receive(:get_object)
46
+ .with(123, {fields: [:custom_field, :name, :description]})
47
+ .and_return([])
48
+
49
+ Eucalyptus::CustomAudience.find(123, graph: graph, fields: [:custom_field])
50
+ end
51
+ end
17
52
  end
18
53
 
19
54
  describe '.all' do
@@ -24,6 +59,35 @@ describe Eucalyptus::Resource do
24
59
  it 'returns a collection of resources' do
25
60
  expect(Eucalyptus::CustomAudience.all(graph: graph, parent: parent)).to be_a Array
26
61
  end
62
+
63
+ context 'when the target class has defined valid known fields' do
64
+ let(:graph) { double(:graph, get_connection: [{ "id" => "123", "name" => "test-audience" }]) }
65
+
66
+ before do
67
+ expect(Eucalyptus::CustomAudience.known_fields).to include :name
68
+ end
69
+
70
+ it 'returns an object which responds to those fields' do
71
+ VCR.use_cassette("custom_audiences") do
72
+ audiences = Eucalyptus::CustomAudience.all
73
+ expect(audiences.first).to respond_to :name
74
+ end
75
+ end
76
+
77
+ it 'returns an object which doesnt respond to unkown fields' do
78
+ audiences = Eucalyptus::CustomAudience.all(graph: graph, parent: parent)
79
+ expect(audiences.first).to_not respond_to :random_method
80
+ end
81
+
82
+ it 'accepts extra fields' do
83
+ graph = double(:graph)
84
+ expect(graph).to receive(:get_connection)
85
+ .with(123, "customaudiences", {fields: [:custom_field, :name, :description]})
86
+ .and_return([])
87
+
88
+ Eucalyptus::CustomAudience.all(graph: graph, parent: parent, fields: [:custom_field])
89
+ end
90
+ end
27
91
  end
28
92
 
29
93
  describe '#method_missing' do