Move pin post to admin ✂️ (#14739)

* Update pin post button to be an admin articles button instead

* Rename file since we don't pin posts on show page

* Don't use instant click for admin link

* Update tests to visit the article from the start
This commit is contained in:
Andy Zhao 2021-09-17 14:25:39 -04:00 committed by GitHub
parent 7a1f6246ee
commit e1606bcb0c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 280 deletions

View file

@ -40,22 +40,9 @@ function addRelevantButtonsToArticle(user) {
// we hide the buttons for draft articles, for non admins and
// if there's already a pinned post different from the current one
if (
published &&
user.admin &&
(articleId === pinnedArticleId || !pinnedArticleId)
) {
const isArticlePinned = articleContainer.hasAttribute('data-pinned');
const { pinPath } = articleContainer.dataset;
if (user.admin) {
actions.push(
`<button
id="js-${isArticlePinned ? 'unpin' : 'pin'}-article"
class="crayons-btn crayons-btn--s crayons-btn--secondary ml-1"
data-path="${pinPath}"
data-article-id="${articleId}">${
isArticlePinned ? 'Unpin' : 'Pin'
} Post</button>`,
`<a class="crayons-btn crayons-btn--s crayons-btn--secondary ml-1" href="/admin/content_manager/articles/${articleId}" data-no-instant>Admin</a>`,
);
}

View file

@ -123,47 +123,6 @@ getCsrfToken().then(async () => {
}
});
// Pin/Unpin article
// these element are added by initializeBaseUserData.js:addRelevantButtonsToArticle
const toggleArticlePin = async (button) => {
const isPinButton = button.id === 'js-pin-article';
const { articleId, path } = button.dataset;
const method = isPinButton ? 'PUT' : 'DELETE';
const body = method === 'PUT' ? JSON.stringify({ id: articleId }) : null;
const response = await fetch(path, {
method,
body,
headers: {
Accept: 'application/json',
'X-CSRF-Token': window.csrfToken,
'Content-Type': 'application/json',
},
credentials: 'same-origin',
});
// response could potentially fail if the article is draft but we don't show
// the buttons in those cases, so I think there's no need to handle that scenario client side
if (response.ok) {
// replace id and label
button.id = isPinButton ? 'js-unpin-article' : 'js-pin-article';
button.innerHTML = `${isPinButton ? 'Unpin' : 'Pin'} Post`;
const message = isPinButton
? 'The post has been succesfully pinned'
: 'The post has been succesfully unpinned';
addSnackbarItem({ message });
}
};
const actionsContainer = document.getElementById('action-space');
const pinTargets = ['js-pin-article', 'js-unpin-article'];
actionsContainer.addEventListener('click', async (event) => {
if (pinTargets.includes(event.target.id)) {
toggleArticlePin(event.target);
}
});
// Initialize the profile preview functionality
const profilePreviewTrigger = document.getElementById(
'profile-preview-trigger',

View file

@ -94,4 +94,13 @@ describe('Pin an article from the admin area', () => {
.first()
.should('not.be.checked');
});
it('should show the pinned post to a logged out user', () => {
cy.findAllByRole('checkbox', { name: 'Pinned' }).first().check();
cy.findAllByRole('button', { name: 'Submit' }).first().click();
cy.signOutUser();
cy.findByRole('main').findByTestId('pinned-article').should('be.visible');
});
});

View file

@ -0,0 +1,72 @@
describe('Admin button on article - Anonymous user', () => {
beforeEach(() => {
cy.testSetup();
cy.visit('/admin_mcadmin/test-article-slug');
});
it('should not see the Admin button', () => {
cy.findAllByRole('heading', { name: 'Test article' }).first().click();
cy.findByRole('main')
.findByRole('button', { name: 'Admin' })
.should('not.exist');
});
});
describe('Admin button on article - Non admin user', () => {
beforeEach(() => {
cy.testSetup();
cy.fixture('users/articleEditorV1User.json').as('user');
// Responses from these requests are not required for this test, and are stubbed to prevent responses interfering with subsequent tests
cy.intercept('/reactions?article**', {
body: {
current_user: { id: '' },
reactions: [],
article_reaction_counts: [],
},
});
cy.intercept('/reactions?commentable**', {
body: {
current_user: { id: '' },
reactions: [],
public_reaction_counts: [],
},
});
cy.intercept('/follows**', {});
cy.get('@user').then((user) => {
cy.loginUser(user).then(() => {
cy.visit('/admin_mcadmin/test-article-slug');
});
});
});
it('should not see the Admin button', () => {
cy.findByRole('main')
.findByRole('button', { name: 'Admin' })
.should('not.exist');
});
});
describe('Admin User viewing article', () => {
beforeEach(() => {
cy.testSetup();
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then((user) => {
cy.loginUser(user).then(() => {
cy.visit('/admin_mcadmin/test-article-slug');
});
});
});
it('should see the admin button', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('link', { name: 'Admin' })
.first()
.should('have.attr', 'href')
.and('contains', '/admin/content_manager/articles');
});
});
});

View file

