Merge branch 'origin'

This commit is contained in:
Kay Faraday 2024-08-13 14:43:35 -07:00
commit 08c7908b52
20 changed files with 385 additions and 153 deletions

View File

@ -96,7 +96,7 @@ group :development, :test do
gem "rspec-sidekiq", "~> 5.0", require: false
gem "rubocop", "~> 1.65"
gem "rubocop-rails", "~> 2.25"
gem "shoulda-matchers", "~> 6.2"
gem "shoulda-matchers", "~> 6.3"
gem "simplecov", require: false
gem "simplecov-cobertura", require: false
gem "simplecov-json", require: false

View File

@ -99,7 +99,7 @@ GEM
bigdecimal (3.1.8)
binding_of_caller (1.0.1)
debug_inspector (>= 1.2.0)
bootsnap (1.18.3)
bootsnap (1.18.4)
msgpack (~> 1.2)
bootstrap_form (5.3.2)
actionpack (>= 6.1)
@ -121,7 +121,7 @@ GEM
childprocess (5.0.0)
chunky_png (1.4.0)
colorize (1.1.0)
concurrent-ruby (1.3.3)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
crass (1.0.6)
cssbundling-rails (1.4.1)
@ -301,17 +301,19 @@ GEM
nokogiri (1.16.7)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
oj (3.16.4)
oj (3.16.5)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
openssl (3.2.0)
orm_adapter (0.5.0)
ostruct (0.6.0)
parallel (1.25.1)
parser (3.3.4.0)
ast (~> 2.4.1)
racc
pg (1.5.7)
pghero (3.5.0)
activerecord (>= 6)
pghero (3.6.0)
activerecord (>= 6.1)
prometheus-client (4.2.3)
base64
public_suffix (6.0.1)
@ -463,7 +465,7 @@ GEM
sentry-sidekiq (5.18.2)
sentry-ruby (~> 5.18.2)
sidekiq (>= 3.0)
shoulda-matchers (6.2.0)
shoulda-matchers (6.3.0)
activesupport (>= 5.2.0)
sidekiq (6.5.12)
connection_pool (>= 2.2.5, < 3)
@ -607,7 +609,7 @@ DEPENDENCIES
sentry-rails
sentry-ruby
sentry-sidekiq
shoulda-matchers (~> 6.2)
shoulda-matchers (~> 6.3)
sidekiq (< 7)
sidekiq-scheduler
simplecov

View File

@ -1,7 +1,11 @@
# frozen_string_literal: true
class AboutController < ApplicationController
def index; end
def index
return unless Retrospring::Config.advanced_frontpage_enabled?
render template: "about/index_advanced"
end
def about
@users = Rails.cache.fetch("about_count_users", expires_in: 1.hour) { user_count - current_ban_count }

View File

@ -1,4 +1,8 @@
# frozen_string_literal: true
class User::RegistrationsController < Devise::RegistrationsController
before_action :redirect_if_registrations_disabled!, only: %w[create new] # rubocop:disable Rails/LexicallyScopedActionFilter
def create
if captcha_valid?
super
@ -29,4 +33,8 @@ class User::RegistrationsController < Devise::RegistrationsController
verify_hcaptcha
end
def redirect_if_registrations_disabled!
redirect_to root_path unless Retrospring::Config.registrations_enabled?
end
end

View File

