clearance 0.12.0 → 0.13.0
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/Appraisals +2 -7
- data/CHANGELOG.md +9 -1
- data/CONTRIBUTING.md +38 -0
- data/Gemfile +2 -10
- data/Gemfile.lock +45 -49
- data/LICENSE +1 -1
- data/README.md +122 -13
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/app/views/sessions/_form.html.erb +13 -0
- data/app/views/sessions/new.html.erb +1 -13
- data/clearance.gemspec +7 -2
- data/features/engine/visitor_resets_password.feature +11 -23
- data/features/engine/visitor_signs_in.feature +6 -14
- data/features/engine/visitor_signs_out.feature +1 -1
- data/features/engine/visitor_signs_up.feature +6 -16
- data/features/integration.feature +0 -2
- data/features/step_definitions/engine/clearance_steps.rb +72 -62
- data/features/support/env.rb +2 -2
- data/gemfiles/3.0.9.gemfile +5 -10
- data/gemfiles/3.0.9.gemfile.lock +28 -33
- data/gemfiles/3.1.0.gemfile +13 -0
- data/gemfiles/3.1.0.gemfile.lock +187 -0
- data/lib/clearance.rb +1 -0
- data/lib/clearance/configuration.rb +2 -1
- data/lib/clearance/password_strategies.rb +5 -0
- data/lib/clearance/password_strategies/sha1.rb +46 -0
- data/lib/clearance/user.rb +10 -38
- data/lib/generators/clearance/features/features_generator.rb +0 -10
- data/spec/models/clearance_user_spec.rb +33 -0
- data/spec/models/sha1_spec.rb +43 -0
- data/spec/models/user_spec.rb +13 -21
- metadata +106 -85
- data/features/step_definitions/web_steps.rb +0 -211
- data/features/support/appraisal.rb +0 -18
- data/features/support/paths.rb +0 -22
- data/features/support/selectors.rb +0 -39
- data/gemfiles/3.1.0.rc4.gemfile +0 -23
- data/gemfiles/3.1.0.rc4.gemfile.lock +0 -216
@@ -1,18 +1,6 @@
|
|
1
1
|
<h2>Sign in</h2>
|
2
2
|
|
3
|
-
<%=
|
4
|
-
<div class="text_field">
|
5
|
-
<%= form.label :email %>
|
6
|
-
<%= form.text_field :email, :type => "email" %>
|
7
|
-
</div>
|
8
|
-
<div class="text_field">
|
9
|
-
<%= form.label :password %>
|
10
|
-
<%= form.password_field :password %>
|
11
|
-
</div>
|
12
|
-
<div class="submit_field">
|
13
|
-
<%= form.submit "Sign in" %>
|
14
|
-
</div>
|
15
|
-
<% end %>
|
3
|
+
<%= render :partial => '/sessions/form' %>
|
16
4
|
|
17
5
|
<ul>
|
18
6
|
<li>
|
data/clearance.gemspec
CHANGED
@@ -23,9 +23,14 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.rubygems_version = %q{1.3.7}
|
24
24
|
|
25
25
|
s.add_dependency('rails', '>= 3.0')
|
26
|
-
s.add_dependency('diesel', '~> 0.1.
|
26
|
+
s.add_dependency('diesel', '~> 0.1.5')
|
27
27
|
|
28
|
-
s.add_development_dependency('bundler',
|
28
|
+
s.add_development_dependency('bundler', '~> 1.0.0')
|
29
|
+
s.add_development_dependency('appraisal', '~> 0.3.8')
|
30
|
+
s.add_development_dependency('cucumber-rails', '~> 1.0.2')
|
31
|
+
s.add_development_dependency('rspec-rails', '~> 2.6.0')
|
32
|
+
s.add_development_dependency('sqlite3')
|
33
|
+
s.add_development_dependency('mocha')
|
29
34
|
|
30
35
|
if s.respond_to? :specification_version then
|
31
36
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -5,48 +5,36 @@ Feature: Password reset
|
|
5
5
|
I want to reset my password
|
6
6
|
|
7
7
|
Scenario: User is not signed up
|
8
|
-
|
9
|
-
|
10
|
-
Then I should see "Unknown email"
|
8
|
+
When I reset the password for "unknown.email@example.com"
|
9
|
+
Then I am told email is unknown
|
11
10
|
|
12
11
|
Scenario: User is signed up and requests password reset
|
13
12
|
Given I signed up with "email@example.com"
|
14
|
-
When I
|
15
|
-
Then
|
16
|
-
And a password reset message should be sent to "email@example.com"
|
13
|
+
When I reset the password for "email@example.com"
|
14
|
+
Then instructions for changing my password are emailed to "email@example.com"
|
17
15
|
|
18
16
|
Scenario: User tries to reset his password with a blank password
|
19
17
|
Given I signed up with "email@example.com"
|
20
|
-
|
21
|
-
|
22
|
-
And I fill in "Email address" with "email@example.com"
|
23
|
-
And I press "Reset password"
|
24
|
-
When I follow the password reset link sent to "email@example.com"
|
18
|
+
When I reset the password for "email@example.com"
|
19
|
+
And I follow the password reset link sent to "email@example.com"
|
25
20
|
And I update my password with ""
|
26
|
-
Then I
|
21
|
+
Then I am told to enter a password
|
27
22
|
And I should be signed out
|
28
23
|
|
29
24
|
Scenario: User is signed up and updates his password
|
30
25
|
Given I signed up with "email@example.com"
|
31
|
-
|
32
|
-
And I
|
33
|
-
And I press "Reset password"
|
34
|
-
When I follow the password reset link sent to "email@example.com"
|
26
|
+
When I reset the password for "email@example.com"
|
27
|
+
And I follow the password reset link sent to "email@example.com"
|
35
28
|
And I update my password with "newpassword"
|
36
29
|
Then I should be signed in
|
37
30
|
When I sign out
|
38
31
|
Then I should be signed out
|
39
|
-
When I
|
40
|
-
And I fill in "Email" with "email@example.com"
|
41
|
-
And I fill in "Password" with "newpassword"
|
42
|
-
And I press "Sign in"
|
32
|
+
When I sign in with "email@example.com" and "newpassword"
|
43
33
|
Then I should be signed in
|
44
34
|
|
45
35
|
Scenario: User who was created before Clearance was installed creates password for first time
|
46
36
|
Given a user "email@example.com" exists without a salt, remember token, or password
|
47
|
-
When I
|
48
|
-
And I fill in "Email address" with "email@example.com"
|
49
|
-
And I press "Reset password"
|
37
|
+
When I reset the password for "email@example.com"
|
50
38
|
When I follow the password reset link sent to "email@example.com"
|
51
39
|
And I update my password with "newpassword"
|
52
40
|
Then I should be signed in
|
@@ -5,30 +5,22 @@ Feature: Sign in
|
|
5
5
|
I want to sign in
|
6
6
|
|
7
7
|
Scenario: Visitor is not signed up
|
8
|
-
|
9
|
-
|
10
|
-
And I sign in as "email@example.com"
|
11
|
-
Then I should see "Bad email or password"
|
8
|
+
When I sign in as "unknown.email@example.com"
|
9
|
+
Then I am told email or password is bad
|
12
10
|
And I should be signed out
|
13
11
|
|
14
12
|
Scenario: Visitor enters wrong password
|
15
13
|
Given I am signed up as "email@example.com"
|
16
|
-
When I
|
17
|
-
|
18
|
-
And I fill in "Password" with "badpassword"
|
19
|
-
And I press "Sign in"
|
20
|
-
Then I should see "Bad email or password"
|
14
|
+
When I sign in as "email@example.com" and "badpassword"
|
15
|
+
Then I am told email or password is bad
|
21
16
|
And I should be signed out
|
22
17
|
|
23
18
|
Scenario: Visitor signs in successfully
|
24
19
|
Given I am signed up as "email@example.com"
|
25
|
-
When I
|
26
|
-
Then I should see an email field
|
27
|
-
And I sign in as "email@example.com"
|
20
|
+
When I sign in as "email@example.com"
|
28
21
|
Then I should be signed in
|
29
22
|
|
30
23
|
Scenario: Visitor signs in successfully with uppercase email
|
31
24
|
Given I am signed up as "email@example.com"
|
32
|
-
When I
|
33
|
-
And I sign in as "Email@example.com"
|
25
|
+
When I sign in as "Email@example.com"
|
34
26
|
Then I should be signed in
|
@@ -4,24 +4,14 @@ Feature: Sign up
|
|
4
4
|
As a visitor
|
5
5
|
I want to sign up
|
6
6
|
|
7
|
-
Background:
|
8
|
-
When I go to the sign up page
|
9
|
-
Then I should see an email field
|
10
|
-
|
11
7
|
Scenario: Visitor signs up with invalid email
|
12
|
-
When I
|
13
|
-
|
14
|
-
And I press "Sign up"
|
15
|
-
Then I should see "Must be a valid email address"
|
8
|
+
When I sign up with "invalidemail" and "password"
|
9
|
+
Then I am told to enter a valid email address
|
16
10
|
|
17
11
|
Scenario: Visitor signs up with blank password
|
18
|
-
When I
|
19
|
-
|
20
|
-
And I press "Sign up"
|
21
|
-
Then I should see "Password can't be blank"
|
12
|
+
When I sign up with "email@example.com" and ""
|
13
|
+
Then I am told to enter a password
|
22
14
|
|
23
15
|
Scenario: Visitor signs up with valid data
|
24
|
-
When I
|
25
|
-
|
26
|
-
And I press "Sign up"
|
27
|
-
Then I should be on the home page
|
16
|
+
When I sign up with "email@example.com" and "password"
|
17
|
+
Then I should be signed in
|
@@ -13,8 +13,6 @@ Feature: integrate with application
|
|
13
13
|
And I add the "factory_girl_rails" gem
|
14
14
|
And I add the "database_cleaner" gem
|
15
15
|
And I add the "clearance" gem from this project
|
16
|
-
And I add the "diesel" gem from git "git://github.com/thoughtbot/diesel.git"
|
17
|
-
And I reset Bundler environment variable
|
18
16
|
And I run `bundle install --local`
|
19
17
|
And I successfully run `bundle exec rails generate cucumber:install`
|
20
18
|
And I disable Capybara Javascript emulation
|
@@ -1,63 +1,70 @@
|
|
1
|
-
#
|
1
|
+
# Existing users
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
Given /^(?:I am|I have|I) signed up (?:as|with) "(.*)"$/ do |email|
|
4
|
+
Factory(:user, :email => email)
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
Given /^a user "([^"]*)" exists without a salt, remember token, or password$/ do |email|
|
8
|
+
user = Factory(:user, :email => email)
|
9
|
+
sql = "update users set salt = NULL, encrypted_password = NULL, remember_token = NULL where id = #{user.id}"
|
10
|
+
ActiveRecord::Base.connection.update(sql)
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
if page.respond_to?(:should)
|
13
|
-
page.should have_css("input[type='email']")
|
14
|
-
else
|
15
|
-
assert page.has_css("input[type='email']")
|
16
|
-
end
|
17
|
-
end
|
13
|
+
# Sign up
|
18
14
|
|
19
|
-
|
15
|
+
When /^I sign up (?:with|as) "(.*)" and "(.*)"$/ do |email, password|
|
16
|
+
visit sign_up_path
|
17
|
+
page.should have_css("input[type='email']")
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
fill_in "Email", :with => email
|
20
|
+
fill_in "Password", :with => password
|
21
|
+
click_button "Sign up"
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
# Sign in
|
25
|
+
|
26
|
+
Given /^I sign in$/ do
|
27
|
+
email = Factory.next(:email)
|
28
|
+
steps %{
|
29
|
+
I have signed up with "#{email}"
|
30
|
+
I sign in with "#{email}"
|
31
|
+
}
|
27
32
|
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
sql = "update users set salt = NULL, encrypted_password = NULL, remember_token = NULL where id = #{user.id}"
|
32
|
-
ActiveRecord::Base.connection.update(sql)
|
34
|
+
When /^I sign in (?:with|as) "([^"]*)"$/ do |email|
|
35
|
+
When %{I sign in with "#{email}" and "password"}
|
33
36
|
end
|
34
37
|
|
35
|
-
|
38
|
+
When /^I sign in (?:with|as) "([^"]*)" and "([^"]*)"$/ do |email, password|
|
39
|
+
visit sign_in_path
|
40
|
+
page.should have_css("input[type='email']")
|
36
41
|
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
fill_in "Email", :with => email
|
43
|
+
fill_in "Password", :with => password
|
44
|
+
click_button "Sign in"
|
40
45
|
end
|
41
46
|
|
42
|
-
|
43
|
-
Given %{I am on the homepage}
|
44
|
-
Then %{I should see "Sign in"}
|
45
|
-
end
|
47
|
+
# Sign out
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
-
|
49
|
+
When "I sign out" do
|
50
|
+
visit "/"
|
51
|
+
click_link "Sign out"
|
50
52
|
end
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
-
|
54
|
+
# Reset password
|
55
|
+
|
56
|
+
When /^I reset the password for "(.*)"$/ do |email|
|
57
|
+
visit new_password_path
|
58
|
+
page.should have_css("input[type='email']")
|
59
|
+
|
60
|
+
fill_in "Email address", :with => email
|
61
|
+
click_button "Reset password"
|
55
62
|
end
|
56
63
|
|
57
|
-
|
64
|
+
Then /^instructions for changing my password are emailed to "(.*)"$/ do |email|
|
65
|
+
page.should have_content("instructions for changing your password")
|
58
66
|
|
59
|
-
|
60
|
-
user = User.find_by_email(email)
|
67
|
+
user = User.find_by_email!(email)
|
61
68
|
assert !user.confirmation_token.blank?
|
62
69
|
assert !ActionMailer::Base.deliveries.empty?
|
63
70
|
result = ActionMailer::Base.deliveries.any? do |email|
|
@@ -69,44 +76,47 @@ Then /^a password reset message should be sent to "(.*)"$/ do |email|
|
|
69
76
|
end
|
70
77
|
|
71
78
|
When /^I follow the password reset link sent to "(.*)"$/ do |email|
|
72
|
-
user = User.find_by_email(email)
|
79
|
+
user = User.find_by_email!(email)
|
73
80
|
visit edit_user_password_path(:user_id => user,
|
74
81
|
:token => user.confirmation_token)
|
75
82
|
end
|
76
83
|
|
77
|
-
When /^I
|
78
|
-
user = User.find_by_email(email)
|
84
|
+
When /^I change the password of "(.*)" without token$/ do |email|
|
85
|
+
user = User.find_by_email!(email)
|
79
86
|
visit edit_user_password_path(:user_id => user)
|
80
87
|
end
|
81
88
|
|
82
|
-
|
89
|
+
When /^I update my password with "(.*)"$/ do |password|
|
90
|
+
fill_in "Choose password", :with => password
|
91
|
+
click_button "Save this password"
|
92
|
+
end
|
93
|
+
|
94
|
+
# Flashes
|
83
95
|
|
84
|
-
|
85
|
-
|
86
|
-
And %{I fill in "Email" with "#{email}"}
|
87
|
-
And %{I fill in "Password" with "password"}
|
88
|
-
And %{I press "Sign in"}
|
96
|
+
Then /^I am told email or password is bad$/ do
|
97
|
+
page.should have_content("Bad email or password")
|
89
98
|
end
|
90
99
|
|
91
|
-
|
92
|
-
|
93
|
-
When I go to the homepage
|
94
|
-
And I follow "Sign out"
|
95
|
-
}
|
100
|
+
Then /^I am told email is unknown$/ do
|
101
|
+
page.should have_content("Unknown email")
|
96
102
|
end
|
97
103
|
|
98
|
-
|
99
|
-
|
100
|
-
And %{I fill in "Email address" with "#{email}"}
|
101
|
-
And %{I press "Reset password"}
|
104
|
+
Then /^I am told to enter a valid email address$/ do
|
105
|
+
page.should have_content("Must be a valid email address")
|
102
106
|
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
And %{I press "Save this password"}
|
108
|
+
Then /^I am told to enter a password$/ do
|
109
|
+
page.should have_content("Password can't be blank")
|
107
110
|
end
|
108
111
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
+
# Verification
|
113
|
+
|
114
|
+
Then /^I should be signed in$/ do
|
115
|
+
visit "/"
|
116
|
+
page.should have_content "Sign out"
|
117
|
+
end
|
118
|
+
|
119
|
+
Then /^I should be signed out$/ do
|
120
|
+
visit "/"
|
121
|
+
page.should have_content "Sign in"
|
112
122
|
end
|
data/features/support/env.rb
CHANGED
@@ -15,8 +15,8 @@ Bundler.require
|
|
15
15
|
|
16
16
|
require 'diesel/testing'
|
17
17
|
require 'diesel/testing/integration'
|
18
|
-
require 'cucumber/
|
19
|
-
require 'cucumber/
|
18
|
+
require 'cucumber/rails/application'
|
19
|
+
require 'cucumber/rails/action_controller'
|
20
20
|
require 'rails/test_help'
|
21
21
|
require 'cucumber/rails/world'
|
22
22
|
require 'cucumber/rails/hooks'
|
data/gemfiles/3.0.9.gemfile
CHANGED
@@ -2,17 +2,12 @@
|
|
2
2
|
|
3
3
|
source "http://rubygems.org"
|
4
4
|
|
5
|
-
gem "
|
6
|
-
gem "
|
5
|
+
gem "capybara", "~> 1.0.0"
|
6
|
+
gem "factory_girl_rails"
|
7
7
|
gem "shoulda-matchers", :git=>"git://github.com/thoughtbot/shoulda-matchers.git"
|
8
|
-
gem "diesel", :git=>"git://github.com/thoughtbot/diesel.git"
|
9
8
|
gem "database_cleaner"
|
10
|
-
gem "rspec-rails", "~> 2.6.0"
|
11
|
-
gem "aruba", "~> 0.4.2"
|
12
|
-
gem "cucumber-rails", "1.0.0"
|
13
|
-
gem "mocha"
|
14
|
-
gem "appraisal", :git=>"git://github.com/thoughtbot/appraisal.git"
|
15
|
-
gem "capybara", "1.0.0"
|
16
|
-
gem "factory_girl_rails"
|
17
9
|
gem "launchy"
|
10
|
+
gem "aruba", "~> 0.4.2"
|
11
|
+
gem "rails", "3.0.9"
|
18
12
|
|
13
|
+
gemspec :path=>"../"
|
data/gemfiles/3.0.9.gemfile.lock
CHANGED
@@ -1,25 +1,16 @@
|
|
1
|
-
GIT
|
2
|
-
remote: git://github.com/thoughtbot/appraisal.git
|
3
|
-
revision: f8029181543b4bc4bdea03735a3b1e558fd66501
|
4
|
-
specs:
|
5
|
-
appraisal (0.3.5)
|
6
|
-
aruba (~> 0.4.2)
|
7
|
-
bundler
|
8
|
-
rake
|
9
|
-
|
10
|
-
GIT
|
11
|
-
remote: git://github.com/thoughtbot/diesel.git
|
12
|
-
revision: 9a7955eadd3e2f445ecf3d2d58edfc2a5e80a20b
|
13
|
-
specs:
|
14
|
-
diesel (0.1.4)
|
15
|
-
railties
|
16
|
-
|
17
1
|
GIT
|
18
2
|
remote: git://github.com/thoughtbot/shoulda-matchers.git
|
19
|
-
revision:
|
3
|
+
revision: 5190a39bba699d4989c2500c98622b505e2de828
|
20
4
|
specs:
|
21
5
|
shoulda-matchers (1.0.0.beta3)
|
22
6
|
|
7
|
+
PATH
|
8
|
+
remote: /Users/croaky/dev/clearance
|
9
|
+
specs:
|
10
|
+
clearance (0.12.0)
|
11
|
+
diesel (~> 0.1.5)
|
12
|
+
rails (>= 3.0)
|
13
|
+
|
23
14
|
GEM
|
24
15
|
remote: http://rubygems.org/
|
25
16
|
specs:
|
@@ -50,8 +41,12 @@ GEM
|
|
50
41
|
activemodel (= 3.0.9)
|
51
42
|
activesupport (= 3.0.9)
|
52
43
|
activesupport (3.0.9)
|
44
|
+
addressable (2.2.6)
|
45
|
+
appraisal (0.3.8)
|
46
|
+
bundler
|
47
|
+
rake
|
53
48
|
arel (2.0.10)
|
54
|
-
aruba (0.4.
|
49
|
+
aruba (0.4.5)
|
55
50
|
bcat (>= 0.6.1)
|
56
51
|
childprocess (>= 0.1.9)
|
57
52
|
cucumber (>= 0.10.7)
|
@@ -69,25 +64,25 @@ GEM
|
|
69
64
|
xpath (~> 0.1.4)
|
70
65
|
childprocess (0.1.9)
|
71
66
|
ffi (~> 1.0.6)
|
72
|
-
configuration (1.2.0)
|
73
67
|
cucumber (1.0.0)
|
74
68
|
builder (>= 2.1.2)
|
75
69
|
diff-lcs (>= 1.1.2)
|
76
70
|
gherkin (~> 2.4.1)
|
77
71
|
json (>= 1.4.6)
|
78
72
|
term-ansicolor (>= 1.0.5)
|
79
|
-
cucumber-rails (1.0.
|
73
|
+
cucumber-rails (1.0.2)
|
80
74
|
capybara (>= 1.0.0)
|
81
75
|
cucumber (~> 1.0.0)
|
82
|
-
nokogiri (>= 1.4.
|
83
|
-
rack-test (>= 0.5.7)
|
76
|
+
nokogiri (>= 1.4.6)
|
84
77
|
database_cleaner (0.6.7)
|
78
|
+
diesel (0.1.5)
|
79
|
+
railties
|
85
80
|
diff-lcs (1.1.2)
|
86
81
|
erubis (2.6.6)
|
87
82
|
abstract (>= 1.0.0)
|
88
|
-
factory_girl (
|
89
|
-
factory_girl_rails (1.0
|
90
|
-
factory_girl (~>
|
83
|
+
factory_girl (2.0.5)
|
84
|
+
factory_girl_rails (1.1.0)
|
85
|
+
factory_girl (~> 2.0.0)
|
91
86
|
railties (>= 3.0.0)
|
92
87
|
ffi (1.0.9)
|
93
88
|
gherkin (2.4.1)
|
@@ -95,9 +90,8 @@ GEM
|
|
95
90
|
i18n (0.5.0)
|
96
91
|
json (1.5.3)
|
97
92
|
json_pure (1.5.2)
|
98
|
-
launchy (0.
|
99
|
-
|
100
|
-
rake (>= 0.8.1)
|
93
|
+
launchy (2.0.5)
|
94
|
+
addressable (~> 2.2.6)
|
101
95
|
mail (2.2.19)
|
102
96
|
activesupport (>= 2.3.6)
|
103
97
|
i18n (>= 0.4.0)
|
@@ -105,7 +99,7 @@ GEM
|
|
105
99
|
treetop (~> 1.4.8)
|
106
100
|
mime-types (1.16)
|
107
101
|
mocha (0.9.12)
|
108
|
-
nokogiri (1.4.
|
102
|
+
nokogiri (1.4.6)
|
109
103
|
polyglot (0.3.1)
|
110
104
|
rack (1.2.3)
|
111
105
|
rack-mount (0.6.14)
|
@@ -161,12 +155,13 @@ PLATFORMS
|
|
161
155
|
ruby
|
162
156
|
|
163
157
|
DEPENDENCIES
|
164
|
-
appraisal
|
158
|
+
appraisal (~> 0.3.8)
|
165
159
|
aruba (~> 0.4.2)
|
166
|
-
|
167
|
-
|
160
|
+
bundler (~> 1.0.0)
|
161
|
+
capybara (~> 1.0.0)
|
162
|
+
clearance!
|
163
|
+
cucumber-rails (~> 1.0.2)
|
168
164
|
database_cleaner
|
169
|
-
diesel!
|
170
165
|
factory_girl_rails
|
171
166
|
launchy
|
172
167
|
mocha
|