From 8d869003761e0af622d15937d146f510c3d68254 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 18 Sep 2018 16:59:32 -0600 Subject: [PATCH] feat: added support for action creation via edit --- src/core/server/services/comments/index.ts | 133 ++++++++++++--------- 1 file changed, 77 insertions(+), 56 deletions(-) diff --git a/src/core/server/services/comments/index.ts b/src/core/server/services/comments/index.ts index 0c0073b9f..6a359cee3 100644 --- a/src/core/server/services/comments/index.ts +++ b/src/core/server/services/comments/index.ts @@ -94,6 +94,81 @@ export async function create( return comment; } +export type EditComment = Omit< + EditCommentInput, + "status" | "author_id" | "lastEditableCommentCreatedAt" +>; + +export async function edit( + mongo: Db, + tenant: Tenant, + author: User, + input: EditComment, + req?: Request +) { + // Get the comment that we're editing. + let comment = await retrieveComment(mongo, tenant.id, input.id); + if (!comment) { + // TODO: replace to match error returned by the models/comments.ts + throw new Error("comment not found"); + } + + // Grab the asset that we'll use to check moderation pieces with. + const asset = await retrieveAsset(mongo, tenant.id, comment.asset_id); + if (!asset) { + // TODO: (wyattjoh) return better error. + throw new Error("asset referenced does not exist"); + } + + // Run the comment through the moderation phases. + const { status, metadata, actions } = await processForModeration({ + asset, + tenant, + comment: input, + author, + req, + }); + + comment = await editComment(mongo, tenant.id, { + id: input.id, + author_id: author.id, + body: input.body, + status, + metadata, + // The editable time is based on the current time, and the edit window + // length. By subtracting the current date from the edit window length, we + // get the maximum value for the `created_at` time that would be permitted + // for the comment edit to succeed. + lastEditableCommentCreatedAt: new Date( + Date.now() - tenant.editCommentWindowLength + ), + }); + if (!comment) { + // TODO: replace to match error returned by the models/comments.ts + throw new Error("comment not found"); + } + + if (actions.length > 0) { + // The actions coming from the moderation phases didn't know the item_id + // at the time, and we didn't want the repetitive nature of adding the + // item_type each time, so this mapping function adds them! + const inputs = actions.map( + (action): CreateActionInput => ({ + ...action, + // Strict null check seems to have failed here... Null checking was done + // above where we errored if the comment was falsely. + item_id: comment!.id, + item_type: ACTION_ITEM_TYPE.COMMENTS, + }) + ); + + // Insert and handle creating the actions. + comment = await addCommentActions(mongo, tenant, comment, inputs); + } + + return comment; +} + async function addCommentActions( mongo: Db, tenant: Tenant, @@ -103,7 +178,8 @@ async function addCommentActions( // Create each of the actions, returning each of the action results. const results = await createActions(mongo, tenant.id, inputs); - // Get the actions that were upserted. + // Get the actions that were upserted, we only want to increment the action + // counts of actions that were just created. const upsertedActions = results .filter(({ wasUpserted }) => wasUpserted) .map(({ action }) => action); @@ -132,58 +208,3 @@ async function addCommentActions( return comment; } - -export type EditComment = Omit< - EditCommentInput, - "status" | "author_id" | "lastEditableCommentCreatedAt" ->; - -export async function edit( - mongo: Db, - tenant: Tenant, - author: User, - input: EditComment, - req?: Request -) { - // Get the comment that we're editing. - let comment = await retrieveComment(mongo, tenant.id, input.id); - if (!comment) { - // TODO: replace to match error returned by the models/comments.ts - throw new Error("comment not found"); - } - - // Grab the asset that we'll use to check moderation pieces with. - const asset = await retrieveAsset(mongo, tenant.id, comment.asset_id); - if (!asset) { - // TODO: (wyattjoh) return better error. - throw new Error("asset referenced does not exist"); - } - - // Run the comment through the moderation phases. - const { status, metadata } = await processForModeration({ - asset, - tenant, - comment: input, - author, - req, - }); - - // TODO: (wyattjoh) use the actions somehow. - - comment = await editComment(mongo, tenant.id, { - id: input.id, - author_id: author.id, - body: input.body, - status, - metadata, - // The editable time is based on the current time, and the edit window - // length. By subtracting the current date from the edit window length, we - // get the maximum value for the `created_at` time that would be permitted - // for the comment edit to succeed. - lastEditableCommentCreatedAt: new Date( - Date.now() - tenant.editCommentWindowLength - ), - }); - - return comment; -}