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:
parent
7a1f6246ee
commit
e1606bcb0c
5 changed files with 83 additions and 280 deletions
|
|
@ -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>`,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -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');
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue