From 7b0c8f0e8b5bc4a6fb2a0b2d217da6dfd8ee8ed2 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Wed, 4 Mar 2026 14:34:02 +0200 Subject: [PATCH 1/4] fix(ENG-10087): Update preprint download url --- src/app/app.routes.ts | 7 +++++++ .../preprint-download-redirect.component.ts | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 49c222492..1de586b65 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -107,6 +107,13 @@ export const routes: Routes = [ '@osf/features/preprints/pages/preprint-pending-moderation/preprint-pending-moderation.component' ).then((mod) => mod.PreprintPendingModerationComponent), }, + { + path: 'preprints/:providerId/:id/download', + loadComponent: () => + import('@osf/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component').then( + (c) => c.PreprintDownloadRedirectComponent + ), + }, { path: 'preprints/:providerId/:id', loadComponent: () => diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts new file mode 100644 index 000000000..4e99c8e66 --- /dev/null +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts @@ -0,0 +1,18 @@ +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; + +@Component({ + selector: 'osf-preprint-download-redirect', + template: '', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PreprintDownloadRedirectComponent { + constructor() { + const route = inject(ActivatedRoute); + const id = route.snapshot.paramMap.get('id') ?? ''; + + if (id) { + window.location.href = `/download/${id}`; + } + } +} From 4855cf4a11ae2e62eaccf03880003aef46c3e95d Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 5 Mar 2026 14:53:44 +0200 Subject: [PATCH 2/4] fix(ENG-10087): Update preprint download url and add tests --- ...eprint-download-redirect.component.spec.ts | 76 +++++++++++++++++++ .../preprint-download-redirect.component.ts | 19 +++-- 2 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts new file mode 100644 index 000000000..98fb18c15 --- /dev/null +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts @@ -0,0 +1,76 @@ +import { MockProvider } from 'ng-mocks'; + +import { PLATFORM_ID } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { ActivatedRoute } from '@angular/router'; + +import { SocialShareService } from '@osf/shared/services/social-share.service'; + +import { PreprintDownloadRedirectComponent } from './preprint-download-redirect.component'; + +import { provideOSFCore } from '@testing/osf.testing.provider'; +import { ActivatedRouteMockBuilder } from '@testing/providers/route-provider.mock'; + +const MOCK_ID = 'test-preprint-id'; +const MOCK_DOWNLOAD_URL = 'https://osf.io/download/test-preprint-id'; + +describe('PreprintDownloadRedirectComponent', () => { + let locationReplaceMock: jest.Mock; + + beforeEach(() => { + locationReplaceMock = jest.fn(); + Object.defineProperty(window, 'location', { + value: { replace: locationReplaceMock }, + writable: true, + configurable: true, + }); + }); + + function setup(overrides: { id?: string | null; isBrowser?: boolean } = {}) { + const { id = MOCK_ID, isBrowser = true } = overrides; + + const mockRoute = ActivatedRouteMockBuilder.create() + .withParams(id ? { id } : {}) + .build(); + + const mockSocialShareService = { + createDownloadUrl: jest.fn().mockReturnValue(MOCK_DOWNLOAD_URL), + }; + + TestBed.configureTestingModule({ + imports: [PreprintDownloadRedirectComponent], + providers: [ + provideOSFCore(), + MockProvider(ActivatedRoute, mockRoute), + MockProvider(SocialShareService, mockSocialShareService), + { provide: PLATFORM_ID, useValue: isBrowser ? 'browser' : 'server' }, + ], + }); + + const fixture = TestBed.createComponent(PreprintDownloadRedirectComponent); + return { fixture, component: fixture.componentInstance, mockSocialShareService }; + } + + it('should create', () => { + const { component } = setup(); + expect(component).toBeTruthy(); + }); + + it('should redirect to download URL when id is present in browser', () => { + const { mockSocialShareService } = setup({ id: MOCK_ID }); + expect(mockSocialShareService.createDownloadUrl).toHaveBeenCalledWith(MOCK_ID); + expect(locationReplaceMock).toHaveBeenCalledWith(MOCK_DOWNLOAD_URL); + }); + + it('should not redirect when id is missing', () => { + const { mockSocialShareService } = setup({ id: null }); + expect(mockSocialShareService.createDownloadUrl).not.toHaveBeenCalled(); + expect(locationReplaceMock).not.toHaveBeenCalled(); + }); + + it('should not redirect when not in browser', () => { + const { mockSocialShareService } = setup({ isBrowser: false }); + expect(mockSocialShareService.createDownloadUrl).not.toHaveBeenCalled(); + expect(locationReplaceMock).not.toHaveBeenCalled(); + }); +}); diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts index 4e99c8e66..278976781 100644 --- a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts @@ -1,18 +1,27 @@ -import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; +import { isPlatformBrowser } from '@angular/common'; +import { ChangeDetectionStrategy, Component, inject, PLATFORM_ID } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { SocialShareService } from '@osf/shared/services/social-share.service'; + @Component({ selector: 'osf-preprint-download-redirect', template: '', changeDetection: ChangeDetectionStrategy.OnPush, }) export class PreprintDownloadRedirectComponent { + private readonly route = inject(ActivatedRoute); + private readonly socialShareService = inject(SocialShareService); + private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); + constructor() { - const route = inject(ActivatedRoute); - const id = route.snapshot.paramMap.get('id') ?? ''; + const id = this.route.snapshot.paramMap.get('id') ?? ''; - if (id) { - window.location.href = `/download/${id}`; + if (!id || !this.isBrowser) { + return; } + + const url = this.socialShareService.createDownloadUrl(id); + window.location.replace(url); } } From 43da92d17a822ed194eaebe6415dde4b0de1955c Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 5 Mar 2026 16:46:03 +0200 Subject: [PATCH 3/4] fix(ENG-10087): Add text for download page --- .../preprint-download-redirect.component.spec.ts | 8 +++++++- .../preprint-download-redirect.component.ts | 5 ++++- src/assets/i18n/en.json | 3 +++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts index 98fb18c15..1aabf7386 100644 --- a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.spec.ts @@ -43,7 +43,7 @@ describe('PreprintDownloadRedirectComponent', () => { provideOSFCore(), MockProvider(ActivatedRoute, mockRoute), MockProvider(SocialShareService, mockSocialShareService), - { provide: PLATFORM_ID, useValue: isBrowser ? 'browser' : 'server' }, + MockProvider(PLATFORM_ID, isBrowser ? 'browser' : 'server'), ], }); @@ -56,6 +56,12 @@ describe('PreprintDownloadRedirectComponent', () => { expect(component).toBeTruthy(); }); + it('should render download message', () => { + const { fixture } = setup(); + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector('p').textContent).toContain('preprints.downloadRedirect.message'); + }); + it('should redirect to download URL when id is present in browser', () => { const { mockSocialShareService } = setup({ id: MOCK_ID }); expect(mockSocialShareService.createDownloadUrl).toHaveBeenCalledWith(MOCK_ID); diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts index 278976781..fab33ff6a 100644 --- a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts @@ -1,3 +1,5 @@ +import { TranslateModule } from '@ngx-translate/core'; + import { isPlatformBrowser } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, PLATFORM_ID } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @@ -6,8 +8,9 @@ import { SocialShareService } from '@osf/shared/services/social-share.service'; @Component({ selector: 'osf-preprint-download-redirect', - template: '', + template: `

{{ 'preprints.downloadRedirect.message' | translate }}

`, changeDetection: ChangeDetectionStrategy.OnPush, + imports: [TranslateModule], }) export class PreprintDownloadRedirectComponent { private readonly route = inject(ActivatedRoute); diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 6e2433aa5..768a18305 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -2345,6 +2345,9 @@ "singularCapitalized": "Thesis" } }, + "downloadRedirect": { + "message": "Your download will begin shortly." + }, "details": { "reasonForWithdrawal": "Reason for withdrawal", "originalPublicationDate": "Original Publication Date", From 486535a6a9e0fa9c88cecb20c9d91cd5ca6c22a8 Mon Sep 17 00:00:00 2001 From: Vlad0n20 Date: Thu, 5 Mar 2026 16:52:17 +0200 Subject: [PATCH 4/4] fix(ENG-10087): Update import --- .../preprint-download-redirect.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts index fab33ff6a..aa8bfc451 100644 --- a/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts +++ b/src/app/features/preprints/pages/preprint-download-redirect/preprint-download-redirect.component.ts @@ -1,4 +1,4 @@ -import { TranslateModule } from '@ngx-translate/core'; +import { TranslatePipe } from '@ngx-translate/core'; import { isPlatformBrowser } from '@angular/common'; import { ChangeDetectionStrategy, Component, inject, PLATFORM_ID } from '@angular/core'; @@ -10,7 +10,7 @@ import { SocialShareService } from '@osf/shared/services/social-share.service'; selector: 'osf-preprint-download-redirect', template: `

{{ 'preprints.downloadRedirect.message' | translate }}

`, changeDetection: ChangeDetectionStrategy.OnPush, - imports: [TranslateModule], + imports: [TranslatePipe], }) export class PreprintDownloadRedirectComponent { private readonly route = inject(ActivatedRoute);