Skip to content

Commit

Permalink
🚩 Index local news (#933)
Browse files Browse the repository at this point in the history
  • Loading branch information
padms committed Aug 18, 2022
1 parent 80f0ad5 commit 0729619
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Settings } from '@algolia/client-search'
export const indexSettings: Settings = {
searchableAttributes: ['pageTitle', 'text'],
attributesToSnippet: ['text'],
attributesForFaceting: ['year', 'topicTags', 'countryTags'],
attributesForFaceting: ['year', 'topicTags', 'countryTags', 'localNewsTag'],
attributeForDistinct: 'slug',
distinct: 1,
advancedSyntax: true,
Expand Down
2 changes: 2 additions & 0 deletions search/IndexSanityContent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { indexNews } from './news'
import { indexMagazine } from './magazine'
import { languageFromIso, languageOrDefault } from '../common'
import { pipe } from 'fp-ts/lib/function'
import { indexLocalNews } from './localNews'

const timerTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
await new DotenvAzure().config({
Expand All @@ -21,6 +22,7 @@ const timerTrigger: AzureFunction = async function (context: Context, req: HttpR
await indexTopic(language)().catch(logger.error)
await indexNews(language)().catch(logger.error)
await indexMagazine(language)().catch(logger.error)
await indexLocalNews(language)().catch(logger.error)
}

export default timerTrigger
30 changes: 30 additions & 0 deletions search/IndexSanityContent/localNews/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { flow, pipe } from 'fp-ts/lib/function'
import { flatten } from 'fp-ts/Array'
import { ap } from 'fp-ts/lib/Identity'
import * as E from 'fp-ts/lib/Either'
import * as T from 'fp-ts/lib/Task'
import * as TE from 'fp-ts/lib/TaskEither'
import { update, generateIndexName, Language, getSanityClient } from '../../common'
import { fetchData } from './sanity'
import { indexSettings } from '../common/news/algolia'
import { mapData } from './mapper'

const indexIdentifier = 'NEWS'

export const indexLocalNews = (language: Language) => {
const indexName = flow(
() => E.fromNullable('Use getEnvironment here after acceptance')('dev'),
E.map(generateIndexName(indexIdentifier)(language.isoCode)),
)
const updateAlgolia = flow(indexName, E.map(flow(update, ap(indexSettings))))

return pipe(
getSanityClient(),
TE.fromEither,
TE.chainW(fetchData(language)),
TE.map((pages) => pipe(pages.map(mapData), flatten)),
TE.chainW((data) => pipe(updateAlgolia(), E.ap(E.of(data)), TE.fromEither)),
TE.flatten,
T.map(E.fold(console.error, console.log)),
)
}
187 changes: 187 additions & 0 deletions search/IndexSanityContent/localNews/mapper.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import { LocalNewsArticle } from './sanity'
import { NewsIndex } from '../../common'
import { mapData } from './mapper'

describe('Local News', () => {
describe('mapper tests', () => {
describe('Vanilla version works', () => {
// Hei fremtids-Nils Magne, vi bør ikke ha en en-til-en type mot Sanity?
const newsArticle: LocalNewsArticle = {
title: 'title',
ingress: 'ingress',
slug: '/a/slug',
_id: 'id',
publishDateTime: '2021-11-26T07:00:00.000Z',
localNewsTag: 'Germany',
// tags: ['Oil', 'Norway'],
blocks: [
{
blockKey: 'blockKey',
children: [
{
childKey: 'childKey',
text: 'Some text',
},
],
},
],
}

const sut = mapData
const result = sut(newsArticle)

it('contains one entry', () => {
expect(result).toHaveLength(1)
})

it('entry looks as expected', () => {
expect(result[0]).toEqual({
slug: '/a/slug',
objectID: 'id-blockKey-childKey',
pageTitle: 'title',
ingress: 'ingress',
type: 'localNews',
text: 'Some text',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
} as NewsIndex)
})
})

describe('Multiple children works (advanced version)', () => {
const newsArticle: LocalNewsArticle & { year: number } = {
title: 'title',
ingress: 'ingress',
slug: '/a/slug',
_id: 'id',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
blocks: [
{
blockKey: 'blockKey',
children: [
{
childKey: 'childKey',
text: 'Some text',
},
{
childKey: 'childKey2',
text: 'Some more text',
},
],
},
{
blockKey: 'blockKey2',
children: [
{
childKey: 'childKey3',
text: 'Some text 3',
},
{
childKey: 'childKey4',
text: 'Some more text 4',
},
],
},
],
}

const sut = mapData
const result = sut(newsArticle)

it('contains one entry', () => {
expect(result).toHaveLength(4)
})

it('entry looks as expected', () => {
expect(result[0]).toEqual({
slug: '/a/slug',
objectID: 'id-blockKey-childKey',
pageTitle: 'title',
ingress: 'ingress',
type: 'localNews',
text: 'Some text',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
} as NewsIndex)
expect(result[1]).toEqual({
slug: '/a/slug',
objectID: 'id-blockKey-childKey2',
pageTitle: 'title',
ingress: 'ingress',
type: 'localNews',
text: 'Some more text',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
})
expect(result[2]).toEqual({
slug: '/a/slug',
objectID: 'id-blockKey2-childKey3',
pageTitle: 'title',
ingress: 'ingress',
type: 'localNews',
text: 'Some text 3',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
})
expect(result[3]).toEqual({
slug: '/a/slug',
objectID: 'id-blockKey2-childKey4',
pageTitle: 'title',
ingress: 'ingress',
type: 'localNews',
text: 'Some more text 4',
publishDateTime: '2021-11-26T07:00:00.000Z',
year: 2021,
localNewsTag: 'Germany',
})
})
})

describe('Empty children works', () => {
const newsArticle: LocalNewsArticle = {
title: 'title',
ingress: 'ingress',
slug: '/a/slug',
_id: 'id',
localNewsTag: 'UK',
blocks: [
{
blockKey: 'blockKey',
children: [],
},
],
}

const sut = mapData
const result = sut(newsArticle)

it('Does not contain entries', () => {
expect(result).toHaveLength(0)
})
})

describe('Empty blocks works', () => {
const newsArticle: LocalNewsArticle = {
title: 'title',
ingress: 'ingress',
slug: '/a/slug',
localNewsTag: 'USA',
_id: 'id',
blocks: [],
}

const sut = mapData
const result = sut(newsArticle)

it('Does not contain entries', () => {
expect(result).toHaveLength(0)
})
})
})
})
29 changes: 29 additions & 0 deletions search/IndexSanityContent/localNews/mapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { pipe } from 'fp-ts/lib/function'
import * as A from 'fp-ts/lib/Array'
import { NewsIndex } from '../../common'
import type { LocalNewsArticle } from './sanity'

type MapDataType = (article: LocalNewsArticle) => NewsIndex[]
export const mapData: MapDataType = (article) => {
const { publishDateTime, localNewsTag, title, ingress, slug } = article
// Hu hei hvor det går
const year = publishDateTime ? new Date(publishDateTime).getFullYear() : ''
return pipe(
A.bindTo('blocks')(article.blocks),
A.bind('children', ({ blocks }) => blocks.children),
A.map(
({ blocks, children }) =>
({
slug,
objectID: `${article._id}-${blocks.blockKey}-${children.childKey}`,
type: 'localNews',
pageTitle: title,
ingress,
text: children.text,
publishDateTime: publishDateTime,
localNewsTag,
year,
} as NewsIndex),
),
)
}
63 changes: 63 additions & 0 deletions search/IndexSanityContent/localNews/sanity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import * as E from 'fp-ts/lib/Either'
import * as TE from 'fp-ts/lib/TaskEither'
import { pipe } from 'fp-ts/lib/function'
import { SanityClient } from '@sanity/client'
import { Language } from '../../common'

const publishDateTimeQuery = /* groq */ `
select(
customPublicationDate == true =>
publishDateTime,
coalesce(firstPublishedAt, _createdAt)
)
`

export const query = /* groq */ `*[_type == "localNews" && _lang == $lang && !(_id in path("drafts.**")) && excludeFromSearch != true] {
"slug": slug.current,
_id,
"title": title,
"ingress": ingress,
"type": _type,
"publishDateTime": ${publishDateTimeQuery},
"localNewsTag": localNewsTag->[$lang],
"blocks": content[_type == "block"] {
"blockKey": _key,
"children": children[text match "*"] {
"childKey": _key,
"text": text
}
},
}
`

const getQueryParams = (language: Language) => ({
lang: language.internalCode,
})

export type LocalNewsArticle = {
slug: string
title: string
ingress: string
// ISO 8601
publishDateTime?: string
localNewsTag: string
blocks: {
blockKey: string
children: {
childKey: string
text: string
}[]
}[]
_id: string
}

type FetchDataType = (
query: string,
) => (
getQueryparams: (language: Language) => Readonly<Record<string, string>>,
) => (language: Language) => (sanityClient: SanityClient) => TE.TaskEither<Error, LocalNewsArticle[]>

const fetch: FetchDataType = (query) => (getQueryParams) => (language) => (sanityClient) =>
pipe(TE.tryCatch(() => sanityClient.fetch(query, getQueryParams(language)), E.toError))

export const fetchData = fetch(query)(getQueryParams)
2 changes: 1 addition & 1 deletion search/IndexSanityContent/news/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as T from 'fp-ts/lib/Task'
import * as TE from 'fp-ts/lib/TaskEither'
import { update, generateIndexName, getEnvironment, Language, getSanityClient } from '../../common'
import { fetchData } from './sanity'
import { indexSettings } from './algolia'
import { indexSettings } from '../common/news/algolia'
import { mapData } from './mapper'

const indexIdentifier = 'NEWS'
Expand Down
1 change: 1 addition & 0 deletions search/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type NewsIndex = {
topicTags: string[]
countryTags: string[]
thumbnailUrl: string
localNewsTag: string

This comment has been minimized.

Copy link
@fernandolucchesi

fernandolucchesi Aug 21, 2022

Contributor

You should create a new type, LocalNewsIndex. Even tho it works the way it is, such a type with both localNewsTag doesn't exist. If you want to avoid code duplication you can do it like:

type SharedNewsFields = {
    commonfields...
 }
 
 export type NewsIndex = SharedNewsFields & {
  topicTags,
  countryTags
 }

 export type LocalNewsIndex = SharedNewsFields & {
  localNewsTag
 }

}

export type MagazineIndex = {
Expand Down

0 comments on commit 0729619

Please sign in to comment.