Obviously a novice here, but working through Hartl's book. I can't seem to figure out how to write the right tests for Exercise 3: "The current authentication tests check that navigation links such as “Profile” and “Settings” appear when a user is signed in. Add tests to make sure that these links don’t appear when a user isn’t signed in.":
Here's my authentication_pages_spec.rb:
require 'spec_helper'
describe "AuthenticationPages" do
subject { page }
describe "signin path" do
before { visit signin_path }
it { should have_selector('h1', text: "Sign in") }
it { should have_selector('title', text: "Sign in") }
end
describe "should not have show profile and settings in menu" do
it { should_not have_link('Profile', href: user_path(user)) }
it { should_not have_link('Settings', href: edit_user_path(user)) }
end
describe "signin" do
before { visit signin_path }
describe "with invalid signin information" do
before { click_button "Sign in" }
it { should have_selector('title', text: 'Sign in') }
it { should have_selector('div.alert.alert-error', text: "Invalid") }
describe "after visiting another page" do
before { click_link "Home" }
it { should_not have_selector('div.alert.alert-error') }
end
end
describe "with valid signin information" do
let(:user) { FactoryGirl.create(:user) }
before { sign_in user }
it { should have_selector('title', text: user.name) }
it { should have_link('Users', href: users_path) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Settings', href: edit_user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
describe "followed by signout" do
before { click_link "Sign out" }
it { should have_link('Sign in') }
end
end
describe "authorization" do
describe "for non-signed-in users" do
let(:user) { FactoryGirl.create(:user) }
describe "when attempting to visit a protected page" do
before do
visit edit_user_path(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
describe "after signing in" do
it "should render the desired protected page" do
page.should have_selector('title', text: 'Edit user')
end
end
end
describe "in the Users controller" do
describe "visiting the edit page" do
before { visit edit_user_path(user) }
it { should have_selector('title', text: 'Sign in') }
end
describe "submitting to the update action" do
before { put user_path(user) }
specify { response.should redirect_to(signin_path) }
end
describe "visiting the user index" do
before { visit users_path }
it { should have_selector('title', text: "Sign in") }
end
end
end
describe "as wrong user" do
let(:user) { FactoryGirl.create(:user) }
let(:wrong_user) { FactoryGirl.create(:user, email: "wrong#example.com") }
before { sign_in user }
describe "visiting Users#edit page" do
before { visit edit_user_path(wrong_user) }
it { should_not have_selector('title', text: full_title('Edit user')) }
end
describe "submitting a PUT request to the Users#update action" do
before { put user_path(wrong_user) }
specify { response.should redirect_to(root_url) }
end
end
describe "as a non-admin user" do
let(:user) { FactoryGirl.create(:user) }
let(:non_admin) { FactoryGirl.create(:user) }
before { sign_in non_admin }
describe "submitting a DELETE request to the User#destroy action" do
before { delete user_path(user) }
specify { response.should redirect_to(root_url) }
end
end
end
end
end
The lines I added have the tests still failing. Any insight would be helpful. Thanks.
I might be missing something but I can't see which tests you have added for this exercise.
I have just completed this and now the first AuthenticationPages tests look like this.
authentication_pages_spec.rb
describe "sigin page" do
before { visit signin_path }
it { should have_content('Sign in') }
it { should have_title('Sign in') }
it { should_not have_link('Users') }
it { should_not have_link('Profile') }
it { should_not have_link('Settings') }
it { should_not have_link('Sign out', href: signout_path) }
it { should have_link('Sign in', href: signin_path) }
end
In addition KnownColor's tests above, I added the following tests to verify that the links do not show on profile pages when the user is not signed in:
authentication_pages_spec.rb
describe "authorization" do
describe "for non-signed-in users" do
let(:user) {FactoryGirl.create(:user)}
describe "when visiting a non-protected page" do
before {visit user_path(user)}
it {should have_link('Sign in', href: signin_path)}
it {should_not have_link('Users')}
it {should_not have_link('Profile')}
it {should_not have_link('Settings')}
it {should_not have_link('Sign out')}
end
...
end
...
end
Related
for(let i=1;i<=4;i++) {
console.log("hello ", i);
Alert.alert( "Alert Title", "My Alert Msg", [{ text: "OK", onPress: () => console.log("OK Pressed") }] );
}
I want to show list of inputs dynamically.
I am not asking about using v-bind OR v-model, I want to bind v-model property itself (like v-bind:v-model).
Here is the code but it does not work.
<template>
<div class="form-outside">
<form>
<div v-for="(input, index) in inputs" :key="index">
<div class="caption">{{input.caption}}</div>
<input :type="input.type" :v-model="input.model" />
</div>
<div v-if="error" class="error-message">{{error}}</div>
<div v-if="kind=='login'" class="suggestion">
Don't have an account?
<nuxt-link to="/signup">Sign up</nuxt-link> instead!
</div>
<div v-if="kind=='signup'" class="suggestion">
Have an account?
<nuxt-link to="/login">Log in</nuxt-link> instead!
</div>
<div v-if="loading" class="loading">Loading</div>
<button #click.prevent="submitted" v-if="!loading">{{button_text}}</button>
</form>
</div>
</template>
<script>
export default {
name: "AuthForm",
props: ["kind", "error", "loading"],
methods: {
submitted() {
this.$emit("submitted", {
email: this.email,
password: this.password,
confirm_password: this.confirm_password,
full_name: this.full_name,
login: this.login,
username: this.username
});
}
},
computed: {
button_text() {
if (this.kind == "login") return "Log in";
if (this.kind == "signup") return "Sign up";
},
inputs() {
return this.possible_inputs.filter(
input => input.when == "always" || input.when == this.kind
);
}
},
data() {
return {
email: "",
password: "",
confirm_password: "",
full_name: "",
login: "",
username: "",
possible_inputs: [
{
caption: "Full Name",
type: "text",
when: "signup",
model: this.full_name
},
{
caption: "Email",
type: "email",
when: "signup",
model: this.email
},
{
caption: "Email or Username",
type: "text",
when: "login",
model: this.login
},
{
caption: "Username",
type: "text",
when: "signup",
model: this.username
},
{
caption: "Password",
type: "password",
when: "always",
model: this.password
},
{
caption: "Confirm Password",
type: "password",
when: "signup",
model: this.confirm_password
}
]
};
}
};
</script>
(This is some additional text because stackoverflow says “It looks like your post is mostly code, please add some more details”, just ignore it)
In data(){} you cannot assign in this way model: this.email so you need to assign it in mounted() {} hook, check the code below:
<script>
export default {
data() {
return {
email: "",
password: "",
confirm_password: "",
full_name: "",
login: "",
username: "",
possible_inputs: []
};
},
mounted() {
this.possible_inputs = [
{
caption: "Full Name",
type: "text",
when: "signup",
model: this.full_name
}, {
caption: "Email",
type: "email",
when: "signup",
model: this.email
}, {
caption: "Email or Username",
type: "text",
when: "login",
model: this.login
}, {
caption: "Username",
type: "text",
when: "signup",
model: this.username
}, {
caption: "Password",
type: "password",
when: "always",
model: this.password
}, {
caption: "Confirm Password",
type: "password",
when: "signup",
model: this.confirm_password
},
];
},
};
</script>
I have a Yes and No button in my SweetAlert2. When I click on No it does a post to a method but I just want it to close the SweetAlert.
Here is the code I have written:
$('.js-update-details-click').click(function () {
var Id = Number($(this).data('result-id'));
swal({
title: 'Are you sure you want to ask the User to update their details?',
type: 'warning',
showCancelButton: true,
closeOnConfirm: false,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes',
cancelButtonText: 'No',
confirmButtonClass: 'btn btn-success btn-full-width mar-bot-5',
cancelButtonClass: 'btn btn-danger btn-full-width mar-bot-5',
buttonsStyling: false
})
.then(function (isconfirm) {
if (isconfirm) {
$.ajax({
type: "POST",
url: '/Common/ComposeUpdateDetailsEmail',
data: { ReplyType: 'CleanUpdateDetails', Id: Id },
success: function (data) {
swal('User has been sent an email to Update their Details.')
}
});
}
});
}
);
Most probably you updated the sweetalert2 dependency to ^7.0.0 and didn't read the release notes with breaking changes: https://github.com/sweetalert2/sweetalert2/releases/tag/v7.0.0
Starting from v7.0.0, SweetAlert2 will fulfill the promise for both confirm and cancel buttons and you need to handle the response from it this way:
Swal.fire({
...
}).then(function (result) {
if (result.value) {
// handle confirm
} else {
// handle cancel
}
})
Reference:
https://jsfiddle.net/ad3quksn/199/
`
swal({
title: 'Input something',
type: 'question',
input: 'text',
showCancelButton: true
}).then(
result => {
if (result.value) {
swal({
type: 'success',
html: 'You entered: <strong>' + result.value + '</strong>'
})
} else {
console.log(`dialog was dismissed by ${result.dismiss}`)
}
}
);
`
It shows with an output example of how to handle the promise as of v7.0.0: it helped me understand better!
Maybe help you :
swal("you liked it",{ buttons:{cancel:false,confirm:false}, timer:1000, })
ref : https://github.com/t4t5/sweetalert/issues/763
I can set inputType as password. What are the other input Types supported..?
swal({
title: "Are you sure?",
type: "input",
inputType: "checkbox",
showCancelButton: true,
closeOnConfirm: true,
}, function () {
swal("", "You did it", "success");
});
the checkbox inputType is not supported in swal..
There's a nice way to use checkbox modal type in SweetAlert2:
Swal.fire({
title: 'Do you have a bike?',
input: 'checkbox',
inputPlaceholder: 'I have a bike'
}).then((result) => {
if (result.isConfirmed) {
if (result.value) {
Swal.fire({icon: 'success', text: 'You have a bike!'});
} else {
Swal.fire({icon: 'error', text: "You don't have a bike :("});
}
} else {
console.log(`modal was dismissed by ${result.dismiss}`)
}
})
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#11"></script>
PS. notice that SweetAlert2 is a little bit different from SweetAlert, check the simple migration guide: https://github.com/sweetalert2/sweetalert2/wiki/Migration-from-SweetAlert-to-SweetAlert2
Firstly, here is my code:
Ext.Msg.show({
title: 'Username',
msg: 'Please enter your username',
buttons: Ext.MessageBox.OKCANCEL,
prompt:{ maxlength : 180, autocapitalize : false },
modal: true,
fn: function(buttonId, text) {
console.log("OK ("+text+"), what is you password?");
if (buttonId == 'ok')
{
Ext.Msg.show({
title: 'Password',
msg: 'Please enter your password',
buttons: Ext.MessageBox.OKCANCEL,
prompt:{ maxlength : 180, autocapitalize : false },
modal: true,
fn: function(buttonId2, text2) {
if (buttonId == 'ok')
{
console.log("OK ("+text+", "+text2+"), attempting login..");
}
},
icon: Ext.MessageBox.INFO
});
}
},
icon: Ext.MessageBox.INFO
});
My problem is that when I press OK on the first messagebox, the second one appears for less then a second and then closes too, without me pressing OK on the second messagebox.
Ideally, of course, I'd display both username and password inputs in the same Messagebox, but I can't figure out how to do this.
All help appreciated!
The static show method on Ext.Msg that you are calling basically reconfigures the previous MessageBox and so is getting confused when hiding and showing again.
You should create a new instance of the Ext.MessageBox class and call the show method of that object so it will use independent instances.
var msg = new Ext.MessageBox().show({
title: 'Username',
msg: 'Please enter your username',
buttons: Ext.MessageBox.OKCANCEL,
prompt:{ maxlength : 180, autocapitalize : false },
modal: true,
fn: function(buttonId, text) {
console.log("OK ("+text+"), what is you password?");
if (buttonId == 'ok')
{
var msg2 = new Ext.MessageBox().show({
title: 'Password',
msg: 'Please enter your password',
buttons: Ext.MessageBox.OKCANCEL,
prompt:{ maxlength : 180, autocapitalize : false },
modal: true,
fn: function(buttonId2, text2) {
if (buttonId == 'ok')
{
console.log("OK ("+text+", "+text2+"), attempting login..");
}
},
icon: Ext.MessageBox.INFO
});
}
},
icon: Ext.MessageBox.INFO
});
Although this works, I would recommend you make a custom form panel containing both the fields and collect the information that way.
Hope this helps.
Stuart