<%= t 'activation.welcome_to', site_name: SiteSetting.title %>
-
- <%= button_to(perform_accept_invite_path, method: :put, class: 'btn btn-primary') do %>
- <%= t 'invite.accept_invite' %>
- <% end %>
<%end%>
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index adced32c71c..7eee6facba0 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -1065,6 +1065,15 @@ en:
github:
title: "with GitHub"
message: "Authenticating with GitHub (make sure pop up blockers are not enabled)"
+ invites:
+ accept_title: "Invitation"
+ welcome_to: "Welcome to %{site_name}!"
+ invited_by: "You were invited by:"
+ form_instructions: "You can choose your username and set your password now, or later from your preferences."
+ social_login_available: "After your account is created, you'll be able to sign in with social login."
+ your_email: "Your account's email address will be %{email}."
+ accept_invite: "Accept Invitation"
+ success: "Your account has been created and you're now logged in."
password_reset:
continue: "Continue to %{site_name}"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 090b3bca008..c73371c9040 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -137,7 +137,6 @@ en:
<<: *errors
invite:
- accept_invite: "Accept Invitation"
not_found: "Your invite token is invalid. Please contact the site's administrator."
bulk_invite:
diff --git a/public/images/envelope.svg b/public/images/envelope.svg
new file mode 100644
index 00000000000..6400f5af466
--- /dev/null
+++ b/public/images/envelope.svg
@@ -0,0 +1 @@
+
diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb
index 6c9ace61b2a..146a007753f 100644
--- a/spec/controllers/invites_controller_spec.rb
+++ b/spec/controllers/invites_controller_spec.rb
@@ -2,6 +2,21 @@ require 'rails_helper'
describe InvitesController do
+ context '.show' do
+ it "shows error if invite not found" do
+ get :show, id: 'nopeNOPEnope'
+ expect(response).to render_template(layout: 'no_ember')
+ expect(flash[:error]).to be_present
+ end
+
+ it "renders the accept invite page if invite exists" do
+ i = Fabricate(:invite)
+ get :show, id: i.invite_key
+ expect(response).to render_template(layout: 'application')
+ expect(flash[:error]).to be_nil
+ end
+ end
+
context '.destroy' do
it 'requires you to be logged in' do
@@ -127,12 +142,14 @@ describe InvitesController do
context 'with an invalid invite id' do
before do
- put :perform_accept_invitation, id: "doesn't exist"
+ xhr :put, :perform_accept_invitation, id: "doesn't exist", format: :json
end
it "redirects to the root" do
expect(response).to be_success
- expect(flash[:error]).to be_present
+ json = JSON.parse(response.body)
+ expect(json["success"]).to eq(false)
+ expect(json["message"]).to eq(I18n.t('invite.not_found'))
end
it "should not change the session" do
@@ -145,12 +162,14 @@ describe InvitesController do
let(:invite) { topic.invite_by_email(topic.user, "iceking@adventuretime.ooo") }
let(:deleted_invite) { invite.destroy; invite }
before do
- put :perform_accept_invitation, id: deleted_invite.invite_key
+ xhr :put, :perform_accept_invitation, id: deleted_invite.invite_key, format: :json
end
it "redirects to the root" do
expect(response).to be_success
- expect(flash[:error]).to be_present
+ json = JSON.parse(response.body)
+ expect(json["success"]).to eq(false)
+ expect(json["message"]).to eq(I18n.t('invite.not_found'))
end
it "should not change the session" do
@@ -164,24 +183,43 @@ describe InvitesController do
it 'redeems the invite' do
Invite.any_instance.expects(:redeem)
- put :perform_accept_invitation, id: invite.invite_key
+ xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json
end
context 'when redeem returns a user' do
let(:user) { Fabricate(:coding_horror) }
context 'success' do
+ subject { xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json }
+
before do
Invite.any_instance.expects(:redeem).returns(user)
- put :perform_accept_invitation, id: invite.invite_key
end
it 'logs in the user' do
+ subject
expect(session[:current_user_id]).to eq(user.id)
end
it 'redirects to the first topic the user was invited to' do
- expect(response).to redirect_to(topic.relative_url)
+ subject
+ json = JSON.parse(response.body)
+ expect(json["success"]).to eq(true)
+ expect(json["redirect_to"]).to eq(topic.relative_url)
+ end
+ end
+
+ context 'failure' do
+ subject { xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json }
+
+ it "doesn't log in the user if there's a validation error" do
+ user.errors.add(:password, :common)
+ Invite.any_instance.expects(:redeem).raises(ActiveRecord::RecordInvalid.new(user))
+ subject
+ expect(response).to be_success
+ json = JSON.parse(response.body)
+ expect(json["success"]).to eq(false)
+ expect(json["errors"]["password"]).to be_present
end
end
@@ -194,12 +232,12 @@ describe InvitesController do
it 'sends a welcome message if set' do
user.send_welcome_message = true
user.expects(:enqueue_welcome_message).with('welcome_invite')
- put :perform_accept_invitation, id: invite.invite_key
+ xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json
end
it "doesn't send a welcome message if not set" do
user.expects(:enqueue_welcome_message).with('welcome_invite').never
- put :perform_accept_invitation, id: invite.invite_key
+ xhr :put, :perform_accept_invitation, id: invite.invite_key, format: :json
end
end
end
diff --git a/spec/models/invite_redeemer_spec.rb b/spec/models/invite_redeemer_spec.rb
index 4b5d1bcc447..c06b11e73d0 100644
--- a/spec/models/invite_redeemer_spec.rb
+++ b/spec/models/invite_redeemer_spec.rb
@@ -3,20 +3,38 @@ require 'rails_helper'
describe InviteRedeemer do
describe '#create_user_from_invite' do
- let(:user) { InviteRedeemer.create_user_from_invite(Fabricate(:invite, email: 'walter.white@email.com'), 'walter', 'Walter White') }
-
it "should be created correctly" do
+ user = InviteRedeemer.create_user_from_invite(Fabricate(:invite, email: 'walter.white@email.com'), 'walter', 'Walter White')
expect(user.username).to eq('walter')
expect(user.name).to eq('Walter White')
expect(user).to be_active
expect(user.email).to eq('walter.white@email.com')
end
+
+ it "can set the password too" do
+ password = 's3cure5tpasSw0rD'
+ user = InviteRedeemer.create_user_from_invite(Fabricate(:invite, email: 'walter.white@email.com'), 'walter', 'Walter White', password)
+ expect(user).to have_password
+ expect(user.confirm_password?(password)).to eq(true)
+ end
+
+ it "raises exception with record and errors" do
+ error = nil
+ begin
+ InviteRedeemer.create_user_from_invite(Fabricate(:invite, email: 'walter.white@email.com'), 'walter', 'Walter White', 'aaa')
+ rescue ActiveRecord::RecordInvalid => e
+ error = e
+ end
+ expect(error).to be_present
+ expect(error.record.errors[:password]).to be_present
+ end
end
describe "#redeem" do
let(:invite) { Fabricate(:invite) }
let(:name) { 'john snow' }
let(:username) { 'kingofthenorth' }
+ let(:password) { 'know5nOthiNG'}
let(:invite_redeemer) { InviteRedeemer.new(invite, username, name) }
it "should redeem the invite" do
@@ -39,5 +57,12 @@ describe InviteRedeemer do
expect(user.username).to eq(username)
expect(user.invited_by).to eq(nil)
end
+
+ it "can set password" do
+ inviter = invite.invited_by
+ user = InviteRedeemer.new(invite, username, name, password).redeem
+ expect(user).to have_password
+ expect(user.confirm_password?(password)).to eq(true)
+ end
end
end
diff --git a/test/javascripts/acceptance/invite-accept-test.js.es6 b/test/javascripts/acceptance/invite-accept-test.js.es6
new file mode 100644
index 00000000000..2a58c89e9b8
--- /dev/null
+++ b/test/javascripts/acceptance/invite-accept-test.js.es6
@@ -0,0 +1,40 @@
+import { acceptance } from "helpers/qunit-helpers";
+import PreloadStore from 'preload-store';
+
+acceptance("Invite Accept");
+
+test("Invite Acceptance Page", () => {
+ PreloadStore.store('invite_info', {
+ invited_by: {"id":123,"username":"neil","avatar_template":"/user_avatar/localhost/neil/{size}/25_1.png","name":"Neil Lalonde","title":"team"},
+ email: "invited@asdf.com",
+ username: "invited"
+ });
+
+ visit("/invites/myvalidinvitetoken");
+ andThen(() => {
+ ok(exists("#new-account-username"), "shows the username input");
+ equal(find("#new-account-username").val(), "invited", "username is prefilled");
+ ok(exists("#new-account-password"), "shows the password input");
+ not(exists('.invites-show .btn-primary:disabled'), 'submit is enabled');
+ });
+
+ fillIn("#new-account-username", 'a');
+ andThen(() => {
+ ok(exists(".username-input .bad"), "username is not valid");
+ ok(exists('.invites-show .btn-primary:disabled'), 'submit is disabled');
+ });
+
+ fillIn("#new-account-password", 'aaa');
+ andThen(() => {
+ ok(exists(".password-input .bad"), "password is not valid");
+ ok(exists('.invites-show .btn-primary:disabled'), 'submit is disabled');
+ });
+
+ fillIn("#new-account-username", 'validname');
+ fillIn("#new-account-password", 'secur3ty4Y0uAndMe');
+ andThen(() => {
+ ok(exists(".username-input .good"), "username is valid");
+ ok(exists(".password-input .good"), "password is valid");
+ not(exists('.invites-show .btn-primary:disabled'), 'submit is enabled');
+ });
+});