mirror of
https://github.com/discourse/discourse.git
synced 2026-08-04 10:23:17 -05:00
DEV: Allow new instances to be set up directly with Discourse ID (#36731)
This relies on https://github.com/discourse/discourse_docker/pull/1010 When email setup is skipped, we can register the site for Discourse ID. That means the admin (and other users), can signup/login without the site having working email at all. The goal of this feature is to simplify bootstrapping a test site. A well-functioning community will likely need working email at some point, this simplifies the first step of getting started.
This commit is contained in:
@@ -379,10 +379,11 @@ body.wizard {
|
||||
}
|
||||
}
|
||||
|
||||
// Register admin pages
|
||||
// New instance setup screens
|
||||
// /finish-installation and /finish-installation/register
|
||||
.wizard-container-contents.finish-installation {
|
||||
font-family: var(--font-family);
|
||||
max-width: min(800px, 90vh);
|
||||
|
||||
.wizard-container__combobox {
|
||||
background: var(--secondary);
|
||||
@@ -436,4 +437,12 @@ body.wizard {
|
||||
background-color: var(--tertiary-low);
|
||||
}
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
padding: 0.5em 2.5em 0.5em 1em;
|
||||
background-color: var(--danger-low);
|
||||
color: var(--primary);
|
||||
position: relative;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ class FinishInstallationController < ApplicationController
|
||||
before_action :ensure_no_admins, except: %w[confirm_email resend_email]
|
||||
|
||||
def index
|
||||
@setting_up_discourse_id = ENV["DISCOURSE_SKIP_EMAIL_SETUP"] == "1"
|
||||
|
||||
setup_discourse_id if @setting_up_discourse_id
|
||||
end
|
||||
|
||||
def register
|
||||
@@ -49,6 +52,16 @@ class FinishInstallationController < ApplicationController
|
||||
send_signup_email if @user.present?
|
||||
end
|
||||
|
||||
def redirect_discourse_id
|
||||
seed_admin_users
|
||||
|
||||
# Set a global notice in case the first admin login doesn't get completed
|
||||
# This gets cleared when an admin successfully actives their account
|
||||
SiteSetting.global_notice = I18n.t("finish_installation.discourse_id.global_notice")
|
||||
|
||||
redirect_to("/auth/discourse_id")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def send_signup_email
|
||||
@@ -70,6 +83,49 @@ class FinishInstallationController < ApplicationController
|
||||
GlobalSetting.developer_emails.split(",").map(&:strip)
|
||||
end
|
||||
|
||||
def setup_discourse_id
|
||||
begin
|
||||
if find_allowed_emails.empty?
|
||||
raise StandardError.new(I18n.t("finish_installation.discourse_id.no_allowed_emails"))
|
||||
end
|
||||
SiteSetting.enable_discourse_id = true
|
||||
# Since we're setting up Discourse ID, disable local logins
|
||||
SiteSetting.enable_local_logins = false
|
||||
# Let ID set people's usernames
|
||||
SiteSetting.auth_overrides_username = true
|
||||
@discourse_id_enabled = true
|
||||
@discourse_id_error = nil
|
||||
rescue StandardError => e
|
||||
@discourse_id_enabled = false
|
||||
@discourse_id_error = e.message
|
||||
end
|
||||
end
|
||||
|
||||
def seed_admin_users
|
||||
allowed_emails = find_allowed_emails
|
||||
if allowed_emails.empty?
|
||||
raise StandardError.new(I18n.t("finish_installation.discourse_id.no_allowed_emails"))
|
||||
end
|
||||
|
||||
allowed_emails.each do |email|
|
||||
next if User.find_by_email(email)
|
||||
|
||||
username = UserNameSuggester.suggest(email)
|
||||
|
||||
user =
|
||||
User.new(
|
||||
email: email,
|
||||
username: username,
|
||||
# no password needed, users will login via Discourse ID
|
||||
active: false, # will be activated upon first login
|
||||
admin: true,
|
||||
trust_level: TrustLevel[4],
|
||||
)
|
||||
user.save!(validate: false)
|
||||
end
|
||||
Group.refresh_automatic_groups!(:staff, :admins)
|
||||
end
|
||||
|
||||
def ensure_no_admins
|
||||
raise Discourse::InvalidAccess.new unless SiteSetting.has_login_hint?
|
||||
end
|
||||
|
||||
+1
-1
@@ -1977,7 +1977,7 @@ class User < ActiveRecord::Base
|
||||
def clear_global_notice_if_needed
|
||||
return if id < 0
|
||||
|
||||
if admin && SiteSetting.has_login_hint
|
||||
if admin && active && SiteSetting.has_login_hint
|
||||
SiteSetting.has_login_hint = false
|
||||
SiteSetting.global_notice = ""
|
||||
end
|
||||
|
||||
@@ -55,13 +55,11 @@ class DiscourseId::Register
|
||||
SiteSetting.discourse_id_client_secret = data["client_secret"]
|
||||
end
|
||||
|
||||
def log_action(guardian:, params:, data:)
|
||||
def log_action(params:, data:)
|
||||
return if params.update
|
||||
return if guardian.blank?
|
||||
|
||||
StaffActionLogger.new(guardian.user).log_custom(
|
||||
"discourse_id_register",
|
||||
client_id: data["client_id"],
|
||||
)
|
||||
user = context[:guardian]&.user || Discourse.system_user
|
||||
|
||||
StaffActionLogger.new(user).log_custom("discourse_id_register", client_id: data["client_id"])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,15 +1,29 @@
|
||||
<div class="wizard-congratulations-wrap">
|
||||
<div class='row'>
|
||||
<h1><%= t 'finish_installation.congratulations' %></h1>
|
||||
<p><%= t 'finish_installation.register.help' %></p>
|
||||
|
||||
<%= link_to(finish_installation_register_path, class: 'wizard-container__button btn-primary finish-installation__register') do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14px" height="14px" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</svg>
|
||||
<%= t 'finish_installation.register.button' %>
|
||||
<% if @setting_up_discourse_id && @discourse_id_enabled %>
|
||||
<p><%= raw(t 'finish_installation.discourse_id_help') %></p>
|
||||
<%= link_to(finish_installation_redirect_discourse_id_path, class: 'wizard-container__button btn-primary finish-installation__discourse-id') do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14px" height="14px" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</svg>
|
||||
<%= t 'finish_installation.login_with_discourse_id' %>
|
||||
<% end %>
|
||||
<% elsif @setting_up_discourse_id && @discourse_id_error %>
|
||||
<div class="alert alert-error">
|
||||
<%= @discourse_id_error %>
|
||||
</div>
|
||||
<p><%= raw(t 'finish_installation.discourse_id_error_help') %></p>
|
||||
<% else %>
|
||||
<p><%= t 'finish_installation.register.help' %></p>
|
||||
<%= link_to(finish_installation_register_path, class: 'wizard-container__button btn-primary finish-installation__register') do %>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14px" height="14px" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</svg>
|
||||
<%= t 'finish_installation.register.button' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
|
||||
<div class='row finish-installation-image'>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<div class="wizard-congratulations-wrap">
|
||||
<div class='row'>
|
||||
<h1><%= t 'finish_installation.congratulations' %></h1>
|
||||
<p><%= t 'finish_installation.discourse_id.help' %></p>
|
||||
|
||||
<div class='row finish-installation-image'>
|
||||
<img src="<%= Discourse.base_path + '/images/wizard/tada.svg' %>" alt="tada emoji" class="tada">
|
||||
</div>
|
||||
</div>
|
||||
@@ -13,9 +13,6 @@
|
||||
<div class='wizard-container-contents finish-installation'>
|
||||
<%= yield %>
|
||||
</div>
|
||||
<div class='wizard-footer'>
|
||||
<div class='discourse-logo'></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -5482,6 +5482,9 @@ en:
|
||||
|
||||
finish_installation:
|
||||
congratulations: "Congratulations, you installed Discourse!"
|
||||
login_with_discourse_id: "Login with Discourse ID"
|
||||
discourse_id_help: "Please log in with Discourse ID using the button below. <br/><br/>Make sure you use a Discourse ID account with a primary email that matches the `DISCOURSE_DEVELOPER_EMAILS` environment variable."
|
||||
discourse_id_error_help: "You have opted to skip setting up email for now. Unfortunately due to the error message above, the setup cannot continue. Please report this issue on <a href='https://meta.discourse.org/'>meta.discourse.org</a>."
|
||||
register:
|
||||
button: "Register"
|
||||
title: "Register Admin Account"
|
||||
@@ -5493,6 +5496,10 @@ en:
|
||||
resend_email:
|
||||
title: "Resend Activation Email"
|
||||
message: "<p>We've re-sent the activation email to <b>%{email}</b>"
|
||||
discourse_id:
|
||||
help: "We are now setting up Discourse ID for you."
|
||||
no_allowed_emails: "No allowed emails configured in DISCOURSE_DEVELOPER_EMAILS. Cannot continue with site setup."
|
||||
global_notice: "No admins have logged in yet. Please log in using a Discourse ID account with an email that matches the `DISCOURSE_DEVELOPER_EMAILS` environment variable to complete the installation."
|
||||
|
||||
safe_mode:
|
||||
title: "Enter safe mode"
|
||||
|
||||
@@ -71,6 +71,7 @@ Discourse::Application.routes.draw do
|
||||
get "finish-installation" => "finish_installation#index"
|
||||
get "finish-installation/register" => "finish_installation#register"
|
||||
post "finish-installation/register" => "finish_installation#register"
|
||||
get "finish-installation/redirect-discourse-id" => "finish_installation#redirect_discourse_id"
|
||||
get "finish-installation/confirm-email" => "finish_installation#confirm_email"
|
||||
put "finish-installation/resend-email" => "finish_installation#resend_email"
|
||||
|
||||
|
||||
@@ -2360,6 +2360,7 @@ RSpec.describe User do
|
||||
describe ".clear_global_notice_if_needed" do
|
||||
fab!(:user)
|
||||
fab!(:admin)
|
||||
let!(:inactive_user) { Fabricate(:user, active: false) }
|
||||
|
||||
before do
|
||||
SiteSetting.has_login_hint = true
|
||||
@@ -2378,11 +2379,18 @@ RSpec.describe User do
|
||||
expect(SiteSetting.global_notice).to eq("some notice")
|
||||
end
|
||||
|
||||
it "clears the notice when the admin is saved" do
|
||||
it "clears the notice when an active admin is saved" do
|
||||
admin.save
|
||||
expect(SiteSetting.has_login_hint).to eq(false)
|
||||
expect(SiteSetting.global_notice).to eq("")
|
||||
end
|
||||
|
||||
it "does not clear the notice when an inactive admin is saved" do
|
||||
inactive_user.admin = true
|
||||
inactive_user.save
|
||||
expect(SiteSetting.has_login_hint).to eq(true)
|
||||
expect(SiteSetting.global_notice).to eq("some notice")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".human_users" do
|
||||
|
||||
@@ -1,6 +1,86 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe FinishInstallationController do
|
||||
describe "#index" do
|
||||
context "when has_login_hint is false" do
|
||||
before { SiteSetting.has_login_hint = false }
|
||||
|
||||
it "doesn't allow access" do
|
||||
get "/finish-installation"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
|
||||
context "when has_login_hint is true" do
|
||||
before { SiteSetting.has_login_hint = true }
|
||||
|
||||
it "allows access" do
|
||||
get "/finish-installation"
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
|
||||
context "when setting up Discourse ID" do
|
||||
before do
|
||||
allow(ENV).to receive(:[]).and_call_original
|
||||
allow(ENV).to receive(:[]).with("DISCOURSE_SKIP_EMAIL_SETUP").and_return("1")
|
||||
GlobalSetting.stubs(:developer_emails).returns("admin@example.com")
|
||||
end
|
||||
|
||||
it "enables the enable_discourse_id site setting and shows login button on success" do
|
||||
stub_request(:post, "https://id.discourse.com/challenge").to_return(
|
||||
status: 200,
|
||||
body: { domain: Discourse.current_hostname, token: "test_token" }.to_json,
|
||||
)
|
||||
stub_request(:post, "https://id.discourse.com/register").to_return(
|
||||
status: 200,
|
||||
body: { client_id: "test_client_id", client_secret: "test_client_secret" }.to_json,
|
||||
)
|
||||
|
||||
get "/finish-installation"
|
||||
expect(response.status).to eq(200)
|
||||
expect(SiteSetting.enable_discourse_id).to eq(true)
|
||||
expect(SiteSetting.enable_local_logins).to eq(false)
|
||||
expect(response.body).to include("Login with Discourse ID")
|
||||
expect(response.body).to include("/finish-installation/redirect-discourse-id")
|
||||
end
|
||||
|
||||
it "shows error message and no login button on failure" do
|
||||
stub_request(:post, "https://id.discourse.com/challenge").to_return(
|
||||
status: 500,
|
||||
body: "Internal Server Error",
|
||||
)
|
||||
|
||||
get "/finish-installation"
|
||||
expect(response.status).to eq(200)
|
||||
expect(SiteSetting.enable_discourse_id).to eq(false)
|
||||
expect(response.body).not_to include("Login with Discourse ID")
|
||||
expect(response.body).to include("alert-error")
|
||||
end
|
||||
|
||||
it "shows error when developer_emails is empty" do
|
||||
GlobalSetting.stubs(:developer_emails).returns("")
|
||||
|
||||
stub_request(:post, "https://id.discourse.com/challenge").to_return(
|
||||
status: 200,
|
||||
body: { domain: Discourse.current_hostname, token: "test_token" }.to_json,
|
||||
)
|
||||
stub_request(:post, "https://id.discourse.com/register").to_return(
|
||||
status: 200,
|
||||
body: { client_id: "test_client_id", client_secret: "test_client_secret" }.to_json,
|
||||
)
|
||||
|
||||
get "/finish-installation"
|
||||
expect(response.status).to eq(200)
|
||||
expect(response.body).not_to include("Login with Discourse ID")
|
||||
expect(response.body).to include("alert-error")
|
||||
expect(response.body).to include(
|
||||
I18n.t("finish_installation.discourse_id.no_allowed_emails"),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#register" do
|
||||
before do
|
||||
SiteSetting.has_login_hint = true
|
||||
@@ -62,4 +142,32 @@ RSpec.describe FinishInstallationController do
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#redirect_discourse_id" do
|
||||
context "when has_login_hint is true" do
|
||||
before do
|
||||
SiteSetting.has_login_hint = true
|
||||
GlobalSetting.stubs(:developer_emails).returns("info@test.com")
|
||||
end
|
||||
|
||||
it "creates admin users and redirects to Discourse ID auth" do
|
||||
get "/finish-installation/redirect-discourse-id"
|
||||
expect(response.status).to eq(302)
|
||||
expect(response.location).to include("/auth/discourse_id")
|
||||
|
||||
admin_user = User.find_by_email("info@test.com")
|
||||
expect(admin_user).to be_present
|
||||
expect(admin_user.admin).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when has_login_hint is false" do
|
||||
before { SiteSetting.has_login_hint = false }
|
||||
|
||||
it "returns 403" do
|
||||
get "/finish-installation/redirect-discourse-id"
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,92 +7,190 @@ RSpec.describe "Finish Installation", type: :system do
|
||||
before { SiteSetting.has_login_hint = false }
|
||||
|
||||
it "denies access" do
|
||||
finish_installation_page.visit_index
|
||||
finish_installation_page.visit_page
|
||||
expect(finish_installation_page).to have_access_denied
|
||||
end
|
||||
end
|
||||
|
||||
context "when has_login_hint is true" do
|
||||
before do
|
||||
SiteSetting.has_login_hint = true
|
||||
GlobalSetting.stubs(:developer_emails).returns("admin@example.com,other@example.com")
|
||||
before { SiteSetting.has_login_hint = true }
|
||||
|
||||
context "when DISCOURSE_SKIP_EMAIL_SETUP=1" do
|
||||
before do
|
||||
allow(ENV).to receive(:[]).and_call_original
|
||||
allow(ENV).to receive(:[]).with("DISCOURSE_SKIP_EMAIL_SETUP").and_return("1")
|
||||
end
|
||||
|
||||
context "when ID registration is successful" do
|
||||
before do
|
||||
GlobalSetting.stubs(:developer_emails).returns("dev1@example.com,dev2@example.com")
|
||||
|
||||
stub_request(:post, "https://id.discourse.com/challenge").to_return(
|
||||
status: 200,
|
||||
body: { domain: Discourse.current_hostname, token: "test_token" }.to_json,
|
||||
)
|
||||
stub_request(:post, "https://id.discourse.com/register").to_return(
|
||||
status: 200,
|
||||
body: { client_id: "test_client_id", client_secret: "test_client_secret" }.to_json,
|
||||
)
|
||||
end
|
||||
|
||||
it "enables Discourse ID and shows login button" do
|
||||
finish_installation_page.visit_page
|
||||
|
||||
expect(finish_installation_page).to have_discourse_id_button
|
||||
expect(finish_installation_page).to have_no_register_button
|
||||
expect(finish_installation_page).to have_no_error_message
|
||||
end
|
||||
|
||||
it "creates multiple admin users when multiple emails are configured" do
|
||||
finish_installation_page.visit_page
|
||||
finish_installation_page.click_login_with_discourse_id
|
||||
|
||||
user1 = User.find_by_email("dev1@example.com")
|
||||
user2 = User.find_by_email("dev2@example.com")
|
||||
|
||||
expect(user1).to be_present
|
||||
expect(user1.admin).to eq(true)
|
||||
expect(user2).to be_present
|
||||
expect(user2.admin).to eq(true)
|
||||
|
||||
expect(page.current_url).to include("id.discourse.com")
|
||||
end
|
||||
|
||||
it "skips creating users that already exist" do
|
||||
Fabricate(:user, email: "dev1@example.com", admin: false)
|
||||
Fabricate(:user, email: "dev2@example.com", admin: false)
|
||||
initial_user_count = User.count
|
||||
|
||||
finish_installation_page.visit_page
|
||||
finish_installation_page.click_login_with_discourse_id
|
||||
|
||||
expect(User.count).to eq(initial_user_count)
|
||||
end
|
||||
end
|
||||
|
||||
context "when developer_emails is empty" do
|
||||
before { GlobalSetting.stubs(:developer_emails).returns("") }
|
||||
|
||||
it "shows error message about missing allowed emails" do
|
||||
finish_installation_page.visit_page
|
||||
|
||||
expect(finish_installation_page).to have_no_discourse_id_button
|
||||
expect(finish_installation_page).to have_no_register_button
|
||||
expect(finish_installation_page).to have_error_message
|
||||
expect(finish_installation_page.error_message_text).to include(
|
||||
I18n.t("finish_installation.discourse_id.no_allowed_emails"),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when ID registration fails with an error" do
|
||||
before do
|
||||
GlobalSetting.stubs(:developer_emails).returns("dev1@example.com,dev2@example.com")
|
||||
|
||||
failed_context = Service::Base::Context.new
|
||||
failed_context.fail(error: "Failed to connect to Discourse ID")
|
||||
allow(DiscourseId::Register).to receive(:call).and_return(failed_context)
|
||||
end
|
||||
|
||||
it "shows error message and no login button" do
|
||||
finish_installation_page.visit_page
|
||||
|
||||
expect(finish_installation_page).to have_no_discourse_id_button
|
||||
expect(finish_installation_page).to have_no_register_button
|
||||
expect(finish_installation_page).to have_error_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "shows validation error when username is blank" do
|
||||
finish_installation_page.visit_register.fill_password("supersecurepassword").submit
|
||||
expect(finish_installation_page).to have_username_error
|
||||
end
|
||||
context "when using local registration" do
|
||||
before do
|
||||
GlobalSetting.stubs(:developer_emails).returns("admin@example.com,other@example.com")
|
||||
end
|
||||
|
||||
it "shows validation error when password is blank" do
|
||||
finish_installation_page.visit_register.fill_username("newadmin").submit
|
||||
expect(finish_installation_page).to have_password_error
|
||||
end
|
||||
it "shows local register form button" do
|
||||
finish_installation_page.visit_page
|
||||
|
||||
it "shows validation error when password is too short" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.fill_username("newadmin")
|
||||
.fill_password("short")
|
||||
.submit
|
||||
expect(finish_installation_page).to have_password_error("too short")
|
||||
end
|
||||
expect(finish_installation_page).to have_register_button
|
||||
expect(finish_installation_page).to have_no_discourse_id_button
|
||||
expect(finish_installation_page).to have_no_error_message
|
||||
end
|
||||
|
||||
it "registers admin and redirects to confirm email page" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("admin@example.com")
|
||||
.fill_username("newadmin")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
it "shows validation error when username is blank" do
|
||||
finish_installation_page.visit_register.fill_password("supersecurepassword").submit
|
||||
expect(finish_installation_page).to have_username_error
|
||||
end
|
||||
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
expect(User.find_by(username: "newadmin")).to have_attributes(
|
||||
email: "admin@example.com",
|
||||
trust_level: 1,
|
||||
)
|
||||
end
|
||||
it "shows validation error when password is blank" do
|
||||
finish_installation_page.visit_register.fill_username("newadmin").submit
|
||||
expect(finish_installation_page).to have_password_error
|
||||
end
|
||||
|
||||
it "handles multiple developer emails" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("other@example.com")
|
||||
.fill_username("otheradmin")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
it "shows validation error when password is too short" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.fill_username("newadmin")
|
||||
.fill_password("short")
|
||||
.submit
|
||||
expect(finish_installation_page).to have_password_error("too short")
|
||||
end
|
||||
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
expect(User.find_by(username: "otheradmin")).to be_present
|
||||
end
|
||||
|
||||
it "resends activation email when user already exists" do
|
||||
Fabricate(:user, email: "admin@example.com")
|
||||
|
||||
expect {
|
||||
it "registers admin and redirects to confirm email page" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("admin@example.com")
|
||||
.fill_username("differentuser")
|
||||
.fill_username("newadmin")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
}.to change { Jobs::CriticalUserEmail.jobs.size }.by(1)
|
||||
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
end
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
expect(User.find_by(username: "newadmin")).to have_attributes(
|
||||
email: "admin@example.com",
|
||||
trust_level: 1,
|
||||
)
|
||||
end
|
||||
|
||||
it "does not send email when user is already active and confirmed" do
|
||||
user = Fabricate(:user, email: "admin@example.com", active: true)
|
||||
user.activate
|
||||
|
||||
expect {
|
||||
it "handles multiple developer emails" do
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("admin@example.com")
|
||||
.fill_username("differentuser")
|
||||
.select_email("other@example.com")
|
||||
.fill_username("otheradmin")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
}.not_to change { Jobs::CriticalUserEmail.jobs.size }
|
||||
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
expect(User.find_by(username: "otheradmin")).to be_present
|
||||
end
|
||||
|
||||
it "resends activation email when user already exists" do
|
||||
Fabricate(:user, email: "admin@example.com")
|
||||
|
||||
expect {
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("admin@example.com")
|
||||
.fill_username("differentuser")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
}.to change { Jobs::CriticalUserEmail.jobs.size }.by(1)
|
||||
|
||||
expect(finish_installation_page).to be_redirected_to_confirm_email
|
||||
end
|
||||
|
||||
it "does not send email when user is already active and confirmed" do
|
||||
user = Fabricate(:user, email: "admin@example.com", active: true)
|
||||
user.activate
|
||||
|
||||
expect {
|
||||
finish_installation_page
|
||||
.visit_register
|
||||
.select_email("admin@example.com")
|
||||
.fill_username("differentuser")
|
||||
.fill_password("supersecurepassword")
|
||||
.submit
|
||||
}.not_to change { Jobs::CriticalUserEmail.jobs.size }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,13 +3,46 @@
|
||||
module PageObjects
|
||||
module Pages
|
||||
class FinishInstallation < PageObjects::Pages::Base
|
||||
def visit_page
|
||||
page.visit("/finish-installation")
|
||||
self
|
||||
end
|
||||
|
||||
def visit_register
|
||||
visit("/finish-installation/register")
|
||||
self
|
||||
end
|
||||
|
||||
def visit_index
|
||||
visit("/finish-installation")
|
||||
def has_discourse_id_button?
|
||||
page.has_css?(".finish-installation__discourse-id", text: "Login with Discourse ID")
|
||||
end
|
||||
|
||||
def has_no_discourse_id_button?
|
||||
page.has_no_css?(".finish-installation__discourse-id")
|
||||
end
|
||||
|
||||
def has_register_button?
|
||||
page.has_css?(".finish-installation__register", text: "Register")
|
||||
end
|
||||
|
||||
def has_no_register_button?
|
||||
page.has_no_css?(".finish-installation__register")
|
||||
end
|
||||
|
||||
def has_error_message?
|
||||
page.has_css?(".alert-error")
|
||||
end
|
||||
|
||||
def has_no_error_message?
|
||||
page.has_no_css?(".alert-error")
|
||||
end
|
||||
|
||||
def error_message_text
|
||||
find(".alert-error").text
|
||||
end
|
||||
|
||||
def click_login_with_discourse_id
|
||||
find(".finish-installation__discourse-id").click
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user