hitfox_coupon_api 0.0.2 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.keep ADDED
File without changes
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
data/Gemfile CHANGED
@@ -9,8 +9,8 @@ group :development do
9
9
  gem 'pry'
10
10
  gem 'pry-doc'
11
11
  gem 'gist'
12
- gem "thoughtbot-shoulda", ">= 0"
13
- gem "bundler", "~> 1.0.0"
12
+ gem "shoulda"
13
+ gem "bundler"
14
14
  gem "jeweler", "~> 1.6.4"
15
15
  gem "rcov", ">= 0"
16
16
  gem 'rr'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.6
@@ -4,21 +4,23 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "hitfox_coupon_api"
8
- s.version = "0.0.2"
7
+ s.name = %q{hitfox_coupon_api}
8
+ s.version = "0.0.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gerrit Riessen"]
12
- s.date = "2011-09-01"
13
- s.description = "Simple JSON interface to the HitFox coupon API"
14
- s.email = "gerrit.riessen@gmail.com"
12
+ s.date = %q{2012-05-02}
13
+ s.description = %q{Simple JSON interface to the HitFox coupon API}
14
+ s.email = %q{gerrit.riessen@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
+ ".keep",
21
22
  ".rvmrc",
23
+ ".travis.yml",
22
24
  "Gemfile",
23
25
  "LICENSE.txt",
24
26
  "README.rdoc",
@@ -27,18 +29,24 @@ Gem::Specification.new do |s|
27
29
  "hitfox_coupon_api.gemspec",
28
30
  "lib/hitfox_coupon_api.rb",
29
31
  "lib/hitfox_coupon_api/application.rb",
32
+ "lib/hitfox_coupon_api/client.rb",
30
33
  "lib/hitfox_coupon_api/configuration.rb",
31
34
  "lib/hitfox_coupon_api/coupon.rb",
35
+ "lib/hitfox_coupon_api/order.rb",
36
+ "lib/hitfox_coupon_api/user.rb",
32
37
  "test/.login.yml.sample",
33
38
  "test/helper.rb",
39
+ "test/test_coupon.rb",
34
40
  "test/test_hitfox_coupon_api.rb",
41
+ "test/test_order.rb",
42
+ "test/test_user.rb",
35
43
  "test_shell"
36
44
  ]
37
- s.homepage = "https://github.com/gorenje/hitfox_coupon_api"
45
+ s.homepage = %q{https://github.com/gorenje/hitfox_coupon_api}
38
46
  s.licenses = ["MIT"]
39
47
  s.require_paths = ["lib"]
40
- s.rubygems_version = "1.8.10"
41
- s.summary = "Simple JSON interface to the HitFox coupon API"
48
+ s.rubygems_version = %q{1.6.2}
49
+ s.summary = %q{Simple JSON interface to the HitFox coupon API}
42
50
 
43
51
  if s.respond_to? :specification_version then
44
52
  s.specification_version = 3
@@ -50,8 +58,8 @@ Gem::Specification.new do |s|
50
58
  s.add_development_dependency(%q<pry>, [">= 0"])
51
59
  s.add_development_dependency(%q<pry-doc>, [">= 0"])
52
60
  s.add_development_dependency(%q<gist>, [">= 0"])
53
- s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
54
- s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
61
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
62
+ s.add_development_dependency(%q<bundler>, [">= 0"])
55
63
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
56
64
  s.add_development_dependency(%q<rcov>, [">= 0"])
57
65
  s.add_development_dependency(%q<rr>, [">= 0"])
@@ -63,8 +71,8 @@ Gem::Specification.new do |s|
63
71
  s.add_dependency(%q<pry>, [">= 0"])
64
72
  s.add_dependency(%q<pry-doc>, [">= 0"])
65
73
  s.add_dependency(%q<gist>, [">= 0"])
66
- s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
67
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
74
+ s.add_dependency(%q<shoulda>, [">= 0"])
75
+ s.add_dependency(%q<bundler>, [">= 0"])
68
76
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
69
77
  s.add_dependency(%q<rcov>, [">= 0"])
70
78
  s.add_dependency(%q<rr>, [">= 0"])
@@ -77,8 +85,8 @@ Gem::Specification.new do |s|
77
85
  s.add_dependency(%q<pry>, [">= 0"])
78
86
  s.add_dependency(%q<pry-doc>, [">= 0"])
79
87
  s.add_dependency(%q<gist>, [">= 0"])
80
- s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
81
- s.add_dependency(%q<bundler>, ["~> 1.0.0"])
88
+ s.add_dependency(%q<shoulda>, [">= 0"])
89
+ s.add_dependency(%q<bundler>, [">= 0"])
82
90
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
83
91
  s.add_dependency(%q<rcov>, [">= 0"])
84
92
  s.add_dependency(%q<rr>, [">= 0"])
@@ -9,5 +9,42 @@ module HitfoxCouponApi
9
9
  def coupon(code)
10
10
  Coupon.new(self, code)
11
11
  end
12
+
13
+ def user(user_id)
14
+ User.new(self, user_id)
15
+ end
16
+
17
+ def order(order_id)
18
+ Order.new(self, order_id)
19
+ end
20
+
21
+ # return the true/false if count coupons are available for the application
22
+ def available?(count = 1)
23
+ Coupon.new(self,nil).available?(count)
24
+ end
25
+
26
+ # take an array of coupon details and create deal coupons. The array is assumed to be
27
+ # structured as: [type, code, type, code, link, type, code, type, code, ... etc]
28
+ # where type is one of: :actlink (2 args), :ingame (1 arg), :url (1 arg), e.g.
29
+ # [:actlink, code, link, :ingame, code, :url, link, :ingame, code, ....]
30
+ # would a valid array.
31
+ def add_coupons(cpns_code)
32
+ Coupon.new(self,nil).add(cpns_code)
33
+ end
34
+ def add_coupons!(cpns_code)
35
+ Coupon.new(self,nil).add!(cpns_code)
36
+ end
37
+
38
+ # Allow an application to have a specific configuration. This allows
39
+ # one company to manage multiple products.
40
+ def configuration
41
+ @configuration
42
+ end
43
+
44
+ def configure
45
+ @configuration ||= HitfoxCouponApi.configuration.dup
46
+ block_given? ? yield(@configuration) : @configuration
47
+ @configuration
48
+ end
12
49
  end
13
50
  end
@@ -0,0 +1,32 @@
1
+ module HitfoxCouponApi
2
+ class Client
3
+ HitfoxApiException = Class.new(RuntimeError)
4
+
5
+ def configuration
6
+ @application.configuration || HitfoxCouponApi.configuration
7
+ end
8
+
9
+ def apiheaders
10
+ config = configuration
11
+ {
12
+ "X-API-TOKEN" => config.api_token,
13
+ "X-API-APP-ID" => @application.identifier,
14
+ "X-API-TIMESTAMP" => config.generate_timestamp,
15
+ }
16
+ end
17
+
18
+ def generate_url(path, params)
19
+ '%s%s' % [configuration.api_endpoint, path % params.map { |a| CGI.escape(a) }]
20
+ end
21
+
22
+ def handle_coupon_results(res)
23
+ if res["status"] == 0
24
+ res["coupons"].map { |c| c[c.keys.first] }.map do |cc|
25
+ block_given? ? yield(cc) : Coupon.new(@application, cc["code"], cc["download_url"])
26
+ end
27
+ else
28
+ raise HitfoxApiException, "#{res['status']}: #{res['msg']}"
29
+ end
30
+ end
31
+ end
32
+ end
@@ -3,28 +3,90 @@ require 'digest/sha1'
3
3
  require 'json'
4
4
 
5
5
  module HitfoxCouponApi
6
- class Coupon
7
- def initialize(product, code)
8
- @application, @code = product, code
6
+ class Coupon < Client
7
+ attr_accessor :code, :url, :state
8
+
9
+ def initialize(application, code, url = nil)
10
+ @application, @code, @url = application, code, url
11
+ end
12
+
13
+ # Add new coupon codes to an application.
14
+ # Take an array of coupon details and create deal coupons. The array is assumed to be
15
+ # structured as: [type, code, type, code, link, type, code, type, code, ... etc]
16
+ # where type is one of: :actlink (2 args), :ingame (1 arg), :url (1 arg), e.g.
17
+ # [:actlink, code, link, :ingame, code, :url, link, :ingame, code, ....]
18
+ # would a valid array.
19
+ # The :actlink type takes two further parameters: link and code, while the ingame and
20
+ # url types only take one further argument.
21
+ def add(cpns_code)
22
+ headers, params = build_request_data(cpns_code.count) do |config, headers, hshstr|
23
+ [config.api_version.to_s, Digest::SHA1.hexdigest(hshstr)]
24
+ end
25
+ urlstr = generate_url('/%s/coupons/create.json?hash=%s', params)
26
+ JSON.parse(RestClient.post(urlstr, { :coupons => cpns_code }, headers))
27
+ end
28
+
29
+ def add!(cpns_code)
30
+ res = add(cpns_code)
31
+ res["status"] == 0 ? true : raise(HitfoxApiException, "#{res['status']}: #{res['msg']}")
9
32
  end
10
33
 
34
+
35
+ # Make a coupon as having been used by the end-user. This should be called once
36
+ # the user has entered and reclaimed their coupon. It provides HitFox with the information
37
+ # that the coupon has been used.
11
38
  def used
12
- config = HitfoxCouponApi.configuration
13
- timestamp = config.generate_timestamp
14
- headers = {
15
- "X-API-TOKEN" => config.api_token,
16
- "X-API-APP-ID" => @application.identifier,
17
- "X-API-TIMESTAMP" => timestamp,
18
- }
19
-
20
- str = [ @code, config.api_token, timestamp, @application.identifier,
21
- config.api_secret ].join(",")
22
-
23
- path = "/%s/coupon/%s/used.json?hash=%s" % [CGI.escape(config.api_version.to_s),
24
- CGI.escape(@code),
25
- CGI.escape(Digest::SHA1.hexdigest(str))]
26
-
27
- JSON.parse(RestClient.get("%s%s" % [config.api_endpoint, path], headers))
39
+ headers, params = build_request_data(@code) do |config, headers, hshstr|
40
+ [config.api_version.to_s, @code, Digest::SHA1.hexdigest(hshstr)]
41
+ end
42
+ urlstr = generate_url('/%s/coupon/%s/used.json?hash=%s', params)
43
+ JSON.parse(RestClient.get(urlstr, headers))
44
+ end
45
+
46
+ def used!
47
+ res = used
48
+ res["status"] == 0 ? true : raise(HitfoxApiException, "#{res['status']}: #{res['msg']}")
49
+ end
50
+
51
+ # Provide details on this coupon. The code, download url and the status are provided
52
+ # of the coupon.
53
+ def info
54
+ headers, params = build_request_data(@code) do |config, headers, hshstr|
55
+ [config.api_version.to_s, @code, Digest::SHA1.hexdigest(hshstr)]
56
+ end
57
+
58
+ urlstr = generate_url('/%s/coupon/%s/info.json?hash=%s', params)
59
+
60
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers))) do |cpn|
61
+ Coupon.new(Application.new(cpn["app_id"]), cpn["code"], cpn["download_url"]).tap do |cc|
62
+ cc.state = cpn["state"]
63
+ end
64
+ end
65
+ end
66
+
67
+ # Are there count-number of coupons avaiable for this product. This is not strictly
68
+ # related to a particular coupon, rather this is delegated down from the application
69
+ # to the coupon, Application#available? should be used instead of this method
70
+ # directly.
71
+ def available?(count = 1)
72
+ headers, params = build_request_data(count) do |config, headers, hshstr|
73
+ [config.api_version.to_s, Digest::SHA1.hexdigest(hshstr), count.to_s]
74
+ end
75
+ urlstr = generate_url('/%s/coupons/available.json?hash=%s&count=%s', params)
76
+ JSON.parse(RestClient.get(urlstr, headers))["status"] == 0
77
+ end
78
+
79
+ def app_id
80
+ @application.identifier
81
+ end
82
+
83
+ protected
84
+
85
+ def build_request_data(hsh_param, &block)
86
+ config, headers = configuration, apiheaders
87
+ hshstr = [ hsh_param, config.api_token, headers["X-API-TIMESTAMP"],
88
+ @application.identifier, config.api_secret ].join(",")
89
+ [headers, yield(config, headers, hshstr)]
28
90
  end