@ -1,88 +1,33 @@
- provide(:title, APP_CONFIG["site_name"])
.container
.card.bg-primary.my-3.text-bg-primary.text-center
.card-body.py-4
= render "layouts/messages"
%h1= APP_CONFIG["site_name"]
%p= t(".subtitle")
%p
%a.btn.btn-outline-light.btn-lg{ href: url_for(new_user_registration_path) }
= t(".register")
%small
= t(".already_member")
= link_to t("voc.login"), new_user_session_path
.row.my-5.my-sm-10
.col-sm-6.order-5.order-sm-1.text-center.text-sm-right
%h2.mb-4= t(".questions.header")
= t(".questions.body_html", app_name: APP_CONFIG["site_name"])
.col-sm-6.order-1.order-sm-5
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-envelope.align-self-center.mb-5.mb-sm-0
.row.my-5.my-sm-10
.col-sm-6
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-comments.align-self-center.mb-5.mb-sm-0
.col-sm-6.text-center.text-sm-left
%h2.mb-4= t(".discussions.header")
= t(".discussions.body_html", app_name: APP_CONFIG["site_name"])
.row.my-5.my-sm-10
.col-sm-6.order-5.order-sm-1.text-center.text-sm-right
%h2.mb-4= t(".share.header")
= t(".share.body_html", app_name: APP_CONFIG["site_name"])
.col-sm-6.order-1.order-sm-5
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-share.align-self-center.mb-5.mb-sm-0
.row.my-5.my-sm-10
.col-sm-6
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-paint-brush.align-self-center.mb-5.mb-sm-0
.col-sm-6.text-center.text-sm-left
%h2.mb-4= t(".customize.header")
= t(".customize.body_html", app_name: APP_CONFIG["site_name"])
.py-3.py-sm-5
.row.d-sm-flex
.col-md-8.align-self-center.text-center.text-md-start
%h1
- if APP_CONFIG["use_svg_logo"]
.d-inline-block.w-50
= render inline: Rails.application.config.justask_svg_logo
- else
= APP_CONFIG["site_name"]
- if Rails.env.development?
%span.badge.rounded-pill.bg-warning.text-bg-warning
DEV
%p.lead= APP_CONFIG["site_tagline"]
.col-md-4
- if Retrospring::Config.registrations_enabled?
%a.btn.btn-primary.d-grid{ href: url_for(new_user_registration_path) }
= t("voc.register_now")
.d-block.text-center.py-2.text-secondary
= t(".or")
.card
.card-body
.row.mx-n2
.col.px-2
.d-grid
%button.btn.btn-success.js-theme-button{ data: { theme: "theme-success" } }= t(".customize.themes.green")
.col.px-2
.d-grid
%button.btn.btn-warning.js-theme-button{ data: { theme: "theme-warning" } }= t(".customize.themes.orange")
.col.px-2
.d-grid
%button.btn.btn-danger.js-theme-button{ data: { theme: "theme-danger" } }= t(".customize.themes.red")
.col.px-2
.d-grid
%button.btn.btn-default.js-theme-button{ data: { theme: "reset" } }= t(".customize.themes.reset")
= bootstrap_form_for(User.new, as: :user, url: session_path(:user), data: { turbo: false }) do |f|
.container.text-center
%h2.mb-4= t(".more_features")
.row.my-5
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-globe.text-primary
= t(".open_source.header")
%p= t(".open_source.body", app_name: APP_CONFIG["site_name"])
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-eye-slash.text-primary
= t(".no_ads.header")
%p= t(".no_ads.body")
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-user-secret.text-primary
= t(".your_data.header")
%p= t(".your_data.body", app_name: APP_CONFIG["site_name"])
= f.text_field :login, autofocus: true, autocomplete: :username
= f.password_field :password, autocomplete: "current-password"
.card
.card-body
%h2= t(".prompt.header")
%p= t(".prompt.body")
%p
%a.btn.btn-primary.btn-lg{ href: url_for(new_user_registration_path) }
= t(".register")
- if Devise.mappings[:user].rememberable?
= f.check_box :remember_me
= f.primary t("voc.login"), class: "btn btn-primary d-grid w-100"
= render "shared/links"

View File

