mj-suspenders 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +3 -3
  3. data/bin/mj-suspenders +0 -5
  4. data/lib/suspenders/app_builder.rb +87 -1
  5. data/lib/suspenders/generators/app_generator.rb +7 -0
  6. data/lib/suspenders/version.rb +1 -1
  7. data/templates/Gemfile.erb +10 -1
  8. data/templates/MIT-LICENSE.erb +20 -0
  9. data/templates/README.md.erb +5 -2
  10. data/templates/app/controllers/omniauth_callbacks_controller.rb +40 -0
  11. data/templates/app/models/concerns/.keep +0 -0
  12. data/templates/app/models/oauth/base.rb +21 -0
  13. data/templates/app/models/oauth/facebook.rb +4 -0
  14. data/templates/app/models/oauth/github.rb +4 -0
  15. data/templates/app/models/oauth/google.rb +7 -0
  16. data/templates/app/models/user.rb +12 -0
  17. data/templates/app/views/application/_login_button.html.erb +10 -0
  18. data/templates/app/views/application/_login_links.html.erb +11 -0
  19. data/templates/app/views/application/_login_status.html.erb +1 -0
  20. data/templates/coveralls.yml +1 -0
  21. data/templates/db/migrate/20140522135601_devise_create_users.rb +48 -0
  22. data/templates/db/migrate/20140522142949_add_name_to_users.rb +5 -0
  23. data/templates/pt-BR.yml +1 -26
  24. data/templates/spec/controllers/omniauth_callbacks_controller_spec.rb +26 -0
  25. data/templates/spec/models/oauth/base_spec.rb +4 -0
  26. data/templates/spec/models/oauth/facebook_spec.rb +6 -0
  27. data/templates/spec/models/oauth/github_spec.rb +6 -0
  28. data/templates/spec/models/oauth/google_spec.rb +6 -0
  29. data/templates/spec/models/user_spec.rb +24 -0
  30. data/templates/spec/support/blueprints.rb +16 -0
  31. data/templates/spec/support/capybara_helper.rb +73 -0
  32. data/templates/spec/support/database_cleaner.rb +21 -0
  33. data/templates/spec/support/email_format_validation.rb +39 -0
  34. data/templates/spec/support/features/.keep +0 -0
  35. data/templates/spec/support/features/oauth_login_specs.rb +33 -0
  36. data/templates/spec/support/i18n.rb +3 -0
  37. data/templates/spec/support/matchers/.keep +0 -0
  38. data/templates/spec/support/mixins/.keep +0 -0
  39. data/templates/spec/support/oauth_providers.rb +63 -0
  40. data/templates/spec/support/omniauth_controller_specs.rb +46 -0
  41. data/templates/spec/support/omniauth_model_specs.rb +52 -0
  42. data/templates/spec/support/records.rb +9 -0
  43. data/templates/spec/support/shared_examples/.keep +0 -0
  44. data/templates/spec_helper.rb +12 -1
  45. data/templates/suspenders_layout.html.erb.erb +2 -0
  46. data/templates/system.pt-BR.yml +29 -0
  47. data/templates/travis.yml.erb +1 -1
  48. metadata +37 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 010107e642701974deff8096e6c52eae616a585d
4
- data.tar.gz: 65050d708ad0bc6207e2a7bc9162e20ab9118e00
3
+ metadata.gz: 84851a4936e65fc87d9a1b803c7db885c23800a6
4
+ data.tar.gz: 04fe033e2c9b60cdd4e09376bd04d6ca40a7d1f3
5
5
  SHA512:
6
- metadata.gz: ed5258f3379bf3178d579e8664fd07bc82936d73a20699383f80f48d066deb631e251056638e4564455615874067a95eabdd84c6f7f44170447afd49a00790fb
7
- data.tar.gz: 06c52592d210680f14409c50887c6d4f4865cc308b1f40b09549690516b5023cfe2b7e19eafdaf1a42c63544ef2451c01d10ab6a82760496eebe6796b0646960
6
+ metadata.gz: 0c08e662a92957c733f45247617fdd614543b3759e7d97e889780e73bc07dacedd9cea4c02e11522d13f0e00d4f29ac2d918e1d1198e539843dc465983793059
7
+ data.tar.gz: 034b23a3c741744779a8f47f079179d5f84b45edc6524de41f916f8f0d29f51470f8fa3abb506ef8b2ea2bedcac183a4d482454f713c8fb7a1e9fab492419c2a
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mj-suspenders (0.0.7)
4
+ mj-suspenders (0.0.8)
5
5
  bundler (~> 1.6)
6
6
  rails (= 4.1.1)
7
7
 
@@ -67,7 +67,7 @@ GEM
67
67
  treetop (~> 1.4.8)
68
68
  mime-types (1.25.1)
69
69
  mini_portile (0.5.3)
70
- minitest (5.3.3)
70
+ minitest (5.3.4)
71
71
  multi_json (1.9.2)
72
72
  multi_test (0.1.1)
73
73
  nokogiri (1.6.1)
@@ -91,7 +91,7 @@ GEM
91
91
  activesupport (= 4.1.1)
