From 681c942d8fddab4de90d712eb5e7946ed4e3b4b0 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Fri, 26 Apr 2024 12:12:10 +0300 Subject: [PATCH 01/11] Remove the createUserCtx helper --- test/functional/functional_test_helper.js | 51 ----------------------- test/functional/private_groups.js | 14 ++++--- test/functional/privates.js | 15 ++++--- 3 files changed, 17 insertions(+), 63 deletions(-) diff --git a/test/functional/functional_test_helper.js b/test/functional/functional_test_helper.js index 237b89b18..af372e33a 100644 --- a/test/functional/functional_test_helper.js +++ b/test/functional/functional_test_helper.js @@ -22,57 +22,6 @@ const apiUrl = async (relativeUrl) => { return `${app.context.config.host}${relativeUrl}`; }; -export function createUser(username, password, attributes, callback) { - return function (done) { - if (typeof attributes === 'function') { - callback = attributes; - attributes = {}; - } - - if (typeof attributes === 'undefined') { - attributes = {}; - } - - const user = { - username, - password, - }; - - if (attributes.email) { - user.email = attributes.email; - } - - apiUrl('/v1/users') - .then((url) => { - request - .post(url) - .send(user) - .end((err, res) => { - if (callback) { - const luna = res.body.users; - luna.password = user.password; - callback(res.body.authToken, luna); - } - - done(); - }); - }) - .catch((e) => { - done(e); - }); - }; -} - -export function createUserCtx(context, username, password, attrs) { - return createUser(username, password, attrs, (token, user) => { - context.user = user; - context.authToken = token; - context.username = username.toLowerCase(); - context.password = password; - context.attributes = attrs; - }); -} - export function subscribeToCtx(context, username) { return function (done) { apiUrl(`/v1/users/${username}/subscribe`) diff --git a/test/functional/private_groups.js b/test/functional/private_groups.js index 91a25f68a..8236176ad 100644 --- a/test/functional/private_groups.js +++ b/test/functional/private_groups.js @@ -177,10 +177,12 @@ describe('PrivateGroups', () => { }); describe('#update', () => { - const context = {}; + let context; let group; - beforeEach(funcTestHelper.createUserCtx(context, 'Luna', 'password')); + beforeEach(async () => { + context = await funcTestHelper.createTestUser('luna'); + }); beforeEach((done) => { request @@ -296,11 +298,11 @@ describe('PrivateGroups', () => { }); describe('#unadmin', () => { - const adminContext = {}; - const nonAdminContext = {}; + let adminContext; - beforeEach(funcTestHelper.createUserCtx(adminContext, 'Luna', 'password')); - beforeEach(funcTestHelper.createUserCtx(nonAdminContext, 'yole', 'wordpass')); + beforeEach(async () => { + [adminContext] = await funcTestHelper.createTestUsers(['luna', 'yole']); + }); beforeEach((done) => { request diff --git a/test/functional/privates.js b/test/functional/privates.js index 63219fc4b..6c43f52ea 100644 --- a/test/functional/privates.js +++ b/test/functional/privates.js @@ -1155,13 +1155,16 @@ describe('Privates', () => { }); describe('Checking, that private posts are correctly propagated', () => { - const lunaContext = {}; - const marsContext = {}; - const zeusContext = {}; + let lunaContext, marsContext, zeusContext; + + beforeEach(async () => { + [lunaContext, marsContext, zeusContext] = await funcTestHelper.createTestUsers([ + 'luna', + 'mars', + 'zeus', + ]); + }); - beforeEach(funcTestHelper.createUserCtx(lunaContext, 'luna', 'pw')); - beforeEach(funcTestHelper.createUserCtx(marsContext, 'mars', 'pw')); - beforeEach(funcTestHelper.createUserCtx(zeusContext, 'zeus', 'pw')); beforeEach(() => funcTestHelper.mutualSubscriptions([lunaContext, marsContext, zeusContext])); beforeEach(() => funcTestHelper.goPrivate(lunaContext)); From e043e43a0388f48369a62073cdf28e230328e4e2 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Fri, 26 Apr 2024 12:13:49 +0300 Subject: [PATCH 02/11] Use models' methods in mutualSubscriptions and subscribeToAsync helpers These methods are a way faster than HTTP-requests --- test/functional/functional_test_helper.js | 13 ++++++++++--- test/functional/privates.js | 10 +++++----- test/functional/timelines-rss.js | 2 +- test/functional/timelinesV2.js | 16 ++++++++-------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/test/functional/functional_test_helper.js b/test/functional/functional_test_helper.js index af372e33a..aadbf796a 100644 --- a/test/functional/functional_test_helper.js +++ b/test/functional/functional_test_helper.js @@ -542,8 +542,15 @@ export function groupToProtected(group, userContext) { return updateGroupAsync(group, userContext, { isPrivate: '0', isProtected: '1' }); } -export function subscribeToAsync(subscriber, victim) { - return postJson(`/v1/users/${victim.username}/subscribe`, { authToken: subscriber.authToken }); +export async function subscribeToAsync(subscriber, victim) { + let victimObj = victim.user; + + if (!victimObj) { + // Group or old-fashion user context + victimObj = await dbAdapter.getFeedOwnerById(victim.id ?? victim.group.id); + } + + await subscriber.user.subscribeTo(victimObj); } export function unsubscribeFromAsync(unsubscriber, victim) { @@ -577,7 +584,7 @@ export async function mutualSubscriptions(userContexts) { continue; } - promises.push(subscribeToAsync(ctx1, ctx2)); + promises.push(ctx1.user.subscribeTo(ctx2.user)); } } diff --git a/test/functional/privates.js b/test/functional/privates.js index 6c43f52ea..4f38ef8af 100644 --- a/test/functional/privates.js +++ b/test/functional/privates.js @@ -35,15 +35,15 @@ describe('Privates', () => { }); describe('publish private post to public feed', () => { - const group = 'group'; + let group; beforeEach(async () => { - await Promise.all([ + [, group] = await Promise.all([ funcTestHelper.mutualSubscriptions([marsContext, lunaContext]), - funcTestHelper.createGroupAsync(lunaContext, group), + funcTestHelper.createGroupAsync(lunaContext, 'group'), ]); - await funcTestHelper.subscribeToAsync(zeusContext, { username: group }); + await funcTestHelper.subscribeToAsync(zeusContext, group); }); it('should send private post to public feed', (done) => { @@ -52,7 +52,7 @@ describe('Privates', () => { .post(`${app.context.config.host}/v1/posts`) .send({ post: { body: post }, - meta: { feeds: [group, lunaContext.user.username] }, + meta: { feeds: [group.username, lunaContext.user.username] }, authToken: lunaContext.authToken, }) .end(() => { diff --git a/test/functional/timelines-rss.js b/test/functional/timelines-rss.js index d01b2eabd..0640ec07e 100644 --- a/test/functional/timelines-rss.js +++ b/test/functional/timelines-rss.js @@ -233,7 +233,7 @@ describe('TimelinesAsRSS', () => { createUserAsync('mars', 'pw'), ]); celestials = await createGroupAsync(luna, 'celestials', 'Celestials'); - await subscribeToAsync(mars, { username: 'celestials' }); + await subscribeToAsync(mars, celestials); post1 = await createAndReturnPostToFeed(celestials, luna, 'Luna post'); post2 = await createAndReturnPostToFeed(celestials, mars, 'Mars post'); }); diff --git a/test/functional/timelinesV2.js b/test/functional/timelinesV2.js index 8a3e81d90..a413208d4 100644 --- a/test/functional/timelinesV2.js +++ b/test/functional/timelinesV2.js @@ -311,12 +311,12 @@ describe('TimelinesControllerV2', () => { }); describe('Luna subscribed to Selenites group and not subscribed to Celestials group', () => { - let selenitesPost, celestialsPost; + let selenitesPost, celestialsPost, celestials; beforeEach(async () => { - await createGroupAsync(venus, 'selenites'); - await createGroupAsync(venus, 'celestials'); - await subscribeToAsync(luna, { username: 'selenites' }); + const selenites = await createGroupAsync(venus, 'selenites'); + celestials = await createGroupAsync(venus, 'celestials'); + await subscribeToAsync(luna, selenites); selenitesPost = await createAndReturnPostToFeed( { username: 'selenites' }, @@ -348,7 +348,7 @@ describe('TimelinesControllerV2', () => { }); it('should return timeline with Mars posts from Celestials group in "friends-all-activity" mode', async () => { - await subscribeToAsync(mars, { username: 'celestials' }); + await subscribeToAsync(mars, celestials); const marsCelestialsPost = await createAndReturnPostToFeed( { username: 'celestials' }, mars, @@ -367,9 +367,9 @@ describe('TimelinesControllerV2', () => { beforeEach(async () => { mars = await createUserAsync('mars', 'pw'); venus = await createUserAsync('venus', 'pw'); - await createGroupAsync(venus, 'selenites'); - await subscribeToAsync(luna, { username: 'selenites' }); - await subscribeToAsync(mars, { username: 'selenites' }); + const selenites = await createGroupAsync(venus, 'selenites'); + await subscribeToAsync(luna, selenites); + await subscribeToAsync(mars, selenites); await banUser(mars, luna); }); From c52a410f4df2aa6e17a4aa153fc282d88294ae3d Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sat, 27 Apr 2024 10:37:21 +0300 Subject: [PATCH 03/11] Add just* function helpers for the faster tests setup The just* functions create objects using the model API (without HTTP requests) and without any checks. Use them to speed up test setup (for example, in beforeEach) when object creation is not the purpose of the test. --- test/functional/functional_test_helper.d.ts | 24 +++++++++- test/functional/functional_test_helper.js | 49 +++++++++++++++++++-- 2 files changed, 68 insertions(+), 5 deletions(-) diff --git a/test/functional/functional_test_helper.d.ts b/test/functional/functional_test_helper.d.ts index edb21e4a4..2d0dd847b 100644 --- a/test/functional/functional_test_helper.d.ts +++ b/test/functional/functional_test_helper.d.ts @@ -1,4 +1,5 @@ -import { User } from '../../app/models'; +import { Comment, Group, Post, User } from '../../app/models'; +import { UUID } from '../../app/support/types'; export type UserCtx = { authToken: string; @@ -28,3 +29,24 @@ export function authHeaders(userCtx: Pick | null): { }; export function cmpBy(key: keyof T): (a: T, b: T) => number; + +export function justCreatePost( + authorCtx: UserCtx, + body: string, + destNames?: string[], +): Promise; + +export function justCreateComment(authorCtx: UserCtx, postId: UUID, body: string): Promise; + +export function justCreateGroup( + creatorCtx: UserCtx, + username: string, + screenName?: string, + opts?: { + isPrivate?: boolean; + isProtected?: boolean; + isRestricted?: boolean; + }, +): Promise; + +export function justLikeComment(commentObj: Comment, userCtx: UserCtx): Promise; diff --git a/test/functional/functional_test_helper.js b/test/functional/functional_test_helper.js index aadbf796a..22400d29a 100644 --- a/test/functional/functional_test_helper.js +++ b/test/functional/functional_test_helper.js @@ -10,10 +10,11 @@ import socketIO from 'socket.io-client'; import expect from 'unexpected'; import Application from 'koa'; -import { dbAdapter, sessionTokenV1Store, User } from '../../app/models'; +import { dbAdapter, sessionTokenV1Store, User, Group } from '../../app/models'; import { getSingleton as initApp } from '../../app/app'; import { addMailListener } from '../../lib/mailer'; import { API_VERSION_ACTUAL } from '../../app/api-versions'; +import { createPost as iCreatePost } from '../integration/helpers/posts-and-comments'; import * as schema from './schemaV2-helper'; @@ -109,6 +110,42 @@ export async function getSummary(context, params = {}) { return await response.json(); } +// The just* functions create objects using the model API (without HTTP +// requests) and without any checks. Use them to speed up test setup (for +// example, in beforeEach) when object creation is not the purpose of the test. + +export async function justCreatePost(authorCtx, body, destNames = [authorCtx.username]) { + const destAccounts = await dbAdapter.getFeedOwnersByUsernames(destNames); + return await iCreatePost(authorCtx.user, body, destAccounts); +} + +export async function justCreateComment(authorCtx, postId, body) { + const comment = authorCtx.user.newComment({ body, postId }); + await comment.create(); + return comment; +} + +export async function justCreateGroup( + creatorCtx, + username, + screenName = username, + { isPrivate = false, isProtected = isPrivate, isRestricted = false } = {}, +) { + const g = new Group({ + username, + screenName, + isPrivate: isPrivate ? '1' : '0', + isProtected: isProtected ? '1' : '0', + isRestricted: isRestricted ? '1' : '0', + }); + await g.create(creatorCtx.user.id); + return g; +} + +export async function justLikeComment(commentObj, userCtx) { + await commentObj.addLike(userCtx.user); +} + export function createPost(context, body, callback) { return function (done) { apiUrl('/v1/posts') @@ -543,10 +580,14 @@ export function groupToProtected(group, userContext) { } export async function subscribeToAsync(subscriber, victim) { - let victimObj = victim.user; + let victimObj; - if (!victimObj) { - // Group or old-fashion user context + if (victim instanceof User) { + victimObj = victim; + } else if (victim.user) { + victimObj = victim.user; + } else { + // Old-fashion group or user context victimObj = await dbAdapter.getFeedOwnerById(victim.id ?? victim.group.id); } From 52d78a321ef398fdf26d8e72f7e6ac66ada56f01 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sat, 27 Apr 2024 13:25:21 +0300 Subject: [PATCH 04/11] Use faster setup functions in some functional tests --- test/functional/backlinks.js | 30 +- test/functional/comment_likes.js | 446 ++++++++++----------- test/functional/comments.js | 81 ++-- test/functional/events.js | 121 +++--- test/functional/local-bumps.js | 6 +- test/functional/posts/edit-destinations.js | 12 +- test/functional/posts/leave-direct.js | 18 +- test/functional/posts/posts.js | 47 ++- test/functional/posts/postsV2.js | 38 +- test/functional/private_groups.js | 134 ++----- test/functional/timelinesV2.js | 50 +-- 11 files changed, 450 insertions(+), 533 deletions(-) diff --git a/test/functional/backlinks.js b/test/functional/backlinks.js index 3bb8a1c79..214641767 100644 --- a/test/functional/backlinks.js +++ b/test/functional/backlinks.js @@ -9,12 +9,12 @@ import { PubSubAdapter } from '../../app/support/PubSubAdapter'; import { authHeaders, - createAndReturnPost, createCommentAsync, createTestUsers, deletePostAsync, goPrivate, goPublic, + justCreatePost, performJSONRequest, removeCommentAsync, updateCommentAsync, @@ -30,11 +30,10 @@ describe('Backlinks in API output', () => { await cleanDB($pg_database); [luna, mars] = await createTestUsers(['luna', 'mars']); - ({ id: lunaPostId, shortId: lunaPostShortId } = await createAndReturnPost(luna, 'Luna post')); - ({ id: marsPostId } = await createAndReturnPost( - mars, - `As Luna said, example.com/${lunaPostId}`, - )); + const lunaPost = await justCreatePost(luna, 'Luna post'); + lunaPostId = lunaPost.id; + lunaPostShortId = await lunaPost.getShortId(); + ({ id: marsPostId } = await justCreatePost(mars, `As Luna said, example.com/${lunaPostId}`)); }); it(`should return Luna post with 1 backlink`, async () => { @@ -104,7 +103,7 @@ describe('Backlinks in API output', () => { describe('Counting backlinks in posts and comments', () => { before(async () => { - mars.post = await createAndReturnPost(mars, `As Luna said, example.com/${lunaPostId}`); + mars.post = await justCreatePost(mars, `As Luna said, example.com/${lunaPostId}`); }); after(() => deletePostAsync(mars, mars.post.id)); @@ -147,7 +146,8 @@ describe('Backlinks in realtime', () => { await lunaSession.sendAsync('subscribe', { timeline: [lunaTimeline.id] }); // Luna created post - luna.post = await createAndReturnPost(luna, 'Luna post'); + luna.post = await justCreatePost(luna, 'Luna post'); + luna.post.shortId = await luna.post.getShortId(); }); describe('Mars is public', () => { @@ -155,10 +155,7 @@ describe('Backlinks in realtime', () => { const test = lunaSession.receiveWhile( 'post:update', async () => - (mars.post = await createAndReturnPost( - mars, - `As Luna said, example.com/${luna.post.id}`, - )), + (mars.post = await justCreatePost(mars, `As Luna said, example.com/${luna.post.id}`)), ); await expect(test, 'when fulfilled', 'to satisfy', { posts: { id: luna.post.id, backlinksCount: 1 }, @@ -205,7 +202,7 @@ describe('Backlinks in realtime', () => { const test = lunaSession.receiveWhile( 'post:update', async () => - (mars.post = await createAndReturnPost(mars, `As Luna said, /luna/${luna.post.shortId}`)), + (mars.post = await justCreatePost(mars, `As Luna said, /luna/${luna.post.shortId}`)), ); await expect(test, 'when fulfilled', 'to satisfy', { posts: { id: luna.post.id, backlinksCount: 1 }, @@ -255,10 +252,7 @@ describe('Backlinks in realtime', () => { const test = lunaSession.notReceiveWhile( 'post:update', async () => - (mars.post = await createAndReturnPost( - mars, - `As Luna said, example.com/${luna.post.id}`, - )), + (mars.post = await justCreatePost(mars, `As Luna said, example.com/${luna.post.id}`)), ); await expect(test, 'to be fulfilled'); }); @@ -293,7 +287,7 @@ describe('Backlinks in realtime', () => { }); describe('Backlinks in comments', () => { - before(async () => (mars.post = await createAndReturnPost(mars, `Just a post`))); + before(async () => (mars.post = await justCreatePost(mars, `Just a post`))); after(() => deletePostAsync(mars, mars.post.id)); describe('Mars is public', () => { diff --git a/test/functional/comment_likes.js b/test/functional/comment_likes.js index 6287a4235..c46cd9362 100644 --- a/test/functional/comment_likes.js +++ b/test/functional/comment_likes.js @@ -13,10 +13,7 @@ import { acceptRequestToJoinGroup, banUser, createAndReturnPost, - createAndReturnPostToFeed, - createCommentAsync, likeComment, - createGroupAsync, createUserAsync, unlikeComment, getCommentLikes, @@ -25,6 +22,12 @@ import { sendRequestToJoinGroup, performSearch, updateUserAsync, + createTestUsers, + justCreatePost, + createTestUser, + justCreateComment, + justCreateGroup, + justLikeComment, } from './functional_test_helper'; import * as schema from './schemaV2-helper'; @@ -32,11 +35,10 @@ const expect = unexpected.clone().use(schema.freefeedAssertions); describe('Comment likes', () => { let app; - let writeComment, getPost, getFeed; + let getPost, getFeed; before(async () => { app = await getSingleton(); - writeComment = createComment(); getPost = fetchPost(app); getFeed = fetchTimeline(app); PubSub.setPublisher(new DummyPublisher()); @@ -57,14 +59,10 @@ describe('Comment likes', () => { let lunaPost, marsPost; beforeEach(async () => { - [luna, mars, jupiter] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - ]); + [luna, mars, jupiter] = await createTestUsers(['luna', 'mars', 'jupiter']); [lunaPost, marsPost] = await Promise.all([ - createAndReturnPost(luna, 'Luna post'), - createAndReturnPost(mars, 'Mars post'), + justCreatePost(luna, 'Luna post'), + justCreatePost(mars, 'Mars post'), ]); await mutualSubscriptions([luna, mars]); }); @@ -75,37 +73,37 @@ describe('Comment likes', () => { }); it('should not allow to like own comments to own post', async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); const res = await likeComment(lunaComment.id, luna); expect(res, 'to be an API error', 403, "You can't like your own comment"); }); it('should not allow to like own comments to other user post', async () => { - const lunaComment = await writeComment(luna, marsPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, marsPost.id, 'Luna comment'); const res = await likeComment(lunaComment.id, luna); expect(res, 'to be an API error', 403, "You can't like your own comment"); }); it("should allow Luna to like Mars' comment to Luna's post", async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, luna); expect(res, 'to have 1 like by', luna); }); it("should allow Luna to like Mars' comment to Mars' post", async () => { - const marsComment = await writeComment(mars, marsPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, marsPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, luna); expect(res, 'to have 1 like by', luna); }); it("should allow Jupiter to like Mars' comment to Luna's post", async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, jupiter); expect(res, 'to have 1 like by', jupiter); }); it('should not allow to like comment more than one time', async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); const res1 = await likeComment(marsComment.id, luna); expect(res1.status, 'to be', 200); @@ -122,11 +120,11 @@ describe('Comment likes', () => { let pluto; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); + pluto = await createTestUser('pluto'); }); it('should sort comment likes chronologically descending (except viewer)', async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); let res = await likeComment(lunaComment.id, mars); expect(res, 'to have 1 like by', mars); await likeComment(lunaComment.id, jupiter); @@ -151,50 +149,58 @@ describe('Comment likes', () => { let plutoPost; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); - plutoPost = await createAndReturnPost(pluto, 'Pluto post'); + pluto = await createTestUser('pluto'); + plutoPost = await justCreatePost(pluto, 'Pluto post'); await Promise.all([banUser(luna, mars), banUser(luna, pluto)]); }); it("should not allow Luna to like Mars' comment to Mars' post", async () => { - const marsComment = await writeComment(mars, marsPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, marsPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Luna to like Pluto's comment to Pluto's post", async () => { - const plutoComment = await writeComment(pluto, plutoPost.id, 'Pluto comment'); + const plutoComment = await justCreateComment(pluto, plutoPost.id, 'Pluto comment'); const res = await likeComment(plutoComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Luna to like Pluto's comment to Mars' post", async () => { - const plutoComment = await writeComment(pluto, marsPost.id, 'Pluto comment'); + const plutoComment = await justCreateComment(pluto, marsPost.id, 'Pluto comment'); const res = await likeComment(plutoComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Mars to like Luna's comment to Luna's post", async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); const res = await likeComment(lunaComment.id, mars); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Pluto to like Luna's comment to Luna's post", async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); const res = await likeComment(lunaComment.id, pluto); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Pluto to like Jupiter's comment to Luna's post", async () => { - const jupiterComment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); + const jupiterComment = await justCreateComment( + jupiter, + lunaPost.id, + 'Jupiter comment', + ); const res = await likeComment(jupiterComment.id, pluto); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it('should not display Luna comment likes of Pluto and Mars', async () => { - const jupiterPost = await createAndReturnPost(jupiter, 'Jupiter post'); - const jupiterComment = await writeComment(jupiter, jupiterPost.id, 'Jupiter comment'); + const jupiterPost = await justCreatePost(jupiter, 'Jupiter post'); + const jupiterComment = await justCreateComment( + jupiter, + jupiterPost.id, + 'Jupiter comment', + ); let res = await likeComment(jupiterComment.id, pluto); expect(res, 'to have 1 like by', pluto); await likeComment(jupiterComment.id, mars); @@ -208,56 +214,60 @@ describe('Comment likes', () => { let dubhePost, merakPost, phadPost, alkaidPost; beforeEach(async () => { [dubhe, merak, phad, alkaid] = await Promise.all([ - createGroupAsync(luna, 'dubhe', 'Dubhe', false, false), - createGroupAsync(luna, 'merak', 'Merak', false, true), - createGroupAsync(luna, 'phad', 'Phad', true, false), - createGroupAsync(luna, 'alkaid', 'Alkaid', true, true), + justCreateGroup(luna, 'dubhe', 'Dubhe'), + justCreateGroup(luna, 'merak', 'Merak', { isRestricted: true }), + justCreateGroup(luna, 'phad', 'Phad', { isPrivate: true }), + justCreateGroup(luna, 'alkaid', 'Alkaid', { isPrivate: true, isRestricted: true }), ]); [dubhePost, merakPost, phadPost, alkaidPost] = await Promise.all([ - createAndReturnPostToFeed(dubhe, luna, 'Dubhe post'), - createAndReturnPostToFeed(merak, luna, 'Merak post'), - createAndReturnPostToFeed(phad, luna, 'Phad post'), - createAndReturnPostToFeed(alkaid, luna, 'Alkaid post'), + justCreatePost(luna, 'Dubhe post', [dubhe.username]), + justCreatePost(luna, 'Merak post', [merak.username]), + justCreatePost(luna, 'Phad post', [phad.username]), + justCreatePost(luna, 'Alkaid post', [alkaid.username]), + ]); + await Promise.all([ + sendRequestToJoinGroup(mars, phad), + sendRequestToJoinGroup(mars, alkaid), + ]); + await Promise.all([ + acceptRequestToJoinGroup(luna, mars, phad), + acceptRequestToJoinGroup(luna, mars, alkaid), ]); - await sendRequestToJoinGroup(mars, phad); - await acceptRequestToJoinGroup(luna, mars, phad); - await sendRequestToJoinGroup(mars, alkaid); - await acceptRequestToJoinGroup(luna, mars, alkaid); }); it('should allow any user to like comment in a public group', async () => { - const marsComment = await writeComment(mars, dubhePost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, dubhePost.id, 'Mars comment'); const res = await likeComment(marsComment.id, jupiter); expect(res, 'to have 1 like by', jupiter); }); it('should allow any user to like comment in a public restricted group', async () => { - const marsComment = await writeComment(mars, merakPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, merakPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, jupiter); expect(res, 'to have 1 like by', jupiter); }); it('should allow members to like comment in a private group', async () => { - const marsComment = await writeComment(mars, phadPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, phadPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, luna); expect(res, 'to have 1 like by', luna); }); it('should not allow non-members to like comment in a private group', async () => { - const marsComment = await writeComment(mars, phadPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, phadPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, jupiter); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it('should allow members to like comment in a private restricted group', async () => { - const marsComment = await writeComment(mars, alkaidPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, alkaidPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, luna); expect(res, 'to have 1 like by', luna); }); it('should not allow non-members to like comment in a private restricted group', async () => { - const marsComment = await writeComment(mars, alkaidPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, alkaidPost.id, 'Mars comment'); const res = await likeComment(marsComment.id, jupiter); expect(res, 'to be an API error', 403, 'You can not see this post'); }); @@ -278,14 +288,10 @@ describe('Comment likes', () => { let lunaPost, marsPost; beforeEach(async () => { - [luna, mars, jupiter] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - ]); + [luna, mars, jupiter] = await createTestUsers(['luna', 'mars', 'jupiter']); [lunaPost, marsPost] = await Promise.all([ - createAndReturnPost(luna, 'Luna post'), - createAndReturnPost(mars, 'Mars post'), + justCreatePost(luna, 'Luna post'), + justCreatePost(mars, 'Mars post'), ]); await mutualSubscriptions([luna, mars]); }); @@ -296,40 +302,40 @@ describe('Comment likes', () => { }); it('should not allow to unlike own comments to own post', async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); const res = await unlikeComment(lunaComment.id, luna); expect(res, 'to be an API error', 403, "You can't un-like your own comment"); }); it('should not allow to unlike own comments to other user post', async () => { - const lunaComment = await writeComment(luna, marsPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, marsPost.id, 'Luna comment'); const res = await unlikeComment(lunaComment.id, luna); expect(res, 'to be an API error', 403, "You can't un-like your own comment"); }); it("should allow Luna to unlike Mars' comment to Luna's post", async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); await likeComment(marsComment.id, luna); const res = await unlikeComment(marsComment.id, luna); expect(res, 'to have no likes'); }); it("should allow Luna to unlike Mars' comment to Mars' post", async () => { - const marsComment = await writeComment(mars, marsPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, marsPost.id, 'Mars comment'); await likeComment(marsComment.id, luna); const res = await unlikeComment(marsComment.id, luna); expect(res, 'to have no likes'); }); it("should allow Jupiter to unlike Mars' comment to Luna's post", async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); await likeComment(marsComment.id, jupiter); const res = await unlikeComment(marsComment.id, jupiter); expect(res, 'to have no likes'); }); it("should not allow to unlike comment that haven't been liked", async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); const res = await unlikeComment(marsComment.id, luna); expect( res, @@ -340,7 +346,7 @@ describe('Comment likes', () => { }); it('should not allow to unlike comment more than one time', async () => { - const marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, lunaPost.id, 'Mars comment'); await likeComment(marsComment.id, luna); const res1 = await unlikeComment(marsComment.id, luna); expect(res1, 'to have no likes'); @@ -358,11 +364,11 @@ describe('Comment likes', () => { let pluto; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); + pluto = await createTestUser('pluto'); }); it('should sort comment likes chronologically descending', async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); await likeComment(lunaComment.id, mars); await likeComment(lunaComment.id, jupiter); await likeComment(lunaComment.id, pluto); @@ -386,53 +392,61 @@ describe('Comment likes', () => { let plutoPost; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); - plutoPost = await createAndReturnPost(pluto, 'Pluto post'); + pluto = await createTestUser('pluto'); + plutoPost = await justCreatePost(pluto, 'Pluto post'); await Promise.all([banUser(luna, mars), banUser(luna, pluto)]); }); it("should not allow Luna to unlike Mars' comment to Mars' post", async () => { - const marsComment = await writeComment(mars, marsPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, marsPost.id, 'Mars comment'); const res = await unlikeComment(marsComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Luna to unlike Pluto's comment to Pluto's post", async () => { - const plutoComment = await writeComment(pluto, plutoPost.id, 'Pluto comment'); + const plutoComment = await justCreateComment(pluto, plutoPost.id, 'Pluto comment'); const res = await unlikeComment(plutoComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Luna to unlike Pluto's comment to Mars' post", async () => { - const plutoComment = await writeComment(pluto, marsPost.id, 'Pluto comment'); + const plutoComment = await justCreateComment(pluto, marsPost.id, 'Pluto comment'); const res = await unlikeComment(plutoComment.id, luna); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Mars to unlike Luna's comment to Luna's post", async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); await likeComment(lunaComment.id, mars); const res = await unlikeComment(lunaComment.id, mars); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Pluto to unlike Luna's comment to Luna's post", async () => { - const lunaComment = await writeComment(luna, lunaPost.id, 'Luna comment'); + const lunaComment = await justCreateComment(luna, lunaPost.id, 'Luna comment'); await likeComment(lunaComment.id, pluto); const res = await unlikeComment(lunaComment.id, pluto); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it("should not allow Pluto to unlike Jupiter's comment to Luna's post", async () => { - const jupiterComment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); + const jupiterComment = await justCreateComment( + jupiter, + lunaPost.id, + 'Jupiter comment', + ); await likeComment(jupiterComment.id, pluto); const res = await unlikeComment(jupiterComment.id, pluto); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it('should not display Luna comment likes of Pluto and Mars', async () => { - const jupiterPost = await createAndReturnPost(jupiter, 'Jupiter post'); - const jupiterComment = await writeComment(jupiter, jupiterPost.id, 'Jupiter comment'); + const jupiterPost = await justCreatePost(jupiter, 'Jupiter post'); + const jupiterComment = await justCreateComment( + jupiter, + jupiterPost.id, + 'Jupiter comment', + ); await likeComment(jupiterComment.id, pluto); await likeComment(jupiterComment.id, mars); await likeComment(jupiterComment.id, luna); @@ -442,8 +456,8 @@ describe('Comment likes', () => { describe('when Luna bans Jupiter after liking his comment', () => { it("should not allow Luna to unlike Jupiter's comment to Jupiter's post", async () => { - const jupiterPost = await createAndReturnPost(jupiter, 'Jupiter post'); - const jupiterComment = await writeComment( + const jupiterPost = await justCreatePost(jupiter, 'Jupiter post'); + const jupiterComment = await justCreateComment( jupiter, jupiterPost.id, 'Jupiter comment', @@ -463,60 +477,65 @@ describe('Comment likes', () => { let dubhePost, merakPost, phadPost, alkaidPost; beforeEach(async () => { [dubhe, merak, phad, alkaid] = await Promise.all([ - createGroupAsync(luna, 'dubhe', 'Dubhe', false, false), - createGroupAsync(luna, 'merak', 'Merak', false, true), - createGroupAsync(luna, 'phad', 'Phad', true, false), - createGroupAsync(luna, 'alkaid', 'Alkaid', true, true), + justCreateGroup(luna, 'dubhe', 'Dubhe'), + justCreateGroup(luna, 'merak', 'Merak', { isRestricted: true }), + justCreateGroup(luna, 'phad', 'Phad', { isPrivate: true }), + justCreateGroup(luna, 'alkaid', 'Alkaid', { isPrivate: true, isRestricted: true }), ]); [dubhePost, merakPost, phadPost, alkaidPost] = await Promise.all([ - createAndReturnPostToFeed(dubhe, luna, 'Dubhe post'), - createAndReturnPostToFeed(merak, luna, 'Merak post'), - createAndReturnPostToFeed(phad, luna, 'Phad post'), - createAndReturnPostToFeed(alkaid, luna, 'Alkaid post'), + justCreatePost(luna, 'Dubhe post', [dubhe.username]), + justCreatePost(luna, 'Merak post', [merak.username]), + justCreatePost(luna, 'Phad post', [phad.username]), + justCreatePost(luna, 'Alkaid post', [alkaid.username]), + ]); + + await Promise.all([ + sendRequestToJoinGroup(mars, phad), + sendRequestToJoinGroup(mars, alkaid), + ]); + await Promise.all([ + acceptRequestToJoinGroup(luna, mars, phad), + acceptRequestToJoinGroup(luna, mars, alkaid), ]); - await sendRequestToJoinGroup(mars, phad); - await acceptRequestToJoinGroup(luna, mars, phad); - await sendRequestToJoinGroup(mars, alkaid); - await acceptRequestToJoinGroup(luna, mars, alkaid); }); it('should allow any user to unlike comment in a public group', async () => { - const marsComment = await writeComment(mars, dubhePost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, dubhePost.id, 'Mars comment'); await likeComment(marsComment.id, jupiter); const res = await unlikeComment(marsComment.id, jupiter); expect(res, 'to have no likes'); }); it('should allow any user to unlike comment in a public restricted group', async () => { - const marsComment = await writeComment(mars, merakPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, merakPost.id, 'Mars comment'); await likeComment(marsComment.id, jupiter); const res = await unlikeComment(marsComment.id, jupiter); expect(res, 'to have no likes'); }); it('should allow members to unlike comment in a private group', async () => { - const marsComment = await writeComment(mars, phadPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, phadPost.id, 'Mars comment'); await likeComment(marsComment.id, luna); const res = await unlikeComment(marsComment.id, luna); expect(res, 'to have no likes'); }); it('should not allow non-members to unlike comment in a private group', async () => { - const marsComment = await writeComment(mars, phadPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, phadPost.id, 'Mars comment'); const res = await unlikeComment(marsComment.id, jupiter); expect(res, 'to be an API error', 403, 'You can not see this post'); }); it('should allow members to unlike comment in a private restricted group', async () => { - const marsComment = await writeComment(mars, alkaidPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, alkaidPost.id, 'Mars comment'); await likeComment(marsComment.id, luna); const res = await unlikeComment(marsComment.id, luna); expect(res, 'to have no likes'); }); it('should not allow non-members to unlike comment in a private restricted group', async () => { - const marsComment = await writeComment(mars, alkaidPost.id, 'Mars comment'); + const marsComment = await justCreateComment(mars, alkaidPost.id, 'Mars comment'); const res = await unlikeComment(marsComment.id, jupiter); expect(res, 'to be an API error', 403, 'You can not see this post'); }); @@ -531,19 +550,17 @@ describe('Comment likes', () => { let marsComment, lunaComment; beforeEach(async () => { - [luna, mars, jupiter] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - ]); + [luna, mars, jupiter] = await createTestUsers(['luna', 'mars', 'jupiter']); [lunaPost, marsPost] = await Promise.all([ - createAndReturnPost(luna, 'Luna post'), - createAndReturnPost(mars, 'Mars post'), + justCreatePost(luna, 'Luna post'), + justCreatePost(mars, 'Mars post'), ]); await mutualSubscriptions([luna, mars]); - marsComment = await writeComment(mars, lunaPost.id, 'Mars comment'); - lunaComment = await writeComment(luna, marsPost.id, 'Luna comment'); - await likeComment(marsComment.id, luna); + [marsComment, lunaComment] = await Promise.all([ + justCreateComment(mars, lunaPost.id, 'Mars comment'), + justCreateComment(luna, marsPost.id, 'Luna comment'), + ]); + await justLikeComment(marsComment, luna); }); it('should not allow to show likes of nonexisting comment', async () => { @@ -615,9 +632,9 @@ describe('Comment likes', () => { let pluto; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); - await likeComment(marsComment.id, jupiter); - await likeComment(marsComment.id, pluto); + pluto = await createTestUser('pluto'); + await justLikeComment(marsComment, jupiter); + await justLikeComment(marsComment, pluto); }); it('should sort comment likes chronologically descending (except viewer)', async () => { @@ -670,12 +687,12 @@ describe('Comment likes', () => { let pluto, plutoPost, plutoComment, jupiterComment; beforeEach(async () => { - pluto = await createUserAsync('pluto', 'pw'); - plutoPost = await createAndReturnPost(pluto, 'Pluto post'); - plutoComment = await writeComment(pluto, plutoPost.id, 'Pluto comment'); - jupiterComment = await writeComment(jupiter, plutoPost.id, 'Jupiter comment'); - await likeComment(plutoComment.id, jupiter); - await likeComment(jupiterComment.id, pluto); + pluto = await createTestUser('pluto'); + plutoPost = await justCreatePost(pluto, 'Pluto post'); + plutoComment = await justCreateComment(pluto, plutoPost.id, 'Pluto comment'); + jupiterComment = await justCreateComment(jupiter, plutoPost.id, 'Jupiter comment'); + await justLikeComment(plutoComment, jupiter); + await justLikeComment(jupiterComment, pluto); await Promise.all([banUser(luna, mars), banUser(luna, pluto)]); }); @@ -710,8 +727,12 @@ describe('Comment likes', () => { }); it('should not display Luna comment likes of Pluto and Mars', async () => { - const jupiterPost = await createAndReturnPost(jupiter, 'Jupiter post'); - const jupiterComment2 = await writeComment(jupiter, jupiterPost.id, 'Jupiter comment'); + const jupiterPost = await justCreatePost(jupiter, 'Jupiter post'); + const jupiterComment2 = await justCreateComment( + jupiter, + jupiterPost.id, + 'Jupiter comment', + ); await likeComment(jupiterComment2.id, pluto); await likeComment(jupiterComment2.id, mars); @@ -766,13 +787,8 @@ describe('Comment likes', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); - lunaPost = await createAndReturnPost(luna, 'Luna post'); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); + lunaPost = await justCreatePost(luna, 'Luna post'); await mutualSubscriptions([luna, mars]); }); @@ -796,10 +812,10 @@ describe('Comment likes', () => { describe('should contain actual comment likes count for post with', () => { describe('1 comment', () => { beforeEach(async () => { - const comment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - await likeComment(comment.id, pluto); - await likeComment(comment.id, mars); - await likeComment(comment.id, luna); + const comment = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + await justLikeComment(comment, pluto); + await justLikeComment(comment, mars); + await justLikeComment(comment, luna); }); it('for anonymous user', async () => @@ -812,13 +828,13 @@ describe('Comment likes', () => { describe('2 comments', () => { beforeEach(async () => { - const comment1 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - const comment2 = await writeComment(luna, lunaPost.id, 'Luna comment'); - await likeComment(comment1.id, pluto); - await likeComment(comment1.id, mars); - await likeComment(comment1.id, luna); - await likeComment(comment2.id, pluto); - await likeComment(comment2.id, mars); + const comment1 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + const comment2 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + await justLikeComment(comment1, pluto); + await justLikeComment(comment1, mars); + await justLikeComment(comment1, luna); + await justLikeComment(comment2, pluto); + await justLikeComment(comment2, mars); }); it('for anonymous user', async () => @@ -833,14 +849,14 @@ describe('Comment likes', () => { describe('3 comments', () => { beforeEach(async () => { - const comment1 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - await writeComment(luna, lunaPost.id, 'Luna comment'); - const comment3 = await writeComment(mars, lunaPost.id, 'Mars comment'); - await likeComment(comment1.id, pluto); - await likeComment(comment1.id, mars); - await likeComment(comment1.id, luna); - await likeComment(comment3.id, pluto); - await likeComment(comment3.id, luna); + const comment1 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + await justCreateComment(luna, lunaPost.id, 'Luna comment'); + const comment3 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + await justLikeComment(comment1, pluto); + await justLikeComment(comment1, mars); + await justLikeComment(comment1, luna); + await justLikeComment(comment3, pluto); + await justLikeComment(comment3, luna); }); it('for anonymous user', async () => @@ -857,14 +873,14 @@ describe('Comment likes', () => { describe('4 comments', () => { beforeEach(async () => { - const comment1 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - const comment2 = await writeComment(luna, lunaPost.id, 'Luna comment'); - const comment3 = await writeComment(mars, lunaPost.id, 'Mars comment'); - const comment4 = await writeComment(mars, lunaPost.id, 'Mars comment'); - await likeComment(comment1.id, pluto); - await likeComment(comment2.id, mars); - await likeComment(comment3.id, jupiter); - await likeComment(comment4.id, luna); + const comment1 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + const comment2 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + const comment3 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + const comment4 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + await justLikeComment(comment1, pluto); + await justLikeComment(comment2, mars); + await justLikeComment(comment3, jupiter); + await justLikeComment(comment4, luna); }); describe('with comment folding', () => { @@ -896,15 +912,15 @@ describe('Comment likes', () => { describe('5 comments', () => { beforeEach(async () => { - const comment1 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - const comment2 = await writeComment(luna, lunaPost.id, 'Luna comment'); - const comment3 = await writeComment(mars, lunaPost.id, 'Mars comment'); - await writeComment(mars, lunaPost.id, 'Mars comment'); - const comment5 = await writeComment(pluto, lunaPost.id, 'Pluto comment'); - await likeComment(comment1.id, pluto); - await likeComment(comment2.id, mars); - await likeComment(comment3.id, jupiter); - await likeComment(comment5.id, luna); + const comment1 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + const comment2 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + const comment3 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + await justCreateComment(mars, lunaPost.id, 'Mars comment'); + const comment5 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment'); + await justLikeComment(comment1, pluto); + await justLikeComment(comment2, mars); + await justLikeComment(comment3, jupiter); + await justLikeComment(comment5, luna); }); describe('with comment folding', () => { @@ -937,15 +953,15 @@ describe('Comment likes', () => { describe("should exclude banned user's comment likes", () => { beforeEach(async () => { - const comment1 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - const comment2 = await writeComment(luna, lunaPost.id, 'Luna comment'); - const comment3 = await writeComment(mars, lunaPost.id, 'Mars comment'); - await writeComment(mars, lunaPost.id, 'Mars comment'); - const comment5 = await writeComment(pluto, lunaPost.id, 'Pluto comment'); - await likeComment(comment1.id, pluto); - await likeComment(comment2.id, mars); - await likeComment(comment3.id, jupiter); - await likeComment(comment5.id, luna); + const comment1 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + const comment2 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + const comment3 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + await justCreateComment(mars, lunaPost.id, 'Mars comment'); + const comment5 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment'); + await justLikeComment(comment1, pluto); + await justLikeComment(comment2, mars); + await justLikeComment(comment3, jupiter); + await justLikeComment(comment5, luna); await Promise.all([banUser(luna, jupiter), banUser(luna, pluto)]); }); @@ -971,10 +987,10 @@ describe('Comment likes', () => { describe('should be present in comment payload', () => { beforeEach(async () => { - const comment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - await likeComment(comment.id, pluto); - await likeComment(comment.id, mars); - await likeComment(comment.id, luna); + const comment = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + await justLikeComment(comment, pluto); + await justLikeComment(comment, mars); + await justLikeComment(comment, luna); }); it('for anonymous user', async () => { @@ -1097,18 +1113,13 @@ describe('Comment likes', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); - lunaPost = await createAndReturnPost(luna, 'Luna post'); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); + lunaPost = await justCreatePost(luna, 'Luna post'); await mutualSubscriptions([luna, mars]); - comment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - await likeComment(comment.id, pluto); - await likeComment(comment.id, mars); + comment = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + await justLikeComment(comment, pluto); + await justLikeComment(comment, mars); }); describe('comment likes fields should be present', () => { @@ -1131,7 +1142,7 @@ describe('Comment likes', () => { { username: 'mars', authToken: luna.authToken }, 'Luna direct', ); - const directComment = await writeComment( + const directComment = await justCreateComment( mars, luna2marsDirectPost.id, 'Mars direct comment', @@ -1149,10 +1160,10 @@ describe('Comment likes', () => { describe('comments likes fields should contain correct counts', () => { let comment2, comment3, comment4, comment5; beforeEach(async () => { - comment2 = await writeComment(mars, lunaPost.id, 'Mars comment'); - comment3 = await writeComment(pluto, lunaPost.id, 'Pluto comment'); - comment4 = await writeComment(luna, lunaPost.id, 'Luna comment'); - comment5 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); + comment2 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + comment3 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment'); + comment4 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + comment5 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); }); it('when only first comment is liked', async () => await expectFeedCommentLikesCountsToBe('home', luna, 2, 0, 0, 0)); @@ -1227,7 +1238,7 @@ describe('Comment likes', () => { }); it(`and last (and liked) comment's author is banned by viewer [negative OmittedCommentLikes]`, async () => { - const comment6 = await writeComment(pluto, lunaPost.id, 'Pluto comment 2'); + const comment6 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment 2'); await likeComment(comment6.id, mars); await likeComment(comment6.id, jupiter); await banUser(luna, pluto); @@ -1239,23 +1250,23 @@ describe('Comment likes', () => { describe('#bestOf', () => { beforeEach(async () => { - const neptune = await createUserAsync('neptune', 'pw'); + const neptune = await createTestUser('neptune'); await Promise.all([ - writeComment(jupiter, lunaPost.id, 'Jupiter comment2'), - writeComment(jupiter, lunaPost.id, 'Jupiter comment3'), - writeComment(pluto, lunaPost.id, 'Pluto comment1'), - writeComment(pluto, lunaPost.id, 'Pluto comment2'), - writeComment(pluto, lunaPost.id, 'Pluto comment3'), - writeComment(mars, lunaPost.id, 'Mars comment1'), - writeComment(mars, lunaPost.id, 'Mars comment2'), - writeComment(mars, lunaPost.id, 'Mars comment3'), - writeComment(luna, lunaPost.id, 'Luna comment1'), - writeComment(luna, lunaPost.id, 'Luna comment2'), - writeComment(luna, lunaPost.id, 'Luna comment3'), - writeComment(neptune, lunaPost.id, 'Neptune comment1'), - writeComment(neptune, lunaPost.id, 'Neptune comment2'), - writeComment(neptune, lunaPost.id, 'Neptune comment3'), + justCreateComment(jupiter, lunaPost.id, 'Jupiter comment2'), + justCreateComment(jupiter, lunaPost.id, 'Jupiter comment3'), + justCreateComment(pluto, lunaPost.id, 'Pluto comment1'), + justCreateComment(pluto, lunaPost.id, 'Pluto comment2'), + justCreateComment(pluto, lunaPost.id, 'Pluto comment3'), + justCreateComment(mars, lunaPost.id, 'Mars comment1'), + justCreateComment(mars, lunaPost.id, 'Mars comment2'), + justCreateComment(mars, lunaPost.id, 'Mars comment3'), + justCreateComment(luna, lunaPost.id, 'Luna comment1'), + justCreateComment(luna, lunaPost.id, 'Luna comment2'), + justCreateComment(luna, lunaPost.id, 'Luna comment3'), + justCreateComment(neptune, lunaPost.id, 'Neptune comment1'), + justCreateComment(neptune, lunaPost.id, 'Neptune comment2'), + justCreateComment(neptune, lunaPost.id, 'Neptune comment3'), ]); const promises = []; @@ -1313,18 +1324,13 @@ describe('Comment likes', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); - lunaPost = await createAndReturnPost(luna, 'Luna post cliked'); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); + lunaPost = await justCreatePost(luna, 'Luna post cliked'); await mutualSubscriptions([luna, mars]); - comment = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); - await likeComment(comment.id, pluto); - await likeComment(comment.id, mars); + comment = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); + await justLikeComment(comment, pluto); + await justLikeComment(comment, mars); }); describe('comment likes fields should be present', () => { @@ -1340,10 +1346,10 @@ describe('Comment likes', () => { describe('comments likes fields should contain correct counts', () => { let comment2, comment3, comment4, comment5; beforeEach(async () => { - comment2 = await writeComment(mars, lunaPost.id, 'Mars comment'); - comment3 = await writeComment(pluto, lunaPost.id, 'Pluto comment'); - comment4 = await writeComment(luna, lunaPost.id, 'Luna comment'); - comment5 = await writeComment(jupiter, lunaPost.id, 'Jupiter comment'); + comment2 = await justCreateComment(mars, lunaPost.id, 'Mars comment'); + comment3 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment'); + comment4 = await justCreateComment(luna, lunaPost.id, 'Luna comment'); + comment5 = await justCreateComment(jupiter, lunaPost.id, 'Jupiter comment'); }); it('when only first comment is liked', async () => await expectSearchResultsCommentLikesCountsToBe('cliked', luna, 2, 0, 0, 0)); @@ -1418,7 +1424,7 @@ describe('Comment likes', () => { }); it(`and last (and liked) comment's author is banned by viewer [negative OmittedCommentLikes]`, async () => { - const comment6 = await writeComment(pluto, lunaPost.id, 'Pluto comment 2'); + const comment6 = await justCreateComment(pluto, lunaPost.id, 'Pluto comment 2'); await likeComment(comment6.id, mars); await likeComment(comment6.id, jupiter); await banUser(luna, pluto); @@ -1430,12 +1436,6 @@ describe('Comment likes', () => { }); }); -const createComment = () => async (userContext, postId, body) => { - const response = await createCommentAsync(userContext, postId, body); - const commentData = await response.json(); - return commentData.comments; -}; - const fetchPost = (app) => async (postId, viewerContext = null, allComments = false) => { diff --git a/test/functional/comments.js b/test/functional/comments.js index 6cf14bdd0..5c03e30c9 100644 --- a/test/functional/comments.js +++ b/test/functional/comments.js @@ -26,7 +26,7 @@ describe('CommentsController', () => { let context = {}; beforeEach(async () => { context = await funcTestHelper.createUserAsync('Luna', 'password'); - context.post = await funcTestHelper.createAndReturnPost(context, 'Post body'); + context.post = await funcTestHelper.justCreatePost(context, 'Post body'); }); describe('in a group', () => { @@ -154,7 +154,7 @@ describe('CommentsController', () => { beforeEach(async () => { mars = await funcTestHelper.createUserAsync('Mars', 'password'); - postOfMars = await funcTestHelper.createAndReturnPost(mars, 'I am mars!'); + postOfMars = await funcTestHelper.justCreatePost(mars, 'I am mars!'); await funcTestHelper.banUser(context, mars); }); @@ -181,11 +181,8 @@ describe('CommentsController', () => { funcTestHelper.createUserAsync('yole', 'pw'), ]); - const post = await funcTestHelper.createAndReturnPost(lunaContext, 'post body'); - const response = await funcTestHelper.createCommentAsync(lunaContext, post.id, 'comment'); - const commentData = await response.json(); - - comment = commentData.comments; + const post = await funcTestHelper.justCreatePost(lunaContext, 'post body'); + comment = await funcTestHelper.justCreateComment(lunaContext, post.id, 'comment'); }); it('should update a comment with a valid user', (done) => { @@ -258,33 +255,39 @@ describe('CommentsController', () => { ]); const [lunaPost, marsPost] = await Promise.all([ - funcTestHelper.createAndReturnPost(lunaContext, 'Post body 1'), - funcTestHelper.createAndReturnPost(marsContext, 'Post body 2'), + funcTestHelper.justCreatePost(lunaContext, 'Post body 1'), + funcTestHelper.justCreatePost(marsContext, 'Post body 2'), ]); - let response = await funcTestHelper.createCommentAsync( + ({ id: lunaPostLunaComment } = await funcTestHelper.justCreateComment( lunaContext, lunaPost.id, 'Comment 1-1', - ); - let data = await response.json(); - lunaPostLunaComment = data.comments.id; + )); - response = await funcTestHelper.createCommentAsync(marsContext, lunaPost.id, 'Comment 1-2'); - data = await response.json(); - lunaPostMarsComment = data.comments.id; - - response = await funcTestHelper.createCommentAsync(marsContext, marsPost.id, 'Comment 2-1'); - data = await response.json(); - marsPostMarsComment = data.comments.id; + ({ id: lunaPostMarsComment } = await funcTestHelper.justCreateComment( + marsContext, + lunaPost.id, + 'Comment 1-2', + )); - response = await funcTestHelper.createCommentAsync(lunaContext, marsPost.id, 'Comment 2-2'); - data = await response.json(); - marsPostLunaComment = data.comments.id; + ({ id: marsPostMarsComment } = await funcTestHelper.justCreateComment( + marsContext, + marsPost.id, + 'Comment 2-1', + )); - response = await funcTestHelper.createCommentAsync(ceresContext, marsPost.id, 'Comment 2-3'); - data = await response.json(); - marsPostCeresComment = data.comments.id; + ({ id: marsPostLunaComment } = await funcTestHelper.justCreateComment( + lunaContext, + marsPost.id, + 'Comment 2-2', + )); + + ({ id: marsPostCeresComment } = await funcTestHelper.justCreateComment( + ceresContext, + marsPost.id, + 'Comment 2-3', + )); }); it('should remove comment (your own comment in your own post)', async () => { @@ -330,19 +333,17 @@ describe('CommentsController', () => { let luna, mars, venus, postId, commentIds; beforeEach(async () => { [luna, mars, venus] = await funcTestHelper.createTestUsers(['luna', 'mars', 'venus']); - ({ id: postId } = await funcTestHelper.createAndReturnPost(luna, 'post')); + ({ id: postId } = await funcTestHelper.justCreatePost(luna, 'post')); commentIds = []; for (let i = 0; i < 3; i++) { // eslint-disable-next-line no-await-in-loop - const resp = await funcTestHelper.createCommentAsync( + const data = await funcTestHelper.justCreateComment( [luna, mars, luna][i], postId, `Comment ${i + 1}`, ); - // eslint-disable-next-line no-await-in-loop - const data = await resp.json(); - commentIds.push(data.comments.id); + commentIds.push(data.id); } }); @@ -572,25 +573,15 @@ describe('CommentsController', () => { const nComments = 10; let luna, mars, venus, comments; beforeEach(async () => { - luna = await funcTestHelper.createUserAsync('luna', 'password'); - mars = await funcTestHelper.createUserAsync('mars', 'password'); - venus = await funcTestHelper.createUserAsync('venus', 'password'); - const post = await funcTestHelper.createAndReturnPost(venus, 'Post body'); + [luna, mars, venus] = await funcTestHelper.createTestUsers(['luna', 'mars', 'venus']); + const post = await funcTestHelper.justCreatePost(venus, 'Post body'); comments = []; for (let n = 0; n < nComments; n++) { comments.push( - // eslint-disable-next-line prettier/prettier - ( - // eslint-disable-next-line no-await-in-loop - await funcTestHelper.performJSONRequest( - 'POST', - `/v2/comments`, - { comment: { body: 'Comment', postId: post.id } }, - funcTestHelper.authHeaders(n % 2 == 0 ? luna : mars), - ) - ).comments, + // eslint-disable-next-line no-await-in-loop + await funcTestHelper.justCreateComment(n % 2 == 0 ? luna : mars, post.id, 'Comment'), ); } diff --git a/test/functional/events.js b/test/functional/events.js index ee0b2ae27..8706906e9 100644 --- a/test/functional/events.js +++ b/test/functional/events.js @@ -44,6 +44,8 @@ import { performJSONRequest, authHeaders, createTestUsers, + justCreateComment, + justCreatePost, } from '../functional/functional_test_helper'; import * as schema from './schemaV2-helper'; @@ -82,15 +84,14 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); - [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = - await dbAdapter.getUsersByIds([luna.user.id, mars.user.id, jupiter.user.id, pluto.user.id]); + [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = [ + luna.user, + mars.user, + jupiter.user, + pluto.user, + ]; await mutualSubscriptions([luna, mars]); await subscribeToAsync(jupiter, luna); @@ -212,12 +213,8 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); - - [lunaUserModel, marsUserModel] = await dbAdapter.getUsersByIds([luna.user.id, mars.user.id]); + [luna, mars] = await createTestUsers(['luna', 'mars']); + [lunaUserModel, marsUserModel] = [luna.user, mars.user]; }); it('should create user_subscribed event when user subscribed', async () => { @@ -363,9 +360,8 @@ describe('EventService', () => { let luna, mars, lunasPost, marsesComment; beforeEach(async () => { [luna, mars] = await createTestUsers(['luna', 'mars']); - lunasPost = await createAndReturnPost(luna, 'Post'); - const resp = await createCommentAsync(mars, lunasPost.id, 'Comment'); - ({ comments: marsesComment } = await resp.json()); + lunasPost = await justCreatePost(luna, 'Post'); + marsesComment = await justCreateComment(mars, lunasPost.id, 'Comment'); }); it(`should create comment_moderated event for Mars when Luna removes Mars'es comment`, async () => { @@ -397,12 +393,8 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); - - [lunaUserModel, marsUserModel] = await dbAdapter.getUsersByIds([luna.user.id, mars.user.id]); + [luna, mars] = await createTestUsers(['luna', 'mars']); + [lunaUserModel, marsUserModel] = [luna.user, mars.user]; await goPrivate(luna); }); @@ -537,15 +529,14 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); - [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = - await dbAdapter.getUsersByIds([luna.user.id, mars.user.id, jupiter.user.id, pluto.user.id]); + [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = [ + luna.user, + mars.user, + jupiter.user, + pluto.user, + ]; }); describe('creation', () => { @@ -1012,15 +1003,14 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); - [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = - await dbAdapter.getUsersByIds([luna.user.id, mars.user.id, jupiter.user.id, pluto.user.id]); + [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = [ + luna.user, + mars.user, + jupiter.user, + pluto.user, + ]; await mutualSubscriptions([luna, mars, jupiter, pluto]); }); @@ -1224,15 +1214,14 @@ describe('EventService', () => { }; beforeEach(async () => { - [luna, mars, jupiter, pluto] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('jupiter', 'pw'), - createUserAsync('pluto', 'pw'), - ]); - - [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = - await dbAdapter.getUsersByIds([luna.user.id, mars.user.id, jupiter.user.id, pluto.user.id]); + [luna, mars, jupiter, pluto] = await createTestUsers(['luna', 'mars', 'jupiter', 'pluto']); + + [lunaUserModel, marsUserModel, jupiterUserModel, plutoUserModel] = [ + luna.user, + mars.user, + jupiter.user, + pluto.user, + ]; await mutualSubscriptions([luna, jupiter]); await goPrivate(jupiter); }); @@ -1420,7 +1409,7 @@ describe('EventService', () => { let post; beforeEach(async () => { - post = await createAndReturnPostToFeed(luna, luna, 'Test post'); + post = await justCreatePost(luna, 'Test post'); }); it('should create mention_in_comment event for mentioned user', async () => { @@ -1705,12 +1694,8 @@ describe('EventService', () => { let lunaUserModel, marsUserModel; beforeEach(async () => { - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); - - [lunaUserModel, marsUserModel] = await dbAdapter.getUsersByIds([luna.user.id, mars.user.id]); + [luna, mars] = await createTestUsers(['luna', 'mars']); + [lunaUserModel, marsUserModel] = [luna.user, mars.user]; }); describe("event shouldn't be deleted when", () => { @@ -1811,12 +1796,8 @@ describe('EventsController', () => { let luna, mars, lunaUserModel, marsUserModel; beforeEach(async () => { - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); - - [lunaUserModel, marsUserModel] = await dbAdapter.getUsersByIds([luna.user.id, mars.user.id]); + [luna, mars] = await createTestUsers(['luna', 'mars']); + [lunaUserModel, marsUserModel] = [luna.user, mars.user]; await mutualSubscriptions([luna, mars]); }); @@ -2252,12 +2233,8 @@ describe('Unread events counter', () => { beforeEach(async () => { await cleanDB($pg_database); - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); - - [lunaUserModel] = await dbAdapter.getUsersByIds([luna.user.id]); + [luna, mars] = await createTestUsers(['luna', 'mars']); + lunaUserModel = luna.user; }); const getUnreadEventsCountFromWhoAmI = async (user) => { @@ -2371,10 +2348,7 @@ describe('Unread events counter realtime updates for ', () => { beforeEach(async () => { await cleanDB($pg_database); - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); + [luna, mars] = await createTestUsers(['luna', 'mars']); }); describe('user_subscribed event', () => { @@ -2876,10 +2850,7 @@ describe('eventById', () => { beforeEach(async () => { await cleanDB($pg_database); - [luna, mars] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - ]); + [luna, mars] = await createTestUsers(['luna', 'mars']); // To create some records in events history await mutualSubscriptions([luna, mars]); }); diff --git a/test/functional/local-bumps.js b/test/functional/local-bumps.js index 432126e8d..467f229a9 100644 --- a/test/functional/local-bumps.js +++ b/test/functional/local-bumps.js @@ -28,7 +28,7 @@ describe('Local bumps', () => { marsPosts = []; for (let i = 0; i < nPosts; i++) { - const { id } = await helper.createAndReturnPost(mars, 'post'); // eslint-disable-line no-await-in-loop + const { id } = await helper.justCreatePost(mars, 'post'); // eslint-disable-line no-await-in-loop marsPosts.push(id); } @@ -38,7 +38,7 @@ describe('Local bumps', () => { lunaPosts = []; for (let i = 0; i < nPosts; i++) { - const { id } = await helper.createAndReturnPost(luna, 'post'); // eslint-disable-line no-await-in-loop + const { id } = await helper.justCreatePost(luna, 'post'); // eslint-disable-line no-await-in-loop lunaPosts.push(id); } @@ -52,7 +52,7 @@ describe('Local bumps', () => { marsPostsInGroup = []; for (let i = 0; i < nPosts; i++) { - const { id } = await helper.createAndReturnPostToFeed(celestials, mars, 'post'); // eslint-disable-line no-await-in-loop + const { id } = await helper.justCreatePost(mars, 'post', [celestials.username]); // eslint-disable-line no-await-in-loop marsPostsInGroup.push(id); } diff --git a/test/functional/posts/edit-destinations.js b/test/functional/posts/edit-destinations.js index 576e14030..2992a118f 100644 --- a/test/functional/posts/edit-destinations.js +++ b/test/functional/posts/edit-destinations.js @@ -6,11 +6,11 @@ import cleanDB from '../../dbCleaner'; import { createTestUsers, mutualSubscriptions, - createAndReturnPostToFeed, performJSONRequest, authHeaders, - createGroupAsync, groupToPrivate, + justCreatePost, + justCreateGroup, } from '../functional_test_helper'; import { GONE_SUSPENDED } from '../../../app/models/user'; @@ -29,7 +29,7 @@ describe('Update destinations of existing post', () => { await mutualSubscriptions([luna, mars]); // Luna sent direct message to Mars - post = await createAndReturnPostToFeed([mars], luna, 'Hello, Mars!'); + post = await justCreatePost(luna, 'Hello, Mars!', [mars.username, luna.username]); // Mars decide to delete his account await mars.user.setGoneStatus(GONE_SUSPENDED); @@ -72,10 +72,10 @@ describe('Update destinations of existing post', () => { describe('Luna wrote post to group, group became private', () => { let celestials; beforeEach(async () => { - celestials = await createGroupAsync(mars, 'celestials', 'Celestials'); + celestials = await justCreateGroup(mars, 'celestials', 'Celestials'); - post = await createAndReturnPostToFeed([celestials, luna], luna, 'Hello, world!'); - await groupToPrivate(celestials.group, mars); + post = await justCreatePost(luna, 'Hello, world!', [celestials.username, luna.username]); + await groupToPrivate(celestials, mars); }); it(`should allow Luna to update the post without 'feeds' field`, async () => { diff --git a/test/functional/posts/leave-direct.js b/test/functional/posts/leave-direct.js index 0ff6ca0aa..1017193c3 100644 --- a/test/functional/posts/leave-direct.js +++ b/test/functional/posts/leave-direct.js @@ -8,8 +8,8 @@ import { PubSubAdapter } from '../../../app/support/PubSubAdapter'; import { dbAdapter, PubSub } from '../../../app/models'; import { authHeaders, - createAndReturnPostToFeed, createTestUsers, + justCreatePost, mutualSubscriptions, performJSONRequest, } from '../functional_test_helper'; @@ -20,7 +20,7 @@ import { getEventText } from '../../../app/mailers/NotificationDigestMailer'; describe('POST /v2/posts/:postId/leave', () => { let luna, mars, venus, jupiter; - beforeEach(async () => { + before(async () => { await cleanDB($pg_database); [luna, mars, venus, jupiter] = await createTestUsers(['luna', 'mars', 'venus', 'jupiter']); @@ -30,7 +30,10 @@ describe('POST /v2/posts/:postId/leave', () => { describe('Luna create direct with Mars and Venus', () => { let post; beforeEach(async () => { - post = await createAndReturnPostToFeed([mars.user, venus.user], luna, 'Hello'); + post = await justCreatePost(luna, 'Hello', [luna.username, mars.username, venus.username]); + }); + afterEach(async () => { + await post.destroy(); }); it('should allow Mars to leave direct', async () => { @@ -59,7 +62,10 @@ describe('POST /v2/posts/:postId/leave', () => { }); describe('Mars leaving direct', () => { - beforeEach(() => leave(post, mars)); + beforeEach(async () => { + await clearAllEvents(); + await leave(post, mars); + }); it('should not allow Mars to see post', async () => { const resp = await getPost(post, mars); @@ -237,6 +243,10 @@ async function getSerializedEvents(userId) { return serializeEvents(events, userId); } +async function clearAllEvents() { + await dbAdapter.database.raw(`delete from events`); +} + function stripHTML(str) { return str.replace(/<.+?>/g, ''); } diff --git a/test/functional/posts/posts.js b/test/functional/posts/posts.js index 848f87644..bcd0d9dfe 100644 --- a/test/functional/posts/posts.js +++ b/test/functional/posts/posts.js @@ -191,7 +191,7 @@ describe('PostsController', () => { beforeEach(async () => { [zeusCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('zeus', 'password'), - funcTestHelper.createAndReturnPostToFeed(marsCtx, ctx, 'body'), + funcTestHelper.justCreatePost(ctx, 'body', [ctx.username, marsCtx.username]), ]); }); @@ -379,7 +379,7 @@ describe('PostsController', () => { beforeEach(async () => { const screenName = 'Pepyatka Developers'; - await funcTestHelper.createGroupAsync(ctx, groupName, screenName); + await funcTestHelper.justCreateGroup(ctx, groupName, screenName); const yole = await funcTestHelper.createUserAsync(otherUserName, 'pw'); otherUserAuthToken = yole.authToken; @@ -638,7 +638,7 @@ describe('PostsController', () => { [marsCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('mars', 'password2'), - funcTestHelper.createAndReturnPost(context, 'Post body'), + funcTestHelper.justCreatePost(context, 'Post body'), ]); context.post = post; @@ -650,7 +650,7 @@ describe('PostsController', () => { beforeEach(async () => { const screenName = 'Pepyatka Developers'; - await funcTestHelper.createGroupAsync(context, groupName, screenName); + await funcTestHelper.justCreateGroup(context, groupName, screenName); }); it("should not update group's last activity", (done) => { @@ -752,7 +752,7 @@ describe('PostsController', () => { let postOfMars; beforeEach(async () => { - postOfMars = await funcTestHelper.createAndReturnPost(marsCtx, 'I am mars!'); + postOfMars = await funcTestHelper.justCreatePost(marsCtx, 'I am mars!'); await funcTestHelper.banUser(context, marsCtx); }); @@ -777,7 +777,7 @@ describe('PostsController', () => { const [marsCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('mars', 'password2'), - funcTestHelper.createAndReturnPost(context, 'Post body'), + funcTestHelper.justCreatePost(context, 'Post body'), ]); context.post = post; @@ -850,7 +850,7 @@ describe('PostsController', () => { const [marsCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('mars', 'password2'), - funcTestHelper.createAndReturnPost(context, 'Post body'), + funcTestHelper.justCreatePost(context, 'Post body'), ]); context.post = post; @@ -899,14 +899,14 @@ describe('PostsController', () => { beforeEach(async () => { context = await funcTestHelper.createUserAsync('Luna', 'password'); - const [marsCtx, response] = await Promise.all([ + const [marsCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('mars', 'password2'), - funcTestHelper.createPostWithCommentsDisabled(context, 'Post body', true), + funcTestHelper.justCreatePost(context, 'Post body'), ]); - const data = await response.json(); + await post.setCommentsDisabled('1'); - context.post = data.posts; + context.post = post; otherUserAuthToken = marsCtx.authToken; }); @@ -954,7 +954,7 @@ describe('PostsController', () => { const [yoleCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('yole', 'pw'), - funcTestHelper.createAndReturnPost(context, 'Post body'), + funcTestHelper.justCreatePost(context, 'Post body'), ]); context.post = post; @@ -1068,8 +1068,8 @@ describe('PostsController', () => { [luna, mars, yole] = await funcTestHelper.createTestUsers(3); await funcTestHelper.mutualSubscriptions([luna, mars]); await funcTestHelper.mutualSubscriptions([luna, yole]); - celestials = await funcTestHelper.createGroupAsync(luna, 'celestials'); - evilmartians = await funcTestHelper.createGroupAsync(mars, 'evilmartians'); + celestials = await funcTestHelper.justCreateGroup(luna, 'celestials'); + evilmartians = await funcTestHelper.justCreateGroup(mars, 'evilmartians'); }); const updatePost = async (postObj, userContext, parameters) => { @@ -1100,7 +1100,7 @@ describe('PostsController', () => { describe('Luna creates post in their feed', () => { beforeEach(async () => { - post = await funcTestHelper.createAndReturnPostToFeed([luna], luna, 'Post body'); + post = await funcTestHelper.justCreatePost(luna, 'Post body'); }); it('should be able to change destinations of regular post', async () => { @@ -1131,7 +1131,10 @@ describe('PostsController', () => { describe('Luna creates direct post', () => { beforeEach(async () => { - post = await funcTestHelper.createAndReturnPostToFeed([mars], luna, 'Post body'); + post = await funcTestHelper.justCreatePost(luna, 'Post body', [ + mars.username, + luna.username, + ]); }); it('should be able to add recipient to direct post', async () => { @@ -1146,7 +1149,11 @@ describe('PostsController', () => { describe('Luna creates direct post with two recipients', () => { beforeEach(async () => { - post = await funcTestHelper.createAndReturnPostToFeed([mars, yole], luna, 'Post body'); + post = await funcTestHelper.justCreatePost(luna, 'Post body', [ + mars.username, + yole.username, + luna.username, + ]); }); it('should not be able to remove recipient from direct post', async () => { @@ -1169,7 +1176,7 @@ describe('PostsController', () => { beforeEach(async () => { context = await funcTestHelper.createUserAsync('Luna', 'password'); - context.post = await funcTestHelper.createAndReturnPost(context, 'Post body'); + context.post = await funcTestHelper.justCreatePost(context, 'Post body'); }); it('should show a post', (done) => { @@ -1244,7 +1251,7 @@ describe('PostsController', () => { beforeEach(async () => { context = await funcTestHelper.createUserAsync('Luna', 'password'); - context.post = await funcTestHelper.createAndReturnPost(context, 'Post body'); + context.post = await funcTestHelper.justCreatePost(context, 'Post body'); }); it('should hide and unhide post', (done) => { @@ -1300,7 +1307,7 @@ describe('PostsController', () => { const [yoleCtx, post] = await Promise.all([ funcTestHelper.createUserAsync('yole', 'pw'), - funcTestHelper.createAndReturnPost(context, 'Post body'), + funcTestHelper.justCreatePost(context, 'Post body'), ]); context.post = post; diff --git a/test/functional/posts/postsV2.js b/test/functional/posts/postsV2.js index 4f91ce254..45269b88f 100644 --- a/test/functional/posts/postsV2.js +++ b/test/functional/posts/postsV2.js @@ -9,7 +9,6 @@ import { PubSub } from '../../../app/models'; import { createUserAsync, createAndReturnPost, - createCommentAsync, like, goPrivate, goProtected, @@ -27,6 +26,8 @@ import { acceptRequestToSubscribe, banUser, createTestUser, + justCreatePost, + justCreateComment, } from '../functional_test_helper'; import { postsByIdsResponse } from '../schemaV2-helper'; @@ -46,21 +47,21 @@ describe('TimelinesControllerV2', () => { let luna, mars, venus; let lunaPost; beforeEach(async () => { - [luna, mars, venus] = await Promise.all([ - createUserAsync('luna', 'pw'), - createUserAsync('mars', 'pw'), - createUserAsync('venus', 'pw'), - ]); - lunaPost = await createAndReturnPost(luna, 'Luna post'); + [luna, mars, venus] = await createTestUsers(['luna', 'mars', 'venus']); + lunaPost = await justCreatePost(luna, 'Luna post'); await mutualSubscriptions([luna, mars]); }); describe('Comments folding test', () => { const expectFolding = async (nComments, expComments, expOmitted, allComments = false) => { + const promises = []; + for (let n = 0; n < nComments; n++) { - await createCommentAsync(luna, lunaPost.id, `Comment ${n + 1}`); // eslint-disable-line no-await-in-loop + promises.push(justCreateComment(luna, lunaPost.id, `Comment ${n + 1}`)); } + await Promise.all(promises); + const post = await fetchPost(lunaPost.id, null, { allComments }); expect(post.posts.comments, 'to have length', expComments); expect(post.posts.omittedComments, 'to equal', expOmitted); @@ -217,8 +218,10 @@ describe('TimelinesControllerV2', () => { let lunaPostWithSpecialCharacters, lunaPostWithNewLines; beforeEach(async () => { - lunaPostWithSpecialCharacters = await createAndReturnPost(luna, 'Test with tags
'); - lunaPostWithNewLines = await createAndReturnPost(luna, 'A\nB\nC'); + [lunaPostWithSpecialCharacters, lunaPostWithNewLines] = await Promise.all([ + justCreatePost(luna, 'Test with tags
'), + justCreatePost(luna, 'A\nB\nC'), + ]); }); describe('Luna is a public user', () => { @@ -230,7 +233,8 @@ describe('TimelinesControllerV2', () => { }); it('should return information for a public post by its short id', async () => { - const response = await fetchPostOpenGraph(lunaPost.shortId); + const shortId = await lunaPost.getShortId(); + const response = await fetchPostOpenGraph(shortId); response.should.include('og:title'); response.should.include('luna'); response.should.include(''); @@ -273,7 +277,7 @@ describe('TimelinesControllerV2', () => { let attId1, attId2, attId3; beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); - luna.post = await createAndReturnPost(luna, 'Luna post'); + luna.post = await justCreatePost(luna, 'Luna post'); attId1 = (await createMockAttachmentAsync(luna)).id; attId2 = (await createMockAttachmentAsync(luna)).id; attId3 = (await createMockAttachmentAsync(luna)).id; @@ -340,7 +344,7 @@ describe('TimelinesControllerV2', () => { let post1, post2; beforeEach(async () => { post1 = luna.post; - post2 = await createAndReturnPost(luna, 'Luna post 2'); + post2 = await justCreatePost(luna, 'Luna post 2'); }); it('should not allow to rebind attachment from post1 to post2', async () => { @@ -356,7 +360,7 @@ describe('TimelinesControllerV2', () => { let mars; beforeEach(async () => { mars = await createUserAsync('mars', 'pw'); - mars.post = await createAndReturnPost(mars, 'Mars post'); + mars.post = await justCreatePost(mars, 'Mars post'); }); it('should not allow Mars to steal Luna attachments', async () => { @@ -374,7 +378,7 @@ describe('TimelinesControllerV2', () => { let luna; beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); - luna.post = await createAndReturnPost(luna, 'Luna post'); + luna.post = await justCreatePost(luna, 'Luna post'); await hidePost(luna.post.id, luna); }); @@ -388,7 +392,7 @@ describe('TimelinesControllerV2', () => { let luna; beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); - luna.post = await createAndReturnPost(luna, 'Luna post'); + luna.post = await justCreatePost(luna, 'Luna post'); await savePost(luna.post.id, luna); }); @@ -419,7 +423,7 @@ describe('TimelinesControllerV2', () => { for (let n = 0; n < nPosts; n++) { // eslint-disable-next-line no-await-in-loop - posts.push(await createAndReturnPost(n % 2 == 0 ? luna : mars, 'post')); + posts.push(await justCreatePost(n % 2 == 0 ? luna : mars, 'post')); } }); diff --git a/test/functional/private_groups.js b/test/functional/private_groups.js index 8236176ad..028c0ccc3 100644 --- a/test/functional/private_groups.js +++ b/test/functional/private_groups.js @@ -23,7 +23,7 @@ describe('PrivateGroups', () => { let context = {}; beforeEach(async () => { - context = await funcTestHelper.createUserAsync('Luna', 'password'); + context = await funcTestHelper.createTestUser('luna'); }); it('should create a public not-restricted group by default', (done) => { @@ -151,15 +151,12 @@ describe('PrivateGroups', () => { let group = {}; beforeEach(async () => { - [adminContext, nonAdminContext] = await Promise.all([ - funcTestHelper.createUserAsync('Luna', 'password'), - funcTestHelper.createUserAsync('yole', 'wordpass'), - ]); - group = await funcTestHelper.createGroupAsync( + [adminContext, nonAdminContext] = await funcTestHelper.createTestUsers(['Luna', 'yole']); + group = await funcTestHelper.justCreateGroup( adminContext, 'pepyatka-dev', 'Pepyatka Developers', - true, + { private: true }, ); }); @@ -182,19 +179,9 @@ describe('PrivateGroups', () => { beforeEach(async () => { context = await funcTestHelper.createTestUser('luna'); - }); - - beforeEach((done) => { - request - .post(`${app.context.config.host}/v1/groups`) - .send({ - group: { username: 'pepyatka-dev', screenName: 'Pepyatka Developers', isPrivate: '1' }, - authToken: context.authToken, - }) - .end((err, res) => { - group = res.body.groups; - done(); - }); + group = await funcTestHelper.justCreateGroup(context, 'pepyatka-dev', 'pepyatka-dev', { + isPrivate: true, + }); }); it('should update private group settings', (done) => { @@ -302,18 +289,9 @@ describe('PrivateGroups', () => { beforeEach(async () => { [adminContext] = await funcTestHelper.createTestUsers(['luna', 'yole']); - }); - - beforeEach((done) => { - request - .post(`${app.context.config.host}/v1/groups`) - .send({ - group: { username: 'pepyatka-dev', screenName: 'Pepyatka Developers', isPrivate: '1' }, - authToken: adminContext.authToken, - }) - .end(() => { - done(); - }); + await funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev', 'pepyatka-dev', { + isPrivate: true, + }); }); beforeEach((done) => { @@ -342,18 +320,10 @@ describe('PrivateGroups', () => { let group; beforeEach(async () => { - [adminContext, nonAdminContext] = await Promise.all([ - funcTestHelper.createUserAsync('Luna', 'password'), - funcTestHelper.createUserAsync('yole', 'wordpass'), - ]); - - const response = await funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev', - 'Pepyatka Developers', - true, - ); - ({ group } = response); + [adminContext, nonAdminContext] = await funcTestHelper.createTestUsers(['Luna', 'yole']); + group = await funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev', 'pepyatka-dev', { + isPrivate: true, + }); }); it('should reject unauthenticated users', (done) => { @@ -466,19 +436,9 @@ describe('PrivateGroups', () => { let group; beforeEach(async () => { - [adminContext, secondAdminContext, nonAdminContext, groupMemberContext] = await Promise.all([ - funcTestHelper.createUserAsync('Luna', 'password'), - funcTestHelper.createUserAsync('Neptune', 'password'), - funcTestHelper.createUserAsync('yole', 'wordpass'), - funcTestHelper.createUserAsync('Pluto', 'wordpass'), - ]); - - const response = await funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev', - 'Pepyatka Developers', - ); - ({ group } = response); + [adminContext, secondAdminContext, nonAdminContext, groupMemberContext] = + await funcTestHelper.createTestUsers(['Luna', 'Neptune', 'yole', 'Pluto']); + group = await funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev'); await Promise.all([ funcTestHelper.subscribeToAsync(secondAdminContext, group), @@ -488,7 +448,7 @@ describe('PrivateGroups', () => { await funcTestHelper.promoteToAdmin(group, adminContext, secondAdminContext); await funcTestHelper.groupToPrivate(group, adminContext); - await funcTestHelper.createAndReturnPostToFeed(group, adminContext, 'Post body'); + await funcTestHelper.justCreatePost(adminContext, 'Post body', [group.username]); await funcTestHelper.sendRequestToJoinGroup(nonAdminContext, group); }); @@ -1079,24 +1039,19 @@ describe('PrivateGroups', () => { let group; beforeEach(async () => { - [adminContext, marsContext, plutoContext] = await Promise.all([ - funcTestHelper.createUserAsync('Luna', 'password'), - funcTestHelper.createUserAsync('Mars', 'wordpass'), - funcTestHelper.createUserAsync('Pluto', 'wordpass'), + [adminContext, marsContext, plutoContext] = await funcTestHelper.createTestUsers([ + 'Luna', + 'Mars', + 'Pluto', ]); - const response = await funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev', - 'Pepyatka Developers', - ); - ({ group } = response); + group = await funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev'); await funcTestHelper.subscribeToAsync(plutoContext, group); await funcTestHelper.groupToPrivate(group, adminContext); - await funcTestHelper.createAndReturnPostToFeed(group, adminContext, 'Post body'); + await funcTestHelper.justCreatePost(adminContext, 'Post body', [group.username]); }); it('anonymous users should have no access to private group subscribers', async () => { @@ -1127,34 +1082,25 @@ describe('PrivateGroups', () => { let nonMemberContext = {}; beforeEach(async () => { - [adminContext, nonAdminContext, nonMemberContext] = await Promise.all([ - funcTestHelper.createUserAsync('Luna', 'password'), - funcTestHelper.createUserAsync('yole', 'wordpass'), - funcTestHelper.createUserAsync('Pluto', 'wordpass'), + [adminContext, nonAdminContext, nonMemberContext] = await funcTestHelper.createTestUsers([ + 'Luna', + 'yole', + 'Pluto', ]); const [group1, group2, group3] = await Promise.all([ - funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev', - 'Pepyatka Developers', - true, - true, - ), - funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev-2', - 'Pepyatka Developers 2', - true, - false, - ), - funcTestHelper.createGroupAsync( - adminContext, - 'pepyatka-dev-3', - 'Pepyatka Developers 3', - false, - true, - ), + funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev', 'Pepyatka Developers', { + isPrivate: true, + isRestricted: true, + }), + funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev-2', 'Pepyatka Developers 2', { + isPrivate: true, + isRestricted: false, + }), + funcTestHelper.justCreateGroup(adminContext, 'pepyatka-dev-3', 'Pepyatka Developers 3', { + isPrivate: false, + isRestricted: true, + }), ]); await Promise.all([ diff --git a/test/functional/timelinesV2.js b/test/functional/timelinesV2.js index a413208d4..8dbde83ab 100644 --- a/test/functional/timelinesV2.js +++ b/test/functional/timelinesV2.js @@ -33,6 +33,8 @@ import { savePost, createTestUsers, unsavePost, + justCreatePost, + justCreateComment, } from './functional_test_helper'; describe('TimelinesControllerV2', () => { @@ -318,16 +320,8 @@ describe('TimelinesControllerV2', () => { celestials = await createGroupAsync(venus, 'celestials'); await subscribeToAsync(luna, selenites); - selenitesPost = await createAndReturnPostToFeed( - { username: 'selenites' }, - venus, - 'Post', - ); - celestialsPost = await createAndReturnPostToFeed( - { username: 'celestials' }, - venus, - 'Post', - ); + selenitesPost = await justCreatePost(venus, 'Post', ['selenites']); + celestialsPost = await justCreatePost(venus, 'Post', ['celestials']); }); it('should return timeline without posts from Celestials group', async () => { @@ -404,10 +398,10 @@ describe('TimelinesControllerV2', () => { beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); mars = await createUserAsync('mars', 'pw'); - marsPostLikedByLuna = await createAndReturnPost(mars, 'Mars post 1'); - marsPostCommentedByLuna = await createAndReturnPost(mars, 'Mars post 2'); - lunaPost = await createAndReturnPost(luna, 'Luna post'); - await createCommentAsync(luna, marsPostCommentedByLuna.id, 'Comment'); + marsPostLikedByLuna = await justCreatePost(mars, 'Mars post 1'); + marsPostCommentedByLuna = await justCreatePost(mars, 'Mars post 2'); + lunaPost = await justCreatePost(luna, 'Luna post'); + await justCreateComment(luna, marsPostCommentedByLuna.id, 'Comment'); await like(marsPostLikedByLuna.id, luna.authToken); }); @@ -461,8 +455,8 @@ describe('TimelinesControllerV2', () => { luna = await createUserAsync('luna', 'pw'); mars = await createUserAsync('mars', 'pw'); await mutualSubscriptions([luna, mars]); - postLunaToMars = await createAndReturnPostToFeed({ username: 'mars' }, luna, 'Post'); - postMarsToLuna = await createAndReturnPostToFeed({ username: 'luna' }, mars, 'Post'); + postLunaToMars = await justCreatePost(luna, 'Post', ['luna', 'mars']); + postMarsToLuna = await justCreatePost(mars, 'Post', ['luna', 'mars']); }); it('should return timeline with directs from Luna and to Luna', async () => { @@ -496,10 +490,10 @@ describe('TimelinesControllerV2', () => { createUserAsync('venus', 'pw'), ]); await subscribeToAsync(venus, mars); - postCreatedByMars = await createAndReturnPost(mars, 'Post'); - postCommentedByMars = await createAndReturnPost(venus, 'Post'); - postLikedByMars = await createAndReturnPost(venus, 'Post'); - await createCommentAsync(mars, postCommentedByMars.id, 'Comment'); + postCreatedByMars = await justCreatePost(mars, 'Post'); + postCommentedByMars = await justCreatePost(venus, 'Post'); + postLikedByMars = await justCreatePost(venus, 'Post'); + await justCreateComment(mars, postCommentedByMars.id, 'Comment'); await like(postLikedByMars.id, mars.authToken); await hidePost(postCreatedByMars.id, luna); }); @@ -606,8 +600,8 @@ describe('TimelinesControllerV2', () => { let post1, post2; beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); - post1 = await createAndReturnPost(luna, 'Post'); - post2 = await createAndReturnPost(luna, 'Post'); + post1 = await justCreatePost(luna, 'Post'); + post2 = await justCreatePost(luna, 'Post'); }); it('should return uncommented Luna posts in creation order', async () => { @@ -631,7 +625,7 @@ describe('TimelinesControllerV2', () => { beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); // Luna creates 10 posts - await Promise.all([...new Array(10)].map(() => createAndReturnPost(luna, 'Post'))); + await Promise.all([...new Array(10)].map(() => justCreatePost(luna, 'Post'))); }); it('should return first page with isLastPage = false', async () => { @@ -655,9 +649,9 @@ describe('TimelinesControllerV2', () => { let post1, post2, post3; beforeEach(async () => { luna = await createUserAsync('luna', 'pw'); - post1 = await createAndReturnPost(luna, 'Post'); - post2 = await createAndReturnPost(luna, 'Post'); - post3 = await createAndReturnPost(luna, 'Post'); + post1 = await justCreatePost(luna, 'Post'); + post2 = await justCreatePost(luna, 'Post'); + post3 = await justCreatePost(luna, 'Post'); await dbAdapter .database('posts') .where('uid', post1.id) @@ -700,8 +694,8 @@ describe('TimelinesControllerV2', () => { let post1, post2; beforeEach(async () => { [luna, mars] = await createTestUsers(2); - post1 = await createAndReturnPost(luna, 'Post'); - post2 = await createAndReturnPost(mars, 'Post'); + post1 = await justCreatePost(luna, 'Post'); + post2 = await justCreatePost(mars, 'Post'); }); it('should not return Saves timeline to anonymous', async () => { From def11c999ab6a9784c336268026bd1bcee485e25 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sat, 4 May 2024 12:16:53 +0300 Subject: [PATCH 05/11] Allow to use multiple Postgres schemas in tests --- app/setup/postgres.js | 44 ++++++++----- app/support/parallel-testing.ts | 18 ++++++ bin/clean_test_db.js | 33 ---------- bin/reset_test_db.js | 61 +++++++++++++++++++ migrations/20160405133637_initial.js | 35 +++++++---- .../20161215174952_posts_privacy_flags.js | 14 ++--- .../20171205142923_post_is_propagable.js | 6 +- package.json | 4 +- test/dbCleaner.ts | 9 ++- yarn.lock | 11 +++- 10 files changed, 160 insertions(+), 75 deletions(-) create mode 100644 app/support/parallel-testing.ts delete mode 100755 bin/clean_test_db.js create mode 100644 bin/reset_test_db.js diff --git a/app/setup/postgres.js b/app/setup/postgres.js index 1673469f9..3c6467a59 100644 --- a/app/setup/postgres.js +++ b/app/setup/postgres.js @@ -2,31 +2,47 @@ import knexjs from 'knex'; import createDebug from 'debug'; import config from 'config'; +import { uniq } from 'lodash'; import { stylize } from '../support/debugLogger'; +import { getDbSchemaName } from '../support/parallel-testing'; + +/** @type {import("knex").Knex.Config} */ +const pgConfig = { ...config.postgres }; + +const schemaName = getDbSchemaName(); + +if (schemaName !== 'public') { + pgConfig.searchPath = uniq([schemaName, 'public', ...(pgConfig.searchPath || [])]); +} -const knex = knexjs(config.postgres); const log = createDebug('freefeed:sql'); const errLog = createDebug('freefeed:sql:error'); -knex.on('start', (builder) => { - const q = builder.toString(); - const start = new Date().getTime(); +let knex = null; +export function connect() { + if (knex) { + return knex; + } - builder.on('end', () => { - log('%s %s', q, stylize(`[took ${new Date().getTime() - start}ms]`, 'green')); - }); + knex = knexjs(pgConfig); + knex.on('start', (builder) => { + const q = builder.toString(); + const start = new Date().getTime(); - builder.on('error', () => { - errLog('%s %s', stylize('ERROR', 'red'), q); + builder.on('end', () => { + log('%s %s', q, stylize(`[took ${new Date().getTime() - start}ms]`, 'green')); + }); + + builder.on('error', () => { + errLog('%s %s', stylize('ERROR', 'red'), q); + }); }); -}); -export function connect() { return knex; } -export function setSearchConfig() { - const { textSearchConfigName } = config.postgres; - return knex.raw(`SET default_text_search_config TO '${textSearchConfigName}'`); +export async function setSearchConfig() { + const { textSearchConfigName } = pgConfig; + await knex.raw(`SET default_text_search_config TO '${textSearchConfigName}'`); } diff --git a/app/support/parallel-testing.ts b/app/support/parallel-testing.ts new file mode 100644 index 000000000..adb7bb586 --- /dev/null +++ b/app/support/parallel-testing.ts @@ -0,0 +1,18 @@ +export function getWorkerId(): number { + if (process.env.NODE_ENV !== 'test') { + return 0; + } + + let id = Number.parseInt(process.env.MOCHA_WORKER_ID || '0'); + + if (!Number.isFinite(id)) { + id = 0; + } + + return id; +} + +export function getDbSchemaName(): 'public' | string { + const workerId = getWorkerId(); + return workerId === 0 ? 'public' : `test${workerId}`; +} diff --git a/bin/clean_test_db.js b/bin/clean_test_db.js deleted file mode 100755 index 8067e6df8..000000000 --- a/bin/clean_test_db.js +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env babel-node -import knexLib from 'knex'; - -// Forcefully set the NODE_ENV to 'test' -const prevEnv = process.env.NODE_ENV; -process.env.NODE_ENV = 'test'; - -const config = require('../knexfile'); - -process.env.NODE_ENV = prevEnv; - -if (!('test' in config)) { - process.stderr.write(`Error: no "test" section in knexfile`); - process.exit(1); -} - -const knex = knexLib(config.test); - -async function run() { - await knex.raw('drop schema public cascade'); - await knex.raw('create schema public'); -} - -run() - .then(() => { - knex.destroy(); - process.exit(0); - }) - .catch((e) => { - process.stderr.write(`Error: ${e}\n`); - knex.destroy(); - process.exit(1); - }); diff --git a/bin/reset_test_db.js b/bin/reset_test_db.js new file mode 100644 index 000000000..8d0793a7e --- /dev/null +++ b/bin/reset_test_db.js @@ -0,0 +1,61 @@ +/* eslint-disable no-await-in-loop */ +import knexLib from 'knex'; +import parseArgs from 'minimist'; + +import { getDbSchemaName } from '../app/support/parallel-testing'; + +const args = parseArgs(process.argv.slice(2)); +let nSchemas = Number.parseInt(args['schemas']); + +if (!Number.isFinite(nSchemas) || nSchemas < 1) { + nSchemas = 1; +} + +// Forcefully set the NODE_ENV to 'test' +process.env.NODE_ENV = 'test'; + +const config = require('../knexfile'); + +if (!('test' in config)) { + process.stderr.write(`Error: no "test" section in knexfile`); + process.exit(1); +} + +const knex = knexLib(config.test); + +async function resetSchema(schemaName) { + console.log(`Resetting the ${schemaName} schema`); + await knex.raw(`drop schema if exists :schemaName: cascade`, { schemaName }); + await knex.raw(`create schema :schemaName:`, { schemaName }); +} + +async function run() { + // Public schema + await resetSchema('public'); + console.log(`Running migrations`); + await knex.migrate.latest(); + console.log(`Migration completed`); + + // Other schemas + for (let i = 1; i < nSchemas; i++) { + // Emulating MOCHA_WORKER_ID for proper schema name generation + process.env.MOCHA_WORKER_ID = i.toString(10); + const schemaName = getDbSchemaName(); + await resetSchema(schemaName); + console.log(`Running migrations on ${schemaName} schema`); + await knex.migrate.latest({ schemaName }); + console.log(`Migration completed on ${schemaName} schema`); + } +} + +run() + .then(() => { + knex.destroy(); + console.log(`All done.`); + process.exit(0); + }) + .catch((e) => { + process.stderr.write(`Error: ${e}\n`); + knex.destroy(); + process.exit(1); + }); diff --git a/migrations/20160405133637_initial.js b/migrations/20160405133637_initial.js index 402a822a8..253c3674f 100644 --- a/migrations/20160405133637_initial.js +++ b/migrations/20160405133637_initial.js @@ -1,18 +1,27 @@ +const { getDbSchemaName } = require('../app/support/parallel-testing'); + exports.up = function (knex) { + const schemaName = getDbSchemaName(); + const isPublicSchema = !schemaName || schemaName === 'public'; + return Promise.all([ - knex.raw('SET statement_timeout = 0'), - knex.raw('SET lock_timeout = 0'), - knex.raw("SET client_encoding = 'UTF8'"), - knex.raw('SET standard_conforming_strings = on'), - knex.raw('SET check_function_bodies = false'), - knex.raw('SET client_min_messages = warning'), - knex.raw('SET row_security = off'), - knex.raw('CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog'), - knex.raw('CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public'), - knex.raw('CREATE EXTENSION IF NOT EXISTS intarray WITH SCHEMA public'), - knex.raw('SET search_path = public, pg_catalog'), - knex.raw("SET default_tablespace = ''"), - knex.raw('SET default_with_oids = false'), + ...(isPublicSchema + ? [ + knex.raw('SET statement_timeout = 0'), + knex.raw('SET lock_timeout = 0'), + knex.raw("SET client_encoding = 'UTF8'"), + knex.raw('SET standard_conforming_strings = on'), + knex.raw('SET check_function_bodies = false'), + knex.raw('SET client_min_messages = warning'), + knex.raw('SET row_security = off'), + knex.raw('CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog'), + knex.raw('CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public'), + knex.raw('CREATE EXTENSION IF NOT EXISTS intarray WITH SCHEMA public'), + knex.raw('SET search_path = public, pg_catalog'), + knex.raw("SET default_tablespace = ''"), + knex.raw('SET default_with_oids = false'), + ] + : [knex.raw('SET search_path = :schemaName:, public, pg_catalog', { schemaName })]), knex.schema.createTable('users', function (table) { table.increments().notNullable().primary(); diff --git a/migrations/20161215174952_posts_privacy_flags.js b/migrations/20161215174952_posts_privacy_flags.js index c70e1b83e..f45f17076 100644 --- a/migrations/20161215174952_posts_privacy_flags.js +++ b/migrations/20161215174952_posts_privacy_flags.js @@ -7,7 +7,7 @@ export function up(knex) { }) .raw( `CREATE INDEX feeds_id_array_idx - ON public.feeds + ON feeds USING gin ((ARRAY[id]) gin__int_ops); `, @@ -15,7 +15,7 @@ export function up(knex) { // Trigger function for individual posts .raw( ` - CREATE OR REPLACE FUNCTION public.trgfun_set_post_privacy_on_insert_update() + CREATE OR REPLACE FUNCTION trgfun_set_post_privacy_on_insert_update() RETURNS trigger AS $BODY$ -- Set proper is_private and is_protected flags on post insert or update @@ -46,7 +46,7 @@ export function up(knex) { // Trigger function for users/groups .raw( ` - CREATE OR REPLACE FUNCTION public.trgfun_set_posts_privacy_on_user_update() + CREATE OR REPLACE FUNCTION trgfun_set_posts_privacy_on_user_update() RETURNS trigger AS $BODY$ -- Set proper is_private and is_protected flags on all user's posts when the user changes his privacy @@ -107,17 +107,17 @@ export function up(knex) { .raw( `CREATE TRIGGER trg_set_post_privacy_on_insert_update BEFORE INSERT OR UPDATE OF destination_feed_ids - ON public.posts + ON posts FOR EACH ROW - EXECUTE PROCEDURE public.trgfun_set_post_privacy_on_insert_update();`, + EXECUTE PROCEDURE trgfun_set_post_privacy_on_insert_update();`, ) .raw( `CREATE TRIGGER trg_set_posts_privacy_on_user_update AFTER UPDATE OF is_private, is_protected - ON public.users + ON users FOR EACH ROW WHEN (((old.is_protected <> new.is_protected) OR (old.is_private <> new.is_private))) - EXECUTE PROCEDURE public.trgfun_set_posts_privacy_on_user_update();`, + EXECUTE PROCEDURE trgfun_set_posts_privacy_on_user_update();`, ) // Data migration .raw('update posts set destination_feed_ids = destination_feed_ids') diff --git a/migrations/20171205142923_post_is_propagable.js b/migrations/20171205142923_post_is_propagable.js index a4d10e741..fe07f2387 100644 --- a/migrations/20171205142923_post_is_propagable.js +++ b/migrations/20171205142923_post_is_propagable.js @@ -10,7 +10,7 @@ export async function up(knex) { // Trigger function to update 'is_propagable' flag .raw( ` - CREATE OR REPLACE FUNCTION public.trgfun_set_post_is_propagable_on_insert_update() + CREATE OR REPLACE FUNCTION trgfun_set_post_is_propagable_on_insert_update() RETURNS trigger AS $BODY$ -- Set 'is_propagable' post flag on insert or update. @@ -36,9 +36,9 @@ export async function up(knex) { .raw( `CREATE TRIGGER trg_set_post_is_propagable_on_insert_update BEFORE INSERT OR UPDATE OF destination_feed_ids - ON public.posts + ON posts FOR EACH ROW - EXECUTE PROCEDURE public.trgfun_set_post_is_propagable_on_insert_update();`, + EXECUTE PROCEDURE trgfun_set_post_is_propagable_on_insert_update();`, ) // Data migration .raw( diff --git a/package.json b/package.json index 6eaf0cef8..d1761ccfc 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "eslint": "eslint . --ext \".js,.jsx,.ts\"", "babel": "node -r './esm/register.cjs'", "typecheck": "tsc", - "reset-test-db": "run-s \"babel bin/clean_test_db.js\" && knex --env test migrate:latest", + "reset-test-db": "run-s \"babel bin/reset_test_db.js\"", "test-rollback": "knex --env test migrate:rollback && knex --env test migrate:latest", "test-just": "cross-env NODE_ENV=test FRFS_SECRET=test-secret mocha", "mocha": "cross-env TZ=UTC run-s \"test-just -b test/unit test/integration test/functional test/cleanup.js\"", @@ -131,6 +131,7 @@ "@types/koa-static": "~4.0.4", "@types/koa__router": "~12.0.4", "@types/lodash": "~4.17.0", + "@types/minimist": "^1", "@types/mocha": "~10.0.6", "@types/n3": "~1.16.4", "@types/node": "~18.19.31", @@ -156,6 +157,7 @@ "eslint-plugin-promise": "~6.1.1", "eslint-plugin-you-dont-need-lodash-underscore": "~6.14.0", "mailparser": "~3.7.0", + "minimist": "~1.2.8", "mkdirp": "~3.0.1", "mocha": "~10.4.0", "npm-run-all": "~4.1.5", diff --git a/test/dbCleaner.ts b/test/dbCleaner.ts index 01cabc25a..a57ce063d 100644 --- a/test/dbCleaner.ts +++ b/test/dbCleaner.ts @@ -1,10 +1,13 @@ import pgFormat from 'pg-format'; import { type Knex } from 'knex'; +import { getDbSchemaName } from '../app/support/parallel-testing'; + const tablesToKeep = ['admin_roles', 'event_types']; -export default function cleanDB(knex: Knex) { - return knex.raw( +export default async function cleanDB(knex: Knex) { + const schemaName = getDbSchemaName(); + await knex.raw( ` do $$ declare @@ -14,7 +17,7 @@ export default function cleanDB(knex: Knex) { set session_replication_role = replica; for row in select tablename from pg_tables - where schemaname = 'public' + where schemaname = '${schemaName}' and tablename not in (${pgFormat(`%L`, tablesToKeep)}) loop execute format('delete from %I', row.tablename); diff --git a/yarn.lock b/yarn.lock index 528a49b1f..0b8106c62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2424,6 +2424,13 @@ __metadata: languageName: node linkType: hard +"@types/minimist@npm:^1": + version: 1.2.5 + resolution: "@types/minimist@npm:1.2.5" + checksum: 3f791258d8e99a1d7d0ca2bda1ca6ea5a94e5e7b8fc6cde84dd79b0552da6fb68ade750f0e17718f6587783c24254bbca0357648dd59dc3812c150305cabdc46 + languageName: node + linkType: hard + "@types/mocha@npm:~10.0.6": version: 10.0.6 resolution: "@types/mocha@npm:10.0.6" @@ -6178,6 +6185,7 @@ __metadata: "@types/koa-static": "npm:~4.0.4" "@types/koa__router": "npm:~12.0.4" "@types/lodash": "npm:~4.17.0" + "@types/minimist": "npm:^1" "@types/mocha": "npm:~10.0.6" "@types/n3": "npm:~1.16.4" "@types/node": "npm:~18.19.31" @@ -6246,6 +6254,7 @@ __metadata: mailparser: "npm:~3.7.0" media-type: "npm:~0.3.1" mime-types: "npm:~2.1.35" + minimist: "npm:~1.2.8" mkdirp: "npm:~3.0.1" mmmagic: "npm:~0.5.3" mocha: "npm:~10.4.0" @@ -8743,7 +8752,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.0, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.6": +"minimist@npm:^1.1.0, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.6, minimist@npm:~1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 From 2941e2bd306e6f2be675fde721709d1e7a7098b8 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sat, 4 May 2024 12:07:10 +0300 Subject: [PATCH 06/11] Use different ports in parallel tests --- app/app.js | 26 ++++++++++++++++++++++- app/freefeed-app.ts | 2 +- config/test.js | 6 ++++-- test/functional/functional_test_helper.js | 3 +-- test/functional/posts/leave-direct.js | 2 +- test/unit/support/rss-text-parser.ts | 5 +++-- 6 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/app.js b/app/app.js index 71c7a687c..c7ad36b3b 100644 --- a/app/app.js +++ b/app/app.js @@ -41,8 +41,10 @@ export async function getSingleton() { _app.context.pubsub = new PubsubListener(server, _app); - const port = process.env.PEPYATKA_SERVER_PORT || process.env.PORT || _app.context.config.port; + const port = getListeningPort(_app); await listen(port); + // The actual port + _app.context.port = server.address().port; const log = createDebug('freefeed:init'); @@ -56,3 +58,25 @@ export async function getSingleton() { lock.release(); } } + +function getListeningPort(_app) { + let port = validPortValue(process.env.PEPYATKA_SERVER_PORT); + + if (port === undefined) { + port = validPortValue(process.env.PORT); + } + + if (port === undefined) { + port = validPortValue(_app.context.config.port); + } + + return port ?? 0; +} + +function validPortValue(port) { + if (typeof port === 'number' && port >= 0 && port < 65536) { + return port; + } + + return undefined; +} diff --git a/app/freefeed-app.ts b/app/freefeed-app.ts index f795a9d54..9daf649f9 100644 --- a/app/freefeed-app.ts +++ b/app/freefeed-app.ts @@ -38,7 +38,7 @@ class FreefeedApp extends Application { } this.context.config = config; - this.context.port = process.env.PORT ? parseInt(process.env.PORT) : config.port; + this.context.port = 0; // to be configured on listen this.use(asyncContextMiddleware); diff --git a/config/test.js b/config/test.js index c602f4384..a9dab3af1 100644 --- a/config/test.js +++ b/config/test.js @@ -2,9 +2,11 @@ import { resolve } from 'path'; import stubTransport from 'nodemailer-stub-transport'; +import { getWorkerId } from '../app/support/parallel-testing'; + module.exports = { - port: 31337, - database: 3, + port: 31337 + getWorkerId(), + database: 3 + getWorkerId(), monitorPrefix: 'tests', application: { EXTRA_STOP_LIST: ['thatcreepyguy', 'nicegirlnextdoor', 'perfectstranger'] }, diff --git a/test/functional/functional_test_helper.js b/test/functional/functional_test_helper.js index 22400d29a..c13ff06a6 100644 --- a/test/functional/functional_test_helper.js +++ b/test/functional/functional_test_helper.js @@ -1016,8 +1016,7 @@ const PromisifiedIO = (host, options, events) => { export async function createRealtimeConnection(context, callbacks) { const app = await initApp(); - - const port = process.env.PEPYATKA_SERVER_PORT || app.context.port; + const { port } = app.context; const options = { transports: ['websocket'], forceNew: true, diff --git a/test/functional/posts/leave-direct.js b/test/functional/posts/leave-direct.js index 1017193c3..1266c3d3e 100644 --- a/test/functional/posts/leave-direct.js +++ b/test/functional/posts/leave-direct.js @@ -172,7 +172,7 @@ describe('POST /v2/posts/:postId/leave', () => { before(async () => { const app = await getSingleton(); - port = process.env.PEPYATKA_SERVER_PORT || app.context.config.port; + ({ port } = app.context); const pubsubAdapter = new PubSubAdapter($database); PubSub.setPublisher(pubsubAdapter); }); diff --git a/test/unit/support/rss-text-parser.ts b/test/unit/support/rss-text-parser.ts index 464393e6a..429c02968 100644 --- a/test/unit/support/rss-text-parser.ts +++ b/test/unit/support/rss-text-parser.ts @@ -1,4 +1,5 @@ /* eslint-env node, mocha */ +import config from 'config'; import expect from 'unexpected'; import { extractTitle, textToHTML } from '../../../app/support/rss-text-parser'; @@ -50,10 +51,10 @@ describe('textToHTML function', () => { In the forests of the night,
What immortal.com hand or eye Dare frame thy fearful #symmetry?`; - const expected = `

Tiger, @tiger, burning bright
+ const expected = `

Tiger, @tiger, burning bright
In the forests of the night,<br>
What immortal.com hand or eye
-Dare frame thy fearful #symmetry?

`; +Dare frame thy fearful #symmetry?

`; expect(textToHTML(input), 'to be', expected); }); }); From 3414eb62af88fec794d1ea99fcecd1ecee685c8d Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sat, 4 May 2024 12:17:09 +0300 Subject: [PATCH 07/11] Update testing node script --- package.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index d1761ccfc..e5ba0c96e 100644 --- a/package.json +++ b/package.json @@ -8,17 +8,18 @@ "scripts": { "start": "cross-env TZ=UTC yarn babel index.js", "travis": "run-s -c typecheck test lint", - "test": "run-s typecheck reset-test-db test-rollback mocha", + "test": "run-s typecheck reset-test-db test-rollback mocha-p", "coverage": "run-s reset-test-db nyc", "lint": "run-s eslint ejslint", "ejslint": "ejslint app", "eslint": "eslint . --ext \".js,.jsx,.ts\"", "babel": "node -r './esm/register.cjs'", "typecheck": "tsc", - "reset-test-db": "run-s \"babel bin/reset_test_db.js\"", + "reset-test-db": "run-s \"babel bin/reset_test_db.js --schemas=4\"", "test-rollback": "knex --env test migrate:rollback && knex --env test migrate:latest", "test-just": "cross-env NODE_ENV=test FRFS_SECRET=test-secret mocha", "mocha": "cross-env TZ=UTC run-s \"test-just -b test/unit test/integration test/functional test/cleanup.js\"", + "mocha-p": "cross-env TZ=UTC run-s \"test-just -b -p -j 4 test/unit test/integration test/functional test/cleanup.js\"", "console": "yarn babel bin/console", "nyc": "nyc yarn mocha", "data_transfer": "yarn babel bin/data_transfer", From 4232a1e33b8df3e262504736ebc3d8deb64abe80 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sun, 5 May 2024 16:31:08 +0300 Subject: [PATCH 08/11] Move some tests settings to the config --- config/default.js | 7 +++++++ test/functional/realtime-session.js | 5 ++--- test/functional/realtime_assertions.js | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/config/default.js b/config/default.js index af17a071b..f5e18d6c3 100644 --- a/config/default.js +++ b/config/default.js @@ -503,4 +503,11 @@ config.translation = { apiKey: 'OVERRIDE_IT', }; +config.tests = { + realtime: { + eventTimeout: 2000, + silenceTimeout: 500, + }, +}; + module.exports = config; diff --git a/test/functional/realtime-session.js b/test/functional/realtime-session.js index 821074807..09a848cd7 100644 --- a/test/functional/realtime-session.js +++ b/test/functional/realtime-session.js @@ -1,11 +1,10 @@ import socketIO from 'socket.io-client'; import socketIOModern from 'socket.io-client-modern'; +import config from 'config'; import { API_VERSION_ACTUAL } from '../../app/api-versions'; -const eventTimeout = 2000; -const silenceTimeout = 500; - +const { eventTimeout, silenceTimeout } = config.tests.realtime; /** * Session is a helper class * for the realtime testing diff --git a/test/functional/realtime_assertions.js b/test/functional/realtime_assertions.js index 24237192d..e010b1bb0 100644 --- a/test/functional/realtime_assertions.js +++ b/test/functional/realtime_assertions.js @@ -1,12 +1,12 @@ import socketIO from 'socket.io-client'; +import config from 'config'; import { API_VERSION_ACTUAL } from '../../app/api-versions'; import { getSingleton as initApp } from '../../app/app'; import * as funcTestHelper from './functional_test_helper'; -const eventTimeout = 2000; -const silenceTimeout = 600; +const { eventTimeout, silenceTimeout } = config.tests.realtime; class Session { socket = null; From 6eb5c74a9e582775198981a285e7e14a2f26f762 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sun, 5 May 2024 16:32:57 +0300 Subject: [PATCH 09/11] Set tests concurrency using the TEST_THREADS environment variable --- package.json | 14 ++++++-------- yarn.lock | 15 +-------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index e5ba0c96e..b413ad048 100644 --- a/package.json +++ b/package.json @@ -6,22 +6,21 @@ "version": "2.20.0", "private": true, "scripts": { - "start": "cross-env TZ=UTC yarn babel index.js", + "start": "TZ=UTC yarn babel index.js", "travis": "run-s -c typecheck test lint", - "test": "run-s typecheck reset-test-db test-rollback mocha-p", + "test": "run-s typecheck reset-test-db test-rollback test-all", "coverage": "run-s reset-test-db nyc", "lint": "run-s eslint ejslint", "ejslint": "ejslint app", "eslint": "eslint . --ext \".js,.jsx,.ts\"", "babel": "node -r './esm/register.cjs'", "typecheck": "tsc", - "reset-test-db": "run-s \"babel bin/reset_test_db.js --schemas=4\"", + "reset-test-db": "run-s \"babel bin/reset_test_db.js --schemas ${TEST_THREADS:-1}\"", "test-rollback": "knex --env test migrate:rollback && knex --env test migrate:latest", - "test-just": "cross-env NODE_ENV=test FRFS_SECRET=test-secret mocha", - "mocha": "cross-env TZ=UTC run-s \"test-just -b test/unit test/integration test/functional test/cleanup.js\"", - "mocha-p": "cross-env TZ=UTC run-s \"test-just -b -p -j 4 test/unit test/integration test/functional test/cleanup.js\"", + "test-just": "NODE_ENV=test FRFS_SECRET=test-secret mocha -p -j ${TEST_THREADS:-1}", + "test-all": "TZ=UTC run-s \"test-just -b test/unit test/integration test/functional test/cleanup.js\"", "console": "yarn babel bin/console", - "nyc": "nyc yarn mocha", + "nyc": "nyc yarn test-all", "data_transfer": "yarn babel bin/data_transfer", "reindex_hashtags": "yarn babel bin/reindex_hashtags", "notification_emails": "yarn babel bin/notification_emails", @@ -146,7 +145,6 @@ "@typescript-eslint/parser": "~6.19.1", "chai": "5.1.0", "chai-fs": "~2.0.0", - "cross-env": "~7.0.3", "ejs-lint": "~2.0.0", "esbuild": "~0.20.2", "eslint": "~8.56.0", diff --git a/yarn.lock b/yarn.lock index 0b8106c62..dcfe908ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4238,18 +4238,6 @@ __metadata: languageName: node linkType: hard -"cross-env@npm:~7.0.3": - version: 7.0.3 - resolution: "cross-env@npm:7.0.3" - dependencies: - cross-spawn: "npm:^7.0.1" - bin: - cross-env: src/bin/cross-env.js - cross-env-shell: src/bin/cross-env-shell.js - checksum: f3765c25746c69fcca369655c442c6c886e54ccf3ab8c16847d5ad0e91e2f337d36eedc6599c1227904bf2a228d721e690324446876115bc8e7b32a866735ecf - languageName: node - linkType: hard - "cross-spawn@npm:^4.0.0": version: 4.0.2 resolution: "cross-spawn@npm:4.0.2" @@ -4284,7 +4272,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": version: 7.0.3 resolution: "cross-spawn@npm:7.0.3" dependencies: @@ -6213,7 +6201,6 @@ __metadata: commander: "npm:~11.1.0" config: "npm:~3.3.11" console-stamp: "npm:~3.1.2" - cross-env: "npm:~7.0.3" debug: "npm:~4.3.4" ejs: "npm:~3.1.10" ejs-lint: "npm:~2.0.0" From 79265a4c65aeb717f2f34c9530f664986d1a2443 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sun, 5 May 2024 16:36:14 +0300 Subject: [PATCH 10/11] Use 4 test threads in Github CI --- .github/workflows/checks.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 8248de182..01daf2a74 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -67,4 +67,6 @@ jobs: run: yarn lint - name: run tests + env: + TEST_THREADS: 4 run: yarn test From 94504b844310f79ab0cd7efd0612040a74a4e976 Mon Sep 17 00:00:00 2001 From: David Mzareulyan Date: Sun, 5 May 2024 16:49:00 +0300 Subject: [PATCH 11/11] Set thread-unique name for the MAINTENANCE file --- config/test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/test.js b/config/test.js index a9dab3af1..8832e540a 100644 --- a/config/test.js +++ b/config/test.js @@ -50,6 +50,8 @@ module.exports = { registrationsLimit: { maxCount: 10 }, + maintenance: { messageFile: `tmp/MAINTENANCE${getWorkerId()}.txt` }, + userPreferences: { defaults: { // User does't want to view banned comments by default (for compatibility