@ -0,0 +1,95 @@
- provide(:title, APP_CONFIG["site_name"])
.container
.card.bg-primary.my-3.text-bg-primary.text-center
.card-body.py-4
= render "layouts/messages"
%h1= APP_CONFIG["site_name"]
%p= APP_CONFIG["site_tagline"]
- if Retrospring::Config.registrations_enabled?
%p
%a.btn.btn-outline-light.btn-lg{ href: url_for(new_user_registration_path) }
= t("voc.register_now")
%small
= t(".already_member")
= link_to t("voc.login"), new_user_session_path
- else
%p
%a.btn.btn-outline-light.btn-lg{ href: url_for(new_user_session_path) }
= t("voc.login")
.row.my-5.my-sm-10
.col-sm-6.order-5.order-sm-1.text-center.text-sm-right
%h2.mb-4= t(".questions.header")
= t(".questions.body_html", app_name: APP_CONFIG["site_name"])
.col-sm-6.order-1.order-sm-5
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-envelope.align-self-center.mb-5.mb-sm-0
.row.my-5.my-sm-10
.col-sm-6
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-comments.align-self-center.mb-5.mb-sm-0
.col-sm-6.text-center.text-sm-left
%h2.mb-4= t(".discussions.header")
= t(".discussions.body_html", app_name: APP_CONFIG["site_name"])
.row.my-5.my-sm-10
.col-sm-6.order-5.order-sm-1.text-center.text-sm-right
%h2.mb-4= t(".share.header")
= t(".share.body_html", app_name: APP_CONFIG["site_name"])
.col-sm-6.order-1.order-sm-5
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-share.align-self-center.mb-5.mb-sm-0
.row.my-5.my-sm-10
.col-sm-6
.text-center.text-primary.d-flex.h-100.justify-content-center.fs-10
%i.fa.fa-paint-brush.align-self-center.mb-5.mb-sm-0
.col-sm-6.text-center.text-sm-left
%h2.mb-4= t(".customize.header")
= t(".customize.body_html", app_name: APP_CONFIG["site_name"])
.card
.card-body
.row.mx-n2
.col.px-2
.d-grid
%button.btn.btn-success.js-theme-button{ data: { theme: "theme-success" } }= t(".customize.themes.green")
.col.px-2
.d-grid
%button.btn.btn-warning.js-theme-button{ data: { theme: "theme-warning" } }= t(".customize.themes.orange")
.col.px-2
.d-grid
%button.btn.btn-danger.js-theme-button{ data: { theme: "theme-danger" } }= t(".customize.themes.red")
.col.px-2
.d-grid
%button.btn.btn-default.js-theme-button{ data: { theme: "reset" } }= t(".customize.themes.reset")
.container.text-center
%h2.mb-4= t(".more_features")
.row.my-5
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-globe.text-primary
= t(".open_source.header")
%p= t(".open_source.body", app_name: APP_CONFIG["site_name"])
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-eye-slash.text-primary
= t(".no_ads.header")
%p= t(".no_ads.body")
.col-sm-4
%h3.mb-3
%i.fa.fa-fw.fa-user-secret.text-primary
= t(".your_data.header")
%p= t(".your_data.body", app_name: APP_CONFIG["site_name"])
- if APP_CONFIG.dig(:features, :registration, :enabled)
.card
.card-body
%h2= t(".prompt.header")
%p= t(".prompt.body")
%p
%a.btn.btn-primary.btn-lg{ href: url_for(new_user_registration_path) }
= t(".register")
= render "shared/links"

View File

