checkdin 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/checkdin/activities.rb +1 -0
- data/lib/checkdin/leaderboard.rb +11 -0
- data/lib/checkdin/user_bridge.rb +24 -9
- data/lib/checkdin/users.rb +13 -2
- data/lib/checkdin/version.rb +1 -1
- data/spec/checkdin/leaderboard_spec.rb +10 -0
- data/spec/checkdin/user_bridge_spec.rb +25 -12
- data/spec/fixtures/vcr_cassettes/Checkdin_Leaderboard/viewing_a_leaderboard_for_a_campaign_s_classifications.yml +46 -0
- metadata +2 -1
data/Gemfile.lock
CHANGED
data/lib/checkdin/activities.rb
CHANGED
@@ -14,6 +14,7 @@ module Checkdin
|
|
14
14
|
#
|
15
15
|
# @param [Hash] options
|
16
16
|
# @option options Integer :campaign_id - Only return won rewards for this campaign.
|
17
|
+
# @option options String :classification - Only return activities for users in this classification.
|
17
18
|
# @option options Integer :user_id - Only return won rewards for this user.
|
18
19
|
# @option options Integer :since - Only fetch updates since this time (UNIX timestamp)
|
19
20
|
# @option options Integer :limit - The maximum number of records to return.
|
data/lib/checkdin/leaderboard.rb
CHANGED
@@ -14,5 +14,16 @@ module Checkdin
|
|
14
14
|
return_error_or_body(response)
|
15
15
|
end
|
16
16
|
|
17
|
+
# Get the classification leaderboard for a given campaign
|
18
|
+
#
|
19
|
+
# param [Integer] campaign_id The ID of the campaign to fetch the leaderboard for.
|
20
|
+
|
21
|
+
def classification_leaderboard(campaign_id)
|
22
|
+
response = connection.get do |req|
|
23
|
+
req.url "campaigns/#{campaign_id}/classification_leaderboard"
|
24
|
+
end
|
25
|
+
return_error_or_body(response)
|
26
|
+
end
|
27
|
+
|
17
28
|
end
|
18
29
|
end
|
data/lib/checkdin/user_bridge.rb
CHANGED
@@ -30,7 +30,6 @@ module Checkdin
|
|
30
30
|
|
31
31
|
@checkdin_landing_url = options.delete(:checkdin_landing_url) || CHECKDIN_DEFAULT_LANDING
|
32
32
|
|
33
|
-
raise ArgumentError.new("Unknown arguments given: #{options.keys.inspect}") unless options.empty?
|
34
33
|
end
|
35
34
|
|
36
35
|
# Public: Build a full signed url for logging a specific user into checkd.in. Notice:
|
@@ -42,15 +41,25 @@ module Checkdin
|
|
42
41
|
# user_identifier - REQUIRED, your unique identifier for the user, MUST NOT change over time.
|
43
42
|
# authentication_action - OPTIONAL, the given action will be performed immediately,
|
44
43
|
# and the user redirected back to your site afterwards.
|
44
|
+
# referral_token - OPTIONAL, the referral token of the user that referred the user being created.
|
45
|
+
# first_name - OPTIONAL
|
46
|
+
# last_name - OPTIONAL
|
47
|
+
# gender - OPTIONAL, format of male or female
|
48
|
+
# birth_date - OPTIONAL, YYYY-MM-DD format
|
49
|
+
# username - OPTIONAL
|
50
|
+
# mobile_number - OPTIONAL, XXXYYYZZZZ format
|
51
|
+
# postal_code_text - OPTIONAL, XXXXX format
|
52
|
+
# classification - OPTIONAL, the internal group or classification a user belongs to
|
53
|
+
# delivery_email - OPTIONAL, whether a user should receive email notifications
|
54
|
+
# delivery_sms - OPTIONAL, whether a user should receive sms notifications
|
45
55
|
#
|
46
56
|
# Returns a URL you can use for redirecting a user. Notice this will expire, so it should
|
47
57
|
# be generated and used only when a user actually wants to log into checkd.in.
|
48
58
|
def login_url options
|
49
59
|
email = options.delete(:email) or raise ArgumentError.new("No :email passed for user")
|
50
60
|
user_identifier = options.delete(:user_identifier) or raise ArgumentError.new("No :user_identifier passed for user")
|
51
|
-
authentication_action = options.delete(:authentication_action)
|
52
61
|
|
53
|
-
authenticated_parameters = build_authenticated_parameters(email, user_identifier,
|
62
|
+
authenticated_parameters = build_authenticated_parameters(email, user_identifier, options)
|
54
63
|
|
55
64
|
[checkdin_landing_url, authenticated_parameters.to_query].join
|
56
65
|
end
|
@@ -58,22 +67,22 @@ module Checkdin
|
|
58
67
|
# Private: Build a signed hash of parameters for redirecting the user to checkd.in.
|
59
68
|
#
|
60
69
|
# Returns a hash including a secure message digest and the current timestamp
|
61
|
-
def build_authenticated_parameters email, user_identifier,
|
62
|
-
build_request(email, user_identifier,
|
70
|
+
def build_authenticated_parameters email, user_identifier, options
|
71
|
+
build_request(email, user_identifier, options).tap do |request|
|
63
72
|
request['digest'] = digest_request(request)
|
64
73
|
end
|
65
74
|
end
|
66
75
|
|
67
76
|
private
|
68
|
-
def build_request email, user_identifier,
|
77
|
+
def build_request email, user_identifier, options
|
78
|
+
stringified_options = stringify_keys(options)
|
79
|
+
|
69
80
|
{
|
70
81
|
'auth_timestamp' => Time.now.to_i,
|
71
82
|
'client_id' => client_identifier,
|
72
83
|
'client_uid' => user_identifier,
|
73
84
|
'email' => email,
|
74
|
-
}.
|
75
|
-
request['authentication_action'] = authentication_action if authentication_action
|
76
|
-
end
|
85
|
+
}.merge(stringified_options)
|
77
86
|
end
|
78
87
|
|
79
88
|
def digest_request request
|
@@ -81,5 +90,11 @@ module Checkdin
|
|
81
90
|
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, bridge_secret, encoded_request)
|
82
91
|
end
|
83
92
|
|
93
|
+
def stringify_keys hash
|
94
|
+
hash.inject({}) do |options, (key, value)|
|
95
|
+
options[key.to_s] = value
|
96
|
+
options
|
97
|
+
end
|
98
|
+
end
|
84
99
|
end
|
85
100
|
end
|
data/lib/checkdin/users.rb
CHANGED
@@ -34,8 +34,19 @@ module Checkdin
|
|
34
34
|
# Create a user in the checkd.in system tied to the authenticating client.
|
35
35
|
#
|
36
36
|
# @param [Hash] options
|
37
|
-
# @option options String :identifier
|
38
|
-
# @option options String :email
|
37
|
+
# @option options String :identifier - REQUIRED, The authenticating client's internal identifier for this user.
|
38
|
+
# @option options String :email - REQUIRED, A valid email for the user
|
39
|
+
# @option options String :referral_token - OPTIONAL, the referral token of the user that referred the user being created.
|
40
|
+
# @option options String :first_name - OPTIONAL
|
41
|
+
# @option options String :last_name - OPTIONAL
|
42
|
+
# @option options String :gender - OPTIONAL, format of male or female
|
43
|
+
# @option options String :birth_date - OPTIONAL, YYYY-MM-DD format
|
44
|
+
# @option options String :username - OPTIONAL
|
45
|
+
# @option options String :mobile_number - OPTIONAL, XXXYYYZZZZ format
|
46
|
+
# @option options String :postal_code_text - OPTIONAL, XXXXX format
|
47
|
+
# @option options String :classification - OPTIONAL, the internal group or classification a user belongs to
|
48
|
+
# @option options String :delivery_email - OPTIONAL, whether a user should receive email notifications
|
49
|
+
# @option options String :delivery_sms - OPTIONAL, whether a user should receive sms notifications
|
39
50
|
|
40
51
|
def create_user(options={})
|
41
52
|
response = connection.post do |req|
|
data/lib/checkdin/version.rb
CHANGED
@@ -15,4 +15,14 @@ describe Checkdin::Leaderboard do
|
|
15
15
|
result.leaders.count.should == 5
|
16
16
|
end
|
17
17
|
end
|
18
|
+
|
19
|
+
context "viewing a leaderboard for a campaign's classifications" do
|
20
|
+
use_vcr_cassette
|
21
|
+
let(:result) { @client.classification_leaderboard(35) }
|
22
|
+
|
23
|
+
it "should provide a list of classifications" do
|
24
|
+
result.classifications.first.classification.should == "grouped"
|
25
|
+
result.classifications.first.total_points.should == 10
|
26
|
+
end
|
27
|
+
end
|
18
28
|
end
|
@@ -24,10 +24,10 @@ describe Checkdin::UserBridge, 'constructor' do
|
|
24
24
|
instance.checkdin_landing_url.should == landing_url
|
25
25
|
end
|
26
26
|
|
27
|
-
it "
|
27
|
+
it "does not raise an error on unknown arguments" do
|
28
28
|
expect do
|
29
29
|
Checkdin::UserBridge.new(default_options.merge(:misspelled_option => 'error me'))
|
30
|
-
end.
|
30
|
+
end.to_not raise_error(ArgumentError, /misspelled_option/)
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -35,14 +35,16 @@ describe Checkdin::UserBridge, '#login_url' do
|
|
35
35
|
let(:instance) { Checkdin::UserBridge.new(:client_identifier => client_identifier,
|
36
36
|
:bridge_secret => bridge_secret,
|
37
37
|
:checkdin_landing_url => checkdin_landing_url) }
|
38
|
-
subject { instance.login_url(
|
39
|
-
|
40
|
-
|
38
|
+
subject { instance.login_url(options) }
|
39
|
+
let(:options) { default_options }
|
40
|
+
let(:default_options) {{
|
41
|
+
:email => user_email,
|
42
|
+
:user_identifier => user_identifier
|
43
|
+
}}
|
41
44
|
let(:client_identifier) { 'client-1704' }
|
42
45
|
let(:bridge_secret) { '123-shared-secret' }
|
43
46
|
let(:user_email) { 'bob@example.com' }
|
44
47
|
let(:user_identifier) { '17-batch1-bob' }
|
45
|
-
let(:authentication_action) { nil }
|
46
48
|
let(:checkdin_landing_url) { nil }
|
47
49
|
let(:timestamp) { 1325605589 }
|
48
50
|
|
@@ -64,7 +66,7 @@ describe Checkdin::UserBridge, '#login_url' do
|
|
64
66
|
end
|
65
67
|
|
66
68
|
context "with an optional action set" do
|
67
|
-
let(:
|
69
|
+
let(:options) { default_options.merge(:authentication_action => 'authenticate_facebook') }
|
68
70
|
|
69
71
|
it "includes the authentication_action" do
|
70
72
|
Timecop.freeze(Time.at(timestamp)) do
|
@@ -72,6 +74,16 @@ describe Checkdin::UserBridge, '#login_url' do
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
end
|
77
|
+
|
78
|
+
context "with additional attributes set" do
|
79
|
+
let(:options) { default_options.merge(:delivery_email => false) }
|
80
|
+
|
81
|
+
it "includes the additional attriubtes" do
|
82
|
+
Timecop.freeze(Time.at(timestamp)) do
|
83
|
+
subject.should == "https://app.checkd.in/user_landing?auth_timestamp=1325605589&client_id=client-1704&client_uid=17-batch1-bob&delivery_email=false&digest=f3950bee05fb1ca97727d9c190f2b30cfbdcf74a7150b3c337afbfc557d988dc&email=bob%40example.com"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
75
87
|
end
|
76
88
|
|
77
89
|
context "custom subdomain" do
|
@@ -95,7 +107,8 @@ end
|
|
95
107
|
|
96
108
|
describe Checkdin::UserBridge, '#build_authenticated_parameters' do
|
97
109
|
let(:instance) { Checkdin::UserBridge.new(:client_identifier => client_identifier, :bridge_secret => bridge_secret) }
|
98
|
-
subject { instance.build_authenticated_parameters(user_email, user_identifier) }
|
110
|
+
subject { instance.build_authenticated_parameters(user_email, user_identifier, options) }
|
111
|
+
let(:options) { {} }
|
99
112
|
let(:client_identifier) { 'client-1704' }
|
100
113
|
let(:bridge_secret) { '123-shared-secret' }
|
101
114
|
let(:user_email) { 'bob@example.com' }
|
@@ -114,15 +127,15 @@ describe Checkdin::UserBridge, '#build_authenticated_parameters' do
|
|
114
127
|
end
|
115
128
|
end
|
116
129
|
|
117
|
-
context "with an authenticated action" do
|
118
|
-
subject { instance.build_authenticated_parameters(user_email, user_identifier,
|
119
|
-
let(:
|
130
|
+
context "with an authenticated action in the options" do
|
131
|
+
subject { instance.build_authenticated_parameters(user_email, user_identifier, options) }
|
132
|
+
let(:options) { {:authentication_action => 'authenticate_facebook'} }
|
120
133
|
|
121
134
|
it "should output a hash with a different digest and the authenticated_action included" do
|
122
135
|
Timecop.freeze(Time.at(timestamp)) do
|
123
136
|
subject.should == {
|
124
137
|
'auth_timestamp' => timestamp,
|
125
|
-
'authentication_action' =>
|
138
|
+
'authentication_action' => 'authenticate_facebook',
|
126
139
|
'client_id' => client_identifier,
|
127
140
|
'client_uid' => user_identifier,
|
128
141
|
'email' => user_email,
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
- !ruby/struct:VCR::HTTPInteraction
|
3
|
+
request: !ruby/struct:VCR::Request
|
4
|
+
method: :get
|
5
|
+
uri: https://staging:cKGdyvb4gQD9YJg3cACV@staging.checkd.in:443/api/v1/campaigns/35/classification_leaderboard?client_id={client_id}&client_secret={client_secret}
|
6
|
+
body:
|
7
|
+
headers:
|
8
|
+
accept:
|
9
|
+
- application/json
|
10
|
+
user-agent:
|
11
|
+
- checkdin ruby gem 0.2.7
|
12
|
+
accept-encoding:
|
13
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
14
|
+
response: !ruby/struct:VCR::Response
|
15
|
+
status: !ruby/struct:VCR::ResponseStatus
|
16
|
+
code: 200
|
17
|
+
message: OK
|
18
|
+
headers:
|
19
|
+
server:
|
20
|
+
- nginx/1.0.11
|
21
|
+
date:
|
22
|
+
- Thu, 16 Aug 2012 14:06:50 GMT
|
23
|
+
content-type:
|
24
|
+
- application/json; charset=utf-8
|
25
|
+
transfer-encoding:
|
26
|
+
- chunked
|
27
|
+
connection:
|
28
|
+
- keep-alive
|
29
|
+
status:
|
30
|
+
- 200 OK
|
31
|
+
strict-transport-security:
|
32
|
+
- max-age=31536000
|
33
|
+
x-ua-compatible:
|
34
|
+
- IE=Edge,chrome=1
|
35
|
+
etag:
|
36
|
+
- "\"0016a5775b88d5dbd81551ebc2148c1b\""
|
37
|
+
cache-control:
|
38
|
+
- must-revalidate, private, max-age=0
|
39
|
+
x-request-id:
|
40
|
+
- 707edb8903bd34be9db20d17dc393e6d
|
41
|
+
x-runtime:
|
42
|
+
- "0.159060"
|
43
|
+
x-rack-cache:
|
44
|
+
- miss
|
45
|
+
body: "{\"classifications\":[{\"classification\":\"grouped\",\"total_points\":10,\"members\":1}]}"
|
46
|
+
http_version: "1.1"
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: checkdin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.2.
|
5
|
+
version: 0.2.8
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Matt Mueller
|
@@ -183,6 +183,7 @@ files:
|
|
183
183
|
- spec/fixtures/vcr_cassettes/Checkdin_Campaigns/viewing_a_single_campaign.yml
|
184
184
|
- spec/fixtures/vcr_cassettes/Checkdin_CustomActivities.yml
|
185
185
|
- spec/fixtures/vcr_cassettes/Checkdin_Leaderboard/viewing_a_leaderboard_for_a_campaign.yml
|
186
|
+
- spec/fixtures/vcr_cassettes/Checkdin_Leaderboard/viewing_a_leaderboard_for_a_campaign_s_classifications.yml
|
186
187
|
- spec/fixtures/vcr_cassettes/Checkdin_Promotions/viewing_a_list_of_promotions.yml
|
187
188
|
- spec/fixtures/vcr_cassettes/Checkdin_Promotions/viewing_a_single_promotion.yml
|
188
189
|
- spec/fixtures/vcr_cassettes/Checkdin_Promotions/viewing_the_votes_leaderboard_for_a_promotion.yml
|