Rework the Sign Up/Sign In views

Use Capybaras save_page when feature tests go wrong
This commit is contained in:
Henne Vogelsang 2014-07-23 14:55:06 +02:00
parent 76028f5755
commit 5f96c276e9
24 changed files with 326 additions and 100 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

104
app/assets/images/suse.svg Normal file
View file

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="219.73804"
height="219.75543"
id="svg35341"
version="1.1"
inkscape:version="0.48.4 r9939"
inkscape:export-filename="/home/hvogel/Development/Apps/osem/app/assets/images/suse.png"
inkscape:export-xdpi="54.93"
inkscape:export-ydpi="54.93"
sodipodi:docname="New document 3">
<defs
id="defs35343" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="14.751074"
inkscape:cy="103.38237"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="5"
fit-margin-left="5"
fit-margin-right="5"
fit-margin-bottom="5"
inkscape:window-width="1366"
inkscape:window-height="702"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1" />
<metadata
id="metadata35346">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-279.76666,-394.98438)">
<path
sodipodi:type="arc"
style="fill:#6ec72e;fill-opacity:1"
id="path35312"
sodipodi:cx="984.52637"
sodipodi:cy="2255.1992"
sodipodi:rx="22.381727"
sodipodi:ry="23.460365"
d="m 1006.9081,2255.1992 c 0,12.9568 -10.02065,23.4604 -22.38173,23.4604 -12.36109,0 -22.38173,-10.5036 -22.38173,-23.4604 0,-12.9568 10.02064,-23.4603 22.38173,-23.4603 12.36108,0 22.38173,10.5035 22.38173,23.4603 z"
transform="matrix(4.6854748,0,0,4.4704212,-4223.3378,-9576.8283)" />
<g
id="g35314"
transform="matrix(7.2461388,0,0,-7.2461388,-4445.5838,4425.1399)">
<g
transform="translate(663.7622,540.6406)"
id="g30926">
<path
inkscape:connector-curvature="0"
id="path30928"
style="fill:#e11f27;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 0.002,0.002 0,0 z" />
</g>
<g
transform="translate(668.3052,544.6201)"
id="g30930">
<path
inkscape:connector-curvature="0"
id="path30932"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 0.646,0.603 1.488,0.916 2.371,0.884 4.188,0.819 5.623,-0.714 5.559,-2.531 5.525,-3.415 5.156,-4.234 4.512,-4.832 3.863,-5.435 3.025,-5.748 2.145,-5.718 0.322,-5.654 -1.105,-4.121 -1.041,-2.3 -1.016,-1.418 -0.643,-0.602 0,0 m -4.852,-10.997 c 0.803,-0.092 1.709,-0.194 2.651,-0.219 2.629,-0.014 5.455,0.47 7.197,1.227 1.129,0.494 1.85,0.822 2.299,1.228 0.168,0.137 0.246,0.358 0.338,0.591 l 0.06,0.157 c 0.071,0.184 0.176,0.586 0.223,0.806 0.022,0.098 0.031,0.201 -0.031,0.254 -0.076,0.05 -0.168,0.001 -0.246,-0.046 -0.762,-0.46 -2.682,-1.335 -4.471,-1.369 -2.219,-0.045 -6.693,2.236 -7.158,2.475 l -0.043,0.054 c -0.113,0.27 -0.787,1.856 -0.926,2.191 3.219,-2.123 5.889,-3.294 7.936,-3.476 2.277,-0.205 4.052,1.038 4.806,1.57 0.149,0.103 0.264,0.182 0.311,0.2 l 0.047,0.081 C 8.014,-4.475 6.824,-0.608 5.926,0.321 5.678,0.58 5.479,0.826 5.076,1.061 1.826,2.957 -5.9,4.104 -6.262,4.156 L -6.32,4.142 -6.344,4.085 c 0,0 -0.033,-1.603 -0.037,-1.78 -0.412,0.137 -2.18,0.711 -4.547,1.25 -1.465,-2.035 -2.332,-4.536 -2.332,-7.241 0,-3.532 1.479,-6.717 3.846,-8.981 0.398,2.136 2.152,1.942 4.562,1.67" />
</g>
<g
transform="translate(671.0259,543.375)"
id="g30934">
<path
inkscape:connector-curvature="0"
id="path30936"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0.564,0 1.02,-0.305 1.02,-0.679 0,-0.376 -0.456,-0.68 -1.02,-0.68 -0.566,0 -1.025,0.304 -1.025,0.68 C -1.025,-0.305 -0.566,0 0,0 m -0.533,-3.446 c 0.617,-0.024 1.203,0.194 1.652,0.615 0.451,0.419 0.709,0.989 0.729,1.602 0.045,1.271 -0.953,2.343 -2.225,2.388 -0.615,0.022 -1.201,-0.198 -1.65,-0.616 -0.453,-0.42 -0.713,-0.989 -0.729,-1.604 -0.045,-1.27 0.951,-2.34 2.223,-2.385" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