92
92
  rake (>= 0.8.7)
93
93
  thor (>= 0.18.1, < 2.0)
94
- rake (10.3.1)
94
+ rake (10.3.2)
95
95
  rspec (2.14.1)
96
96
  rspec-core (~> 2.14.0)
97
97
  rspec-expectations (~> 2.14.0)
data/bin/mj-suspenders CHANGED
@@ -6,11 +6,6 @@ $LOAD_PATH << source_path
6
6
 
7
7
  require 'suspenders'
8
8
 
9
- if ['create', '--create'].include? ARGV[0]
10
- ARGV.shift
11
- puts "[WARNING] the suspenders create argument is deprecated. Just use `suspenders #{ARGV.join}` instead"
12
- end
13
-
14
9
  templates_root = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
15
10
  Suspenders::AppGenerator.source_root templates_root
16
11
  Suspenders::AppGenerator.source_paths << Rails::Generators::AppGenerator.source_root << templates_root
@@ -4,6 +4,7 @@ module Suspenders
4
4
 
5
5
  def readme
6
6
  template 'README.md.erb', 'README.md'
7
+ template 'MIT-LICENSE.erb', 'MIT-LICENSE.md'
7
8
  end
8
9
 
9
10
  def raise_on_delivery_errors
@@ -44,6 +45,85 @@ module Suspenders
44
45
  inject_into_class 'config/application.rb', 'Application', config
45
46
  end
46
47
 
48
+ def generate_devise
49
+ generate 'devise:install'
50
+
51
+ config = <<CODE
52
+
53
+ if ENV['GITHUB_KEY']
54
+ config.omniauth :github, ENV['GITHUB_KEY'], ENV['FACEBOOK_SECRET'],
55
+ scope: 'email,public_repo'
56
+ end
57
+
58
+ if ENV['FACEBOOK_KEY']
59
+ config.omniauth :facebook, ENV['FACEBOOK_KEY'], ENV['FACEBOOK_SECRET'],
60
+ scope: 'email'
61
+ end
62
+
63
+ if ENV['GOOGLE_KEY']
64
+ config.omniauth :google_oauth2, ENV['GOOGLE_KEY'], ENV['GOOGLE_SECRET'],
65
+ scope: 'email', strategy_class: OmniAuth::Strategies::GoogleOAuth2
66
+ end
67
+ CODE
68
+
69
+ inject_into_file 'config/initializers/devise.rb', config, before: "\nend"
70
+
71
+ create_oauth_config(:development)
72
+ create_oauth_config(:test)
73
+ create_oauth_config(:staging)
74
+ create_oauth_config(:production)
75
+ end
76
+
77
+ def create_oauth_config(env)
78
+ application(nil, env: env) do
79
+ <<CODE
80
+ ENV['FACEBOOK_KEY'] = 'fake'
81
+ ENV['FACEBOOK_SECRET'] = 'fake'
82
+ ENV['GOOGLE_KEY'] = 'fake'
83
+ ENV['GOOGLE_SECRET'] = 'fake'
84
+ ENV['GITHUB_KEY'] = 'fake'
85
+ ENV['GITHUB_SECRET'] = 'fake'
86
+ CODE
87
+ end
88
+ end
89
+
90
+ def setup_user_auth
91
+ %w(
92
+ db/migrate/20140522135601_devise_create_users.rb
93
+ db/migrate/20140522142949_add_name_to_users.rb
94
+ app/views/application/_login_button.html.erb
95
+ app/views/application/_login_status.html.erb
96
+ app/views/application/_login_links.html.erb
97
+ app/controllers/omniauth_callbacks_controller.rb
98
+ spec/controllers/omniauth_callbacks_controller_spec.rb
99
+ app/models/user.rb
100
+ spec/models/user_spec.rb
101
+ ).each do |file|
102
+ copy_file file, file, force: true
103
+ end
104
+
105
+ %w(
106
+ app/models/oauth
107
+ spec/models/oauth
108
+ spec/support
109
+ ).each do |dir|
110
+ directory dir
111
+ end
112
+
113
+ omniauth_routes = <<CODE
114
+
115
+ devise_for :users, controllers: {
116
+ omniauth_callbacks: "omniauth_callbacks"
117
+ }
118
+
119
+ devise_scope :user do
120
+ get 'sign_in', to: 'devise/sessions#new', as: :new_user_session
121
+ get 'sign_out', to: 'devise/sessions#destroy', as: :destroy_user_session
122
+ end
123
+ CODE
124
+ route omniauth_routes
125
+ end
126
+
47
127
  def generate_machinist
48
128
  generate 'machinist:install'
49
129
  end
@@ -159,6 +239,10 @@ end
159
239
  template 'travis.yml.erb', '.travis.yml'
160
240
  end
161
241
 
242
+ def configure_coveralls
243
+ template 'coveralls.yml', '.coveralls.yml'
244
+ end
245
+
162
246
  def configure_i18n_in_specs
163
247
  copy_file 'i18n.rb', 'spec/support/i18n.rb'