29
91
  end
30
92
  end
@@ -0,0 +1,47 @@
1
+ module HitfoxCouponApi
2
+ class Order < Client
3
+ attr_accessor :order_id
4
+
5
+ def initialize(application, order_id)
6
+ @application, @order_id = application, order_id
7
+ end
8
+
9
+ # Reserve count coupons for an order. These are reserved for a specific application,
10
+ # if an order contains multiple products/deals/applications, then this needs to called
11
+ # once for each.
12
+ def reserve(count = 1)
13
+ headers, params = build_request_data
14
+ urlstr = generate_url('/%s/coupon/%s/reserve.json?hash=%s&count=%s', params + [count.to_s])
15
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers)))
16
+ end
17
+
18
+ # Make as paid the coupons attached to the order. Once again, this is related only to
19
+ # those coupons that are from this application. If an order contains coupons from an
20
+ # application, then they need to be marked paid separately.
21
+ def paid
22
+ headers, params = build_request_data
23
+ urlstr = generate_url('/%s/coupon/%s/paid.json?hash=%s', params)
24
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers)))
25
+ end
26
+
27
+ # Return a list of coupons of this order. Once again, this will only provide a list of
28
+ # coupons that are attached to this application.
29
+ def coupons
30
+ headers, params = build_request_data
31
+ urlstr = generate_url('/%s/coupon/%s/list.json?hash=%s', params)
32
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers)))
33
+ end
34
+
35
+ protected
36
+
37
+ def build_request_data
38
+ config, headers = configuration, apiheaders
39
+
40
+ hshstr = [@order_id, config.api_token, headers["X-API-TIMESTAMP"],
41
+ @application.identifier, config.api_secret].join(",")
42
+
43
+ params = [config.api_version.to_s, @order_id, Digest::SHA1.hexdigest(hshstr)]
44
+ [headers, params]
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,37 @@
1
+ module HitfoxCouponApi
2
+ class User < Client
3
+ attr_accessor :user_id
4
+
5
+ def initialize(application, user_id)
6
+ @application, @user_id = application, user_id
7
+ end
8
+
9
+ # buy count coupons for this application. If there aren't enough coupons, then this
10
+ # will return an empty list. This is an all-or-nothing call, if count coupons aren't
11
+ # available, then none are bought.
12
+ def buy_coupon(count = 1)
13
+ headers, params = build_request_data
14
+ urlstr = generate_url('/%s/coupon/%s/buy.json?hash=%s&count=%s', params + [count.to_s])
15
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers)))
16
+ end
17
+
18
+ # Get a list coupons for this user, for this application.
19
+ def coupons
20
+ headers, params = build_request_data
21
+ urlstr = generate_url('/%s/coupon/%s/show.json?hash=%s', params)
22
+ handle_coupon_results(JSON.parse(RestClient.get(urlstr, headers)))
23
+ end
24
+
25
+ protected
26
+
27
+ def build_request_data
28
+ config, headers = configuration, apiheaders
29
+
30
+ hshstr = [@user_id, config.api_token, headers["X-API-TIMESTAMP"],
31
+ @application.identifier, config.api_secret].join(",")
32
+
33
+ params = [config.api_version.to_s, @user_id, Digest::SHA1.hexdigest(hshstr)]
34
+ [headers, params]
35
+ end
36
+ end
37
+ end
@@ -1,8 +1,11 @@
1
1
  require 'rest-client'
2
2
 
3
3
  require 'hitfox_coupon_api/configuration'
4
+ require 'hitfox_coupon_api/client'
4
5
  require 'hitfox_coupon_api/application'
5
6
  require 'hitfox_coupon_api/coupon'
7
+ require 'hitfox_coupon_api/order'
8
+ require 'hitfox_coupon_api/user'
6
9
 
7
10
  module HitfoxCouponApi
8
11
  extend self
data/test/helper.rb CHANGED
@@ -19,4 +19,26 @@ require 'hitfox_coupon_api'
19
19
 
20
20
  class Test::Unit::TestCase
21
21
  include RR::Adapters::TestUnit
22
+
23
+ def setup_api_and_header
24
+ HitfoxCouponApi.configure do |c|
25
+ c.api_token = "1234"
26
+ c.api_secret = "2143abce"
27
+ c.api_version = "one"
28
+ c.api_endpoint = "http://banana.com"
29
+ end
30
+
31
+ @header = {
32
+ "X-API-APP-ID" => "productidentiefer",
33
+ "X-API-TIMESTAMP" => "1314792296",
34
+ "X-API-TOKEN" => "1234"
35
+ }
36
+ end
37
+
38
+ def mock_rest_client(jsonstr = nil)
39
+ jsonstr ||= '{ "status" : 1, "msg" : "no message" }'
40
+ mock.instance_of(HitfoxCouponApi::Configuration).
41
+ generate_timestamp { '1314792296' }
42
+ mock(RestClient).get(@url,@header) { jsonstr }
43
+ end
22
44
  end
