Skip to content

Commit

Permalink
Require agreement to the Code of Conduct
Browse files Browse the repository at this point in the history
Refs #1973
  • Loading branch information
thewilkybarkid committed Oct 2, 2024
1 parent e07079b commit f920951
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 22 deletions.
21 changes: 17 additions & 4 deletions integration/writing-feedback.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Doi } from 'doi-ts'
import { Orcid } from 'orcid-id-ts'
import path from 'path'
import { URL } from 'url'
import { type Record, RecordC, RecordsC } from 'zenodo-ts'
import { areLoggedIn, canLogIn, canWriteFeedback, expect, test, willPublishFeedback } from './base.js'
Expand Down Expand Up @@ -90,6 +89,8 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback).extend(willPu
await (javaScriptEnabled ? page.keyboard.press('Control+b') : page.keyboard.type('</b>'))
await page.keyboard.type('.')
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.getByLabel('I’m following the Code of Conduct').check()
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.getByRole('button', { name: 'Publish feedback' }).click()

await expect(page.getByRole('heading', { level: 1 })).toHaveText('We’re publishing your feedback')
Expand Down Expand Up @@ -185,6 +186,8 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback)(
await page.waitForLoadState()
await page.getByLabel('Write your feedback').fill('Lorem ipsum dolor sit amet, consectetur adipiscing elit.')
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.getByLabel('I’m following the Code of Conduct').check()
await page.getByRole('button', { name: 'Save and continue' }).click()

await expect(page.getByRole('region', { name: 'Your feedback' })).toContainText(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
Expand Down Expand Up @@ -287,7 +290,7 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback)(

await page.getByRole('button', { name: 'Continue' }).click()

await expect(page.getByRole('heading', { level: 1 })).toHaveText('Check your feedback')
await expect(page.getByRole('heading', { level: 1 })).toHaveText('Code of Conduct')
},
)

