Skip to content

Commit 38332e8

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

5 files changed

Lines changed: 158 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
@@ -1,3 +1,31 @@
1+
import {ComponentFixture, TestBed} from '@angular/core/testing';
2+
3+
import {LuckySearchComponent} from './lucky-search.component';
4+
import {LuckySearchService} from '../lucky-search.service';
5+
import {SearchConfigurationService} from '../../core/shared/search/search-configuration.service';
6+
import {Router, UrlTree} from '@angular/router';
7+
import {createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$} from '../../shared/remote-data.utils';
8+
import {createPaginatedList} from '../../shared/testing/utils.test';
9+
import {Item} from '../../core/shared/item.model';
10+
import {of as observableOf} from 'rxjs';
11+
import {PaginatedSearchOptions} from '../../shared/search/models/paginated-search-options.model';
12+
import {PaginationComponentOptions} from '../../shared/pagination/pagination-component-options.model';
13+
import {SortDirection, SortOptions} from '../../core/cache/models/sort-options.model';
14+
import {TranslateModule} from '@ngx-translate/core';
15+
import {By} from '@angular/platform-browser';
16+
import {SearchResult} from '../../shared/search/models/search-result.model';
17+
import {DSpaceObject} from '../../core/shared/dspace-object.model';
18+
import {BitstreamDataService, MetadataFilter} from '../../core/data/bitstream-data.service';
19+
import {Bitstream} from '../../core/shared/bitstream.model';
20+
import {RouterMock} from '../../shared/mocks/router.mock';
21+
import {MetadataMap, MetadataValue} from '../../core/shared/metadata.models';
22+
import {FileSizePipe} from '../../shared/utils/file-size-pipe';
23+
import {HardRedirectService} from '../../core/services/hard-redirect.service';
24+
import {getBitstreamDownloadRoute} from '../../app-routing-paths';
25+
import {PLATFORM_ID} from '@angular/core';
26+
import {NotificationsService} from '../../shared/notifications/notifications.service';
27+
import {NotificationsServiceStub} from '../../shared/testing/notifications-service.stub';
28+
import {APP_CONFIG} from '../../../config/app-config.interface';
129
import {
230
ChangeDetectionStrategy,
331
PLATFORM_ID,
@@ -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
@@ -66,6 +66,7 @@ import { TruncatableComponent } from '../../shared/truncatable/truncatable.compo
6666
import { TruncatablePartComponent } from '../../shared/truncatable/truncatable-part/truncatable-part.component';
6767
import { FileSizePipe } from '../../shared/utils/file-size-pipe';
6868
import { LuckySearchService } from '../lucky-search.service';
69+
import {APP_CONFIG, AppConfig} from '../../../config/app-config.interface';
6970

7071
@Component({
7172
selector: 'ds-lucky-search',
@@ -132,6 +133,7 @@ export class LuckySearchComponent implements OnInit {
132133
private hardRedirectService: HardRedirectService,
133134
private notificationService: NotificationsService,
134135
private translateService: TranslateService,
136+
@Inject(APP_CONFIG) private appConfig: AppConfig,
135137
) {}
136138

137139
ngOnInit(): void {
@@ -241,12 +243,21 @@ export class LuckySearchComponent implements OnInit {
241243

242244
public redirect(url: string): void {
243245
if (isPlatformServer(this.platformId)) {
244-
this.hardRedirectService.redirect(url, 302);
246+
this.hardRedirectService.redirect(url, this.getRedirectCode());
245247
} else {
246248
this.router.navigateByUrl(url, { replaceUrl: true });
247249
}
248250
}
249251

252+
private getRedirectCode(): number {
253+
let code: number = this.appConfig?.luckySearchRedirects?.default || 302;
254+
if (Object.keys(this.appConfig?.luckySearchRedirects).includes(this.currentFilter.identifier)) {
255+
code = this.appConfig.luckySearchRedirects[this.currentFilter.identifier];
256+
}
257+
258+
return code;
259+
}
260+
250261
private parseBitstreamFilters(queryParams: Params): MetadataFilter[] {
251262
const metadataName = queryParams?.bitstreamMetadata;
252263
const metadataValue = queryParams?.bitstreamValue;

src/config/app-config.interface.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ import { QualityAssuranceConfig } from './quality-assurance.config';
4949
import { FollowAuthorityMetadata } from './search-follow-metadata.interface';
5050
import { SearchConfig } from './search-page-config.interface';
5151
import { SearchResultConfig } from './search-result-config.interface';
52+
import {VirtualCollectionConfig} from './virtual-collection-config.interface';
53+
import {EpflUnpaywallMetadata} from './epfl-unpaywall-metadata';
54+
import { MiradorConfig } from './mirador-config.interfaces';
55+
import { LoaderConfig } from './loader-config.interfaces';
56+
import { MetaTagsConfig } from './meta-tags.config';
57+
import { MetadataLinkViewPopoverDataConfig } from './metadata-link-view-popoverdata-config.interface';
58+
import { IdentifierSubtypesConfig } from './identifier-subtypes-config.interface';
59+
import { DatadogRumConfig } from './datadog-rum-config.interfaces';
60+
import { LocationConfig } from './location-config.interface';
61+
import {LuckySearchRedirectConfig} from './lucky-search-redirect-config';
5262
import { ServerConfig } from './server-config.interface';
5363
import { SubmissionConfig } from './submission-config.interface';
5464
import { SuggestionConfig } from './suggestion-config.interfaces';
@@ -106,6 +116,11 @@ interface AppConfig extends Config {
106116
metadataLinkViewPopoverData: MetadataLinkViewPopoverDataConfig;
107117
identifierSubtypes: IdentifierSubtypesConfig[];
108118
datadogRum?: DatadogRumConfig;
119+
location: LocationConfig;
120+
epflUnpaywallMetadata: EpflUnpaywallMetadata;
121+
loader: LoaderConfig;
122+
permanentRedirectPaths?: string[];
123+
luckySearchRedirects?: LuckySearchRedirectConfig;
109124
}
110125

111126
/**

src/config/default-app-config.ts

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

5787
export class DefaultAppConfig implements AppConfig {
5888
production = false;
@@ -1023,4 +1053,17 @@ export class DefaultAppConfig implements AppConfig {
10231053
trackLongTasks: true,
10241054
defaultPrivacyLevel: 'mask-user-input',
10251055
};
1056+
1057+
location: LocationConfig = {
1058+
nominatimApi: {
1059+
searchEndpoint: 'https://nominatim.openstreetmap.org/search',
1060+
reverseSearchEndpoint: 'https://nominatim.openstreetmap.org/reverse',
1061+
statusEndpoint: 'https://nominatim.openstreetmap.org/status',
1062+
}
1063+
};
1064+
1065+
luckySearchRedirects: LuckySearchRedirectConfig = {
1066+
'legacy-id': 301,
1067+
default: 302
1068+
};
10261069
}
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)