@ -19,10 +19,18 @@
%strong= t(".status.locked")
- elsif !user_signed_in? && user.privacy_require_user?
.text-center
%strong= t(".status.require_user_html", sign_in: link_to(t("voc.login"), new_user_session_path), sign_up: link_to(t("voc.register"), new_user_registration_path))
- if Retrospring::Config.registrations_enabled?
%strong= t(".status.require_user_html",
sign_in: link_to(t("voc.login"), new_user_session_path),
sign_up: link_to(t("voc.register"), new_user_registration_path))
- else
%strong= t(".status.require_user_no_registration_html",
sign_in: link_to(t("voc.login"), new_user_session_path))
- else
- if user_signed_in? || user.privacy_allow_anonymous_questions?
#question-box{ data: user.profile.allow_long_questions ? {} : { controller: "character-count", "character-count-max-value": user.profile.question_length_limit }}
#question-box{
data: user.profile.allow_long_questions ? {} : { controller: "character-count", "character-count-max-value": user.profile.question_length_limit }
}
%textarea.form-control{ name: "qb-question", placeholder: t(".placeholder"), data: { "character-count-target": "input" } }
.row{ style: "padding-top: 5px;" }
.col-6
@ -36,14 +44,21 @@
%input{ name: "qb-anonymous", type: :hidden, value: false }/
.col-6
%p.pull-right
%span.text-muted.me-1{ class: user.profile.allow_long_questions ? "d-none" : "", data: { "character-count-target": "counter" } }= Question::SHORT_QUESTION_MAX_LENGTH
%span.text-muted.me-1{ class: user.profile.allow_long_questions ? "d-none" : "",
data: { "character-count-target": "counter" } }= Question::SHORT_QUESTION_MAX_LENGTH
%input{ name: "qb-to", type: "hidden", value: user.id }/
%button.btn.btn-primary{ name: "qb-ask",
type: :button,
data: { loading_text: t(".load"), promote: user_signed_in? ? "false" : "true", "character-count-target": "action" } }
data: {
loading_text: t(".load"),
promote: user_signed_in? || !user_signed_in? && !Retrospring::Config.registrations_enabled? ? "false" : "true",
"character-count-target": "action"
}
}
Ask
- unless user_signed_in?
- if user.privacy_allow_anonymous_questions?
- if Retrospring::Config.registrations_enabled?
.d-none#question-box-promote
.row
.col-12.text-center
@ -60,4 +75,9 @@
%small= t(".promote.join", app_title: APP_CONFIG["site_name"])
- else
.text-center
%strong= t(".status.non_anonymous_html", sign_in: link_to(t("voc.login"), new_user_session_path), sign_up: link_to(t("voc.register"), new_user_registration_path))
- if Retrospring::Config.registrations_enabled?
%strong= t(".status.non_anonymous_html",
sign_in: link_to(t("voc.login"), new_user_session_path),
sign_up: link_to(t("voc.register"), new_user_registration_path))
- else
%strong= t(".status.non_anonymous_no_registration_html", sign_in: link_to(t("voc.login"), new_user_session_path))

View File

@ -2,7 +2,7 @@
= link_to 'Sign in', new_session_path(resource_name)
%br/
- if devise_mapping.registerable? && controller_name != 'registrations'
- if devise_mapping.registerable? && controller_name != 'registrations' && Retrospring::Config.registrations_enabled?
= link_to 'Sign up', new_registration_path(resource_name)
%br/

View File

@ -14,4 +14,5 @@
.collapse.navbar-collapse#j2-main-navbar-collapse
%ul.nav.navbar-nav.ms-auto
= nav_entry t("voc.login"), new_user_session_path
- if Retrospring::Config.registrations_enabled?
= nav_entry t("voc.register"), new_user_registration_path

View File

@ -1,23 +1,4 @@
# frozen_string_literal: true
# Auxiliary config
APP_CONFIG = {}.with_indifferent_access
# load yml config if it's present
justask_yml_path = Rails.root.join("config/justask.yml")
APP_CONFIG.merge!(YAML.load_file(justask_yml_path)) if File.exist?(justask_yml_path)
# load config from ENV where possible
env_config = {
# The site name, shown everywhere
site_name: ENV.fetch("SITE_NAME", nil),
hostname: ENV.fetch("HOSTNAME", nil),
}.compact
APP_CONFIG.merge!(env_config)
# Update rails config for mail
Rails.application.config.action_mailer.default_url_options = {
host: APP_CONFIG["hostname"],
}
APP_CONFIG = Retrospring::Config.config_hash

View File

@ -1,6 +1,9 @@
# The site name, shown everywhere.
site_name: "justask"
# The sites tagline, shown on the start page
site_tagline: "Ask questions, give answers and learn more about your friends."
# Use the SVG logo from `/public/logo.svg`
use_svg_logo: false
@ -52,6 +55,12 @@ features:
# Public timeline
public:
enabled: true
# Registrations
registration:
enabled: true
# Advanced (marketing) frontpage layout
advanced_frontpage:
enabled: false
# Redis
redis_url: "redis://localhost:6379"