164
248
  end
@@ -196,8 +280,10 @@ end
196
280
  end
197
281
 
198
282
  def set_i18n
199
- copy_file 'devise.en.yml', 'config/locales/devise.en.yml'
283
+ copy_file 'devise.en.yml', 'config/locales/devise.en.yml', force: true
200
284
  copy_file 'devise.pt-BR.yml', 'config/locales/devise.pt-BR.yml'
285
+ copy_file 'pt-BR.yml', 'config/locales/pt-BR.yml'
286
+ copy_file 'system.pt-BR.yml', 'config/locales/system.pt-BR.yml'
201
287
 
202
288
  config = <<-RUBY
203
289
  config.i18n.default_locale = 'pt-BR'
@@ -30,6 +30,7 @@ module Suspenders
30
30
  invoke :customize_error_pages
31
31
  invoke :remove_routes_comment_lines
32
32
  invoke :setup_home_page
33
+ invoke :setup_oauth
33
34
  invoke :setup_git
34
35
  end
35
36
 
@@ -66,9 +67,15 @@ module Suspenders
66
67
  build :enable_database_cleaner
67
68
  build :configure_spec_support_features
68
69
  build :configure_travis
70
+ build :configure_coveralls
69
71
  build :configure_i18n_in_specs
70
72
  end
71
73
 
74
+ def setup_oauth
75
+ build :generate_devise
76
+ build :setup_user_auth
77
+ end
78
+
72
79
  def setup_production_environment
73
80
  say 'Setting up the production environment'
74
81
  build :enable_rack_deflater
@@ -1,3 +1,3 @@
1
1
  module Suspenders
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- ruby '<%= RUBY_VERSION %>'
3
+ # ruby '<%= RUBY_VERSION %>'
4
4
 
5
5
  gem 'rails', '4.1.0'
6
6
  gem 'sass-rails', '~> 4.0.3'
@@ -20,6 +20,13 @@ gem 'spring', group: :development
20
20
 
21
21
  # Rails non default
22
22
 
23
+ # Auth
24
+ gem 'devise'
25
+ gem 'omniauth'
26
+ gem 'omniauth-facebook'
27
+ gem 'omniauth-google_oauth2'
28
+ gem 'omniauth-github'
29
+
23
30
  gem 'email_validator'
24
31
  gem 'high_voltage'
25
32
  gem 'mysql2'
@@ -40,9 +47,11 @@ group :development, :test do
40
47
  gem 'pry-rails'
41
48
  gem 'rspec-rails', '~> 3.0.0.beta'
42
49
  gem 'machinist', '>= 2.0.0.beta2'
50
+ gem 'coveralls'
43
51
  end
44
52
 
45
53
  group :test do
54
+ gem "capybara"
46
55
  # gem 'capybara-webkit', '>= 1.0.0'
47
56
  gem 'database_cleaner'
48
57
  # gem 'launchy'
@@ -0,0 +1,20 @@
1
+ Copyright <%= Time.now.year %> Marcelo Guilherme Jacobus Jr
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -4,6 +4,7 @@
4
4
  [![Build Status](https://travis-ci.org/mjacobus/<%= app_name %>.png?branch=master)](https://travis-ci.org/mjacobus/<%= app_name %>)
5
5
  [![Coverage Status](https://coveralls.io/repos/mjacobus/<%= app_name %>/badge.png)](https://coveralls.io/r/mjacobus/<%= app_name %>)
6
6
  [![Code Climate](https://codeclimate.com/github/mjacobus/<%= app_name %>.png)](https://codeclimate.com/github/mjacobus/<%= app_name %>)
7
+ [![Dependency Status](https://gemnasium.com/mjacobus/<%= app_name %>.png)](https://gemnasium.com/mjacobus/<%= app_name %>)
7
8
 
8
9
  Getting Started
9
10
  ---------------
@@ -20,8 +21,10 @@ programming in style.
20
21
  * [Best Practices](http://github.com/thoughtbot/guides/blob/master/best-practices)
21
22
  * [Style](http://github.com/thoughtbot/guides/blob/master/style)
22
23
 
23
- Authors
24
- -------
24
+ ## Lincense
25
+ [MIT](MIT-LICENSE)
26
+
27
+ ## Authors
25
28
 
26
29
  - [Marcelo Jacobus](https://github.com/mjacobus)
27
30
 
@@ -0,0 +1,40 @@
1
+ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
2
+
3
+ def facebook
4
+ login_with(Oauth::Facebook)
5
+ end
6
+
7
+ def google_oauth2
8
+ login_with(Oauth::Google)
9
+ end
10
+
11
+ def github
12
+ login_with(Oauth::Github)
13
+ end
14
+
15
+ def login_with(klass)
16
+ env = request.env["omniauth.auth"]
17
+ origin = request.env["omniauth.origin"]
18
+ user = klass.find_or_build_user(env)
19
+ redirect_url = redirect_url_for(user, origin)
20
+ message = login_message(user)
21
+ user.save!(validate: false)
22
+ sign_in(user, event: :authentication)
23
+ redirect_to redirect_url, notice: message, only_path: true
24
+ end
25
+
26
+ def login_message(user)
27
+ key = user.new_record? ? 'account_created' : 'login_succeed'
28
+ I18n.t("system.messages.#{key}")
29
+ end
30
+
31
+ def redirect_url_for(user, origin = nil)
32
+ root_path
33
+ end
34
+
35
+ def relative_path(url)
36
+ matches = url.match(/^http(s)?:\/\/[^\/]+(.*)/)
37
+ matches ? matches[2] : url
38
+ end
39
+
40
+ end
File without changes
@@ -0,0 +1,21 @@
1
+ module Oauth
2
+ class Base
3
+ def self.provider_key
4
+ to_s.underscore.split('/').last.to_sym
5
+ end
6
+
7
+ def self.find_or_build_user(params)
8
+ user = User.where(uid: params[:uid], provider: provider_key).first
9
+
10
+ unless user
11
+ user = User.new
12
+ user.uid = params[:uid]
13
+ user.provider = provider_key
14
+ end
15
+
16
+ user.email = params[:info][:email]
17
+ user.name = params[:info][:name]
18
+ user
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module Oauth
2
+ class Facebook < Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Oauth
2
+ class Github < Base
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module Oauth
2
+ class Google < Base
3
+ def self.provider_key
4
+ :google_oauth2
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ class User < ActiveRecord::Base
2
+ devise :omniauthable, :trackable
3
+ serialize :provider_data, JSON
4
+
5
+ validates :name, presence: true
6
+
7
+ validates :email, presence: true, email: true, uniqueness: {
8
+ case_sensitive: false
9
+ }
10
+
11
+ validates :uid, uniqueness: { case_sensitive: false, scope: :provider }
12
+ end
@@ -0,0 +1,10 @@
1
+ <%
2
+ options = {
3
+ class: "login #{provider}",
4
+ title: t("system.messages.login_with.#{provider}")
5
+ }
6
+ %>
7
+
8
+ <%= link_to user_omniauth_authorize_path(provider), options do %>
9
+ <%= t("system.links.login.#{provider}") %>
10
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <% if ENV['FACEBOOK_KEY'] %>
2
+ <%= render 'login_button', provider: :facebook %>
3
+ <% end %>
4
+
5
+ <% if ENV['GOOGLE_KEY'] %>
6
+ <%= render 'login_button', provider: :google_oauth2 %>
7
+ <% end %>
8
+
9
+ <% if ENV['GITHUB_KEY'] %>
10
+ <%= render 'login_button', provider: :github %>
11
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= link_to t('system.links.logout'), :destroy_user_session %>
@@ -0,0 +1 @@
1
+ repo_token: repo_token_here
@@ -0,0 +1,48 @@
1
+ class DeviseCreateUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table(:users) do |t|
4
+ ## Database authenticatable
5
+ t.string :email, :null => false, :default => ""
6
+ # t.string :encrypted_password, :null => false, :default => ""
7
+
8
+ ## Recoverable
9
+ # t.string :reset_password_token
10
+ # t.datetime :reset_password_sent_at
11
+
12
+ ## Rememberable
13
+ t.datetime :remember_created_at
14
+
15
+ ## Trackable
16
+ t.integer :sign_in_count, :default => 0, :null => false
17
+ t.datetime :current_sign_in_at
18
+ t.datetime :last_sign_in_at
19
+ t.string :current_sign_in_ip
20
+ t.string :last_sign_in_ip
21
+
22
+ ## Confirmable
23
+ # t.string :confirmation_token
24
+ # t.datetime :confirmed_at
25
+ # t.datetime :confirmation_sent_at
26
+ # t.string :unconfirmed_email # Only if using reconfirmable
27
+
28
+ ## Lockable
29
+ # t.integer :failed_attempts, :default => 0, :null => false # Only if lock strategy is :failed_attempts
30
+ # t.string :unlock_token # Only if unlock strategy is :email or :both
31
+ # t.datetime :locked_at
32
+
33
+
34
+ t.timestamps
35
+
36
+ ## omniauthable
37
+ t.string :provider
38
+ t.string :uid
39
+ t.text :provider_data
40
+ end
41
+
42
+ add_index :users, :email, :unique => true
43
+ # add_index :users, :reset_password_token, :unique => true
44
+ # add_index :users, :confirmation_token, :unique => true
45
+ # add_index :users, :unlock_token, :unique => true
46
+ add_index :users, [:provider, :uid], unique: true
47
+ end
48
+ end
@@ -0,0 +1,5 @@
1
+ class AddNameToUsers < ActiveRecord::Migration
2
+ def change
3
+ add_column :users, :name, :string
4
+ end
5
+ end
data/templates/pt-BR.yml CHANGED
@@ -214,30 +214,5 @@ pt-BR:
214
214
  attributes:
215
215
  user:
216
216
  username: Nome
217
- order:
218
- email: Email
219
- phone: Telefone
220
- address_street: Rua
221
- address_number: Número
222
- address_complement: Complemento
223
- address_district: Bairro
224
- address_city: Cidade
225
- address_state: Estado
226
- address: Endereço
227
- status: Situação
228
- store:
229
217
  name: Nome
230
- slug: Url
231
- city: Cidade
232
- type: Tipo
233
- address: Endereço
234
- phone: Telefone
235
- email: Email
236
- state_id: Estado
237
- category: Categoria
238
- category_id: Categoria
239
- payment_gateway_configuration:
240
- name: Nome
241
- enabled: Ativo?
242
- email: Email
243
- token: Token
218
+ provider: Provedor
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe OmniauthCallbacksController do
4
+ include OmniauthControllerSpecs
5
+
6
+ it_logs_in_with(Oauth::Facebook)
7
+ it_logs_in_with(Oauth::Github)
8
+ it_logs_in_with(Oauth::Google)
9
+
10
+ describe "#redirect_url_for" do
11
+ it "redirects to root path after the login" do
12
+ expect(controller.redirect_url_for(user)).to eq(root_path)
13
+ end
14
+ end
15
+
16
+ describe "#relative_path" do
17
+ it "returns the relative path when full url is given" do
18
+ expect(controller.relative_path('http://www.someurl.com/abc?foo=bar')).to eq('/abc?foo=bar')
19
+ expect(controller.relative_path('https://www.someurl.com/abc?foo=bar')).to eq('/abc?foo=bar')
20
+ end
21
+
22
+ it "returns the param given if given url does not match given url" do
23
+ expect(controller.relative_path('abc?foo=bar')).to eq('abc?foo=bar')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe Oauth::Base do
4
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe Oauth::Facebook do
4
+ include OmniauthModelSpecs
5
+ it_behaves_like_a_strategy_model(Oauth::Facebook, :facebook);
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe Oauth::Github do
4
+ include OmniauthModelSpecs
5
+ it_behaves_like_a_strategy_model(Oauth::Github, :github);
6
+ end
@@ -0,0 +1,6 @@
1
+ require 'spec_helper'
2
+
3
+ describe Oauth::Google do
4
+ include OmniauthModelSpecs
5
+ it_behaves_like_a_strategy_model(Oauth::Google, :google_oauth2);
6
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe User, "#name" do
4
+ it { should validate_presence_of(:name) }
5
+ end
6
+
7
+ describe User, "#email" do
8
+ it { should validate_presence_of(:email) }
9
+ it { should validate_uniqueness_of(:email).case_insensitive }
10
+ it_validates_email_format_of :email
11
+ end
12
+
13
+ describe User, "#uid" do
14
+ it { should validate_uniqueness_of(:uid).case_insensitive.scoped_to(:provider) }
15
+ end
16
+
17
+ describe User, "#provider_data" do
18
+ it "stores json serialized data" do
19
+ data = { 'some' => 'data' }
20
+ user = User.make!(provider_data: data)
21
+ user.reload
22
+ expect(user.provider_data).to eq(data)
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ require 'machinist/active_record'
2
+
3
+ # Add your blueprints here.
4
+ #
5
+ # e.g.
6
+ # Post.blueprint do
7
+ # title { "Post #{sn}" }
8
+ # body { "Lorem ipsum..." }
9
+ # end
10
+
11
+ User.blueprint do
12
+ name { "The Name #{sn}" }
13
+ email { "email#{sn}@example.com" }
14
+ provider { 'github' }
15
+ uid { sn }
16
+ end
@@ -0,0 +1,73 @@
1
+ module CapybaraHelper
2
+
3
+ def manage_store(provider = :facebook)
4
+ create_dependencies
5
+ login_with(provider)
6
+ OwnershipAssignment.new(User.last, Store.make!).assign!
7
+ visit managers_stores_path
8
+ end
9
+
10
+ def login_with(provider = :facebook)
11
+ visit root_url
12
+ first(:link, I18n.t("system.links.login.#{provider}")).click
13
+ end
14
+
15
+ def t(*args)
16
+ I18n.t(*args)
17
+ end
18
+
19
+ def root_url
20
+ Capybara.app_host
21
+ end
22
+
23
+ def logout
24
+ click_link I18n.t('system.links.logout')
25
+ expect(page).not_to have_text(last_user.name)
26
+ end
27
+
28
+ def last_user
29
+ User.last
30
+ end
31
+
32
+ def switch_to_subdomain(subdomain)
33
+ # resolve subdomain to 127.0.0.1
34
+ subdomain = subdomain ? "#{subdomain}.#{domain}" : "www.#{domain}"
35
+ Capybara.app_host = "http://#{subdomain}"
36
+ Capybara.app_host
37
+ end
38
+
39
+ def switch_to_main_domain
40
+ switch_to_subdomain nil
41
+ end
42
+
43
+ def create_dependencies
44
+ state
45
+ store_category
46
+ end
47
+
48
+ def click_submit_button
49
+ click_button I18n.t('system.links.save')
50
+ end
51
+
52
+ def create_store
53
+ within('#new_store') do
54
+ fill_in 'store[name]', with: 'My Store'
55
+ fill_in 'store[slug]', with: 'my-store'
56
+ select state.name, from: 'store[state_id]'
57
+ select store_category.name, from: 'store[category_id]'
58
+ fill_in 'store[address]', with: 'Some Addresss'
59
+ fill_in 'store[phone]', with: '(51) 3535-5555'
60
+ fill_in 'store[email]', with: Faker::Internet.email
61
+ click_submit_button
62
+ end
63
+
64
+ # for is invalid, missing cities
65
+ within('#new_store') do
66
+ select city.name, from: 'store[city_id]'
67
+ click_submit_button
68
+ end
69
+
70
+ expect(page).to have_text(I18n.t('managers.stores.create.success'))
71
+ end
72
+
73
+ end
@@ -0,0 +1,21 @@
1
+ RSpec.configure do |config|
2
+ config.before(:suite) do
3
+ DatabaseCleaner.clean_with(:deletion)
4
+ end
5
+
6
+ config.before(:each) do
7
+ DatabaseCleaner.strategy = :transaction
8
+ end
9
+
10
+ config.before(:each, :js => true) do
11
+ DatabaseCleaner.strategy = :deletion
12
+ end
13
+
14
+ config.before(:each) do
15
+ DatabaseCleaner.start
16
+ end
17
+
18
+ config.after(:each) do
19
+ DatabaseCleaner.clean
20
+ end
21
+ end
@@ -0,0 +1,39 @@
1
+ module EmailExamples
2
+ def invalid_email_addresses
3
+ %w(
4
+ marcelo.jacobusgmail.com
5
+ example@email
6
+ )
7
+ end
8
+
9
+ def valid_email_addresses
10
+ %w(
11
+ marcelo.jacobus@gmail.com
12
+ example@email.com
13
+ a-bc@email.com
14
+ )
15
+ end
16
+ end
17
+
18
+ module EmailFormatValidationSpecHelper
19
+ def it_validates_email_format_of(attribute)
20
+ it "validates email format of #{attribute}" do
21
+ valid_email_addresses.each do |email|
22
+ subject.send("#{attribute}=", email)
23
+ subject.valid?
24
+ expect(subject.errors[attribute]).to be_empty
25
+ end
26
+
27
+ invalid_email_addresses.each do |email|
28
+ subject.send("#{attribute}=", email)
29
+ subject.valid?
30
+ expect(subject.errors[attribute]).not_to be_empty
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ RSpec.configure do |config|
37
+ config.extend EmailFormatValidationSpecHelper
38
+ config.include EmailExamples
39
+ end
File without changes
@@ -0,0 +1,33 @@
1
+ module Features
2
+ module Login
3
+ extend ActiveSupport::Concern
4
+
5
+ def login_with_strategy(strategy_class)
6
+ click_link t("system.links.login.#{strategy_class.provider_key}")
7
+ end
8
+
9
+ def logout
10
+ click_link(t('system.links.logout'))
11
+ end
12
+
13
+ module ClassMethods
14
+ def user_logs_in_and_out_with(strategy_class)
15
+
16
+ scenario "user logs in and out with #{strategy_class.provider_key}" do
17
+ visit root_path
18
+
19
+ login_with_strategy(strategy_class)
20
+ expect(page).to have_text(t('system.messages.account_created'))
21
+
22
+ logout
23
+ expect(page).to have_text(t('devise.sessions.signed_out'))
24
+
25
+ login_with_strategy(strategy_class)
26
+ expect(page).to have_text(t('system.messages.login_succeed'))
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,3 @@
1
+ RSpec.configure do |config|
2
+ config.include AbstractController::Translation
3
+ end
File without changes
File without changes
@@ -0,0 +1,63 @@
1
+ OmniAuth.config.test_mode = true
2
+ OmniAuth.config.mock_auth = {}
3
+ ################################################################################
4
+ # twitter
5
+ ################################################################################
6
+ OmniAuth.config.mock_auth[:twitter] = {
7
+ :provider => 'twitter',
8
+ :uid => '123456',
9
+ :info => {
10
+ :name => 'Example Name'
11
+ }
12
+ }
13
+
14
+ ################################################################################
15
+ # google
16
+ ################################################################################
17
+ OmniAuth.config.mock_auth[:google_oauth2] = {
18
+ :provider => 'google_oauth2',
19
+ :uid => '223456',
20
+ :info => {
21
+ :name => 'Example Name',
22
+ :email => "email@google.com",
23
+ :first_name => "Marcelo",
24
+ :last_name => "Jacobus"
25
+ }
26
+ }
27
+
28
+ ################################################################################
29
+ # Facebook
30
+ ################################################################################
31
+ OmniAuth.config.mock_auth[:facebook] = {
32
+ :provider => 'facebook',
33
+ :uid => '2234567',
34
+ :info => {
35
+ :nickname => 'jbloggs',
36
+ :email => 'email@facebook.com',
37
+ :name => 'Example Name facebook',
38
+ :first_name => 'Joe',
39
+ :last_name => 'Bloggs',
40
+ :image => '',
41
+ :urls => { :Facebook => '' },
42
+ :location => 'some place',
43
+ :verified => true
44
+ }
45
+ }
46
+ ################################################################################
47
+ # Github
48
+ ################################################################################
49
+ OmniAuth.config.mock_auth[:github] = {
50
+ :provider => 'github',
51
+ :uid => '123458',
52
+ :info => {
53
+ :name => 'Example Name',
54
+ :email => "email@google.com",
55
+ }
56
+ }
57
+
58
+
59
+ class OauthHelper
60
+ def self.providers
61
+ OmniAuth.config.mock_auth
62
+ end
63
+ end
@@ -0,0 +1,46 @@
1
+ module OmniauthControllerSpecs
2
+ extend ActiveSupport::Concern
3
+
4
+ def stub_omniauth_with(params, origin = root_url)
5
+ @request.env["devise.mapping"] = Devise.mappings[:user]
6
+ @request.env["omniauth.auth"] = params
7
+ @request.env["omniauth.origin"] = origin
8
+ end
9
+
10
+ module ClassMethods
11
+ def it_logs_in_with(strategy_class)
12
+ provider_key = strategy_class.provider_key
13
+
14
+ describe "#{provider_key}" do
15
+ let(:env) { OauthHelper.providers[provider_key] }
16
+ let(:user) { User.make }
17
+
18
+ before do
19
+ expect(strategy_class).to receive(:find_or_build_user).with(env).and_return(user)
20
+ stub_omniauth_with(env)
21
+ expect(controller).to receive(:redirect_url_for).with(user, root_url).and_return(root_url)
22
+ end
23
+
24
+ it "saves user" do
25
+ expect(user).to receive(:save!).with(validate: false)
26
+ get provider_key
27
+ end
28
+
29
+ it "logs user in" do
30
+ get provider_key
31
+ expect(controller.current_user).to eq(User.last)
32
+ end
33
+
34
+ it "redirects to the 'redirect_url'" do
35
+ get provider_key
36
+ expect(response).to redirect_to(root_url)
37
+ end
38
+
39
+ it "presents 'login_message'" do
40
+ get provider_key
41
+ expect(flash[:notice]).to eq(I18n.t('system.messages.account_created'))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,52 @@
1
+ module OmniauthModelSpecs
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def it_behaves_like_a_strategy_model(model_class, strategy_key)
6
+ let(:params) { OauthHelper.providers[strategy_key] }
7
+
8
+ let(:existing_user) do
9
+ user = model_class.find_or_build_user(params)
10
+ user.save!
11
+ user
12
+ end
13
+
14
+ describe ".find_or_build_user" do
15
+ context "when user does not exist" do
16
+ it "builds a new user" do
17
+ user = model_class.find_or_build_user(params)
18
+ expect(user).to be_a(User)
19
+ expect(user).not_to be_persisted
20
+ expect(user).to be_new_record
21
+ end
22
+
23
+ it "assigns correct data to users" do
24
+ user = model_class.find_or_build_user(params)
25
+ expect(user.uid).to eq(params[:uid])
26
+ expect(user.provider.to_s).to eq(strategy_key.to_s)
27
+ expect(user.email).to eq(params[:info][:email])
28
+ expect(user.name).to eq(params[:info][:name])
29
+ end
30
+ end
31
+
32
+ context "when user does exist" do
33
+ it "does not create an user" do
34
+ existing_user
35
+ user = model_class.find_or_build_user(params)
36
+ expect(user.id).to eq(existing_user.id)
37
+ expect(user).not_to be_new_record
38
+ end
39
+
40
+ it "updates data when user changes it" do
41
+ existing_user.email = 'another@email.com'
42
+ existing_user.name = 'another name'
43
+ existing_user.save(validate: false)
44
+ user = model_class.find_or_build_user(params)
45
+ expect(user.email).to eq(params[:info][:email])
46
+ expect(user.name).to eq(params[:info][:name])
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ module Records
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ let(:user) { User.make! }
6
+ let(:user2) { User.make! }
7
+ let(:user3) { User.make! }
8
+ end
9
+ end
File without changes
@@ -1,9 +1,12 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
1
4
  require 'simplecov'
2
5
  SimpleCov.start 'rails'
3
6
 
4
7
  ENV['RAILS_ENV'] = 'test'
5
8
 
6
- # TODO remvoe when warning is fixed
9
+ # TODO remove when warning is fixed
7
10
  require 'minitest/autorun'
8
11
 
9
12
  require File.expand_path('../../config/environment', __FILE__)
@@ -26,7 +29,15 @@ RSpec.configure do |config|
26
29
  config.infer_base_class_for_anonymous_controllers = false
27
30
  config.order = 'random'
28
31
  config.use_transactional_fixtures = false
32
+
33
+ # config.include Formulaic::Dsl, type: :feature
34
+ config.include Features, type: :feature
35
+ config.include CapybaraHelper, type: :feature
36
+ config.include Devise::TestHelpers, type: :controller
37
+ config.include Records
29
38
  end
30
39
 
31
40
  # Capybara.javascript_driver = :webkit
32
41
  WebMock.disable_net_connect!(allow_localhost: true)
42
+
43
+
@@ -12,6 +12,8 @@
12
12
  </head>
13
13
 
14
14
  <body>
15
+ <%%= render 'login_links' unless current_user -%>
16
+ <%%= render 'login_status' if current_user -%>
15
17
  <%%= render 'flashes' -%>
16
18
  <div class="row">
17
19
  <%%= yield %>
@@ -0,0 +1,29 @@
1
+ "pt-BR":
2
+ system:
3
+ links:
4
+ logout: Sair
5
+ login:
6
+ google_oauth2: Google
7
+ github: Github
8
+ facebook: Facebook
9
+ messages:
10
+ login_with:
11
+ google_oauth2: Entre com com sua conta do Google
12
+ github: Entre com sua conta do Github
13
+ facebook: Entre com sua conta do Facebook
14
+ welcome: Bem vindo!
15
+ logout_succeed: Login efetuado com sucesso.
16
+ login_succeed: Login efetuado com sucesso.
17
+ account_created: Sua conta foi criada com sucesso!
18
+ confirm_destroy: Tem certeza de que deseja excluir?
19
+ crud:
20
+ create:
21
+ success: Registro criado com sucesso
22
+ error: Um ou mais errors ocorreram ao criar o registro
23
+ update:
24
+ success: Registro atualizado com sucesso
25
+ error: Um ou mais errors ocorreram ao atualizar o registro
26
+ destroy:
27
+ success: Registro excluído com sucesso
28
+ error: O Registro não pode ser excluído
29
+ confirm: Tem certeza de que deseja excluir este registro?
@@ -18,5 +18,5 @@ branches:
18
18
  only: master
19
19
  notifications:
20
20
  email:
21
- on_failure: change
21
+ on_success: change
22
22
  on_failure: always
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mj-suspenders
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - thoughtbot
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-14 00:00:00.000000000 Z
12
+ date: 2014-05-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -140,12 +140,26 @@ files:
140
140
  - spec/spec_helper.rb
141
141
  - spec/support/suspenders.rb
142
142
  - templates/Gemfile.erb
143
+ - templates/MIT-LICENSE.erb
143
144
  - templates/README.md.erb
144
145
  - templates/_flashes.html.erb
145
146
  - templates/_javascript.html.erb
147
+ - templates/app/controllers/omniauth_callbacks_controller.rb
148
+ - templates/app/models/concerns/.keep
149
+ - templates/app/models/oauth/base.rb
150
+ - templates/app/models/oauth/facebook.rb
151
+ - templates/app/models/oauth/github.rb
152
+ - templates/app/models/oauth/google.rb
153
+ - templates/app/models/user.rb
154
+ - templates/app/views/application/_login_button.html.erb
155
+ - templates/app/views/application/_login_links.html.erb
156
+ - templates/app/views/application/_login_status.html.erb
146
157
  - templates/application.css.scss
147
158
  - templates/config_locales_en.yml
159
+ - templates/coveralls.yml
148
160
  - templates/database_cleaner_rspec.rb
161
+ - templates/db/migrate/20140522135601_devise_create_users.rb
162
+ - templates/db/migrate/20140522142949_add_name_to_users.rb
149
163
  - templates/devise.en.yml
150
164
  - templates/devise.pt-BR.yml
151
165
  - templates/disable_xml_params.rb
@@ -158,10 +172,31 @@ files:
158
172
  - templates/secret_token.rb
159
173
  - templates/smtp.yml.erb
160
174
  - templates/smtp_initializer.rb
175
+ - templates/spec/controllers/omniauth_callbacks_controller_spec.rb
176
+ - templates/spec/models/oauth/base_spec.rb
177
+ - templates/spec/models/oauth/facebook_spec.rb
178
+ - templates/spec/models/oauth/github_spec.rb
179
+ - templates/spec/models/oauth/google_spec.rb
180
+ - templates/spec/models/user_spec.rb
181
+ - templates/spec/support/blueprints.rb
182
+ - templates/spec/support/capybara_helper.rb
183
+ - templates/spec/support/database_cleaner.rb
184
+ - templates/spec/support/email_format_validation.rb
185
+ - templates/spec/support/features/.keep
186
+ - templates/spec/support/features/oauth_login_specs.rb
187
+ - templates/spec/support/i18n.rb
188
+ - templates/spec/support/matchers/.keep
189
+ - templates/spec/support/mixins/.keep
190
+ - templates/spec/support/oauth_providers.rb
191
+ - templates/spec/support/omniauth_controller_specs.rb
192
+ - templates/spec/support/omniauth_model_specs.rb
193
+ - templates/spec/support/records.rb
194
+ - templates/spec/support/shared_examples/.keep
161
195
  - templates/spec_helper.rb
162
196
  - templates/staging.rb
163
197
  - templates/suspenders_gitignore
164
198
  - templates/suspenders_layout.html.erb.erb
199
+ - templates/system.pt-BR.yml
165
200
  - templates/travis.yml.erb
166
201
  - templates/unicorn.rb
167
202
  homepage: http://github.com/mjacobus/mg-suspenders