[deploy] UserSubscription liquid tag update & re-enable JS (#9082)
This commit is contained in:
parent
9af9a489e5
commit
f86b8a55a4
4 changed files with 243 additions and 57 deletions
|
|
@ -13,73 +13,117 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
|
||||
// Hiding/showing elements
|
||||
// ***************************************
|
||||
|
||||
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
|
||||
const subscriptionSignedOut = document.getElementById('subscription-signed-out');
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
const subscriberAppleAuth = document.getElementById('subscriber-apple-auth');
|
||||
const confirmationModal = document.getElementById('user-subscription-confirmation-modal');
|
||||
const profileImageContainer = document.getElementById('profile-images');
|
||||
const subscriberImageContainer = document.querySelector('.ltag__user-subscription-tag__subscriber-profile-image');
|
||||
|
||||
function clearSubscriptionArea() {
|
||||
subscriptionSignedIn.classList.add("hidden");
|
||||
subscriptionSignedOut.classList.add("hidden");
|
||||
responseMessage.classList.add("hidden");
|
||||
subscriberAppleAuth.classList.add("hidden");
|
||||
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
|
||||
if (subscriptionSignedIn) {
|
||||
subscriptionSignedIn.classList.add("hidden");
|
||||
}
|
||||
|
||||
const subscriptionSignedOut = document.getElementById('subscription-signed-out');
|
||||
if (subscriptionSignedOut) {
|
||||
subscriptionSignedOut.classList.add("hidden");
|
||||
}
|
||||
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
if (responseMessage) {
|
||||
responseMessage.classList.add("hidden");
|
||||
}
|
||||
|
||||
const subscriberAppleAuth = document.getElementById('subscriber-apple-auth');
|
||||
if (subscriberAppleAuth) {
|
||||
subscriberAppleAuth.classList.add("hidden");
|
||||
}
|
||||
|
||||
hideConfirmationModal();
|
||||
}
|
||||
|
||||
function showSignedIn() {
|
||||
clearSubscriptionArea();
|
||||
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
|
||||
if (subscriptionSignedIn) {
|
||||
subscriptionSignedIn.classList.remove("hidden");
|
||||
}
|
||||
|
||||
subscriptionSignedIn.classList.remove("hidden");
|
||||
profileImageContainer.classList.remove("signed-out");
|
||||
const profileImages = document.getElementById('profile-images');
|
||||
if (profileImages) {
|
||||
profileImages.classList.remove("signed-out");
|
||||
profileImages.classList.add("signed-in");
|
||||
}
|
||||
}
|
||||
|
||||
function showSignedOut() {
|
||||
clearSubscriptionArea();
|
||||
subscriptionSignedOut.classList.remove("hidden");
|
||||
|
||||
const subscriptionSignedOut = document.getElementById('subscription-signed-out');
|
||||
if (subscriptionSignedOut) {
|
||||
subscriptionSignedOut.classList.remove("hidden");
|
||||
}
|
||||
|
||||
const profileImages = document.getElementById('profile-images');
|
||||
if (profileImages) {
|
||||
profileImages.classList.remove("signed-in");
|
||||
profileImages.classList.add("signed-out");
|
||||
}
|
||||
|
||||
const subscriberProfileImage = document.querySelector('.ltag__user-subscription-tag__subscriber-profile-image');
|
||||
if (subscriberProfileImage) {
|
||||
subscriberProfileImage.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function showResponseMessage(noticeType, msg) {
|
||||
clearSubscriptionArea();
|
||||
|
||||
responseMessage.classList.remove("hidden");
|
||||
responseMessage.classList.add(`crayons-notice--${noticeType}`);
|
||||
responseMessage.textContent = msg;
|
||||
const responseMessage = document.getElementById('response-message');
|
||||
if (responseMessage) {
|
||||
responseMessage.classList.remove("hidden");
|
||||
responseMessage.classList.add(`crayons-notice--${noticeType}`);
|
||||
responseMessage.textContent = msg;
|
||||
}
|
||||
}
|
||||
|
||||
function showAppleAuthMessage() {
|
||||
clearSubscriptionArea();
|
||||
subscriberAppleAuth.classList.remove("hidden");
|
||||
const subscriber = userData();
|
||||
if (subscriber) {
|
||||
updateProfileImages('.ltag__user-subscription-tag__subscriber-profile-image', subscriber);
|
||||
}
|
||||
|
||||
const subscriberAppleAuth = document.getElementById('subscriber-apple-auth');
|
||||
if (subscriberAppleAuth) {
|
||||
subscriberAppleAuth.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function showSubscribed() {
|
||||
updateSubscriberData();
|
||||
const authorUsername = document.getElementById('user-subscription-tag').dataset.authorUsername;
|
||||
const authorUsername = document.getElementById('user-subscription-tag')?.dataset.authorUsername;
|
||||
const alreadySubscribedMsg = `You are already subscribed.`;
|
||||
showResponseMessage('success', alreadySubscribedMsg);
|
||||
}
|
||||
|
||||
function showConfirmationModal() {
|
||||
confirmationModal.classList.remove("hidden");
|
||||
const confirmationModal = document.getElementById('user-subscription-confirmation-modal');
|
||||
if (confirmationModal) {
|
||||
confirmationModal.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
function hideConfirmationModal() {
|
||||
confirmationModal.classList.add("hidden");
|
||||
const confirmationModal = document.getElementById('user-subscription-confirmation-modal');
|
||||
if (confirmationModal) {
|
||||
confirmationModal.classList.add("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
// Updating DOM elements
|
||||
// ***************************************
|
||||
function updateSubscriberData() {
|
||||
const subscriber = userData();
|
||||
|
||||
if (subscriber) {
|
||||
if (subscriber.email) {
|
||||
updateElementsTextContent('.ltag__user-subscription-tag__subscriber-email', subscriber.email);
|
||||
updateProfileImages('.ltag__user-subscription-tag__subscriber-profile-image', subscriber);
|
||||
}
|
||||
|
||||
updateProfileImages('.ltag__user-subscription-tag__subscriber-profile-image', subscriber);
|
||||
}
|
||||
|
||||
function updateElementsTextContent(identifier, value) {
|
||||
|
|
@ -102,29 +146,42 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
// Adding event listeners for 'click'
|
||||
// ***************************************
|
||||
function addSignInClickHandler() {
|
||||
document.getElementById('sign-in-btn').addEventListener('click', function(e) {
|
||||
if (typeof showModal !== 'undefined') {
|
||||
const signInBtn = document.getElementById('sign-in-btn');
|
||||
if (signInBtn && typeof showModal !== 'undefined') {
|
||||
signInBtn.addEventListener('click', function(e) {
|
||||
showModal('email_signup');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function addConfirmationModalClickHandlers() {
|
||||
document.getElementById('subscribe-btn').addEventListener('click', function(e) {
|
||||
showConfirmationModal();
|
||||
});
|
||||
const subscribeBtn = document.getElementById('subscribe-btn');
|
||||
if (subscribeBtn) {
|
||||
subscribeBtn.addEventListener('click', function(e) {
|
||||
showConfirmationModal();
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('cancel-btn').addEventListener('click', function(e) {
|
||||
hideConfirmationModal();
|
||||
});
|
||||
const cancelBtn = document.getElementById('cancel-btn');
|
||||
if (cancelBtn) {
|
||||
cancelBtn.addEventListener('click', function(e) {
|
||||
hideConfirmationModal();
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('close-confirmation-modal').addEventListener('click', function(e) {
|
||||
hideConfirmationModal();
|
||||
});
|
||||
const closeConfirmationModal = document.getElementById('close-confirmation-modal');
|
||||
if (closeConfirmationModal) {
|
||||
closeConfirmationModal.addEventListener('click', function(e) {
|
||||
hideConfirmationModal();
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById('confirmation-btn').addEventListener('click', function(e) {
|
||||
handleSubscription();
|
||||
});
|
||||
const confirmationModal = document.getElementById('confirmation-btn')
|
||||
if (confirmationModal) {
|
||||
confirmationModal.addEventListener('click', function(e) {
|
||||
handleSubscription();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// API calls
|
||||
|
|
@ -136,7 +193,9 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
'Content-Type': 'application/json',
|
||||
}
|
||||
|
||||
const articleId = document.getElementById('article-body').dataset.articleId;
|
||||
const articleBody = document.getElementById('article-body');
|
||||
const articleId = (articleBody ? articleBody.dataset.articleId : null);
|
||||
|
||||
const subscriber = userData();
|
||||
const body = JSON.stringify(
|
||||
{
|
||||
|
|
@ -159,7 +218,8 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
}
|
||||
|
||||
function fetchIsSubscribed() {
|
||||
const articleId = document.getElementById('article-body').dataset.articleId;
|
||||
const articleBody = document.getElementById('article-body');
|
||||
const articleId = (articleBody ? articleBody.dataset.articleId : null);
|
||||
|
||||
const params = new URLSearchParams({
|
||||
source_type: 'Article',
|
||||
|
|
@ -190,7 +250,8 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
function handleSubscription() {
|
||||
submitSubscription().then(function(response) {
|
||||
if (response.success) {
|
||||
const authorUsername = document.getElementById('user-subscription-tag').dataset.authorUsername;
|
||||
const userSubscriptionTag = document.getElementById('user-subscription-tag');
|
||||
const authorUsername = (userSubscriptionTag ? userSubscriptionTag.dataset.authorUsername : null);
|
||||
const successMsg = `You are now subscribed and may receive emails from ${authorUsername}`;
|
||||
showResponseMessage('success', successMsg);
|
||||
} else {
|
||||
|
|
@ -202,7 +263,7 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
function checkIfSubscribed() {
|
||||
fetchIsSubscribed().then(function(response) {
|
||||
const subscriber = userData();
|
||||
const isSubscriberAuthedWithApple = subscriber.email.endsWith('@privaterelay.appleid.com');
|
||||
const isSubscriberAuthedWithApple = (subscriber.email ? subscriber.email.endsWith('@privaterelay.appleid.com') : false);
|
||||
|
||||
if (response.is_subscribed) {
|
||||
showSubscribed();
|
||||
|
|
@ -218,8 +279,6 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
if (isUserSignedIn()) {
|
||||
showSignedIn();
|
||||
addConfirmationModalClickHandlers();
|
||||
profileImageContainer.classList.remove("signed-out");
|
||||
profileImageContainer.classList.add("signed-in");
|
||||
|
||||
// We need access to some DOM elements (i.e. csrf token, article id, userData, etc.)
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
|
@ -228,9 +287,6 @@ class UserSubscriptionTag < LiquidTagBase
|
|||
} else {
|
||||
showSignedOut();
|
||||
addSignInClickHandler();
|
||||
profileImageContainer.classList.remove("signed-in");
|
||||
profileImageContainer.classList.add("signed-out");
|
||||
subscriberImageContainer.classList.add("hidden");
|
||||
}
|
||||
JAVASCRIPT
|
||||
|
||||
|
|
|
|||
|
|
@ -254,6 +254,6 @@
|
|||
<%== PollTag.script %>
|
||||
<%== RunkitTag.script %>
|
||||
<%== TweetTag.script %>
|
||||
<%#== UserSubscriptionTag.script %>
|
||||
<%== UserSubscriptionTag.script %>
|
||||
</script>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@
|
|||
</div>
|
||||
|
||||
<div class="ltag__user-subscription-tag__apple-auth fs-s hidden" id="subscriber-apple-auth">
|
||||
<button disabled class="crayons-btn" id="subscribe-btn">Subscribe</button>
|
||||
<button disabled class="crayons-btn" id="apple-subscribe-btn">Subscribe</button>
|
||||
<div class="fs-s" id="apple-auth-message">
|
||||
Hey, there! It looks like when you created your DEV account you signed
|
||||
up with Apple using a private relay email address. If you'd like to
|
||||
|
|
@ -71,9 +71,8 @@
|
|||
</header>
|
||||
<div class="crayons-modal__box__body">
|
||||
<p id="confirmation-text" class="fs-base mb-4 mt-0">
|
||||
You'll share your email address
|
||||
<span class="ltag__user-subscription-tag__subscriber-email"></span>
|
||||
with
|
||||
You'll share your email address<span class="ltag__user-subscription-tag__subscriber-email"></span>,
|
||||
username, name, and DEV profile URL with
|
||||
<span class="ltag__user-subscription-tag__author-username fw-medium"><%= author_username %></span>.
|
||||
Once you do this, you cannot undo this.
|
||||
<p>
|
||||
|
|
|
|||
131
spec/liquid_tags/user_subscription_tag_spec.rb
Normal file
131
spec/liquid_tags/user_subscription_tag_spec.rb
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
require "rails_helper"
|
||||
|
||||
RSpec.describe UserSubscriptionTag, type: :liquid_tag do
|
||||
setup { Liquid::Template.register_tag("user_subscription", described_class) }
|
||||
|
||||
let(:subscriber) { create(:user) }
|
||||
let(:author) { create(:user, :super_admin) } # TODO: (Alex Smith) - update roles before release
|
||||
let(:article_with_user_subscription_tag) { create(:article, :with_user_subscription_tag_role_user, with_user_subscription_tag: true) }
|
||||
|
||||
context "when rendering" do
|
||||
it "renders default data correctly" do
|
||||
source = create(:article, user: author)
|
||||
liquid_tag_options = { source: source, user: source.user }
|
||||
cta_text = "Some sweet CTA text"
|
||||
liquid_tag = Liquid::Template.parse("{% user_subscription #{cta_text} %}", liquid_tag_options).render
|
||||
expect(liquid_tag).to include(CGI.escapeHTML(cta_text))
|
||||
expect(liquid_tag).to include(CGI.escapeHTML(author.username))
|
||||
expect(liquid_tag).to include(CGI.escapeHTML(author.profile_image_90))
|
||||
end
|
||||
|
||||
it "displays signed out view by default", type: :system, js: true do
|
||||
sign_in author
|
||||
visit "/new" # Preview behaves differently - we don't load liquid tag scripts
|
||||
fill_in "article_body_markdown", with: "{% user_subscription Some sweet CTA text %}"
|
||||
page.execute_script("window.scrollTo(0, -100000)")
|
||||
find("button", text: /\APreview\z/).click
|
||||
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :visible)
|
||||
expect(page).to have_css("img.ltag__user-subscription-tag__author-profile-image[src='#{author.profile_image_90}']")
|
||||
end
|
||||
end
|
||||
|
||||
context "when signed in", type: :system, js: true do
|
||||
before do
|
||||
sign_in subscriber
|
||||
visit article_with_user_subscription_tag.path
|
||||
end
|
||||
|
||||
it "shows the signed in UX" do
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :visible)
|
||||
expect(page).to have_css("img.ltag__user-subscription-tag__subscriber-profile-image[src='#{subscriber.profile_image_90}']")
|
||||
end
|
||||
|
||||
it "asks the user to confirm their subscription" do
|
||||
expect(page).to have_css("#user-subscription-confirmation-modal", visible: :hidden)
|
||||
click_button("Subscribe", id: "subscribe-btn")
|
||||
expect(page).to have_css("#user-subscription-confirmation-modal", visible: :visible)
|
||||
end
|
||||
|
||||
it "displays a sucess mesage when a subscription is created" do
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :visible)
|
||||
click_button("Subscribe", id: "subscribe-btn")
|
||||
click_button("Confirm subscription", id: "confirmation-btn")
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#response-message.crayons-notice--success", visible: :visible)
|
||||
|
||||
within "#response-message" do
|
||||
expect(page).to have_text("You are now subscribed")
|
||||
end
|
||||
end
|
||||
|
||||
it "displays errors when there's an error creating a subscription" do
|
||||
# Create a subscription so it causes an error by already being subscribed
|
||||
create(:user_subscription, subscriber_id: subscriber.id, subscriber_email: subscriber.email, author_id: article_with_user_subscription_tag.user_id, user_subscription_sourceable: article_with_user_subscription_tag)
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :visible)
|
||||
click_button("Subscribe", id: "subscribe-btn")
|
||||
click_button("Confirm subscription", id: "confirmation-btn")
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#response-message.crayons-notice--danger", visible: :visible)
|
||||
|
||||
within "#response-message" do
|
||||
expect(page).to have_text("Subscriber has already been taken")
|
||||
end
|
||||
end
|
||||
|
||||
it "tells the user they're already subscribed by default if they're already subscribed" do
|
||||
create(:user_subscription, subscriber_id: subscriber.id, subscriber_email: subscriber.email, author_id: article_with_user_subscription_tag.user_id, user_subscription_sourceable: article_with_user_subscription_tag)
|
||||
visit article_with_user_subscription_tag.path
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#response-message.crayons-notice--success", visible: :visible)
|
||||
|
||||
within "#response-message" do
|
||||
expect(page).to have_text("You are already subscribed.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when signed out", type: :sytem, js: true do
|
||||
before { visit article_with_user_subscription_tag.path }
|
||||
|
||||
it "prompts a user to sign in when they're signed out", type: :system, js: true do
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :visible)
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: [@thepracticaldev/delightful]: re-enable this once email confirmation
|
||||
# is re-enabled and confirm it isn't flaky.
|
||||
xcontext "when a user has an Apple private relay email address", type: :system, js: true do
|
||||
it "prompts the user to update their email address" do
|
||||
allow(subscriber).to receive(:email).and_return("test@privaterelay.appleid.com")
|
||||
sign_in subscriber
|
||||
visit article_with_user_subscription_tag.path
|
||||
|
||||
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
|
||||
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
|
||||
expect(page).to have_css("#response-message", visible: :hidden)
|
||||
expect(page).to have_css("#subscriber-apple-auth", visible: :visible)
|
||||
|
||||
within "#subscriber-apple-auth" do
|
||||
expect(page).to have_button("Subscribe", disabled: true, visible: :visible)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue