Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit f9c2f95

Browse files
committed
fix(news): display no news message on api unavailability
Display a message that no news are available if the api endpoint is not available instead of failing the navigation and breaking the complete page. Important for recents news on index page and news list and for selected news. Add test for news service. --- src/services/news/news-service.js | 6 +- src/view-models/contents/index.js | 10 +- src/view-models/news/index.js | 7 +- src/view-models/news/view.js | 2 + src/views/news/view.html | 8 +- test/unit/configuration/app.spec.js | 132 ------------------- test/unit/configuration/router-config.spec.js | 132 +++++++++++++++++++ test/unit/modules/news.spec.js | 2 +- test/unit/services/news.spec.js | 83 ++++++++++++ 9 files changed, 242 insertions(+), 140 deletions(-)
1 parent 3eaaf28 commit f9c2f95

File tree

8 files changed

+110
-8
lines changed

8 files changed

+110
-8
lines changed

src/services/news/news-service.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ export class NewsService {
99

1010
getRecent() {
1111
return this.httpClient.fetch('/news')
12-
.then(response => response.json());
12+
.then(response => response.json())
13+
.catch(error => Promise.reject(error));
1314
}
1415

1516
get(id) {
1617
return this.httpClient.fetch('/news/' + id)
17-
.then(response => response.json());
18+
.then(response => response.json())
19+
.catch(error => Promise.reject(error));
1820
}
1921
}

src/view-models/contents/index.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ import {NewsService} from '../../services/news/news-service';
33

44
@inject(NewsService)
55
export class Index {
6-
news = [];
7-
86
constructor(newsService) {
97
this.newsService = newsService;
8+
this.news = [];
109
}
1110

1211
activate() {
1312
return this.newsService.getRecent()
14-
.then(news => this.news = news);
13+
.then(news => {
14+
this.news = news;
15+
})
16+
.catch(() => {
17+
this.news = [];
18+
});
1519
}
1620
}

src/view-models/news/index.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ export class Index {
1010

1111
activate() {
1212
return this.newsService.getRecent()
13-
.then(news => this.news = news);
13+
.then(news => {
14+
this.news = news;
15+
})
16+
.catch(() => {
17+
this.news = [];
18+
});
1419
}
1520
}

src/view-models/news/view.js

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export class View {
1212
.then(news => {
1313
this.news = news;
1414
routeConfig.navModel.setTitle(news.title);
15+
})
16+
.catch(() => {
1517
});
1618
}
1719
}

src/views/news/view.html

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<section class="au-animate">
33
<div class="row">
44
<div class="col-lg-12">
5-
<div class="card card-default card-block">
5+
<div class="card card-default card-block" if.bind="news">
66
<h4 class="card-title">${news.title}<br>
77
<small>on
88
<time>${news.created_at}</time>
@@ -14,6 +14,12 @@ <h4 class="card-title">${news.title}<br>
1414
posted by <a href="#/profiles/view/${news.user_id}">${news.user.username}</a>
1515
</p>
1616
</div>
17+
18+
<div class="card card-default card-block" if.bind="!news">
19+
<p class="card-text">
20+
The selected news entry is not available.
21+
</p>
22+
</div>
1723
</div>
1824
</div>
1925
</section>

test/unit/modules/news.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('the News Index module', () => {
4141
});
4242

4343
describe('the News View module', () => {
44-
it('sets fetch response to news', (done) => {
44+
it('sets fetch response to selected news', (done) => {
4545
var newsService = new NewsServiceStub();
4646
var sut = new View(newsService);
4747

test/unit/services/news.spec.js

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {NewsService} from '../../../src/services/news/news-service';
2+
3+
var mockedRequest = {
4+
json: function() {
5+
return {news: 'test'};
6+
}
7+
};
8+
9+
class HttpServiceStub {
10+
reject = false;
11+
12+
fetch(resource) {
13+
this.resource = resource;
14+
15+
return new Promise((resolve, reject) => {
16+
if (this.reject == false) {
17+
resolve(mockedRequest);
18+
} else {
19+
reject();
20+
}
21+
});
22+
}
23+
}
24+
25+
describe('the News service', () => {
26+
var mockedHttpService;
27+
var sut;
28+
29+
beforeEach(() => {
30+
mockedHttpService = new HttpServiceStub();
31+
sut = new NewsService(mockedHttpService);
32+
});
33+
34+
it('contains a http service property', () => {
35+
expect(sut.httpClient).toBeDefined();
36+
});
37+
38+
it('returns recent news', (done) => {
39+
mockedHttpService.reject = false;
40+
sut.getRecent()
41+
.then(resp => {
42+
expect(mockedHttpService.resource).toEqual('/news');
43+
expect(resp).toEqual({news: 'test'});
44+
done();
45+
})
46+
.catch(result => {
47+
expect(result).not.toBe(result);
48+
done();
49+
});
50+
});
51+
52+
it('returns the selected news', (done) => {
53+
mockedHttpService.reject = false;
54+
sut.get(1)
55+
.then(resp => {
56+
expect(mockedHttpService.resource).toEqual('/news/1');
57+
expect(resp).toEqual({news: 'test'});
58+
done();
59+
})
60+
.catch(result => {
61+
expect(result).not.toBe(result);
62+
done();
63+
});
64+
});
65+
66+
it('rejects recent news on failure', (done) => {
67+
mockedHttpService.reject = true;
68+
sut.getRecent()
69+
.catch(result => {
70+
expect(mockedHttpService.resource).toEqual('/news');
71+
done();
72+
});
73+
});
74+
75+
it('rejects selected news on failure', (done) => {
76+
mockedHttpService.reject = true;
77+
sut.get(1)
78+
.catch(result => {
79+
expect(mockedHttpService.resource).toEqual('/news/1');
80+
done();
81+
});
82+
});
83+
});

0 commit comments

Comments
 (0)