feat(app): смена сервера API и очистка данных устройства при выходе
Адрес бэкенда хранится в shared_preferences и читается до runApp; switchApiBaseUrl сбрасывает токены и кэш старого сервера. Выход стирает refresh-токен и sqlite-кэш ответов. Экран настроек переделан под разделы.
This commit is contained in:
@@ -23,11 +23,16 @@ class _ErrorCapture extends ErrorInterceptorHandler {
|
||||
void next(DioException error) => forwarded = error;
|
||||
}
|
||||
|
||||
RequestOptions _request(String method, String path, [Map<String, dynamic> query = const {}]) =>
|
||||
RequestOptions(path: path, method: method, queryParameters: query);
|
||||
RequestOptions _request(
|
||||
String method,
|
||||
String path, [
|
||||
Map<String, dynamic> query = const {},
|
||||
]) => RequestOptions(path: path, method: method, queryParameters: query);
|
||||
|
||||
DioException _offline(RequestOptions options) =>
|
||||
DioException(requestOptions: options, type: DioExceptionType.connectionError);
|
||||
DioException _offline(RequestOptions options) => DioException(
|
||||
requestOptions: options,
|
||||
type: DioExceptionType.connectionError,
|
||||
);
|
||||
|
||||
void main() {
|
||||
late ResponseCacheDatabase db;
|
||||
@@ -44,7 +49,11 @@ void main() {
|
||||
final options = _request('GET', '/networth/breakdown');
|
||||
|
||||
interceptor.onResponse(
|
||||
Response<dynamic>(requestOptions: options, statusCode: 200, data: {'totalRub': '100'}),
|
||||
Response<dynamic>(
|
||||
requestOptions: options,
|
||||
statusCode: 200,
|
||||
data: {'totalRub': '100'},
|
||||
),
|
||||
_ResponseCapture(),
|
||||
);
|
||||
await pumpEventQueue(); // the write is fire-and-forget
|
||||
@@ -53,17 +62,20 @@ void main() {
|
||||
expect(cached?.body, {'totalRub': '100'});
|
||||
});
|
||||
|
||||
test('a connection error is answered from the cache, with fetchedAt set', () async {
|
||||
final options = _request('GET', '/networth/breakdown');
|
||||
await db.put(CacheInterceptor.requestKey(options), {'totalRub': '100'});
|
||||
test(
|
||||
'a connection error is answered from the cache, with fetchedAt set',
|
||||
() async {
|
||||
final options = _request('GET', '/networth/breakdown');
|
||||
await db.put(CacheInterceptor.requestKey(options), {'totalRub': '100'});
|
||||
|
||||
final handler = _ErrorCapture();
|
||||
await interceptor.onError(_offline(options), handler);
|
||||
final handler = _ErrorCapture();
|
||||
await interceptor.onError(_offline(options), handler);
|
||||
|
||||
expect(handler.resolvedResponse?.data, {'totalRub': '100'});
|
||||
expect(handler.resolvedResponse?.extra['fetchedAt'], isA<DateTime>());
|
||||
expect(handler.forwarded, isNull);
|
||||
});
|
||||
expect(handler.resolvedResponse?.data, {'totalRub': '100'});
|
||||
expect(handler.resolvedResponse?.extra['fetchedAt'], isA<DateTime>());
|
||||
expect(handler.forwarded, isNull);
|
||||
},
|
||||
);
|
||||
|
||||
test('a connection error with nothing cached still fails', () async {
|
||||
final options = _request('GET', '/networth/breakdown', {'never': 'asked'});
|
||||
|
||||
Reference in New Issue
Block a user