swrve 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +14 -0
- data/.travis.yml +2 -0
- data/Gemfile +10 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +23 -0
- data/README.md +44 -0
- data/Rakefile +6 -0
- data/lib/swrve.rb +27 -0
- data/lib/swrve/api/events.rb +100 -0
- data/lib/swrve/api/resources.rb +70 -0
- data/lib/swrve/configuration.rb +18 -0
- data/lib/swrve/errors.rb +3 -0
- data/lib/swrve/middleware/http.rb +23 -0
- data/lib/swrve/version.rb +3 -0
- data/spec/api/events_spec.rb +208 -0
- data/spec/api/resources_spec.rb +36 -0
- data/spec/configuration_spec.rb +0 -0
- data/spec/middleware/http_spec.rb +9 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/swrve_spec.rb +77 -0
- data/swrve.gemspec +36 -0
- metadata +309 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
guard 'bundler' do
|
2
|
+
watch('Gemfile')
|
3
|
+
watch(/^.+\.gemspec/)
|
4
|
+
end
|
5
|
+
|
6
|
+
guard :rspec, cli: '-fs --color --order rand' do
|
7
|
+
watch(%r{^spec/.+_spec\.rb$})
|
8
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
9
|
+
watch('spec/spec_helper.rb') { "spec" }
|
10
|
+
end
|
11
|
+
|
12
|
+
guard 'ctags-bundler', src_path: ["lib", "spec/support"] do
|
13
|
+
watch(/^(lib|spec\/support)\/.*\.rb$/)
|
14
|
+
watch('Gemfile.lock')
|
15
|
+
end
|
16
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
Copyright (c) 2013 John O'Gara
|
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.
|
23
|
+
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
The Swrve Ruby Gem
|
2
|
+
=====
|
3
|
+
[](https://coveralls.io/r/johnogara/swrve?branch=master)
|
4
|
+
[](https://travis-ci.org/jkogara/swrve)
|
5
|
+
[](https://codeclimate.com/repos/51eee7b989af7e75f4010537/feed)
|
6
|
+
[](http://badge.fury.io/rb/swrve)
|
7
|
+
|
8
|
+
A Ruby interface to the Swrve AB Testing API.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
gem install swrve
|
12
|
+
|
13
|
+
## Quick Start Guide
|
14
|
+
Once your account is set up at Swrve.com use the following to configure Swrve
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
Swrve.configure do |config|
|
18
|
+
config.api_key = YOUR_API_KEY
|
19
|
+
config.game_id = YOUR_GAME_ID
|
20
|
+
end
|
21
|
+
```
|
22
|
+
|
23
|
+
### Events
|
24
|
+
```ruby
|
25
|
+
Swrve.session_start('user uuid')
|
26
|
+
Swrve.create_event('user uuid', "custom.event.name.that.occurred")
|
27
|
+
Swrve.purchase('user uuid', 'Item Id', 5)
|
28
|
+
...
|
29
|
+
...
|
30
|
+
Swrve.session_end('user uuid')
|
31
|
+
```
|
32
|
+
|
33
|
+
### Resources
|
34
|
+
```ruby
|
35
|
+
json_resource = Swrve.resource(UniqueUserIdentifier, "ab_test_name")
|
36
|
+
```
|
37
|
+
|
38
|
+
[Usage Examples]: #usage-examples
|
39
|
+
|
40
|
+
## Documentation
|
41
|
+
[http://rdoc.info/gems/swrve][documentation]
|
42
|
+
|
43
|
+
[documentation]: http://rdoc.info/gems/swrve
|
44
|
+
|
data/Rakefile
ADDED
data/lib/swrve.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'swrve/version'
|
3
|
+
require 'swrve/configuration'
|
4
|
+
require 'swrve/middleware/http'
|
5
|
+
require 'swrve/api/events'
|
6
|
+
require 'swrve/api/resources'
|
7
|
+
|
8
|
+
module Swrve
|
9
|
+
class << self
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
attr_accessor :config, :event_sender, :resource_getter
|
13
|
+
|
14
|
+
def_delegators :@resource_getter, :resources, :resources_diff, :resource
|
15
|
+
def_delegators :@event_sender, :session_start, :session_end, :create_event, :purchase, :buy_in, :currency_given, :update_user
|
16
|
+
|
17
|
+
def configure
|
18
|
+
yield(config) if block_given?
|
19
|
+
@event_sender = Swrve::Api::Events.new
|
20
|
+
@resource_getter = Swrve::Api::Resources.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def config
|
24
|
+
@config ||= Configuration.new
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'swrve/middleware/http'
|
3
|
+
|
4
|
+
module Swrve
|
5
|
+
module Api
|
6
|
+
class Events
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
attr_accessor :api_endpoint
|
10
|
+
|
11
|
+
def_instance_delegator :@api_endpoint, :post
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@api_endpoint = Swrve::Middleware::Http.new(Swrve.config.api_url + "/#{Swrve.config.api_version}")
|
15
|
+
@web_app_version = Swrve.config.web_app_version
|
16
|
+
@api_key = Swrve.config.api_key
|
17
|
+
end
|
18
|
+
|
19
|
+
# Starts the user game session
|
20
|
+
# @param [String, #uuid] uuid Unique identifier for the user starting the session
|
21
|
+
# @return [String, swrve_payload (Hash) (defaults to: {}) — A customizable payload associated with the session_start event
|
22
|
+
def session_start(uuid, swrve_payload = {})
|
23
|
+
response = post('session_start', query_options(uuid, swrve_payload: fill_nil_values(swrve_payload)))
|
24
|
+
handle_response(response)
|
25
|
+
end
|
26
|
+
|
27
|
+
def session_end(uuid, swrve_payload = {})
|
28
|
+
post('session_end', query_options(uuid, swrve_payload: fill_nil_values(swrve_payload)))
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_user(uuid, user_attributes = {})
|
32
|
+
params = { user_initiated: (user_attributes.delete(:user_initiated) || true) }
|
33
|
+
params.merge!(swrve_payload: fill_nil_values(user_attributes.delete(:swrve_payload) || {}))
|
34
|
+
|
35
|
+
response = post('user', query_options(uuid, user_attributes.merge(params)))
|
36
|
+
handle_response(response)
|
37
|
+
end
|
38
|
+
|
39
|
+
def purchase(uuid, item_id, cost, options = {})
|
40
|
+
options = { item: item_id.to_s, cost: cost.to_f, currency: "USD", quantity: 1}.merge(options)
|
41
|
+
|
42
|
+
response = post('purchase', query_options(uuid, options))
|
43
|
+
handle_response(response)
|
44
|
+
end
|
45
|
+
|
46
|
+
def buy_in(uuid, amount, real_currency_name, reward_amount, reward_currency, options = {})
|
47
|
+
payment_provider = options.delete( :payment_provider ) || "Default Payment Provider"
|
48
|
+
swrve_payload = fill_nil_values(options[:swrve_payload] || {})
|
49
|
+
|
50
|
+
response = post('buy_in', query_options(uuid, {cost: amount.to_f, local_currency: real_currency_name,
|
51
|
+
reward_amount: reward_amount.to_f, reward_currency: reward_currency,
|
52
|
+
payment_provider: payment_provider, swrve_payload: swrve_payload}))
|
53
|
+
handle_response(response)
|
54
|
+
end
|
55
|
+
|
56
|
+
def currency_given(uuid, given_amount, given_currency, payload={})
|
57
|
+
validate_amount(given_amount, given_currency)
|
58
|
+
payload = fill_nil_values(payload)
|
59
|
+
|
60
|
+
response = post('currency_given', query_options(uuid, { given_currency: given_currency,
|
61
|
+
given_amount: given_amount,
|
62
|
+
swrve_payload: payload }))
|
63
|
+
handle_response(response)
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_event(uuid, name, payload = {})
|
67
|
+
params = query_options(uuid, name: name, swrve_payload: fill_nil_values(payload))
|
68
|
+
|
69
|
+
response = post('event', params)
|
70
|
+
handle_response(response)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def handle_response(response)
|
76
|
+
if response.status < 400
|
77
|
+
return 'OK'
|
78
|
+
else
|
79
|
+
raise Exception, "Error in request to Swrve: status => #{response.status}, info => #{response.body}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def validate_amount(amount, currency_name)
|
84
|
+
raise Exception, "Invalid currency name #{currency_name}" if currency_name.empty?
|
85
|
+
raise Exception, "Cannot give a zero amount #{amount.to_f}" if amount.to_f == (0)
|
86
|
+
raise Exception, "A negative amount is invalid #{amount.to_f}" if amount.to_f < (0)
|
87
|
+
end
|
88
|
+
|
89
|
+
def query_options(uuid, payload = {})
|
90
|
+
{ api_key: @api_key, app_version: @web_app_version, user: uuid }.merge(payload)
|
91
|
+
end
|
92
|
+
|
93
|
+
#The swrve api does not accept nul JSON values
|
94
|
+
def fill_nil_values(hash = {})
|
95
|
+
( hash.each { |k, v| hash[k] = '' if v.nil? } ).to_json
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'json'
|
4
|
+
require 'swrve/middleware/http'
|
5
|
+
|
6
|
+
module Swrve
|
7
|
+
module Api
|
8
|
+
class Resources
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :@resources_endpoint, :get
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@resources_endpoint = Middleware::Http.new(Swrve.config.ab_test_url + "/api/#{Swrve.config.api_version}")
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource(uuid, test_name, timestamp = nil)
|
18
|
+
convert_to_bools(resources(uuid, timestamp).detect{ |exists| exists['uid'] == test_name } || {})
|
19
|
+
end
|
20
|
+
|
21
|
+
def resources(uuid, timestamp = nil)
|
22
|
+
return local_resources if Swrve.config.load_local_resources
|
23
|
+
remote_resources(uuid, true, timestamp)
|
24
|
+
end
|
25
|
+
|
26
|
+
def resources_diff(uuid, timestamp = nil)
|
27
|
+
return local_resources if Swrve.config.load_local_resources
|
28
|
+
remote_resources(uuid, false, timestamp)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def convert_to_bools(resource)
|
34
|
+
resource.each do |k,v|
|
35
|
+
resource[k] = true if v == 'true'
|
36
|
+
resource[k] = false if v == 'false'
|
37
|
+
end
|
38
|
+
resource
|
39
|
+
end
|
40
|
+
|
41
|
+
def remote_resources(uuid, full_resource, created_at = nil)
|
42
|
+
request = full_resource ? 'user_resources' : 'user_resources_diff'
|
43
|
+
response = get(request, build_params(uuid, created_at))
|
44
|
+
|
45
|
+
response.status < 400 ? response.body : []
|
46
|
+
end
|
47
|
+
|
48
|
+
def build_params(uuid, created_at)
|
49
|
+
{
|
50
|
+
user: uuid,
|
51
|
+
api_key: Swrve.config.api_key,
|
52
|
+
app_version: Swrve.config.web_app_version,
|
53
|
+
joined: (created_at || Time.now).to_i * 1000
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def local_fixtures
|
58
|
+
Dir[File.join(Swrve.config.local_resource_path, '**/*.yaml')]
|
59
|
+
end
|
60
|
+
|
61
|
+
def local_resources
|
62
|
+
local_fixtures.
|
63
|
+
map { |f| YAML.load(File.read(f)) }.
|
64
|
+
select { |test| test["enabled"] }.
|
65
|
+
map { |test| test["variants"][test["selected"]] }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Swrve
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :ab_test_url, :api_url, :web_app_version, :api_key, :local_resource_path, :game_id, :debug_url,
|
6
|
+
:load_local_resources, :debug, :http_adapter, :api_version, :resource_timeout
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@ab_test_url = 'https://abtest.swrve.com'
|
10
|
+
@api_url = 'https://api.swrve.com'
|
11
|
+
@web_app_version = '1.0'
|
12
|
+
@debug_url = 'https://debug.api.swrve.com'
|
13
|
+
@http_adapter = Faraday.default_adapter
|
14
|
+
@api_version = 1
|
15
|
+
@resource_timeout = 4
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/swrve/errors.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday_middleware'
|
3
|
+
|
4
|
+
module Swrve
|
5
|
+
module Middleware
|
6
|
+
class Http
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
attr_accessor :client
|
11
|
+
|
12
|
+
def_instance_delegators :@client, :get, :post, :put
|
13
|
+
|
14
|
+
def initialize(endpoint)
|
15
|
+
@client = Faraday.new(endpoint) do |faraday|
|
16
|
+
faraday.request :url_encoded
|
17
|
+
faraday.adapter Swrve.config.http_adapter
|
18
|
+
faraday.use FaradayMiddleware::ParseJson
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'swrve/middleware/http'
|
3
|
+
module Swrve
|
4
|
+
module Api
|
5
|
+
describe Events do
|
6
|
+
|
7
|
+
subject { Events.new }
|
8
|
+
|
9
|
+
let(:http_middleware) { mock('http_middleware') }
|
10
|
+
let(:config) { stub_everything('config', web_app_version: '1', api_version: 1, api_key: 'KEY', api_url: 'http://api_url') }
|
11
|
+
|
12
|
+
before do
|
13
|
+
Swrve.stubs(config: config)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.new' do
|
17
|
+
it 'sets up the endpoint with the correct url' do
|
18
|
+
Swrve::Middleware::Http.expects(:new).with(config.api_url + "/#{config.api_version}")
|
19
|
+
|
20
|
+
subject
|
21
|
+
end
|
22
|
+
|
23
|
+
before { Swrve::Middleware::Http.stubs(new: http_middleware) }
|
24
|
+
|
25
|
+
it 'sets the correct app_version' do
|
26
|
+
config.expects(:web_app_version)
|
27
|
+
|
28
|
+
subject
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'sets the correct api_key' do
|
32
|
+
config.expects(:api_key)
|
33
|
+
|
34
|
+
subject
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'Instance methods' do
|
39
|
+
let(:good_response) { mock('response', status: 200) }
|
40
|
+
|
41
|
+
before do
|
42
|
+
Swrve::Middleware::Http.stubs(new: http_middleware)
|
43
|
+
subject.stubs(query_options: {})
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#session_start' do
|
47
|
+
it 'posts to the session_start endpoint' do
|
48
|
+
http_middleware.expects(:post).with('session_start', {}).returns(good_response)
|
49
|
+
subject.session_start('UUID')
|
50
|
+
end
|
51
|
+
|
52
|
+
before { http_middleware.stubs(:post).returns(good_response) }
|
53
|
+
|
54
|
+
it 'prepares the query_options' do
|
55
|
+
subject.expects(:query_options).with('UUID', swrve_payload: {}.to_json)
|
56
|
+
|
57
|
+
subject.session_start('UUID')
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'fills nil values on the swrve_payload' do
|
61
|
+
subject.expects(:fill_nil_values).with({name: nil})
|
62
|
+
|
63
|
+
subject.session_start('UUID', name: nil)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#session_end' do
|
68
|
+
it 'posts to the session_end endpoint' do
|
69
|
+
http_middleware.expects(:post).with('session_end', {})
|
70
|
+
subject.session_end('UUID')
|
71
|
+
end
|
72
|
+
|
73
|
+
before { http_middleware.stubs(:post) }
|
74
|
+
|
75
|
+
it 'prepares the query_options' do
|
76
|
+
subject.expects(:query_options).with('UUID', swrve_payload: {}.to_json)
|
77
|
+
|
78
|
+
subject.session_end('UUID')
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'fills nil values on the swrve_payload' do
|
82
|
+
subject.expects(:fill_nil_values).with({name: nil})
|
83
|
+
|
84
|
+
subject.session_end('UUID', name: nil)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#update_user' do
|
89
|
+
it 'posts to the user endpoint' do
|
90
|
+
http_middleware.expects(:post).with('user', {}).returns(good_response)
|
91
|
+
|
92
|
+
subject.update_user('UUID')
|
93
|
+
end
|
94
|
+
|
95
|
+
before { http_middleware.stubs(:post).returns(good_response) }
|
96
|
+
|
97
|
+
it 'defaults user_initiated to being true' do
|
98
|
+
subject.expects(:query_options).with('UUID', user_initiated: true, swrve_payload: {}.to_json)
|
99
|
+
|
100
|
+
subject.update_user('UUID')
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'fills nil values on the swrve_payload' do
|
104
|
+
subject.expects(:fill_nil_values).with({name: nil})
|
105
|
+
|
106
|
+
subject.update_user('UUID', swrve_payload:{ name: nil })
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe '#purchase' do
|
111
|
+
it 'posts to the purchase endpoint' do
|
112
|
+
http_middleware.expects(:post).with('purchase', {}).returns(good_response)
|
113
|
+
|
114
|
+
subject.purchase('UUID', 1, 1)
|
115
|
+
end
|
116
|
+
|
117
|
+
before { http_middleware.stubs(:post).returns(good_response)}
|
118
|
+
|
119
|
+
it 'defaults currency and quantity to the correct values' do
|
120
|
+
subject.expects(:query_options).with('UUID', item: 1.to_s, cost: 1.to_f, currency: 'USD', quantity: 1)
|
121
|
+
|
122
|
+
subject.purchase('UUID', 1, 1)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'accepts currency and quantity values in the options' do
|
126
|
+
subject.expects(:query_options).with('UUID', item: 1.to_s, cost: 1.to_f, currency: 'EURO', quantity: 10)
|
127
|
+
|
128
|
+
subject.purchase('UUID', 1, 1, currency: 'EURO', quantity: 10)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#buy_in' do
|
133
|
+
it 'posts to the buy_in endpoint' do
|
134
|
+
http_middleware.expects(:post).with('buy_in', {}).returns(good_response)
|
135
|
+
|
136
|
+
subject.buy_in('UUID', 1, 'USD', 5, 'Gold Coins')
|
137
|
+
end
|
138
|
+
|
139
|
+
before { http_middleware.stubs(:post).returns(good_response) }
|
140
|
+
|
141
|
+
it 'defaults payment_provider to Default Payment Provider' do
|
142
|
+
subject.expects(:query_options).with('UUID', { cost: 1.to_f, local_currency: 'USD', reward_amount: 5.to_f,
|
143
|
+
reward_currency: 'Gold Coins' ,
|
144
|
+
payment_provider: 'Default Payment Provider',
|
145
|
+
swrve_payload: {}.to_json})
|
146
|
+
subject.buy_in('UUID', 1, 'USD', 5, 'Gold Coins')
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'accepts payment_provider and swrve_payload values in the options' do
|
150
|
+
subject.expects(:query_options).with('UUID', { cost: 1.to_f, local_currency: 'USD', reward_amount: 5.to_f,
|
151
|
+
reward_currency: 'Gold Coins' ,
|
152
|
+
payment_provider: 'PayPal',
|
153
|
+
swrve_payload: { payload: '' }.to_json})
|
154
|
+
|
155
|
+
subject.buy_in('UUID', 1, 'USD', 5, 'Gold Coins', payment_provider: 'PayPal', swrve_payload: {payload: nil})
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#currency_given' do
|
160
|
+
before { http_middleware.stubs(:post).returns(good_response) }
|
161
|
+
|
162
|
+
it 'validates the given_amount and the given_currency' do
|
163
|
+
subject.expects(:validate_amount).with(1, "USD").returns(good_response)
|
164
|
+
|
165
|
+
subject.currency_given('UUID', 1, 'USD')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'builds the correct query options' do
|
169
|
+
subject.expects(:fill_nil_values).with({}).returns({}.to_json)
|
170
|
+
subject.expects(:query_options).with('UUID', { given_currency: 'USD',
|
171
|
+
given_amount: 1,
|
172
|
+
swrve_payload: {}.to_json })
|
173
|
+
|
174
|
+
subject.currency_given('UUID', 1, 'USD')
|
175
|
+
end
|
176
|
+
|
177
|
+
before { subject.stubs(:query_options).returns({}) }
|
178
|
+
|
179
|
+
it 'posts to the correct url' do
|
180
|
+
http_middleware.expects(:post).with('currency_given', {}).returns(good_response)
|
181
|
+
|
182
|
+
subject.currency_given('UUID', 1, 'Gold Coins')
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe '#create_event' do
|
187
|
+
|
188
|
+
before { http_middleware.stubs(:post).returns(good_response) }
|
189
|
+
|
190
|
+
it 'builds the correct query options' do
|
191
|
+
subject.expects(:fill_nil_values).with({}).returns({}.to_json)
|
192
|
+
subject.expects(:query_options).with('UUID', {name: 'event_name', swrve_payload: {}.to_json})
|
193
|
+
|
194
|
+
subject.create_event('UUID', 'event_name')
|
195
|
+
end
|
196
|
+
|
197
|
+
before { subject.stubs(:query_options).returns({}) }
|
198
|
+
|
199
|
+
it 'posts to the correct url' do
|
200
|
+
http_middleware.expects(:post).with('event', {}).returns(good_response)
|
201
|
+
|
202
|
+
subject.create_event('UUID', 'event_name')
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'swrve/middleware/http'
|
3
|
+
module Swrve
|
4
|
+
module Api
|
5
|
+
describe Resources do
|
6
|
+
|
7
|
+
subject { Resources.new }
|
8
|
+
|
9
|
+
describe '.new' do
|
10
|
+
let(:config) { stub_everything('config', ab_test_url: 'http://ab_test_url', api_version: 1) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
Swrve.stubs(config: config)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'Creates a resources endpoint' do
|
17
|
+
Middleware::Http.expects(:new).with([config.ab_test_url, 'api', config.api_version].join('/'))
|
18
|
+
|
19
|
+
subject
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#get' do
|
24
|
+
let(:resources_endpoint) { mock('resources_endpoint') }
|
25
|
+
|
26
|
+
before { Middleware::Http.stubs(:new).returns(resources_endpoint) }
|
27
|
+
|
28
|
+
it 'delegates it to the resources endpoint' do
|
29
|
+
resources_endpoint.expects(:get)
|
30
|
+
|
31
|
+
subject.send(:get)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
require 'simplecov'
|
3
|
+
if ENV['TRAVIS']
|
4
|
+
Coveralls.wear!
|
5
|
+
else
|
6
|
+
SimpleCov.start
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rspec'
|
10
|
+
require 'mocha/setup'
|
11
|
+
GEM_ROOT = File.expand_path('../../', __FILE__)
|
12
|
+
$:.unshift File.join(GEM_ROOT, 'lib')
|
13
|
+
require 'swrve'
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.mock_framework = :mocha
|
17
|
+
end
|
18
|
+
|
data/spec/swrve_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Swrve do
|
4
|
+
|
5
|
+
subject { Swrve }
|
6
|
+
let(:event_sender) { mock('event_sender') }
|
7
|
+
let(:resource_getter) { mock('resource_getter') }
|
8
|
+
|
9
|
+
before do
|
10
|
+
Swrve::Api::Events.stubs(new: event_sender)
|
11
|
+
Swrve::Api::Resources.stubs(new: resource_getter)
|
12
|
+
Swrve.configure
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".config" do
|
16
|
+
it 'is a configuration' do
|
17
|
+
Swrve.config.should be_a(Swrve::Configuration)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'responds to required configurations' do
|
21
|
+
[:ab_test_url, :api_url, :web_app_version, :api_key, :local_resource_path, :game_id, :debug_url,
|
22
|
+
:load_local_resources, :debug, :http_adapter].map do |value|
|
23
|
+
Swrve.config.respond_to?(value)
|
24
|
+
end.uniq.should == [true]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '.configure' do
|
29
|
+
|
30
|
+
before { Swrve.configure { |config| config.web_app_version = '11' }}
|
31
|
+
|
32
|
+
it 'should be configurable' do
|
33
|
+
Swrve.config.web_app_version.should == '11'
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
it "has a version" do
|
39
|
+
Swrve::VERSION.should be_a(String)
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'methods_delegated to event_sender' do
|
43
|
+
let(:event_sender) { Swrve::Api::Events.new }
|
44
|
+
@delegated_events = [
|
45
|
+
:session_start, :session_end, :create_event,
|
46
|
+
:purchase, :buy_in, :currency_given, :update_user
|
47
|
+
]
|
48
|
+
|
49
|
+
@delegated_events.each do |event|
|
50
|
+
specify { subject.should respond_to(event) }
|
51
|
+
specify { event_sender.should respond_to(event) }
|
52
|
+
|
53
|
+
it "send the #{event} request to the resources endpoint" do
|
54
|
+
event_sender.expects(event)
|
55
|
+
|
56
|
+
subject.send(event)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'methods_delegated to resource_getter' do
|
63
|
+
let(:resource_getter) { Swrve::Api::Resources.new }
|
64
|
+
@delegated_events = [:resource, :resources_diff, :resources]
|
65
|
+
|
66
|
+
@delegated_events.each do |event|
|
67
|
+
specify { subject.should respond_to(event) }
|
68
|
+
specify { resource_getter.should respond_to(event) }
|
69
|
+
|
70
|
+
it "send the #{event} request to the resources endpoint" do
|
71
|
+
resource_getter.expects(event)
|
72
|
+
|
73
|
+
subject.send(event)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/swrve.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'swrve/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'swrve'
|
8
|
+
gem.version = Swrve::VERSION
|
9
|
+
gem.authors = ["John O'Gara"]
|
10
|
+
gem.email = ['johnogara@radiatorhead.com']
|
11
|
+
gem.description = %q{Simple Client for Swrve API}
|
12
|
+
gem.summary = %q{}
|
13
|
+
gem.homepage = 'https://github.com/johnogara/swrve'
|
14
|
+
|
15
|
+
gem.add_dependency 'faraday', ['~> 0.8', '< 0.10']
|
16
|
+
gem.add_dependency 'faraday_middleware', ['~> 0.8', '< 0.10']
|
17
|
+
gem.add_dependency 'multi_json', '~> 1.0'
|
18
|
+
|
19
|
+
gem.add_development_dependency 'bundler', '~> 1.3'
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec'
|
22
|
+
gem.add_development_dependency 'mocha'
|
23
|
+
gem.add_development_dependency 'guard'
|
24
|
+
gem.add_development_dependency 'guard-rspec'
|
25
|
+
gem.add_development_dependency 'guard-bundler'
|
26
|
+
gem.add_development_dependency 'guard-ctags-bundler'
|
27
|
+
gem.add_development_dependency 'yard'
|
28
|
+
gem.add_development_dependency 'redcarpet'
|
29
|
+
gem.add_development_dependency 'github-markup'
|
30
|
+
|
31
|
+
|
32
|
+
gem.files = `git ls-files`.split($/)
|
33
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
34
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
35
|
+
gem.require_paths = ['lib']
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: swrve
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- John O'Gara
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-07-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: faraday
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0.8'
|
22
|
+
- - <
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0.10'
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.8'
|
33
|
+
- - <
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0.10'
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: faraday_middleware
|
38
|
+
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0.8'
|
44
|
+
- - <
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.10'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.8'
|
55
|
+
- - <
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0.10'
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: multi_json
|
60
|
+
requirement: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '1.0'
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ~>
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '1.0'
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: bundler
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1.3'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
90
|
+
- !ruby/object:Gem::Dependency
|
91
|
+
name: rake
|
92
|
+
requirement: !ruby/object:Gem::Requirement
|
93
|
+
none: false
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
type: :development
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: rspec
|
108
|
+
requirement: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
type: :development
|
115
|
+
prerelease: false
|
116
|
+
version_requirements: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
- !ruby/object:Gem::Dependency
|
123
|
+
name: mocha
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: guard
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: guard-rspec
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
type: :development
|
163
|
+
prerelease: false
|
164
|
+
version_requirements: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
166
|
+
requirements:
|
167
|
+
- - ! '>='
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
- !ruby/object:Gem::Dependency
|
171
|
+
name: guard-bundler
|
172
|
+
requirement: !ruby/object:Gem::Requirement
|
173
|
+
none: false
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
type: :development
|
179
|
+
prerelease: false
|
180
|
+
version_requirements: !ruby/object:Gem::Requirement
|
181
|
+
none: false
|
182
|
+
requirements:
|
183
|
+
- - ! '>='
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
- !ruby/object:Gem::Dependency
|
187
|
+
name: guard-ctags-bundler
|
188
|
+
requirement: !ruby/object:Gem::Requirement
|
189
|
+
none: false
|
190
|
+
requirements:
|
191
|
+
- - ! '>='
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '0'
|
194
|
+
type: :development
|
195
|
+
prerelease: false
|
196
|
+
version_requirements: !ruby/object:Gem::Requirement
|
197
|
+
none: false
|
198
|
+
requirements:
|
199
|
+
- - ! '>='
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '0'
|
202
|
+
- !ruby/object:Gem::Dependency
|
203
|
+
name: yard
|
204
|
+
requirement: !ruby/object:Gem::Requirement
|
205
|
+
none: false
|
206
|
+
requirements:
|
207
|
+
- - ! '>='
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
210
|
+
type: :development
|
211
|
+
prerelease: false
|
212
|
+
version_requirements: !ruby/object:Gem::Requirement
|
213
|
+
none: false
|
214
|
+
requirements:
|
215
|
+
- - ! '>='
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '0'
|
218
|
+
- !ruby/object:Gem::Dependency
|
219
|
+
name: redcarpet
|
220
|
+
requirement: !ruby/object:Gem::Requirement
|
221
|
+
none: false
|
222
|
+
requirements:
|
223
|
+
- - ! '>='
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: '0'
|
226
|
+
type: :development
|
227
|
+
prerelease: false
|
228
|
+
version_requirements: !ruby/object:Gem::Requirement
|
229
|
+
none: false
|
230
|
+
requirements:
|
231
|
+
- - ! '>='
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: '0'
|
234
|
+
- !ruby/object:Gem::Dependency
|
235
|
+
name: github-markup
|
236
|
+
requirement: !ruby/object:Gem::Requirement
|
237
|
+
none: false
|
238
|
+
requirements:
|
239
|
+
- - ! '>='
|
240
|
+
- !ruby/object:Gem::Version
|
241
|
+
version: '0'
|
242
|
+
type: :development
|
243
|
+
prerelease: false
|
244
|
+
version_requirements: !ruby/object:Gem::Requirement
|
245
|
+
none: false
|
246
|
+
requirements:
|
247
|
+
- - ! '>='
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
250
|
+
description: Simple Client for Swrve API
|
251
|
+
email:
|
252
|
+
- johnogara@radiatorhead.com
|
253
|
+
executables: []
|
254
|
+
extensions: []
|
255
|
+
extra_rdoc_files: []
|
256
|
+
files:
|
257
|
+
- .gitignore
|
258
|
+
- .travis.yml
|
259
|
+
- Gemfile
|
260
|
+
- Guardfile
|
261
|
+
- LICENSE.txt
|
262
|
+
- README.md
|
263
|
+
- Rakefile
|
264
|
+
- lib/swrve.rb
|
265
|
+
- lib/swrve/api/events.rb
|
266
|
+
- lib/swrve/api/resources.rb
|
267
|
+
- lib/swrve/configuration.rb
|
268
|
+
- lib/swrve/errors.rb
|
269
|
+
- lib/swrve/middleware/http.rb
|
270
|
+
- lib/swrve/version.rb
|
271
|
+
- spec/api/events_spec.rb
|
272
|
+
- spec/api/resources_spec.rb
|
273
|
+
- spec/configuration_spec.rb
|
274
|
+
- spec/middleware/http_spec.rb
|
275
|
+
- spec/spec_helper.rb
|
276
|
+
- spec/swrve_spec.rb
|
277
|
+
- swrve.gemspec
|
278
|
+
homepage: https://github.com/johnogara/swrve
|
279
|
+
licenses: []
|
280
|
+
post_install_message:
|
281
|
+
rdoc_options: []
|
282
|
+
require_paths:
|
283
|
+
- lib
|
284
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
285
|
+
none: false
|
286
|
+
requirements:
|
287
|
+
- - ! '>='
|
288
|
+
- !ruby/object:Gem::Version
|
289
|
+
version: '0'
|
290
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
291
|
+
none: false
|
292
|
+
requirements:
|
293
|
+
- - ! '>='
|
294
|
+
- !ruby/object:Gem::Version
|
295
|
+
version: '0'
|
296
|
+
requirements: []
|
297
|
+
rubyforge_project:
|
298
|
+
rubygems_version: 1.8.23
|
299
|
+
signing_key:
|
300
|
+
specification_version: 3
|
301
|
+
summary: ''
|
302
|
+
test_files:
|
303
|
+
- spec/api/events_spec.rb
|
304
|
+
- spec/api/resources_spec.rb
|
305
|
+
- spec/configuration_spec.rb
|
306
|
+
- spec/middleware/http_spec.rb
|
307
|
+
- spec/spec_helper.rb
|
308
|
+
- spec/swrve_spec.rb
|
309
|
+
has_rdoc:
|