View File

@ -2,8 +2,8 @@ en:
language: "English"
about:
index:
subtitle: "Ask questions, give answers and learn more about your friends."
register: "Register now"
or: "or"
index_advanced:
already_member: "Already a member?"
more_features: "But wait, there's more!"
questions:
@ -143,9 +143,15 @@ en:
require_user_html: |
This user requires others to be logged in to ask questions. <br/>
(%{sign_in} or %{sign_up})
require_user_no_registration_html: |
This user requires others to be logged in to ask questions. <br/>
(%{sign_in})
non_anonymous_html: |
This user does not want to receive anonymous questions. <br/>
(%{sign_in} or %{sign_up})
non_anonymous_no_registration_html: |
This user does not want to receive anonymous questions. <br/>
(%{sign_in})
comment:
show_reactions:
title: "People who smiled this comment"

View File

@ -24,6 +24,7 @@ en:
subscribe: "Subscribe"
unsubscribe: "Unsubscribe"
register: "Sign up"
register_now: "Register now"
remove: "Remove"
report: "Report"
terms: "Terms of Service"

View File

@ -63,7 +63,7 @@ Rails.application.routes.draw do
# :registrations
get "settings/delete_account" => "devise/registrations#cancel", :as => :cancel_user_registration
post "/user/create" => "user/registrations#create", :as => :user_registration
get "/sign_up" => "devise/registrations#new", :as => :new_user_registration
get "/sign_up" => "user/registrations#new", :as => :new_user_registration
get "/settings/account" => "devise/registrations#edit", :as => :edit_user_registration
patch "/settings/account" => "devise/registrations#update", :as => :update_user_registration
put "/settings/account" => "devise/registrations#update"

29
lib/retrospring/config.rb Normal file
View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
module Retrospring
module Config
module_function
def config_hash = {}.with_indifferent_access.tap do |hash|
# load yml config if it's present
justask_yml_path = Rails.root.join("config/justask.yml")
hash.merge!(YAML.load_file(justask_yml_path)) if File.exist?(justask_yml_path)
# load config from ENV where possible
env_config = {
# The site name, shown everywhere
site_name: ENV.fetch("SITE_NAME", nil),
}.compact
hash.merge!(env_config)
# Update rails config for mail
Rails.application.config.action_mailer.default_url_options = {
host: hash["hostname"],
}
end
def registrations_enabled? = APP_CONFIG.dig(:features, :registration, :enabled)
def advanced_frontpage_enabled? = APP_CONFIG.dig(:features, :advanced_frontpage, :enabled)
end
end

View File

@ -17,9 +17,9 @@ module Retrospring
def month = 8
def day = 6
def day = 11
def patch = 0
def patch = 1
def suffix = ""

View File

@ -3,6 +3,32 @@
require "rails_helper"
describe AboutController, type: :controller do
describe "#index" do
subject { get :index }
context "advanced layout is enabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :advanced_frontpage, :enabled).and_return(true)
end
it "renders the correct template" do
subject
expect(response).to render_template("about/index_advanced")
end
end
context "advanced layout is disabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :advanced_frontpage, :enabled).and_return(false)
end
it "renders the correct template" do
subject
expect(response).to render_template("about/index")
end
end
end
describe "#about" do
subject { get :about }

View File

@ -15,15 +15,15 @@ describe User::RegistrationsController, type: :controller do
justask_admin retrospring_admin admin justask retrospring
moderation moderator mod administrator siteadmin site_admin
help retro_spring retroospring retrosprlng
]
})
],
},)
end
describe "#create" do
context "valid user sign up" do
before do
allow(APP_CONFIG).to receive(:dig).with(:hcaptcha, :enabled).and_return(true)
allow(controller).to receive(:verify_hcaptcha).and_return(captcha_successful)
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(true)
end
let :registration_params do
@ -32,15 +32,18 @@ describe User::RegistrationsController, type: :controller do
screen_name: "dio",
email: "the-world-21@somewhere.everywhere.now",
password: "AReallySecurePassword456!",
password_confirmation: "AReallySecurePassword456!"
}
password_confirmation: "AReallySecurePassword456!",
},
}
end
subject { post :create, params: registration_params }
context "when captcha is invalid" do
let(:captcha_successful) { false }
before do
allow(controller).to receive(:verify_hcaptcha).and_return(false)
end
it "doesn't allow a registration with an invalid captcha" do
expect { subject }.not_to(change { User.count })
expect(response).to redirect_to :new_user_registration
@ -48,17 +51,39 @@ describe User::RegistrationsController, type: :controller do
end
context "when captcha is valid" do
let(:captcha_successful) { true }
before do
allow(controller).to receive(:verify_hcaptcha).and_return(true)
end
it "creates a user" do
allow(controller).to receive(:verify_hcaptcha).and_return(true)
expect { subject }.to change { User.count }.by(1)
end
end
context "when registrations are disabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:hcaptcha, :enabled).and_return(false)
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(false)
end
it "redirects to the root page" do
allow(controller).to receive(:verify_hcaptcha).and_return(true)
subject
expect(response).to redirect_to(root_path)
end
it "does not create a user" do
allow(controller).to receive(:verify_hcaptcha).and_return(true)
expect { subject }.not_to(change { User.count })
end
end
end
context "invalid user sign up" do
before do
allow(APP_CONFIG).to receive(:dig).with(:hcaptcha, :enabled).and_return(false)
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(true)
end
subject { post :create, params: registration_params }
@ -70,8 +95,8 @@ describe User::RegistrationsController, type: :controller do
screen_name: "",
email: "",
password: "",
password_confirmation: ""
}
password_confirmation: "",
},
}
end
@ -87,8 +112,8 @@ describe User::RegistrationsController, type: :controller do
screen_name: "Dio Brando",
email: "the-world-21@somewhere.everywhere.now",
password: "AReallySecurePassword456!",
password_confirmation: "AReallySecurePassword456!"
}
password_confirmation: "AReallySecurePassword456!",
},
}
end
@ -104,8 +129,8 @@ describe User::RegistrationsController, type: :controller do
screen_name: "moderator",
email: "the-world-21@somewhere.everywhere.now",
password: "AReallySecurePassword456!",
password_confirmation: "AReallySecurePassword456!"
}
password_confirmation: "AReallySecurePassword456!",
},
}
end
@ -115,4 +140,20 @@ describe User::RegistrationsController, type: :controller do
end
end
end
describe "#new" do
subject { get :new }
context "when registrations are disabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:hcaptcha, :enabled).and_return(false)
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(false)
end
it "redirects to the root page" do
subject
expect(response).to redirect_to(root_path)
end
end
end
end

View File

@ -0,0 +1,35 @@
# frozen_string_literal: true
require "rails_helper"
describe "about/index_advanced.html.haml", type: :view do
before do
stub_const("APP_CONFIG", {
"hostname" => "example.com",
"https" => true,
"sitename" => "yastask",
},)
end
subject(:rendered) { render }
context "registrations are enabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(true)
end
it "has references to registering now" do
expect(rendered).to match(/Register now/)
end
end
context "registrations are disabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(false)
end
it "has no references to registering now" do
expect(rendered).to_not match(/Register now/)
end
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
require "rails_helper"
describe "navigation/_guest.html.haml", type: :view do
subject(:rendered) do
render partial: "navigation/guest"
end
context "registrations are enabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(true)
end
it "has a sign up link" do
expect(rendered).to match(/Sign up/)
end
end
context "registrations are disabled" do
before do
allow(APP_CONFIG).to receive(:dig).with(:features, :registration, :enabled).and_return(false)
end
it "has no sign up link" do
expect(rendered).to_not match(/Sign up/)
end
end
end