behaviour 0.0.1.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +47 -0
  7. data/Rakefile +7 -0
  8. data/behaviour.gemspec +27 -0
  9. data/lib/behaviour.rb +4 -0
  10. data/lib/behaviour/version.rb +3 -0
  11. data/lib/generators/behaviour/authentication/USAGE +2 -0
  12. data/lib/generators/behaviour/authentication/authentication_generator.rb +37 -0
  13. data/lib/generators/behaviour/authentication/templates/.rspec +1 -0
  14. data/lib/generators/behaviour/authentication/templates/features/authentication/reset_password.feature +13 -0
  15. data/lib/generators/behaviour/authentication/templates/features/authentication/sign_in.feature +28 -0
  16. data/lib/generators/behaviour/authentication/templates/features/authentication/sign_out.feature +7 -0
  17. data/lib/generators/behaviour/authentication/templates/features/authentication/sign_up.feature +19 -0
  18. data/lib/generators/behaviour/authentication/templates/features/authentication/update_account.feature +19 -0
  19. data/lib/generators/behaviour/authentication/templates/features/step_definitions/authentication.rb +184 -0
  20. data/lib/generators/behaviour/authentication/templates/features/support/authentication.rb +18 -0
  21. data/lib/generators/behaviour/authentication/templates/features/support/i18n.rb +1 -0
  22. data/lib/generators/behaviour/authentication/templates/features/support/rack_session_access.rb +1 -0
  23. data/lib/generators/behaviour/authentication/templates/features/support/rspec_syntax.rb +2 -0
  24. data/lib/generators/behaviour/authentication/templates/spec/controllers/authentication/reset_passwords_controller_spec.rb +99 -0
  25. data/lib/generators/behaviour/authentication/templates/spec/controllers/authentication/sessions_controller_spec.rb +98 -0
  26. data/lib/generators/behaviour/authentication/templates/spec/controllers/authentication/users_controller_spec.rb +107 -0
  27. data/lib/generators/behaviour/authentication/templates/spec/support/i18n.rb +14 -0
  28. data/lib/generators/behaviour/authentication/templates/spec/support/syntax.rb +6 -0
  29. data/spec/dummy/Gemfile +0 -0
  30. data/spec/dummy/bin/rails +2 -0
  31. data/spec/generators/behaviour/authentication/authentication_generator_spec.rb +62 -0
  32. data/spec/spec_helper.rb +2 -0
  33. metadata +149 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: addcbefac6e9175f7296597777e567bdf6a7c3ed
4
+ data.tar.gz: a48782fb7567f2a57d295bb84dd17cf9c44c467f
5
+ SHA512:
6
+ metadata.gz: 9a3533c28b5e5c62833da6ebcff092c413dc6cd5384c0bc2324c2ee115486b63677399de03de3aa42d998afba6bbb1c3c657acfd65d8e7acf5bfaa8ae9c7ecb3
7
+ data.tar.gz: 7be2b5cdef36f6f4d2d97f7103fcf72d79245b3c9fbdb2e18d70906999337fb01ade2ea235e6f7c456e3b6d088ba47144e9dfc4244329f44ed01d0ab58e4371b
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in behaviour.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Décio Ferreira
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,47 @@
1
+ # Behaviour (alpha version)
2
+
3
+ Behaviour generates the tests you need, to implement new features from scratch on your application.
4
+
5
+ Currently, there is only one feature available: user authentication.
6
+
7
+ ## About
8
+
9
+ Behaviour is a first attempt to rething the way we develop gems.
10
+
11
+ Instead of extending your code with the implementation for a new feature, the behaviour gem gives you the tests needed to confidently develop the new functionality.
12
+
13
+ Some of the advantages of this approach are:
14
+
15
+ * Learn by example, great source of community written tests
16
+ * Flexibility, easily adapt the generated tests to match the functionality wanted
17
+ * Testing, helps you writing tests for your application
18
+ * Freedom, to discover new ways of implementing features, and to adapt it to your own style/project
19
+ * Adaptable/dynamic, be in control of what features to implement, and how to implement them
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ gem 'behaviour', :group => :development
26
+
27
+ And then execute:
28
+
29
+ $ bundle
30
+
31
+ Or install it yourself as:
32
+
33
+ $ gem install behaviour
34
+
35
+ ## Usage
36
+
37
+ To generate the features and specs for the user authentication system run:
38
+
39
+ $ rails generate behaviour:authentication
40
+
41
+ ## Contributing
42
+
43
+ 1. Fork it ( http://github.com/decioferreira/behaviour/fork )
44
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
45
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
46
+ 4. Push to the branch (`git push origin my-new-feature`)
47
+ 5. Create new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task default: :test
7
+ task test: :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'behaviour/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "behaviour"
8
+ spec.version = Behaviour::VERSION
9
+ spec.authors = ["Décio Ferreira"]
10
+ spec.email = ["decio.ferreira@decioferreira.com"]
11
+ spec.summary = %q{Specify your application's behaviour.}
12
+ spec.description = %q{Add new features to your application by specifying behaviour.}
13
+ spec.homepage = ""
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
+
21
+ spec.add_runtime_dependency "rails"
22
+
23
+ spec.add_development_dependency "ammeter"
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec"
27
+ end
@@ -0,0 +1,4 @@
1
+ require "behaviour/version"
2
+
3
+ module Behaviour
4
+ end
@@ -0,0 +1,3 @@
1
+ module Behaviour
2
+ VERSION = "0.0.1-alpha"
3
+ end
@@ -0,0 +1,2 @@
1
+ Description:
2
+ Sets up authentication behaviour on your application.
@@ -0,0 +1,37 @@
1
+ module Behaviour
2
+ module Generators
3
+ class AuthenticationGenerator < ::Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ def gem_dependencies
7
+ gem_group :development, :test do
8
+ gem "rspec-rails", version: "~> 3.0.0.beta"
9
+ gem "rack_session_access"
10
+ end
11
+
12
+ gem_group :test do
13
+ gem "cucumber-rails", require: false
14
+ gem "database_cleaner"
15
+ end
16
+
17
+ run "bundle install"
18
+ end
19
+
20
+ def cucumber_setup
21
+ generate "cucumber:install"
22
+ end
23
+
24
+ def rspec_setup
25
+ generate "rspec:install"
26
+ end
27
+
28
+ def copy_spec_files
29
+ directory "spec"
30
+ end
31
+
32
+ def copy_feature_files
33
+ directory "features"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,13 @@
1
+ Feature: Reset password
2
+ Scenario: Receive reset password email
3
+ Given I am a registered user
4
+ When I ask for a password reset
5
+ Then I should receive a password reset email
6
+ And I should see a reset password email sent message
7
+
8
+ Scenario: Successful password reset
9
+ Given I received a password reset email
10
+ When I follow the reset password link
11
+ And I submit a valid new password
12
+ Then I should see a successful password reset message
13
+ And I should be signed in
@@ -0,0 +1,28 @@
1
+ Feature: Sign in
2
+ Scenario: Unauthenticated
3
+ When I access a page with restricted access
4
+ Then I should be redirected to the sign in page
5
+ And I should see an unauthenticated user message
6
+
7
+ Scenario: Successful sign in
8
+ Given I am a registered user
9
+ When I sign in with valid user data
10
+ Then I should see a successful sign in message
11
+ And I should be signed in
12
+
13
+ Scenario: Unregistered email
14
+ When I try to sign in with an unregistered email
15
+ Then I should see an invalid email message
16
+ And I should be signed out
17
+
18
+ Scenario: Wrong password
19
+ Given I am a registered user
20
+ When I try to sign in with a wrong password
21
+ Then I should see an invalid password message
22
+ And I should be signed out
23
+
24
+ Scenario: Already authenticated
25
+ Given I am signed in
26
+ When I access the sign in page
27
+ Then I should be redirected to the homepage
28
+ And I should see an already authenticated message
@@ -0,0 +1,7 @@
1
+ Feature: Sign out
2
+ Scenario: Successful sign out
3
+ Given I am signed in
4
+ When I sign out
5
+ Then I should be redirected to the homepage
6
+ And I should see a successful sign out message
7
+ And I should be signed out
@@ -0,0 +1,19 @@
1
+ Feature: Sign up
2
+ Scenario: Successful sign up
3
+ When I sign up with valid user data
4
+ Then I should be redirected to the homepage
5
+ And I should see a successful sign up message
6
+ And I should be signed in
7
+
8
+ Scenario: Already authenticated
9
+ Given I am signed in
10
+ When I access the sign up page
11
+ Then I should be redirected to the homepage
12
+ And I should see an already authenticated, sign out an try again message
13
+
14
+ Scenario: Already registered
15
+ Given I am a registered user
16
+ And I am signed out
17
+ When I sign up with valid user data
18
+ Then I should see an already registered message
19
+ And I should be signed out
@@ -0,0 +1,19 @@
1
+ Feature: Update Account
2
+ Scenario: Successful account update
3
+ Given I am signed in
4
+ When I update my password
5
+ Then I should see a successful account update message
6
+ And I should be signed in
7
+
8
+ Scenario: No current password
9
+ Given I am signed in
10
+ When I try to update my password without the current password
11
+ Then I should see a current password required message
12
+
13
+ Scenario: Sign in after account update
14
+ Given I am signed in
15
+ When I update my password
16
+ And I sign out
17
+ And I sign in with the new password
18
+ Then I should see a successful sign in message
19
+ And I should be signed in
@@ -0,0 +1,184 @@
1
+ Given(/^I am a registered user$/) do
2
+ steps %Q{
3
+ Given I sign up with valid user data
4
+ And I sign out
5
+ }
6
+ end
7
+
8
+ When(/^I ask for a password reset$/) do
9
+ visit "/reset_password"
10
+ fill_in "Email", with: user.email
11
+ click_button I18n.t("authentication.ask_reset_password_email.submit")
12
+ end
13
+
14
+ Then(/^I should receive a password reset email$/) do
15
+ expect(first_email.subject).to eq(I18n.t("authentication.email.reset_password.subject"))
16
+ end
17
+
18
+ Then(/^I should see a reset password email sent message$/) do
19
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_sent_reset_password_email"))
20
+ end
21
+
22
+ Given(/^I received a password reset email$/) do
23
+ steps %Q{
24
+ Given I am a registered user
25
+ And I ask for a password reset
26
+ Then I should receive a password reset email
27
+ }
28
+ end
29
+
30
+ When(/^I follow the reset password link$/) do
31
+ visit reset_password_path_from_email(first_email.body)
32
+ end
33
+
34
+ When(/^I submit a valid new password$/) do
35
+ fill_in "Password", with: user.new_password
36
+ fill_in "Confirm password", with: user.new_password
37
+ click_button I18n.t("authentication.reset_password.submit")
38
+ end
39
+
40
+ Then(/^I should see a successful password reset message$/) do
41
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_reset_password"))
42
+ end
43
+
44
+ Then(/^I should be signed in$/) do
45
+ expect { page.get_rack_session_key("user_id") }.not_to raise_error
46
+ end
47
+
48
+ When(/^I access a page with restricted access$/) do
49
+ visit "/restricted"
50
+ end
51
+
52
+ Then(/^I should be redirected to the sign in page$/) do
53
+ expect(current_path).to eq("/sign_in")
54
+ end
55
+
56
+ Then(/^I should see an unauthenticated user message$/) do
57
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.unauthenticated_user"))
58
+ end
59
+
60
+ When(/^I sign in with valid user data$/) do
61
+ visit "/sign_in"
62
+ fill_in "Email", with: user.email
63
+ fill_in "Password", with: user.password
64
+ click_button I18n.t("authentication.sign_in.submit")
65
+ end
66
+
67
+ Then(/^I should see a successful sign in message$/) do
68
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_signed_in"))
69
+ end
70
+
71
+ When(/^I try to sign in with an unregistered email$/) do
72
+ visit "/sign_in"
73
+ fill_in "Email", with: "unregistered@email.com"
74
+ fill_in "Password", with: user.password
75
+ click_button I18n.t("authentication.sign_in.submit")
76
+ end
77
+
78
+ Then(/^I should see an invalid email message$/) do
79
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.invalid_email"))
80
+ end
81
+
82
+ Then(/^I should be signed out$/) do
83
+ expect { page.get_rack_session_key("user_id") }.to raise_error(KeyError)
84
+ end
85
+
86
+ When(/^I try to sign in with a wrong password$/) do
87
+ visit "/sign_in"
88
+ fill_in "Email", with: user.email
89
+ fill_in "Password", with: "wrong_password"
90
+ click_button I18n.t("authentication.sign_in.submit")
91
+ end
92
+
93
+ Then(/^I should see an invalid password message$/) do
94
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.invalid_password"))
95
+ end
96
+
97
+ Given(/^I am signed in$/) do
98
+ steps %Q{
99
+ Given I sign up with valid user data
100
+ Then I should be signed in
101
+ }
102
+ end
103
+
104
+ When(/^I access the sign in page$/) do
105
+ visit "/sign_in"
106
+ end
107
+
108
+ Then(/^I should be redirected to the homepage$/) do
109
+ expect(current_path).to eq("/")
110
+ end
111
+
112
+ Then(/^I should see an already authenticated message$/) do
113
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.already_authenticated"))
114
+ end
115
+
116
+ When(/^I sign out$/) do
117
+ visit "/" unless page.has_button?("Sign out")
118
+ click_button I18n.t("authentication.sign_out.submit")
119
+ end
120
+
121
+ Then(/^I should see a successful sign out message$/) do
122
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_signed_out"))
123
+ end
124
+
125
+ When(/^I sign up with valid user data$/) do
126
+ visit "/sign_up"
127
+ fill_in "Email", with: user.email
128
+ fill_in "Password", with: user.password
129
+ fill_in "Confirm password", with: user.password
130
+ click_button I18n.t("authentication.sign_up.submit")
131
+ end
132
+
133
+ Then(/^I should see a successful sign up message$/) do
134
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_signed_up"))
135
+ end
136
+
137
+ When(/^I access the sign up page$/) do
138
+ visit "/sign_up"
139
+ end
140
+
141
+ Then(/^I should see an already authenticated, sign out an try again message$/) do
142
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.authenticated_sign_out_try_again"))
143
+ end
144
+
145
+ Given(/^I am signed out$/) do
146
+ visit "/" unless page.has_button?(I18n.t("authentication.action.sign_out"))
147
+ click_button I18n.t("authentication.action.sign_out")
148
+ end
149
+
150
+ Then(/^I should see an already registered message$/) do
151
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.already_registered"))
152
+ end
153
+
154
+ When(/^I update my password$/) do
155
+ visit "/account/edit"
156
+ fill_in "Password", with: user.new_password
157
+ fill_in "Confirm password", with: user.new_password
158
+ fill_in "Current password", with: user.password
159
+ click_button I18n.t("authentication.update_account.submit")
160
+ end
161
+
162
+ Then(/^I should see a successful account update message$/) do
163
+ expect(page).to have_selector("#notice-message", text: I18n.t("authentication.notice.successfully_updated_account"))
164
+ end
165
+
166
+ When(/^I try to update my password without the current password$/) do
167
+ visit "/account/edit"
168
+ fill_in "Password", with: user.new_password
169
+ fill_in "Confirm password", with: user.new_password
170
+ fill_in "Current password", with: ""
171
+ click_button I18n.t("authentication.update_account.submit")
172
+ end
173
+
174
+ Then(/^I should see a current password required message$/) do
175
+ expect(page).to have_selector("#alert-message", text: I18n.t("authentication.alert.current_password_required"))
176
+ end
177
+
178
+ When(/^I sign in with the new password$/) do
179
+ visit "/sign_in"
180
+ fill_in "Email", with: user.email
181
+ fill_in "Password", with: user.new_password
182
+ click_button I18n.t("authentication.sign_in.submit")
183
+ save_page
184
+ end
@@ -0,0 +1,18 @@
1
+ module Authentication
2
+ def user
3
+ OpenStruct.new(
4
+ email: "user@email.com",
5
+ password: "password"
6
+ )
7
+ end
8
+
9
+ def first_email
10
+ ActionMailer::Base.deliveries.first
11
+ end
12
+
13
+ def reset_password_path_from_email(body)
14
+ body.match(/https?:\/\/[^\/]+(\/reset\_password\/edit\?token=\h+)/)[1]
15
+ end
16
+ end
17
+
18
+ World(Authentication)
@@ -0,0 +1 @@
1
+ require_relative "../../spec/support/i18n"
@@ -0,0 +1,2 @@
1
+ require 'rspec/core'
2
+ require_relative "../../spec/support/syntax"
@@ -0,0 +1,99 @@
1
+ require 'spec_helper'
2
+
3
+ describe Authentication::ResetPasswordsController do
4
+ describe "GET new" do
5
+ context "when I am not logged in" do
6
+ before :each do
7
+ allow(controller).to receive(:signed_in?) { false }
8
+ get :new
9
+ end
10
+
11
+ it { expect(response).to render_template(:new) }
12
+ it { expect(response).to be_success }
13
+ end
14
+
15
+ context "when I am logged in" do
16
+ before :each do
17
+ allow(controller).to receive(:signed_in?) { true }
18
+ get :new
19
+ end
20
+
21
+ it { expect(response).to redirect_to root_path }
22
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
23
+ end
24
+ end
25
+
26
+ describe "POST create" do
27
+ context "when I am not logged in" do
28
+ let(:mailer) { double(:mailer).as_null_object }
29
+ let!(:user) { User.create(email: "valid@email.com", password: "password") }
30
+
31
+ before :each do
32
+ allow(AuthenticationMailer).to receive(:reset_password).and_return(mailer)
33
+ post :create, email: "valid@email.com"
34
+ end
35
+
36
+ it { expect(AuthenticationMailer).to have_received(:reset_password).with(user) }
37
+ it { expect(mailer).to have_received(:deliver) }
38
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_sent_reset_password_email")) }
39
+ it { expect(response).to render_template(:new) }
40
+ it { expect(response).to be_success }
41
+ end
42
+
43
+ context "when I am logged in" do
44
+ before :each do
45
+ allow(controller).to receive(:signed_in?) { true }
46
+ post :create
47
+ end
48
+
49
+ it { expect(response).to redirect_to root_path }
50
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
51
+ end
52
+ end
53
+
54
+ describe "GET edit" do
55
+ context "when I am not logged in" do
56
+ before :each do
57
+ allow(controller).to receive(:signed_in?) { false }
58
+ get :edit
59
+ end
60
+
61
+ it { expect(response).to render_template(:edit) }
62
+ it { expect(response).to be_success }
63
+ end
64
+
65
+ context "when I am logged in" do
66
+ before :each do
67
+ allow(controller).to receive(:signed_in?) { true }
68
+ get :edit
69
+ end
70
+
71
+ it { expect(response).to redirect_to root_path }
72
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
73
+ end
74
+ end
75
+
76
+ describe "PUT update" do
77
+ context "when I am not logged in" do
78
+ let!(:user) { User.create(email: "valid@email.com", password: "password") }
79
+
80
+ before :each do
81
+ put :update
82
+ end
83
+
84
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_reset_password")) }
85
+ it { expect(response).to render_template(:edit) }
86
+ it { expect(response).to be_success }
87
+ end
88
+
89
+ context "when I am logged in" do
90
+ before :each do
91
+ allow(controller).to receive(:signed_in?) { true }
92
+ put :update
93
+ end
94
+
95
+ it { expect(response).to redirect_to root_path }
96
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe Authentication::SessionsController do
4
+ describe "GET new" do
5
+ context "when I am not logged in" do
6
+ before :each do
7
+ allow(controller).to receive(:signed_in?) { false }
8
+ get :new
9
+ end
10
+
11
+ it { expect(response).to be_success }
12
+ end
13
+
14
+ context "when I am logged in" do
15
+ before :each do
16
+ allow(controller).to receive(:signed_in?) { true }
17
+ get :new
18
+ end
19
+
20
+ it { expect(response).to redirect_to root_path }
21
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.already_authenticated")) }
22
+ end
23
+ end
24
+
25
+ describe "POST create" do
26
+ context "when I am not logged in" do
27
+ before :each do
28
+ allow(controller).to receive(:signed_in?) { false }
29
+ end
30
+
31
+ context "when I am successfully registered" do
32
+ let!(:user) { User.create(email: "valid@email.com", password: "validpassword") }
33
+
34
+ context "when I sign in with a valid email" do
35
+ before :each do
36
+ post :create, email: "valid@email.com", password: "validpassword"
37
+ end
38
+
39
+ it { expect(response).to redirect_to root_path }
40
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_signed_in")) }
41
+ it { expect(session[:user_id]).to eq(user.id) }
42
+ end
43
+
44
+ context "when I sign in with an invalid email" do
45
+ before :each do
46
+ post :create, email: "invalid@email.com", password: "password"
47
+ end
48
+
49
+ it { expect(response).to be_success }
50
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.invalid_email")) }
51
+ end
52
+
53
+ context "when I sign in with an invalid password" do
54
+ before :each do
55
+ post :create, email: "valid@email.com", password: "invalid"
56
+ end
57
+
58
+ it { expect(response).to be_success }
59
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.invalid_password")) }
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when I am logged in" do
65
+ before :each do
66
+ allow(controller).to receive(:signed_in?) { true }
67
+ post :create
68
+ end
69
+
70
+ it { expect(response).to redirect_to root_path }
71
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.already_authenticated")) }
72
+ end
73
+ end
74
+
75
+ describe "DELETE destroy" do
76
+ context "when I am not logged in" do
77
+ before :each do
78
+ delete :destroy
79
+ end
80
+
81
+ it { expect(response).to redirect_to root_path }
82
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_signed_out")) }
83
+ end
84
+
85
+ context "when I am logged in" do
86
+ let!(:user) { User.create(email: "valid@email.com", password: "validpassword") }
87
+
88
+ before :each do
89
+ session[:user_id] = user.id
90
+ delete :destroy
91
+ end
92
+
93
+ it { expect(response).to redirect_to root_path }
94
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_signed_out")) }
95
+ it { expect(session[:user_id]).to be_nil }
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,107 @@
1
+ require 'spec_helper'
2
+
3
+ describe Authentication::UsersController do
4
+ describe "GET new" do
5
+ context "when I am not logged in" do
6
+ before :each do
7
+ allow(controller).to receive(:signed_in?) { false }
8
+ get :new
9
+ end
10
+
11
+ it { expect(response).to be_success }
12
+ end
13
+
14
+ context "when I am logged in" do
15
+ before :each do
16
+ allow(controller).to receive(:signed_in?) { true }
17
+ get :new
18
+ end
19
+
20
+ it { expect(response).to redirect_to root_path }
21
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
22
+ end
23
+ end
24
+
25
+ describe "POST create" do
26
+ context "when I am not logged in" do
27
+ before :each do
28
+ allow(controller).to receive(:signed_in?) { false }
29
+ end
30
+
31
+ context "when I submit valid data" do
32
+ before :each do
33
+ allow(controller).to receive(:signed_in?) { false }
34
+ post :create, email: "valid@email.com", password: "password"
35
+ end
36
+
37
+ it { expect(response).to redirect_to root_path }
38
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_signed_up")) }
39
+
40
+ it "logs me in" do
41
+ expect(User.count).to eq(1)
42
+ expect(session[:user_id]).to eq(User.first.id)
43
+ end
44
+ end
45
+ end
46
+
47
+ context "when I am logged in" do
48
+ before :each do
49
+ allow(controller).to receive(:signed_in?) { true }
50
+ post :create
51
+ end
52
+
53
+ it { expect(response).to redirect_to root_path }
54
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.authenticated_sign_out_try_again")) }
55
+ end
56
+ end
57
+
58
+ describe "GET edit" do
59
+ context "when I am not logged in" do
60
+ before :each do
61
+ allow(controller).to receive(:signed_in?) { false }
62
+ get :edit
63
+ end
64
+
65
+ it { expect(response).to redirect_to root_path }
66
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.unauthenticated_user")) }
67
+ end
68
+
69
+ context "when I am logged in" do
70
+ before :each do
71
+ allow(controller).to receive(:signed_in?) { true }
72
+ get :edit
73
+ end
74
+
75
+ it { expect(response).to be_success }
76
+ end
77
+ end
78
+
79
+ describe "PUT update" do
80
+ context "when I am not logged in" do
81
+ before :each do
82
+ allow(controller).to receive(:signed_in?) { false }
83
+ put :update
84
+ end
85
+
86
+ it { expect(response).to redirect_to root_path }
87
+ it { expect(flash[:alert]).to eq(I18n.t("authentication.alert.unauthenticated_user")) }
88
+ end
89
+
90
+ context "when I am logged in" do
91
+ let(:user) { User.create(email: "valid@email.com", password: "password") }
92
+
93
+ before :each do
94
+ session[:user_id] = user.id
95
+ end
96
+
97
+ context "when I submit valid data" do
98
+ before :each do
99
+ put :update, password: "new_password", current_password: "password"
100
+ end
101
+
102
+ it { expect(response).to be_success }
103
+ it { expect(flash[:notice]).to eq(I18n.t("authentication.notice.successfully_updated_account")) }
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,14 @@
1
+ # Source: http://guides.rubyonrails.org/i18n.html#using-different-exception-handlers
2
+ module I18n
3
+ class JustRaiseExceptionHandler < ExceptionHandler
4
+ def call(exception, locale, key, options)
5
+ if exception.is_a?(MissingTranslation)
6
+ raise exception.to_exception
7
+ else
8
+ super
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ I18n.exception_handler = I18n::JustRaiseExceptionHandler.new
@@ -0,0 +1,6 @@
1
+ # Source: http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax#configuration_options
2
+ RSpec.configure do |config|
3
+ config.expect_with :rspec do |c|
4
+ c.syntax = :expect
5
+ end
6
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
@@ -0,0 +1,62 @@
1
+ require "spec_helper"
2
+ require "generators/behaviour/authentication/authentication_generator"
3
+
4
+ describe Behaviour::Generators::AuthenticationGenerator do
5
+ # Tell the generator where to put its output (what it thinks of as Rails.root)
6
+ destination File.expand_path("../../../../../tmp", __FILE__)
7
+
8
+ before do
9
+ prepare_destination
10
+ FileUtils.cp_r "spec/dummy/.", destination_root
11
+ end
12
+
13
+ describe "no arguments" do
14
+ before { run_generator }
15
+
16
+ describe "Gemfile" do
17
+ subject { file("Gemfile") }
18
+
19
+ it {
20
+ expect(subject).to contain <<-GROUP
21
+ group :development, :test do
22
+ gem "rspec-rails", "~> 3.0.0.beta"
23
+ gem "rack_session_access"
24
+ end
25
+ GROUP
26
+ }
27
+
28
+ it {
29
+ expect(subject).to contain <<-GROUP
30
+ group :test do
31
+ gem "cucumber-rails", require: false
32
+ gem "database_cleaner"
33
+ end
34
+ GROUP
35
+ }
36
+ end
37
+
38
+ describe "features" do
39
+ it { expect(file("features/authentication/reset_password.feature")).to exist }
40
+ it { expect(file("features/authentication/sign_in.feature")).to exist }
41
+ it { expect(file("features/authentication/sign_out.feature")).to exist }
42
+ it { expect(file("features/authentication/sign_up.feature")).to exist }
43
+ it { expect(file("features/authentication/update_account.feature")).to exist }
44
+
45
+ it { expect(file("features/step_definitions/authentication.rb")).to exist }
46
+
47
+ it { expect(file("features/support/authentication.rb")).to exist }
48
+ it { expect(file("features/support/i18n.rb")).to exist }
49
+ it { expect(file("features/support/rack_session_access.rb")).to exist }
50
+ it { expect(file("features/support/rspec_syntax.rb")).to exist }
51
+ end
52
+
53
+ describe "specs" do
54
+ it { expect(file("spec/controllers/authentication/reset_passwords_controller_spec.rb")).to exist }
55
+ it { expect(file("spec/controllers/authentication/sessions_controller_spec.rb")).to exist }
56
+ it { expect(file("spec/controllers/authentication/users_controller_spec.rb")).to exist }
57
+
58
+ it { expect(file("spec/support/i18n.rb")).to exist }
59
+ it { expect(file("spec/support/syntax.rb")).to exist }
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,2 @@
1
+ require 'rails/all'
2
+ require 'ammeter/init'
metadata ADDED
@@ -0,0 +1,149 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: behaviour
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1.pre.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Décio Ferreira
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ammeter
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Add new features to your application by specifying behaviour.
84
+ email:
85
+ - decio.ferreira@decioferreira.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - behaviour.gemspec
97
+ - lib/behaviour.rb
98
+ - lib/behaviour/version.rb
99
+ - lib/generators/behaviour/authentication/USAGE
100
+ - lib/generators/behaviour/authentication/authentication_generator.rb
101
+ - lib/generators/behaviour/authentication/templates/.rspec
102
+ - lib/generators/behaviour/authentication/templates/features/authentication/reset_password.feature
103
+ - lib/generators/behaviour/authentication/templates/features/authentication/sign_in.feature
104
+ - lib/generators/behaviour/authentication/templates/features/authentication/sign_out.feature
105
+ - lib/generators/behaviour/authentication/templates/features/authentication/sign_up.feature
106
+ - lib/generators/behaviour/authentication/templates/features/authentication/update_account.feature
107
+ - lib/generators/behaviour/authentication/templates/features/step_definitions/authentication.rb
108
+ - lib/generators/behaviour/authentication/templates/features/support/authentication.rb
109
+ - lib/generators/behaviour/authentication/templates/features/support/i18n.rb
110
+ - lib/generators/behaviour/authentication/templates/features/support/rack_session_access.rb
111
+ - lib/generators/behaviour/authentication/templates/features/support/rspec_syntax.rb
112
+ - lib/generators/behaviour/authentication/templates/spec/controllers/authentication/reset_passwords_controller_spec.rb
113
+ - lib/generators/behaviour/authentication/templates/spec/controllers/authentication/sessions_controller_spec.rb
114
+ - lib/generators/behaviour/authentication/templates/spec/controllers/authentication/users_controller_spec.rb
115
+ - lib/generators/behaviour/authentication/templates/spec/support/i18n.rb
116
+ - lib/generators/behaviour/authentication/templates/spec/support/syntax.rb
117
+ - spec/dummy/Gemfile
118
+ - spec/dummy/bin/rails
119
+ - spec/generators/behaviour/authentication/authentication_generator_spec.rb
120
+ - spec/spec_helper.rb
121
+ homepage: ''
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.3.1
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.2.0.rc.1
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Specify your application's behaviour.
145
+ test_files:
146
+ - spec/dummy/Gemfile
147
+ - spec/dummy/bin/rails
148
+ - spec/generators/behaviour/authentication/authentication_generator_spec.rb
149
+ - spec/spec_helper.rb