@@ -0,0 +1,214 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestCoupon < Test::Unit::TestCase
4
+ context "coupon funcationality" do
5
+ setup do
6
+ setup_api_and_header
7
+ @app = HitfoxCouponApi::Application.new("productidentiefer")
8
+ end
9
+
10
+ context "coupon available" do
11
+ setup do
12
+ @url = ("http://banana.com/one/coupons/available.json?"+
13
+ "hash=dfb33057c8670f2f088bf5d12ea30a00955cdfa8&count=1")
14
+ end
15
+
16
+ should "fail if status non zero" do
17
+ mock_rest_client
18
+ assert !@app.available?(1)
19
+ end
20
+
21
+ should "fail if status non existent" do
22
+ mock_rest_client('{}')
23
+ assert !@app.available?(1)
24
+ end
25
+
26
+ should "succeed if status is zero" do
27
+ mock_rest_client('{"status" : 0}')
28
+ assert @app.available?(1)
29
+ end
30
+ end
31
+
32
+ context "coupon reservation for order" do
33
+ setup do
34
+ @url = ("http://banana.com/one/coupon/1231/reserve.json?"+
35
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40&count=1")
36
+ end
37
+
38
+ should "fail if status non-zero" do
39
+ mock_rest_client
40
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
41
+ @app.order("1231").reserve
42
+ end
43
+ end
44
+
45
+ should "generate coupons if all is well" do
46
+ jsonstr = {
47
+ :status => 0,
48
+ :coupons => [{"in_game_coupon" => {
49
+ :code => 'fubar',
50
+ :download_url => "http://example.com?dd"
51
+ }},
52
+ {"fubar" => {
53
+ :code => 'snafu',
54
+ :download_url => "http://example.com?dd/snahf"
55
+ }}]}.to_json
56
+ mock_rest_client(jsonstr)
57
+
58
+ cpns = @app.order("1231").reserve
59
+ assert_equal 2, cpns.count
60
+ assert_equal "fubar", cpns.first.code
61
+ assert_equal "http://example.com?dd", cpns.first.url
62
+ assert_equal "snafu", cpns.last.code
63
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
64
+ end
65
+ end
66
+
67
+ context "coupon info" do
68
+ setup do
69
+ @url = ("http://banana.com/one/coupon/abcdedfg-1234-jakl/info.json?"+
70
+ "hash=97c68554af339f1017155b1c4eb4cf3d14039bea")
71
+ end
72
+
73
+ should "work if status is zero" do
74
+ jsonstr = {
75
+ :status => 0,
76
+ :coupons => [{"in_game_coupon" => {
77
+ :code => 'fubar',
78
+ :download_url => "http://example.com?dd",
79
+ :state => 'all good',
80
+ :app_id => "1231121",
81
+ }},
82
+ {"fubar" => {
83
+ :code => 'snafu',
84
+ :download_url => "http://example.com?dd/snahf",
85
+ :state => 'all bad',
86
+ :app_id => 12131412,
87
+ }}]}.to_json
88
+ mock_rest_client(jsonstr)
89
+
90
+ cpns = @app.coupon("abcdedfg-1234-jakl").info
91
+ assert_equal 2, cpns.count
92
+
93
+ cpn = cpns.first
94
+ assert_equal "1231121", cpn.app_id
95
+ assert_equal "fubar", cpn.code
96
+ assert_equal "http://example.com?dd", cpn.url
97
+ assert_equal 'all good', cpn.state
98
+
99
+ cpn = cpns.last
100
+ assert_equal 12131412, cpn.app_id
101
+ assert_equal "http://example.com?dd/snahf", cpn.url
102
+ assert_equal 'all bad', cpn.state
103
+ assert_equal 'snafu', cpn.code
104
+ end
105
+
106
+ should "die if the status is not zero" do
107
+ mock_rest_client('{ "status" : "banana" }')
108
+
109
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
110
+ @app.coupon("abcdedfg-1234-jakl").info
111
+ end
112
+ end
113
+ end
114
+
115
+ context "coupon adding" do
116
+ setup do
117
+ @url = ("http://banana.com/one/coupons/create.json?"+
118
+ "hash=6f6e6aab956d49491b799daf4ed6f8cdadb3ee59")
119
+ end
120
+
121
+ should "generate hash based on count" do
122
+ ary = [:one,:two,:three,:four]
123
+ mock.instance_of(HitfoxCouponApi::Configuration).
124
+ generate_timestamp { '1314792296' }
125
+ mock(RestClient).post(@url.gsub(/6f6e6aab956d49491b799daf4ed6f8cdadb3ee59/,
126
+ "b99ac8c4a3027c6bbe759cfc8179bd338bfd6e14"),
127
+ { :coupons => ary}, @header) { '{ "status" : 1 }'}
128
+
129
+ HitfoxCouponApi::Application.new("productidentiefer").add_coupons(ary)
130
+ end
131
+
132
+ should "generate hash based on count not content of array" do
133
+ ary = [:oned,:twod,:dthree,:dfour]
134
+ mock.instance_of(HitfoxCouponApi::Configuration).
135
+ generate_timestamp { '1314792296' }
136
+ mock(RestClient).post(@url.gsub(/6f6e6aab956d49491b799daf4ed6f8cdadb3ee59/,
137
+ "b99ac8c4a3027c6bbe759cfc8179bd338bfd6e14"),
138
+ { :coupons => ary}, @header) { '{ "status" : 1 }'}
139
+
140
+ @app.add_coupons(ary)
141
+ end
142
+
143
+ should "raise exception with bang" do
144
+ ary = [:one,:two,:three]
145
+ mock.instance_of(HitfoxCouponApi::Configuration).
146
+ generate_timestamp { '1314792296' }
147
+ mock(RestClient).post(@url, { :coupons => ary}, @header) { '{ "status" : 1 }'}
148
+
149
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
150
+ @app.add_coupons!(ary)
151
+ end
152
+ end
153
+
154
+ should "work with bang also" do
155
+ ary = [:one,:two,:three]
156
+ mock.instance_of(HitfoxCouponApi::Configuration).
157
+ generate_timestamp { '1314792296' }
158
+ mock(RestClient).post(@url, { :coupons => ary}, @header) { '{ "status" : 0 }'}
159
+
160
+ @app.add_coupons!(ary)
161
+ end
162
+
163
+ should "work" do
164
+ ary = [:one,:two,:three]
165
+ mock.instance_of(HitfoxCouponApi::Configuration).
166
+ generate_timestamp { '1314792296' }
167
+ mock(RestClient).post(@url, { :coupons => ary}, @header) { '{ "status" : 0 }'}
168
+
169
+ @app.add_coupons(ary)
170
+ end
171
+ end
172
+
173
+ context "coupon used" do
174
+ setup do
175
+ @url = ("http://banana.com/one/coupon/abcdedfg-1234-jakl/used.json?"+
176
+ "hash=97c68554af339f1017155b1c4eb4cf3d14039bea")
177
+ end
178
+
179
+ should "have a bang variation for throwing exceptions" do
180
+ cpn = @app.coupon("abcdedfg-1234-jakl")
181
+
182
+ mock(cpn).used { { "status" => 1 }}
183
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
184
+ cpn.used!
185
+ end
186
+ end
187
+
188
+ should "have a bang variation for returning true" do
189
+ product = HitfoxCouponApi::Application.new("productidentiefer")
190
+ cpn = product.coupon("abcdedfg-1234-jakl")
191
+ mock(cpn).used { { "status" => 0 }}
192
+ assert cpn.used
193
+ end
194
+
195
+ should "generate the correct hash value" do
196
+ mock_rest_client('{ "status" : "banana" }')
197
+
198
+ hsh = @app.coupon("abcdedfg-1234-jakl").used
199
+
200
+ assert_equal "banana", hsh["status"]
201
+ end
202
+
203
+ should "propagate exceptions" do
204
+ mock(RestClient).get.with_any_args do
205
+ raise RuntimeError, "no good"
206
+ end
207
+
208
+ assert_raise RuntimeError do
209
+ @app.coupon("asdsad").used
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
@@ -1,60 +1,109 @@
1
1
  require File.dirname(__FILE__)+'/helper'
2
2
 
3
3
  class TestHitfoxCouponApi < Test::Unit::TestCase
4
- context "coupon used" do
4
+
5
+ context "hitfox api" do
5
6
  setup do
6
- HitfoxCouponApi.configure do |c|
7
- c.api_token = "1234"
8
- c.api_secret = "2143abce"
9
- c.api_version = "one"
10
- c.api_endpoint = "http://banana.com"
11
- end
7
+ setup_api_and_header
12
8
  end
13
9
 
14
- should "generate the correct hash value" do
15
- url = ("http://banana.com/one/coupon/abcdedfg-1234-jakl/used.json?"+
16
- "hash=97c68554af339f1017155b1c4eb4cf3d14039bea")
17
- header = {
18
- "X-API-APP-ID" => "productidentiefer",
19
- "X-API-TIMESTAMP" => "1314792296",
20
- "X-API-TOKEN" => "1234"
21
- }
10
+ context "configuration can be application specific" do
11
+ should "have default global configuration" do
12
+ app1 = HitfoxCouponApi.application("12131")
13
+ assert_nil app1.configuration
14
+ assert_equal "http://banana.com", app1.user("121").configuration.api_endpoint
15
+ end
22
16
 
23
- mock.instance_of(HitfoxCouponApi::Configuration).generate_timestamp { '1314792296' }
24
- mock(RestClient).get(url,header) { '{ "status" : "banana" }'}
17
+ should "can have application specific configuration" do
18
+ app1 = HitfoxCouponApi.application("12131")
19
+ assert_nil app1.configuration
20
+ user = app1.user("121")
21
+ assert_equal "http://banana.com", user.configuration.api_endpoint
25
22
 
26
- product = HitfoxCouponApi::Application.new("productidentiefer")
27
- hsh = product.coupon("abcdedfg-1234-jakl").used
23
+ app1.configure { |c| c.api_endpoint = "http://new.endpoint.com" }
24
+ assert_equal "http://new.endpoint.com", app1.user("121").configuration.api_endpoint
25
+ assert_equal "http://new.endpoint.com", user.configuration.api_endpoint
28
26
 
29
- assert_equal "banana", hsh["status"]
30
- end
27
+ # but remains application specific
28
+ app2 = HitfoxCouponApi.application("12131")
29
+ assert_equal "http://banana.com", app2.user("121").configuration.api_endpoint
30
+ assert_equal "http://new.endpoint.com", app1.user("1").configuration.api_endpoint
31
+ end
31
32
 
32
- should "provide a shortcut application instanciation method" do
33
- url = ("http://banana.com/one/coupon/abcdedfg-1234-jakl/used.json?"+
34
- "hash=97c68554af339f1017155b1c4eb4cf3d14039bea")
35
- header = {
36
- "X-API-APP-ID" => "productidentiefer",
37
- "X-API-TIMESTAMP" => "1314792296",
38
- "X-API-TOKEN" => "1234"
39
- }
33
+ should "global configuration provides default values for things not set" do
34
+ app1 = HitfoxCouponApi.application("12131")
35
+ app1.configure { |c| c.api_endpoint = "http://new.endpoint.com" }
40
36
 
41
- mock.instance_of(HitfoxCouponApi::Configuration).generate_timestamp { '1314792296' }
42
- mock(RestClient).get(url,header) { '{ "status" : "banana" }' }
37
+ user = app1.user("1211")
38
+ url = ("http://new.endpoint.com/one/coupon/1211/buy.json?"+
39
+ "hash=5d13dc25ee89649c5e02c3b93f0f9f4faa6d6d21&count=1")
43
40
 
44
- hsh = HitfoxCouponApi.application("productidentiefer").
45
- coupon("abcdedfg-1234-jakl").used
41
+ header = {
42
+ "X-API-APP-ID" => "12131",
43
+ "X-API-TIMESTAMP" => "1314792296",
44
+ "X-API-TOKEN" => "1234"
45
+ }
46
+ mock(app1.configuration).generate_timestamp { "1314792296" }
47
+ mock(RestClient).get(url,header) { '{ "status" : 1, "msg" : "no message" }'}
46
48
 
47
- assert_equal "banana", hsh["status"]
49
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
50
+ user.buy_coupon
51
+ end
52
+ end
48
53
  end
49
54
 
50
- should "propagate exceptions" do
51
- product = HitfoxCouponApi::Application.new("productidentiefer")
52
- mock(RestClient).get.with_any_args do
53
- raise RuntimeError, "no good"
55
+ context "client helpers" do
56
+ setup do
57
+ @cpnres = {
58
+ "status" => 0,
59
+ "coupons" => [ "some_key" => {
60
+ "app_id" => 'fubar',
61
+ "code" => "edoc",
62
+ "download_url" => "url",
63
+ "state" => "active"
64
+ }
65
+ ]
66
+ }
67
+
68
+ @client = Class.new(HitfoxCouponApi::Client) do
69
+ def initialize(app)
70
+ @application = app
71
+ end
72
+ end.new(HitfoxCouponApi::Application.new("fubar"))
73
+ end
74
+
75
+ should "be able to generate a url" do
76
+ assert_equal "http://banana.com", @client.generate_url("",[])
77
+ assert_equal "http://banana.com/path", @client.generate_url("/%s",["path"])
78
+ assert_equal("http://banana.com/path?c=%2B%3F%26%2F",
79
+ @client.generate_url("/%s?c=%s",["path","+?&/"]))
80
+ end
81
+
82
+ should "handle a coupon return value - raise exception if status non zero" do
83
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
84
+ @client.handle_coupon_results({"status" => 1})
85
+ end
86
+ end
87
+
88
+ should "handle coupon results" do
89
+ cpns = @client.handle_coupon_results(@cpnres)
90
+ assert_equal 1, cpns.count
91
+ assert_equal "edoc", cpns.first.code
92
+ assert_equal "url", cpns.first.url
93
+ assert_equal nil, cpns.first.state
54
94
  end
55
95
 
56
- assert_raise RuntimeError do
57
- product.coupon("asdsad").used
96
+ should "handle coupon results and yield to block" do
97
+ cpns = @client.handle_coupon_results(@cpnres) do |cc|
98
+ HitfoxCouponApi::Coupon.new(HitfoxCouponApi::Application.new(cc["app_id"]),
99
+ cc["code"], cc["download_url"]).tap do |cpn|
100
+ cpn.state = cc["state"]
101
+ end
102
+ end
103
+ assert_equal 1, cpns.count
104
+ assert_equal "edoc", cpns.first.code
105
+ assert_equal "url", cpns.first.url
106
+ assert_equal "active", cpns.first.state
58
107
  end
59
108
  end
60
109
  end
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestOrder < Test::Unit::TestCase
4
+ context "order functionality" do
5
+ setup do
6
+ setup_api_and_header
7
+ @app = HitfoxCouponApi::Application.new("productidentiefer")
8
+ end
9
+
10
+ context "reserve coupons" do
11
+ setup do
12
+ @url = ("http://banana.com/one/coupon/1231/reserve.json?"+
13
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40&count=2")
14
+ end
15
+
16
+ should "fail with status non zero" do
17
+ mock_rest_client
18
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
19
+ order = @app.order("1231").reserve(2)
20
+ end
21
+ end
22
+
23
+ should "work well enough" do
24
+ jsonstr = {
25
+ :status => 0,
26
+ :coupons => [{"in_game_coupon" => {
27
+ :code => 'fubar',
28
+ :download_url => "http://example.com?dd"
29
+ }},
30
+ {"fubar" => {
31
+ :code => 'snafu',
32
+ :download_url => "http://example.com?dd/snahf"
33
+ }}]}.to_json
34
+
35
+ mock_rest_client(jsonstr)
36
+ cpns = @app.order("1231").reserve(2)
37
+ assert_equal 2, cpns.count
38
+ assert_equal "fubar", cpns.first.code
39
+ assert_equal "http://example.com?dd", cpns.first.url
40
+ assert_equal "snafu", cpns.last.code
41
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
42
+ end
43
+ end
44
+
45
+ context "paid coupons" do
46
+ setup do
47
+ @url = ("http://banana.com/one/coupon/1231/paid.json?"+
48
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40")
49
+ end
50
+
51
+ should "fail with status non zero" do
52
+ mock_rest_client
53
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
54
+ order = @app.order("1231").paid
55
+ end
56
+ end
57
+
58
+ should "work well enough" do
59
+ jsonstr = {
60
+ :status => 0,
61
+ :coupons => [{"in_game_coupon" => {
62
+ :code => 'fubar',
63
+ :download_url => "http://example.com?dd"
64
+ }},
65
+ {"fubar" => {
66
+ :code => 'snafu',
67
+ :download_url => "http://example.com?dd/snahf"
68
+ }}]}.to_json
69
+
70
+ mock_rest_client(jsonstr)
71
+ cpns = @app.order("1231").paid
72
+ assert_equal 2, cpns.count
73
+ assert_equal "fubar", cpns.first.code
74
+ assert_equal "http://example.com?dd", cpns.first.url
75
+ assert_equal "snafu", cpns.last.code
76
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
77
+ end
78
+ end
79
+
80
+ context "obtain a list of coupons" do
81
+ setup do
82
+ @url = ("http://banana.com/one/coupon/1231/list.json?"+
83
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40")
84
+ end
85
+
86
+ should "fail with status non zero" do
87
+ mock_rest_client
88
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
89
+ order = @app.order("1231").coupons
90
+ end
91
+ end
92
+
93
+ should "work well enough" do
94
+ jsonstr = {
95
+ :status => 0,
96
+ :coupons => [{"in_game_coupon" => {
97
+ :code => 'fubar',
98
+ :download_url => "http://example.com?dd"
99
+ }},
100
+ {"fubar" => {
101
+ :code => 'snafu',
102
+ :download_url => "http://example.com?dd/snahf"
103
+ }}]}.to_json
104
+
105
+ mock_rest_client(jsonstr)
106
+ cpns = @app.order("1231").coupons
107
+ assert_equal 2, cpns.count
108
+ assert_equal "fubar", cpns.first.code
109
+ assert_equal "http://example.com?dd", cpns.first.url
110
+ assert_equal "snafu", cpns.last.code
111
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
112
+ end
113
+ end
114
+ end
115
+ end
data/test/test_user.rb ADDED
@@ -0,0 +1,83 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestUser < Test::Unit::TestCase
4
+ context "user functionality" do
5
+ setup do
6
+ setup_api_and_header
7
+ @app = HitfoxCouponApi::Application.new("productidentiefer")
8
+ end
9
+
10
+ context "user coupon listing" do
11
+ setup do
12
+ @url = ("http://banana.com/one/coupon/1231/show.json?"+
13
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40")
14
+ end
15
+
16
+ should "fail if status is non zero" do
17
+ mock_rest_client
18
+
19
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
20
+ @app.user("1231").coupons
21
+ end
22
+ end
23
+
24
+ should "succeed if status zero" do
25
+ jsonstr = {
26
+ :status => 0,
27
+ :coupons => [{"in_game_coupon" => {
28
+ :code => 'fubar',
29
+ :download_url => "http://example.com?dd"
30
+ }},
31
+ {"fubar" => {
32
+ :code => 'snafu',
33
+ :download_url => "http://example.com?dd/snahf"
34
+ }}]}.to_json
35
+
36
+ mock_rest_client(jsonstr)
37
+
38
+ cpns = @app.user("1231").coupons
39
+ assert_equal 2, cpns.count
40
+ assert_equal "fubar", cpns.first.code
41
+ assert_equal "http://example.com?dd", cpns.first.url
42
+ assert_equal "snafu", cpns.last.code
43
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
44
+ end
45
+ end
46
+
47
+ context "user coupon purchase" do
48
+ setup do
49
+ @url = ("http://banana.com/one/coupon/1231/buy.json?"+
50
+ "hash=09b0150d9aeabb6d61427864f0c637051e69cf40&count=1")
51
+ end
52
+
53
+ should "fail if status non-zero" do
54
+ mock_rest_client
55
+
56
+ assert_raise HitfoxCouponApi::Client::HitfoxApiException do
57
+ @app.user("1231").buy_coupon
58
+ end
59
+ end
60
+
61
+ should "generate coupons if all is well" do
62
+ jsonstr = {
63
+ :status => 0,
64
+ :coupons => [{"in_game_coupon" => {
65
+ :code => 'fubar',
66
+ :download_url => "http://example.com?dd"
67
+ }},
68
+ {"fubar" => {
69
+ :code => 'snafu',
70
+ :download_url => "http://example.com?dd/snahf"
71
+ }}]}.to_json
72
+ mock_rest_client(jsonstr)
73
+
74
+ cpns = @app.user("1231").buy_coupon
75
+ assert_equal 2, cpns.count
76
+ assert_equal "fubar", cpns.first.code
77
+ assert_equal "http://example.com?dd", cpns.first.url
78
+ assert_equal "snafu", cpns.last.code
79
+ assert_equal "http://example.com?dd/snahf", cpns.last.url
80
+ end
81
+ end
82
+ end
83
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hitfox_coupon_api
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 2
10
- version: 0.0.2
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gerrit Riessen
@@ -15,10 +15,12 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-01 00:00:00 Z
18
+ date: 2012-05-02 00:00:00 +02:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ type: :runtime
23
+ requirement: &id001 !ruby/object:Gem::Requirement
22
24
  none: false
23
25
  requirements:
24
26
  - - ">="
@@ -28,11 +30,11 @@ dependencies:
28
30
  - 0
29
31
  version: "0"
30
32
  name: rest-client
33
+ version_requirements: *id001
31
34
  prerelease: false
32
- type: :runtime
33
- requirement: *id001
34
35
  - !ruby/object:Gem::Dependency
35
- version_requirements: &id002 !ruby/object:Gem::Requirement
36
+ type: :runtime
37
+ requirement: &id002 !ruby/object:Gem::Requirement
36
38
  none: false
37
39
  requirements:
38
40
  - - ">="
@@ -42,11 +44,11 @@ dependencies:
42
44
  - 0
43
45
  version: "0"
44
46
  name: json
47
+ version_requirements: *id002
45
48
  prerelease: false
46
- type: :runtime
47
- requirement: *id002
48
49
  - !ruby/object:Gem::Dependency
49
- version_requirements: &id003 !ruby/object:Gem::Requirement
50
+ type: :development
51
+ requirement: &id003 !ruby/object:Gem::Requirement
50
52
  none: false
51
53
  requirements:
52
54
  - - "="
@@ -58,11 +60,11 @@ dependencies:
58
60
  - 7
59
61
  version: 0.8.7
60
62
  name: rake
63
+ version_requirements: *id003
61
64
  prerelease: false
62
- type: :development
63
- requirement: *id003
64
65
  - !ruby/object:Gem::Dependency
65
- version_requirements: &id004 !ruby/object:Gem::Requirement
66
+ type: :development
67
+ requirement: &id004 !ruby/object:Gem::Requirement
66
68
  none: false
67
69
  requirements:
68
70
  - - ">="
@@ -72,11 +74,11 @@ dependencies:
72
74
  - 0
73
75
  version: "0"
74
76
  name: pry
77
+ version_requirements: *id004
75
78
  prerelease: false
76
- type: :development
77
- requirement: *id004
78
79
  - !ruby/object:Gem::Dependency
79
- version_requirements: &id005 !ruby/object:Gem::Requirement
80
+ type: :development
81
+ requirement: &id005 !ruby/object:Gem::Requirement
80
82
  none: false
81
83
  requirements:
82
84
  - - ">="
@@ -86,11 +88,11 @@ dependencies:
86
88
  - 0
87
89
  version: "0"
88
90
  name: pry-doc
91
+ version_requirements: *id005
89
92
  prerelease: false
90
- type: :development
91
- requirement: *id005
92
93
  - !ruby/object:Gem::Dependency
93
- version_requirements: &id006 !ruby/object:Gem::Requirement
94
+ type: :development
95
+ requirement: &id006 !ruby/object:Gem::Requirement
94
96
  none: false
95
97
  requirements:
96
98
  - - ">="
@@ -100,11 +102,11 @@ dependencies:
100
102
  - 0
101
103
  version: "0"
102
104
  name: gist
105
+ version_requirements: *id006
103
106
  prerelease: false
104
- type: :development
105
- requirement: *id006
106
107
  - !ruby/object:Gem::Dependency
107
- version_requirements: &id007 !ruby/object:Gem::Requirement
108
+ type: :development
109
+ requirement: &id007 !ruby/object:Gem::Requirement
108
110
  none: false
109
111
  requirements:
110
112
  - - ">="
@@ -113,28 +115,26 @@ dependencies:
113
115
  segments:
114
116
  - 0
115
117
  version: "0"
116
- name: thoughtbot-shoulda
118
+ name: shoulda
119
+ version_requirements: *id007
117
120
  prerelease: false
118
- type: :development
119
- requirement: *id007
120
121
  - !ruby/object:Gem::Dependency
121
- version_requirements: &id008 !ruby/object:Gem::Requirement
122
+ type: :development
123
+ requirement: &id008 !ruby/object:Gem::Requirement
122
124
  none: false
123
125
  requirements:
124
- - - ~>
126
+ - - ">="
125
127
  - !ruby/object:Gem::Version
126
- hash: 23
128
+ hash: 3
127
129
  segments:
128
- - 1
129
130
  - 0
130
- - 0
131
- version: 1.0.0
131
+ version: "0"
132
132
  name: bundler
133
+ version_requirements: *id008
133
134
  prerelease: false
134
- type: :development
135
- requirement: *id008
136
135
  - !ruby/object:Gem::Dependency
137
- version_requirements: &id009 !ruby/object:Gem::Requirement
136
+ type: :development
137
+ requirement: &id009 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ~>
@@ -146,11 +146,11 @@ dependencies:
146
146
  - 4
147
147
  version: 1.6.4
148
148
  name: jeweler
149
+ version_requirements: *id009
149
150
  prerelease: false
150
- type: :development
151
- requirement: *id009
152
151
  - !ruby/object:Gem::Dependency
153
- version_requirements: &id010 !ruby/object:Gem::Requirement
152
+ type: :development
153
+ requirement: &id010 !ruby/object:Gem::Requirement
154
154
  none: false
155
155
  requirements:
156
156
  - - ">="
@@ -160,11 +160,11 @@ dependencies:
160
160
  - 0
161
161
  version: "0"
162
162
  name: rcov
163
+ version_requirements: *id010
163
164
  prerelease: false
164
- type: :development
165
- requirement: *id010
166
165
  - !ruby/object:Gem::Dependency
167
- version_requirements: &id011 !ruby/object:Gem::Requirement
166
+ type: :development
167
+ requirement: &id011 !ruby/object:Gem::Requirement
168
168
  none: false
169
169
  requirements:
170
170
  - - ">="
@@ -174,11 +174,11 @@ dependencies:
174
174
  - 0
175
175
  version: "0"
176
176
  name: rr
177
+ version_requirements: *id011
177
178
  prerelease: false
178
- type: :development
179
- requirement: *id011
180
179
  - !ruby/object:Gem::Dependency
181
- version_requirements: &id012 !ruby/object:Gem::Requirement
180
+ type: :development
181
+ requirement: &id012 !ruby/object:Gem::Requirement
182
182
  none: false
183
183
  requirements:
184
184
  - - ">="
@@ -188,9 +188,8 @@ dependencies:
188
188
  - 0
189
189
  version: "0"
190
190
  name: cheat
191
+ version_requirements: *id012
191
192
  prerelease: false
192
- type: :development
193
- requirement: *id012
194
193
  description: Simple JSON interface to the HitFox coupon API
195
194
  email: gerrit.riessen@gmail.com
196
195
  executables: []
@@ -202,7 +201,9 @@ extra_rdoc_files:
202
201
  - README.rdoc
203
202
  files:
204
203
  - .document
204
+ - .keep
205
205
  - .rvmrc
206
+ - .travis.yml
206
207
  - Gemfile
207
208
  - LICENSE.txt
208
209
  - README.rdoc
@@ -211,12 +212,19 @@ files:
211
212
  - hitfox_coupon_api.gemspec
212
213
  - lib/hitfox_coupon_api.rb
213
214
  - lib/hitfox_coupon_api/application.rb
215
+ - lib/hitfox_coupon_api/client.rb
214
216
  - lib/hitfox_coupon_api/configuration.rb
215
217
  - lib/hitfox_coupon_api/coupon.rb
218
+ - lib/hitfox_coupon_api/order.rb
219
+ - lib/hitfox_coupon_api/user.rb
216
220
  - test/.login.yml.sample
217
221
  - test/helper.rb
222
+ - test/test_coupon.rb
218
223
  - test/test_hitfox_coupon_api.rb
224
+ - test/test_order.rb
225
+ - test/test_user.rb
219
226
  - test_shell
227
+ has_rdoc: true
220
228
  homepage: https://github.com/gorenje/hitfox_coupon_api
221
229
  licenses:
222
230
  - MIT
@@ -246,7 +254,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
254
  requirements: []
247
255
 
248
256
  rubyforge_project:
249
- rubygems_version: 1.8.10
257
+ rubygems_version: 1.6.2
250
258
  signing_key:
251
259
  specification_version: 3
252
260
  summary: Simple JSON interface to the HitFox coupon API