d6b7ebb517
ref https://github.com/TryGhost/Ghost/issues/11038
1. Enforced lint rule
**[ghost/mocha/no-identical-title](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-identical-title.md)**
- Fixed relevant tests
2. Enforced lint rule
**[ghost/mocha/max-top-level-suites](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/max-top-level-suites.md)**
- No required fixes, as tests are compliant already
#### Additional details
Specifically for `ghost/mocha/no-identical-title` most fixes were simple
test description updates. Added comments to aid the PR review for the
ones that had relevant changes, and might require more attention. They
are as follows:
*
[e2e-api/admin/invites.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496397548):
Removed duplicated test (exact same code on both);
*
[e2e-api/admin/members.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496399107):
From the[ PR this was
introduced](73466c1c40 (diff-4dbc7e96e356428561085147e00e9acb5c71b58d4c1bd3d9fc9ac30e77c45be0L236-L237)
)
seems like author based his test on an existing one but possibly forgot
to rename it;
*
[unit/api/canary/utils/serializers/input/pages.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496400143):
The [page filter](https://github.com/TryGhost/Ghost/pull/14829/files)
was removed, so changed the description accordingly;
*
[unit/api/canary/utils/serializers/input/posts.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496400329):
The [page filter](https://github.com/TryGhost/Ghost/pull/14829/files)
was removed, so changed the description accordingly;
*
[unit/frontend/services/rendering/templates.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496402430):
Removed duplicated test
*
[unit/server/models/post.test.js](https://github.com/TryGhost/Ghost/pull/19720#discussion_r1496403529):
the change in [this
PR](https://github.com/TryGhost/Ghost/pull/14586/files#diff-c351cb589adefbb886570cfadb33b33eb8fdc12bde1024d1188cd18c165fc5e8L1010)
made three tests here mostly the same. Deduplicated them and kept only
one.
517 lines
20 KiB
JavaScript
517 lines
20 KiB
JavaScript
const {agentProvider, fixtureManager, mockManager} = require('../../utils/e2e-framework');
|
|
const nock = require('nock');
|
|
const assert = require('assert/strict');
|
|
const markdownToMobiledoc = require('../../utils/fixtures/data-generator').markdownToMobiledoc;
|
|
const jobsService = require('../../../core/server/services/mentions-jobs');
|
|
|
|
let agent;
|
|
let mentionUrl = new URL('https://www.otherghostsite.com/');
|
|
let mentionUrl2 = new URL('https://www.otherghostsite2.com/');
|
|
let mentionHtml = `Check out this really cool <a href="${mentionUrl.href}">other site</a>.`;
|
|
let mentionHtml2 = `Check out this really cool <a href="${mentionUrl2.href}">other site</a>.`;
|
|
let endpointUrl = new URL('https://www.endpoint.com/');
|
|
let endpointUrl2 = new URL('https://www.endpoint2.com/');
|
|
let targetHtml = `<head><link rel="webmention" href="${endpointUrl.href}"</head><body>Some content</body>`;
|
|
let targetHtml2 = `<head><link rel="webmention" href="${endpointUrl2.href}"</head><body>Some content</body>`;
|
|
let mentionMock;
|
|
let endpointMock;
|
|
const DomainEvents = require('@tryghost/domain-events');
|
|
|
|
const mentionsPost = {
|
|
title: 'testing sending webmentions',
|
|
mobiledoc: markdownToMobiledoc(mentionHtml)
|
|
};
|
|
|
|
const editedMentionsPost = {
|
|
title: 'testing sending webmentions',
|
|
mobiledoc: markdownToMobiledoc(mentionHtml2)
|
|
};
|
|
|
|
function addMentionMocks() {
|
|
// mock response from website mentioned by post to provide endpoint
|
|
mentionMock = nock(mentionUrl.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml, {'content-type': 'text/html'});
|
|
|
|
// mock response from mention endpoint, usually 201, sometimes 202
|
|
endpointMock = nock(endpointUrl.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
}
|
|
|
|
describe('Mentions Service', function () {
|
|
before(async function () {
|
|
agent = await agentProvider.getAdminAPIAgent();
|
|
await fixtureManager.init('users');
|
|
await agent.loginAsAdmin();
|
|
});
|
|
|
|
beforeEach(async function () {
|
|
// externalRequest does dns lookup; stub to make sure we don't fail with fake domain names
|
|
mockManager.disableNetwork();
|
|
|
|
// mock response from website mentioned by post to provide endpoint
|
|
addMentionMocks();
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
});
|
|
|
|
afterEach(async function () {
|
|
mockManager.restore();
|
|
});
|
|
|
|
describe('Sending Service', function () {
|
|
describe(`does not send when we expect it to not send`, function () {
|
|
it('New draft post created', async function () {
|
|
const draftPost = {status: 'draft', ...mentionsPost};
|
|
await agent
|
|
.post('posts/')
|
|
.body({posts: [draftPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(endpointMock.isDone(), false);
|
|
});
|
|
|
|
it('Email only post published', async function () {
|
|
const publishedPost = {status: 'published', email_only: true, ...mentionsPost};
|
|
await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(endpointMock.isDone(), false);
|
|
});
|
|
|
|
it('Post without content', async function () {
|
|
const publishedPost = {status: 'published', mobiledoc: markdownToMobiledoc(''), title: 'empty post'};
|
|
await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(endpointMock.isDone(), false);
|
|
});
|
|
|
|
it('New draft page created', async function () {
|
|
const draftPage = {status: 'draft', ...mentionsPost};
|
|
await agent
|
|
.post('pages/')
|
|
.body({pages: [draftPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(endpointMock.isDone(), false);
|
|
});
|
|
});
|
|
|
|
describe(`does send when we expect it to send`, function () {
|
|
it('Newly published post (post.published)', async function () {
|
|
let publishedPost = {status: 'published', ...mentionsPost};
|
|
await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
});
|
|
|
|
it('Does not send for edited post without url changes (post.published.edited)', async function () {
|
|
const publishedPost = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
addMentionMocks();
|
|
assert.equal(mentionMock.isDone(), false, 'should be reset');
|
|
assert.equal(endpointMock.isDone(), false, 'should be reset');
|
|
|
|
const postId = res.body.posts[0].id;
|
|
const editedPost = {
|
|
mobiledoc: markdownToMobiledoc(mentionHtml + 'More content'),
|
|
updated_at: res.body.posts[0].updated_at
|
|
};
|
|
|
|
await agent.put(`posts/${postId}/`)
|
|
.body({posts: [editedPost]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(endpointMock.isDone(), false);
|
|
});
|
|
|
|
it('Does send for edited post with url changes (post.published.edited)', async function () {
|
|
const publishedPost = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
addMentionMocks();
|
|
assert.equal(mentionMock.isDone(), false, 'should be reset');
|
|
assert.equal(endpointMock.isDone(), false, 'should be reset');
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl2.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml2, {'content-type': 'text/html'});
|
|
|
|
const endpointMockTwo = nock(endpointUrl2.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const postId = res.body.posts[0].id;
|
|
const editedPost = {
|
|
...editedMentionsPost,
|
|
updated_at: res.body.posts[0].updated_at
|
|
};
|
|
|
|
await agent.put(`posts/${postId}/`)
|
|
.body({posts: [editedPost]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
|
|
// Also send again to the deleted url
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
});
|
|
|
|
it('Unpublished post (post.unpublished)', async function () {
|
|
const publishedPost = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml, {'content-type': 'text/html'});
|
|
const endpointMockTwo = nock(endpointUrl.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const postId = res.body.posts[0].id;
|
|
// moving back to draft is how we unpublish
|
|
const unpublishedPost = {
|
|
status: 'draft',
|
|
updated_at: res.body.posts[0].updated_at
|
|
};
|
|
await agent.put(`posts/${postId}/`)
|
|
.body({posts: [unpublishedPost]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
});
|
|
|
|
it('Newly published page (page.published)', async function () {
|
|
let publishedPage = {status: 'published', ...mentionsPost};
|
|
await agent
|
|
.post('pages/')
|
|
.body({pages: [publishedPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
});
|
|
|
|
it('Edited published page without url changes (page.published.edited)', async function () {
|
|
const publishedPage = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('pages/')
|
|
.body({pages: [publishedPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
addMentionMocks();
|
|
assert.equal(mentionMock.isDone(), false, 'should be reset');
|
|
assert.equal(endpointMock.isDone(), false, 'should be reset');
|
|
|
|
const pageId = res.body.pages[0].id;
|
|
const editedPage = {
|
|
mobiledoc: markdownToMobiledoc(mentionHtml + 'More content'),
|
|
updated_at: res.body.pages[0].updated_at
|
|
};
|
|
|
|
await agent.put(`pages/${pageId}/`)
|
|
.body({pages: [editedPage]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), false);
|
|
assert.equal(mentionMock.isDone(), false);
|
|
});
|
|
|
|
it('Edited published page with url changes (page.published.edited)', async function () {
|
|
const publishedPage = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('pages/')
|
|
.body({pages: [publishedPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
addMentionMocks();
|
|
assert.equal(mentionMock.isDone(), false, 'should be reset');
|
|
assert.equal(endpointMock.isDone(), false, 'should be reset');
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl2.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml2, {'content-type': 'text/html'});
|
|
|
|
const endpointMockTwo = nock(endpointUrl2.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const pageId = res.body.pages[0].id;
|
|
const editedPage = {
|
|
...editedMentionsPost,
|
|
updated_at: res.body.pages[0].updated_at
|
|
};
|
|
|
|
await agent.put(`pages/${pageId}/`)
|
|
.body({pages: [editedPage]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
|
|
// Also send again to the deleted url
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
});
|
|
|
|
it('Unpublished page (page.unpublished)', async function () {
|
|
const publishedPage = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('pages/')
|
|
.body({pages: [publishedPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml, {'content-type': 'text/html'});
|
|
const endpointMockTwo = nock(endpointUrl.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const pageId = res.body.pages[0].id;
|
|
// moving back to draft is how we unpublish
|
|
const unpublishedPage = {
|
|
status: 'draft',
|
|
updated_at: res.body.pages[0].updated_at
|
|
};
|
|
await agent.put(`pages/${pageId}/`)
|
|
.body({pages: [unpublishedPage]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
});
|
|
|
|
it('Sends for links that got removed from a post', async function () {
|
|
const publishedPost = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml, {'content-type': 'text/html'});
|
|
|
|
const endpointMockTwo = nock(endpointUrl.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const postId = res.body.posts[0].id;
|
|
const editedPost = {
|
|
mobiledoc: markdownToMobiledoc(`mentions were removed from this post`),
|
|
updated_at: res.body.posts[0].updated_at
|
|
};
|
|
await agent.put(`posts/${postId}/`)
|
|
.body({posts: [editedPost]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
});
|
|
|
|
it('Sends for links that got removed from a page', async function () {
|
|
const publishedPage = {status: 'published', ...mentionsPost};
|
|
const res = await agent
|
|
.post('pages/')
|
|
.body({pages: [publishedPage]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
// while not the point of the test, we should have real links/mentions to start with
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
|
|
nock.cleanAll();
|
|
|
|
// reset mocks for mention
|
|
const mentionMockTwo = nock(mentionUrl.href)
|
|
.persist()
|
|
.get('/')
|
|
.reply(200, targetHtml, {'content-type': 'text/html'});
|
|
|
|
const endpointMockTwo = nock(endpointUrl.href)
|
|
.persist()
|
|
.post('/')
|
|
.reply(201);
|
|
|
|
const pageId = res.body.pages[0].id;
|
|
const editedPage = {
|
|
mobiledoc: markdownToMobiledoc(`mentions were removed from this post`),
|
|
updated_at: res.body.pages[0].updated_at
|
|
};
|
|
await agent.put(`pages/${pageId}/`)
|
|
.body({pages: [editedPage]})
|
|
.expectStatus(200);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMockTwo.isDone(), true);
|
|
assert.equal(endpointMockTwo.isDone(), true);
|
|
});
|
|
|
|
// there's no special handling for this atm, but could be down the road
|
|
it('New paid post', async function () {
|
|
const publishedPost = {status: 'published', visibility: 'paid', ...mentionsPost};
|
|
await agent
|
|
.post('posts/')
|
|
.body({posts: [publishedPost]})
|
|
.expectStatus(201);
|
|
|
|
await jobsService.allSettled();
|
|
await DomainEvents.allSettled();
|
|
|
|
assert.equal(mentionMock.isDone(), true);
|
|
assert.equal(endpointMock.isDone(), true);
|
|
});
|
|
});
|
|
});
|
|
});
|