appdirect 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1c6a0ac2a415fe05554d0afd962ad67aa26de0d7
4
+ data.tar.gz: 8693ff887bccd8d4513b3da2cb58c26aac3224d7
5
+ SHA512:
6
+ metadata.gz: b2c999cff3cf4658c0316bb5cbc543418b3f30b4d58cd1be8c8eb68c9fd7af8350ffa281d6ab5e4e3de98cbb0fff25c0a720e6da03d269fcb43b011afcbeb133
7
+ data.tar.gz: 25f764ff894a03c03a13e233181cb889ee9ac720af6ddf7b72f7009ff78b5004a2807bf2bf7f27eb96b7ab28c601d845095e9d92eab7148e77422d8b67475f66
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in appdirect.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Tim Williams
2
+
3
+ MIT License
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.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # AppDirect
2
+
3
+ Ruby bindings for the AppDirect Vendor API. Provides oauth signed retrieval of AppDirect events. Intended for use with the [AppDirect Subscription API](http://info.appdirect.com/developers/docs/api_integration/subscription_management)
4
+
5
+ Please note this is NOT an offical library and is not endorsed or supported by AppDirect.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'appdirect'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install appdirect
20
+
21
+ ## Usage
22
+
23
+ ### Configuration
24
+ The AppDirect API requires your own OAuth 1.0 Consumer Key and Secret. This is used to sign all get requests to the AppDirect REST API.
25
+
26
+ #config/initializers/appdirect.rb
27
+ AppDirect.consumer_key = "Dummy"
28
+ AppDirect.secret = "secret"
29
+
30
+ ### Retrieving an event
31
+ Subscription Management is intiated by a call from AppDirect to your defined callback urls. Part of this callback will include a URL parameter storing the URL for the event that you need to respond to.
32
+
33
+ For example you may have defined a callback URL as follows in your AppDirect integration settings
34
+
35
+ ``https://example.com/create?url={eventUrl}``
36
+
37
+ Once you have retrieved the URL you can retrieve the Event:
38
+
39
+ url = "https://www.appdirect.com/rest/api/events/dummyOrder" # <-- this should be the url from the callback
40
+ event = AppDirect::Event.retrieve(url)
41
+
42
+ #Inspect the event
43
+ if event.type == "SUBSCRIPTION_CANCEL"
44
+ puts "Bad news, somebody just cancelled!"
45
+ end
46
+
47
+ ### Event data structure
48
+ As part of the retrieval the XML representation of the event is converted to a Ruby object, exposing the child elements of the ``<event>`` tag as methods on the event object.
49
+
50
+ In this SUBSCRIPTION_NOTICE XML example:
51
+
52
+ <event>
53
+ <flag>STATELESS</flag>
54
+ <marketplace>
55
+ <baseUrl>https://acme.appdirect.com</baseUrl>
56
+ <partner>ACME</partner>
57
+ </marketplace>
58
+ <payload>
59
+ <account>
60
+ <accountIdentifier>dummy-account</accountIdentifier>
61
+ <status>SUSPENDED</status>
62
+ </account>
63
+ <configuration/>
64
+ <notice>
65
+ <type>DEACTIVATED</type>
66
+ </notice>
67
+ </payload>
68
+ <type>SUBSCRIPTION_NOTICE</type>
69
+ </event>
70
+
71
+ You can access the information as follows:
72
+
73
+ event = AppDirect::Event.retrieve(url)
74
+ event.flag # STATELESS
75
+ event.payload.account.status # SUSPENDED
76
+ event.type # SUBSCRIPTION_NOTICE
77
+
78
+ ## Contributing
79
+
80
+ 1. Fork it ( https://github.com/timrwilliams/appdirect/fork )
81
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
82
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
83
+ 4. Push to the branch (`git push origin my-new-feature`)
84
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/appdirect.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'appdirect/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "appdirect"
8
+ spec.version = AppDirect::VERSION
9
+ spec.authors = ["Tim Williams"]
10
+ spec.email = ["tim@teachmatic.com"]
11
+ spec.summary = %q{Ruby wrapper for AppDirect API}
12
+ spec.description = %q{Basic ruby wrapper for the AppDirect Vendor API. Handles event retrieval and parsing XML in to Ruby object.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "minitest", "~> 5.4"
23
+ spec.add_development_dependency "vcr", '~> 2.9'
24
+ spec.add_development_dependency "webmock",'~> 1.20'
25
+ spec.add_development_dependency "rake"
26
+
27
+ spec.add_dependency 'oauth', '~> 0.4'
28
+ spec.add_dependency 'nori', '~> 2.4'
29
+ end
@@ -0,0 +1,193 @@
1
+ module AppDirect
2
+ class AppDirectObject
3
+ include Enumerable
4
+
5
+ attr_accessor :consumer_key, :secret
6
+ @@permanent_attributes = Set.new([:consumer_key, :secret, :id])
7
+
8
+ # The default :id method is deprecated and isn't useful to us
9
+ if method_defined?(:id)
10
+ undef :id
11
+ end
12
+
13
+ def initialize(id=nil, consumer_key=nil, secret=nil)
14
+
15
+ # parameter overloading!
16
+ if id.kind_of?(Hash)
17
+ @retrieve_options = id.dup
18
+ @retrieve_options.delete(:id)
19
+ id = id[:id]
20
+ else
21
+ @retrieve_options = {}
22
+ end
23
+
24
+ @consumer_key = consumer_key
25
+ @secret = secret
26
+ @values = {}
27
+ # This really belongs in APIResource, but not putting it there allows us
28
+ # to have a unified inspect method
29
+ @unsaved_values = Set.new
30
+ @transient_values = Set.new
31
+ @values[:id] = id if id
32
+ end
33
+
34
+ def self.construct_from(values, consumer_key=nil, secret=nil)
35
+ obj = self.new(values[:id], consumer_key, secret)
36
+ obj.refresh_from(values, consumer_key, secret)
37
+ obj
38
+ end
39
+
40
+ def to_s(*args)
41
+ JSON.pretty_generate(@values)
42
+ end
43
+
44
+ def inspect()
45
+ id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
46
+ "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> JSON: " + JSON.pretty_generate(@values)
47
+ end
48
+
49
+ def refresh_from(values, consumer_key, secret, partial=false)
50
+ @consumer_key = consumer_key
51
+ @secret = secret
52
+
53
+ @previous_metadata = values[:metadata]
54
+ removed = partial ? Set.new : Set.new(@values.keys - values.keys)
55
+ added = Set.new(values.keys - @values.keys)
56
+ # Wipe old state before setting new. This is useful for e.g. updating a
57
+ # customer, where there is no persistent card parameter. Mark those values
58
+ # which don't persist as transient
59
+
60
+ instance_eval do
61
+ remove_accessors(removed)
62
+ add_accessors(added)
63
+ end
64
+ removed.each do |k|
65
+ @values.delete(k)
66
+ @transient_values.add(k)
67
+ @unsaved_values.delete(k)
68
+ end
69
+ values.each do |k, v|
70
+ @values[k] = Util.convert_to_appdirect_object(v, consumer_key, secret)
71
+ @transient_values.delete(k)
72
+ @unsaved_values.delete(k)
73
+ end
74
+ end
75
+
76
+ def [](k)
77
+ @values[k.to_sym]
78
+ end
79
+
80
+ def []=(k, v)
81
+ send(:"#{k}=", v)
82
+ end
83
+
84
+ def keys
85
+ @values.keys
86
+ end
87
+
88
+ def values
89
+ @values.values
90
+ end
91
+
92
+ def to_json(*a)
93
+ JSON.generate(@values)
94
+ end
95
+
96
+ def as_json(*a)
97
+ @values.as_json(*a)
98
+ end
99
+
100
+ def to_hash
101
+ @values.inject({}) do |acc, (key, value)|
102
+ acc[key] = value.respond_to?(:to_hash) ? value.to_hash : value
103
+ acc
104
+ end
105
+ end
106
+
107
+ def each(&blk)
108
+ @values.each(&blk)
109
+ end
110
+
111
+ def _dump(level)
112
+ Marshal.dump([@values, @consumer_key, @secret])
113
+ end
114
+
115
+ def self._load(args)
116
+ values, api_key = Marshal.load(args)
117
+ construct_from(values, consumer_key, secret)
118
+ end
119
+
120
+ if RUBY_VERSION < '1.9.2'
121
+ def respond_to?(symbol)
122
+ @values.has_key?(symbol) || super
123
+ end
124
+ end
125
+
126
+ protected
127
+
128
+ def metaclass
129
+ class << self; self; end
130
+ end
131
+
132
+ def remove_accessors(keys)
133
+ metaclass.instance_eval do
134
+ keys.each do |k|
135
+ next if @@permanent_attributes.include?(k)
136
+ k_eq = :"#{k}="
137
+ remove_method(k) if method_defined?(k)
138
+ remove_method(k_eq) if method_defined?(k_eq)
139
+ end
140
+ end
141
+ end
142
+
143
+ def add_accessors(keys)
144
+ metaclass.instance_eval do
145
+ keys.each do |k|
146
+ next if @@permanent_attributes.include?(k)
147
+ k_eq = :"#{k}="
148
+ define_method(k) { @values[k] }
149
+ define_method(k_eq) do |v|
150
+ if v == ""
151
+ raise ArgumentError.new(
152
+ "You cannot set #{k} to an empty string." +
153
+ "We interpret empty strings as nil in requests." +
154
+ "You may set #{self}.#{k} = nil to delete the property.")
155
+ end
156
+ @values[k] = v
157
+ @unsaved_values.add(k)
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ def method_missing(name, *args)
164
+ # TODO: only allow setting in updateable classes.
165
+ if name.to_s.end_with?('=')
166
+ attr = name.to_s[0...-1].to_sym
167
+ add_accessors([attr])
168
+ begin
169
+ mth = method(name)
170
+ rescue NameError
171
+ raise NoMethodError.new("Cannot set #{attr} on this object. HINT: you can't set: #{@@permanent_attributes.to_a.join(', ')}")
172
+ end
173
+ return mth.call(args[0])
174
+ else
175
+ return @values[name] if @values.has_key?(name)
176
+ end
177
+
178
+ begin
179
+ super
180
+ rescue NoMethodError => e
181
+ if @transient_values.include?(name)
182
+ raise NoMethodError.new(e.message + ". HINT: The '#{name}' attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by AppDirect's API, probably as a result of a save(). The attributes currently available on this object are: #{@values.keys.join(', ')}")
183
+ else
184
+ raise
185
+ end
186
+ end
187
+ end
188
+
189
+ def respond_to_missing?(symbol, include_private = false)
190
+ @values && @values.has_key?(symbol) || super
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,20 @@
1
+ module AppDirect
2
+ class AppDirectError < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+ attr_reader :http_body
6
+ attr_reader :json_body
7
+
8
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
9
+ @message = message
10
+ @http_status = http_status
11
+ @http_body = http_body
12
+ @json_body = json_body
13
+ end
14
+
15
+ def to_s
16
+ status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
17
+ "#{status_string}#{@message}"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,4 @@
1
+ module AppDirect
2
+ class AuthenticationError < AppDirectError
3
+ end
4
+ end
@@ -0,0 +1,15 @@
1
+ module AppDirect
2
+ class Event < AppDirectObject
3
+
4
+ def refresh
5
+ response, consumer_key, secret = AppDirect.signed_get(@values[:id], @consumer_key, @secret, @retrieve_options)
6
+ refresh_from(response[:event], consumer_key, secret)
7
+ end
8
+
9
+ def self.retrieve(url, consumer_key=nil, secret=nil)
10
+ instance = self.new(url, consumer_key, secret)
11
+ instance.refresh
12
+ instance
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ module AppDirect
2
+ module Util
3
+
4
+ def self.object_classes
5
+ @object_classes ||= {
6
+ :event => Event
7
+ }
8
+ end
9
+
10
+ def self.symbolize_names(object)
11
+ case object
12
+ when Hash
13
+ new = {}
14
+ object.each do |key, value|
15
+ key = (key.to_sym rescue key) || key
16
+ new[key] = symbolize_names(value)
17
+ end
18
+ new
19
+ when Array
20
+ object.map { |value| symbolize_names(value) }
21
+ else
22
+ object
23
+ end
24
+ end
25
+
26
+ def self.convert_to_appdirect_object(resp, consumer_key, secret)
27
+ case resp
28
+ when Array
29
+ resp.map { |i| convert_to_appdirect_object(i, consumer_key, secret) }
30
+ when Hash
31
+ # Try converting to a known object class. If none available, fall back to generic BoffinIOObject
32
+ object_classes.fetch(resp.keys.first, AppDirectObject).construct_from(resp, consumer_key, secret)
33
+ else
34
+ resp
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module AppDirect
2
+ VERSION = "0.0.1"
3
+ end
data/lib/appdirect.rb ADDED
@@ -0,0 +1,48 @@
1
+ require "set"
2
+
3
+ require_relative "appdirect/version"
4
+ require_relative "appdirect/util"
5
+ require_relative "appdirect/appdirect_object"
6
+ require_relative "appdirect/event"
7
+
8
+ #Error declarations
9
+ require_relative "appdirect/errors/appdirect_error"
10
+ require_relative "appdirect/errors/authentication_error"
11
+
12
+ require 'oauth'
13
+ require 'nori'
14
+
15
+
16
+ module AppDirect
17
+ class << self
18
+ attr_accessor :consumer_key, :secret
19
+ end
20
+
21
+ def self.signed_get(event_url, consumer_key, secret, params={})
22
+ unless consumer_key ||= @consumer_key
23
+ raise AuthenticationError.new('No Consumer key provided. ' +
24
+ 'Set your Consumer key using "AppDirect.consumer_key = <CONSUMER-KEY>". ' +
25
+ 'You can view your consumer key via the AppDirect Edit Integration page. ')
26
+ end
27
+
28
+ if consumer_key =~ /\s/
29
+ raise AuthenticationError.new('Your Consumer key is invalid, as it contains whitespace')
30
+ end
31
+
32
+ unless secret ||= @secret
33
+ raise AuthenticationError.new('No API Secret provided. ' +
34
+ 'Set your Secret using "AppDirect.secret = <SECRET>". ' +
35
+ 'You can view your secret key via the AppDirect Edit Integration page. ')
36
+ end
37
+
38
+ if secret =~ /\s/
39
+ raise AuthenticationError.new('Your API Secret is invalid, as it contains whitespace')
40
+ end
41
+ consumer = OAuth::Consumer.new(consumer_key, secret)
42
+ access_token = OAuth::AccessToken.new(consumer)
43
+ response = access_token.get(event_url)
44
+ parser = Nori.new
45
+ hash = parser.parse(response.body)
46
+ [Util.symbolize_names(hash),consumer_key, secret]
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ require './test/test_helper'
2
+
3
+ class EventTest < Minitest::Test
4
+ def test_exists
5
+ assert AppDirect::Event
6
+ end
7
+
8
+ def test_it_retrieves_an_order_event
9
+ VCR.use_cassette('dummy_order') do
10
+ event = AppDirect::Event.retrieve("https://www.appdirect.com/rest/api/events/dummyOrder")
11
+ assert_equal "STATELESS",event.flag
12
+ assert_equal "SUBSCRIPTION_ORDER",event.type
13
+ assert_equal "test-email+creator@appdirect.com", event.creator.email
14
+ assert_equal "BASIC", event.payload.order.editionCode
15
+ end
16
+ end
17
+
18
+ def test_it_retrieves_a_change_event
19
+ VCR.use_cassette('dummy_change') do
20
+ event = AppDirect::Event.retrieve("https://www.appdirect.com/rest/api/events/dummyChange")
21
+ assert_equal "STATELESS",event.flag
22
+ assert_equal "SUBSCRIPTION_CHANGE",event.type
23
+ assert_equal "test-email+creator@appdirect.com", event.creator.email
24
+ assert_equal "PREMIUM", event.payload.order.editionCode
25
+ assert_equal "dummy-account", event.payload.account.accountIdentifier
26
+ end
27
+ end
28
+
29
+ def test_it_retrieves_a_cancel_event
30
+ VCR.use_cassette('dummy_cancel') do
31
+ event = AppDirect::Event.retrieve("https://www.appdirect.com/rest/api/events/dummyCancel")
32
+ assert_equal "STATELESS",event.flag
33
+ assert_equal "SUBSCRIPTION_CANCEL",event.type
34
+ assert_equal "test-email+creator@appdirect.com", event.creator.email
35
+ assert_equal "dummy-account", event.payload.account.accountIdentifier
36
+ end
37
+ end
38
+
39
+ def test_it_retrieves_a_notice_event
40
+ VCR.use_cassette('dummy_notice') do
41
+ event = AppDirect::Event.retrieve("https://www.appdirect.com/rest/api/events/dummyNotice")
42
+ assert_equal "STATELESS",event.flag
43
+ assert_equal "SUBSCRIPTION_NOTICE",event.type
44
+ assert_equal "DEACTIVATED", event.payload.notice.type
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.appdirect.com/rest/api/events/dummyCancel
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - OAuth gem v0.4.7
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="statica-16287", oauth_nonce="YEm8lGN4ZmMRLCsjViZxg8b3SjiUTHiCBUYUrAxbFRE",
18
+ oauth_signature="LpMD%2BZI8adU2ysTHe4gVWYr4gEc%3D", oauth_signature_method="HMAC-SHA1",
19
+ oauth_timestamp="1414773354", oauth_version="1.0"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Cache-Control:
26
+ - no-cache, no-store, max-age=0, must-revalidate
27
+ - no-cache="set-cookie"
28
+ - private
29
+ Content-Type:
30
+ - application/xml;charset=UTF-8
31
+ Date:
32
+ - Fri, 31 Oct 2014 16:35:41 GMT
33
+ Expires:
34
+ - '0'
35
+ - Wed, 31 Dec 1969 19:00:00 EST
36
+ Pragma:
37
+ - no-cache
38
+ Server:
39
+ - APPSERVER
40
+ Set-Cookie:
41
+ - AWSELB=9DF3DFDB06E99836F49B4DBC3EB5DEE1BC2F4E2A51DC93894B5743680C134F214C9ED5CD7830863BD5B9D917450CCAC074115D10BF13AB9026347C3B6098744FCE8AD5B33F;PATH=/;MAX-AGE=3600
42
+ - JSESSIONID=5BA1D0BFED13E8D5DFB562BF0C34E620-n1; Path=/; Secure; HttpOnly
43
+ Strict-Transport-Security:
44
+ - max-age=0 ; includeSubDomains
45
+ X-Content-Type-Options:
46
+ - nosniff
47
+ X-Frame-Options:
48
+ - SAMEORIGIN
49
+ X-Xss-Protection:
50
+ - 1; mode=block
51
+ Content-Length:
52
+ - '731'
53
+ Connection:
54
+ - keep-alive
55
+ body:
56
+ encoding: UTF-8
57
+ string: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><event><creator><email>test-email+creator@appdirect.com</email><firstName>DummyCreatorFirst</firstName><language>fr</language><lastName>DummyCreatorLast</lastName><openId>https://www.appdirect.com/openid/id/ec5d8eda-5cec-444d-9e30-125b6e4b67e2</openId><uuid>ec5d8eda-5cec-444d-9e30-125b6e4b67e2</uuid></creator><flag>STATELESS</flag><marketplace><baseUrl>https://acme.appdirect.com</baseUrl><partner>ACME</partner></marketplace><payload><account><accountIdentifier>dummy-account</accountIdentifier><status>ACTIVE</status></account><configuration/></payload><returnUrl>https://www.appdirect.com/finishcancel?token=dummyCancel</returnUrl><type>SUBSCRIPTION_CANCEL</type></event>
58
+ http_version:
59
+ recorded_at: Fri, 31 Oct 2014 16:35:55 GMT
60
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,60 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.appdirect.com/rest/api/events/dummyChange
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - OAuth gem v0.4.7
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="statica-16287", oauth_nonce="r2kLZO3UiSYDNDZXgvfodt5GGz6i3zoaSgiwmt148tU",
18
+ oauth_signature="ZnSGKiCauwR0h%2Bu%2F9wbpwH4veDs%3D", oauth_signature_method="HMAC-SHA1",
19
+ oauth_timestamp="1414773354", oauth_version="1.0"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Cache-Control:
26
+ - no-cache, no-store, max-age=0, must-revalidate
27
+ - no-cache="set-cookie"
28
+ - private
29
+ Content-Type:
30
+ - application/xml;charset=UTF-8
31
+ Date:
32
+ - Fri, 31 Oct 2014 16:35:40 GMT
33
+ Expires:
34
+ - '0'
35
+ - Wed, 31 Dec 1969 19:00:00 EST
36
+ Pragma:
37
+ - no-cache
38
+ Server:
39
+ - APPSERVER
40
+ Set-Cookie:
41
+ - AWSELB=9DF3DFDB06E99836F49B4DBC3EB5DEE1BC2F4E2A51DC93894B5743680C134F214C9ED5CD7830863BD5B9D917450CCAC074115D10BF13AB9026347C3B6098744FCE8AD5B33F;PATH=/;MAX-AGE=3600
42
+ - JSESSIONID=B1A5F585AFDF31D1E124B5DAF76018D0-n1; Path=/; Secure; HttpOnly
43
+ Strict-Transport-Security:
44
+ - max-age=0 ; includeSubDomains
45
+ X-Content-Type-Options:
46
+ - nosniff
47
+ X-Frame-Options:
48
+ - SAMEORIGIN
49
+ X-Xss-Protection:
50
+ - 1; mode=block
51
+ Content-Length:
52
+ - '933'
53
+ Connection:
54
+ - keep-alive
55
+ body:
56
+ encoding: UTF-8
57
+ string: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><event><creator><email>test-email+creator@appdirect.com</email><firstName>DummyCreatorFirst</firstName><language>fr</language><lastName>DummyCreatorLast</lastName><openId>https://www.appdirect.com/openid/id/ec5d8eda-5cec-444d-9e30-125b6e4b67e2</openId><uuid>ec5d8eda-5cec-444d-9e30-125b6e4b67e2</uuid></creator><flag>STATELESS</flag><marketplace><baseUrl>https://acme.appdirect.com</baseUrl><partner>ACME</partner></marketplace><payload><account><accountIdentifier>dummy-account</accountIdentifier><status>ACTIVE</status></account><configuration/><order><editionCode>PREMIUM</editionCode><item><quantity>20</quantity><unit>USER</unit></item><item><quantity>15</quantity><unit>MEGABYTE</unit></item><pricingDuration>MONTHLY</pricingDuration></order></payload><returnUrl>https://www.appdirect.com/finishprocure?token=dummyChange</returnUrl><type>SUBSCRIPTION_CHANGE</type></event>
58
+ http_version:
59
+ recorded_at: Fri, 31 Oct 2014 16:35:54 GMT
60
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,60 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.appdirect.com/rest/api/events/dummyNotice
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - OAuth gem v0.4.7
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="statica-16287", oauth_nonce="WsOv09nHw5TqcnMLSnwGffhIlEN7KXoOX14zp334ho",
18
+ oauth_signature="2HoWoJn1Va0wrH%2Bqytqb%2FHNZ5dA%3D", oauth_signature_method="HMAC-SHA1",
19
+ oauth_timestamp="1414773355", oauth_version="1.0"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Cache-Control:
26
+ - no-cache, no-store, max-age=0, must-revalidate
27
+ - no-cache="set-cookie"
28
+ - private
29
+ Content-Type:
30
+ - application/xml;charset=UTF-8
31
+ Date:
32
+ - Fri, 31 Oct 2014 16:35:41 GMT
33
+ Expires:
34
+ - '0'
35
+ - Wed, 31 Dec 1969 19:00:00 EST
36
+ Pragma:
37
+ - no-cache
38
+ Server:
39
+ - APPSERVER
40
+ Set-Cookie:
41
+ - AWSELB=9DF3DFDB06E99836F49B4DBC3EB5DEE1BC2F4E2A51DC93894B5743680C134F214C9ED5CD7830863BD5B9D917450CCAC074115D10BF13AB9026347C3B6098744FCE8AD5B33F;PATH=/;MAX-AGE=3600
42
+ - JSESSIONID=D73433A6327A1412ED887D792D28FA87-n1; Path=/; Secure; HttpOnly
43
+ Strict-Transport-Security:
44
+ - max-age=0 ; includeSubDomains
45
+ X-Content-Type-Options:
46
+ - nosniff
47
+ X-Frame-Options:
48
+ - SAMEORIGIN
49
+ X-Xss-Protection:
50
+ - 1; mode=block
51
+ Content-Length:
52
+ - '392'
53
+ Connection:
54
+ - keep-alive
55
+ body:
56
+ encoding: UTF-8
57
+ string: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><event><flag>STATELESS</flag><marketplace><baseUrl>https://acme.appdirect.com</baseUrl><partner>ACME</partner></marketplace><payload><account><accountIdentifier>dummy-account</accountIdentifier><status>SUSPENDED</status></account><configuration/><notice><type>DEACTIVATED</type></notice></payload><type>SUBSCRIPTION_NOTICE</type></event>
58
+ http_version:
59
+ recorded_at: Fri, 31 Oct 2014 16:35:55 GMT
60
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,63 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://www.appdirect.com/rest/api/events/dummyOrder
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - OAuth gem v0.4.7
16
+ Authorization:
17
+ - OAuth oauth_consumer_key="statica-16287", oauth_nonce="WpcvHpByfAlbD8Z7SFwFn2yg7WDknEzm4libw8jDeuI",
18
+ oauth_signature="NG4YV5tyrVt6IAifvq2bt%2BwXvHY%3D", oauth_signature_method="HMAC-SHA1",
19
+ oauth_timestamp="1414774026", oauth_version="1.0"
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Cache-Control:
26
+ - no-cache, no-store, max-age=0, must-revalidate
27
+ - no-cache="set-cookie"
28
+ - private
29
+ Content-Type:
30
+ - application/xml;charset=UTF-8
31
+ Date:
32
+ - Fri, 31 Oct 2014 16:47:06 GMT
33
+ Expires:
34
+ - '0'
35
+ - Wed, 31 Dec 1969 19:00:00 EST
36
+ Pragma:
37
+ - no-cache
38
+ Server:
39
+ - APPSERVER
40
+ Set-Cookie:
41
+ - AWSELB=9DF3DFDB06E99836F49B4DBC3EB5DEE1BC2F4E2A51185BCBF9FE9B1556FC26BE90C967D51C7D29762B45076D59BE46F256800BBA3472C60D6240760072A996081A81F83201;PATH=/;MAX-AGE=3600
42
+ - JSESSIONID=17CB0F4248F7ADD1420ACC30AFF69677-n1; Path=/; Secure; HttpOnly
43
+ Strict-Transport-Security:
44
+ - max-age=0 ; includeSubDomains
45
+ Vary:
46
+ - Accept-Encoding
47
+ X-Content-Type-Options:
48
+ - nosniff
49
+ X-Frame-Options:
50
+ - SAMEORIGIN
51
+ X-Xss-Protection:
52
+ - 1; mode=block
53
+ Content-Length:
54
+ - '603'
55
+ Connection:
56
+ - keep-alive
57
+ body:
58
+ encoding: UTF-8
59
+ string: <?xml version="1.0" encoding="UTF-8" standalone="yes"?><event><creator><email>test-email+creator@appdirect.com</email><firstName>DummyCreatorFirst</firstName><language>fr</language><lastName>DummyCreatorLast</lastName><openId>https://www.appdirect.com/openid/id/ec5d8eda-5cec-444d-9e30-125b6e4b67e2</openId><uuid>ec5d8eda-5cec-444d-9e30-125b6e4b67e2</uuid></creator><flag>STATELESS</flag><marketplace><baseUrl>https://acme.appdirect.com</baseUrl><partner>ACME</partner></marketplace><payload><company><country>CA</country><email>company-email@example.com</email><name>Example
60
+ Company Name</name><phoneNumber>415-555-1212</phoneNumber><uuid>d15bb36e-5fb5-11e0-8c3c-00262d2cda03</uuid><website>http://www.example.com</website></company><configuration><entry><key>domain</key><value>mydomain</value></entry></configuration><order><editionCode>BASIC</editionCode><item><quantity>10</quantity><unit>USER</unit></item><item><quantity>15</quantity><unit>MEGABYTE</unit></item><pricingDuration>MONTHLY</pricingDuration></order></payload><returnUrl>https://www.appdirect.com/finishprocure?token=dummyOrder</returnUrl><type>SUBSCRIPTION_ORDER</type></event>
61
+ http_version:
62
+ recorded_at: Fri, 31 Oct 2014 16:47:07 GMT
63
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,15 @@
1
+ #test/test_helper.rb
2
+ require './lib/appdirect'
3
+ require 'minitest/autorun'
4
+ require 'webmock/minitest'
5
+ require 'vcr'
6
+
7
+ VCR.configure do |c|
8
+ c.cassette_library_dir = "test/fixtures"
9
+ c.hook_into :webmock
10
+ end
11
+
12
+ # If you need to record more test responses using VCR you need genuine AppDirect keys
13
+ # You can find them on the Edit Integration page of your AppDirect Product's dashboard.
14
+ AppDirect.consumer_key=ENV["APPDIRECT_KEY"] || "Dummy"
15
+ AppDirect.secret=ENV["APPDIRECT_SECRET"] || "secret"
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: appdirect
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tim Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '5.4'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '5.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: vcr
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: webmock
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.20'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.20'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: oauth
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: nori
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2.4'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2.4'
111
+ description: Basic ruby wrapper for the AppDirect Vendor API. Handles event retrieval
112
+ and parsing XML in to Ruby object.
113
+ email:
114
+ - tim@teachmatic.com
115
+ executables: []
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - Gemfile
121
+ - LICENSE.txt
122
+ - README.md
123
+ - Rakefile
124
+ - appdirect.gemspec
125
+ - lib/appdirect.rb
126
+ - lib/appdirect/appdirect_object.rb
127
+ - lib/appdirect/errors/appdirect_error.rb
128
+ - lib/appdirect/errors/authentication_error.rb
129
+ - lib/appdirect/event.rb
130
+ - lib/appdirect/util.rb
131
+ - lib/appdirect/version.rb
132
+ - test/event/event_test.rb
133
+ - test/fixtures/dummy_cancel.yml
134
+ - test/fixtures/dummy_change.yml
135
+ - test/fixtures/dummy_notice.yml
136
+ - test/fixtures/dummy_order.yml
137
+ - test/test_helper.rb
138
+ homepage: ''
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.2.2
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Ruby wrapper for AppDirect API
162
+ test_files:
163
+ - test/event/event_test.rb
164
+ - test/fixtures/dummy_cancel.yml
165
+ - test/fixtures/dummy_change.yml
166
+ - test/fixtures/dummy_notice.yml
167
+ - test/fixtures/dummy_order.yml
168
+ - test/test_helper.rb