mirror of
https://github.com/discourse/discourse.git
synced 2024-12-12 03:23:43 +08:00
e0ba35350e
With this change, plugins can create custom unsubscribe keys, extend the unsubscribe view with custom preferences, and decide how they are updated.
293 lines
10 KiB
Ruby
293 lines
10 KiB
Ruby
# frozen_string_literal: true
|
||
|
||
describe EmailController do
|
||
fab!(:user) { Fabricate(:user) }
|
||
|
||
describe '#perform_unsubscribe' do
|
||
it 'raises not found on invalid key' do
|
||
post "/email/unsubscribe/123.json"
|
||
expect(response.status).to eq(404)
|
||
end
|
||
|
||
describe 'unsubscribe from all emails' do
|
||
let(:key) { UnsubscribeKey.create_key_for(user, UnsubscribeKey::ALL_TYPE) }
|
||
|
||
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],
|
||
mailing_list_mode: true)
|
||
|
||
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])
|
||
expect(user.user_option.mailing_list_mode).to eq(false)
|
||
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)
|
||
expect(user.user_option.reload.mailing_list_mode).to eq(false)
|
||
end
|
||
end
|
||
|
||
describe 'unsubscribe from digest' do
|
||
let(:key) { UnsubscribeKey.create_key_for(user, UnsubscribeKey::DIGEST_TYPE) }
|
||
|
||
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)
|
||
expect(user.user_option.reload.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
|
||
end
|
||
|
||
describe 'unsubscribe from a topic' do
|
||
fab!(:a_post) { Fabricate(:post) }
|
||
let(:key) { UnsubscribeKey.create_key_for(user, UnsubscribeKey::TOPIC_TYPE, post: a_post) }
|
||
|
||
it 'can unwatch topic' do
|
||
TopicUser.change(user.id, a_post.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(a_post.topic, user).notification_level).to eq(TopicUser.notification_levels[:tracking])
|
||
end
|
||
|
||
it 'can mute topic' do
|
||
TopicUser.change(user.id, a_post.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(a_post.topic, user).notification_level).to eq(TopicUser.notification_levels[:muted])
|
||
end
|
||
|
||
it 'can unwatch category' do
|
||
cu = CategoryUser.create!(user_id: user.id,
|
||
category_id: a_post.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
|
||
cu = CategoryUser.create!(user_id: user.id,
|
||
category_id: a_post.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
|
||
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
|
||
fab!(:topic) { Fabricate(:topic) }
|
||
|
||
it 'should return the right response' do
|
||
key = SecureRandom.hex
|
||
Discourse.cache.write(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
|
||
fab!(:private_topic) { Fabricate(:private_message_topic) }
|
||
|
||
it 'should return the right response' do
|
||
key = SecureRandom.hex
|
||
Discourse.cache.write(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 '#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
|
||
|
||
fab!(:user) { Fabricate(:user) }
|
||
let(:unsubscribe_key) { UnsubscribeKey.create_key_for(user, key_type, post: post) }
|
||
|
||
context 'Unsubscribe from digest' do
|
||
let(:key_type) { UnsubscribeKey::DIGEST_TYPE }
|
||
let(:post) { nil }
|
||
|
||
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 'displays correct label when email_digests is set to false' do
|
||
user.user_option.update!(email_digests: false, digest_after_minutes: 10080)
|
||
|
||
navigate_to_unsubscribe
|
||
|
||
expect(body).to include("You are not receiving summary emails")
|
||
expect(body).to include("Don’t send me any mail from Discourse")
|
||
end
|
||
|
||
it 'hides unsubscribe from all checkbox when user already unsubscribed' do
|
||
user.user_option.update!(email_digests: false, mailing_list_mode: false, email_level: 2, email_messages_level: 2)
|
||
|
||
navigate_to_unsubscribe
|
||
|
||
expect(body).to include("You are not receiving summary emails")
|
||
expect(body).not_to include("Don't send me any mail from Discourse")
|
||
end
|
||
|
||
it 'correctly handles mailing list mode' do
|
||
SiteSetting.disable_mailing_list_mode = false
|
||
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::HTML5::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::HTML5::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::HTML5::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
|
||
fab!(:post) { Fabricate(:post) }
|
||
let(:user) { post.user }
|
||
let(:key_type) { UnsubscribeKey::TOPIC_TYPE }
|
||
|
||
it 'correctly handles watched categories' do
|
||
cu = create_category_user(:watching)
|
||
|
||
navigate_to_unsubscribe
|
||
expect(response.body).to include("unwatch_category")
|
||
doc = Nokogiri::HTML5::fragment(response.body)
|
||
expect(doc.css('a.badge-wrapper[href="/c/uncategorized/1"]').size).to eq(1)
|
||
|
||
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
|