diff --git a/src/write-review/write-review-add-authors.ts b/src/write-review/write-review-add-authors.ts index a3e017d77..ba99da301 100644 --- a/src/write-review/write-review-add-authors.ts +++ b/src/write-review/write-review-add-authors.ts @@ -1,12 +1,14 @@ import { format } from 'fp-ts-routing' import * as E from 'fp-ts/Either' +import * as O from 'fp-ts/Option' import { Reader } from 'fp-ts/Reader' import { flow, pipe } from 'fp-ts/function' import { Status, StatusOpen } from 'hyper-ts' +import * as M from 'hyper-ts/lib/Middleware' import * as RM from 'hyper-ts/lib/ReaderMiddleware' import * as D from 'io-ts/Decoder' import { get } from 'spectacles-ts' -import { match } from 'ts-pattern' +import { P, match } from 'ts-pattern' import { canAddAuthors } from '../feature-flags' import { MissingE, hasAnError, missingE } from '../form' import { html, plainText, rawHtml, sendHtml } from '../html' @@ -42,6 +44,10 @@ export const writeReviewAddAuthors = flow( RM.apSW('method', RM.fromMiddleware(getMethod)), RM.ichainW(state => match(state) + .with( + { canAddAuthors: true, form: { moreAuthors: 'yes', otherAuthors: P.optional([]) } }, + fromMiddlewareK(() => seeOther(format(writeReviewAddAuthorMatch.formatter, { doi: preprint.doi }))), + ) .with({ canAddAuthors: true, form: { moreAuthors: 'yes' }, method: 'POST' }, handleAddAuthorsForm) .with({ canAddAuthors: true, form: { moreAuthors: 'yes' } }, showAddAuthorsForm) .with({ form: { moreAuthors: 'yes' }, method: 'POST' }, handleCannotAddAuthorsForm) @@ -268,6 +274,14 @@ function cannotAddAuthorsForm(preprint: Preprint) { }) } +// https://github.com/DenisFrezzato/hyper-ts/pull/83 +const fromMiddlewareK = + , B, I, O, E>( + f: (...a: A) => M.Middleware, + ): ((...a: A) => RM.ReaderMiddleware) => + (...a) => + RM.fromMiddleware(f(...a)) + // https://github.com/DenisFrezzato/hyper-ts/pull/85 function fromReaderK, B, I = StatusOpen, E = never>( f: (...a: A) => Reader, diff --git a/test/write-review/write-review-add-authors.test.ts b/test/write-review/write-review-add-authors.test.ts index 6f6d01335..010201dfe 100644 --- a/test/write-review/write-review-add-authors.test.ts +++ b/test/write-review/write-review-add-authors.test.ts @@ -100,7 +100,7 @@ describe('writeReviewAddAuthors', () => { competingInterestsDetails: fc.lorem(), conduct: fc.constant('yes'), moreAuthors: fc.constant('yes'), - otherAuthors: fc.array( + otherAuthors: fc.nonEmptyArray( fc.record({ name: fc.nonEmptyString(), orcid: fc.orcid() }, { requiredKeys: ['name'] }), ), persona: fc.constantFrom('public', 'pseudonym'), @@ -214,6 +214,70 @@ describe('writeReviewAddAuthors', () => { expect(getPreprintTitle).toHaveBeenCalledWith(preprintDoi) }, ) + + fc.test( + 'when there are no other authors yet', + [ + fc.preprintDoi(), + fc.record({ title: fc.html(), language: fc.languageCode() }), + fc.tuple(fc.uuid(), fc.string()).chain(([sessionId, secret]) => + fc.tuple( + fc.connection({ + headers: fc.constant({ Cookie: `session=${cookieSignature.sign(sessionId, secret)}` }), + }), + fc.constant(sessionId), + fc.constant(secret), + ), + ), + fc.user(), + fc.record( + { + competingInterests: fc.constantFrom('yes', 'no'), + competingInterestsDetails: fc.lorem(), + conduct: fc.constant('yes'), + moreAuthors: fc.constant('yes'), + otherAuthors: fc.constant([]), + persona: fc.constantFrom('public', 'pseudonym'), + review: fc.nonEmptyString(), + }, + { requiredKeys: ['moreAuthors'] }, + ), + ], + async (preprintDoi, preprintTitle, [connection, sessionId, secret], user, newReview) => { + const sessionStore = new Keyv() + await sessionStore.set(sessionId, UserC.encode(user)) + const formStore = new Keyv() + await formStore.set(`${user.orcid}_${preprintDoi}`, newReview) + const getPreprintTitle: jest.MockedFunction<_.GetPreprintTitleEnv['getPreprintTitle']> = jest.fn(_ => + TE.right(preprintTitle), + ) + const actual = await runMiddleware( + _.writeReviewAddAuthors(preprintDoi)({ + canAddAuthors: () => true, + formStore, + getPreprintTitle, + secret, + sessionStore, + }), + connection, + )() + + expect(actual).toStrictEqual( + E.right([ + { type: 'setStatus', status: Status.SeeOther }, + { + type: 'setHeader', + name: 'Location', + value: `/preprints/doi-${encodeURIComponent( + preprintDoi.toLowerCase().replaceAll('-', '+').replaceAll('/', '-'), + )}/write-a-prereview/add-author`, + }, + { type: 'endResponse' }, + ]), + ) + expect(getPreprintTitle).toHaveBeenCalledWith(preprintDoi) + }, + ) }) describe('when authors cannot be added', () => {