Skip to content

Commit

Permalink
Use Effect for the page
Browse files Browse the repository at this point in the history
Refs #1834
  • Loading branch information
thewilkybarkid committed Dec 13, 2024
1 parent 24737da commit 3b88de4
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 76 deletions.
29 changes: 3 additions & 26 deletions src/Router.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,9 @@
import {
Cookies,
FetchHttpClient,
Headers,
HttpMiddleware,
HttpRouter,
HttpServerRequest,
HttpServerResponse,
} from '@effect/platform'
import { Cookies, Headers, HttpMiddleware, HttpRouter, HttpServerRequest, HttpServerResponse } from '@effect/platform'
import { Effect, identity, Option, pipe, Record } from 'effect'
import { format } from 'fp-ts-routing'
import { StatusCodes } from 'http-status-codes'
import { aboutUs } from './about-us.js'
import { DeprecatedSleepEnv, ExpressConfig, FlashMessage, Locale } from './Context.js'
import * as FptsToEffect from './FptsToEffect.js'
import { GhostApi } from './ghost.js'
import { ExpressConfig, FlashMessage, Locale } from './Context.js'
import { PublicUrl } from './public-url.js'
import { Redis } from './Redis.js'
import {
Expand Down Expand Up @@ -220,20 +210,7 @@ const WriteCommentFlowRouter = pipe(

export const Router = pipe(
HttpRouter.empty,
HttpRouter.get(
Routes.AboutUs.path,
pipe(
Effect.gen(function* () {
const locale = yield* Locale
const fetch = yield* FetchHttpClient.Fetch
const ghostApi = yield* GhostApi
const sleep = yield* DeprecatedSleepEnv

return yield* FptsToEffect.readerTask(aboutUs(locale), { fetch, ghostApi, ...sleep })
}),
Effect.andThen(toHttpServerResponse),
),
),
HttpRouter.get(Routes.AboutUs.path, pipe(aboutUs, Effect.andThen(toHttpServerResponse))),
HttpRouter.concat(WriteCommentFlowRouter),
HttpRouter.use(
HttpMiddleware.make(
Expand Down
31 changes: 20 additions & 11 deletions src/about-us.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { FetchHttpClient } from '@effect/platform'
import { Effect } from 'effect'
import { format } from 'fp-ts-routing'
import * as RTE from 'fp-ts/lib/ReaderTaskEither.js'
import { pipe } from 'fp-ts/lib/function.js'
import { getPage } from './ghost.js'
import { DeprecatedSleepEnv, Locale } from './Context.js'
import * as FptsToEffect from './FptsToEffect.js'
import { getPage, GhostApi } from './ghost.js'
import { HavingProblemsPage } from './HavingProblemsPage/index.js'
import { type Html, fixHeadingLevels, html, plainText } from './html.js'
import { havingProblemsPage } from './http-error.js'
import { type SupportedLocale, translate } from './locales/index.js'
import { PageResponse } from './response.js'
import { aboutUsMatch } from './routes.js'

export const aboutUs = (locale: SupportedLocale) =>
pipe(
RTE.Do,
RTE.apS('content', getPage('6154aa157741400e8722bb14')),
RTE.let('locale', () => locale),
RTE.matchW(() => havingProblemsPage, createPage),
)
export const aboutUs = Effect.gen(function* () {
const locale = yield* Locale
const fetch = yield* FetchHttpClient.Fetch
const ghostApi = yield* GhostApi
const sleep = yield* DeprecatedSleepEnv

const content = yield* FptsToEffect.readerTaskEither(getPage('6154aa157741400e8722bb14'), {
fetch,
ghostApi,
...sleep,
})

return createPage({ content, locale })
}).pipe(Effect.catchAll(() => HavingProblemsPage))

function createPage({ content, locale }: { content: Html; locale: SupportedLocale }) {
const t = translate(locale)
Expand Down
102 changes: 63 additions & 39 deletions test/about-us.test.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,86 @@
import { FetchHttpClient } from '@effect/platform'
import { test } from '@fast-check/jest'
import { describe, expect } from '@jest/globals'
import { Effect, pipe, TestContext } from 'effect'
import fetchMock from 'fetch-mock'
import { format } from 'fp-ts-routing'
import { Status } from 'hyper-ts'
import * as _ from '../src/about-us.js'
import { DeprecatedSleepEnv, Locale } from '../src/Context.js'
import { GhostApi } from '../src/ghost.js'
import { aboutUsMatch } from '../src/routes.js'
import * as fc from './fc.js'
import { shouldNotBeCalled } from './should-not-be-called.js'

describe('aboutUs', () => {
test.prop([fc.supportedLocale(), fc.string({ unit: fc.alphanumeric(), minLength: 1 })])(
'when the page can be loaded',
async (locale, key) => {
const fetch = fetchMock.sandbox().getOnce(
{
url: 'https://content.prereview.org/ghost/api/content/pages/6154aa157741400e8722bb14',
query: { key },
},
{ body: { pages: [{ html: '<p>Foo<script>bar</script></p>' }] } },
)
(locale, key) =>
Effect.gen(function* () {
const fetch = fetchMock.sandbox().getOnce(
{
url: 'https://content.prereview.org/ghost/api/content/pages/6154aa157741400e8722bb14',
query: { key },
},
{ body: { pages: [{ html: '<p>Foo<script>bar</script></p>' }] } },
)

const actual = await _.aboutUs(locale)({ fetch, ghostApi: { key }, sleep: shouldNotBeCalled })()
const actual = yield* pipe(
_.aboutUs,
Effect.provideService(FetchHttpClient.Fetch, fetch as typeof FetchHttpClient.Fetch.Service),
)

expect(actual).toStrictEqual({
_tag: 'PageResponse',
canonical: format(aboutUsMatch.formatter, {}),
current: 'about-us',
status: Status.OK,
title: expect.anything(),
main: expect.anything(),
skipToLabel: 'main',
js: [],
})
},
expect(actual).toStrictEqual({
_tag: 'PageResponse',
canonical: format(aboutUsMatch.formatter, {}),
current: 'about-us',
status: Status.OK,
title: expect.anything(),
main: expect.anything(),
skipToLabel: 'main',
js: [],
})
}).pipe(
Effect.provideService(Locale, locale),
Effect.provideService(DeprecatedSleepEnv, { sleep: shouldNotBeCalled }),
Effect.provideService(GhostApi, { key }),
Effect.provide(TestContext.TestContext),
Effect.runPromise,
),
)

test.prop([fc.supportedLocale(), fc.string({ unit: fc.alphanumeric(), minLength: 1 }), fc.fetchResponse()])(
'when the page cannot be loaded',
async (locale, key, response) => {
const fetch = fetchMock.sandbox().getOnce(
{
url: 'begin:https://content.prereview.org/ghost/api/content/pages/6154aa157741400e8722bb14?',
query: { key },
},
response,
)
async (locale, key, response) =>
Effect.gen(function* () {
const fetch = fetchMock.sandbox().getOnce(
{
url: 'begin:https://content.prereview.org/ghost/api/content/pages/6154aa157741400e8722bb14?',
query: { key },
},
response,
)

const actual = await _.aboutUs(locale)({ fetch, ghostApi: { key }, sleep: shouldNotBeCalled })()
const actual = yield* pipe(
_.aboutUs,
Effect.provideService(FetchHttpClient.Fetch, fetch as typeof FetchHttpClient.Fetch.Service),
)

expect(actual).toStrictEqual({
_tag: 'PageResponse',
status: Status.ServiceUnavailable,
title: expect.anything(),
main: expect.anything(),
skipToLabel: 'main',
js: [],
})
expect(fetch.done()).toBeTruthy()
},
expect(actual).toStrictEqual({
_tag: 'PageResponse',
status: Status.ServiceUnavailable,
title: expect.anything(),
main: expect.anything(),
skipToLabel: 'main',
js: [],
})
expect(fetch.done()).toBeTruthy()
}).pipe(
Effect.provideService(Locale, locale),
Effect.provideService(DeprecatedSleepEnv, { sleep: shouldNotBeCalled }),
Effect.provideService(GhostApi, { key }),
Effect.provide(TestContext.TestContext),
Effect.runPromise,
),
)
})

0 comments on commit 3b88de4

Please sign in to comment.