Skip to content

Commit

Permalink
Support EdArXiv preprints
Browse files Browse the repository at this point in the history
Refs #290
  • Loading branch information
thewilkybarkid committed May 1, 2024
1 parent b891602 commit 8917b4d
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 37 deletions.
1 change: 1 addition & 0 deletions src/Crossref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export const WorkSchema = Schema.Struct({
),
),
DOI: Doi.DoiSchema,
'group-title': Schema.optional(Schema.String),
institution: Schema.optional(Schema.Array(Schema.Struct({ name: Schema.String }))),
subtype: Schema.optional(Schema.String),
published: Schema.optional(DateFromPartsSchema),
Expand Down
3 changes: 2 additions & 1 deletion src/CrossrefPreprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface CrossrefPreprint {
readonly authors: ReadonlyArray<string>
readonly doi: Doi.Doi
readonly posted: Temporal.PlainDate
readonly server: 'biorxiv' | 'scielo'
readonly server: 'biorxiv' | 'edarxiv' | 'scielo'
readonly title: string
}

Expand Down Expand Up @@ -43,6 +43,7 @@ export const getPreprintFromCrossref = (
Match.value([Doi.getRegistrant(work.DOI), work]),
Match.when(['1101', { institution: [{ name: 'bioRxiv' }] }], () => 'biorxiv' as const),
Match.when(['1590'], () => 'scielo' as const),
Match.when(['35542', { 'group-title': 'EdArXiv' }], () => 'edarxiv' as const),
Match.either,
Either.mapLeft(() => new GetPreprintFromCrossrefError({ message: 'Not from a supported server' })),
)
Expand Down
2 changes: 1 addition & 1 deletion src/Preprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const getPreprint: (
doi: Doi.Doi,
) => Effect.Effect<Preprint, GetPreprintError, Crossref.CrossrefApi | Datacite.DataciteApi> = flow(
Match.value,
Match.when(Doi.hasRegistrant('1101', '1590'), CrossrefPreprint.getPreprintFromCrossref),
Match.when(Doi.hasRegistrant('1101', '1590', '35542'), CrossrefPreprint.getPreprintFromCrossref),
Match.when(Doi.hasRegistrant('48550'), DatacitePreprint.getPreprintFromDatacite),
Match.orElse(() => Effect.fail('Not from a supported server')),
Effect.mapError(toGetPreprintError),
Expand Down
1 change: 1 addition & 0 deletions src/ReviewRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ ${Array.match(preprint.authors, {
Preprint server: """${Match.value(preprint.server).pipe(
Match.when('arxiv', () => 'arXiv'),
Match.when('biorxiv', () => 'bioRxiv'),
Match.when('edarxiv', () => 'EdArXiv'),
Match.when('scielo', () => 'SciELO Preprints'),
Match.exhaustive,
)}"""
Expand Down
122 changes: 88 additions & 34 deletions test/CrossrefPreprint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,66 @@ describe('getPreprintFromCrossref', () => {
test.prop([
fc.doi(),
fc.oneof(
fc.tuple(fc.doi({ registrant: fc.constant('1101') }), fc.constant([{ name: 'bioRxiv' }]), fc.constant('biorxiv')),
fc.tuple(
fc.doi({ registrant: fc.constant('1101') }),
fc.constant([{ name: 'bioRxiv' }]),
fc.option(fc.string(), { nil: undefined }),
fc.constant('biorxiv'),
),
fc.tuple(
fc.doi({ registrant: fc.constant('1590') }),
fc.option(fc.array(fc.record({ name: fc.string() })), { nil: undefined }),
fc.option(fc.string(), { nil: undefined }),
fc.constant('scielo'),
),
fc.tuple(
fc.doi({ registrant: fc.constant('35542') }),
fc.option(fc.array(fc.record({ name: fc.string() })), { nil: undefined }),
fc.constant('EdArXiv'),
fc.constant('edarxiv'),
),
),
fc.string(),
fc.string(),
fc.plainDate(),
])('when a work is found', (doi, [expectedDoi, institution, expectedServer], expectedTitle, abstract, posted) =>
Effect.gen(function* ($) {
const actual = yield* $(_.getPreprintFromCrossref(doi))
])(
'when a work is found',
(doi, [expectedDoi, institution, groupTitle, expectedServer], expectedTitle, abstract, posted) =>
Effect.gen(function* ($) {
const actual = yield* $(_.getPreprintFromCrossref(doi))

expect(actual).toStrictEqual({
abstract,
authors: ['Author 1', 'Author 2', 'Prefix Given Author 3 Suffix'],
doi: expectedDoi,
posted,
server: expectedServer,
title: expectedTitle,
})
}).pipe(
Effect.provide(
Layer.succeed(Crossref.CrossrefApi, {
getWork: () =>
Effect.succeed({
abstract,
author: [
{ name: 'Author 1' },
{ family: 'Author 2' },
{ family: 'Author 3', given: 'Given', prefix: 'Prefix', suffix: 'Suffix' },
],
DOI: expectedDoi,
institution,
published: posted,
subtype: 'preprint',
title: [expectedTitle],
type: 'posted-content',
}),
}),
expect(actual).toStrictEqual({
abstract,
authors: ['Author 1', 'Author 2', 'Prefix Given Author 3 Suffix'],
doi: expectedDoi,
posted,
server: expectedServer,
title: expectedTitle,
})
}).pipe(
Effect.provide(
Layer.succeed(Crossref.CrossrefApi, {
getWork: () =>
Effect.succeed({
abstract,
author: [
{ name: 'Author 1' },
{ family: 'Author 2' },
{ family: 'Author 3', given: 'Given', prefix: 'Prefix', suffix: 'Suffix' },
],
DOI: expectedDoi,
'group-title': groupTitle,
institution,
published: posted,
subtype: 'preprint',
title: [expectedTitle],
type: 'posted-content',
}),
}),
),
Effect.provide(TestContext.TestContext),
Effect.runPromise,
),
Effect.provide(TestContext.TestContext),
Effect.runPromise,
),
)

test.prop([
Expand All @@ -73,6 +88,13 @@ describe('getPreprintFromCrossref', () => {
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
fc.crossrefWork({
DOI: fc.doi({ registrant: fc.constant('35542') }),
'group-title': fc.constant('EdArXiv'),
title: fc.constant([]),
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
),
])("when a work doesn't have a title", (doi, work) =>
Effect.gen(function* ($) {
Expand Down Expand Up @@ -105,6 +127,14 @@ describe('getPreprintFromCrossref', () => {
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
fc.crossrefWork({
abstract: fc.constant(undefined),
DOI: fc.doi({ registrant: fc.constant('35542') }),
'group-title': fc.constant('EdArXiv'),
title: fc.nonEmptyArray(fc.string()),
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
),
])("when a work doesn't have an abstract", (doi, work) =>
Effect.gen(function* ($) {
Expand Down Expand Up @@ -139,6 +169,15 @@ describe('getPreprintFromCrossref', () => {
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
fc.crossrefWork({
abstract: fc.string(),
DOI: fc.doi({ registrant: fc.constant('35542') }),
'group-title': fc.constant('EdArXiv'),
published: fc.oneof(fc.plainYear(), fc.plainYearMonth()),
title: fc.nonEmptyArray(fc.string()),
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
),
])('when a work has an incomplete published date', (doi, work) =>
Effect.gen(function* ($) {
Expand Down Expand Up @@ -173,6 +212,15 @@ describe('getPreprintFromCrossref', () => {
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
fc.crossrefWork({
abstract: fc.string(),
DOI: fc.doi({ registrant: fc.constant('35542') }),
'group-title': fc.constant('EdArXiv'),
published: fc.constant(undefined),
title: fc.nonEmptyArray(fc.string()),
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
),
])("when a work doesn't have a published date", (doi, work) =>
Effect.gen(function* ($) {
Expand Down Expand Up @@ -225,6 +273,12 @@ describe('getPreprintFromCrossref', () => {
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
fc.crossrefWork({
DOI: fc.doi({ registrant: fc.constant('35542') }),
institution: fc.array(fc.record({ name: fc.string().filter(name => name !== 'EdArXiv') })),
type: fc.constant('posted-content'),
subtype: fc.constant('preprint'),
}),
),
])("when the preprint server isn't supported", (doi, work) =>
Effect.gen(function* ($) {
Expand Down
4 changes: 3 additions & 1 deletion test/fc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export const crossrefWork = (
),
),
DOI: doi(),
'group-title': fc.option(fc.string(), { nil: undefined }),
institution: fc.option(fc.array(fc.record({ name: fc.string() })), { nil: undefined }),
published: fc.option(fc.oneof(plainYear(), plainYearMonth(), plainDate()), { nil: undefined }),
subtype: fc.option(fc.string(), { nil: undefined }),
Expand All @@ -111,7 +112,8 @@ export const crossrefWork = (
.map(work => {
return Object.fromEntries(
Object.entries(work).filter(
([key, value]) => !['abstract', 'institution', 'published', 'subtype'].includes(key) || value !== undefined,
([key, value]) =>
!['abstract', 'group-title', 'institution', 'published', 'subtype'].includes(key) || value !== undefined,
),
) as never
})
Expand Down

0 comments on commit 8917b4d

Please sign in to comment.