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.
@@ -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
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class File < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Format < AdGear::Base
3
+ end
4
+ end
@@ -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
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Interaction < AdGear::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module AdGear
2
+ class Site < AdGear::Base
3
+ has_many :ad_spots
4
+ ignorable_attributes :embed_code
5
+ end
6
+ end
@@ -0,0 +1,4 @@
1
+ module AdGear
2
+ class Template < AdGear::Base
3
+ end
4
+ end
@@ -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,4 @@
1
+ module AdGear
2
+ class Variable < AdGear::Base
3
+ end
4
+ 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