@ -1,224 +0,0 @@
describe('Pin an article - Anonymous user', () => {
beforeEach(() => {
cy.testSetup();
cy.visit('/');
});
it('should not see the Pin Post button', () => {
cy.findAllByRole('heading', { name: 'Test article' }).first().click();
cy.findByRole('main')
.findByRole('button', { name: 'Pin Post' })
.should('not.exist');
});
});
describe('Pin an article - Non admin user', () => {
beforeEach(() => {
cy.testSetup();
cy.fixture('users/articleEditorV1User.json').as('user');
// Responses from these requests are not required for this test, and are stubbed to prevent responses interfering with subsequent tests
cy.intercept('/reactions?article**', {
body: {
current_user: { id: '' },
reactions: [],
article_reaction_counts: [],
},
});
cy.intercept('/reactions?commentable**', {
body: {
current_user: { id: '' },
reactions: [],
public_reaction_counts: [],
},
});
cy.intercept('/follows**', {});
cy.get('@user').then((user) => {
cy.loginUser(user).then(() => {
cy.createArticle({
title: 'Test Article',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: true,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
// Wait for page to load
cy.findByRole('heading', { name: 'Test Article' });
});
});
});
});
it('should not see the Pin Post button', () => {
cy.findByRole('main')
.findByRole('button', { name: 'Pin Post' })
.should('not.exist');
});
});
describe('Pin an article - Admin User', () => {
beforeEach(() => {
cy.testSetup();
cy.fixture('users/adminUser.json').as('user');
cy.get('@user').then((user) => {
cy.loginUser(user).then(() => {
cy.createArticle({
title: 'Test Article',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: true,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
});
});
});
});
it('should pin a post', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('button', { name: 'Pin Post' }).first().click();
// check the button has changed to "Unpin Post"
cy.findAllByRole('button', { name: 'Unpin Post' }).first();
});
cy.visitAndWaitForUserSideEffects('/');
cy.findByRole('main').findByTestId('pinned-article').should('be.visible');
});
it('should unpin a post', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('button', { name: 'Pin Post' }).first().click();
cy.findAllByRole('button', { name: 'Unpin Post' }).first().click();
cy.findAllByRole('button', { name: 'Pin Post' }).first();
});
cy.visitAndWaitForUserSideEffects('/');
cy.findByRole('main').findByTestId('pinned-article').should('not.exist');
});
it('should not add the "Pin Post" button to a draft article', () => {
cy.findByRole('main')
.findAllByRole('button', { name: 'Pin Post' })
.first()
.click();
cy.createArticle({
title: 'Test Article 2',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: false,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
cy.findByRole('heading', { name: 'Test Article 2' });
cy.findByRole('main')
.findByRole('button', { name: 'Pin Post' })
.should('not.exist');
});
});
it('should not add the "Pin Post" button to the non currently pinned article', () => {
cy.findByRole('main')
.findAllByRole('button', { name: 'Pin Post' })
.first()
.click();
cy.createArticle({
title: 'Test Article 2',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: true,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
cy.findByRole('heading', { name: 'Test Article 2' });
cy.findByRole('main')
.findByRole('button', { name: 'Pin Post' })
.should('not.exist');
});
});
it('should allow to pin another post after the current pinned post is deleted', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('button', { name: 'Pin Post' }).first().click();
cy.findAllByRole('link', { name: 'Manage' }).first().click();
});
cy.findByRole('heading', { name: 'Tools:' });
cy.findByRole('main')
.findAllByRole('link', { name: 'Delete' })
.first()
.click();
cy.findByRole('heading', {
name: 'Are you sure you want to delete this article?',
});
cy.findByRole('main')
.findAllByRole('button', { name: 'Delete' })
.first()
.click();
cy.createArticle({
title: 'Another Article',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: true,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
cy.findByRole('heading', { name: 'Another Article' });
cy.findByRole('main')
.findAllByRole('button', { name: 'Pin Post' })
.first()
.should('exist');
});
});
it('should allow to pin another post after the current pinned post is unpublished', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('button', { name: 'Pin Post' }).first().click();
cy.findAllByRole('link', { name: 'Edit' }).first().click();
});
cy.findByRole('form', { name: 'Edit post' });
cy.findByRole('main').within(() => {
cy.findAllByTitle(/^Post options$/i)
.first()
.click();
cy.findAllByRole('button', { name: 'Unpublish post' }).first().click();
});
cy.findByRole('heading', { name: 'Test Article' });
cy.createArticle({
title: 'Another Article',
tags: ['beginner', 'ruby', 'go'],
content: `This is a test article's contents.`,
published: true,
}).then((response) => {
cy.visitAndWaitForUserSideEffects(response.body.current_state_path);
cy.findByRole('heading', { name: 'Another Article' });
cy.findByRole('main')
.findAllByRole('button', { name: 'Pin Post' })
.first()
.should('exist');
});
});
it('should show the pinned post to a logged out user', () => {
cy.findByRole('main').within(() => {
cy.findAllByRole('button', { name: 'Pin Post' }).first().click();
// check the button has changed to "Unpin Post"
cy.findAllByRole('button', { name: 'Unpin Post' }).first();
});
cy.signOutUser();
cy.findByRole('main').findByTestId('pinned-article').should('be.visible');
});
});