View file

@ -10,6 +10,7 @@
*= require osem-schedule
*= require osem-schedule-print
*= require osem-dashboard
*= require osem-fonts
*= require font-awesome
*= require bootstrap-markdown.min
*/

Binary file not shown.

View file

@ -0,0 +1,11 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by Fontastic.me</metadata>
<defs>
<font id="suse-icons" horiz-adv-x="512">
<font-face font-family="suse-icons" units-per-em="512" ascent="480" descent="-32"/>
<missing-glyph horiz-adv-x="512" />
<glyph unicode="&#97;" d="M500 256c0-135-110-244-244-244-135 0-244 109-244 244 0 135 109 244 244 244 134 0 244-109 244-244z m-304-6l0 0z m77 67c11 10 25 16 40 15 31-1 55-27 54-58-1-15-7-28-18-38-11-11-25-16-40-15-31 1-55 27-54 57 1 15 7 29 18 39m-82-185c14-2 29-4 45-4 44 0 92 8 121 21 19 8 31 13 39 20 3 3 4 6 6 10l1 3c1 3 3 10 3 14 1 1 1 3 0 4-1 1-3 0-4-1-13-8-45-22-76-23-37-1-112 38-120 42l-1 1c-2 4-13 31-16 37 55-36 100-56 134-59 39-4 68 17 81 26 3 2 5 3 5 4l1 1c-2 14-22 79-37 94-4 5-8 9-14 13-55 32-186 51-192 52l-1 0 0-1c0 0-1-27-1-30-7 2-36 12-76 21-25-34-40-76-40-122 0-60 25-113 65-152 7 36 36 33 77 29m128 164c9 0 17-5 17-11 0-7-8-12-17-12-10 0-17 5-17 12 0 6 7 11 17 11m-9-58c10 0 20 3 28 10 7 7 12 17 12 27 1 22-16 40-38 41-10 0-20-4-27-11-8-7-12-16-13-27 0-21 16-39 38-40"/>
</font></defs></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,47 @@
/* Generated with http://fontastic.me/ and app/assets/images/suse.svg */
@charset "UTF-8";
@font-face {
font-family: "suse-icons";
src:url("fonts/suse-icons.eot");
src:url("fonts/suse-icons.eot?#iefix") format("embedded-opentype"),
url("fonts/suse-icons.woff") format("woff"),
url("fonts/suse-icons.ttf") format("truetype"),
url("fonts/suse-icons.svg#suse-icons") format("svg");
font-weight: normal;
font-style: normal;
}
[data-icon]:before {
font-family: "suse-icons" !important;
content: attr(data-icon);
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* We have to repeat this for every symbol that extends font awesome. So if
you add fa-rutzelfuz you need to copy and paste these two...
*/
[class^="fa-suse"]:before,
[class*=" fa-suse"]:before {
font-family: "suse-icons" !important;
font-style: normal !important;
font-weight: normal !important;
font-variant: normal !important;
text-transform: none !important;
speak: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fa-suse:before {
content: "a";
}

View file

@ -120,4 +120,4 @@ body {
.pad{
padding-top: 35px;
padding-bottom: 35px;
}
}

View file

@ -210,4 +210,16 @@ module ApplicationHelper
def markdown_hint(text="")
markdown("#{text} Please look at #{link_to '**Markdown Syntax**', 'https://daringfireball.net/projects/markdown/syntax', target: '_blank'} to format your text")
end
def omniauth_configured
providers = []
Devise.omniauth_providers.each do |provider|
provider_key = "#{provider}_key"
provider_secret = "#{provider}_secret"
unless Rails.application.secrets.send(provider_key).blank? || Rails.application.secrets.send(provider_secret).blank?
providers << provider
end
end
return providers
end
end

View file

@ -7,7 +7,7 @@ class User < ActiveRecord::Base
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
:omniauthable, omniauth_providers: [:novell, :google, :facebook]
:omniauthable, omniauth_providers: [:suse, :google, :facebook]
has_and_belongs_to_many :roles
has_many :openids

View file

@ -23,7 +23,8 @@
%h4
To add an openID with a different email address to your account, sign in with your
openID while logged in to OSEM
= render 'devise/shared/openid'
#openidlinks
= render 'devise/shared/openid'
= f.inputs name: 'Account' do
= f.input :email, required: false, input_html: {autocomplete: "off"}

View file

@ -1,21 +1,32 @@
.row
.page-header
%h1.text-center Sign Up
.col-md-5.col-md-offset-1
.well
= semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= f.input :email
= f.input :name, required: true
= f.input :password
= f.input :password_confirmation
= f.action :submit, as: :button, label: 'Sign Up', button_html: {class: 'btn btn-primary'}
%br
%br
%h4 Already have an account?
= render 'devise/shared/links'
- if resource_class.omniauth_providers.present?
.col-md-4
.well
%h4 Or use your openID
= render 'devise/shared/openid'
.col-md-6.col-md-offset-3
.panel.panel-default
.panel-heading
%h3.panel-title
Sign Up
.panel-body
= semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= f.input :email
= f.input :name, required: true
= f.input :password
= f.input :password_confirmation
%p.text-right
= f.action :submit, as: :button, label: 'Sign Up', button_html: {class: 'btn btn-success' }
- unless omniauth_configured.empty?
.row
.col-md-4
%hr
.col-md-4
%h4.text-center
or sign up using
.col-md-4
%hr
.row
.col-md-12
#openidlinks
= render 'devise/shared/openid'
%p.text-right
%a.small{"data-toggle" => "collapse", "data-target" => "#devise-help"}
Need Help?
#devise-help.collapse
= render 'devise/shared/links'

View file

@ -1,22 +1,34 @@
.row
.page-header
%h2.text-center Sign In
.col-md-5.col-md-offset-1
.well
= semantic_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
= f.input :email
= f.input :password
- if devise_mapping.rememberable?
= f.check_box :remember_me
= f.label 'Remember me'
%br
= f.action :submit, as: :button, label: 'Sign In', button_html: {class: 'btn btn-primary'}
%br
%br
= render "devise/shared/links"
- if resource_class.omniauth_providers.present?
.col-md-4
.well
%h4 Or use your openID
= render 'devise/shared/openid'
.col-md-6.col-md-offset-3
.panel.panel-default
.panel-heading
%h3.panel-title
Sign In
.panel-body
= semantic_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
= f.input :email
= f.input :password
- if devise_mapping.rememberable?
%p.text-right.small
= f.label 'Remember me'
= f.check_box :remember_me
%p.text-right
= f.action :submit, as: :button, label: 'Sign In', button_html: {class: 'btn btn-success'}
- unless omniauth_configured.empty?
.row
.col-md-4
%hr
.col-md-4
%h4.text-center
or sign in using
.col-md-4
%hr
.row
.col-md-12
#openidlinks
= render 'devise/shared/openid'
%p.text-right
%a.small{"data-toggle" => "collapse", "data-target" => "#devise-help"}
Need Help?
#devise-help.collapse
= render 'devise/shared/links'

View file

@ -1,16 +1,8 @@
- if controller_name != 'sessions'
= link_to "Sign in", new_user_session_path
%br
- if devise_mapping.registerable? && controller_name != 'registrations'
= link_to "Sign up", new_registration_path(resource_name)
%br
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
- if devise_mapping.recoverable? && controller_name != 'passwords'
= link_to "Forgot your password?", new_password_path(resource_name)
%br
- if devise_mapping.confirmable? && controller_name != 'confirmations'
- if devise_mapping.confirmable? && controller_name != 'confirmations' && controller_name == 'passwords'
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name)
%br

View file

@ -1,7 +1,7 @@
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
- provider_key = "#{provider}_key"
- provider_secret = "#{provider}_secret"
- unless Rails.application.secrets.send(provider_key).blank? || Rails.application.secrets.send(provider_secret).blank?
= link_to image_tag("#{provider}.png", size: '32x32') + provider , omniauth_authorize_path(resource_name, provider)
%br
.btn-group.btn-group-lg
- omniauth_configured.each do |provider|
= link_to user_omniauth_authorize_path(provider),
class: "btn btn-success btn-lg",
id: "omniauth-#{provider}",
title: "Your #{provider} login" do
%i{:class => "fa fa-#{provider}"}

View file

@ -36,26 +36,29 @@
= link_to(new_registration_path('user')) do
%span.glyphicon.glyphicon-heart
Sign Up
%li.dropdown.visible-desktop
%a.dropdown-toggle{"data-toggle" => "dropdown", :href => "#"}
%span.glyphicon.glyphicon-user
Sign In
%span.caret
.dropdown-menu{:style => "padding: 17px;"}
= form_tag user_session_path do
= text_field_tag 'user[email]', nil, id: 'user_email_dd'
= password_field_tag 'user[password]', nil, id: 'user_password_dd'
%p.text-right
%small
Remember me
= check_box_tag 'user[remember_me]'
%button.btn.btn-success.btn-block Sign in
%p
%small
%ul.list-unstyled
%li
= link_to "Forgot your password?", new_password_path('user')
%li
= link_to 'Sign in with openID', new_user_session_path
%li.dropdown.visible-desktop
%a.dropdown-toggle{"data-toggle" => "dropdown", :href => "#"}
%span.glyphicon.glyphicon-user
Sign In
%span.caret
.dropdown-menu{:style => "padding: 17px;"}
= form_tag user_session_path do
= text_field_tag 'user[email]', nil, id: 'user_email_dd'
= password_field_tag 'user[password]', nil, id: 'user_password_dd'
%p.text-right
%small
Remember me
= check_box_tag 'user[remember_me]'
%button.btn.btn-success.btn-block Sign in
- unless omniauth_configured.empty?
.divider
%h6.text-center
or
= render 'devise/shared/openid'
%p.text-right
%a.small{"data-toggle" => "collapse", "data-target" => "#navbar-devise-help"}
Need Help?
#navbar-devise-help.collapse
= link_to "Forgot your password?", new_password_path(User.new)
%li.hidden-lg
= link_to('Sign In', new_user_session_path)

View file

@ -9,10 +9,10 @@ Devise.setup do |config|
# Define the available openID providers that can be used to log in
# Pass each provider to User model in :omniauth_providers (for open_id providers use their name)
config.omniauth :open_id, name: 'novell', identifier: 'http://www.opensuse.org/openid/user'
config.omniauth :google_oauth2, Rails.application.secrets.google_key, Rails.application.secrets.google_secret,
config.omniauth :open_id, name: 'suse', identifier: 'http://www.opensuse.org/openid/user'
config.omniauth :google_oauth2, Rails.application.secrets.google_key, Rails.application.secrets.google_secret,
name: 'google',
scope: 'email'
scope: 'email'
config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret
# ==> Mailer Configuration

View file

@ -23,11 +23,10 @@ defaults: &defaults
facebook_key: ''
facebook_secret: ''
# Developers do not need to register their application for novell account to work.
# Developers do not need to register their application for suse account to work.
# You must, however, leave the sample data there, for the login option to appear.
novell_key: 'sample data'
novell_secret: 'sample data'
suse_key: 'sample data'
suse_secret: 'sample data'
# If you add more providers that do not require a key, you still have to create the 2 variables with sample data

View file

@ -8,8 +8,8 @@ feature Openid do
scenario 'has option to log in with Google account' do
visit '/accounts/sign_in'
expect(page.has_content?('Or use your openID')).to be true
expect(page.has_content?('google')).to be true
expect(page.has_content?('or sign in using')).to be true
expect(page.has_link?('omniauth-google')).to be true
end
scenario 'signs in *new* user with Google account' do
@ -18,7 +18,9 @@ feature Openid do
visit '/accounts/sign_in'
mock_auth_new_user
click_link 'google'
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq('test-1@gmail.com signed in successfully with google')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)
@ -31,7 +33,9 @@ feature Openid do
visit '/accounts/sign_in'
mock_auth_existing_user_participant
click_link 'google'
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)
@ -40,8 +44,11 @@ feature Openid do
scenario 'can handle authentication error' do
OmniAuth.config.mock_auth[:google] = :invalid_credentials
visit '/accounts/sign_in'
expect(page.has_content?('Or use your openID')).to be true
click_link 'google'
expect(page.has_content?('or sign in using')).to be true
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq("Could not authenticate you from Google because \"Invalid credentials\".")
end
@ -56,7 +63,9 @@ feature Openid do
visit '/accounts/edit'
mock_auth_new_user
click_link 'google'
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)
@ -71,7 +80,9 @@ feature Openid do
visit '/accounts/sign_in'
mock_auth_existing_user_participant
click_link 'google'
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)
@ -82,7 +93,9 @@ feature Openid do
visit '/accounts/edit'
mock_auth_new_user
click_link 'google'
within("#openidlinks") do
click_link 'omniauth-google'
end
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)
@ -96,7 +109,9 @@ feature Openid do
visit '/accounts/sign_in'
mock_auth_new_user_fb
click_link 'facebook'
within("#openidlinks") do
click_link 'omniauth-facebook'
end
expect(flash).to eq('test-participant-1@google.com signed in successfully with facebook')
expect(Openid.count).to eq(expected_count_openid)
expect(User.count).to eq(expected_count_user)

View file

@ -26,7 +26,7 @@ module OmniauthMacros
def mock_auth_new_user_fb
OmniAuth.config.mock_auth[:facebook] =
OmniAuth::AuthHash.new(
provider: 'google',
provider: 'facebook',
uid: 'facebook-test-uid-1',
info: {
name: 'new user fb name',

View file

@ -0,0 +1,18 @@
# Automatically save and open the page
# whenever an expectation is not met in a features spec
RSpec.configure do |config|
config.after(:each, type: :feature) do
ename = RSpec.current_example.full_description
ename = ename.gsub " ", "_"
ename.downcase!
ename = ename + ".html"
if RSpec.current_example.exception.present?
save_page(ename)
else
capfile = File.expand_path(ename, Capybara.save_and_open_page_path)
if File.exist?(capfile)
File.unlink(capfile)
end
end
end
end