Skip to content

Commit

Permalink
Tambahkan parameter baseUrl di endpoint ping
Browse files Browse the repository at this point in the history
Tambahkan parameter `baseUrl` di endpoint, implement function endpoint, use case, dan business logic ping. Sekalian update unit testnya.
  • Loading branch information
CoderJava committed Nov 17, 2024
1 parent f5bbc6d commit 59b917d
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ abstract class GeneralRemoteDataSource {
/// Throws [DioException] untuk semua error kode
late String pathPing;

Future<GeneralResponse> ping();
Future<GeneralResponse> ping(String baseUrl);
}

class GeneralRemoteDataSourceImpl implements GeneralRemoteDataSource {
Expand All @@ -24,7 +24,7 @@ class GeneralRemoteDataSourceImpl implements GeneralRemoteDataSource {
String pathPing = '';

@override
Future<GeneralResponse> ping() async {
Future<GeneralResponse> ping(String baseUrl) async {
pathPing = '$baseUrl/api/ping';
final response = await dio.get(pathPing);
if (response.statusCode.toString().startsWith('2')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ class GeneralRepositoryImpl implements GeneralRepository {
}

@override
Future<({Failure? failure, GeneralResponse? response})> ping() async {
Future<({Failure? failure, GeneralResponse? response})> ping(String baseUrl) async {
Failure? failure;
GeneralResponse? response;
final isConnected = await networkInfo.isConnected;
if (isConnected) {
try {
response = await remoteDataSource.ping();
response = await remoteDataSource.ping(baseUrl);
} on DioException catch (error) {
final message = error.message ?? error.toString();
if (error.response == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import 'package:dipantau_desktop_client/core/error/failure.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';

abstract class GeneralRepository {
Future<({Failure? failure, GeneralResponse? response})> ping();
Future<({Failure? failure, GeneralResponse? response})> ping(String baseUrl);
}
27 changes: 23 additions & 4 deletions lib/feature/domain/usecase/ping/ping.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,33 @@ import 'package:dipantau_desktop_client/core/error/failure.dart';
import 'package:dipantau_desktop_client/core/usecase/usecase.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/domain/repository/general/general_repository.dart';
import 'package:equatable/equatable.dart';

class Ping implements UseCaseRecords<GeneralResponse, NoParams> {
class Ping implements UseCaseRecords<GeneralResponse, ParamsPing> {
final GeneralRepository repository;

Ping({required this.repository});

@override
Future<({Failure? failure, GeneralResponse? response})> call(NoParams params) {
return repository.ping();
Future<({Failure? failure, GeneralResponse? response})> call(ParamsPing params) {
return repository.ping(params.baseUrl);
}
}
}

class ParamsPing extends Equatable {
final String baseUrl;

ParamsPing({
required this.baseUrl,
});

@override
List<Object?> get props => [
baseUrl,
];

@override
String toString() {
return 'ParamsPing{baseUrl: $baseUrl}';
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:dipantau_desktop_client/core/usecase/usecase.dart';
import 'package:dipantau_desktop_client/core/util/helper.dart';
import 'package:dipantau_desktop_client/feature/domain/usecase/ping/ping.dart';

part 'setup_credential_event.dart';

part 'setup_credential_state.dart';

class SetupCredentialBloc extends Bloc<SetupCredentialEvent, SetupCredentialState> {
Expand All @@ -23,12 +23,17 @@ class SetupCredentialBloc extends Bloc<SetupCredentialEvent, SetupCredentialStat
PingSetupCredentialEvent event,
Emitter<SetupCredentialState> emit,
) async {
final baseUrl = event.baseUrl;
emit(LoadingSetupCredentialState());
final result = await ping(NoParams());
final result = await ping(
ParamsPing(
baseUrl: baseUrl,
),
);
final response = result.response;
final failure = result.failure;
if (response != null) {
emit(SuccessPingSetupCredentialState());
emit(SuccessPingSetupCredentialState(baseUrl: baseUrl));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,15 @@ part of 'setup_credential_bloc.dart';

abstract class SetupCredentialEvent {}

class PingSetupCredentialEvent extends SetupCredentialEvent {}
class PingSetupCredentialEvent extends SetupCredentialEvent {
final String baseUrl;

PingSetupCredentialEvent({
required this.baseUrl,
});

@override
String toString() {
return 'PingSetupCredentialEvent{baseUrl: $baseUrl}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,15 @@ class FailureSetupCredentialState extends SetupCredentialState {
}
}

class SuccessPingSetupCredentialState extends SetupCredentialState {}
class SuccessPingSetupCredentialState extends SetupCredentialState {
final String baseUrl;

SuccessPingSetupCredentialState({
required this.baseUrl,
});

@override
String toString() {
return 'SuccessPingSetupCredentialState{baseUrl: $baseUrl}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ void main() {

group('ping', () {
const tPathResponse = 'general_response.json';
const hostname = baseUrl;
final tResponse = GeneralResponse.fromJson(
json.decode(
fixture(tPathResponse),
Expand All @@ -64,10 +65,10 @@ void main() {
setUpMockDioSuccess();

// act
await remoteDataSource.ping();
await remoteDataSource.ping(hostname);

// assert
verify(mockDio.get('$baseUrl/api/ping'));
verify(mockDio.get('$hostname/api/ping'));
},
);

Expand All @@ -79,7 +80,7 @@ void main() {
setUpMockDioSuccess();

// act
final result = await remoteDataSource.ping();
final result = await remoteDataSource.ping(hostname);

// assert
expect(result, tResponse);
Expand All @@ -98,7 +99,7 @@ void main() {
when(mockDio.get(any)).thenAnswer((_) async => response);

// act
final call = remoteDataSource.ping();
final call = remoteDataSource.ping(hostname);

// assert
expect(() => call, throwsA(const TypeMatcher<DioException>()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,20 +105,21 @@ void main() {
fixture('general_response.json'),
),
);
const hostname = 'https://example.com';

test(
'pastikan mengembalikan objek model GeneralResponse ketika RemoteDataSource berhasil menerima '
'respon sukses dari endpoint',
() async {
// arrange
setUpMockNetworkConnected();
when(mockRemoteDataSource.ping()).thenAnswer((_) async => tResponse);
when(mockRemoteDataSource.ping(any)).thenAnswer((_) async => tResponse);

// act
final result = await repository.ping();
final result = await repository.ping(hostname);

// assert
verify(mockRemoteDataSource.ping());
verify(mockRemoteDataSource.ping(hostname));
expect(result.response, tResponse);
},
);
Expand All @@ -129,14 +130,14 @@ void main() {
() async {
// arrange
setUpMockNetworkConnected();
when(mockRemoteDataSource.ping())
when(mockRemoteDataSource.ping(any))
.thenThrow(DioException(requestOptions: tRequestOptions, message: 'testError'));

// act
final result = await repository.ping();
final result = await repository.ping(hostname);

// assert
verify(mockRemoteDataSource.ping());
verify(mockRemoteDataSource.ping(hostname));
expect(result.failure, ServerFailure('testError'));
},
);
Expand All @@ -147,7 +148,7 @@ void main() {
() async {
// arrange
setUpMockNetworkConnected();
when(mockRemoteDataSource.ping()).thenThrow(
when(mockRemoteDataSource.ping(any)).thenThrow(
DioException(
requestOptions: tRequestOptions,
message: 'testError',
Expand All @@ -163,26 +164,26 @@ void main() {
);

// act
final result = await repository.ping();
final result = await repository.ping(hostname);

// assert
verify(mockRemoteDataSource.ping());
verify(mockRemoteDataSource.ping(hostname));
expect(result.failure, ServerFailure('400 testMessageError'));
},
);

testServerFailureString(
() => mockRemoteDataSource.ping(),
() => repository.ping(),
() => mockRemoteDataSource.ping(),
() => mockRemoteDataSource.ping(any),
() => repository.ping(hostname),
() => mockRemoteDataSource.ping(hostname),
);

testParsingFailure(
() => mockRemoteDataSource.ping(),
() => repository.ping(),
() => mockRemoteDataSource.ping(),
() => mockRemoteDataSource.ping(any),
() => repository.ping(hostname),
() => mockRemoteDataSource.ping(hostname),
);

testDisconnected(() => repository.ping());
testDisconnected(() => repository.ping(hostname));
});
}
33 changes: 29 additions & 4 deletions test/feature/domain/usecase/ping/ping_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:convert';

import 'package:dipantau_desktop_client/core/usecase/usecase.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/domain/usecase/ping/ping.dart';
import 'package:flutter_test/flutter_test.dart';
Expand All @@ -18,6 +17,9 @@ void main() {
useCase = Ping(repository: mockRepository);
});

const hostname = 'https://example.com';
final tParams = ParamsPing(baseUrl: hostname);

test(
'pastikan objek repository berhasil menerima respon sukses atau gagal dari endpoint',
() async {
Expand All @@ -27,17 +29,40 @@ void main() {
fixture('general_response.json'),
),
);
final tParams = NoParams();
final tResult = (failure: null, response: tResponse);
when(mockRepository.ping()).thenAnswer((_) async => tResult);
when(mockRepository.ping(any)).thenAnswer((_) async => tResult);

// act
final result = await useCase(tParams);

// assert
expect(result, tResult);
verify(mockRepository.ping());
verify(mockRepository.ping(hostname));
verifyNoMoreInteractions(mockRepository);
},
);

test(
'pastikan output dari nilai props',
() async {
// assert
expect(
tParams.props,
[
tParams.baseUrl,
],
);
},
);

test(
'pastikan output dari fungsi toString',
() async {
// assert
expect(
tParams.toString(),
'ParamsPing{baseUrl: ${tParams.baseUrl}}',
);
},
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:convert';

import 'package:bloc_test/bloc_test.dart';
import 'package:dipantau_desktop_client/core/error/failure.dart';
import 'package:dipantau_desktop_client/core/usecase/usecase.dart';
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
import 'package:dipantau_desktop_client/feature/domain/usecase/ping/ping.dart';
import 'package:dipantau_desktop_client/feature/presentation/bloc/setup_credential/setup_credential_bloc.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
Expand Down Expand Up @@ -39,8 +39,9 @@ void main() {
);

group('ping setup credential', () {
final params = NoParams();
final event = PingSetupCredentialEvent();
const baseUrl = 'https://example.com';
final params = ParamsPing(baseUrl: baseUrl);
final event = PingSetupCredentialEvent(baseUrl: baseUrl);

blocTest(
'pastikan emit [LoadingSetupCredentialState, SuccessPingSetupCredentialState] ketika terima event '
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:dipantau_desktop_client/feature/presentation/bloc/setup_credential/setup_credential_bloc.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
group('PingSetupCredentialEvent', () {
final event = PingSetupCredentialEvent(baseUrl: 'https://example.com');

test(
'pastikan output dari fungsi toString',
() async {
// assert
expect(
event.toString(),
'PingSetupCredentialEvent{baseUrl: ${event.baseUrl}}',
);
},
);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,19 @@ void main() {
},
);
});

group('SuccessPingSetupCredentialState', () {
final state = SuccessPingSetupCredentialState(baseUrl: 'https://example.com');

test(
'pastikan output dari fungsi toString',
() async {
// assert
expect(
state.toString(),
'SuccessPingSetupCredentialState{baseUrl: ${state.baseUrl}}',
);
},
);
});
}

0 comments on commit 59b917d

Please sign in to comment.