Skip to content

Commit 5ed2172

Browse files
committed
Create implementation endpoint getTopHeadlineNews
1 parent 3fff877 commit 5ed2172

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'package:dartz/dartz.dart';
2+
import 'package:dio/dio.dart';
3+
import 'package:flutter_news_app/core/error/failure.dart';
4+
import 'package:flutter_news_app/core/network/network_info.dart';
5+
import 'package:flutter_news_app/core/util/enum/top_headline_news_category.dart';
6+
import 'package:flutter_news_app/feature/data/datasource/news/news_remote_data_source.dart';
7+
import 'package:flutter_news_app/feature/data/model/news/news_response.dart';
8+
import 'package:flutter_news_app/feature/___domain/repository/news/news_repository.dart';
9+
10+
class NewsRepositoryImpl implements NewsRepository {
11+
final NewsRemoteDataSource newsRemoteDataSource;
12+
final NetworkInfo networkInfo;
13+
14+
NewsRepositoryImpl({
15+
required this.newsRemoteDataSource,
16+
required this.networkInfo,
17+
});
18+
19+
@override
20+
Future<Either<Failure, NewsResponse>> getTopHeadlineNews(
21+
TopHeadlineNewsCategory topHeadlineNewsCategory,
22+
) async {
23+
final isConnected = await networkInfo.isConnected;
24+
if (isConnected) {
25+
try {
26+
final response = await newsRemoteDataSource.getTopHeadlineNews(topHeadlineNewsCategory);
27+
return Right(response);
28+
} on DioError catch (error) {
29+
return Left(ServerFailure(error.message));
30+
} on TypeError catch (error) {
31+
return Left(ParsingFailure(error.toString()));
32+
}
33+
} else {
34+
return Left(ConnectionFailure());
35+
}
36+
}
37+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import 'package:dartz/dartz.dart';
2+
import 'package:flutter_news_app/core/error/failure.dart';
3+
import 'package:flutter_news_app/core/util/enum/top_headline_news_category.dart';
4+
import 'package:flutter_news_app/feature/data/model/news/news_response.dart';
5+
6+
abstract class NewsRepository {
7+
Future<Either<Failure, NewsResponse>> getTopHeadlineNews(TopHeadlineNewsCategory topHeadlineNewsCategory);
8+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import 'dart:convert';
2+
3+
import 'package:dartz/dartz.dart';
4+
import 'package:dio/dio.dart';
5+
import 'package:flutter_news_app/core/error/failure.dart';
6+
import 'package:flutter_news_app/core/util/enum/top_headline_news_category.dart';
7+
import 'package:flutter_news_app/feature/data/model/news/news_response.dart';
8+
import 'package:flutter_news_app/feature/data/repository/news/news_repository_impl.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:mockito/mockito.dart';
11+
12+
import '../../../../fixture/fixture_reader.dart';
13+
import '../../../../helper/mock_helper.mocks.dart';
14+
15+
void main() {
16+
late NewsRepositoryImpl newsRepositoryImpl;
17+
late MockNewsRemoteDataSource mockNewsRemoteDataSource;
18+
late MockNetworkInfo mockNetworkInfo;
19+
20+
setUp(() {
21+
mockNewsRemoteDataSource = MockNewsRemoteDataSource();
22+
mockNetworkInfo = MockNetworkInfo();
23+
newsRepositoryImpl = NewsRepositoryImpl(
24+
newsRemoteDataSource: mockNewsRemoteDataSource,
25+
networkInfo: mockNetworkInfo,
26+
);
27+
});
28+
29+
final tRequestOptions = RequestOptions(path: '');
30+
31+
void setUpMockNetworkConnected() {
32+
when(mockNetworkInfo.isConnected).thenAnswer((_) async => true);
33+
}
34+
35+
void setUpMockNetworkDisconnected() {
36+
when(mockNetworkInfo.isConnected).thenAnswer((_) async => false);
37+
}
38+
39+
void testDisconnected(Function endpointInvoke) {
40+
test(
41+
'Should return ConnectionFailure while device is not connected to the internet',
42+
() async {
43+
// arrange
44+
setUpMockNetworkDisconnected();
45+
46+
// act
47+
final result = await endpointInvoke.call();
48+
49+
// assert
50+
verify(mockNetworkInfo.isConnected);
51+
expect(result, Left(ConnectionFailure()));
52+
},
53+
);
54+
}
55+
56+
void testParsingFailure(Function whenInvoke, Function actInvoke, Function verifyInvoke) {
57+
test(
58+
'Should return ParsingFailure while NewsRemoteDataSource failure parsing response JSON from the endpoint',
59+
() async {
60+
// arrange
61+
setUpMockNetworkConnected();
62+
when(whenInvoke.call()).thenThrow(TypeError());
63+
64+
// act
65+
final result = await actInvoke.call();
66+
67+
// assert
68+
verify(verifyInvoke.call());
69+
expect(result, Left(ParsingFailure(TypeError().toString())));
70+
},
71+
);
72+
}
73+
74+
group('getTopHeadlineNews', () {
75+
const tTopHeadlineNewsCategory = TopHeadlineNewsCategory.general;
76+
final tResponse = NewsResponse.fromJson(
77+
json.decode(
78+
fixture('news_response.json'),
79+
),
80+
);
81+
82+
test(
83+
'Should return NewsResponse while NewsRemoteDataSoure retrieve response success from the endpoint',
84+
() async {
85+
// arrange
86+
setUpMockNetworkConnected();
87+
when(mockNewsRemoteDataSource.getTopHeadlineNews(any)).thenAnswer((_) async => tResponse);
88+
89+
// act
90+
final result = await newsRepositoryImpl.getTopHeadlineNews(tTopHeadlineNewsCategory);
91+
92+
// assert
93+
verify(mockNewsRemoteDataSource.getTopHeadlineNews(tTopHeadlineNewsCategory));
94+
expect(result, Right(tResponse));
95+
},
96+
);
97+
98+
test(
99+
'Should return ServerFailure while NewsRemoteDataSource retrieve timeout response from the endpoint',
100+
() async {
101+
// arrange
102+
setUpMockNetworkConnected();
103+
when(mockNewsRemoteDataSource.getTopHeadlineNews(any)).thenThrow(
104+
DioError(
105+
requestOptions: tRequestOptions,
106+
error: 'testError',
107+
),
108+
);
109+
110+
// act
111+
final result = await newsRepositoryImpl.getTopHeadlineNews(tTopHeadlineNewsCategory);
112+
113+
// assert
114+
verify(mockNewsRemoteDataSource.getTopHeadlineNews(tTopHeadlineNewsCategory));
115+
expect(result, Left(ServerFailure('testError')));
116+
},
117+
);
118+
119+
test(
120+
'Should return ServerFailure while NewsRemoteDataSource retrieve failure response from the endpoint',
121+
() async {
122+
// arrange
123+
setUpMockNetworkConnected();
124+
when(mockNewsRemoteDataSource.getTopHeadlineNews(any)).thenThrow(
125+
DioError(
126+
requestOptions: tRequestOptions,
127+
error: 'testError',
128+
response: Response(
129+
requestOptions: tRequestOptions,
130+
statusCode: 400,
131+
),
132+
),
133+
);
134+
135+
// act
136+
final result = await newsRepositoryImpl.getTopHeadlineNews(tTopHeadlineNewsCategory);
137+
138+
// assert
139+
verify(mockNewsRemoteDataSource.getTopHeadlineNews(tTopHeadlineNewsCategory));
140+
expect(result, Left(ServerFailure('testError')));
141+
},
142+
);
143+
144+
testParsingFailure(
145+
() => mockNewsRemoteDataSource.getTopHeadlineNews(any),
146+
() => newsRepositoryImpl.getTopHeadlineNews(tTopHeadlineNewsCategory),
147+
() => mockNewsRemoteDataSource.getTopHeadlineNews(tTopHeadlineNewsCategory),
148+
);
149+
150+
testDisconnected(() => newsRepositoryImpl.getTopHeadlineNews(tTopHeadlineNewsCategory));
151+
});
152+
}

0 commit comments

Comments
 (0)