mirror of https://github.com/flutter/samples.git
[Compass App] Cleanup and extra tests (#2437)
Some changes to make the project ready to merge to main - Fix formatting. - Add project to the `stable` channel CI (potentially could be added for `beta` and `master`) - CI only runs when targeting `main`, so I run the command locally and it worked. - Add unit tests for the `ApiClient` and `AuthApiClient` which had no test coverage outside of integration tests. - Resolved some TODOs I left before. ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-devrel channel on [Discord]. <!-- Links --> [Flutter Style Guide]: https://github.com/flutter/flutter/blob/master/docs/contributing/Style-guide-for-Flutter-repo.md [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [Contributors Guide]: https://github.com/flutter/samples/blob/main/CONTRIBUTING.mdpull/2440/head
parent
b00ce6c7b3
commit
799ce7f548
@ -1,24 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
|
||||||
|
|
||||||
// TODO: Maybe the text styles here should be moved to the respective widgets
|
|
||||||
class TextStyles {
|
|
||||||
// Note: original Figma file uses Nikkei Maru
|
|
||||||
// which is not available on GoogleFonts
|
|
||||||
// Note: Card title theme doesn't change based on light/dark mode
|
|
||||||
static final cardTitleStyle = GoogleFonts.rubik(
|
|
||||||
textStyle: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w800,
|
|
||||||
fontSize: 15.0,
|
|
||||||
color: Colors.white,
|
|
||||||
letterSpacing: 1,
|
|
||||||
shadows: [
|
|
||||||
// Helps to read the text a bit better
|
|
||||||
Shadow(
|
|
||||||
blurRadius: 3.0,
|
|
||||||
color: Colors.black,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
import 'package:compass_app/data/services/api/api_client.dart';
|
||||||
|
import 'package:compass_app/domain/models/continent/continent.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../../../testing/mocks.dart';
|
||||||
|
import '../../../../testing/models/activity.dart';
|
||||||
|
import '../../../../testing/models/booking.dart';
|
||||||
|
import '../../../../testing/models/destination.dart';
|
||||||
|
import '../../../../testing/models/user.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('ApiClient', () {
|
||||||
|
late MockHttpClient mockHttpClient;
|
||||||
|
late ApiClient apiClient;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
mockHttpClient = MockHttpClient();
|
||||||
|
apiClient = ApiClient(clientFactory: () => mockHttpClient);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get continents', () async {
|
||||||
|
final continents = [const Continent(name: 'NAME', imageUrl: 'URL')];
|
||||||
|
mockHttpClient.mockGet('/continent', continents);
|
||||||
|
final result = await apiClient.getContinents();
|
||||||
|
expect(result.asOk.value, continents);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get activities by destination', () async {
|
||||||
|
final activites = [kActivity];
|
||||||
|
mockHttpClient.mockGet(
|
||||||
|
'/destination/${kDestination1.ref}/activity',
|
||||||
|
activites,
|
||||||
|
);
|
||||||
|
final result =
|
||||||
|
await apiClient.getActivityByDestination(kDestination1.ref);
|
||||||
|
expect(result.asOk.value, activites);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get booking', () async {
|
||||||
|
mockHttpClient.mockGet(
|
||||||
|
'/booking/${kBookingApiModel.id}',
|
||||||
|
kBookingApiModel,
|
||||||
|
);
|
||||||
|
final result = await apiClient.getBooking(kBookingApiModel.id!);
|
||||||
|
expect(result.asOk.value, kBookingApiModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get bookings', () async {
|
||||||
|
mockHttpClient.mockGet('/booking', [kBookingApiModel]);
|
||||||
|
final result = await apiClient.getBookings();
|
||||||
|
expect(result.asOk.value, [kBookingApiModel]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get destinations', () async {
|
||||||
|
mockHttpClient.mockGet('/destination', [kDestination1]);
|
||||||
|
final result = await apiClient.getDestinations();
|
||||||
|
expect(result.asOk.value, [kDestination1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should get user', () async {
|
||||||
|
mockHttpClient.mockGet('/user', userApiModel);
|
||||||
|
final result = await apiClient.getUser();
|
||||||
|
expect(result.asOk.value, userApiModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should post booking', () async {
|
||||||
|
mockHttpClient.mockPost('/booking', kBookingApiModel);
|
||||||
|
final result = await apiClient.postBooking(kBookingApiModel);
|
||||||
|
expect(result.asOk.value, kBookingApiModel);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:compass_app/data/services/api/auth_api_client.dart';
|
||||||
|
import 'package:compass_app/data/services/api/model/login_request/login_request.dart';
|
||||||
|
import 'package:compass_app/data/services/api/model/login_response/login_response.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import '../../../../testing/mocks.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('AuthApiClient', () {
|
||||||
|
late MockHttpClient mockHttpClient;
|
||||||
|
late AuthApiClient apiClient;
|
||||||
|
|
||||||
|
setUp(() {
|
||||||
|
mockHttpClient = MockHttpClient();
|
||||||
|
apiClient = AuthApiClient(clientFactory: () => mockHttpClient);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should post login', () async {
|
||||||
|
const loginResponse = LoginResponse(
|
||||||
|
token: 'TOKEN',
|
||||||
|
userId: '123',
|
||||||
|
);
|
||||||
|
mockHttpClient.mockPost(
|
||||||
|
'/login',
|
||||||
|
loginResponse,
|
||||||
|
200,
|
||||||
|
);
|
||||||
|
final result = await apiClient.login(
|
||||||
|
const LoginRequest(
|
||||||
|
email: 'EMAIL',
|
||||||
|
password: 'PASSWORD',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
expect(result.asOk.value, loginResponse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
@ -1,4 +1,43 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
|
|
||||||
class MockGoRouter extends Mock implements GoRouter {}
|
class MockGoRouter extends Mock implements GoRouter {}
|
||||||
|
|
||||||
|
class MockHttpClient extends Mock implements HttpClient {}
|
||||||
|
|
||||||
|
class MockHttpHeaders extends Mock implements HttpHeaders {}
|
||||||
|
|
||||||
|
class MockHttpClientRequest extends Mock implements HttpClientRequest {}
|
||||||
|
|
||||||
|
class MockHttpClientResponse extends Mock implements HttpClientResponse {}
|
||||||
|
|
||||||
|
extension HttpMethodMocks on MockHttpClient {
|
||||||
|
void mockGet(String path, Object object) {
|
||||||
|
when(() => get(any(), any(), path)).thenAnswer((invocation) {
|
||||||
|
final request = MockHttpClientRequest();
|
||||||
|
final response = MockHttpClientResponse();
|
||||||
|
when(() => request.close()).thenAnswer((_) => Future.value(response));
|
||||||
|
when(() => request.headers).thenReturn(MockHttpHeaders());
|
||||||
|
when(() => response.statusCode).thenReturn(200);
|
||||||
|
when(() => response.transform(utf8.decoder))
|
||||||
|
.thenAnswer((_) => Stream.value(jsonEncode(object)));
|
||||||
|
return Future.value(request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void mockPost(String path, Object object, [int statusCode = 201]) {
|
||||||
|
when(() => post(any(), any(), path)).thenAnswer((invocation) {
|
||||||
|
final request = MockHttpClientRequest();
|
||||||
|
final response = MockHttpClientResponse();
|
||||||
|
when(() => request.close()).thenAnswer((_) => Future.value(response));
|
||||||
|
when(() => request.headers).thenReturn(MockHttpHeaders());
|
||||||
|
when(() => response.statusCode).thenReturn(statusCode);
|
||||||
|
when(() => response.transform(utf8.decoder))
|
||||||
|
.thenAnswer((_) => Stream.value(jsonEncode(object)));
|
||||||
|
return Future.value(request);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in new issue