Skip to content

Commit a82b66c

Browse files
authored
Add interim fix for typename error when linking drafts (#85)
* Ignore server errors if not handled * Add interim fix for typename errors * Handle null values in content types and rich media bodies * Make unit tests run * Remove comment * Update search proxy url
1 parent 1233c8a commit a82b66c

20 files changed

+99
-19
lines changed

research-hub-web/karma.conf.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = function (config) {
1212
require('karma-coverage'),
1313
require('@angular-devkit/build-angular/plugins/karma'),
1414
require('karma-verbose-reporter'),
15+
require("karma-spec-reporter")
1516
],
1617
client: {
1718
clearContext: false // leave Jasmine Spec Runner output visible in browser
@@ -30,7 +31,15 @@ module.exports = function (config) {
3031
},
3132
fixWebpackSourcePaths: true
3233
},
33-
reporters: ['progress', 'kjhtml'],
34+
reporters: ['spec'],
35+
specReporter: {
36+
maxLogLines: 5, // limit number of lines logged per test
37+
suppressErrorSummary: true, // do not print error summary
38+
suppressFailed: false, // do not print information about failed tests
39+
suppressPassed: false, // do not print information about passed tests
40+
suppressSkipped: true, // do not print information about skipped tests
41+
showSpecTiming: false // print the time elapsed for each spec
42+
},
3443
port: 9876,
3544
colors: true,
3645
logLevel: config.LOG_INFO,

research-hub-web/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
"karma-coverage": "^2.0.3",
107107
"karma-jasmine": "~4.0.0",
108108
"karma-jasmine-html-reporter": "^1.5.0",
109+
"karma-spec-reporter": "0.0.32",
109110
"karma-verbose-reporter": "0.0.6",
110111
"nodemon": "^2.0.4",
111112
"sass": "^1.26.9",

research-hub-web/src/app/app.module.ts

+15-1
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,29 @@ export class AppModule {
9292

9393

9494
// The error link handler. Redirects to SSO login on UNAUTHENTICATED errors
95-
const error = onError(({ networkError, graphQLErrors }) => {
95+
const error = onError(({ response, networkError, graphQLErrors }) => {
96+
const hasErrors = networkError || graphQLErrors;
9697
if (networkError) {
98+
console.log("API returned networkError", networkError);
9799
if (networkError['error']['errors'][0]['extensions']['code'] === 'UNAUTHENTICATED') {
98100
this.loginService.doLogin(this.router.url);
101+
return;
99102
}
100103
}
101104
if (graphQLErrors) {
105+
console.log("API returned graphQLErrors", graphQLErrors);
102106
if (graphQLErrors[0].extensions.code === "UNAUTHENTICATED") {
103107
this.loginService.doLogin(this.router.url);
108+
return;
109+
}
110+
}
111+
112+
if (hasErrors) {
113+
// If there is any data, disregard any errors.
114+
// This will mean the page will render as usual.
115+
if (response.data) {
116+
console.log("Ignoring errors as there is partial data to render.");
117+
response.errors = null;
104118
}
105119
}
106120
});

research-hub-web/src/app/components/articles/articles.component.ts

+6
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ export class ArticlesComponent implements OnInit, OnDestroy {
9797
this.article = this.getArticleBySlug(this.slug);
9898
this.article$ = this.getArticleBySlug(this.slug).subscribe(data => {
9999
this.detectDevice();
100+
// Strip nulls from related collection data.
101+
data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item);
102+
data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item);
103+
data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item);
104+
data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item);
105+
100106
this.bodyMediaService.setBodyMedia(data.bodyText?.links);
101107
this.appComponentService.setTitle(data.title);
102108
});

research-hub-web/src/app/components/equipments/equipment.component.ts

+5
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ export class EquipmentComponent implements OnInit, OnDestroy {
9191
this.equipment = this.getEquipmentBySlug(this.slug);
9292
this.equipment$ = this.getEquipmentBySlug(this.slug).subscribe(data => {
9393
this.detectDevice();
94+
// Strip nulls from related collection data.
95+
data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item);
96+
data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item);
97+
data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item);
98+
data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item);
9499
this.bodyMediaService.setBodyMedia(data.bodyText?.links);
95100
this.appComponentService.setTitle(data.title);
96101
});

research-hub-web/src/app/components/events/events.component.ts

+6
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ export class EventsComponent implements OnInit, OnDestroy {
9393
if (data.callToAction.match( /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
9494
data['callToAction'] = 'mailto:' + data['callToAction'];
9595
}
96+
97+
// Strip nulls from related collection data.
98+
data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item);
99+
data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item);
100+
data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item);
101+
data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item);
96102

97103
this.detectDevice();
98104
this.bodyMediaService.setBodyMedia(data.bodyText?.links);

research-hub-web/src/app/components/home/featured/featured.component.spec.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
22
import { RouterTestingModule } from '@angular/router/testing';
3+
import { ApolloTestingModule } from 'apollo-angular/testing';
34
import { FeaturedComponent } from './featured.component';
45

