Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
51e5c0d
Squashed commit of the following:
Trombach Oct 19, 2021
3b70c8c
initial refactor of article component
Trombach Oct 20, 2021
18a9c20
Merge branch 'master' into content-pages-refactor
Trombach Nov 9, 2021
c23c6a9
merge changes to article.component
Trombach Nov 9, 2021
782c113
Merge branch 'master' into content-pages-refactor
Trombach Nov 10, 2021
76ae8f4
more changes
Trombach Nov 10, 2021
6e7ce10
fixes and 404 redirect
Trombach Nov 10, 2021
e5f22a7
breadcrumb refactor
Trombach Nov 10, 2021
055d8d9
final changes to article
Trombach Nov 10, 2021
e68bd14
final changes to case study
Trombach Nov 11, 2021
4001b50
removed unused import from article
Trombach Nov 11, 2021
f77833d
final changes to equipment
Trombach Nov 11, 2021
1439933
final changes to event
Trombach Nov 11, 2021
41a7f04
final changes to funding
Trombach Nov 11, 2021
0ab5e85
changes to subhub component
Trombach Nov 15, 2021
39fb047
changes to service
Trombach Nov 15, 2021
886455d
changes to software
Trombach Nov 15, 2021
1c37cc2
fix for dynamic routing
Trombach Nov 15, 2021
293aab7
Merge branch 'master' into content-pages-refactor
Trombach Nov 15, 2021
6e1d854
added default images to cards
Trombach Nov 15, 2021
2f68379
changed template name
Trombach Nov 16, 2021
c8900ef
formatting
Trombach Nov 16, 2021
5b37e6c
streamlined observables
Trombach Nov 16, 2021
9de1f77
workaround for 404 page flashing when viewing protected content
Trombach Nov 18, 2021
37b4264
redirect to list page if no slug is present
Trombach Nov 18, 2021
84adc44
Merge branch 'master' into content-pages-refactor
Trombach Nov 18, 2021
a9af9f2
unit tests WIP
rosemcc Nov 19, 2021
5d45729
unit tests wip
rosemcc Nov 19, 2021
5149a85
error handling
rosemcc Nov 21, 2021
d890e7d
more error handling
rosemcc Nov 21, 2021
e2df9e2
removing icons
rosemcc Nov 21, 2021
b181970
delete unneeded module
rosemcc Nov 22, 2021
3a75638
unit tests clean ups and mock breadcrumbs
rosemcc Nov 22, 2021
ab44805
breadcrumbs unit test
rosemcc Nov 22, 2021
469956d
add page titles for list pages
rosemcc Nov 22, 2021
8368d7e
content page unit tests passing and moving collection list tests
rosemcc Nov 22, 2021
afc9474
fix event page unit test
rosemcc Nov 22, 2021
d912e60
list pages unit tests passing
rosemcc Nov 22, 2021
d37da13
delete unused queries, add limit to all-items queries
rosemcc Nov 22, 2021
869bb02
minor fix for empty collection
rosemcc Nov 22, 2021
fbafbf2
fix empty doc and org cards for items in draft
rosemcc Nov 22, 2021
fb10bc1
added breadcrumbs unit tests
rosemcc Nov 23, 2021
ef9deb0
fix breadcrumbs bug
rosemcc Nov 23, 2021
038dae7
Merge branch 'master' into content-pages-refactor
rosemcc Nov 23, 2021
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
1 change: 0 additions & 1 deletion cer-graphql/validateUnauthenticatedQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const GRAPHQL_INTROSPECTION_FIELDS = [
'linkedFrom',
'slug',
'banner',
'icon',
...GRAPHQL_INTROSPECTION_FIELDS
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { StageCollection, AllStagesGQL } from '@graphql/schema';
import { Observable, of } from 'rxjs';
import { MockComponent, MockProvider } from 'ng-mocks';
import { PageTitleService } from '@services/page-title.service';

import { RouterTestingModule } from '@angular/router/testing';

describe('ActivitiesPageComponent', () => {
let component: ActivitiesPageComponent;
Expand Down Expand Up @@ -49,7 +49,8 @@ describe('ActivitiesPageComponent', () => {
],
imports: [
HttpClientTestingModule,
ApolloTestingModule
ApolloTestingModule,
RouterTestingModule.withRoutes([])
],
providers: [
MockProvider(SearchService),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<app-collection-list [collection]="articles"></app-collection-list>
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing';
import { ArticleListComponent } from './article-list.component';
import { SharedModule } from '@components/shared/app.shared.module';
import { MockComponent, MockModule, MockProvider } from 'ng-mocks';
import { RouterTestingModule } from '@angular/router/testing';
import { PageTitleService } from '@services/page-title.service';
import { CollectionListComponent } from '@app/components/shared/collection-list/collection-list.component';
import { ArticleCollection } from '@app/graphql/schema';
import { Observable, of } from 'rxjs';

describe('ArticleListComponent', () => {
let component: ArticleListComponent;
let fixture: ComponentFixture<ArticleListComponent>;
let controller: ApolloTestingController;

const mockAllArticles$: Observable<ArticleCollection> = of({
'items': [
{
'__typename': 'Article',
'slug': 'first-article',
'title': 'First article',
'summary': 'A brief description of the first article. I\'m writing some more stuff here just so that this seems a little more realistic. Sam was here. Have a good day.',
'ssoProtected': false,
'searchable': true
},
{
'__typename': 'Article',
'slug': 'top-secret-article',
'title': 'Top Secret Article',
'summary': 'For testing SSO',
'ssoProtected': true,
'searchable': true
}
],
'__typename': 'ArticleCollection'
} as ArticleCollection);

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [
ArticleListComponent,
MockComponent(CollectionListComponent)
],
imports: [
ApolloTestingModule,
MockModule(SharedModule),
RouterTestingModule.withRoutes([])
],
providers: [
MockProvider(PageTitleService)
]
})
.compileComponents();
});

beforeEach(() => {
controller = TestBed.inject(ApolloTestingController);
fixture = TestBed.createComponent(ArticleListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

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

it('Should get all articles', () => {
spyOn(component, 'loadContent').and.returnValue(mockAllArticles$);

fixture.whenStable().then(() => {
component.loadContent().subscribe(res => {
expect(res.items.length).toBe(1);
});
})
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { AllArticlesGQL, ArticleCollection } from '@app/graphql/schema';
import { Observable, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { PageTitleService } from '@services/page-title.service';

@Component({
selector: 'app-article-list',
templateUrl: './article-list.component.html',
styleUrls: ['./article-list.component.scss']
})
export class ArticleListComponent implements OnInit, OnDestroy {
public articles: ArticleCollection;
public title: string = 'Article Collection';

private subscription = new Subscription();

constructor(
private allArticlesGQL: AllArticlesGQL,
public pageTitleService: PageTitleService
) { }

ngOnInit(): void {
this.pageTitleService.title = this.title;
this.subscription.add(
this.loadContent().subscribe((collection) => this.articles = collection)
);
}

public loadContent(): Observable<ArticleCollection> {
return this.allArticlesGQL.fetch().pipe(
map((result) => result.data.articleCollection as ArticleCollection)
)
}

ngOnDestroy(): void {
this.subscription.unsubscribe();
}

}
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
<!-- If we're displaying a collection of articles-->
<div
*ngIf="allArticles$ | async as allArticles"
class="site-padding margin-bottom top-padding"
ngClass.lt-md="site-padding-mobile margin-bottom top-padding"
>
<app-collection-list [collection]="allArticles"></app-collection-list>
</div>

<div id="article-container" *ngIf="article | async as article">
<div id="article-container" *ngIf="article">
<div
class="banner-container"
[ngClass]="
bannerImageUrl === undefined
? ''
: isMobile
? 'mobile-banner'
: 'standard-banner'
"
[ngClass]="{ 'standard-banner': bannerImageUrl }"
[ngClass.xs]="{ 'mobile-banner': bannerImageUrl }"
[ngStyle]="
bannerImageUrl && { 'background-image': 'url(' + bannerImageUrl + ')' }
"
Expand Down Expand Up @@ -87,10 +73,7 @@
</div>

<div class="site-padding margin-bottom" ngClass.lt-md="site-padding-mobile">
<app-breadcrumbs
[contentItem]="parentSubHubs"
[title]="article.title"
></app-breadcrumbs>
<app-breadcrumbs [title]="article.title"></app-breadcrumbs>

<div fxLayout="row" fxLayoutAlign="space-around" fxLayout.lt-lg="column">
<!-- Article Body -->
Expand Down Expand Up @@ -124,7 +107,8 @@ <h3 *ngIf="article?.relatedContactsCollection.items.length > 0">
<hr />
</h3>
<div
fxLayout.lg="column"
fxLayout="column"
fxLayoutGap="0px"
fxLayout.lt-lg="row wrap"
fxLayoutGap.lt-lg="25px"
fxLayout.lt-sm="column"
Expand All @@ -142,7 +126,8 @@ <h3 *ngIf="article?.relatedDocsCollection.items.length > 0">
</h3>
<div
id="documents"
fxLayout.lg="column"
fxLayout="column"
fxLayoutGap="0px"
fxLayout.lt-lg="row wrap"
fxLayoutGap.lt-lg="25px"
fxLayout.lt-sm="column"
Expand All @@ -158,7 +143,8 @@ <h3 *ngIf="article?.relatedOrgsCollection.items.length > 0">
<hr />
</h3>
<div
fxLayout.lg="column"
fxLayout="column"
fxLayoutGap="0px"
fxLayout.lt-lg="row wrap"
fxLayoutGap.lt-lg="25px"
fxLayout.lt-sm="column"
Expand All @@ -184,7 +170,8 @@ <h3>
</h3>
<div
id="you-might-be-interested-in"
fxLayout.lg="column"
fxLayout="column"
fxLayoutGap="0px"
fxLayout.lt-lg="row wrap"
fxLayoutGap.lt-lg="25px"
fxLayout.lt-sm="column"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,23 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { PageTitleService } from '../../services/page-title.service';
import { ArticlesComponent } from './articles.component';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { PageTitleService } from '@services/page-title.service';
import { ArticleComponent } from './article.component';
import { ApolloTestingController, ApolloTestingModule } from 'apollo-angular/testing';
import { RouterModule, ActivatedRoute, convertToParamMap, Router } from '@angular/router';
import { By } from '@angular/platform-browser';
import { ActivatedRoute } from '@angular/router';
import { Observable, of } from 'rxjs';
import { ArticleCollection, AllArticlesGQL, Article } from '@graphql/schema';
import { Article } from '@graphql/schema';
import { CommonModule } from '@angular/common';
import { MaterialModule } from '@app/app.material.module';
import { SharedModule } from '@components/shared/app.shared.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { MockModule, MockProvider } from 'ng-mocks';
import { MockComponent, MockModule, MockProvider } from 'ng-mocks';
import { BreadcrumbsComponent } from '@app/components/shared/breadcrumbs/breadcrumbs.component';
import { ArticleListComponent } from '../article-list/article-list.component';

describe('ArticlesComponent', () => {
let component: ArticlesComponent;
let appComponentService: PageTitleService;
let fixture: ComponentFixture<ArticlesComponent>;
describe('ArticleComponent', () => {
let component: ArticleComponent;
let fixture: ComponentFixture<ArticleComponent>;
let controller: ApolloTestingController;
const mockAllArticles$: Observable<ArticleCollection> = of({
'items': [
{
'__typename': 'Article',
'slug': 'first-article',
'title': 'First article',
'summary': 'A brief description of the first article. I\'m writing some more stuff here just so that this seems a little more realistic. Sam was here. Have a good day.',
'ssoProtected': false,
'searchable': true
},
{
'__typename': 'Article',
'slug': 'top-secret-article',
'title': 'Top Secret Article',
'summary': 'For testing SSO',
'ssoProtected': true,
'searchable': true
}
],
'__typename': 'ArticleCollection'
} as ArticleCollection);

const mockArticle$: Observable<Article> = of({
'title': 'First article',
Expand Down Expand Up @@ -238,12 +217,6 @@ describe('ArticlesComponent', () => {
},
'slug': 'first-article',
'searchable': true,
'icon': {
'title': 'Pippy',
'description': 'Sam\'s dog Pippy',
'url': 'https://imgs.ctfassets.net/vbuxn5csp0ik/014fpqFg0KmnP8NWc9Jyxe/0a1a14a6a0dd438443f70d5f917568fc/Screen_Shot_2020-07-23_at_3.12.46_PM.png',
'__typename': 'Asset'
},
'relatedItemsCollection': {
'items': [
{
Expand All @@ -264,16 +237,21 @@ describe('ArticlesComponent', () => {
'__typename': 'Article'
} as unknown as Article);

beforeEach(waitForAsync(() => {
beforeEach(waitForAsync (() => {
TestBed.configureTestingModule({
declarations: [ArticlesComponent],
declarations: [
ArticleComponent,
MockComponent(BreadcrumbsComponent)
],
imports: [
ApolloTestingModule,
MockModule(CommonModule),
MockModule(MaterialModule),
MockModule(SharedModule),
MockModule(BrowserAnimationsModule),
RouterTestingModule.withRoutes([])
RouterTestingModule.withRoutes([
{ path: 'article/list', component: ArticleListComponent }
])
], providers: [
MockProvider(PageTitleService)
]
Expand All @@ -282,12 +260,11 @@ describe('ArticlesComponent', () => {

beforeEach(() => {
controller = TestBed.inject(ApolloTestingController);
fixture = TestBed.createComponent(ArticlesComponent);
fixture = TestBed.createComponent(ArticleComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


afterEach(() => {
fixture.destroy();
});
Expand All @@ -296,29 +273,28 @@ describe('ArticlesComponent', () => {
expect(component).toBeTruthy();
});

it('Should get all articles', () => {
spyOn(component, 'getAllArticles').and.returnValue(mockAllArticles$);
component.getAllArticles().subscribe(res => {
expect(res).toBeTruthy();
});
})

describe('When a url slug is present', async () => {
const testSlug: string = 'first-article';

beforeEach(() => {
controller = TestBed.inject(ApolloTestingController);
fixture = TestBed.createComponent(ArticlesComponent);
fixture = TestBed.createComponent(ArticleComponent);
component = fixture.componentInstance;
TestBed.inject(ActivatedRoute).params = of({
slug: 'first-article'
slug: testSlug
});
fixture.detectChanges();
component.ngOnInit();
});

it('Should get a single article data', () => {
spyOn(component, 'getArticleBySlug').and.returnValue(mockArticle$);
component.getArticleBySlug(component.slug).subscribe(res => {
expect(res.slug).toEqual('first-article');
});

fixture.whenStable().then(() => {
component.getArticleBySlug(testSlug).subscribe(res => {
expect(res.slug).toEqual(testSlug);
});
})
});
});
});
Loading