Skip to content

Commit 9425e05

Browse files
atarix83Mattia Vianelli
authored andcommitted
[DSC-2764] Add configuration to define lucky search redirect codes
(cherry picked from commit bb6bed556693e518da4b4e444f8868d177bb057f)
1 parent 7e34920 commit 9425e05

5 files changed

Lines changed: 149 additions & 1 deletion

File tree

src/app/lucky-search/search/lucky-search.component.spec.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,34 @@ import { TruncatablePartComponent } from '../../shared/truncatable/truncatable-p
5252
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
5353
import { LuckySearchService } from '../lucky-search.service';
5454
import { LuckySearchComponent } from './lucky-search.component';
55+
import {ComponentFixture, TestBed} from '@angular/core/testing';
56+
57+
import {LuckySearchComponent} from './lucky-search.component';
58+
import {LuckySearchService} from '../lucky-search.service';
59+
import {SearchConfigurationService} from '../../core/shared/search/search-configuration.service';
60+
import {Router, UrlTree} from '@angular/router';
61+
import {createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$} from '../../shared/remote-data.utils';
62+
import {createPaginatedList} from '../../shared/testing/utils.test';
63+
import {Item} from '../../core/shared/item.model';
64+
import {of as observableOf} from 'rxjs';
65+
import {PaginatedSearchOptions} from '../../shared/search/models/paginated-search-options.model';
66+
import {PaginationComponentOptions} from '../../shared/pagination/pagination-component-options.model';
67+
import {SortDirection, SortOptions} from '../../core/cache/models/sort-options.model';
68+
import {TranslateModule} from '@ngx-translate/core';
69+
import {By} from '@angular/platform-browser';
70+
import {SearchResult} from '../../shared/search/models/search-result.model';
71+
import {DSpaceObject} from '../../core/shared/dspace-object.model';
72+
import {BitstreamDataService, MetadataFilter} from '../../core/data/bitstream-data.service';
73+
import {Bitstream} from '../../core/shared/bitstream.model';
74+
import {RouterMock} from '../../shared/mocks/router.mock';
75+
import {MetadataMap, MetadataValue} from '../../core/shared/metadata.models';
76+
import {FileSizePipe} from '../../shared/utils/file-size-pipe';
77+
import {HardRedirectService} from '../../core/services/hard-redirect.service';
78+
import {getBitstreamDownloadRoute} from '../../app-routing-paths';
79+
import {PLATFORM_ID} from '@angular/core';
80+
import {NotificationsService} from '../../shared/notifications/notifications.service';
81+
import {NotificationsServiceStub} from '../../shared/testing/notifications-service.stub';
82+
import {APP_CONFIG} from '../../../config/app-config.interface';
5583

5684
describe('LuckySearchComponent', () => {
5785
let fixture: ComponentFixture<LuckySearchComponent>;
@@ -131,6 +159,7 @@ describe('LuckySearchComponent', () => {
131159
{ provide: HardRedirectService, useValue: hardRedirectService },
132160
{ provide: PLATFORM_ID, useValue: 'browser' },
133161
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
162+
{provide: APP_CONFIG, useValue: {}},
134163
],
135164
}).overrideComponent(LuckySearchComponent, {
136165
remove: {
@@ -355,4 +384,57 @@ describe('LuckySearchComponent', () => {
355384
});
356385

357386
});
387+
388+
describe('', () => {
389+
beforeEach(() => {
390+
fixture = TestBed.createComponent(LuckySearchComponent);
391+
component = fixture.componentInstance;
392+
});
393+
394+
it('should return default code when no specific identifier is found', () => {
395+
// @ts-ignore: Accessing private method for testing
396+
component.appConfig = {
397+
luckySearchRedirects: {
398+
default: 301
399+
}
400+
} as any;
401+
// @ts-ignore: Accessing private method for testing
402+
component.currentFilter = {identifier: 'unknown'};
403+
404+
// @ts-ignore: Accessing private method for testing
405+
const result = component.getRedirectCode();
406+
407+
expect(result).toBe(301);
408+
});
409+
410+
it('should return 302 when default is not set and identifier is not found', () => {
411+
// @ts-ignore: Accessing private method for testing
412+
component.appConfig = {
413+
luckySearchRedirects: {}
414+
} as any;
415+
// @ts-ignore: Accessing private method for testing
416+
component.currentFilter = {identifier: 'unknown'};
417+
418+
// @ts-ignore: Accessing private method for testing
419+
const result = component.getRedirectCode();
420+
expect(result).toBe(302);
421+
});
422+
423+
it('should return specific code for known identifier', () => {
424+
// @ts-ignore: Accessing private method for testing
425+
component.appConfig = {
426+
luckySearchRedirects: {
427+
default: 302,
428+
'legacy-id': 301
429+
}
430+
};
431+
// @ts-ignore: Accessing private method for testing
432+
component.currentFilter = {identifier: 'legacy-id'};
433+
434+
// @ts-ignore: Accessing private method for testing
435+
const result = component.getRedirectCode();
436+
expect(result).toBe(301);
437+
});
438+
439+
});
358440
});

src/app/lucky-search/search/lucky-search.component.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import { TruncatableComponent } from '../../shared/truncatable/truncatable.compo
6464
import { TruncatablePartComponent } from '../../shared/truncatable/truncatable-part/truncatable-part.component';
6565
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
6666
import { LuckySearchService } from '../lucky-search.service';
67+
import {APP_CONFIG, AppConfig} from '../../../config/app-config.interface';
6768

6869
@Component({
6970
selector: 'ds-lucky-search',
@@ -127,6 +128,7 @@ export class LuckySearchComponent implements OnInit {
127128
private hardRedirectService: HardRedirectService,
128129
private notificationService: NotificationsService,
129130
private translateService: TranslateService,
131+
@Inject(APP_CONFIG) private appConfig: AppConfig,
130132
) {}
131133

132134
ngOnInit(): void {
@@ -236,12 +238,21 @@ export class LuckySearchComponent implements OnInit {
236238

237239
public redirect(url: string): void {
238240
if (isPlatformServer(this.platformId)) {
239-
this.hardRedirectService.redirect(url, 302);
241+
this.hardRedirectService.redirect(url, this.getRedirectCode());
240242
} else {
241243
this.router.navigateByUrl(url, { replaceUrl: true });
242244
}
243245
}
244246

247+
private getRedirectCode(): number {
248+
let code: number = this.appConfig?.luckySearchRedirects?.default || 302;
249+
if (Object.keys(this.appConfig?.luckySearchRedirects).includes(this.currentFilter.identifier)) {
250+
code = this.appConfig.luckySearchRedirects[this.currentFilter.identifier];
251+
}
252+
253+
return code;
254+
}
255+
245256
private parseBitstreamFilters(queryParams: Params): MetadataFilter[] {
246257
const metadataName = queryParams?.bitstreamMetadata;
247258
const metadataValue = queryParams?.bitstreamValue;

src/config/app-config.interface.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import { SubmissionConfig } from './submission-config.interface';
5656
import { SuggestionConfig } from './suggestion-config.interfaces';
5757
import { ThemeConfig } from './theme.config';
5858
import { UIServerConfig } from './ui-server-config.interface';
59+
import {LuckySearchRedirectConfig} from './lucky-search-redirect-config';
5960

6061
interface AppConfig extends Config {
6162
ui: UIServerConfig;
@@ -109,6 +110,11 @@ interface AppConfig extends Config {
109110
metadataLinkViewPopoverData: MetadataLinkViewPopoverDataConfig;
110111
identifierSubtypes: IdentifierSubtypesConfig[];
111112
datadogRum?: DatadogRumConfig;
113+
location: LocationConfig;
114+
epflUnpaywallMetadata: EpflUnpaywallMetadata;
115+
loader: LoaderConfig;
116+
permanentRedirectPaths?: string[];
117+
luckySearchRedirects?: LuckySearchRedirectConfig;
112118
}
113119

114120
/**

src/config/default-app-config.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,36 @@ import { ServerConfig } from './server-config.interface';
5555
import { SubmissionConfig } from './submission-config.interface';
5656
import { ThemeConfig } from './theme.config';
5757
import { UIServerConfig } from './ui-server-config.interface';
58+
import { BundleConfig } from './bundle-config.interface';
59+
import { ActuatorsConfig } from './actuators.config';
60+
import { InfoConfig } from './info-config.interface';
61+
import { CommunityListConfig } from './community-list-config.interface';
62+
import { HomeConfig } from './homepage-config.interface';
63+
import { MarkdownConfig } from './markdown-config.interface';
64+
import { FilterVocabularyConfig } from './filter-vocabulary-config';
65+
import { DiscoverySortConfig } from './discovery-sort.config';
66+
import { AddToAnyPluginConfig } from './add-to-any-plugin-config';
67+
import { CmsMetadata } from './cms-metadata';
68+
import { CrisLayoutConfig, LayoutConfig, SuggestionConfig } from './layout-config.interfaces';
69+
import { MetadataSecurityConfig } from './metadata-security-config';
70+
import { FollowAuthorityMetadata } from './search-follow-metadata.interface';
71+
import { MetricVisualizationConfig } from './metric-visualization-config.interfaces';
72+
import {
73+
AdvancedAttachmentElementType,
74+
AdvancedAttachmentRenderingConfig
75+
} from './advanced-attachment-rendering.config';
76+
import { AttachmentRenderingConfig } from './attachment-rendering.config';
77+
import { SearchResultConfig } from './search-result-config.interface';
78+
import { VirtualCollectionConfig } from './virtual-collection-config.interface';
79+
import { EpflUnpaywallMetadata } from './epfl-unpaywall-metadata';
80+
import { MiradorConfig } from './mirador-config.interfaces';
81+
import { LoaderConfig } from './loader-config.interfaces';
82+
import { MetaTagsConfig } from './meta-tags.config';
83+
import { MetadataLinkViewPopoverDataConfig } from './metadata-link-view-popoverdata-config.interface';
84+
import { IdentifierSubtypesConfig, IdentifierSubtypesIconPositionEnum } from './identifier-subtypes-config.interface';
85+
import { DatadogRumConfig } from './datadog-rum-config.interfaces';
86+
import { LocationConfig } from './location-config.interface';
87+
import {LuckySearchRedirectConfig} from './lucky-search-redirect-config';
5888

5989
export class DefaultAppConfig implements AppConfig {
6090
production = false;
@@ -1054,4 +1084,17 @@ export class DefaultAppConfig implements AppConfig {
10541084
trackLongTasks: true,
10551085
defaultPrivacyLevel: 'mask-user-input',
10561086
};
1087+
1088+
location: LocationConfig = {
1089+
nominatimApi: {
1090+
searchEndpoint: 'https://nominatim.openstreetmap.org/search',
1091+
reverseSearchEndpoint: 'https://nominatim.openstreetmap.org/reverse',
1092+
statusEndpoint: 'https://nominatim.openstreetmap.org/status',
1093+
}
1094+
};
1095+
1096+
luckySearchRedirects: LuckySearchRedirectConfig = {
1097+
'legacy-id': 301,
1098+
default: 302
1099+
};
10571100
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import {Config} from './config.interface';
2+
3+
export interface LuckySearchRedirectConfig extends Config {
4+
[indexName: string]: number;
5+
default: number;
6+
}

0 commit comments

Comments
 (0)