From 862cd54dc7c7223b0463ca8d0180acc5de2a3c5b Mon Sep 17 00:00:00 2001 From: Joshua Wehner Date: Thu, 25 May 2023 10:03:12 +0200 Subject: [PATCH] Refactoring onboarding (#19525) * Quick refactor onboardings controller(s) * Quick refactor onboardings controller(s), pt2 * Quick refactor onboardings controller(s), pt3 * Quick refactor onboardings controller(s), pt4 * Quick refactor onboardings controller(s), pt5 * Add test for checkboxes --- app/controllers/application_controller.rb | 2 +- app/controllers/onboardings_controller.rb | 98 ++++++++++ app/controllers/tags_controller.rb | 22 +-- .../users/notification_settings_controller.rb | 12 -- .../users/onboardings_controller.rb | 67 ------- .../components/EmailPreferencesForm.jsx | 2 +- .../onboarding/components/FollowTags.jsx | 2 +- .../onboarding/components/IntroSlide.jsx | 2 +- app/models/tag.rb | 3 + app/views/articles/index.html.erb | 2 +- .../onboardings/_task_card.html.erb | 0 .../{users => }/onboardings/show.html.erb | 0 app/views/tags/onboarding.json.jbuilder | 4 - config/routes.rb | 13 +- spec/requests/onboardings_spec.rb | 175 +++++++++++++++++- spec/requests/tags_spec.rb | 52 ------ .../user/user_notification_settings_spec.rb | 38 ---- spec/requests/users_onboarding_spec.rb | 75 -------- 18 files changed, 291 insertions(+), 278 deletions(-) create mode 100644 app/controllers/onboardings_controller.rb delete mode 100644 app/controllers/users/onboardings_controller.rb rename app/views/{users => }/onboardings/_task_card.html.erb (100%) rename app/views/{users => }/onboardings/show.html.erb (100%) delete mode 100644 app/views/tags/onboarding.json.jbuilder delete mode 100644 spec/requests/users_onboarding_spec.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ac36db1b1..b6bbbaceb 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -45,7 +45,7 @@ class ApplicationController < ActionController::Base private_constant :PUBLIC_CONTROLLERS CONTENT_CHANGE_PATHS = [ - "/tags/onboarding", # Needs to change when suggested_tags is edited. + "/onboarding/tags", # Needs to change when suggested_tags is edited. "/onboarding", # Page is cached at edge. "/", # Page is cached at edge. ].freeze diff --git a/app/controllers/onboardings_controller.rb b/app/controllers/onboardings_controller.rb new file mode 100644 index 000000000..8de9aa0c3 --- /dev/null +++ b/app/controllers/onboardings_controller.rb @@ -0,0 +1,98 @@ +class OnboardingsController < ApplicationController + before_action :authenticate_user! + before_action :check_suspended, only: %i[notifications] + before_action :set_cache_control_headers, only: %i[show tags] + before_action :set_no_cache_header, only: %i[update] + after_action :verify_authorized, only: %i[update checkbox] + + TAG_ONBOARDING_ATTRIBUTES = %i[id name taggings_count].freeze + ALLOWED_USER_PARAMS = %i[last_onboarding_page username].freeze + ALLOWED_CHECKBOX_PARAMS = %i[checked_code_of_conduct checked_terms_and_conditions].freeze + ALLOWED_NOTIFICATION_PARAMS = %i[email_newsletter email_digest_periodic].freeze + + def show + set_surrogate_key_header "onboarding-slideshow" + end + + def tags + @tags = Tags::SuggestedForOnboarding.call + .select(TAG_ONBOARDING_ATTRIBUTES) + + render json: @tags + set_surrogate_key_header Tag.table_key, @tags.map(&:record_key) + end + + def update + authorize User, :onboarding_update? + + user_params = {} + + if params[:user] + if unset_username? + return render json: { errors: I18n.t("users_controller.username_blank") }, status: :unprocessable_entity + end + + sanitize_user_params + user_params = params[:user].permit(ALLOWED_USER_PARAMS) + end + + update_result = Users::Update.call(current_user, user: user_params, profile: profile_params) + + if update_result.success? + render json: {}, status: :ok + else + render json: { errors: update_result.errors_as_sentence }, status: :unprocessable_entity + end + end + + def checkbox + authorize User, :onboarding_checkbox_update? + + if params[:user] + current_user.assign_attributes(params[:user].permit(ALLOWED_CHECKBOX_PARAMS)) + end + + current_user.saw_onboarding = true + + if current_user.save + render json: {}, status: :ok + else + render json: { errors: errors }, status: :unprocessable_entity + end + end + + def notifications + authorize User, :onboarding_notifications_checkbox_update? + + if params[:notifications] + current_user.notification_setting.assign_attributes(params[:notifications].permit(ALLOWED_NOTIFICATION_PARAMS)) + end + + current_user.saw_onboarding = true + + success = current_user.notification_setting.save + notifications_updated_response(success, current_user.notification_setting.errors_as_sentence) + end + + private + + def unset_username? + params[:user].key?(:username) && params[:user][:username].blank? + end + + def sanitize_user_params + params[:user].compact_blank! + end + + def profile_params + params[:profile]&.permit(Profile.static_fields + Profile.attributes) + end + + def notifications_updated_response(success, errors) + status = success ? 200 : 422 + + respond_to do |format| + format.json { render json: { errors: errors }, status: status } + end + end +end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index bbb7a741c..e298edb33 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -1,10 +1,8 @@ class TagsController < ApplicationController - before_action :set_cache_control_headers, only: %i[index onboarding] + before_action :set_cache_control_headers, only: %i[index] before_action :authenticate_user!, only: %i[edit update] after_action :verify_authorized - ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex short_summary badge_id].freeze - ONBOARDING_API_ATTRIBUTES = %i[id name taggings_count].freeze INDEX_API_ATTRIBUTES = %i[name rules_html short_summary bg_color_hex badge_id].freeze TAGS_ALLOWED_PARAMS = %i[ @@ -24,7 +22,7 @@ class TagsController < ApplicationController def bulk skip_authorization - @tags = Tag.includes(:badge).select(ATTRIBUTES_FOR_SERIALIZATION) + @tags = Tag.includes(:badge).select_attributes_for_serialization page = params[:page] per_page = (params[:per_page] || 10).to_i @@ -36,8 +34,8 @@ class TagsController < ApplicationController @tags = @tags.where(name: params[:tag_names]) end - @tags = @tags.order(taggings_count: :desc).page(page).per(num) - render json: @tags, only: ATTRIBUTES_FOR_SERIALIZATION, include: [badge: { only: [:badge_image] }] + @tags = @tags.order(taggings_count: :desc).select_attributes_for_serialization.page(page).per(num) + render json: @tags, only: Tag::ATTRIBUTES_FOR_SERIALIZATION, include: [badge: { only: [:badge_image] }] end def edit @@ -63,16 +61,6 @@ class TagsController < ApplicationController redirect_to edit_admin_tag_path(tag.id) end - def onboarding - skip_authorization - - @tags = Tags::SuggestedForOnboarding.call - .select(ONBOARDING_API_ATTRIBUTES) - - render json: @tags - set_surrogate_key_header Tag.table_key, @tags.map(&:record_key) - end - def suggest skip_authorization tags = Tag.supported.order(hotness_score: :desc).limit(100).select(INDEX_API_ATTRIBUTES) @@ -95,6 +83,4 @@ class TagsController < ApplicationController convert_empty_string_to_nil params.require(:tag).permit(TAGS_ALLOWED_PARAMS) end - - private_constant :ATTRIBUTES_FOR_SERIALIZATION end diff --git a/app/controllers/users/notification_settings_controller.rb b/app/controllers/users/notification_settings_controller.rb index 54f594ec5..aa468d58c 100644 --- a/app/controllers/users/notification_settings_controller.rb +++ b/app/controllers/users/notification_settings_controller.rb @@ -34,18 +34,6 @@ module Users redirect_to user_settings_path(:notifications) end - def onboarding_notifications_checkbox_update - authorize User - - if params[:notifications] - current_user.notification_setting.assign_attributes(params[:notifications].permit(ONBOARDING_ALLOWED_PARAMS)) - end - - current_user.saw_onboarding = true - success = current_user.notification_setting.save - render_update_response(success, current_user.notification_setting.errors_as_sentence) - end - private def render_update_response(success, errors = nil) diff --git a/app/controllers/users/onboardings_controller.rb b/app/controllers/users/onboardings_controller.rb deleted file mode 100644 index 9f4fc7d0f..000000000 --- a/app/controllers/users/onboardings_controller.rb +++ /dev/null @@ -1,67 +0,0 @@ -module Users - class OnboardingsController < ApplicationController - before_action :authenticate_user! - before_action :set_cache_control_headers, only: [:show] - before_action :set_no_cache_header, only: %i[update onboarding_checkbox_update] - after_action :verify_authorized, except: [:show] - - ALLOWED_USER_PARAMS = %i[last_onboarding_page username].freeze - ALLOWED_CHECKBOX_PARAMS = %i[checked_code_of_conduct checked_terms_and_conditions].freeze - - def show - set_surrogate_key_header "onboarding-slideshow" - end - - def update - authorize User, :onboarding_update? - - user_params = {} - - if params[:user] - if unset_username? - return render json: { errors: I18n.t("users_controller.username_blank") }, status: :unprocessable_entity - end - - sanitize_user_params - user_params = params[:user].permit(ALLOWED_USER_PARAMS) - end - - update_result = Users::Update.call(current_user, user: user_params, profile: profile_params) - - if update_result.success? - render json: {}, status: :ok - else - render json: { errors: update_result.errors_as_sentence }, status: :unprocessable_entity - end - end - - def onboarding_checkbox_update - if params[:user] - current_user.assign_attributes(params[:user].permit(ALLOWED_CHECKBOX_PARAMS)) - end - - current_user.saw_onboarding = true - authorize User - - if current_user.save - render json: {}, status: :ok - else - render json: { errors: errors }, status: :unprocessable_entity - end - end - - private - - def unset_username? - params[:user].key?(:username) && params[:user][:username].blank? - end - - def sanitize_user_params - params[:user].compact_blank! - end - - def profile_params - params[:profile]&.permit(Profile.static_fields + Profile.attributes) - end - end -end diff --git a/app/javascript/onboarding/components/EmailPreferencesForm.jsx b/app/javascript/onboarding/components/EmailPreferencesForm.jsx index 5e42ff4d4..eeaf68c19 100644 --- a/app/javascript/onboarding/components/EmailPreferencesForm.jsx +++ b/app/javascript/onboarding/components/EmailPreferencesForm.jsx @@ -24,7 +24,7 @@ export class EmailPreferencesForm extends Component { onSubmit() { const csrfToken = getContentOfToken('csrf-token'); - fetch('/onboarding_notifications_checkbox_update', { + fetch('/onboarding/notifications', { method: 'PATCH', headers: { 'X-CSRF-Token': csrfToken, diff --git a/app/javascript/onboarding/components/FollowTags.jsx b/app/javascript/onboarding/components/FollowTags.jsx index 6a5b854be..7984a6252 100644 --- a/app/javascript/onboarding/components/FollowTags.jsx +++ b/app/javascript/onboarding/components/FollowTags.jsx @@ -18,7 +18,7 @@ export class FollowTags extends Component { } componentDidMount() { - fetch('/tags/onboarding') + fetch('/onboarding/tags') .then((response) => response.json()) .then((data) => { this.setState({ allTags: data }); diff --git a/app/javascript/onboarding/components/IntroSlide.jsx b/app/javascript/onboarding/components/IntroSlide.jsx index 258d9b8f7..41d815a05 100644 --- a/app/javascript/onboarding/components/IntroSlide.jsx +++ b/app/javascript/onboarding/components/IntroSlide.jsx @@ -28,7 +28,7 @@ export class IntroSlide extends Component { const { next } = this.props; const csrfToken = getContentOfToken('csrf-token'); - fetch('/onboarding_checkbox_update', { + fetch('/onboarding/checkbox', { method: 'PATCH', headers: { 'X-CSRF-Token': csrfToken, diff --git a/app/models/tag.rb b/app/models/tag.rb index ce97fa6cf..abc3553b2 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -33,6 +33,7 @@ class Tag < ActsAsTaggableOn::Tag include StringAttributeCleaner.nullify_blanks_for(:alias_for) ALLOWED_CATEGORIES = %w[uncategorized language library tool site_mechanic location subcommunity].freeze HEX_COLOR_REGEXP = /\A#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})\z/ + ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex short_summary badge_id].freeze belongs_to :badge, optional: true @@ -75,6 +76,8 @@ class Tag < ActsAsTaggableOn::Tag # this scope we have a name. scope :direct, -> { where(alias_for: [nil, ""]) } + scope :select_attributes_for_serialization, -> { select(ATTRIBUTES_FOR_SERIALIZATION) } + pg_search_scope :search_by_name, against: :name, using: { tsearch: { prefix: true } } diff --git a/app/views/articles/index.html.erb b/app/views/articles/index.html.erb index a1d992a53..4919097dd 100644 --- a/app/views/articles/index.html.erb +++ b/app/views/articles/index.html.erb @@ -39,7 +39,7 @@ <%# BEGIN Feed menu bar %>
- <%= render(partial: "users/onboardings/task_card") if user_signed_in? %> + <%= render(partial: "onboardings/task_card") if user_signed_in? %>

<%= t("views.stories.heading") %>

diff --git a/app/views/users/onboardings/_task_card.html.erb b/app/views/onboardings/_task_card.html.erb similarity index 100% rename from app/views/users/onboardings/_task_card.html.erb rename to app/views/onboardings/_task_card.html.erb diff --git a/app/views/users/onboardings/show.html.erb b/app/views/onboardings/show.html.erb similarity index 100% rename from app/views/users/onboardings/show.html.erb rename to app/views/onboardings/show.html.erb diff --git a/app/views/tags/onboarding.json.jbuilder b/app/views/tags/onboarding.json.jbuilder deleted file mode 100644 index c6a960e2f..000000000 --- a/app/views/tags/onboarding.json.jbuilder +++ /dev/null @@ -1,4 +0,0 @@ -json.array! @tags.each do |tag| - json.extract!(tag, :id, :name, :bg_color_hex, :text_color_hex) - json.following nil -end diff --git a/config/routes.rb b/config/routes.rb index c712a81b6..110d45e87 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -114,7 +114,6 @@ Rails.application.routes.draw do resources :notifications, only: [:index] resources :tags, only: [:index] do collection do - get "/onboarding", to: "tags#onboarding" get "/suggest", to: "tags#suggest", defaults: { format: :json } get "/bulk", to: "tags#bulk", defaults: { format: :json } end @@ -150,6 +149,7 @@ Rails.application.routes.draw do get "/subscribed", action: "subscribed" end end + namespace :followings, defaults: { format: :json } do get :users get :tags @@ -157,9 +157,12 @@ Rails.application.routes.draw do get :podcasts end - scope module: "users" do - resource :onboarding, only: %i[show update] - patch "/onboarding_checkbox_update", to: "onboardings#onboarding_checkbox_update" + resource :onboarding, only: %i[show update] do + member do + patch :checkbox + patch :notifications + get :tags + end end resources :profiles, only: %i[update] @@ -178,8 +181,6 @@ Rails.application.routes.draw do get "/notifications/:filter/:org_id", to: "notifications#index", as: :notifications_filter_org get "/notification_subscriptions/:notifiable_type/:notifiable_id", to: "notification_subscriptions#show" post "/notification_subscriptions/:notifiable_type/:notifiable_id", to: "notification_subscriptions#upsert" - patch "/onboarding_notifications_checkbox_update", - to: "users/notification_settings#onboarding_notifications_checkbox_update" get "email_subscriptions/unsubscribe" get "/internal", to: redirect("/admin") diff --git a/spec/requests/onboardings_spec.rb b/spec/requests/onboardings_spec.rb index 099c27551..59bced252 100644 --- a/spec/requests/onboardings_spec.rb +++ b/spec/requests/onboardings_spec.rb @@ -1,7 +1,12 @@ require "rails_helper" RSpec.describe "Onboardings" do - let(:user) { create(:user, saw_onboarding: false) } + let(:user) do + create(:user, + saw_onboarding: false, + _skip_creating_profile: true, + profile: create(:profile, location: "Llama Town")) + end describe "GET /onboarding" do it "redirects user if unauthenticated" do @@ -34,4 +39,172 @@ RSpec.describe "Onboardings" do expect(response.body).to include(Settings::General.onboarding_background_image) end end + + describe "GET /onboarding/tags" do + let(:headers) do + { + Accept: "application/json", + "Content-Type": "application/json" + } + end + + before do + sign_in user + allow(Settings::General).to receive(:suggested_tags).and_return(%w[beginners javascript career]) + end + + it "returns tags" do + create(:tag, name: Settings::General.suggested_tags.first) + + get tags_onboarding_path, headers: headers + + expect(response.parsed_body.size).to eq(1) + end + + it "returns tags with the correct json representation" do + tag = create(:tag, name: Settings::General.suggested_tags.first) + + get tags_onboarding_path, headers: headers + + response_tag = response.parsed_body.first + expect(response_tag.keys).to \ + match_array(OnboardingsController::TAG_ONBOARDING_ATTRIBUTES.map(&:to_s)) + expect(response_tag["id"]).to eq(tag.id) + expect(response_tag["name"]).to eq(tag.name) + expect(response_tag["taggings_count"]).to eq(tag.taggings_count) + end + + it "returns suggested and supported tags" do + not_suggested_but_supported = create(:tag, name: "notsuggestedbutsupported", supported: true, suggested: false) + neither_suggested_nor_supported = create(:tag, name: "definitelynotasuggestedtag", supported: false) + + get tags_onboarding_path, headers: headers + + expect(response.parsed_body.filter { |t| t["name"] == not_suggested_but_supported.name }).not_to be_empty + expect(response.parsed_body.filter { |t| t["name"] == neither_suggested_nor_supported.name }).to be_empty + end + + it "sets the correct edge caching surrogate key for all tags" do + tag = create(:tag, name: Settings::General.suggested_tags.first) + + get tags_onboarding_path, headers: headers + + expected_key = ["tags", tag.record_key].to_set + expect(response.headers["surrogate-key"].split.to_set).to eq(expected_key) + end + end + + describe "PATCH /onboarding" do + context "when signed in" do + before { sign_in user } + + it "updates the user's last_onboarding_page attribute" do + params = { user: { last_onboarding_page: "v2: personal info form", username: "test" } } + expect do + patch "/onboarding", params: params + end.to change(user, :last_onboarding_page) + end + + it "updates the user's username attribute" do + params = { user: { username: "WilhuffTarkin" } } + expect do + patch "/onboarding", params: params + end.to change(user, :username).to("wilhufftarkin") + end + + it "returns a 422 error if the username is blank" do + params = { user: { username: "" } } + patch "/onboarding", params: params + expect(response).to have_http_status(:unprocessable_entity) + end + + it "updates the user's profile" do + params = { profile: { location: "Galactic Empire" } } + expect do + patch "/onboarding", params: params + end.to change(user.profile, :location).to("Galactic Empire") + end + + it "does not update the user's last_onboarding_page if it is empty" do + params = { user: { last_onboarding_page: "" } } + expect do + patch "/onboarding", params: params + end.not_to change(user, :last_onboarding_page) + end + end + + context "when signed out" do + it "returns a not found error if user is not signed in" do + patch "/onboarding.json", params: {} + expect(response.parsed_body["error"]).to include("Please sign in") + end + end + end + + describe "PATCH /onboarding/checkbox" do + context "when signed in" do + before { sign_in user } + + it "updates saw_onboarding boolean" do + patch "/onboarding/checkbox.json", params: {} + expect(user.saw_onboarding).to be(true) + end + + it "updates checked_code_of_conduct and checked_terms_and_conditions" do + patch "/onboarding/checkbox.json", + params: { + checked_code_of_conduct: "1", + checked_terms_and_conditions: "1" + } + + expect(user.checked_code_of_conduct).to be(true) + expect(user.checked_terms_and_conditions).to be(true) + end + end + + context "when signed out" do + it "returns a not found error if user is not signed in" do + patch "/onboarding/checkbox.json", params: {} + expect(response.parsed_body["error"]).to include("Please sign in") + end + end + end + + describe "PATCH /onboarding/notifications" do + before { sign_in user } + + it "updates onboarding checkbox" do + user.update_column(:saw_onboarding, false) + + expect do + patch notifications_onboarding_path(format: :json), + params: { notifications: { tab: "notifications", email_newsletter: 1 } } + end.to change { user.notification_setting.reload.email_newsletter }.from(false).to(true) + expect(user.saw_onboarding).to be(true) + end + + it "can toggle email_newsletter" do + expect do + patch notifications_onboarding_path(format: :json), + params: { notifications: { tab: "notifications", email_newsletter: 1 } } + end.to change { user.notification_setting.reload.email_newsletter }.from(false).to(true) + + expect do + patch notifications_onboarding_path(format: :json), + params: { notifications: { tab: "notifications", email_newsletter: 0 } } + end.to change { user.notification_setting.reload.email_newsletter }.from(true).to(false) + end + + it "can toggle email_digest_periodic" do + expect do + patch notifications_onboarding_path(format: :json), + params: { notifications: { tab: "notifications", email_digest_periodic: 1 } } + end.to change { user.notification_setting.reload.email_digest_periodic }.from(false).to(true) + + expect do + patch notifications_onboarding_path(format: :json), + params: { notifications: { tab: "notifications", email_digest_periodic: 0 } } + end.to change { user.notification_setting.reload.email_digest_periodic }.from(true).to(false) + end + end end diff --git a/spec/requests/tags_spec.rb b/spec/requests/tags_spec.rb index df0cf66be..7bbc7d4ec 100644 --- a/spec/requests/tags_spec.rb +++ b/spec/requests/tags_spec.rb @@ -187,56 +187,4 @@ RSpec.describe "Tags", proper_status: true do end end end - - describe "GET /tags/onboarding" do - let(:headers) do - { - Accept: "application/json", - "Content-Type": "application/json" - } - end - - before do - allow(Settings::General).to receive(:suggested_tags).and_return(%w[beginners javascript career]) - end - - it "returns tags" do - create(:tag, name: Settings::General.suggested_tags.first) - - get onboarding_tags_path, headers: headers - - expect(response.parsed_body.size).to eq(1) - end - - it "returns tags with the correct json representation" do - tag = create(:tag, name: Settings::General.suggested_tags.first) - - get onboarding_tags_path, headers: headers - - response_tag = response.parsed_body.first - expect(response_tag.keys).to match_array(%w[id name taggings_count]) - expect(response_tag["id"]).to eq(tag.id) - expect(response_tag["name"]).to eq(tag.name) - expect(response_tag["taggings_count"]).to eq(tag.taggings_count) - end - - it "returns suggested and supported tags" do - not_suggested_but_supported = create(:tag, name: "notsuggestedbutsupported", supported: true, suggested: false) - neither_suggested_nor_supported = create(:tag, name: "definitelynotasuggestedtag", supported: false) - - get onboarding_tags_path, headers: headers - - expect(response.parsed_body.filter { |t| t["name"] == not_suggested_but_supported.name }).not_to be_empty - expect(response.parsed_body.filter { |t| t["name"] == neither_suggested_nor_supported.name }).to be_empty - end - - it "sets the correct edge caching surrogate key for all tags" do - tag = create(:tag, name: Settings::General.suggested_tags.first) - - get onboarding_tags_path, headers: headers - - expected_key = ["tags", tag.record_key].to_set - expect(response.headers["surrogate-key"].split.to_set).to eq(expected_key) - end - end end diff --git a/spec/requests/user/user_notification_settings_spec.rb b/spec/requests/user/user_notification_settings_spec.rb index bb8b764d1..150baf255 100644 --- a/spec/requests/user/user_notification_settings_spec.rb +++ b/spec/requests/user/user_notification_settings_spec.rb @@ -37,42 +37,4 @@ RSpec.describe "UserNotificationSettings" do expect(user.notification_setting.reload.subscribed_to_welcome_notifications?).to be(true) end end - - describe "PATCH /onboarding_notifications_checkbox_update" do - before { sign_in user } - - it "updates onboarding checkbox" do - user.update_column(:saw_onboarding, false) - - expect do - patch onboarding_notifications_checkbox_update_path(format: :json), - params: { notifications: { tab: "notifications", email_newsletter: 1 } } - end.to change { user.notification_setting.reload.email_newsletter }.from(false).to(true) - expect(user.saw_onboarding).to be(true) - end - - it "can toggle email_newsletter" do - expect do - patch onboarding_notifications_checkbox_update_path(format: :json), - params: { notifications: { tab: "notifications", email_newsletter: 1 } } - end.to change { user.notification_setting.reload.email_newsletter }.from(false).to(true) - - expect do - patch onboarding_notifications_checkbox_update_path(format: :json), - params: { notifications: { tab: "notifications", email_newsletter: 0 } } - end.to change { user.notification_setting.reload.email_newsletter }.from(true).to(false) - end - - it "can toggle email_digest_periodic" do - expect do - patch onboarding_notifications_checkbox_update_path(format: :json), - params: { notifications: { tab: "notifications", email_digest_periodic: 1 } } - end.to change { user.notification_setting.reload.email_digest_periodic }.from(false).to(true) - - expect do - patch onboarding_notifications_checkbox_update_path(format: :json), - params: { notifications: { tab: "notifications", email_digest_periodic: 0 } } - end.to change { user.notification_setting.reload.email_digest_periodic }.from(true).to(false) - end - end end diff --git a/spec/requests/users_onboarding_spec.rb b/spec/requests/users_onboarding_spec.rb deleted file mode 100644 index 3b53fa096..000000000 --- a/spec/requests/users_onboarding_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -require "rails_helper" - -RSpec.describe "UsersOnboarding" do - let!(:user) do - create(:user, - saw_onboarding: false, - _skip_creating_profile: true, - profile: create(:profile, location: "Llama Town")) - end - - describe "PATCH /onboarding" do - context "when signed in" do - before { sign_in user } - - it "updates the user's last_onboarding_page attribute" do - params = { user: { last_onboarding_page: "v2: personal info form", username: "test" } } - expect do - patch "/onboarding", params: params - end.to change(user, :last_onboarding_page) - end - - it "updates the user's username attribute" do - params = { user: { username: "WilhuffTarkin" } } - expect do - patch "/onboarding", params: params - end.to change(user, :username).to("wilhufftarkin") - end - - it "returns a 422 error if the username is blank" do - params = { user: { username: "" } } - patch "/onboarding", params: params - expect(response).to have_http_status(:unprocessable_entity) - end - - it "updates the user's profile" do - params = { profile: { location: "Galactic Empire" } } - expect do - patch "/onboarding", params: params - end.to change(user.profile, :location).to("Galactic Empire") - end - - it "does not update the user's last_onboarding_page if it is empty" do - params = { user: { last_onboarding_page: "" } } - expect do - patch "/onboarding", params: params - end.not_to change(user, :last_onboarding_page) - end - end - - context "when signed out" do - it "returns a not found error if user is not signed in" do - patch "/onboarding.json", params: {} - expect(response.parsed_body["error"]).to include("Please sign in") - end - end - end - - describe "PATCH /onboarding_checkbox_update" do - context "when signed in" do - before { sign_in user } - - it "updates saw_onboarding boolean" do - patch "/onboarding_checkbox_update.json", params: {} - expect(user.saw_onboarding).to be(true) - end - end - - context "when signed out" do - it "returns a not found error if user is not signed in" do - patch "/onboarding_checkbox_update.json", params: {} - expect(response.parsed_body["error"]).to include("Please sign in") - end - end - end -end