Skip to content

Commit

Permalink
feat: return source dataset count from source study apis (#324) (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
hunterckx authored Jun 21, 2024
1 parent fbdd9f9 commit d23a5b4
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 108 deletions.
34 changes: 22 additions & 12 deletions __tests__/api-atlases-id-source-studies-create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
HCAAtlasTrackerSourceStudy,
PublicationInfo,
} from "../app/apis/catalog/hca-atlas-tracker/common/entities";
import { dbSourceStudyToApiSourceStudy } from "../app/apis/catalog/hca-atlas-tracker/common/utils";
import { endPgPool, query } from "../app/services/database";
import createHandler from "../pages/api/atlases/[atlasId]/source-studies/create";
import {
Expand Down Expand Up @@ -52,7 +51,10 @@ import {
resetDatabase,
} from "../testing/db-utils";
import { TestAtlas, TestUser } from "../testing/entities";
import { withConsoleErrorHiding } from "../testing/utils";
import {
expectSourceStudyToMatch,
withConsoleErrorHiding,
} from "../testing/utils";

jest.mock("../app/services/user-profile");
jest.mock("../app/utils/pg-app-connect-config");
Expand Down Expand Up @@ -230,14 +232,14 @@ describe("/api/atlases/[atlasId]/source-studies/create", () => {
});

it("creates, validates, and returns source study entry for journal publication", async () => {
const newStudy = await testSuccessfulCreate(
const { dbStudy } = await testSuccessfulCreate(
ATLAS_DRAFT,
NEW_STUDY_DATA,
PUBLICATION_NORMAL,
HCA_ID_NORMAL,
CELLXGENE_ID_NORMAL
);
const validations = await getValidationsByEntityId(newStudy.id);
const validations = await getValidationsByEntityId(dbStudy.id);
expect(validations).not.toHaveLength(0);
});

Expand Down Expand Up @@ -358,7 +360,7 @@ describe("/api/atlases/[atlasId]/source-studies/create", () => {
expect(validationsBefore).not.toHaveLength(0);
expect(validationsBefore[0].atlas_ids).toHaveLength(1);
expect(validationsBefore[0].atlas_ids[0]).toEqual(ATLAS_DRAFT.id);
const dbStudy = await testSuccessfulCreate(
const { dbStudy } = await testSuccessfulCreate(
ATLAS_PUBLIC,
NEW_STUDY_DRAFT_OK,
PUBLICATION_DRAFT_OK,
Expand All @@ -374,7 +376,7 @@ describe("/api/atlases/[atlasId]/source-studies/create", () => {
});

it("adds and returns source study that already exists via preprint DOI", async () => {
const dbStudy = await testSuccessfulCreate(
const { dbStudy } = await testSuccessfulCreate(
ATLAS_DRAFT,
NEW_STUDY_PUBLIC_WITH_PREPRINT_PREPRINT,
PUBLICATION_PUBLIC_WITH_PREPRINT,
Expand All @@ -385,7 +387,7 @@ describe("/api/atlases/[atlasId]/source-studies/create", () => {
});

it("adds and returns source study that already exists via journal DOI", async () => {
const dbStudy = await testSuccessfulCreate(
const { dbStudy } = await testSuccessfulCreate(
ATLAS_DRAFT,
NEW_STUDY_PUBLIC_WITH_JOURNAL_JOURNAL,
PUBLICATION_PUBLIC_WITH_JOURNAL,
Expand All @@ -406,15 +408,17 @@ describe("/api/atlases/[atlasId]/source-studies/create", () => {
expect(fooBefore).toBeNull();
expect(barBefore).toBeNull();

const dbStudy = await testSuccessfulCreate(
const { apiStudy } = await testSuccessfulCreate(
ATLAS_DRAFT,
NEW_STUDY_WITH_NEW_SOURCE_DATASETS,
null,
null,
CELLXGENE_ID_WITH_NEW_SOURCE_DATASETS
);

const studyDatasets = await getStudySourceDatasets(dbStudy.id);
expect(apiStudy.sourceDatasetCount).toEqual(2);

const studyDatasets = await getStudySourceDatasets(apiStudy.id);

expect(studyDatasets).toHaveLength(2);

Expand Down Expand Up @@ -448,7 +452,10 @@ async function testSuccessfulCreate(
expectedPublication: PublicationInfo | null,
expectedHcaId: string | null,
expectedCellxGeneId: string | null
): Promise<HCAAtlasTrackerDBSourceStudy> {
): Promise<{
apiStudy: HCAAtlasTrackerSourceStudy;
dbStudy: HCAAtlasTrackerDBSourceStudy;
}> {
const res = await doCreateTest(USER_CONTENT_ADMIN, atlas, newData);
expect(res._getStatusCode()).toEqual(201);
const newStudy: HCAAtlasTrackerSourceStudy = res._getJSONData();
Expand All @@ -472,7 +479,10 @@ async function testSuccessfulCreate(
expectedHcaId,
expectedCellxGeneId
);
return newStudyFromDb;
return {
apiStudy: newStudy,
dbStudy: newStudyFromDb,
};
}

async function testSuccessfulUnpublishedCreate(
Expand Down Expand Up @@ -528,5 +538,5 @@ function expectDbStudyToMatch(
expect(dbStudy.study_info.publication).toEqual(publication);
expect(dbStudy.study_info.hcaProjectId).toEqual(hcaId);
expect(dbStudy.study_info.cellxgeneCollectionId).toEqual(cellxgeneId);
expect(dbSourceStudyToApiSourceStudy(dbStudy)).toEqual(apiStudy);
expectSourceStudyToMatch(dbStudy, apiStudy);
}
8 changes: 6 additions & 2 deletions __tests__/api-atlases-id-source-studies-id.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
HCAAtlasTrackerDBSourceStudy,
HCAAtlasTrackerSourceStudy,
} from "../app/apis/catalog/hca-atlas-tracker/common/entities";
import { dbSourceStudyToApiSourceStudy } from "../app/apis/catalog/hca-atlas-tracker/common/utils";
import { METHOD } from "../app/common/entities";
import { endPgPool, query } from "../app/services/database";
import studyHandler from "../pages/api/atlases/[atlasId]/source-studies/[sourceStudyId]";
Expand Down Expand Up @@ -38,6 +37,7 @@ import {
TestUser,
} from "../testing/entities";
import {
expectSourceStudyToMatch,
makeTestSourceStudyOverview,
withConsoleErrorHiding,
} from "../testing/utils";
Expand Down Expand Up @@ -288,7 +288,7 @@ describe("/api/atlases/[atlasId]/source-studies/[sourceStudyId]", () => {
);
expect(studyFromDb.study_info.hcaProjectId).toEqual(null);
expect(studyFromDb.study_info.cellxgeneCollectionId).toEqual(null);
expect(dbSourceStudyToApiSourceStudy(studyFromDb)).toEqual(updatedStudy);
expectSourceStudyToMatch(studyFromDb, updatedStudy);

const validationsAfter = await getValidationsByEntityId(
SOURCE_STUDY_PUBLIC_NO_CROSSREF.id
Expand Down Expand Up @@ -369,6 +369,10 @@ describe("/api/atlases/[atlasId]/source-studies/[sourceStudyId]", () => {
);
expect(res._getStatusCode()).toEqual(200);

const updatedStudy = res._getJSONData() as HCAAtlasTrackerSourceStudy;

expect(updatedStudy.sourceDatasetCount).toEqual(4);

const studyDatasetsAfter = await getStudySourceDatasets(
SOURCE_STUDY_DRAFT_OK.id
);
Expand Down
1 change: 1 addition & 0 deletions __tests__/api-atlases-id-source-studies.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { TestPublishedSourceStudy, TestUser } from "../testing/entities";

jest.mock("../app/services/user-profile");
jest.mock("../app/services/hca-projects");
jest.mock("../app/services/cellxgene");
jest.mock("../app/utils/pg-app-connect-config");

beforeAll(async () => {
Expand Down
6 changes: 6 additions & 0 deletions app/apis/catalog/hca-atlas-tracker/common/entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ interface HCAAtlasTrackerSourceStudyCommon {
doiStatus: DOI_STATUS;
hcaProjectId: string | null;
id: string;
sourceDatasetCount: number;
}

export interface HCAAtlasTrackerPublishedSourceStudy
Expand Down Expand Up @@ -231,6 +232,11 @@ export interface HCAAtlasTrackerDBUnpublishedSourceStudyInfo {
unpublishedInfo: UnpublishedInfo;
}

export type HCAAtlasTrackerDBSourceStudyWithSourceDatasets =
HCAAtlasTrackerDBSourceStudy & {
source_dataset_count: number;
};

export interface HCAAtlasTrackerDBSourceDataset {
created_at: Date;
id: string;
Expand Down
26 changes: 15 additions & 11 deletions app/apis/catalog/hca-atlas-tracker/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
HCAAtlasTrackerDBComponentAtlas,
HCAAtlasTrackerDBSourceDatasetWithStudyProperties,
HCAAtlasTrackerDBSourceStudy,
HCAAtlasTrackerDBSourceStudyWithSourceDatasets,
HCAAtlasTrackerDBValidationWithAtlasProperties,
HCAAtlasTrackerListAtlas,
HCAAtlasTrackerListValidationRecord,
Expand Down Expand Up @@ -89,7 +90,7 @@ export function dbComponentAtlasToApiComponentAtlas(
}

export function dbSourceStudyToApiSourceStudy(
dbSourceStudy: HCAAtlasTrackerDBSourceStudy
dbSourceStudy: HCAAtlasTrackerDBSourceStudyWithSourceDatasets
): HCAAtlasTrackerSourceStudy {
const {
study_info: { capId, cellxgeneCollectionId, hcaProjectId, publication },
Expand All @@ -107,6 +108,7 @@ export function dbSourceStudyToApiSourceStudy(
journal: null,
publicationDate: null,
referenceAuthor: unpublishedInfo.referenceAuthor,
sourceDatasetCount: dbSourceStudy.source_dataset_count,
title: unpublishedInfo.title,
};
} else {
Expand All @@ -121,6 +123,7 @@ export function dbSourceStudyToApiSourceStudy(
journal: publication?.journal ?? null,
publicationDate: publication?.publicationDate ?? null,
referenceAuthor: publication?.authors[0]?.name ?? null,
sourceDatasetCount: dbSourceStudy.source_dataset_count,
title: publication?.title ?? null,
};
}
Expand All @@ -140,7 +143,7 @@ export function dbSourceDatasetToApiSourceDataset(
disease: dbSourceDataset.sd_info.disease,
doi: dbSourceDataset.doi,
id: dbSourceDataset.id,
publicationString: getDbSourceDatasetCitation(dbSourceDataset),
publicationString: getDbEntityCitation(dbSourceDataset),
sourceStudyId: dbSourceDataset.source_study_id,
sourceStudyTitle:
studyInfo.publication?.title ?? studyInfo.unpublishedInfo?.title ?? null,
Expand Down Expand Up @@ -186,19 +189,20 @@ export function getAtlasName(atlas: HCAAtlasTrackerAtlas): string {
}

/**
* Returns the source dataset citation.
* @param sourceDataset - Database model of source dataset with source study properties.
* @returns Source dataset citation.
* Returns the entity's citation.
* @param entity - Database model of entity with source study properties.
* @returns citation for the associated source study.
*/
function getDbSourceDatasetCitation(
sourceDataset: HCAAtlasTrackerDBSourceDatasetWithStudyProperties
export function getDbEntityCitation(
entity:
| HCAAtlasTrackerDBSourceStudy
| HCAAtlasTrackerDBSourceDatasetWithStudyProperties
): string {
if (sourceDataset.doi === null) {
const { contactEmail, referenceAuthor } =
sourceDataset.study_info.unpublishedInfo;
if (entity.doi === null) {
const { contactEmail, referenceAuthor } = entity.study_info.unpublishedInfo;
return getUnpublishedCitation(referenceAuthor, contactEmail);
} else {
const studyInfo = sourceDataset.study_info;
const studyInfo = entity.study_info;
const publication = studyInfo.publication;
return getPublishedCitation(
studyInfo.doiStatus,
Expand Down
Loading

0 comments on commit d23a5b4

Please sign in to comment.