Mailchimp resubscribe (#6256)

* Re-subscribe user to newsletter by setting MC status to pending

* Add guard clause and new spec

* Make trait name more explicit

* Fix guard clause and spec
This commit is contained in:
Michael Kohl 2020-02-28 03:48:38 +07:00 committed by GitHub
parent df98591d6d
commit 32e30c8844
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 5 deletions

View file

@ -39,6 +39,24 @@ class MailchimpBot
}
},
)
success = true
rescue Gibbon::MailChimpError => e
# If user was previously subscribed, set their status to "pending"
return resubscribe_to_newsletter if previously_subcribed?(e)
report_error(e)
end
success
end
def resubscribe_to_newsletter
success = false
begin
gibbon.lists(SiteConfig.mailchimp_newsletter_id).members(target_md5_email).upsert(
body: { status: "pending" },
)
success = true
rescue Gibbon::MailChimpError => e
report_error(e)
@ -174,4 +192,8 @@ class MailchimpBot
email = saved_changes["unconfirmed_email"] ? saved_changes["email"][0] : user.email
md5_email(email)
end
def previously_subcribed?(error)
error.title.match?(/Member In Compliance State/)
end
end

View file

@ -172,9 +172,9 @@ class User < ApplicationRecord
}
after_create_commit :send_welcome_notification
after_save :bust_cache
after_save :subscribe_to_mailchimp_newsletter
after_save :conditionally_resave_articles
after_save :bust_cache
after_save :subscribe_to_mailchimp_newsletter
after_save :conditionally_resave_articles
after_create_commit :estimate_default_language
before_create :set_default_language
before_validation :set_username
@ -411,6 +411,7 @@ class User < ApplicationRecord
def subscribe_to_mailchimp_newsletter
return unless email.present? && email.include?("@")
return if saved_changes["unconfirmed_email"] && saved_changes["confirmation_sent_at"]
return unless saved_changes.key?(:email) || saved_changes.key?(:email_newsletter)
Users::SubscribeToMailchimpNewsletterWorker.perform_async(id)
end

View file

@ -69,7 +69,7 @@ FactoryBot.define do
after(:build) { |user| user.created_at = 3.weeks.ago }
end
trait :ignore_after_callback do
trait :ignore_mailchimp_subscribe_callback do
after(:build) do |user|
user.define_singleton_method(:subscribe_to_mailchimp_newsletter) {}
# user.class.skip_callback(:validates, :after_create)

View file

@ -19,7 +19,7 @@ class FakeGibbonRequest < Gibbon::Request
end
RSpec.describe MailchimpBot, type: :labor do
let(:user) { create(:user, :ignore_after_callback) }
let(:user) { create(:user, :ignore_mailchimp_subscribe_callback) }
let(:article) { create(:article, user_id: user.id) }
let(:my_gibbon_client) { instance_double(FakeGibbonRequest) }
let(:tag) { create(:tag, name: "tagname", bg_color_hex: Faker::Color.hex_color, text_color_hex: Faker::Color.hex_color, supported: true) }
@ -91,6 +91,19 @@ RSpec.describe MailchimpBot, type: :labor do
expect(my_gibbon_client).to have_received(:upsert).
with(hash_including(body: hash_including(email_address: user.email)))
end
it "tries to resubscribe the user if the user has previously been subscribed" do
user.update(email_newsletter: false)
mailchimp_bot = described_class.new(user)
mc_error =
Gibbon::MailChimpError.new("Error", status_code: 400, title: "Member In Compliance State")
allow(mailchimp_bot.gibbon).to receive(:upsert).and_raise(mc_error)
allow(mailchimp_bot).to receive(:resubscribe_to_newsletter)
mailchimp_bot.upsert_to_newsletter
expect(mailchimp_bot).to have_received(:resubscribe_to_newsletter)
end
end
describe "manage community moderator list" do

View file

@ -530,6 +530,15 @@ RSpec.describe User, type: :model do
user.update(unconfirmed_email: "bob@bob.com", confirmation_sent_at: Time.current)
end
end
it "does not enqueue when the email address or subscription status has not changed" do
# The trait replaces the method with a dummy, but we need the actual method for this test.
user = described_class.find(create(:user, :ignore_mailchimp_subscribe_callback).id)
sidekiq_assert_no_enqueued_jobs(only: Users::SubscribeToMailchimpNewsletterWorker) do
user.update(website_url: "http://example.com")
end
end
end
describe "#conditionally_resave_articles" do