discourse/spec/requests/email_controller_spec.rb
Sam Saffron 4ea21fa2d0 DEV: use #frozen_string_literal: true on all spec
This change both speeds up specs (less strings to allocate) and helps catch
cases where methods in Discourse are mutating inputs.

Overall we will be migrating everything to use #frozen_string_literal: true
it will take a while, but this is the first and safest move in this direction
2019-04-30 10:27:42 +10:00

304 lines
9.5 KiB
Ruby

# frozen_string_literal: true
require 'rails_helper'
RSpec.describe EmailController do
let(:user) { Fabricate(:user) }
let(:topic) { Fabricate(:topic) }
let(:private_topic) { Fabricate(:private_message_topic) }
context '.perform unsubscribe' do
it 'raises not found on invalid key' do
post "/email/unsubscribe/123.json"
expect(response.status).to eq(404)
end
let(:user) { Fabricate(:user) }
let(:key) { UnsubscribeKey.create_key_for(user, "all") }
it 'can fully unsubscribe' do
user.user_option.update_columns(email_digests: true,
email_level: UserOption.email_level_types[:never],
email_messages_level: UserOption.email_level_types[:never])
post "/email/unsubscribe/#{key}.json",
params: { unsubscribe_all: "1" }
expect(response.status).to eq(302)
get response.redirect_url
# cause it worked ... yay
expect(body).to include(user.email)
user.user_option.reload
expect(user.user_option.email_digests).to eq(false)
expect(user.user_option.email_level).to eq(UserOption.email_level_types[:never])
expect(user.user_option.email_messages_level).to eq(UserOption.email_level_types[:never])
end
it 'can disable mailing list' do
user.user_option.update_columns(mailing_list_mode: true)
post "/email/unsubscribe/#{key}.json",
params: { disable_mailing_list: "1" }
expect(response.status).to eq(302)
user.user_option.reload
expect(user.user_option.mailing_list_mode).to eq(false)
end
it 'Can change digest frequency' do
weekly_interval_minutes = 10080
user.user_option.update_columns(email_digests: true, digest_after_minutes: 0)
post "/email/unsubscribe/#{key}.json",
params: { digest_after_minutes: weekly_interval_minutes.to_s }
expect(response.status).to eq(302)
user.user_option.reload
expect(user.user_option.digest_after_minutes).to eq(weekly_interval_minutes)
end
it 'Can disable email digests setting frequency to zero' do
user.user_option.update_columns(email_digests: true, digest_after_minutes: 10080)
post "/email/unsubscribe/#{key}.json",
params: { digest_after_minutes: '0' }
expect(response.status).to eq(302)
user.user_option.reload
expect(user.user_option.digest_after_minutes).to be_zero
expect(user.user_option.email_digests).to eq(false)
end
it 'can unwatch topic' do
p = Fabricate(:post)
key = UnsubscribeKey.create_key_for(p.user, p)
TopicUser.change(p.user_id, p.topic_id, notification_level: TopicUser.notification_levels[:watching])
post "/email/unsubscribe/#{key}.json",
params: { unwatch_topic: "1" }
expect(response.status).to eq(302)
expect(TopicUser.get(p.topic, p.user).notification_level).to eq(TopicUser.notification_levels[:tracking])
end
it 'can mute topic' do
p = Fabricate(:post)
key = UnsubscribeKey.create_key_for(p.user, p)
TopicUser.change(p.user_id, p.topic_id, notification_level: TopicUser.notification_levels[:watching])
post "/email/unsubscribe/#{key}.json",
params: { mute_topic: "1" }
expect(response.status).to eq(302)
expect(TopicUser.get(p.topic, p.user).notification_level).to eq(TopicUser.notification_levels[:muted])
end
it 'can unwatch category' do
p = Fabricate(:post)
key = UnsubscribeKey.create_key_for(p.user, p)
cu = CategoryUser.create!(user_id: p.user.id,
category_id: p.topic.category_id,
notification_level: CategoryUser.notification_levels[:watching])
post "/email/unsubscribe/#{key}.json",
params: { unwatch_category: "1" }
expect(response.status).to eq(302)
expect(CategoryUser.find_by(id: cu.id)).to eq(nil)
end
it 'can unwatch first post from category' do
p = Fabricate(:post)
key = UnsubscribeKey.create_key_for(p.user, p)
cu = CategoryUser.create!(user_id: p.user.id,
category_id: p.topic.category_id,
notification_level: CategoryUser.notification_levels[:watching_first_post])
post "/email/unsubscribe/#{key}.json",
params: { unwatch_category: "1" }
expect(response.status).to eq(302)
expect(CategoryUser.find_by(id: cu.id)).to eq(nil)
end
end
describe '#unsubscribed' do
describe 'when email is invalid' do
it 'should return the right response' do
get '/email/unsubscribed', params: { email: 'somerandomstring' }
expect(response.status).to eq(404)
end
end
describe 'when topic is public' do
it 'should return the right response' do
key = SecureRandom.hex
$redis.set(key, user.email)
get '/email/unsubscribed', params: { key: key, topic_id: topic.id }
expect(response.status).to eq(200)
expect(response.body).to include(topic.title)
end
end
describe 'when topic is private' do
it 'should return the right response' do
key = SecureRandom.hex
$redis.set(key, user.email)
get '/email/unsubscribed', params: { key: key, topic_id: private_topic.id }
expect(response.status).to eq(200)
expect(response.body).to_not include(private_topic.title)
end
end
end
context '#preferences_redirect' do
it 'requires you to be logged in' do
get "/email_preferences.json"
expect(response.status).to eq(403)
end
context 'when logged in' do
let!(:user) { sign_in(Fabricate(:user)) }
it 'redirects to your user preferences' do
get "/email_preferences.json"
expect(response).to redirect_to("/u/#{user.username}/preferences")
end
end
end
context '#unsubscribe' do
it 'displays not found if key is not found' do
navigate_to_unsubscribe(SecureRandom.hex)
expect(response.body).to include(CGI.escapeHTML(I18n.t("unsubscribe.not_found_description")))
end
let(:user) { Fabricate(:user) }
let(:unsubscribe_key) { UnsubscribeKey.create_key_for(user, key_type) }
context 'Unsubscribe from digest' do
let(:key_type) { 'digest' }
it 'displays log out button if wrong user logged in' do
sign_in(Fabricate(:admin))
navigate_to_unsubscribe
expect(response.body).to include(I18n.t("unsubscribe.log_out"))
expect(response.body).to include(I18n.t("unsubscribe.different_user_description"))
end
it 'correctly handles mailing list mode' do
user.user_option.update_columns(mailing_list_mode: true)
navigate_to_unsubscribe
expect(response.body).to include(I18n.t("unsubscribe.mailing_list_mode"))
SiteSetting.disable_mailing_list_mode = true
navigate_to_unsubscribe
expect(response.body).not_to include(I18n.t("unsubscribe.mailing_list_mode"))
user.user_option.update_columns(mailing_list_mode: false)
SiteSetting.disable_mailing_list_mode = false
navigate_to_unsubscribe
expect(response.body).not_to include(I18n.t("unsubscribe.mailing_list_mode"))
end
it 'Lets you select the digest frequency ranging from never to half a year' do
selected_digest_frequency = 0
slow_digest_frequencies = ['weekly', 'every month', 'every six months', 'never']
navigate_to_unsubscribe
source = Nokogiri::HTML::fragment(response.body)
expect(source.css(".combobox option").map(&:inner_text)).to eq(slow_digest_frequencies)
end
it 'Selects the next slowest frequency by default' do
every_month_freq = 43200
six_months_freq = 259200
user.user_option.update_columns(digest_after_minutes: every_month_freq)
navigate_to_unsubscribe
source = Nokogiri::HTML::fragment(response.body)
expect(source.css(".combobox option[selected='selected']")[0]['value']).to eq(six_months_freq.to_s)
end
it 'Uses never as the selected frequency if current one is six months' do
never_frequency = 0
six_months_freq = 259200
user.user_option.update_columns(digest_after_minutes: six_months_freq)
navigate_to_unsubscribe
source = Nokogiri::HTML::fragment(response.body)
expect(source.css(".combobox option[selected='selected']")[0]['value']).to eq(never_frequency.to_s)
end
end
context 'Unsubscribe from a post' do
let(:post) { Fabricate(:post) }
let(:user) { post.user }
let(:key_type) { post }
it 'correctly handles watched categories' do
cu = create_category_user(:watching)
navigate_to_unsubscribe
expect(response.body).to include("unwatch_category")
cu.destroy!
navigate_to_unsubscribe
expect(response.body).not_to include("unwatch_category")
end
it 'correctly handles watched first post categories' do
cu = create_category_user(:watching_first_post)
navigate_to_unsubscribe
expect(response.body).to include("unwatch_category")
cu.destroy!
navigate_to_unsubscribe
expect(response.body).not_to include("unwatch_category")
end
def create_category_user(notification_level)
CategoryUser.create!(
user_id: user.id,
category_id: post.topic.category_id,
notification_level: CategoryUser.notification_levels[notification_level]
)
end
end
def navigate_to_unsubscribe(key = unsubscribe_key)
get "/email/unsubscribe/#{key}"
end
end
end