diff --git a/Gemfile b/Gemfile index fe623de6..5770aa17 100644 --- a/Gemfile +++ b/Gemfile @@ -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 diff --git a/Gemfile.lock b/Gemfile.lock index 583a7898..29b329a7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/controllers/about_controller.rb b/app/controllers/about_controller.rb index 0b20d1b2..06b59b9d 100644 --- a/app/controllers/about_controller.rb +++ b/app/controllers/about_controller.rb @@ -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 } diff --git a/app/controllers/user/registrations_controller.rb b/app/controllers/user/registrations_controller.rb index e4f2e906..b7b633b8 100644 --- a/app/controllers/user/registrations_controller.rb +++ b/app/controllers/user/registrations_controller.rb @@ -1,9 +1,13 @@ +# 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 else - respond_with_navigational(resource){ redirect_to new_user_registration_path } + respond_with_navigational(resource) { redirect_to new_user_registration_path } end end @@ -18,7 +22,7 @@ class User::RegistrationsController < Devise::RegistrationsController resource.destroy set_flash_message :notice, :destroyed if is_flashing_format? yield resource if block_given? - respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) } + respond_with_navigational(resource) { redirect_to after_sign_out_path_for(resource_name) } end private @@ -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 diff --git a/app/views/about/index.html.haml b/app/views/about/index.html.haml index 87bf9d14..9af47130 100644 --- a/app/views/about/index.html.haml +++ b/app/views/about/index.html.haml @@ -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 + .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 + = bootstrap_form_for(User.new, as: :user, url: session_path(:user), data: { turbo: false }) do |f| - .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"]) + = f.text_field :login, autofocus: true, autocomplete: :username + = f.password_field :password, autocomplete: "current-password" - .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 + - if Devise.mappings[:user].rememberable? + = f.check_box :remember_me - .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") + = f.primary t("voc.login"), class: "btn btn-primary d-grid w-100" -.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"]) - - .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" + = render "shared/links" diff --git a/app/views/about/index_advanced.html.haml b/app/views/about/index_advanced.html.haml new file mode 100644 index 00000000..b8a6b852 --- /dev/null +++ b/app/views/about/index_advanced.html.haml @@ -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" diff --git a/app/views/application/_questionbox.html.haml b/app/views/application/_questionbox.html.haml index c6bfee72..394f07f9 100644 --- a/app/views/application/_questionbox.html.haml +++ b/app/views/application/_questionbox.html.haml @@ -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,28 +44,40 @@ %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? - .d-none#question-box-promote - .row - .col-12.text-center - %strong= t(".promote.message") - .row - .col-sm-5.offset-sm-1 - .d-grid - %button.btn.btn-primary#create-account= t(".promote.create") - .col-sm-5 - .d-grid - %button.btn.btn-default#new-question= t(".promote.another") - .row - .col-xs-12.col-sm-10.offset-sm-1.text-center - %small= t(".promote.join", app_title: APP_CONFIG["site_name"]) + - if Retrospring::Config.registrations_enabled? + .d-none#question-box-promote + .row + .col-12.text-center + %strong= t(".promote.message") + .row + .col-sm-5.offset-sm-1 + .d-grid + %button.btn.btn-primary#create-account= t(".promote.create") + .col-sm-5 + .d-grid + %button.btn.btn-default#new-question= t(".promote.another") + .row + .col-xs-12.col-sm-10.offset-sm-1.text-center + %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)) diff --git a/app/views/devise/shared/_links.html.haml b/app/views/devise/shared/_links.html.haml index 18ff87cc..8512a6e1 100644 --- a/app/views/devise/shared/_links.html.haml +++ b/app/views/devise/shared/_links.html.haml @@ -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/ diff --git a/app/views/navigation/_guest.html.haml b/app/views/navigation/_guest.html.haml index 4d9c330d..69bf3a62 100644 --- a/app/views/navigation/_guest.html.haml +++ b/app/views/navigation/_guest.html.haml @@ -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 - = nav_entry t("voc.register"), new_user_registration_path + - if Retrospring::Config.registrations_enabled? + = nav_entry t("voc.register"), new_user_registration_path diff --git a/config/initializers/10_config.rb b/config/initializers/10_config.rb index deba98c4..6a366cef 100644 --- a/config/initializers/10_config.rb +++ b/config/initializers/10_config.rb @@ -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 diff --git a/config/justask.yml.example b/config/justask.yml.example index 22f309a4..f6c4fa80 100644 --- a/config/justask.yml.example +++ b/config/justask.yml.example @@ -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" diff --git a/config/locales/views.en.yml b/config/locales/views.en.yml index f918d3e4..27044c0b 100644 --- a/config/locales/views.en.yml +++ b/config/locales/views.en.yml @@ -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.
(%{sign_in} or %{sign_up}) + require_user_no_registration_html: | + This user requires others to be logged in to ask questions.
+ (%{sign_in}) non_anonymous_html: | This user does not want to receive anonymous questions.
(%{sign_in} or %{sign_up}) + non_anonymous_no_registration_html: | + This user does not want to receive anonymous questions.
+ (%{sign_in}) comment: show_reactions: title: "People who smiled this comment" diff --git a/config/locales/voc.en.yml b/config/locales/voc.en.yml index 0603cf05..54af769e 100644 --- a/config/locales/voc.en.yml +++ b/config/locales/voc.en.yml @@ -24,6 +24,7 @@ en: subscribe: "Subscribe" unsubscribe: "Unsubscribe" register: "Sign up" + register_now: "Register now" remove: "Remove" report: "Report" terms: "Terms of Service" diff --git a/config/routes.rb b/config/routes.rb index 52d1f53b..9790212f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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" diff --git a/lib/retrospring/config.rb b/lib/retrospring/config.rb new file mode 100644 index 00000000..9ed9dd74 --- /dev/null +++ b/lib/retrospring/config.rb @@ -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 diff --git a/lib/retrospring/version.rb b/lib/retrospring/version.rb index 950dca6a..accff044 100644 --- a/lib/retrospring/version.rb +++ b/lib/retrospring/version.rb @@ -17,9 +17,9 @@ module Retrospring def month = 8 - def day = 6 + def day = 11 - def patch = 0 + def patch = 1 def suffix = "" diff --git a/spec/controllers/about_controller_spec.rb b/spec/controllers/about_controller_spec.rb index f9fecf7b..79a30785 100644 --- a/spec/controllers/about_controller_spec.rb +++ b/spec/controllers/about_controller_spec.rb @@ -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 } diff --git a/spec/controllers/user/registration_controller_spec.rb b/spec/controllers/user/registration_controller_spec.rb index c31f5670..66484123 100644 --- a/spec/controllers/user/registration_controller_spec.rb +++ b/spec/controllers/user/registration_controller_spec.rb @@ -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 diff --git a/spec/views/about/index_advanced.html.haml_spec.rb b/spec/views/about/index_advanced.html.haml_spec.rb new file mode 100644 index 00000000..000e028d --- /dev/null +++ b/spec/views/about/index_advanced.html.haml_spec.rb @@ -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 diff --git a/spec/views/navigation/_guest.html.haml_spec.rb b/spec/views/navigation/_guest.html.haml_spec.rb new file mode 100644 index 00000000..8f60c87d --- /dev/null +++ b/spec/views/navigation/_guest.html.haml_spec.rb @@ -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