francois-ad_gear_client 0.1.1
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.
- data/.document +1 -0
- data/.gitignore +5 -0
- data/LICENSE +21 -0
- data/README.rdoc +17 -0
- data/Rakefile +117 -0
- data/VERSION +1 -0
- data/ad_gear_client.gemspec +96 -0
- data/examples/.gitignore +1 -0
- data/examples/ad_gear.yml.sample +8 -0
- data/examples/prelude.rb +18 -0
- data/examples/read_write_site.rb +32 -0
- data/examples/upload_file_to_ad_unit.rb +40 -0
- data/lib/ad_gear/ad_spot.rb +6 -0
- data/lib/ad_gear/ad_unit.rb +6 -0
- data/lib/ad_gear/ad_unit_click.rb +4 -0
- data/lib/ad_gear/ad_unit_file.rb +5 -0
- data/lib/ad_gear/ad_unit_interaction.rb +4 -0
- data/lib/ad_gear/ad_unit_variable.rb +4 -0
- data/lib/ad_gear/base.rb +144 -0
- data/lib/ad_gear/campaign.rb +4 -0
- data/lib/ad_gear/click.rb +4 -0
- data/lib/ad_gear/config.rb +139 -0
- data/lib/ad_gear/file.rb +4 -0
- data/lib/ad_gear/format.rb +4 -0
- data/lib/ad_gear/has_many_array.rb +50 -0
- data/lib/ad_gear/interaction.rb +4 -0
- data/lib/ad_gear/site.rb +6 -0
- data/lib/ad_gear/template.rb +4 -0
- data/lib/ad_gear/upload.rb +46 -0
- data/lib/ad_gear/variable.rb +4 -0
- data/lib/ad_gear/xml_format.rb +35 -0
- data/lib/ad_gear.rb +93 -0
- data/lib/core_ext.rb +18 -0
- data/test/ad_gear/ad_spot_test.rb +43 -0
- data/test/ad_gear/config_test.rb +91 -0
- data/test/ad_gear/site_test.rb +69 -0
- data/test/ad_gear/upload_test.rb +37 -0
- data/test/ad_gear_test.rb +23 -0
- data/test/fixtures/access-denied-no-auth.txt +13 -0
- data/test/test_helper.rb +33 -0
- metadata +141 -0
@@ -0,0 +1,139 @@
|
|
1
|
+
module AdGear
|
2
|
+
class Config
|
3
|
+
# Raised when the specified environment could not be found in the YAML configuration file.
|
4
|
+
class MissingEnvironmentSpecification < RuntimeError; end
|
5
|
+
|
6
|
+
# Reads in a YAML file containing configuration parameters for the AdGear::Client. The file
|
7
|
+
# can contain sections relating to the environment the client is running within.
|
8
|
+
#
|
9
|
+
# The YAML configuration file *must* use strings as keys.
|
10
|
+
#
|
11
|
+
# @example A sample YAML configuration file:
|
12
|
+
# development:
|
13
|
+
# site: http://localhost:3000/api
|
14
|
+
# user: dummy
|
15
|
+
# password: whatever
|
16
|
+
# logger: path/to/log/file.log
|
17
|
+
# production:
|
18
|
+
# site: http://admin.adgear.com/api
|
19
|
+
# user: your_real_login
|
20
|
+
# password: your_real_digest_password
|
21
|
+
# logger: path/to/log/file.log
|
22
|
+
#
|
23
|
+
# @example Reading this sample file:
|
24
|
+
# AdGear.config = AdGear::Config.new("path/to/config/file", "development")
|
25
|
+
#
|
26
|
+
# @example Reading from +config/initializers/ad_gear.rb+ in a Rails environment
|
27
|
+
# AdGear.config = AdGear::Config.new(Rails.root + "config/ad_gear.yml", Rails.env)
|
28
|
+
#
|
29
|
+
# @param obj [#read, Hash, String] When the object responds to #read, reads in the IO-like
|
30
|
+
# object and parses it as a YAML stream. If the object is a
|
31
|
+
# Hash, use it as-is. Else, treat the object as the path to a
|
32
|
+
# YAML file containing the configuration.
|
33
|
+
# @param environment [String, Symbol, nil] If this is +nil+, then do no environment unpacking, else
|
34
|
+
# find the environment that matches this string. If none
|
35
|
+
# matches, a MissingEnvironmentSpecification exception will
|
36
|
+
# be raised.
|
37
|
+
#
|
38
|
+
# @raise MissingEnvironmentSpecification When the +environment+ parameter specifies a missing environment declaration.
|
39
|
+
def initialize(obj, environment=nil)
|
40
|
+
@config = Hash.new
|
41
|
+
@logger = nil
|
42
|
+
|
43
|
+
config = if obj.kind_of?(Hash) then
|
44
|
+
obj
|
45
|
+
elsif obj.respond_to?(:read) then
|
46
|
+
YAML.load(obj.read)
|
47
|
+
else
|
48
|
+
YAML.load_file(obj)
|
49
|
+
end
|
50
|
+
if environment then
|
51
|
+
raise MissingEnvironmentSpecification, "Could not find #{environment.to_s.inspect} in #{config.inspect} read from #{obj.inspect}. Add the missing environment declaration, or change the parameter to this method." unless config.respond_to?(:has_key?) && config.has_key?(environment.to_s)
|
52
|
+
config = config[environment.to_s]
|
53
|
+
end
|
54
|
+
|
55
|
+
config.each_pair do |key, value|
|
56
|
+
send("#{key}=", value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns a Hash of the currect configuration.
|
61
|
+
def to_hash
|
62
|
+
@config.dup
|
63
|
+
end
|
64
|
+
|
65
|
+
def site=(value)
|
66
|
+
@config["site"] = value
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the configured site, which is the root of the API.
|
70
|
+
def site
|
71
|
+
@config["site"]
|
72
|
+
end
|
73
|
+
|
74
|
+
def user=(value)
|
75
|
+
@config["user"] = value
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the configured username / login.
|
79
|
+
def user
|
80
|
+
@config["user"]
|
81
|
+
end
|
82
|
+
|
83
|
+
def password=(value)
|
84
|
+
@config["password"] = value
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns the configured password.
|
88
|
+
def password
|
89
|
+
@config["password"]
|
90
|
+
end
|
91
|
+
|
92
|
+
# Denies or allows using Basic authentication method. This will have an effect only if you are using http://github.com/francois/rails/ar_basic/activeresource
|
93
|
+
def use_basic_authentication
|
94
|
+
@config["use_basic_authentication"]
|
95
|
+
end
|
96
|
+
|
97
|
+
def use_basic_authentication=(value)
|
98
|
+
@config["use_basic_authentication"] = value
|
99
|
+
end
|
100
|
+
|
101
|
+
# Denies or allows using Digest authentication method. This will have an effect only if you are using http://github.com/francois/rails/ar_digest/activeresource
|
102
|
+
def use_digest_authentication
|
103
|
+
@config["use_digest_authentication"]
|
104
|
+
end
|
105
|
+
|
106
|
+
def use_digest_authentication=(value)
|
107
|
+
@config["use_digest_authentication"] = value
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns a format object suitable for use by ActiveResource.
|
111
|
+
def format
|
112
|
+
AdGear::XmlFormat
|
113
|
+
end
|
114
|
+
|
115
|
+
# Returns the Logger instance that was configured in #logger=.
|
116
|
+
def logger
|
117
|
+
@logger
|
118
|
+
end
|
119
|
+
|
120
|
+
# Register a Logger for use by AdGear's client.
|
121
|
+
# @param value [nil, String] When nil, no Logger is assigned.
|
122
|
+
# When the values STDERR or STDOUT are used, logs to the specified stream.
|
123
|
+
# Else, it is taken as the path to a log file.
|
124
|
+
def logger=(value)
|
125
|
+
@config["logger"] = value
|
126
|
+
@logger = case value
|
127
|
+
when nil, ""
|
128
|
+
# No logger
|
129
|
+
nil
|
130
|
+
when /^std(err|out)$/i
|
131
|
+
# Existing stream
|
132
|
+
Logger.new(Object.const_get(value.upcase))
|
133
|
+
else
|
134
|
+
# Path to a file
|
135
|
+
Logger.new(value)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/lib/ad_gear/file.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
module AdGear
|
2
|
+
class HasManyArray
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(name, saved=nil)
|
6
|
+
@name = name.to_s.singularize.dasherize + "-attributes"
|
7
|
+
@new = []
|
8
|
+
@saved = []
|
9
|
+
saved.each do |obj|
|
10
|
+
self << obj
|
11
|
+
end if saved
|
12
|
+
end
|
13
|
+
|
14
|
+
def <<(object)
|
15
|
+
is_new = object.respond_to?(:new_record?) && object.new_record?
|
16
|
+
root = is_new ? @new : @saved
|
17
|
+
root << object
|
18
|
+
end
|
19
|
+
|
20
|
+
def each(&block)
|
21
|
+
@saved.each(&block)
|
22
|
+
@new.each(&block)
|
23
|
+
end
|
24
|
+
|
25
|
+
def length
|
26
|
+
@saved.length + @new.length
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :size, :length
|
30
|
+
|
31
|
+
def to_xml(options={})
|
32
|
+
xml = options[:builder] || Builder::XmlMarkup.new
|
33
|
+
xml.__send__(@name) do
|
34
|
+
unless @new.empty?
|
35
|
+
xml.tag!(:new) do
|
36
|
+
@new.each_with_index do |obj, index|
|
37
|
+
obj.to_xml(options.merge(:root => "n" << index.to_s))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
unless @saved.empty?
|
43
|
+
@saved.each do |obj|
|
44
|
+
obj.to_xml(options.merge(:root => "n" << obj.id.to_s))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/ad_gear/site.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
begin
|
2
|
+
gem "francois-rest-client", ">= 1.1.5"
|
3
|
+
rescue
|
4
|
+
# Ignored. We hope we got what we wanted
|
5
|
+
warn "Could not ensure francois-rest-client 1.1.5 is loaded. If you have problems uploading files, make sure you have that gem install and that the AdGear::Client uses that version."
|
6
|
+
end
|
7
|
+
require "restclient"
|
8
|
+
|
9
|
+
module AdGear
|
10
|
+
class Upload < AdGear::Base
|
11
|
+
def save
|
12
|
+
retried = false
|
13
|
+
headers = Hash.new
|
14
|
+
begin
|
15
|
+
uri = self.class.site.merge(URI.parse(self.class.collection_path))
|
16
|
+
params = {"upload[uploaded_data]" => ::File.new(attributes["filename"]), "upload[filename]" => ::File.basename(attributes["filename"])}
|
17
|
+
out = RestClient.post(uri.to_s, params, headers)
|
18
|
+
logger.debug out if logger
|
19
|
+
load(connection.format.decode(out))
|
20
|
+
rescue RestClient::Unauthorized => e
|
21
|
+
# Retry once only
|
22
|
+
raise if retried
|
23
|
+
|
24
|
+
www_authenticate = e.response["www-authenticate"]
|
25
|
+
header = ActiveResource::Digest.authenticate(uri, self.class.user, self.class.password, www_authenticate, :post)
|
26
|
+
headers["Authorization"] = header
|
27
|
+
|
28
|
+
retried = true
|
29
|
+
retry
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_attribute(*args)
|
34
|
+
raise_unsupported_operation
|
35
|
+
end
|
36
|
+
|
37
|
+
def update_attributes(*args)
|
38
|
+
raise_unsupported_operation
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
def raise_unsupported_operation
|
43
|
+
raise UnsupportedOperation, "Unsupported operation: uploads are write-once only"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'active_support/core_ext/hash/conversions'
|
2
|
+
|
3
|
+
module AdGear
|
4
|
+
# Copied from ActiveResource's +active_resource/formats/xml_format.rb+. Changed +mime_type+ to return AdGear's expected mime type.
|
5
|
+
module XmlFormat
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def extension
|
9
|
+
"agml"
|
10
|
+
end
|
11
|
+
|
12
|
+
def mime_type
|
13
|
+
"application/vnd.bloom.adgear.v1+xml"
|
14
|
+
end
|
15
|
+
|
16
|
+
def encode(hash, options={})
|
17
|
+
hash.to_xml(options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def decode(xml)
|
21
|
+
from_xml_data(Hash.from_xml(xml))
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
# Manipulate from_xml Hash, because xml_simple is not exactly what we
|
26
|
+
# want for Active Resource.
|
27
|
+
def from_xml_data(data)
|
28
|
+
if data.is_a?(Hash) && data.keys.size == 1
|
29
|
+
data.values.first
|
30
|
+
else
|
31
|
+
data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/ad_gear.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009 François Beausoleil
|
3
|
+
# Copyright (c) 2009 Bloom Digital Platforms
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
#++
|
24
|
+
|
25
|
+
require "active_support"
|
26
|
+
require "active_resource"
|
27
|
+
require "logger"
|
28
|
+
|
29
|
+
warn "You are using the plain jane version of ActiveResource. You could use Digest authentication if you used http://github.com/francois/rails/tree/ar_digest" unless ActiveResource::Base.respond_to?(:use_basic_authentication)
|
30
|
+
|
31
|
+
module AdGear
|
32
|
+
# AdGear's models superclass
|
33
|
+
autoload :Base, "ad_gear/base"
|
34
|
+
|
35
|
+
# AdGear models themselves
|
36
|
+
autoload :Site, "ad_gear/site"
|
37
|
+
autoload :AdSpot, "ad_gear/ad_spot"
|
38
|
+
autoload :Campaign, "ad_gear/campaign"
|
39
|
+
autoload :Format, "ad_gear/format"
|
40
|
+
autoload :Upload, "ad_gear/upload"
|
41
|
+
|
42
|
+
# AdUnits and it's child models
|
43
|
+
autoload :AdUnit, "ad_gear/ad_unit"
|
44
|
+
autoload :AdUnitFile, "ad_gear/ad_unit_file"
|
45
|
+
autoload :AdUnitInteraction, "ad_gear/ad_unit_interaction"
|
46
|
+
autoload :AdUnitClick, "ad_gear/ad_unit_click"
|
47
|
+
autoload :AdUnitVariable, "ad_gear/ad_unit_variable"
|
48
|
+
|
49
|
+
# Templates and their dependencies, to know what child models are required
|
50
|
+
autoload :Template, "ad_gear/template"
|
51
|
+
autoload :File, "ad_gear/file"
|
52
|
+
autoload :Variable, "ad_gear/variable"
|
53
|
+
autoload :Click, "ad_gear/click"
|
54
|
+
autoload :Interaction, "ad_gear/interaction"
|
55
|
+
|
56
|
+
# Miscellaneous stuff
|
57
|
+
autoload :Config, "ad_gear/config"
|
58
|
+
autoload :XmlFormat, "ad_gear/xml_format"
|
59
|
+
autoload :HasManyArray, "ad_gear/has_many_array"
|
60
|
+
|
61
|
+
class UnsupportedOperation < RuntimeError; end
|
62
|
+
|
63
|
+
# Configures AdGear's ActiveResource models.
|
64
|
+
#
|
65
|
+
# NOTE: AdGear's client expects and uses Nokogiri instead of REXML.
|
66
|
+
# See http://rubyglasses.blogspot.com/2009/07/40-speedup-using-nokogiri.html#instructions
|
67
|
+
def self.config=(config)
|
68
|
+
@config = config
|
69
|
+
|
70
|
+
AdGear::Base.logger = config.logger
|
71
|
+
|
72
|
+
AdGear::Base.site = config.site
|
73
|
+
AdGear::Base.user = config.user
|
74
|
+
AdGear::Base.password = config.password
|
75
|
+
AdGear::Base.format = config.format
|
76
|
+
|
77
|
+
if AdGear::Base.respond_to?(:use_basic_authentication=)
|
78
|
+
AdGear::Base.use_basic_authentication = config.use_basic_authentication
|
79
|
+
end
|
80
|
+
|
81
|
+
if AdGear::Base.respond_to?(:use_digest_authentication=)
|
82
|
+
AdGear::Base.use_digest_authentication = config.use_digest_authentication
|
83
|
+
end
|
84
|
+
|
85
|
+
ActiveSupport::XmlMini.backend = "Nokogiri"
|
86
|
+
|
87
|
+
require "core_ext"
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.config
|
91
|
+
config
|
92
|
+
end
|
93
|
+
end
|
data/lib/core_ext.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#
|
2
|
+
# ActiveSupport's Array#to_xml will build an XML with root set to the full class name including
|
3
|
+
# module(s) it may be nested in - we don't want that, we want it to be *just* the class name,
|
4
|
+
# make it so with this monkey patch...
|
5
|
+
#
|
6
|
+
# Note this is loaded last from AdGear.config= after ActiveSupport has already been loaded. We
|
7
|
+
# cannot simply override because ActiveSupport does lazy loading.
|
8
|
+
#
|
9
|
+
class Array
|
10
|
+
def to_xml_with_module_prefixing(options = {})
|
11
|
+
raise "Not all elements respond to to_xml" unless all? { |e| e.respond_to? :to_xml }
|
12
|
+
root = all? { |e| e.is_a?(first.class) && first.class.to_s != "Hash" } ?
|
13
|
+
ActiveSupport::Inflector.pluralize(ActiveSupport::Inflector.underscore(first.class.to_s.split("::").last)) : "records"
|
14
|
+
to_xml_without_module_prefixing({ :root => root }.merge(options))
|
15
|
+
end
|
16
|
+
|
17
|
+
alias_method_chain :to_xml, :module_prefixing
|
18
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "ostruct"
|
3
|
+
|
4
|
+
class AdGear::AdSpotTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
AdGear.config = OpenStruct.new(:site => "http://test.host", :format => :xml)
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
AdGear::Base.site = nil
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_embed_code_should_not_be_encoded
|
16
|
+
spot = AdGear::AdSpot.new(:id => 84, :name => "XLsuite", :format_id => 42, :embed_code => "some code")
|
17
|
+
|
18
|
+
doc = Nokogiri::XML(spot.encode)
|
19
|
+
xpath doc, "/ad-spot/embed-code" do |ns|
|
20
|
+
assert ns.empty?, doc
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_setting_format_sets_format_id_internally
|
25
|
+
format = stub("AdGear::Format", :id => 231)
|
26
|
+
|
27
|
+
spot = AdGear::AdSpot.new
|
28
|
+
spot.format = format
|
29
|
+
assert_equal 231, spot.attributes["format_id"], spot.attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_instantiating_with_format_sets_format_id_internally
|
33
|
+
format = stub("AdGear::Format", :id => 231)
|
34
|
+
spot = AdGear::AdSpot.new(:format => format)
|
35
|
+
assert_equal 231, spot.attributes["format_id"], spot.attributes
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_setting_format_to_nil_sets_format_id_to_nil
|
39
|
+
spot = AdGear::AdSpot.new
|
40
|
+
spot.format = nil
|
41
|
+
assert_nil spot.attributes["format_id"]
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "tempfile"
|
3
|
+
require "stringio"
|
4
|
+
|
5
|
+
class AdGear::ConfigTest < Test::Unit::TestCase
|
6
|
+
should "read a file on disk when given a path" do
|
7
|
+
econf = {"site" => "http://whatever.com/", "user" => "francois", "password" => "many"}
|
8
|
+
Tempfile.open("config") do |io|
|
9
|
+
io.write econf.to_yaml
|
10
|
+
io.close
|
11
|
+
|
12
|
+
aconf = AdGear::Config.new(io.path)
|
13
|
+
assert_equal econf, aconf.to_hash
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
should "read a stream" do
|
18
|
+
econf = {"site" => "http://whatever.com/", "user" => "francois", "password" => "many"}
|
19
|
+
Tempfile.open("config") do |io|
|
20
|
+
io.write econf.to_yaml
|
21
|
+
io.rewind
|
22
|
+
|
23
|
+
aconf = AdGear::Config.new(io)
|
24
|
+
assert_equal econf, aconf.to_hash
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
should "read the specified env" do
|
29
|
+
econf = {"site" => "http://whatever.com/", "user" => "francois", "password" => "many"}
|
30
|
+
env = {"development" => econf}
|
31
|
+
aconf = AdGear::Config.new(StringIO.new(env.to_yaml), "development")
|
32
|
+
assert_equal econf, aconf.to_hash
|
33
|
+
end
|
34
|
+
|
35
|
+
should "raise a MissingEnvironmentSpecification when the file is empty" do
|
36
|
+
assert_raise AdGear::Config::MissingEnvironmentSpecification do
|
37
|
+
AdGear::Config.new(StringIO.new(""), "development")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
should "raise a MissingEnvironmentSpecification when the env doesn't exist" do
|
42
|
+
econf = {"site" => "http://whatever.com/", "user" => "francois", "password" => "many"}
|
43
|
+
env = {"development" => econf}
|
44
|
+
|
45
|
+
assert_raise AdGear::Config::MissingEnvironmentSpecification do
|
46
|
+
AdGear::Config.new(StringIO.new(env.to_yaml), "test")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
should "instantiate a Logger for STDOUT when the logger key is 'stdout'" do
|
51
|
+
Logger.expects(:new).with(STDOUT).returns(mock("Logger"))
|
52
|
+
AdGear::Config.new(StringIO.new({"logger" => "stdout"}.to_yaml))
|
53
|
+
end
|
54
|
+
|
55
|
+
should "instantiate a Logger for STDERR when the logger key is 'stderr'" do
|
56
|
+
Logger.expects(:new).with(STDERR).returns(mock("Logger"))
|
57
|
+
AdGear::Config.new("logger" => "stderr")
|
58
|
+
end
|
59
|
+
|
60
|
+
should "instantiate a Logger for the file named 'log/adgear.log' when the key is 'log/adgear.log'" do
|
61
|
+
Logger.expects(:new).with("log/adgear.log").returns(mock("Logger"))
|
62
|
+
AdGear::Config.new(StringIO.new({"logger" => "log/adgear.log"}.to_yaml))
|
63
|
+
end
|
64
|
+
|
65
|
+
context "Given a configured AdGear::Config" do
|
66
|
+
setup do
|
67
|
+
conf = {"site" => "http://whatever.com/", "user" => "francois", "password" => "many", "use_basic_authentication" => false, "use_digest_authentication" => true}
|
68
|
+
@config = AdGear::Config.new(conf)
|
69
|
+
end
|
70
|
+
|
71
|
+
should "return the correct site from #site" do
|
72
|
+
assert_equal "http://whatever.com/", @config.site
|
73
|
+
end
|
74
|
+
|
75
|
+
should "return the correct user from #user" do
|
76
|
+
assert_equal "francois", @config.user
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return the correct password from #password" do
|
80
|
+
assert_equal "many", @config.password
|
81
|
+
end
|
82
|
+
|
83
|
+
should "return the correct use_basic_authentication from #use_basic_authentication" do
|
84
|
+
assert_equal false, @config.use_basic_authentication
|
85
|
+
end
|
86
|
+
|
87
|
+
should "return the correct use_digest_authentication from #use_digest_authentication" do
|
88
|
+
assert_equal true, @config.use_digest_authentication
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "ostruct"
|
3
|
+
|
4
|
+
class AdGear::SiteTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
super
|
7
|
+
AdGear.config = OpenStruct.new(:site => "http://test.host", :format => :xml)
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
AdGear::Base.site = nil
|
12
|
+
super
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_adding_an_ad_spot_puts_it_in_the_new_collection
|
16
|
+
site = AdGear::Site.new(:name => "XLsuite", :url => "http://xlsuite.com/", :publisher_id => 1)
|
17
|
+
site.ad_spots << AdGear::AdSpot.new(:format_id => 13, :name => "sidebar top")
|
18
|
+
|
19
|
+
doc = Nokogiri::XML(site.to_xml)
|
20
|
+
xpath doc, "/site/ad-spot-attributes/new/*/name" do |ns|
|
21
|
+
assert_equal 1, ns.length, doc
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_adding_an_existing_ad_spot_puts_it_in_the_old_collection
|
26
|
+
site = AdGear::Site.new(:name => "XLsuite", :url => "http://xlsuite.com/", :publisher_id => 1)
|
27
|
+
FakeWeb.register_uri(:get, "http://test.host/ad_spots/42.xml", :body => "<ad-spot><id>42</id><name>bla</name></ad-spot>")
|
28
|
+
site.ad_spots << AdGear::AdSpot.find(42)
|
29
|
+
|
30
|
+
doc = Nokogiri::XML(site.to_xml)
|
31
|
+
xpath doc, "/site/ad-spot-attributes/n42/name" do |ns|
|
32
|
+
assert_equal 1, ns.length, doc
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_instantiating_with_ad_spots_still_generates_ad_spots_in_the_new_collection
|
37
|
+
site = AdGear::Site.new(:name => "XLsuite",
|
38
|
+
:url => "http://xlsuite.com/",
|
39
|
+
:publisher_id => 1,
|
40
|
+
:ad_spots => [{:format_id => 13, :name => "sidebar top"}])
|
41
|
+
|
42
|
+
doc = Nokogiri::XML(site.to_xml)
|
43
|
+
xpath doc, "/site/ad-spot-attributes/new/*/name" do |ns|
|
44
|
+
assert_equal 1, ns.length, doc
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_adding_a_new_ad_spot_to_existing_ad_spots_adds_to_new_collection
|
49
|
+
site = AdGear::Site.new(:name => "XLsuite",
|
50
|
+
:url => "http://xlsuite.com/",
|
51
|
+
:publisher_id => 1,
|
52
|
+
:ad_spots => [{:format_id => 13, :name => "sidebar top"}])
|
53
|
+
site.ad_spots << AdGear::AdSpot.new(:format_id => 13, :name => "homepage bottom")
|
54
|
+
|
55
|
+
doc = Nokogiri::XML(site.to_xml)
|
56
|
+
xpath doc, "/site/ad-spot-attributes/new/*/name" do |ns|
|
57
|
+
assert_equal 2, ns.length, doc
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_embed_code_should_not_be_encoded
|
62
|
+
site = AdGear::Site.new(:id => 84, :name => "XLsuite", :url => "http://xlsuite.com/", :embed_code => "some code")
|
63
|
+
|
64
|
+
doc = Nokogiri::XML(site.encode)
|
65
|
+
xpath doc, "/site/embed-code" do |ns|
|
66
|
+
assert ns.empty?, doc
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class AdGear::UploadTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
super
|
6
|
+
AdGear.config = OpenStruct.new(:site => "http://test.host/api", :format => :xml)
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
AdGear::Base.site = nil
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
should "upload the data using RestClient" do
|
15
|
+
xml = Builder::XmlMarkup.new
|
16
|
+
xml.upload do
|
17
|
+
xml.id 42
|
18
|
+
end
|
19
|
+
|
20
|
+
RestClient.expects(:post).with(responds_with(:to_s, URI.parse("http://test.host/api/uploads.xml").to_s), has_entry(:upload, has_entry(:uploaded_data, kind_of(File))), kind_of(Hash)).returns(xml.target!)
|
21
|
+
upload = AdGear::Upload.new(:filename => "test/fixtures/access-denied-no-auth.txt")
|
22
|
+
upload.save
|
23
|
+
assert_equal 42, upload.id.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
should "raise an exception when calling #update_attribute" do
|
27
|
+
assert_raise(AdGear::UnsupportedOperation) do
|
28
|
+
AdGear::Upload.new.update_attribute
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
should "raise an exception when calling #update_attributes" do
|
33
|
+
assert_raise(AdGear::UnsupportedOperation) do
|
34
|
+
AdGear::Upload.new.update_attributes
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|