snowplow_ruby_duid 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 644cd8ffeb6e17e8da58f514c6fa34926853ca3a
4
+ data.tar.gz: 7ad6e70b709b0456f5ec0ffc68e3e33937747458
5
+ SHA512:
6
+ metadata.gz: b2cd6f5d17443d916be7017483cc0ba108c2001e7bdac60fd275ee81253a93b248e77f708274efada54926498a9e85bd9333773f5475b4f8fcc38685ea8a8ff9
7
+ data.tar.gz: bc8683b0a2b9946fcf335f54cd0971f788dffd248896eff99d2e8696023ec2ff39466dac36d017a3c913c703b98f7736368868ad9fb6829c4816b8246ade30ae
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ -r rutabaga
2
+ --order rand
3
+ --color
4
+ --require spec_helper
5
+ --format doc
data/Gemfile ADDED
@@ -0,0 +1,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in snowplow_ruby_duid.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry-plus'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rack'
12
+ gem 'rack-test'
13
+ gem 'rspec'
14
+ gem 'rutabaga'
15
+ gem 'timecop'
16
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ snowplow_ruby_duid (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ binding_of_caller (0.7.2)
10
+ debug_inspector (>= 0.0.1)
11
+ bond (0.5.1)
12
+ coderay (1.1.0)
13
+ columnize (0.9.0)
14
+ debug_inspector (0.0.2)
15
+ debugger (1.6.8)
16
+ columnize (>= 0.3.1)
17
+ debugger-linecache (~> 1.2.0)
18
+ debugger-ruby_core_source (~> 1.3.5)
19
+ debugger-linecache (1.2.0)
20
+ debugger-ruby_core_source (1.3.7)
21
+ diff-lcs (1.2.5)
22
+ gherkin (2.12.2)
23
+ multi_json (~> 1.3)
24
+ interception (0.5)
25
+ jist (1.5.1)
26
+ json
27
+ json (1.8.2)
28
+ method_source (0.8.2)
29
+ multi_json (1.10.1)
30
+ pry (0.10.1)
31
+ coderay (~> 1.1.0)
32
+ method_source (~> 0.8.1)
33
+ slop (~> 3.4)
34
+ pry-debugger (0.2.3)
35
+ debugger (~> 1.3)
36
+ pry (>= 0.9.10, < 0.11.0)
37
+ pry-doc (0.6.0)
38
+ pry (~> 0.9)
39
+ yard (~> 0.8)
40
+ pry-docmore (0.1.1)
41
+ pry
42
+ pry-doc
43
+ pry-plus (1.0.0)
44
+ bond
45
+ jist
46
+ pry-debugger
47
+ pry-doc
48
+ pry-docmore
49
+ pry-rescue
50
+ pry-stack_explorer
51
+ pry-rescue (1.4.1)
52
+ interception (>= 0.5)
53
+ pry
54
+ pry-stack_explorer (0.4.9.1)
55
+ binding_of_caller (>= 0.7)
56
+ pry (>= 0.9.11)
57
+ rack (1.6.0)
58
+ rack-test (0.6.2)
59
+ rack (>= 1.0)
60
+ rspec (3.1.0)
61
+ rspec-core (~> 3.1.0)
62
+ rspec-expectations (~> 3.1.0)
63
+ rspec-mocks (~> 3.1.0)
64
+ rspec-core (3.1.7)
65
+ rspec-support (~> 3.1.0)
66
+ rspec-expectations (3.1.2)
67
+ diff-lcs (>= 1.2.0, < 2.0)
68
+ rspec-support (~> 3.1.0)
69
+ rspec-mocks (3.1.3)
70
+ rspec-support (~> 3.1.0)
71
+ rspec-support (3.1.2)
72
+ rutabaga (0.1.1)
73
+ turnip (>= 1.1.0, < 2.0)
74
+ slop (3.6.0)
75
+ timecop (0.7.1)
76
+ turnip (1.2.4)
77
+ gherkin (>= 2.5)
78
+ rspec (>= 2.14.0, < 4.0)
79
+ yard (0.8.7.6)
80
+
81
+ PLATFORMS
82
+ ruby
83
+
84
+ DEPENDENCIES
85
+ pry-plus
86
+ rack
87
+ rack-test
88
+ rspec
89
+ rutabaga
90
+ snowplow_ruby_duid!
91
+ timecop
data/LICENSE.txt ADDED
@@ -0,0 +1,9 @@
1
+ Copyright (c) 2015 Simply Business
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Snowplow Ruby Domain UserId
2
+
3
+ A gem that exposes the Snowplow domain userid in Rack applications. Also allows you to set your own domain userid that will be shared with the Snowplow Javascript tracker. Related Snowplow Google Group discussion [here](https://groups.google.com/forum/#!topic/snowplow-user/GFfhW25UuN8).
4
+
5
+ ## Instructions
6
+
7
+ Add the gem to your Gemfile
8
+
9
+ ```ruby
10
+ gem 'snowplow_ruby_duid', git: 'git@github.com:simplybusiness/snowplow_ruby_duid'
11
+ ```
12
+
13
+ ### Rails
14
+
15
+ The helper will be included in `ActionController::Base` when the gem is loaded.
16
+
17
+ ### Sinatra
18
+
19
+ Add the following to `Sinatra::Base`
20
+
21
+ ```ruby
22
+ require 'snowplow_ruby_duid'
23
+ helpers SnowplowRubyDuid::Helper
24
+ ```
25
+
26
+ ### Usage
27
+
28
+ A method called `snowplow_domain_userid` will be exposed in your application's context. Calling this method results in the following behaviour:
29
+
30
+ - If there is already a Snowplow domain userid in the request's cookie, the value of the id will be returned.
31
+ - Else, a Snowplow domain userid will be generated and persisted in the response's cookie. This domain userid will continue to be used by the Snowplow Javascript tracker on the client side.
32
+
33
+ ## Running the specs and features
34
+
35
+ Use this command to run the specs and features: `bundle exec rspec`
@@ -0,0 +1,10 @@
1
+ require 'digest/sha1'
2
+ require 'snowplow_ruby_duid/cookie'
3
+ require 'snowplow_ruby_duid/domain_userid'
4
+ require 'snowplow_ruby_duid/helper'
5
+
6
+ module SnowplowRubyDuid
7
+ KEY_PREFIX = '_sp_id'
8
+ end
9
+
10
+ ActionController::Base.send :include, SnowplowRubyDuid::Helper if defined?(ActionController)
@@ -0,0 +1,58 @@
1
+ module SnowplowRubyDuid
2
+ # Responsible for generating a cookie that emulates the Snowplow cookie as closely as possible
3
+ # Leverages the method used by ActionDispatch::Cookies::CookieJar to determine the top-level domain
4
+ class Cookie
5
+
6
+ # See: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L142
7
+ COOKIE_PATH = '/'
8
+ # See: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L156
9
+ COOKIE_DURATION_MONTHS = 24
10
+ # See: https://github.com/rails/rails/blob/b1124a2ac88778c0feb0157ac09367cbd204bf01/actionpack/lib/action_dispatch/middleware/cookies.rb#L214
11
+ DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
12
+
13
+ def initialize host, domain_userid, request_created_at
14
+ @host = host
15
+ @domain_userid = domain_userid
16
+ @request_created_at = request_created_at
17
+ end
18
+
19
+ # See: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L358-L360
20
+ # See: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L372-L374
21
+ def key
22
+ domain = top_level_domain || @host
23
+ KEY_PREFIX + '.' + (Digest::SHA1.hexdigest (domain + COOKIE_PATH))[0..3]
24
+ end
25
+
26
+ def value
27
+ cookie_domain = ".#{top_level_domain}" unless top_level_domain.nil?
28
+ {
29
+ value: cookie_value,
30
+ expires: cookie_expiration,
31
+ domain: cookie_domain,
32
+ path: COOKIE_PATH,
33
+ }
34
+ end
35
+
36
+ private
37
+
38
+ # See: https://github.com/rails/rails/blob/b1124a2ac88778c0feb0157ac09367cbd204bf01/actionpack/lib/action_dispatch/middleware/cookies.rb#L286-L294
39
+ def top_level_domain
40
+ if (@host !~ /^[\d.]+$/) && (@host =~ DOMAIN_REGEXP)
41
+ $&
42
+ end
43
+ end
44
+
45
+ # See: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L476-L487
46
+ def cookie_value
47
+ visitCount = '0'
48
+ lastVisitTs = ''
49
+ createTs = nowTs = @request_created_at.to_i.to_s
50
+ [@domain_userid, createTs, visitCount, nowTs, lastVisitTs].join '.'
51
+ end
52
+
53
+ def cookie_expiration
54
+ expiration_date = @request_created_at.to_datetime >> COOKIE_DURATION_MONTHS
55
+ expiration_date.to_time
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,23 @@
1
+ module SnowplowRubyDuid
2
+ # Generates a pseudo-unique ID to fingerprint the user
3
+ # Deviates from this Snowplow Javascript: https://github.com/snowplow/snowplow-javascript-tracker/blob/d3d10067127eb5c95d0054c8ae60f3bdccba619d/src/js/tracker.js#L468-L472
4
+ # in order to provide a more unique identifier
5
+ class DomainUserid
6
+
7
+ LENGTH_OF_DUID_IN_BYTES = 8
8
+
9
+ def initialize
10
+ @domain_user_id = domain_user_id
11
+ end
12
+
13
+ def to_s
14
+ @domain_user_id
15
+ end
16
+
17
+ private
18
+
19
+ def domain_user_id
20
+ SecureRandom.hex LENGTH_OF_DUID_IN_BYTES
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ module SnowplowRubyDuid
2
+ # Exposes a snowplow_domain_userid method in the context
3
+ # that will find or create a domain_userid, which will be
4
+ # saved in the response's cookie if it does not exist
5
+ module Helper
6
+
7
+ def snowplow_domain_userid
8
+ @snowplow_domain_userid ||= find_or_create_snowplow_domain_userid
9
+ end
10
+
11
+ def find_or_create_snowplow_domain_userid
12
+ find_snowplow_domain_userid || create_snowplow_domain_userid
13
+ end
14
+ private :find_or_create_snowplow_domain_userid
15
+
16
+ def create_snowplow_domain_userid
17
+ request_created_at = Time.now
18
+ domain_userid = DomainUserid.new.to_s
19
+ snowplow_cookie = Cookie.new request.host, domain_userid, request_created_at
20
+
21
+ response.set_cookie snowplow_cookie.key, snowplow_cookie.value
22
+ domain_userid
23
+ end
24
+ private :create_snowplow_domain_userid
25
+
26
+ # See: https://github.com/snowplow/snowplow/wiki/Ruby-Tracker#310-setting-the-domain-user-id-with-set_domain_user_id
27
+ def find_snowplow_domain_userid
28
+ snowplow_cookie = find_snowplow_cookie
29
+ # The cookie value is in this format: domainUserId.createTs.visitCount.nowTs.lastVisitTs
30
+ snowplow_cookie.last.split('.').first unless snowplow_cookie.nil?
31
+ end
32
+ private :find_snowplow_domain_userid
33
+
34
+ def find_snowplow_cookie
35
+ request.cookies.find { |(key, value)| key =~ /^#{KEY_PREFIX}/ } # result will be an array containing: [key, value]
36
+ end
37
+ private :find_snowplow_cookie
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module SnowplowRubyDuid
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'snowplow_ruby_duid/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'snowplow_ruby_duid'
8
+ spec.version = SnowplowRubyDuid::VERSION
9
+ spec.authors = ['Simply Business']
10
+ spec.email = ['tech@simplybusiness.co.uk']
11
+ spec.description = %q{A gem that exposes the Snowplow domain userid in Rack applications. Also allows you to set your own domain userid that will be shared with the Snowplow Javascript tracker.}
12
+ spec.summary = %q{A gem that exposes the Snowplow domain userid in Rack applications. Also allows you to set your own domain userid that will be shared with the Snowplow Javascript tracker.}
13
+ spec.homepage = 'https://github.com/simplybusiness/snowplow_ruby_duid'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+ end
@@ -0,0 +1,53 @@
1
+ Feature: Creating a Snowplow cookie
2
+
3
+ Background:
4
+ Given the host is 'www.simplybusiness.co.uk'
5
+ And the domain_userid is 'domain_user_id'
6
+ And the time is '2015-01-22 15:26:31 +0000'
7
+
8
+ Scenario: The cookie should apply to the root path (/)
9
+ When I create a Snowplow cookie
10
+ Then the cookie has the path '/'
11
+
12
+ Scenario Outline: The cookie should apply for all domains under the top-level domain (no domain for localhost or IP addresses, however)
13
+ Given the host is '<host>'
14
+ When I create a Snowplow cookie
15
+ Then the cookie has the domain '<cookie domain>'
16
+
17
+ Examples:
18
+ | host | cookie domain |
19
+ | localhost | |
20
+ | 127.0.0.1 | |
21
+ | 192.168.2.40 | |
22
+ | www.simplybusiness.co.uk | .simplybusiness.co.uk |
23
+ | www.quote.simplybusiness.co.uk | .simplybusiness.co.uk |
24
+ | simplybusiness.co.uk | .simplybusiness.co.uk |
25
+ | www.simplybusiness.com | .simplybusiness.com |
26
+
27
+ Scenario Outline: The cookie should be named using the _sp_id prefix, followed by a 4 character hash generated from the top-level domain and root path
28
+ Given the host is '<host>'
29
+ When I create a Snowplow cookie
30
+ Then the cookie has the name '<cookie name>'
31
+
32
+ Examples:
33
+ | host | cookie name |
34
+ | localhost | _sp_id.1fff |
35
+ | 127.0.0.1 | _sp_id.dc78 |
36
+ | 192.168.2.40 | _sp_id.f0ae |
37
+ | www.simplybusiness.co.uk | _sp_id.8fb9 |
38
+ | www.quote.simplybusiness.co.uk | _sp_id.8fb9 |
39
+ | simplybusiness.co.uk | _sp_id.8fb9 |
40
+ | www.simplybusiness.com | _sp_id.bdbc |
41
+
42
+ Scenario: The cookie should expire after 2 years
43
+ When I create a Snowplow cookie
44
+ Then the cookie expires at '2017-01-22 15:26:31 +0000'
45
+
46
+ Scenario: The cookie's value should be in the following format: domain_userid.createTs.visitCount.nowTs.lastVisitTs
47
+ When I create a Snowplow cookie
48
+ Then the cookie value is 'domain_user_id.1421940391.0.1421940391.'
49
+ And the cookie value for 'domain_userid' is 'domain_user_id'
50
+ And the cookie value for 'createTs' is '1421940391'
51
+ And the cookie value for 'visitCount' is '0'
52
+ And the cookie value for 'nowTs' is '1421940391'
53
+ And the cookie value for 'lastVisitTs' is ''
@@ -0,0 +1,95 @@
1
+ module SnowplowRubyDuid
2
+ describe Cookie do
3
+ before do
4
+ @host = 'www.simplybusiness.co.uk'
5
+ @domain_userid = 'domain_user_id'
6
+ @request_created_at = (DateTime.parse '2015-01-22 15:26:31 +0000').to_time
7
+ end
8
+
9
+ subject { described_class.new @host, @domain_userid, @request_created_at }
10
+
11
+ describe '#key' do
12
+
13
+ it 'generates the key' do
14
+ expect(subject.key).to eq('_sp_id.8fb9')
15
+ end
16
+ end
17
+
18
+ describe '#value' do
19
+
20
+ it 'generates a cookie' do
21
+ expect(subject.value).to eq(
22
+ {
23
+ domain: '.simplybusiness.co.uk',
24
+ expires: (DateTime.parse '2017-01-22 15:26:31 +0000').to_time,
25
+ path: '/',
26
+ value: 'domain_user_id.1421940391.0.1421940391.'
27
+ })
28
+ end
29
+ end
30
+
31
+ it 'runs the feature' do
32
+ feature
33
+ end
34
+
35
+ step 'the host is :host' do |host|
36
+ @host = host
37
+ end
38
+
39
+ step 'the domain_userid is :domain_userid' do |domain_userid|
40
+ @domain_userid = domain_userid
41
+ end
42
+
43
+ step 'the time is :time' do |time|
44
+ @request_created_at = (DateTime.parse time).to_time
45
+ end
46
+
47
+ step 'I create a Snowplow cookie' do; end
48
+
49
+ step 'the cookie has the path :path' do |path|
50
+ expect(subject.value[:path]).to eq(path)
51
+ end
52
+
53
+ step 'the cookie has the domain :domain' do |domain|
54
+ if domain == ''
55
+ expect(subject.value[:domain]).to be_nil
56
+ else
57
+ expect(subject.value[:domain]).to eq(domain)
58
+ end
59
+ end
60
+
61
+ step 'the cookie has the name :name' do |name|
62
+ expect(subject.key).to eq(name)
63
+ end
64
+
65
+ step 'the cookie expires at :time' do |time|
66
+ expect(subject.value[:expires].to_s).to eq(time)
67
+ end
68
+
69
+ step 'the cookie value is :value' do |value|
70
+ expect(subject.value[:value]).to eq(value)
71
+ end
72
+
73
+ step 'the cookie value for :field is :value' do |field, value|
74
+ value_index = case field
75
+ when 'domain_userid'
76
+ then 0
77
+ when 'createTs'
78
+ then 1
79
+ when 'visitCount'
80
+ then 2
81
+ when 'nowTs'
82
+ then 3
83
+ when 'lastVisitTs'
84
+ then 4
85
+ else
86
+ raise "unknown field name: #{field}"
87
+ end
88
+
89
+ value = nil if value == ''
90
+
91
+ values = subject.value[:value].split '.'
92
+ expect(values[value_index]).to eq(value)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,11 @@
1
+ module SnowplowRubyDuid
2
+ describe DomainUserid do
3
+ subject { described_class.new.to_s }
4
+
5
+ describe '#to_s' do
6
+ it 'generates the domain userid' do
7
+ expect(subject.length).to eq(16)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ Feature: Helper method for accessing and saving a Snowplow domain userid
2
+
3
+ Scenario Outline: The helper will return the Snowplow domain userid from the cookie, if it is available. If it is not available, it will generate a domain userid and set it in the cookie.
4
+ Given I set a Snowplow domain userid of '<original domain userid in cookie>' in my cookie
5
+ When I request the Snowplow domain userid
6
+ Then I receive the Snowplow domain userid '<domain userid>'
7
+ And I have the Snowplow domain userid '<current domain userid in cookie>' in my cookie
8
+
9
+ Examples:
10
+ | original domain userid in cookie | domain userid | current domain userid in cookie |
11
+ | 1111111111111111 | 1111111111111111 | 1111111111111111 |
12
+ | | 2222222222222222 | 2222222222222222 |
@@ -0,0 +1,81 @@
1
+ require 'rack'
2
+ require 'rack/test'
3
+ require 'timecop'
4
+
5
+ module SnowplowRubyDuid
6
+ describe Helper do
7
+ include Rack::Test::Methods
8
+
9
+ describe 'snowplow_domain_userid' do
10
+ let(:app) { App.new }
11
+ before do
12
+ Timecop.freeze(Time.local(1990))
13
+ end
14
+ after do
15
+ Timecop.return
16
+ end
17
+ subject { last_response.header['Set-Cookie'] }
18
+
19
+ it 'runs the feature' do
20
+ feature
21
+ end
22
+
23
+ step 'I set a Snowplow domain userid of :domain_userid in my cookie' do |domain_userid|
24
+ set_cookie("_sp_id.3678=#{domain_userid}.631152000.0.631152000.631152000") unless domain_userid == ''
25
+ end
26
+
27
+ step 'I request the Snowplow domain userid' do
28
+ allow_any_instance_of(DomainUserid).to receive(:to_s).and_return('2222222222222222')
29
+ get '/'
30
+ end
31
+
32
+ step 'I receive the Snowplow domain userid :domain_userid' do |domain_userid|
33
+ expect(app.domain_userid).to eq(domain_userid)
34
+ end
35
+
36
+ step 'I have the Snowplow domain userid :domain_userid in my cookie' do |domain_userid|
37
+ expect(subject).to include(domain_userid)
38
+ end
39
+
40
+ context 'when there is an existing snowplow cookie' do
41
+ before do
42
+ set_cookie('_sp_id.3678=111111111111.631152000.0.631152000.631152000')
43
+ end
44
+
45
+ it 'retrieves the domain userid from the cookie' do
46
+ get '/'
47
+ expect(app.domain_userid).to eq('111111111111')
48
+ end
49
+
50
+ it 'does not modify the domain userid' do
51
+ get '/'
52
+ expect(subject).to include('111111111111')
53
+ end
54
+ end
55
+
56
+ context 'when there is not an existing snowplow cookie' do
57
+
58
+ it 'generates a domain userid and saves it in the response cookie' do
59
+ get '/'
60
+ expect(subject).to include(app.domain_userid)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ class App
68
+ include SnowplowRubyDuid::Helper
69
+
70
+ attr_reader :request, :response, :domain_userid
71
+
72
+ def call env
73
+ @request = Rack::Request.new env
74
+ @response = Rack::Response.new
75
+ request.cookies.each{|k,v| response.set_cookie k, v }
76
+
77
+ @domain_userid = snowplow_domain_userid
78
+
79
+ [response.status, response.header, response.body]
80
+ end
81
+ end
@@ -0,0 +1,92 @@
1
+ require 'time'
2
+ require 'snowplow_ruby_duid'
3
+
4
+ # This file was generated by the `rspec --init` command. Conventionally, all
5
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
6
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
7
+ # file to always be loaded, without a need to explicitly require it in any files.
8
+ #
9
+ # Given that it is always loaded, you are encouraged to keep this file as
10
+ # light-weight as possible. Requiring heavyweight dependencies from this file
11
+ # will add to the boot time of your test suite on EVERY test run, even for an
12
+ # individual file that may not need all of that loaded. Instead, consider making
13
+ # a separate helper file that requires the additional dependencies and performs
14
+ # the additional setup, and require it from the spec files that actually need it.
15
+ #
16
+ # The `.rspec` file also contains a few flags that are not defaults but that
17
+ # users commonly want.
18
+ #
19
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
20
+ RSpec.configure do |config|
21
+ # rspec-expectations config goes here. You can use an alternate
22
+ # assertion/expectation library such as wrong or the stdlib/minitest
23
+ # assertions if you prefer.
24
+ config.expect_with :rspec do |expectations|
25
+ # This option will default to `true` in RSpec 4. It makes the `description`
26
+ # and `failure_message` of custom matchers include text for helper methods
27
+ # defined using `chain`, e.g.:
28
+ # be_bigger_than(2).and_smaller_than(4).description
29
+ # # => "be bigger than 2 and smaller than 4"
30
+ # ...rather than:
31
+ # # => "be bigger than 2"
32
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
33
+ end
34
+
35
+ # rspec-mocks config goes here. You can use an alternate test double
36
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
37
+ config.mock_with :rspec do |mocks|
38
+ # Prevents you from mocking or stubbing a method that does not exist on
39
+ # a real object. This is generally recommended, and will default to
40
+ # `true` in RSpec 4.
41
+ mocks.verify_partial_doubles = true
42
+ end
43
+
44
+ # The settings below are suggested to provide a good initial experience
45
+ # with RSpec, but feel free to customize to your heart's content.
46
+ =begin
47
+ # These two settings work together to allow you to limit a spec run
48
+ # to individual examples or groups you care about by tagging them with
49
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
50
+ # get run.
51
+ config.filter_run :focus
52
+ config.run_all_when_everything_filtered = true
53
+
54
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
55
+ # For more details, see:
56
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
57
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
58
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
59
+ config.disable_monkey_patching!
60
+
61
+ # This setting enables warnings. It's recommended, but in some cases may
62
+ # be too noisy due to issues in dependencies.
63
+ config.warnings = true
64
+
65
+ # Many RSpec users commonly either run the entire suite or an individual
66
+ # file, and it's useful to allow more verbose output when running an
67
+ # individual spec file.
68
+ if config.files_to_run.one?
69
+ # Use the documentation formatter for detailed output,
70
+ # unless a formatter has already been configured
71
+ # (e.g. via a command-line flag).
72
+ config.default_formatter = 'doc'
73
+ end
74
+
75
+ # Print the 10 slowest examples and example groups at the
76
+ # end of the spec run, to help surface which specs are running
77
+ # particularly slow.
78
+ config.profile_examples = 10
79
+
80
+ # Run specs in random order to surface order dependencies. If you find an
81
+ # order dependency and want to debug it, you can fix the order by providing
82
+ # the seed, which is printed after each run.
83
+ # --seed 1234
84
+ config.order = :random
85
+
86
+ # Seed global randomization in this process using the `--seed` CLI option.
87
+ # Setting this allows you to use `--seed` to deterministically reproduce
88
+ # test failures related to randomization by passing the same `--seed` value
89
+ # as the one that triggered the failure.
90
+ Kernel.srand config.seed
91
+ =end
92
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snowplow_ruby_duid
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Simply Business
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem that exposes the Snowplow domain userid in Rack applications. Also
14
+ allows you to set your own domain userid that will be shared with the Snowplow Javascript
15
+ tracker.
16
+ email:
17
+ - tech@simplybusiness.co.uk
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - ".rspec"
23
+ - Gemfile
24
+ - Gemfile.lock
25
+ - LICENSE.txt
26
+ - README.md
27
+ - lib/snowplow_ruby_duid.rb
28
+ - lib/snowplow_ruby_duid/cookie.rb
29
+ - lib/snowplow_ruby_duid/domain_userid.rb
30
+ - lib/snowplow_ruby_duid/helper.rb
31
+ - lib/snowplow_ruby_duid/version.rb
32
+ - snowplow_ruby_duid.gemspec
33
+ - spec/lib/snowplow_ruby_duid/cookie.feature
34
+ - spec/lib/snowplow_ruby_duid/cookie_spec.rb
35
+ - spec/lib/snowplow_ruby_duid/domain_userid_spec.rb
36
+ - spec/lib/snowplow_ruby_duid/helper.feature
37
+ - spec/lib/snowplow_ruby_duid/helper_spec.rb
38
+ - spec/spec_helper.rb
39
+ homepage: https://github.com/simplybusiness/snowplow_ruby_duid
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.0.14
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: A gem that exposes the Snowplow domain userid in Rack applications. Also
63
+ allows you to set your own domain userid that will be shared with the Snowplow Javascript
64
+ tracker.
65
+ test_files:
66
+ - spec/lib/snowplow_ruby_duid/cookie.feature
67
+ - spec/lib/snowplow_ruby_duid/cookie_spec.rb
68
+ - spec/lib/snowplow_ruby_duid/domain_userid_spec.rb
69
+ - spec/lib/snowplow_ruby_duid/helper.feature
70
+ - spec/lib/snowplow_ruby_duid/helper_spec.rb
71
+ - spec/spec_helper.rb
72
+ has_rdoc: