behaviour 0.0.1.pre.alpha

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.
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