Expand Down Expand Up @@ -366,11 +369,17 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback)(
await page.waitForLoadState()
await page.getByLabel('Write your feedback').fill('Lorem ipsum dolor sit amet, consectetur adipiscing elit.')
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.getByLabel('I’m following the Code of Conduct').check()
await page.getByRole('button', { name: 'Save and continue' }).click()

await expect(page.getByRole('heading', { level: 1 })).toContainText('Check your feedback')

await page.goBack()

await expect(page.getByLabel('I’m following the Code of Conduct')).toBeChecked()

await page.goBack()

if (javaScriptEnabled) {
await expect(page.getByLabel('Write your feedback')).toHaveText(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
Expand Down Expand Up @@ -462,11 +471,17 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback)(
await page.waitForLoadState()
await page.getByLabel('Write your feedback').fill('Lorem ipsum dolor sit amet, consectetur adipiscing elit.')
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.getByLabel('I’m following the Code of Conduct').check()
await page.getByRole('button', { name: 'Save and continue' }).click()

await expect(page.getByRole('heading', { level: 1 })).toContainText('Check your feedback')

await page.getByRole('navigation').getByRole('link', { name: 'Back' }).click()

await expect(page.getByLabel('I’m following the Code of Conduct')).toBeChecked()

await page.getByRole('navigation').getByRole('link', { name: 'Back' }).click()

if (javaScriptEnabled) {
await expect(page.getByLabel('Write your feedback')).toHaveText(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
Expand Down Expand Up @@ -642,8 +657,6 @@ test.extend(canLogIn).extend(areLoggedIn).extend(canWriteFeedback)(
await page.waitForLoadState()
await page.getByLabel('Write your feedback').fill('Lorem ipsum dolor sit amet, consectetur adipiscing elit.')
await page.getByRole('button', { name: 'Save and continue' }).click()
await page.goto(`${path.dirname(page.url())}/code-of-conduct`)
await page.getByLabel('I’m following the Code of Conduct').uncheck()

await page.getByRole('button', { name: 'Save and continue' }).click()

Expand Down
20 changes: 16 additions & 4 deletions src/Feedback/Evolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ const onFeedbackWasEntered = (event: Events.FeedbackWasEntered) =>
flow(
Match.value<State.FeedbackState>,
Match.tag('FeedbackNotStarted', identity),
Match.tag(
'FeedbackInProgress',
state => new State.FeedbackReadyForPublishing({ ...state, feedback: event.feedback }),
),
Match.tag('FeedbackInProgress', state => new State.FeedbackInProgress({ ...state, feedback: event.feedback })),
Match.tag(
'FeedbackReadyForPublishing',
state => new State.FeedbackReadyForPublishing({ ...state, feedback: event.feedback }),
Expand Down Expand Up @@ -82,4 +79,19 @@ export const EvolveFeedback = (state: State.FeedbackState): ((event: Events.Feed
Match.tag('FeedbackWasPublished', onFeedbackWasPublished),
Match.exhaustive,
Function.apply(state)<State.FeedbackState>,
checkIsReadyForPublication,
)

const checkIsReadyForPublication = (state: State.FeedbackState) => {
if (state._tag !== 'FeedbackInProgress') {
return state
}

const { codeOfConductAgreed, feedback, ...rest } = state

if (typeof feedback !== 'object' || codeOfConductAgreed !== true) {
return state
}

return new State.FeedbackReadyForPublishing({ ...rest, feedback })
}
2 changes: 1 addition & 1 deletion src/WriteFeedbackFlow/CheckPage/CheckPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const CheckPage = ({
}) =>
StreamlinePageResponse({
title: plainText(translate(locale, 'write-feedback-flow', 'checkTitle')()),
nav: html` <a href="${Routes.WriteFeedbackEnterFeedback.href({ feedbackId })}" class="back"
nav: html` <a href="${Routes.WriteFeedbackCodeOfConduct.href({ feedbackId })}" class="back"
>${translate(locale, 'write-feedback-flow', 'back')()}</a
>`,
main: html`
Expand Down
44 changes: 41 additions & 3 deletions src/WriteFeedbackFlow/DecideNextPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,63 @@ import type * as Feedback from '../Feedback/index.js'
import * as Routes from '../routes.js'
import type { Uuid } from '../types/index.js'

const onInProgressState = pipe(
Match.type<Feedback.FeedbackInProgress>(),
Match.withReturnType<Routes.Route<{ feedbackId: Uuid.Uuid }>>(),
Match.when(
state => typeof state.feedback === 'undefined',
() => Routes.WriteFeedbackEnterFeedback,
),
Match.when(
state => typeof state.codeOfConductAgreed === 'undefined',
() => Routes.WriteFeedbackCodeOfConduct,
),
Match.orElse(() => Routes.WriteFeedbackCheck),
)

export const NextPageFromState = pipe(
Match.type<Exclude<Feedback.FeedbackState, Feedback.FeedbackNotStarted>>(),
Match.withReturnType<Routes.Route<{ feedbackId: Uuid.Uuid }>>(),
Match.tag('FeedbackInProgress', () => Routes.WriteFeedbackEnterFeedback),
Match.tag('FeedbackInProgress', onInProgressState),
Match.tag('FeedbackReadyForPublishing', () => Routes.WriteFeedbackCheck),
Match.tag('FeedbackBeingPublished', () => Routes.WriteFeedbackPublishing),
Match.tag('FeedbackPublished', () => Routes.WriteFeedbackPublished),
Match.exhaustive,
)

const onInProgressCommand = pipe(
Match.type<{
command: (Feedback.EnterFeedback | Feedback.AgreeToCodeOfConduct)['_tag']
feedback: Feedback.FeedbackState
}>(),
Match.withReturnType<Routes.Route<{ feedbackId: Uuid.Uuid }>>(),
Match.when(
{
command: command => command !== 'EnterFeedback',
feedback: feedback => feedback._tag === 'FeedbackInProgress' && typeof feedback.feedback === 'undefined',
},
() => Routes.WriteFeedbackEnterFeedback,
),
Match.when(
{
command: command => command !== 'AgreeToCodeOfConduct',
feedback: feedback =>
feedback._tag === 'FeedbackInProgress' && typeof feedback.codeOfConductAgreed === 'undefined',
},
() => Routes.WriteFeedbackCodeOfConduct,
),
Match.orElse(() => Routes.WriteFeedbackCheck),
)

export const NextPageAfterCommand = pipe(
Match.type<{
command: Exclude<Feedback.FeedbackCommand, Feedback.MarkFeedbackAsPublished>['_tag']
feedback: Feedback.FeedbackState
}>(),
Match.withReturnType<Routes.Route<{ feedbackId: Uuid.Uuid }>>(),
Match.when({ command: 'StartFeedback' }, () => Routes.WriteFeedbackEnterFeedback),
Match.when({ command: 'EnterFeedback' }, () => Routes.WriteFeedbackCheck),
Match.when({ command: 'AgreeToCodeOfConduct' }, () => Routes.WriteFeedbackCheck),
Match.when({ command: 'EnterFeedback' }, onInProgressCommand),
Match.when({ command: 'AgreeToCodeOfConduct' }, onInProgressCommand),
Match.when({ command: 'PublishFeedback' }, () => Routes.WriteFeedbackPublishing),
Match.exhaustive,
)
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const fromBody = (body: unknown) =>

export const fromFeedback = pipe(
Match.type<Feedback.FeedbackInProgress | Feedback.FeedbackReadyForPublishing>(),
Match.tag('FeedbackInProgress', () => new EmptyForm()),
Match.tag('FeedbackInProgress', ({ feedback }) => (feedback ? new CompletedForm({ feedback }) : new EmptyForm())),
Match.tag('FeedbackReadyForPublishing', ({ feedback }) => new CompletedForm({ feedback })),
Match.exhaustive,
)
Expand Down
17 changes: 16 additions & 1 deletion test/Feedback/Feedback.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ describe('when ready for publication', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
)
.when(new _.StartFeedback({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }))
.thenError(new _.FeedbackWasAlreadyStarted()))
Expand All @@ -79,6 +80,7 @@ describe('when ready for publication', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
)
.when(new _.EnterFeedback({ feedback: html`<p>Some different feedback.</p>` }))
.then(new _.FeedbackWasEntered({ feedback: html`<p>Some different feedback.</p>` })))
Expand All @@ -87,6 +89,7 @@ describe('when ready for publication', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
)
.when(new _.AgreeToCodeOfConduct())
.then())
Expand All @@ -95,6 +98,7 @@ describe('when ready for publication', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
)
.when(new _.PublishFeedback())
.then(new _.FeedbackPublicationWasRequested()))
Expand All @@ -103,6 +107,7 @@ describe('when ready for publication', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
)
.when(new _.MarkFeedbackAsPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }))
.then(new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') })))
Expand All @@ -113,6 +118,7 @@ describe('when being published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackPublicationWasRequested(),
)
.when(new _.StartFeedback({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }))
Expand All @@ -122,6 +128,7 @@ describe('when being published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackPublicationWasRequested(),
)
.when(new _.EnterFeedback({ feedback: html`<p>Some different feedback.</p>` }))
Expand All @@ -131,6 +138,7 @@ describe('when being published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackPublicationWasRequested(),
)
.when(new _.AgreeToCodeOfConduct())
Expand All @@ -140,6 +148,7 @@ describe('when being published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackPublicationWasRequested(),
)
.when(new _.PublishFeedback())
Expand All @@ -149,6 +158,7 @@ describe('when being published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackPublicationWasRequested(),
)
.when(new _.MarkFeedbackAsPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }))
Expand All @@ -160,6 +170,7 @@ describe('when published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }),
)
.when(new _.StartFeedback({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }))
Expand All @@ -169,15 +180,17 @@ describe('when published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }),
)
.when(new _.EnterFeedback({ feedback: html`<p>Some different feedback.</p>` }))
.thenError(new _.FeedbackWasAlreadyPublished()))

test('cannot agree to the code of conduct', () =>
test('cannot re-agree to the code of conduct', () =>
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }),
)
.when(new _.AgreeToCodeOfConduct())
Expand All @@ -187,6 +200,7 @@ describe('when published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }),
)
.when(new _.PublishFeedback())
Expand All @@ -196,6 +210,7 @@ describe('when published', () => {
given(
new _.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
new _.FeedbackWasEntered({ feedback: html`<p>Some feedback.</p>` }),
new _.CodeOfConductWasAgreed(),
new _.FeedbackWasPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }),
)
.when(new _.MarkFeedbackAsPublished({ id: 107286, doi: Doi('10.5072/zenodo.107286') }))
Expand Down
25 changes: 25 additions & 0 deletions test/Feedback/Queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ describe('GetAllUnpublishedFeedbackByAnAuthorForAPrereview', () => {
event: new Feedback.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
resourceId: '358f7fc0-9725-4192-8673-d7c64f398401' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
resourceId: '51a9ea9e-a960-4b51-83a5-9901a47690c2' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackWasEntered({ feedback: html`Some text` }),
resourceId: '51a9ea9e-a960-4b51-83a5-9901a47690c2' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
Expand All @@ -22,6 +30,10 @@ describe('GetAllUnpublishedFeedbackByAnAuthorForAPrereview', () => {
event: new Feedback.FeedbackWasEntered({ feedback: html`Some text` }),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
},
{
event: new Feedback.CodeOfConductWasAgreed(),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackWasStarted({ prereviewId: 123, authorId: Orcid('0000-0002-1825-0097') }),
resourceId: 'eb8146ea-e643-4ca3-9dc1-2f26013c42b0' as Uuid.Uuid,
Expand All @@ -30,6 +42,10 @@ describe('GetAllUnpublishedFeedbackByAnAuthorForAPrereview', () => {
event: new Feedback.FeedbackWasEntered({ feedback: html`Some other text` }),
resourceId: 'eb8146ea-e643-4ca3-9dc1-2f26013c42b0' as Uuid.Uuid,
},
{
event: new Feedback.CodeOfConductWasAgreed(),
resourceId: 'eb8146ea-e643-4ca3-9dc1-2f26013c42b0' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackPublicationWasRequested(),
resourceId: 'eb8146ea-e643-4ca3-9dc1-2f26013c42b0' as Uuid.Uuid,
Expand All @@ -46,6 +62,11 @@ describe('GetAllUnpublishedFeedbackByAnAuthorForAPrereview', () => {
authorId: Orcid('0000-0002-1825-0097'),
prereviewId: 123,
}),
'51a9ea9e-a960-4b51-83a5-9901a47690c2': new Feedback.FeedbackInProgress({
authorId: Orcid('0000-0002-1825-0097'),
feedback: html`Some text`,
prereviewId: 123,
}),
'2b9e777b-f14d-4294-8e27-2b442e496050': new Feedback.FeedbackReadyForPublishing({
authorId: Orcid('0000-0002-1825-0097'),
feedback: html`Some text`,
Expand Down Expand Up @@ -123,6 +144,10 @@ describe('GetAllUnpublishedFeedbackByAnAuthorForAPrereview', () => {
event: new Feedback.FeedbackWasEntered({ feedback: html`Some text` }),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
},
{
event: new Feedback.CodeOfConductWasAgreed(),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
},
{
event: new Feedback.FeedbackWasPublished({ id: 456, doi: Doi('10.5072/zenodo.456') }),
resourceId: '2b9e777b-f14d-4294-8e27-2b442e496050' as Uuid.Uuid,
Expand Down
Loading

0 comments on commit f920951

Please sign in to comment.