clearance 0.10.2 → 0.10.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of clearance might be problematic. Click here for more details.
- data/.bundle/config +2 -0
- data/.gitignore +8 -0
- data/CHANGELOG.md +15 -0
- data/VERSION +1 -1
- data/clearance.gemspec +36 -0
- data/cucumber.yml +1 -0
- data/db/migrate/20110111224543_create_diesel_clearance_users.rb +19 -0
- data/db/schema.rb +28 -0
- data/features/engine/visitor_resets_password.feature +49 -0
- data/features/engine/visitor_signs_in.feature +28 -0
- data/features/engine/visitor_signs_out.feature +15 -0
- data/features/engine/visitor_signs_up.feature +21 -0
- data/features/integration.feature +54 -0
- data/features/step_definitions/configuration_steps.rb +37 -0
- data/features/step_definitions/engine/clearance_steps.rb +115 -0
- data/features/step_definitions/web_steps.rb +219 -0
- data/features/support/env.rb +45 -0
- data/features/support/paths.rb +22 -0
- data/init.rb +1 -0
- metadata +36 -8
data/.bundle/config
ADDED
data/.gitignore
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
0.10.3.2
|
2
|
+
------------------
|
3
|
+
|
4
|
+
* Fix gemspec to include all necessary files.
|
5
|
+
|
6
|
+
0.10.3.1
|
7
|
+
------------------
|
8
|
+
|
9
|
+
* Ensure everything within features inside any engine directory is included in the gemspec
|
10
|
+
|
11
|
+
0.10.3
|
12
|
+
------------------
|
13
|
+
|
14
|
+
* Include features/engines in gemspec file list so generator works as expected
|
15
|
+
|
1
16
|
0.10.2
|
2
17
|
------------------
|
3
18
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.10.2
|
1
|
+
0.10.3.2
|
data/clearance.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{clearance}
|
5
|
+
s.version = IO.read(File.join(File.dirname(__FILE__), 'VERSION'))
|
6
|
+
s.email = %q{support@thoughtbot.com}
|
7
|
+
s.homepage = %q{http://github.com/thoughtbot/clearance}
|
8
|
+
|
9
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
|
+
s.authors = ["Dan Croak", "Mike Burns", "Jason Morrison", "Joe Ferris", "Eugene Bolshakov", "Nick Quaranto", "Josh Nichols", "Mike Breen", "Marcel G\303\266rner", "Bence Nagy", "Ben Mabey", "Eloy Duran", "Tim Pope", "Mihai Anca", "Mark Cornick", "Shay Arnett", "Jon Yurek", "Chad Pytel"]
|
11
|
+
s.date = Date.today.to_s
|
12
|
+
s.summary = %q{Rails authentication with email & password.}
|
13
|
+
s.description = %q{Rails authentication with email & password.}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"LICENSE",
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,features}/*`.split("\n")
|
20
|
+
|
21
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
s.rubygems_version = %q{1.3.7}
|
24
|
+
|
25
|
+
s.add_dependency('rails', '~> 3.0.0')
|
26
|
+
s.add_dependency('diesel', '~> 0.1.4')
|
27
|
+
|
28
|
+
s.add_development_dependency('rspec', '~> 1.3.0')
|
29
|
+
s.add_development_dependency('cucumber', '~> 0.10.0')
|
30
|
+
|
31
|
+
if s.respond_to? :specification_version then
|
32
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
33
|
+
s.specification_version = 3
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/cucumber.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
default: -r features
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateDieselClearanceUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:users) do |t|
|
4
|
+
t.string :email
|
5
|
+
t.string :encrypted_password, :limit => 128
|
6
|
+
t.string :salt, :limit => 128
|
7
|
+
t.string :confirmation_token, :limit => 128
|
8
|
+
t.string :remember_token, :limit => 128
|
9
|
+
t.timestamps
|
10
|
+
end
|
11
|
+
|
12
|
+
add_index :users, :email
|
13
|
+
add_index :users, :remember_token
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
drop_table :users
|
18
|
+
end
|
19
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# This file is auto-generated from the current state of the database. Instead
|
2
|
+
# of editing this file, please use the migrations feature of Active Record to
|
3
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
4
|
+
#
|
5
|
+
# Note that this schema.rb definition is the authoritative source for your
|
6
|
+
# database schema. If you need to create the application database on another
|
7
|
+
# system, you should be using db:schema:load, not running all the migrations
|
8
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
9
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
10
|
+
#
|
11
|
+
# It's strongly recommended to check this file into your version control system.
|
12
|
+
|
13
|
+
ActiveRecord::Schema.define(:version => 20110111224543) do
|
14
|
+
|
15
|
+
create_table "users", :force => true do |t|
|
16
|
+
t.string "email"
|
17
|
+
t.string "encrypted_password", :limit => 128
|
18
|
+
t.string "salt", :limit => 128
|
19
|
+
t.string "confirmation_token", :limit => 128
|
20
|
+
t.string "remember_token", :limit => 128
|
21
|
+
t.datetime "created_at"
|
22
|
+
t.datetime "updated_at"
|
23
|
+
end
|
24
|
+
|
25
|
+
add_index "users", ["email"], :name => "index_users_on_email"
|
26
|
+
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
Feature: Password reset
|
2
|
+
|
3
|
+
In order to sign in even if I forgot my password
|
4
|
+
As a user
|
5
|
+
I want to reset my password
|
6
|
+
|
7
|
+
Scenario: User is not signed up
|
8
|
+
Given no user exists with an email of "email@example.com"
|
9
|
+
When I request password reset link to be sent to "email@example.com"
|
10
|
+
Then I should see "Unknown email"
|
11
|
+
|
12
|
+
Scenario: User is signed up and requests password reset
|
13
|
+
Given I signed up with "email@example.com/password"
|
14
|
+
When I request password reset link to be sent to "email@example.com"
|
15
|
+
Then I should see "instructions for changing your password"
|
16
|
+
And a password reset message should be sent to "email@example.com"
|
17
|
+
|
18
|
+
Scenario: User is signed up updated his password and types wrong confirmation
|
19
|
+
Given I signed up with "email@example.com/password"
|
20
|
+
And I go to the password reset request page
|
21
|
+
And I fill in "Email address" with "email@example.com"
|
22
|
+
And I press "Reset password"
|
23
|
+
When I follow the password reset link sent to "email@example.com"
|
24
|
+
And I update my password with "newpassword/wrongconfirmation"
|
25
|
+
Then I should see an error message
|
26
|
+
And I should be signed out
|
27
|
+
|
28
|
+
Scenario: User is signed up and updates his password
|
29
|
+
Given I signed up with "email@example.com/password"
|
30
|
+
And I go to the password reset request page
|
31
|
+
And I fill in "Email address" with "email@example.com"
|
32
|
+
And I press "Reset password"
|
33
|
+
When I follow the password reset link sent to "email@example.com"
|
34
|
+
And I update my password with "newpassword/newpassword"
|
35
|
+
Then I should be signed in
|
36
|
+
When I sign out
|
37
|
+
Then I should be signed out
|
38
|
+
And I sign in as "email@example.com/newpassword"
|
39
|
+
Then I should be signed in
|
40
|
+
|
41
|
+
Scenario: User who was created before Clearance was installed creates password for first time
|
42
|
+
Given a user "email@example.com" exists without a salt, remember token, or password
|
43
|
+
When I go to the password reset request page
|
44
|
+
And I fill in "Email address" with "email@example.com"
|
45
|
+
And I press "Reset password"
|
46
|
+
When I follow the password reset link sent to "email@example.com"
|
47
|
+
And I update my password with "newpassword/newpassword"
|
48
|
+
Then I should be signed in
|
49
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Feature: Sign in
|
2
|
+
|
3
|
+
In order to get access to protected sections of the site
|
4
|
+
As a visitor
|
5
|
+
I want to sign in
|
6
|
+
|
7
|
+
Scenario: Visitor is not signed up
|
8
|
+
Given no user exists with an email of "email@person.com"
|
9
|
+
When I go to the sign in page
|
10
|
+
And I sign in as "email@person.com/password"
|
11
|
+
Then I should see "Bad email or password"
|
12
|
+
And I should be signed out
|
13
|
+
|
14
|
+
Scenario: Visitor enters wrong password
|
15
|
+
Given I am signed up as "email@person.com/password"
|
16
|
+
When I go to the sign in page
|
17
|
+
And I sign in as "email@person.com/wrongpassword"
|
18
|
+
Then I should see "Bad email or password"
|
19
|
+
And I should be signed out
|
20
|
+
|
21
|
+
Scenario: Visitor signs in successfully
|
22
|
+
Given I am signed up as "email@person.com/password"
|
23
|
+
When I go to the sign in page
|
24
|
+
And I sign in as "email@person.com/password"
|
25
|
+
Then I should see "Signed in"
|
26
|
+
And I should be signed in
|
27
|
+
When I return next time
|
28
|
+
Then I should be signed in
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Sign out
|
2
|
+
|
3
|
+
In order to protect my account from unauthorized access
|
4
|
+
As a signed in user
|
5
|
+
I want to sign out
|
6
|
+
|
7
|
+
Scenario: User signs out
|
8
|
+
Given I am signed up as "email@person.com/password"
|
9
|
+
When I sign in as "email@person.com/password"
|
10
|
+
Then I should be signed in
|
11
|
+
And I sign out
|
12
|
+
Then I should see "Signed out"
|
13
|
+
And I should be signed out
|
14
|
+
When I return next time
|
15
|
+
Then I should be signed out
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Feature: Sign up
|
2
|
+
|
3
|
+
In order to get access to protected sections of the site
|
4
|
+
As a visitor
|
5
|
+
I want to sign up
|
6
|
+
|
7
|
+
Scenario: Visitor signs up with invalid data
|
8
|
+
When I go to the sign up page
|
9
|
+
And I fill in "Email" with "invalidemail"
|
10
|
+
And I fill in "Password" with "password"
|
11
|
+
And I fill in "Confirm password" with ""
|
12
|
+
And I press "Sign up"
|
13
|
+
Then I should see error messages
|
14
|
+
|
15
|
+
Scenario: Visitor signs up with valid data
|
16
|
+
When I go to the sign up page
|
17
|
+
And I fill in "Email" with "email@person.com"
|
18
|
+
And I fill in "Password" with "password"
|
19
|
+
And I fill in "Confirm password" with "password"
|
20
|
+
And I press "Sign up"
|
21
|
+
Then I should see "signed up"
|
@@ -0,0 +1,54 @@
|
|
1
|
+
@disable-bundler
|
2
|
+
Feature: integrate with application
|
3
|
+
|
4
|
+
Background:
|
5
|
+
When I successfully run "rails new testapp"
|
6
|
+
And I cd to "testapp"
|
7
|
+
And I remove the file "public/index.html"
|
8
|
+
And I remove the file "app/views/layouts/application.html.erb"
|
9
|
+
And I configure ActionMailer to use "localhost" as a host
|
10
|
+
And I configure a root route
|
11
|
+
And I add the "cucumber-rails" gem
|
12
|
+
And I add the "capybara" gem
|
13
|
+
And I add the "rspec-rails" gem
|
14
|
+
And I add the "formtastic" gem
|
15
|
+
And I add the "factory_girl_rails" gem
|
16
|
+
And I add the "dynamic_form" gem
|
17
|
+
And I add the "clearance" gem from this project
|
18
|
+
And I add the "diesel" gem
|
19
|
+
And I run "bundle install --local"
|
20
|
+
And I successfully run "rails generate cucumber:install"
|
21
|
+
And I disable Capybara Javascript emulation
|
22
|
+
And I successfully run "rails generate clearance:features"
|
23
|
+
|
24
|
+
Scenario: generate a Rails app, run the generators, and run the tests
|
25
|
+
When I successfully run "rails generate clearance:install"
|
26
|
+
Then the output should contain "Next steps"
|
27
|
+
When I successfully run "rake db:migrate --trace"
|
28
|
+
And I successfully run "rake --trace"
|
29
|
+
Then the output should contain "passed"
|
30
|
+
And the output should not contain "failed"
|
31
|
+
And the output should not contain "Could not find generator"
|
32
|
+
|
33
|
+
Scenario: Developer already has a users table in their database
|
34
|
+
When I write to "db/migrate/001_create_users.rb" with:
|
35
|
+
"""
|
36
|
+
class CreateUsers < ActiveRecord::Migration
|
37
|
+
def self.up
|
38
|
+
create_table(:users) do |t|
|
39
|
+
t.string :email
|
40
|
+
t.string :name
|
41
|
+
end
|
42
|
+
end
|
43
|
+
def self.down
|
44
|
+
end
|
45
|
+
end
|
46
|
+
"""
|
47
|
+
And I successfully run "rake db:migrate --trace"
|
48
|
+
And I successfully run "rails generate clearance:install"
|
49
|
+
And I successfully run "rake db:migrate --trace"
|
50
|
+
And I successfully run "rake --trace"
|
51
|
+
Then the output should contain "passed"
|
52
|
+
And the output should not contain "failed"
|
53
|
+
And the output should not contain "Could not find generator"
|
54
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
When /^I configure ActionMailer to use "([^"]+)" as a host$/ do |host|
|
2
|
+
mailer_config = "config.action_mailer.default_url_options = { :host => '#{host}' }"
|
3
|
+
path = "config/application.rb"
|
4
|
+
in_current_dir do
|
5
|
+
contents = IO.read(path)
|
6
|
+
contents.sub!(/(class .* < Rails::Application)/, "\\1\n#{mailer_config}")
|
7
|
+
File.open(path, "w") { |file| file.write(contents) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
When /^I configure a root route$/ do
|
12
|
+
route = "root :to => 'home#show'"
|
13
|
+
path = "config/routes.rb"
|
14
|
+
in_current_dir do
|
15
|
+
contents = IO.read(path)
|
16
|
+
contents.sub!(/(\.routes\.draw do)/, "\\1\n#{route}\n")
|
17
|
+
File.open(path, "w") { |file| file.write(contents) }
|
18
|
+
end
|
19
|
+
create_file("app/controllers/home_controller.rb", <<-CONTROLLER)
|
20
|
+
class HomeController < ApplicationController
|
21
|
+
def show
|
22
|
+
render :text => "", :layout => "application"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
CONTROLLER
|
26
|
+
end
|
27
|
+
|
28
|
+
When /^I disable Capybara Javascript emulation$/ do
|
29
|
+
in_current_dir do
|
30
|
+
path = "features/support/env.rb"
|
31
|
+
contents = IO.read(path)
|
32
|
+
contents.sub!(%{require 'cucumber/rails/capybara_javascript_emulation'},
|
33
|
+
"# Disabled")
|
34
|
+
File.open(path, "w") { |file| file.write(contents) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# General
|
2
|
+
|
3
|
+
Then /^I should see error messages$/ do
|
4
|
+
Then %{I should see "errors prohibited"}
|
5
|
+
end
|
6
|
+
|
7
|
+
Then /^I should see an error message$/ do
|
8
|
+
Then %{I should see "error prohibited"}
|
9
|
+
end
|
10
|
+
|
11
|
+
# Database
|
12
|
+
|
13
|
+
Given /^no user exists with an email of "(.*)"$/ do |email|
|
14
|
+
assert_nil User.find_by_email(email)
|
15
|
+
end
|
16
|
+
|
17
|
+
Given /^(?:I am|I have|I) signed up (?:as|with) "(.*)\/(.*)"$/ do |email, password|
|
18
|
+
Factory(:user,
|
19
|
+
:email => email,
|
20
|
+
:password => password,
|
21
|
+
:password_confirmation => password)
|
22
|
+
end
|
23
|
+
|
24
|
+
Given /^a user "([^"]*)" exists without a salt, remember token, or password$/ do |email|
|
25
|
+
user = Factory(:user, :email => email)
|
26
|
+
sql = "update users set salt = NULL, encrypted_password = NULL, remember_token = NULL where id = #{user.id}"
|
27
|
+
ActiveRecord::Base.connection.update(sql)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Session
|
31
|
+
|
32
|
+
Then /^I should be signed in$/ do
|
33
|
+
Given %{I am on the homepage}
|
34
|
+
Then %{I should see "Sign out"}
|
35
|
+
end
|
36
|
+
|
37
|
+
Then /^I should be signed out$/ do
|
38
|
+
Given %{I am on the homepage}
|
39
|
+
Then %{I should see "Sign in"}
|
40
|
+
end
|
41
|
+
|
42
|
+
When /^session is cleared$/ do
|
43
|
+
# TODO: This doesn't work with Capybara
|
44
|
+
# TODO: I tried Capybara.reset_sessions! but that didn't work
|
45
|
+
#request.reset_session
|
46
|
+
#controller.instance_variable_set(:@_current_user, nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
Given /^(?:I am|I have|I) signed in (?:with|as) "(.*)\/(.*)"$/ do |email, password|
|
50
|
+
Given %{I am signed up as "#{email}/#{password}"}
|
51
|
+
And %{I sign in as "#{email}/#{password}"}
|
52
|
+
end
|
53
|
+
|
54
|
+
Given /^I sign in$/ do
|
55
|
+
email = Factory.next(:email)
|
56
|
+
Given %{I have signed in with "#{email}/password"}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Emails
|
60
|
+
|
61
|
+
Then /^a password reset message should be sent to "(.*)"$/ do |email|
|
62
|
+
user = User.find_by_email(email)
|
63
|
+
assert !user.confirmation_token.blank?
|
64
|
+
assert !ActionMailer::Base.deliveries.empty?
|
65
|
+
result = ActionMailer::Base.deliveries.any? do |email|
|
66
|
+
email.to == [user.email] &&
|
67
|
+
email.subject =~ /password/i &&
|
68
|
+
email.body =~ /#{user.confirmation_token}/
|
69
|
+
end
|
70
|
+
assert result
|
71
|
+
end
|
72
|
+
|
73
|
+
When /^I follow the password reset link sent to "(.*)"$/ do |email|
|
74
|
+
user = User.find_by_email(email)
|
75
|
+
visit edit_user_password_path(:user_id => user,
|
76
|
+
:token => user.confirmation_token)
|
77
|
+
end
|
78
|
+
|
79
|
+
When /^I try to change the password of "(.*)" without token$/ do |email|
|
80
|
+
user = User.find_by_email(email)
|
81
|
+
visit edit_user_password_path(:user_id => user)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Actions
|
85
|
+
|
86
|
+
When /^I sign in (?:with|as) "(.*)\/(.*)"$/ do |email, password|
|
87
|
+
When %{I go to the sign in page}
|
88
|
+
And %{I fill in "Email" with "#{email}"}
|
89
|
+
And %{I fill in "Password" with "#{password}"}
|
90
|
+
And %{I press "Sign in"}
|
91
|
+
end
|
92
|
+
|
93
|
+
When "I sign out" do
|
94
|
+
steps %{
|
95
|
+
When I go to the homepage
|
96
|
+
And I follow "Sign out"
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
When /^I request password reset link to be sent to "(.*)"$/ do |email|
|
101
|
+
When %{I go to the password reset request page}
|
102
|
+
And %{I fill in "Email address" with "#{email}"}
|
103
|
+
And %{I press "Reset password"}
|
104
|
+
end
|
105
|
+
|
106
|
+
When /^I update my password with "(.*)\/(.*)"$/ do |password, confirmation|
|
107
|
+
And %{I fill in "Choose password" with "#{password}"}
|
108
|
+
And %{I fill in "Confirm password" with "#{confirmation}"}
|
109
|
+
And %{I press "Save this password"}
|
110
|
+
end
|
111
|
+
|
112
|
+
When /^I return next time$/ do
|
113
|
+
When %{session is cleared}
|
114
|
+
And %{I go to the homepage}
|
115
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
2
|
+
# It is recommended to regenerate this file in the future when you upgrade to a
|
3
|
+
# newer version of cucumber-rails. Consider adding your own code to a new file
|
4
|
+
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
5
|
+
# files.
|
6
|
+
|
7
|
+
|
8
|
+
require 'uri'
|
9
|
+
require 'cgi'
|
10
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
11
|
+
|
12
|
+
module WithinHelpers
|
13
|
+
def with_scope(locator)
|
14
|
+
locator ? within(locator) { yield } : yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
World(WithinHelpers)
|
18
|
+
|
19
|
+
Given /^(?:|I )am on (.+)$/ do |page_name|
|
20
|
+
visit path_to(page_name)
|
21
|
+
end
|
22
|
+
|
23
|
+
When /^(?:|I )go to (.+)$/ do |page_name|
|
24
|
+
visit path_to(page_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
When /^(?:|I )press "([^"]*)"(?: within "([^"]*)")?$/ do |button, selector|
|
28
|
+
with_scope(selector) do
|
29
|
+
click_button(button)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
When /^(?:|I )follow "([^"]*)"(?: within "([^"]*)")?$/ do |link, selector|
|
34
|
+
with_scope(selector) do
|
35
|
+
click_link(link)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"(?: within "([^"]*)")?$/ do |field, value, selector|
|
40
|
+
with_scope(selector) do
|
41
|
+
fill_in(field, :with => value)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
|
46
|
+
with_scope(selector) do
|
47
|
+
fill_in(field, :with => value)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Use this to fill in an entire form with data from a table. Example:
|
52
|
+
#
|
53
|
+
# When I fill in the following:
|
54
|
+
# | Account Number | 5002 |
|
55
|
+
# | Expiry date | 2009-11-01 |
|
56
|
+
# | Note | Nice guy |
|
57
|
+
# | Wants Email? | |
|
58
|
+
#
|
59
|
+
# TODO: Add support for checkbox, select og option
|
60
|
+
# based on naming conventions.
|
61
|
+
#
|
62
|
+
When /^(?:|I )fill in the following(?: within "([^"]*)")?:$/ do |selector, fields|
|
63
|
+
with_scope(selector) do
|
64
|
+
fields.rows_hash.each do |name, value|
|
65
|
+
When %{I fill in "#{name}" with "#{value}"}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
When /^(?:|I )select "([^"]*)" from "([^"]*)"(?: within "([^"]*)")?$/ do |value, field, selector|
|
71
|
+
with_scope(selector) do
|
72
|
+
select(value, :from => field)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
When /^(?:|I )check "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
|
77
|
+
with_scope(selector) do
|
78
|
+
check(field)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
When /^(?:|I )uncheck "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
|
83
|
+
with_scope(selector) do
|
84
|
+
uncheck(field)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
When /^(?:|I )choose "([^"]*)"(?: within "([^"]*)")?$/ do |field, selector|
|
89
|
+
with_scope(selector) do
|
90
|
+
choose(field)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"(?: within "([^"]*)")?$/ do |path, field, selector|
|
95
|
+
with_scope(selector) do
|
96
|
+
attach_file(field, path)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
Then /^(?:|I )should see JSON:$/ do |expected_json|
|
101
|
+
require 'json'
|
102
|
+
expected = JSON.pretty_generate(JSON.parse(expected_json))
|
103
|
+
actual = JSON.pretty_generate(JSON.parse(response.body))
|
104
|
+
expected.should == actual
|
105
|
+
end
|
106
|
+
|
107
|
+
Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
|
108
|
+
with_scope(selector) do
|
109
|
+
if page.respond_to? :should
|
110
|
+
page.should have_content(text)
|
111
|
+
else
|
112
|
+
assert page.has_content?(text)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
Then /^(?:|I )should see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
|
118
|
+
regexp = Regexp.new(regexp)
|
119
|
+
with_scope(selector) do
|
120
|
+
if page.respond_to? :should
|
121
|
+
page.should have_xpath('//*', :text => regexp)
|
122
|
+
else
|
123
|
+
assert page.has_xpath?('//*', :text => regexp)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
Then /^(?:|I )should not see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
|
129
|
+
with_scope(selector) do
|
130
|
+
if page.respond_to? :should
|
131
|
+
page.should have_no_content(text)
|
132
|
+
else
|
133
|
+
assert page.has_no_content?(text)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
Then /^(?:|I )should not see \/([^\/]*)\/(?: within "([^"]*)")?$/ do |regexp, selector|
|
139
|
+
regexp = Regexp.new(regexp)
|
140
|
+
with_scope(selector) do
|
141
|
+
if page.respond_to? :should
|
142
|
+
page.should have_no_xpath('//*', :text => regexp)
|
143
|
+
else
|
144
|
+
assert page.has_no_xpath?('//*', :text => regexp)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
Then /^the "([^"]*)" field(?: within "([^"]*)")? should contain "([^"]*)"$/ do |field, selector, value|
|
150
|
+
with_scope(selector) do
|
151
|
+
field = find_field(field)
|
152
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
153
|
+
if field_value.respond_to? :should
|
154
|
+
field_value.should =~ /#{value}/
|
155
|
+
else
|
156
|
+
assert_match(/#{value}/, field_value)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
Then /^the "([^"]*)" field(?: within "([^"]*)")? should not contain "([^"]*)"$/ do |field, selector, value|
|
162
|
+
with_scope(selector) do
|
163
|
+
field = find_field(field)
|
164
|
+
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
165
|
+
if field_value.respond_to? :should_not
|
166
|
+
field_value.should_not =~ /#{value}/
|
167
|
+
else
|
168
|
+
assert_no_match(/#{value}/, field_value)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector|
|
174
|
+
with_scope(selector) do
|
175
|
+
field_checked = find_field(label)['checked']
|
176
|
+
if field_checked.respond_to? :should
|
177
|
+
field_checked.should be_true
|
178
|
+
else
|
179
|
+
assert field_checked
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector|
|
185
|
+
with_scope(selector) do
|
186
|
+
field_checked = find_field(label)['checked']
|
187
|
+
if field_checked.respond_to? :should
|
188
|
+
field_checked.should be_false
|
189
|
+
else
|
190
|
+
assert !field_checked
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
Then /^(?:|I )should be on (.+)$/ do |page_name|
|
196
|
+
current_path = URI.parse(current_url).path
|
197
|
+
if current_path.respond_to? :should
|
198
|
+
current_path.should == path_to(page_name)
|
199
|
+
else
|
200
|
+
assert_equal path_to(page_name), current_path
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
|
205
|
+
query = URI.parse(current_url).query
|
206
|
+
actual_params = query ? CGI.parse(query) : {}
|
207
|
+
expected_params = {}
|
208
|
+
expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
|
209
|
+
|
210
|
+
if actual_params.respond_to? :should
|
211
|
+
actual_params.should == expected_params
|
212
|
+
else
|
213
|
+
assert_equal expected_params, actual_params
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
Then /^show me the page$/ do
|
218
|
+
save_and_open_page
|
219
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
ENV["RAILS_ENV"] ||= "test"
|
2
|
+
|
3
|
+
PROJECT_ROOT = File.expand_path("../..", __FILE__)
|
4
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, "lib")
|
5
|
+
|
6
|
+
require 'rails/all'
|
7
|
+
Bundler.require
|
8
|
+
|
9
|
+
require 'diesel/testing'
|
10
|
+
require 'diesel/testing/integration'
|
11
|
+
|
12
|
+
require 'clearance'
|
13
|
+
require 'clearance/shoulda_macros'
|
14
|
+
|
15
|
+
Clearance.configure do |config|
|
16
|
+
end
|
17
|
+
|
18
|
+
class ApplicationController < ActionController::Base
|
19
|
+
include Clearance::Authentication
|
20
|
+
|
21
|
+
def show
|
22
|
+
render :text => "", :layout => 'application'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class User < ActiveRecord::Base
|
27
|
+
include Clearance::User
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'cucumber/formatter/unicode'
|
31
|
+
require 'cucumber/rails/world'
|
32
|
+
require 'cucumber/rails/active_record'
|
33
|
+
require 'cucumber/web/tableish'
|
34
|
+
require 'capybara/rails'
|
35
|
+
require 'capybara/cucumber'
|
36
|
+
require 'capybara/session'
|
37
|
+
|
38
|
+
Capybara.default_selector = :css
|
39
|
+
Capybara.save_and_open_page_path = 'tmp'
|
40
|
+
Cucumber::Rails::World.use_transactional_fixtures = true
|
41
|
+
|
42
|
+
Before do
|
43
|
+
@aruba_timeout_seconds = 60
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module NavigationHelpers
|
2
|
+
def path_to(page_name)
|
3
|
+
case page_name
|
4
|
+
|
5
|
+
when /the sign up page/i
|
6
|
+
sign_up_path
|
7
|
+
when /the sign in page/i
|
8
|
+
sign_in_path
|
9
|
+
when /the password reset request page/i
|
10
|
+
new_password_path
|
11
|
+
when /the home ?page/i
|
12
|
+
root_path
|
13
|
+
|
14
|
+
# Add more page name => path mappings here
|
15
|
+
|
16
|
+
else
|
17
|
+
raise "Can't find mapping from \"#{page_name}\" to a path."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
World(NavigationHelpers)
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'clearance'
|
metadata
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clearance
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 10
|
9
|
+
- 3
|
9
10
|
- 2
|
10
|
-
version: 0.10.2
|
11
|
+
version: 0.10.3.2
|
11
12
|
platform: ruby
|
12
13
|
authors:
|
13
14
|
- Dan Croak
|
@@ -32,7 +33,7 @@ autorequire:
|
|
32
33
|
bindir: bin
|
33
34
|
cert_chain: []
|
34
35
|
|
35
|
-
date: 2011-
|
36
|
+
date: 2011-03-06 00:00:00 -05:00
|
36
37
|
default_executable:
|
37
38
|
dependencies:
|
38
39
|
- !ruby/object:Gem::Dependency
|
@@ -109,12 +110,14 @@ extra_rdoc_files:
|
|
109
110
|
- LICENSE
|
110
111
|
- README.md
|
111
112
|
files:
|
113
|
+
- .bundle/config
|
114
|
+
- .gitignore
|
112
115
|
- CHANGELOG.md
|
113
116
|
- Gemfile
|
114
117
|
- Gemfile.lock
|
115
118
|
- LICENSE
|
116
|
-
- Rakefile
|
117
119
|
- README.md
|
120
|
+
- Rakefile
|
118
121
|
- VERSION
|
119
122
|
- app/controllers/clearance/passwords_controller.rb
|
120
123
|
- app/controllers/clearance/sessions_controller.rb
|
@@ -128,18 +131,33 @@ files:
|
|
128
131
|
- app/views/users/_form.html.erb
|
129
132
|
- app/views/users/_inputs.html.erb
|
130
133
|
- app/views/users/new.html.erb
|
134
|
+
- clearance.gemspec
|
131
135
|
- config/routes.rb
|
136
|
+
- cucumber.yml
|
137
|
+
- db/migrate/20110111224543_create_diesel_clearance_users.rb
|
138
|
+
- db/schema.rb
|
139
|
+
- features/engine/visitor_resets_password.feature
|
140
|
+
- features/engine/visitor_signs_in.feature
|
141
|
+
- features/engine/visitor_signs_out.feature
|
142
|
+
- features/engine/visitor_signs_up.feature
|
143
|
+
- features/integration.feature
|
144
|
+
- features/step_definitions/configuration_steps.rb
|
145
|
+
- features/step_definitions/engine/clearance_steps.rb
|
146
|
+
- features/step_definitions/web_steps.rb
|
147
|
+
- features/support/env.rb
|
148
|
+
- features/support/paths.rb
|
149
|
+
- init.rb
|
150
|
+
- lib/clearance.rb
|
132
151
|
- lib/clearance/authentication.rb
|
133
152
|
- lib/clearance/configuration.rb
|
134
153
|
- lib/clearance/engine.rb
|
135
154
|
- lib/clearance/shoulda_macros.rb
|
136
155
|
- lib/clearance/user.rb
|
137
|
-
- lib/clearance.rb
|
138
156
|
- lib/generators/clearance/features/features_generator.rb
|
139
157
|
- lib/generators/clearance/install/install_generator.rb
|
158
|
+
- lib/generators/clearance/install/templates/README
|
140
159
|
- lib/generators/clearance/install/templates/clearance.rb
|
141
160
|
- lib/generators/clearance/install/templates/db/migrate/upgrade_clearance_to_diesel.rb
|
142
|
-
- lib/generators/clearance/install/templates/README
|
143
161
|
- lib/generators/clearance/install/templates/user.rb
|
144
162
|
- lib/generators/clearance/views/views_generator.rb
|
145
163
|
- test/controllers/passwords_controller_test.rb
|
@@ -179,11 +197,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
197
|
requirements: []
|
180
198
|
|
181
199
|
rubyforge_project:
|
182
|
-
rubygems_version: 1.
|
200
|
+
rubygems_version: 1.4.2
|
183
201
|
signing_key:
|
184
202
|
specification_version: 3
|
185
203
|
summary: Rails authentication with email & password.
|
186
204
|
test_files:
|
205
|
+
- features/engine/visitor_resets_password.feature
|
206
|
+
- features/engine/visitor_signs_in.feature
|
207
|
+
- features/engine/visitor_signs_out.feature
|
208
|
+
- features/engine/visitor_signs_up.feature
|
209
|
+
- features/integration.feature
|
210
|
+
- features/step_definitions/configuration_steps.rb
|
211
|
+
- features/step_definitions/engine/clearance_steps.rb
|
212
|
+
- features/step_definitions/web_steps.rb
|
213
|
+
- features/support/env.rb
|
214
|
+
- features/support/paths.rb
|
187
215
|
- test/controllers/passwords_controller_test.rb
|
188
216
|
- test/controllers/sessions_controller_test.rb
|
189
217
|
- test/controllers/users_controller_test.rb
|