Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
'^@osf/(.*)$': '<rootDir>/src/app/$1',
'^@core/(.*)$': '<rootDir>/src/app/core/$1',
'^@shared/(.*)$': '<rootDir>/src/app/shared/$1',
'^@styles/(.*)$': '<rootDir>/src/styles/$1',
'^@styles/(.*)$': '<rootDir>/assets/styles/$1',
'^@testing/(.*)$': '<rootDir>/src/testing/$1',
'^src/environments/environment$': '<rootDir>/src/environments/environment.ts',
},
Expand Down Expand Up @@ -70,16 +70,16 @@ module.exports = {
testPathIgnorePatterns: [
'<rootDir>/src/app/app.config.ts',
'<rootDir>/src/app/app.routes.ts',
'<rootDir>/src/app/features/registry/',
'<rootDir>/src/app/features/project/addons/components/configure-configure-addon/',
'<rootDir>/src/app/features/project/addons/components/connect-configured-addon/',
'<rootDir>/src/app/features/project/addons/components/disconnect-addon-modal/',
'<rootDir>/src/app/features/project/addons/components/confirm-account-connection-modal/',
'<rootDir>/src/app/features/files/',
'<rootDir>/src/app/features/my-projects/',
'<rootDir>/src/app/features/preprints/',
'<rootDir>/src/app/features/project/analytics/',
'<rootDir>/src/app/features/project/contributors/',
'<rootDir>/src/app/features/project/overview/',
'<rootDir>/src/app/features/project/files/',
'<rootDir>/src/app/features/project/metadata/',
'<rootDir>/src/app/features/project/registrations',
'<rootDir>/src/app/features/project/settings',
'<rootDir>/src/app/features/project/wiki',
Expand All @@ -98,6 +98,9 @@ module.exports = {
'<rootDir>/src/app/shared/components/pie-chart/',
'<rootDir>/src/app/shared/components/resource-citations/',
'<rootDir>/src/app/shared/components/reusable-filter/',
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/affiliated-institutions-dialog/',
'<rootDir>/src/app/shared/components/shared-metadata/dialogs/contributors-dialog/',
'<rootDir>/src/app/shared/components/shared-metadata/shared-metadata',
'<rootDir>/src/app/shared/components/subjects/',
'<rootDir>/src/app/shared/components/wiki/edit-section/',
'<rootDir>/src/app/shared/components/wiki/wiki-list/',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export class PreprintProvidersMapper {
backgroundColor: brandRaw.attributes.background_color,
},
iri: response.links.iri,
faviconUrl: response.attributes.assets.favicon,
faviconUrl: response.attributes.assets?.favicon,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change is present because it it impossible to preview preprints locally without it

squareColorNoTransparentImageUrl: response.attributes.assets?.square_color_no_transparent,
reviewsWorkflow: response.attributes.reviews_workflow,
facebookAppId: response.attributes.facebook_app_id,
Expand Down
6 changes: 6 additions & 0 deletions src/app/features/preprints/mappers/preprints.mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ export class PreprintsMapper {
views: meta.metrics.views,
},
embeddedLicense: LicensesMapper.fromLicenseDataJsonApi(data.embeds.license.data),
identifiers: data.embeds.identifiers?.data.map((identifier) => ({
id: identifier.id,
type: identifier.type,
value: identifier.attributes.value,
category: identifier.attributes.category,
})),
preprintDoiLink: links.preprint_doi,
articleDoiLink: links.doi,
};
Expand Down
10 changes: 10 additions & 0 deletions src/app/features/preprints/models/preprint-json-api.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ export interface PreprintEmbedsJsonApi {
data: ContributorResponse[];
};
license: LicenseResponseJsonApi;
identifiers: {
data: {
id: string;
type: string;
attributes: {
category: string;
value: string;
};
}[];
};
}

export interface PreprintMetaJsonApi {
Expand Down
7 changes: 4 additions & 3 deletions src/app/features/preprints/models/preprint.models.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { UserPermissions } from '@osf/shared/enums';
import { BooleanOrNull, StringOrNull } from '@osf/shared/helpers';
import { IdName, License, LicenseOptions } from '@osf/shared/models';
import { Identifier, IdName, License, LicenseOptions } from '@osf/shared/models';
import { UserPermissions } from '@shared/enums';
import { BooleanOrNull, StringOrNull } from '@shared/helpers';

import { ApplicabilityStatus, PreregLinkInfo, ReviewsState } from '../enums';

Expand Down Expand Up @@ -43,6 +43,7 @@ export interface Preprint {
embeddedLicense?: License;
preprintDoiLink?: string;
articleDoiLink?: string;
identifiers?: Identifier[];
}

export interface PreprintFilesLinks {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import { MockComponents, MockPipe, MockProvider } from 'ng-mocks';

import { of } from 'rxjs';

import { signal } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { provideNoopAnimations } from '@angular/platform-browser/animations';
import { ActivatedRoute, Router } from '@angular/router';

import { AdditionalInfoComponent } from '@osf/features/preprints/components/preprint-details/additional-info/additional-info.component';
Expand All @@ -15,15 +17,21 @@ import { ShareAndDownloadComponent } from '@osf/features/preprints/components/pr
import { PreprintSelectors } from '@osf/features/preprints/store/preprint';
import { PreprintProvidersSelectors } from '@osf/features/preprints/store/preprint-providers';
import { MOCK_PROVIDER, MOCK_STORE, TranslateServiceMock } from '@shared/mocks';
import { Identifier } from '@shared/models';
import { DataciteService } from '@shared/services/datacite/datacite.service';

import { PreprintDetailsComponent } from './preprint-details.component';

describe.skip('PreprintDetailsComponent', () => {
describe('PreprintDetailsComponent', () => {
let component: PreprintDetailsComponent;
let fixture: ComponentFixture<PreprintDetailsComponent>;

let dataciteService: jest.Mocked<DataciteService>;

const preprintSignal = signal<any | null>({ id: 'p1', title: 'Test', description: '' });
const mockRoute: Partial<ActivatedRoute> = {
params: of({ providerId: 'osf', preprintId: 'p1' }),
queryParams: of({ providerId: 'osf', preprintId: 'p1' }),
};

beforeEach(async () => {
Expand All @@ -34,13 +42,17 @@ describe.skip('PreprintDetailsComponent', () => {
case PreprintProvidersSelectors.isPreprintProviderDetailsLoading:
return () => false;
case PreprintSelectors.getPreprint:
return () => ({ id: 'p1', title: 'Test', description: '' });
return preprintSignal;
case PreprintSelectors.isPreprintLoading:
return () => false;
default:
return () => [];
}
});
(MOCK_STORE.dispatch as jest.Mock).mockImplementation(() => of());
dataciteService = {
logView: jest.fn().mockReturnValue(of(void 0)),
} as unknown as jest.Mocked<DataciteService>;

await TestBed.configureTestingModule({
imports: [
Expand All @@ -55,6 +67,8 @@ describe.skip('PreprintDetailsComponent', () => {
],
providers: [
MockProvider(Store, MOCK_STORE),
provideNoopAnimations(),
{ provide: DataciteService, useValue: dataciteService },
MockProvider(Router),
MockProvider(ActivatedRoute, mockRoute),
TranslateServiceMock,
Expand All @@ -66,11 +80,36 @@ describe.skip('PreprintDetailsComponent', () => {
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('isOsfPreprint should be true if providerId === osf', () => {
expect(component.isOsfPreprint()).toBeTruthy();
});

it('reacts to sequence of state changes', () => {
fixture.detectChanges();
expect(dataciteService.logView).toHaveBeenCalledTimes(0);

preprintSignal.set(getPreprint([]));

fixture.detectChanges();
expect(dataciteService.logView).toHaveBeenCalledTimes(0);

preprintSignal.set(getPreprint([{ category: 'dio', value: '123', id: '', type: 'identifier' }]));
fixture.detectChanges();
expect(dataciteService.logView).toHaveBeenCalledTimes(0);

preprintSignal.set(getPreprint([{ category: 'doi', value: '123', id: '', type: 'identifier' }]));

fixture.detectChanges();
expect(dataciteService.logView).toHaveBeenCalled();

preprintSignal.set(getPreprint([{ category: 'doi', value: '456', id: '', type: 'identifier' }]));
fixture.detectChanges();
expect(dataciteService.logView).toHaveBeenLastCalledWith('123');
});
});

function getPreprint(identifiers: Identifier[]) {
return {
identifiers: identifiers,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Button } from 'primeng/button';
import { DialogService } from 'primeng/dynamicdialog';
import { Skeleton } from 'primeng/skeleton';

import { filter, map, of } from 'rxjs';
import { filter, map, Observable, of } from 'rxjs';

import { DatePipe, Location } from '@angular/common';
import {
Expand All @@ -19,7 +19,7 @@ import {
OnDestroy,
OnInit,
} from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
import { ActivatedRoute, Router } from '@angular/router';

import { UserSelectors } from '@core/store/user';
Expand All @@ -46,7 +46,9 @@ import {
import { GetPreprintProviderById, PreprintProvidersSelectors } from '@osf/features/preprints/store/preprint-providers';
import { CreateNewVersion, PreprintStepperSelectors } from '@osf/features/preprints/store/preprint-stepper';
import { IS_MEDIUM, pathJoin } from '@osf/shared/helpers';
import { DataciteTrackerComponent } from '@shared/components/datacite-tracker/datacite-tracker.component';
import { ReviewPermissions, UserPermissions } from '@shared/enums';
import { Identifier } from '@shared/models';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is an identifier? I don't see it in the code base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { MetaTagsService } from '@shared/services';
import { ContributorsSelectors } from '@shared/stores';

Expand Down Expand Up @@ -75,7 +77,7 @@ import { environment } from 'src/environments/environment';
providers: [DialogService, DatePipe],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PreprintDetailsComponent implements OnInit, OnDestroy {
export class PreprintDetailsComponent extends DataciteTrackerComponent implements OnInit, OnDestroy {
@HostBinding('class') classes = 'flex-1 flex flex-column w-full';

private readonly router = inject(Router);
Expand Down Expand Up @@ -105,6 +107,7 @@ export class PreprintDetailsComponent implements OnInit, OnDestroy {
preprintProvider = select(PreprintProvidersSelectors.getPreprintProviderDetails(this.providerId()));
isPreprintProviderLoading = select(PreprintProvidersSelectors.isPreprintProviderDetailsLoading);
preprint = select(PreprintSelectors.getPreprint);
preprint$ = toObservable(select(PreprintSelectors.getPreprint));
isPreprintLoading = select(PreprintSelectors.isPreprintLoading);
contributors = select(ContributorsSelectors.getContributors);
areContributorsLoading = select(ContributorsSelectors.isContributorsLoading);
Expand Down Expand Up @@ -281,12 +284,17 @@ export class PreprintDetailsComponent implements OnInit, OnDestroy {
this.fetchPreprint(this.preprintId());
},
});
this.setupDataciteViewTrackerEffect().subscribe();
}

ngOnDestroy() {
this.actions.resetState();
}

protected override get trackable(): Observable<{ identifiers?: Identifier[] } | null> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a collection of identifiers if you are only returning a preprint (singular)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusion, but I am not returning a preprint only. This method returns everything which has identifiers. In our case it it Preprints, Registrations and Projects.

These models have a collection of identifiers because there may be other identifiers other than DOI.

return this.preprint$;
}

fetchPreprintVersion(preprintVersionId: string) {
const currentUrl = this.router.url;
const newUrl = currentUrl.replace(/[^/]+$/, preprintVersionId);
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/preprints/services/preprints.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class PreprintsService {
const params = {
'metrics[views]': 'total',
'metrics[downloads]': 'total',
'embed[]': 'license',
'embed[]': ['license', 'identifiers'],
};
return this.jsonApiService
.get<
Expand Down
Loading