devise_referable 0.1.0
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/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +81 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/app/controllers/referrals_controller.rb +12 -0
- data/app/models/referral.rb +38 -0
- data/devise_referable.gemspec +117 -0
- data/init.rb +1 -0
- data/lib/devise/hooks/referable.rb +13 -0
- data/lib/devise_referable/model.rb +47 -0
- data/lib/devise_referable/routes.rb +12 -0
- data/lib/devise_referable.rb +12 -0
- data/rails/init.rb +1 -0
- data/test/integration/referable_test.rb +59 -0
- data/test/integration_tests_helper.rb +35 -0
- data/test/model_tests_helper.rb +64 -0
- data/test/models/referral_test.rb +40 -0
- data/test/models_test.rb +31 -0
- data/test/rails_app/app/controllers/admins_controller.rb +6 -0
- data/test/rails_app/app/controllers/application_controller.rb +10 -0
- data/test/rails_app/app/controllers/home_controller.rb +4 -0
- data/test/rails_app/app/controllers/users_controller.rb +12 -0
- data/test/rails_app/app/helpers/application_helper.rb +3 -0
- data/test/rails_app/app/models/blog.rb +3 -0
- data/test/rails_app/app/models/user.rb +4 -0
- data/test/rails_app/app/views/home/index.html.erb +1 -0
- data/test/rails_app/config/boot.rb +110 -0
- data/test/rails_app/config/database.yml +22 -0
- data/test/rails_app/config/environment.rb +44 -0
- data/test/rails_app/config/environments/development.rb +17 -0
- data/test/rails_app/config/environments/production.rb +28 -0
- data/test/rails_app/config/environments/test.rb +28 -0
- data/test/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails_app/config/initializers/devise.rb +76 -0
- data/test/rails_app/config/initializers/inflections.rb +2 -0
- data/test/rails_app/config/initializers/new_rails_defaults.rb +21 -0
- data/test/rails_app/config/initializers/session_store.rb +15 -0
- data/test/rails_app/config/routes.rb +4 -0
- data/test/rails_app/vendor/plugins/devise_referable/init.rb +1 -0
- data/test/routes_test.rb +21 -0
- data/test/test_helper.rb +66 -0
- metadata +167 -0
data/.document
ADDED
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Matt Van Horn, derived from work done by Sergio Cambra
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
= devise_referable
|
2
|
+
|
3
|
+
It adds support to devise[http://github.com/plataformatec/devise] for tracking
|
4
|
+
users that were sent by referrers modeled as other classes in your app.
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
All gems are on gemcutter, so you need to add gemcutter to your sources if you haven’t yet:
|
9
|
+
|
10
|
+
sudo gem sources -a http://gemcutter.org/
|
11
|
+
|
12
|
+
Install devise_referable gem, it should install dependencies (such as devise and warden):
|
13
|
+
|
14
|
+
sudo gem install devise_referable
|
15
|
+
|
16
|
+
Configure devise_referable inside your app (and warden and devise if you weren't using them):
|
17
|
+
|
18
|
+
config.gem 'warden'
|
19
|
+
config.gem 'devise'
|
20
|
+
config.gem 'devise_referable'
|
21
|
+
|
22
|
+
== Basic Usage
|
23
|
+
|
24
|
+
Follow the walkthrough for devise with the following modifications.
|
25
|
+
|
26
|
+
Create a migration for the referrals table:
|
27
|
+
|
28
|
+
create_table :referrals, :force => true do |t|
|
29
|
+
t.integer :referrer_id
|
30
|
+
t.string :referrer_type
|
31
|
+
t.integer :recipient_id
|
32
|
+
t.string :referral_token
|
33
|
+
t.datetime :registered_at
|
34
|
+
t.timestamps
|
35
|
+
end
|
36
|
+
|
37
|
+
Add a referrer_token column to your referrer classes.
|
38
|
+
|
39
|
+
add_column :table_name1, :referrer_token, :string
|
40
|
+
add_column :table_name2, :referrer_token, :string
|
41
|
+
|
42
|
+
Add indexes if you want
|
43
|
+
add_index :referrals, :referral_token
|
44
|
+
add_index :table_name1, :referrer_token
|
45
|
+
add_index :table_name2, :referrer_token
|
46
|
+
|
47
|
+
|
48
|
+
Add :referable to the devise line in your model:
|
49
|
+
|
50
|
+
class User < ActiveRecord::Base
|
51
|
+
devise ..., :referable
|
52
|
+
end
|
53
|
+
|
54
|
+
If you are using devise :all, you can add :referable to config.all in devise initializer:
|
55
|
+
Devise.setup do |config|
|
56
|
+
...
|
57
|
+
config.all = [..., :referable]
|
58
|
+
...
|
59
|
+
end
|
60
|
+
|
61
|
+
== Model configuration
|
62
|
+
|
63
|
+
DeviseReferable adds a new configuration option, :referral_types. It should be
|
64
|
+
an array of classes which can act as a referrer
|
65
|
+
|
66
|
+
|
67
|
+
== Note on Patches/Pull Requests
|
68
|
+
|
69
|
+
* Fork the project.
|
70
|
+
* Make your feature addition or bug fix.
|
71
|
+
* Add tests for it. This is important so I don't break it in a
|
72
|
+
future version unintentionally.
|
73
|
+
* Commit, do not mess with rakefile, version, or history.
|
74
|
+
(if you want to have your own version, that is fine but
|
75
|
+
bump version in a commit by itself I can ignore when I pull)
|
76
|
+
* Send me a pull request. Bonus points for topic branches.
|
77
|
+
|
78
|
+
== Copyright
|
79
|
+
|
80
|
+
Copyright (c) 2010 Matt Van Horn, based on work by {Sergio Cambra}[http://github.com/scambra/devise_invitable].
|
81
|
+
See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "devise_referable"
|
8
|
+
gem.summary = %Q{An allows referral tracking for devise}
|
9
|
+
gem.description = %Q{It tracks the referring entity via cookie, and creates a record when user registers.}
|
10
|
+
gem.email = "mattvanhorn@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/mattvanhorn/devise_referable"
|
12
|
+
gem.authors = ["Matt Van Horn, based on work by Sergio Cambra"]
|
13
|
+
gem.add_development_dependency 'mocha'
|
14
|
+
gem.add_development_dependency 'webrat'
|
15
|
+
gem.add_dependency 'devise', '~> 1.0.0'
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
Rake::TestTask.new(:test) do |test|
|
24
|
+
test.libs << 'lib' << 'test'
|
25
|
+
test.pattern = 'test/**/*_test.rb'
|
26
|
+
test.verbose = true
|
27
|
+
end
|
28
|
+
|
29
|
+
begin
|
30
|
+
require 'rcov/rcovtask'
|
31
|
+
Rcov::RcovTask.new do |test|
|
32
|
+
test.libs << 'test'
|
33
|
+
test.pattern = 'test/**/test_*.rb'
|
34
|
+
test.verbose = true
|
35
|
+
end
|
36
|
+
rescue LoadError
|
37
|
+
task :rcov do
|
38
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
task :test => :check_dependencies
|
43
|
+
|
44
|
+
task :default => :test
|
45
|
+
|
46
|
+
require 'rake/rdoctask'
|
47
|
+
Rake::RDocTask.new do |rdoc|
|
48
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
49
|
+
|
50
|
+
rdoc.rdoc_dir = 'rdoc'
|
51
|
+
rdoc.title = "devise_referable #{version}"
|
52
|
+
rdoc.rdoc_files.include('README*')
|
53
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class ReferralsController < ApplicationController
|
2
|
+
|
3
|
+
def create
|
4
|
+
unless user_signed_in?
|
5
|
+
@referral = Referral.from_token(params[:referrer_token])
|
6
|
+
session[:referral_token] = @referral.referral_token if @referral
|
7
|
+
end
|
8
|
+
redirect_to "/#{params[:path].join('/')}"
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'devise/hooks/referable'
|
2
|
+
|
3
|
+
class Referral < ActiveRecord::Base
|
4
|
+
belongs_to :referrer, :polymorphic => true
|
5
|
+
belongs_to :recipient, :class_name => 'User'
|
6
|
+
|
7
|
+
before_create :generate_token
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def referrer_types
|
11
|
+
User.referrer_types
|
12
|
+
end
|
13
|
+
|
14
|
+
def lookup_referrer(token)
|
15
|
+
unless token.blank?
|
16
|
+
referrer_types.map{ |type| type.to_s.classify.constantize }.each do |klass|
|
17
|
+
ref = klass.find_by_referrer_token(token)
|
18
|
+
return ref unless ref.nil?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def from_token(token)
|
25
|
+
sender = lookup_referrer(token)
|
26
|
+
if sender
|
27
|
+
Referral.create do |ref|
|
28
|
+
ref.referrer = sender
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def generate_token
|
35
|
+
self.referral_token ||= Devise.friendly_token
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{devise_referable}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Matt Van Horn, based on work by Sergio Cambra"]
|
12
|
+
s.date = %q{2010-03-16}
|
13
|
+
s.description = %q{It tracks the referring entity via cookie, and creates a record when user registers.}
|
14
|
+
s.email = %q{mattvanhorn@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"app/controllers/referrals_controller.rb",
|
27
|
+
"app/models/referral.rb",
|
28
|
+
"devise_referable.gemspec",
|
29
|
+
"init.rb",
|
30
|
+
"lib/devise/hooks/referable.rb",
|
31
|
+
"lib/devise_referable.rb",
|
32
|
+
"lib/devise_referable/model.rb",
|
33
|
+
"lib/devise_referable/routes.rb",
|
34
|
+
"rails/init.rb",
|
35
|
+
"test/integration/referable_test.rb",
|
36
|
+
"test/integration_tests_helper.rb",
|
37
|
+
"test/model_tests_helper.rb",
|
38
|
+
"test/models/referral_test.rb",
|
39
|
+
"test/models_test.rb",
|
40
|
+
"test/rails_app/app/controllers/admins_controller.rb",
|
41
|
+
"test/rails_app/app/controllers/application_controller.rb",
|
42
|
+
"test/rails_app/app/controllers/home_controller.rb",
|
43
|
+
"test/rails_app/app/controllers/users_controller.rb",
|
44
|
+
"test/rails_app/app/helpers/application_helper.rb",
|
45
|
+
"test/rails_app/app/models/blog.rb",
|
46
|
+
"test/rails_app/app/models/user.rb",
|
47
|
+
"test/rails_app/app/views/home/index.html.erb",
|
48
|
+
"test/rails_app/config/boot.rb",
|
49
|
+
"test/rails_app/config/database.yml",
|
50
|
+
"test/rails_app/config/environment.rb",
|
51
|
+
"test/rails_app/config/environments/development.rb",
|
52
|
+
"test/rails_app/config/environments/production.rb",
|
53
|
+
"test/rails_app/config/environments/test.rb",
|
54
|
+
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
55
|
+
"test/rails_app/config/initializers/devise.rb",
|
56
|
+
"test/rails_app/config/initializers/inflections.rb",
|
57
|
+
"test/rails_app/config/initializers/new_rails_defaults.rb",
|
58
|
+
"test/rails_app/config/initializers/session_store.rb",
|
59
|
+
"test/rails_app/config/routes.rb",
|
60
|
+
"test/rails_app/vendor/plugins/devise_referable/init.rb",
|
61
|
+
"test/routes_test.rb",
|
62
|
+
"test/test_helper.rb"
|
63
|
+
]
|
64
|
+
s.homepage = %q{http://github.com/mattvanhorn/devise_referable}
|
65
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
66
|
+
s.require_paths = ["lib"]
|
67
|
+
s.rubygems_version = %q{1.3.6}
|
68
|
+
s.summary = %q{An allows referral tracking for devise}
|
69
|
+
s.test_files = [
|
70
|
+
"test/integration/referable_test.rb",
|
71
|
+
"test/integration_tests_helper.rb",
|
72
|
+
"test/model_tests_helper.rb",
|
73
|
+
"test/models/referral_test.rb",
|
74
|
+
"test/models_test.rb",
|
75
|
+
"test/rails_app/app/controllers/admins_controller.rb",
|
76
|
+
"test/rails_app/app/controllers/application_controller.rb",
|
77
|
+
"test/rails_app/app/controllers/home_controller.rb",
|
78
|
+
"test/rails_app/app/controllers/users_controller.rb",
|
79
|
+
"test/rails_app/app/helpers/application_helper.rb",
|
80
|
+
"test/rails_app/app/models/blog.rb",
|
81
|
+
"test/rails_app/app/models/user.rb",
|
82
|
+
"test/rails_app/config/boot.rb",
|
83
|
+
"test/rails_app/config/environment.rb",
|
84
|
+
"test/rails_app/config/environments/development.rb",
|
85
|
+
"test/rails_app/config/environments/production.rb",
|
86
|
+
"test/rails_app/config/environments/test.rb",
|
87
|
+
"test/rails_app/config/initializers/backtrace_silencers.rb",
|
88
|
+
"test/rails_app/config/initializers/devise.rb",
|
89
|
+
"test/rails_app/config/initializers/inflections.rb",
|
90
|
+
"test/rails_app/config/initializers/new_rails_defaults.rb",
|
91
|
+
"test/rails_app/config/initializers/session_store.rb",
|
92
|
+
"test/rails_app/config/routes.rb",
|
93
|
+
"test/rails_app/vendor/plugins/devise_referable/init.rb",
|
94
|
+
"test/routes_test.rb",
|
95
|
+
"test/test_helper.rb"
|
96
|
+
]
|
97
|
+
|
98
|
+
if s.respond_to? :specification_version then
|
99
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
100
|
+
s.specification_version = 3
|
101
|
+
|
102
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
103
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
104
|
+
s.add_development_dependency(%q<webrat>, [">= 0"])
|
105
|
+
s.add_runtime_dependency(%q<devise>, ["~> 1.0.0"])
|
106
|
+
else
|
107
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
108
|
+
s.add_dependency(%q<webrat>, [">= 0"])
|
109
|
+
s.add_dependency(%q<devise>, ["~> 1.0.0"])
|
110
|
+
end
|
111
|
+
else
|
112
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
113
|
+
s.add_dependency(%q<webrat>, [">= 0"])
|
114
|
+
s.add_dependency(%q<devise>, ["~> 1.0.0"])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'rails/init'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# After a user is set, we check to make sure that if they were referred, the
|
2
|
+
# referral is updated with the user's id.
|
3
|
+
# This will generally happen on registration, but could possibly happen on login
|
4
|
+
# in other circumstances where a user was existing in a legacy db for example.
|
5
|
+
|
6
|
+
Warden::Manager.after_set_user :except => :fetch do |record, warden, options|
|
7
|
+
token = warden.env['rack.session'][:referral_token]
|
8
|
+
scope = options[:scope]
|
9
|
+
if record.respond_to?(:referral) && record.referral.nil? && warden.authenticated?(scope) && token
|
10
|
+
record.update_referral(token) if record.respond_to?(:update_referral)
|
11
|
+
warden.env['rack.session'][:referral_token] = nil
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Devise
|
2
|
+
module Models
|
3
|
+
# Referable tracks users that arrive at your site via an affiliate link.
|
4
|
+
# Currently this is hardcoded as /ref/:referrer_token/path/to/destination
|
5
|
+
# TODO: make url configurable
|
6
|
+
#
|
7
|
+
# Classes that act as referrers are specified in the config, and must
|
8
|
+
# have a referrer_token column in the database.
|
9
|
+
# TODO: make column name configurable
|
10
|
+
#
|
11
|
+
# When a visitor arrives at the site via the referral_landing_path, the following things happen:
|
12
|
+
# - The referrer is looked up, by doing finds against the referrer_types in order.
|
13
|
+
# - If found, a referral record is created with a unique referral_token.
|
14
|
+
# - The referral_token is also stored in the session
|
15
|
+
# - The visitor is then redirected to the path appended to the referral_landing_path (i.e. /path/to/destination above)
|
16
|
+
# - If no path is given, they're redirected to the root path.
|
17
|
+
# - If the visitor registers during the session, the referral record is updated with the new user id, and the session token is cleared.
|
18
|
+
#
|
19
|
+
# Configuration:
|
20
|
+
#
|
21
|
+
# referrer_types: an array of symbols for classes that can refer users. i.e. [:blog, :customer, :user]
|
22
|
+
#
|
23
|
+
module Referable
|
24
|
+
|
25
|
+
def self.included(base)
|
26
|
+
base.class_eval do
|
27
|
+
has_one :referral, :foreign_key => :recipient_id
|
28
|
+
extend ClassMethods
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_referral(token)
|
33
|
+
referral = Referral.find_by_referral_token(token)
|
34
|
+
if referral
|
35
|
+
referral.update_attributes( :recipient_id => self.id,
|
36
|
+
:registered_at => self.created_at )
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
Devise::Models.config(self, :referrer_types)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module DeviseReferable
|
2
|
+
module Routes
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
def referable(routes, mapping)
|
7
|
+
send(:"referral_landing", 'ref/:referrer_token/*path', {:controller => 'referrals', :action => 'create', :conditions => { :method => :get }})
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ActionController::Routing::RouteSet::Mapper.send :include, DeviseReferable::Routes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Devise.module_eval do
|
2
|
+
# list of classes that can act as referrer.
|
3
|
+
mattr_accessor :referrer_types
|
4
|
+
@@referrer_types = []
|
5
|
+
end
|
6
|
+
Devise.add_module :referable, :controller => :referrals, :model => 'devise_referable/model'
|
7
|
+
|
8
|
+
module DeviseReferable; end
|
9
|
+
|
10
|
+
require File.join(File.dirname(__FILE__), '..', 'app', 'models', 'referral')
|
11
|
+
|
12
|
+
require 'devise_referable/routes'
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'devise_referable'
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
require 'test/integration_tests_helper'
|
3
|
+
|
4
|
+
class ReferralTest < ActionController::IntegrationTest
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@blog = Blog.create!(:name => 'Referrer', :referrer_token => 'abc123')
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'new users should get referral records' do
|
11
|
+
assert_equal 0, Referral.count
|
12
|
+
visit referral_landing_path(:referrer_token => 'abc123')
|
13
|
+
assert :success
|
14
|
+
assert_equal 1, Referral.count
|
15
|
+
assert_not_nil session[:referral_token]
|
16
|
+
|
17
|
+
visit new_user_registration_path
|
18
|
+
assert :success
|
19
|
+
|
20
|
+
fill_in 'email', :with => 'new_user@test.com'
|
21
|
+
fill_in 'password', :with => 'new_user123'
|
22
|
+
fill_in 'password confirmation', :with => 'new_user123'
|
23
|
+
click_button 'Sign up'
|
24
|
+
|
25
|
+
user = User.last :order => "id"
|
26
|
+
|
27
|
+
assert user.referral.referrer == @blog
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'existing users should not get referral records' do
|
31
|
+
assert_equal 0, Referral.count
|
32
|
+
|
33
|
+
visit new_user_registration_path
|
34
|
+
assert :success
|
35
|
+
|
36
|
+
fill_in 'email', :with => 'new_user@test.com'
|
37
|
+
fill_in 'password', :with => 'new_user123'
|
38
|
+
fill_in 'password confirmation', :with => 'new_user123'
|
39
|
+
click_button 'Sign up'
|
40
|
+
assert :success
|
41
|
+
|
42
|
+
visit '/ref/abc123'
|
43
|
+
assert :success
|
44
|
+
|
45
|
+
user = User.last :order => "id"
|
46
|
+
assert_equal 0, Referral.count
|
47
|
+
assert_nil user.referral
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'referral lookup failures should be ignored' do
|
51
|
+
assert_equal 0, Referral.count
|
52
|
+
visit referral_landing_path(:referrer_token => 'bogus')
|
53
|
+
assert :success
|
54
|
+
|
55
|
+
assert_equal 0, Referral.count
|
56
|
+
assert_nil session[:referral_token]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class ActionController::IntegrationTest
|
2
|
+
|
3
|
+
def warden
|
4
|
+
request.env['warden']
|
5
|
+
end
|
6
|
+
|
7
|
+
def sign_in_as_user
|
8
|
+
Warden::Proxy.any_instance.stubs(:user).at_least_once.returns(User.new)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_user(accept_invitation = true)
|
12
|
+
user = User.new :email => 'newuser@test.com'
|
13
|
+
user.save(false)
|
14
|
+
user
|
15
|
+
end
|
16
|
+
|
17
|
+
# Fix assert_redirect_to in integration sessions because they don't take into
|
18
|
+
# account Middleware redirects.
|
19
|
+
#
|
20
|
+
def assert_redirected_to(url)
|
21
|
+
assert [301, 302].include?(@integration_session.status),
|
22
|
+
"Expected status to be 301 or 302, got #{@integration_session.status}"
|
23
|
+
|
24
|
+
url = prepend_host(url)
|
25
|
+
location = prepend_host(@integration_session.headers["Location"])
|
26
|
+
assert_equal url, location
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def prepend_host(url)
|
32
|
+
url = "http://#{request.host}#{url}" if url[0] == ?/
|
33
|
+
url
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class ActiveSupport::TestCase
|
2
|
+
def setup_mailer
|
3
|
+
ActionMailer::Base.deliveries = []
|
4
|
+
end
|
5
|
+
|
6
|
+
def store_translations(locale, translations, &block)
|
7
|
+
begin
|
8
|
+
I18n.backend.store_translations locale, translations
|
9
|
+
yield
|
10
|
+
ensure
|
11
|
+
I18n.reload!
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Helpers for creating new users
|
16
|
+
#
|
17
|
+
def generate_unique_email
|
18
|
+
@@email_count ||= 0
|
19
|
+
@@email_count += 1
|
20
|
+
"test#{@@email_count}@email.com"
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid_attributes(attributes={})
|
24
|
+
{ :email => generate_unique_email,
|
25
|
+
:password => '123456',
|
26
|
+
:password_confirmation => '123456' }.update(attributes)
|
27
|
+
end
|
28
|
+
|
29
|
+
def new_user(attributes={})
|
30
|
+
User.new(valid_attributes(attributes))
|
31
|
+
end
|
32
|
+
|
33
|
+
def new_referral(attributes={})
|
34
|
+
Referral.new(attributes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_user(attributes={})
|
38
|
+
User.create!(valid_attributes(attributes))
|
39
|
+
end
|
40
|
+
|
41
|
+
# def create_user_with_invitation(invitation_token, attributes={})
|
42
|
+
# user = new_user({:password => nil, :password_confirmation => nil}.update(attributes))
|
43
|
+
# user.skip_confirmation!
|
44
|
+
# user.invitation_token = invitation_token
|
45
|
+
# user.invitation_sent_at = Time.now.utc
|
46
|
+
# user.save(false)
|
47
|
+
# user
|
48
|
+
# end
|
49
|
+
|
50
|
+
# Execute the block setting the given values and restoring old values after
|
51
|
+
# the block is executed.
|
52
|
+
def swap(object, new_values)
|
53
|
+
old_values = {}
|
54
|
+
new_values.each do |key, value|
|
55
|
+
old_values[key] = object.send key
|
56
|
+
object.send :"#{key}=", value
|
57
|
+
end
|
58
|
+
yield
|
59
|
+
ensure
|
60
|
+
old_values.each do |key, value|
|
61
|
+
object.send :"#{key}=", value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'test/test_helper'
|
2
|
+
require 'test/model_tests_helper'
|
3
|
+
|
4
|
+
class ReferableTest < ActiveSupport::TestCase
|
5
|
+
def setup
|
6
|
+
end
|
7
|
+
|
8
|
+
test 'should look up referrer' do
|
9
|
+
blog = mock()
|
10
|
+
Blog.expects(:find_by_referrer_token).with('abc123').returns(blog)
|
11
|
+
assert Referral.lookup_referrer('abc123') == blog
|
12
|
+
end
|
13
|
+
|
14
|
+
test 'should return nil if no referrer is found' do
|
15
|
+
Blog.expects(:find_by_referrer_token).with('abc123').returns(nil)
|
16
|
+
assert_nil Referral.lookup_referrer('abc123')
|
17
|
+
end
|
18
|
+
|
19
|
+
test 'should create referral from token' do
|
20
|
+
Blog.expects(:find_by_referrer_token).with('abc123').returns(create_user) # I just need an AR obj here to avoid massive stubbing.
|
21
|
+
# Should be a blog not a user.
|
22
|
+
result = Referral.from_token('abc123')
|
23
|
+
assert result.is_a?( Referral)
|
24
|
+
assert_not_nil result.referral_token
|
25
|
+
assert_not_nil result.referrer_id
|
26
|
+
assert_not_nil result.referrer_type
|
27
|
+
assert !result.new_record?
|
28
|
+
end
|
29
|
+
|
30
|
+
test 'should never generate the same referral token for different users' do
|
31
|
+
referral_tokens = []
|
32
|
+
10.times do
|
33
|
+
ref = new_referral(:referrer_id => 1, :referrer_type => 'Publisher')
|
34
|
+
token = ref.generate_token
|
35
|
+
assert !referral_tokens.include?(token)
|
36
|
+
referral_tokens << token
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|