swrve 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Coverage Status](https://coveralls.io/repos/johnogara/swrve/badge.png?branch=master)](https://coveralls.io/r/johnogara/swrve?branch=master)
|
4
|
+
[![Build Status](https://travis-ci.org/jkogara/swrve.png)](https://travis-ci.org/jkogara/swrve)
|
5
|
+
[![Code Climate](https://codeclimate.com/repos/51eee7b989af7e75f4010537/badges/cbb3edf9ca15d0eb5df4/gpa.png)](https://codeclimate.com/repos/51eee7b989af7e75f4010537/feed)
|
6
|
+
[![Gem Version](https://badge.fury.io/rb/swrve.png)](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:
|