docbrown/app/javascript/packs/initializers/__tests__/subscribeButton.test.js
Lawrence 0c93bde6c2
Subscribe to Comment Functionality (#19555)
* Move save over and add button labels

* comment notification design and functionality

* controller error handling

* add ternery operator for background class

* minor cleanup

* add proper styling toggles

* tests and mobile spec

* add for all buttons

* add article as a param

* comment is not required on article preview

* update policy spec

* add test for coverage

* add proper button titles

* use the last user comment as comment id

* add better error handling and remove multiple fetch calls in js

* copy change to threads

* update copy, fix multiple fetch calls, add observer for loading more notifications

* update spec

* add rspecs

* more test specs

* fix test specs

* subscribe button text tests

* add export

* optimistically update ui function tests

* button initialize test

* check for comment ancestry

* add feature flag block

* some cleanup

* update logic and specs

* oops

* rubocop issues

* change config names

* change config names

* fix spec

* add one more conditional

* check for comments

* service-object the toggler

* separate routes

* continual refactoring

* refine spec tests

* clean up policy

* Adjust js and view files to match be params

* some service object refactoring

* separate endpoints on client-side

* broken spec

* service specs

* policy spec fixes

* remove action param

* remove action param from spec

* minor updates

* trigger build

* update to post

* Services don't need permitted params

* Notifications continue to be a mess, decorator specs to follow

* Not toggling now

* This doesn't really belong here

* Fix tests after moving

* Streamline front-end

* There could be errors?

* polymorphic_name is a class thing

* ☠️ json_data in notification views

* Use feature_flag helper to get current_user

* Cannot derive current subscription status from notification, only from subscription

* Default is subscribe to all article comments

* Sync up matching unsubscribe, make subscribe idempotent-ish

* Temporarily comment-out button jest tests to see if I can unstick CI

* Stop trying to detect potential subscribe-to-comment

* Stop trying to detect potential subscribe-to-comment

* Minor spec refactoring

* Add specs for article notification decoration

* NotificationDecorator specs are rather long

* Rubocop likes it?

* Minor spec refactoring

* Doesn't need to stay pending

* Add spec for subscription finder

* Expand Subscribe service specs

* YAGNI, but I don't like hard-coded config

* Refactor Unsubscribe service specs

* nobody expects the infinite scroll

* This *might* work, except for feature flag

* Ancestry can be quite deep actually

* Rubocop

* Update subscribe button for subscribe-to-thread

* Jest tests are just tests

* hasAttribute != getAttribute

* Test knows **nothing** about window size

* Tests have been lying about mobileLabel this whole time

* Make payload/endpoint testable

* Is Jest actually happy???

* Still cleaning up jest/eslint

* Temporarily comment-out cypress tests pending feature flag

* Thanks, Rubocop, what would we do without you

* Preserve round-trip for 'top-level' and 'only-author' subscriptions

* Update specs

* Move save button icon

* Update test with better config param

* Try feature flag specific to cypress env

* Tell cypress to wait for (un)subscribing to work

---------

Co-authored-by: Lawrence S <lawrence@forem.com>
Co-authored-by: Joshua Wehner <joshua@forem.com>
2023-07-10 17:11:46 +02:00

185 lines
6.9 KiB
JavaScript

// subscribeButton.test.js
import {
initializeSubscribeButton,
updateSubscribeButtonText,
determinePayloadAndEndpoint,
} from '../../subscribeButton';
describe('subscribeButton', () => {
let button;
let originalFetch;
beforeEach(() => {
button = document.createElement('button');
button.classList.add('subscribe-button');
document.body.appendChild(button);
const spanElement = document.createElement('span');
spanElement.textContent = 'Subscribe to comments';
button.appendChild(spanElement);
// Baseline scenario starts Subscribed to all comments on an article
button.setAttribute('data-subscription_id', '1');
button.setAttribute('data-subscribed_to', 'article');
button.setAttribute('data-subscription_mode', 'all_comments');
button.setAttribute('data-article_id', '123');
// Store the original fetch function
originalFetch = global.fetch;
// Mock the fetch function with a spy
global.fetch = jest.fn().mockImplementation(() => Promise.resolve({}));
initializeSubscribeButton();
});
afterEach(() => {
document.body.removeChild(button);
// Restore the original fetch function
global.fetch = originalFetch;
});
it('should initialize subscribe buttons', () => {
expect(button.getAttribute('aria-label')).toBe('Subscribed to comments');
expect(button.querySelector('span').innerText).toBe(
'Subscribed to comments',
);
});
it('should update to unsubscribed setting label, and *not* pressed', () => {
updateSubscribeButtonText(button, 'unsubscribe');
expect(button.getAttribute('aria-label')).toBe('Subscribe to comments');
expect(button.querySelector('span').innerText).toBe(
'Subscribe to comments',
);
expect(button.getAttribute('aria-pressed')).toBe('false');
});
it('should update without override with blank subscription_id setting label, and *not* pressed', () => {
button.setAttribute('data-subscription_id', '');
updateSubscribeButtonText(button);
expect(button.getAttribute('aria-label')).toBe('Subscribe to comments');
expect(button.querySelector('span').innerText).toBe(
'Subscribe to comments',
);
expect(button.getAttribute('aria-pressed')).toBe('false');
});
it('"top_level_comments" scenario', () => {
button.setAttribute('data-subscription_config', 'top_level_comments');
updateSubscribeButtonText(button);
expect(button.getAttribute('aria-label')).toBe(
'Subscribed to top-level comments',
);
expect(button.querySelector('span').innerText).toBe(
'Subscribed to top-level comments',
);
expect(button.getAttribute('aria-pressed')).toBe('true');
});
it('"only_author_comments" scenario', () => {
button.setAttribute('data-subscription_config', 'only_author_comments');
updateSubscribeButtonText(button);
expect(button.getAttribute('aria-label')).toBe(
'Subscribed to author comments',
);
expect(button.querySelector('span').innerText).toBe(
'Subscribed to author comments',
);
expect(button.getAttribute('aria-pressed')).toBe('true');
});
it('unknown config scenario', () => {
button.setAttribute('data-subscription_config', 'unknown_config');
updateSubscribeButtonText(button);
expect(button.getAttribute('aria-label')).toBe('Subscribed to comments');
expect(button.querySelector('span').innerText).toBe(
'Subscribed to comments',
);
expect(button.getAttribute('aria-pressed')).toBe('true');
});
it('subscribed-to-thread scenario', () => {
button.setAttribute('data-subscription_config', 'thread');
button.setAttribute('data-subscribed_to', 'comment');
button.setAttribute('data-comment_id', '456');
updateSubscribeButtonText(button);
expect(button.getAttribute('aria-label')).toBe('Subscribed to thread');
expect(button.querySelector('span').innerText).toBe('Subscribed to thread');
expect(button.getAttribute('aria-pressed')).toBe('true');
});
it('was-subscribed-to-thread scenario', () => {
button.setAttribute('data-subscription_id', '');
button.setAttribute('data-subscription_config', 'thread');
button.setAttribute('data-subscribed_to', 'comment');
button.setAttribute('data-comment_id', '456');
updateSubscribeButtonText(button, 'unsubscribe');
expect(button.getAttribute('aria-label')).toBe('Subscribe to thread');
expect(button.querySelector('span').innerText).toBe('Subscribe to thread');
expect(button.getAttribute('aria-pressed')).toBe('false');
});
it('should capitalize the mobileLabel', () => {
const magicalWindowSize = 700;
updateSubscribeButtonText(button, 'subscribe', magicalWindowSize);
expect(button.getAttribute('aria-label')).toBe('Subscribed to comments');
expect(button.querySelector('span').innerText).toBe('Comments');
updateSubscribeButtonText(button, 'unsubscribe', magicalWindowSize);
expect(button.getAttribute('aria-label')).toBe('Subscribe to comments');
expect(button.querySelector('span').innerText).toBe('Comments');
button.setAttribute('data-subscription_config', 'top_level_comments');
updateSubscribeButtonText(button, 'subscribe', magicalWindowSize);
expect(button.getAttribute('aria-label')).toBe(
'Subscribed to top-level comments',
);
expect(button.querySelector('span').innerText).toBe('Top-level comments');
button.setAttribute('data-subscription_config', 'only_author_comments');
updateSubscribeButtonText(button, 'subscribe', magicalWindowSize);
expect(button.getAttribute('aria-label')).toBe(
'Subscribed to author comments',
);
expect(button.querySelector('span').innerText).toBe('Author comments');
button.setAttribute('data-subscription_config', 'unknown_config');
updateSubscribeButtonText(button, 'subscribe', magicalWindowSize);
expect(button.getAttribute('aria-label')).toBe('Subscribed to comments');
expect(button.querySelector('span').innerText).toBe('Comments');
});
it('should determine the expected payload', async () => {
let { payload, endpoint } = determinePayloadAndEndpoint(button);
// Baseline case: **is** subscribed
expect(payload).toEqual({ subscription_id: '1' });
expect(endpoint).toEqual('comment-unsubscribe');
// When unsubscribed from an article
button.setAttribute('data-subscription_id', '');
({ payload, endpoint } = determinePayloadAndEndpoint(button));
expect(payload).toEqual({ article_id: '123' });
expect(endpoint).toEqual('comment-subscribe');
// When unsubscribed from a thread
button.setAttribute('data-subscription_id', '');
button.setAttribute('data-subscription_config', 'thread');
button.setAttribute('data-subscribed_to', 'comment');
button.setAttribute('data-comment_id', '456');
({ payload, endpoint } = determinePayloadAndEndpoint(button));
expect(payload).toEqual({ comment_id: '456' });
expect(endpoint).toEqual('comment-subscribe');
});
});