56
describe('FeaturedComponent', () => {
@@ -9,7 +10,7 @@ describe('FeaturedComponent', () => {
910
beforeEach(async () => {
1011
await TestBed.configureTestingModule({
1112
declarations: [ FeaturedComponent ],
12-
imports: [RouterTestingModule.withRoutes([])]
13+
imports: [RouterTestingModule.withRoutes([]), ApolloTestingModule]
1314
})
1415
.compileComponents();
1516
});

research-hub-web/src/app/components/legacy-routing/legacy-routing.component.spec.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
2+
import { RouterTestingModule } from "@angular/router/testing";
33
import { LegacyRoutingComponent } from './legacy-routing.component';
44

55
describe('LegacyRoutingComponent', () => {
66
let component: LegacyRoutingComponent;
77
let fixture: ComponentFixture<LegacyRoutingComponent>;
8-
8+
// let controller: ApolloTestingController;
99
beforeEach(async () => {
1010
await TestBed.configureTestingModule({
11-
declarations: [ LegacyRoutingComponent ]
11+
declarations: [ LegacyRoutingComponent ],
12+
imports: [
13+
RouterTestingModule.withRoutes([
14+
// Set up mock routes to make test pass.
15+
{
16+
path: "error/:errorCode",
17+
redirectTo: "",
18+
}
19+
])
20+
]
1221
})
1322
.compileComponents();
1423
});

research-hub-web/src/app/components/services/services.component.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ export class ServicesComponent implements OnInit, OnDestroy {
9393
if (data.callToAction.match( /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)) {
9494
data['callToAction'] = 'mailto:' + data['callToAction'];
9595
}
96-
96+
97+
// Strip nulls from related collection data.
98+
data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item);
99+
data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item);
100+
data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item);
101+
data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item);
97102
this.detectDevice();
98103
this.bodyMediaService.setBodyMedia(data.bodyText?.links);
99104
this.appComponentService.setTitle(data.title);

research-hub-web/src/app/components/shared/body-media/body-media.component.html

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
<span [ngSwitch]="data.nodeType">
1+
<span [ngSwitch]="data.nodeType" *ngIf="contentItem">
32

43
<!-- Asset Block -->
54
<span *ngSwitchCase="'embedded-asset-block'">

research-hub-web/src/app/components/shared/body-media/body-media.component.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,22 @@ export class BodyMediaComponent extends NodeRenderer implements OnInit {
3030
this.returnVal$ = this.bodyMediaService.getBodyMedia();
3131

3232
switch(this.data.nodeType) {
33+
// For each type of node, first filter out null values, then find matching node.
3334
case 'embedded-asset-block':
34-
this.contentItem = this.returnVal$.assets['block'].find(x => x.sys.id == this.data.data.target.sys.id);
35+
this.contentItem = this.returnVal$.assets['block'].filter(x => x).find(x => x.sys.id == this.data.data.target.sys.id);
3536
this.contentItem['size'] = Math.round(this.contentItem['size'] / 1000) + (Math.round(this.contentItem['size'] % 1000) / 100);
3637
break;
3738
case 'embedded-entry-block':
38-
this.contentItem = this.returnVal$.entries['block'].find(x => x.sys.id == this.data.data.target.sys.id);
39+
this.contentItem = this.returnVal$.entries['block'].filter(x => x).find(x => x.sys.id == this.data.data.target.sys.id);
3940
break;
4041
case 'embedded-entry-inline':
41-
this.contentItem = this.returnVal$.entries['inline'].find(x => x.sys.id == this.data.data.target.sys.id);
42+
this.contentItem = this.returnVal$.entries['inline'].filter(x => x).find(x => x.sys.id == this.data.data.target.sys.id);
4243
break;
4344
case 'entry-hyperlink':
44-
this.contentItem = this.returnVal$.entries['hyperlink'].find(x => x.sys.id == this.data.data.target.sys.id);
45+
this.contentItem = this.returnVal$.entries['hyperlink'].filter(x => x).find(x => x.sys.id == this.data.data.target.sys.id);
4546
break;
4647
case 'asset-hyperlink':
47-
this.contentItem = this.returnVal$.assets['hyperlink'].find(x => x.sys.id == this.data.data.target.sys.id);
48+
this.contentItem = this.returnVal$.assets['hyperlink'].filter(x => x).find(x => x.sys.id == this.data.data.target.sys.id);
4849
break;
4950
case 'unordered-list':
5051
this.contentItem = {__typename: '', items: []};

research-hub-web/src/app/components/shared/cards/cards.component.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<div *ngIf="contentItem.items.length > 0" role="article">
1+
<div *ngIf="contentItem?.items?.length > 0" role="article">
22

33
<!-- Title of card collection -->
44
<h3 *ngIf="title">{{ title }}<hr/></h3>

research-hub-web/src/app/components/shared/cards/cards.component.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,19 @@ import { Component, OnInit, Input } from '@angular/core';
77
})
88
export class CardsComponent implements OnInit {
99
@Input() title;
10-
@Input() contentItem;
10+
public contentItem;
11+
@Input("contentItem") _inputContentItem;
1112
@Input() hideImage?: boolean;
1213
@Input() flex;
1314

1415
constructor() { }
1516

1617
async ngOnInit() {
17-
18+
// Make a copy of the contentItem, so we can make changes to it without causing ChangedAfterCheckErrors.
19+
// Then, remove null items.
20+
this.contentItem = Object.assign({}, this._inputContentItem);
21+
// Don't display content without a title or name.
22+
this.contentItem.items = this.contentItem.items.filter(item => item && (item.title || item.name || item.maoriName));
1823
// If you want to hide image when displayed
1924
if (this.hideImage) { this.contentItem.items.forEach(element => {
2025
try { delete element['banner'].url } catch {} });

research-hub-web/src/app/components/shared/large-cards/large-cards.component.ts

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export class LargeCardsComponent implements OnInit {
1919
... this.contentItem.externalPagesCollection.items];
2020
}
2121

22+
// Remove empty items and ones without titles.
23+
this.contentItem['items'] = this.contentItem['items'].filter(item => item && item.title);
24+
2225
// If you want to hide image when displayed
2326
if (this.hideImage) {
2427
this.contentItem.items.forEach(element => {

research-hub-web/src/app/components/softwares/softwares.component.ts

+5
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ export class SoftwaresComponent implements OnInit, OnDestroy {
8888
this.software = this.getSoftwareBySlug(this.slug);
8989
this.software$ = this.getSoftwareBySlug(this.slug).subscribe(data => {
9090
this.detectDevice();
91+
// Strip nulls from related collection data.
92+
data.relatedContactsCollection.items = data.relatedContactsCollection.items.filter(item => item);
93+
data.relatedDocsCollection.items = data.relatedDocsCollection.items.filter(item => item);
94+
data.relatedItemsCollection.items = data.relatedItemsCollection.items.filter(item => item);
95+
data.relatedOrgsCollection.items = data.relatedOrgsCollection.items.filter(item => item);
9196
this.bodyMediaService.setBodyMedia(data.bodyText?.links);
9297
this.appComponentService.setTitle(data.title);
9398
});

research-hub-web/src/app/components/subhub-routes-loader/subhub-routes-loader.component.spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
22
import { RouterTestingModule } from '@angular/router/testing';
3+
import { ApolloTestingModule } from 'apollo-angular/testing';
34

45
import { SubHubRoutesLoaderComponent } from './subhub-routes-loader.component';
56

@@ -15,7 +16,8 @@ describe('SubHubRoutesLoaderComponent', () => {
1516
await TestBed.configureTestingModule({
1617
declarations: [ SubHubRoutesLoaderComponent ],
1718
imports: [
18-
RouterTestingModule.withRoutes([])
19+
RouterTestingModule.withRoutes([]),
20+
ApolloTestingModule
1921
]
2022
})
2123
.compileComponents();

research-hub-web/src/app/components/subhubs/subhubs.component.ts

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ export class SubhubsComponent implements OnInit, OnDestroy {
8484
if (!!this.slug) {
8585
this.subHub = this.getSubHubBySlug(this.slug);
8686
this.subHub$ = this.getSubHubBySlug(this.slug).subscribe(data => {
87+
// Remove nulls from server in case of error.
88+
data.internalPagesCollection.items = data.internalPagesCollection.items.filter(item => item);
89+
data.externalPagesCollection.items = data.externalPagesCollection.items.filter(item => item);
8790
this.detectDevice();
8891
this.bodyMediaService.setBodyMedia(data.bodyText?.links);
8992
this.appComponentService.setTitle(data.title);

research-hub-web/src/app/services/cer-graphql.service.ts

+6
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ export class CerGraphqlService {
110110
private _getBreadCrumbsArray(entrySlug: string, breadcrumbsArray) {
111111
for (const item of this._subHubCollectionWithChildPagesSlugs) {
112112
item.internalPagesCollection.items.forEach(subPage => {
113+
if (!subPage) {
114+
return;
115+
}
113116
if (subPage.slug === entrySlug) { // The SubHub's childPages contains the current entry we're searching for
114117
for (const subHub of breadcrumbsArray) { // Check it's not already known
115118
if (subHub.slug === item.slug) {
@@ -226,6 +229,9 @@ class SubHubMap {
226229
parentSubHub[subHub.slug] = new Content(subHub.slug, subHub.__typename); // Add to the right parent subhub
227230

228231
for (const subHubChildPage of subHub.internalPagesCollection.items) { // Then loop through its child pages
232+
if (!subHubChildPage) {
233+
continue;
234+
}
229235
if (subHubChildPage.__typename === 'SubHub') { // If the child page is a SubHub, check if its known
230236
const subHubChildPageExistingParentSubHub = this.findParentSubHub(subHubChildPage.slug, this.map);
231237
if (subHubChildPageExistingParentSubHub) { // The child SubHub is known, so move it here

research-hub-web/src/environments/environment.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ export const environment = {
2828
},
2929
},
3030

31-
}
31+
}

research-hub-web/test.sh

100644100755
File mode changed.

0 commit comments

Comments
 (0)