mirror of
https://github.com/wger-project/flutter.git
synced 2026-02-18 00:17:48 +01:00
Merge branch 'master' into feature/trophies
# Conflicts: # lib/providers/base_provider.dart # lib/providers/gym_state.dart # lib/providers/gym_state.g.dart # lib/widgets/routines/gym_mode/log_page.dart # test/core/settings_test.mocks.dart # test/exercises/contribute_exercise_image_test.mocks.dart # test/gallery/gallery_form_test.mocks.dart # test/gallery/gallery_screen_test.mocks.dart # test/measurements/measurement_provider_test.mocks.dart # test/nutrition/nutritional_plan_screen_test.mocks.dart # test/nutrition/nutritional_plans_screen_test.mocks.dart # test/routine/gym_mode/gym_mode_test.mocks.dart # test/routine/routine_screen_test.mocks.dart # test/routine/routines_provider_test.mocks.dart # test/routine/routines_screen_test.mocks.dart # test/user/provider_test.mocks.dart # test/weight/weight_provider_test.mocks.dart # test/widgets/routines/gym_mode/log_page_test.dart
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2020 - 2025 wger Team
|
||||
* Copyright (c) 2020 - 2026 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -25,20 +25,24 @@ import 'package:wger/core/exceptions/http_exception.dart';
|
||||
void main() {
|
||||
group('WgerHttpException', () {
|
||||
test('parses valid JSON response', () {
|
||||
// Arrange
|
||||
final resp = http.Response(
|
||||
'{"foo":"bar"}',
|
||||
400,
|
||||
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
|
||||
);
|
||||
|
||||
// Act
|
||||
final ex = WgerHttpException(resp);
|
||||
|
||||
// Assert
|
||||
expect(ex.type, ErrorType.json);
|
||||
expect(ex.errors['foo'], 'bar');
|
||||
expect(ex.toString(), contains('WgerHttpException'));
|
||||
});
|
||||
|
||||
test('falls back on malformed JSON', () {
|
||||
// Arrange
|
||||
const body = '{"foo":';
|
||||
final resp = http.Response(
|
||||
body,
|
||||
@@ -46,13 +50,16 @@ void main() {
|
||||
headers: {HttpHeaders.contentTypeHeader: 'application/json'},
|
||||
);
|
||||
|
||||
// Act
|
||||
final ex = WgerHttpException(resp);
|
||||
|
||||
// Assert
|
||||
expect(ex.type, ErrorType.json);
|
||||
expect(ex.errors['unknown_error'], body);
|
||||
});
|
||||
|
||||
test('detects HTML response', () {
|
||||
test('detects HTML response from headers', () {
|
||||
// Arrange
|
||||
const body = '<html lang="en"><body>Error</body></html>';
|
||||
final resp = http.Response(
|
||||
body,
|
||||
@@ -60,16 +67,39 @@ void main() {
|
||||
headers: {HttpHeaders.contentTypeHeader: 'text/html; charset=utf-8'},
|
||||
);
|
||||
|
||||
// Act
|
||||
final ex = WgerHttpException(resp);
|
||||
|
||||
// Assert
|
||||
expect(ex.type, ErrorType.html);
|
||||
expect(ex.htmlError, body);
|
||||
});
|
||||
|
||||
test('detects HTML response from content', () {
|
||||
// Arrange
|
||||
const body = '<html lang="en"><body>Error</body></html>';
|
||||
final resp = http.Response(
|
||||
body,
|
||||
500,
|
||||
headers: {HttpHeaders.contentTypeHeader: 'text/foo; charset=utf-8'},
|
||||
);
|
||||
|
||||
// Act
|
||||
final ex = WgerHttpException(resp);
|
||||
|
||||
// Assert
|
||||
expect(ex.type, ErrorType.html);
|
||||
expect(ex.htmlError, body);
|
||||
});
|
||||
|
||||
test('fromMap sets errors and type', () {
|
||||
// Arrange
|
||||
final map = <String, dynamic>{'field': 'value'};
|
||||
|
||||
// Act
|
||||
final ex = WgerHttpException.fromMap(map);
|
||||
|
||||
// Assert
|
||||
expect(ex.type, ErrorType.json);
|
||||
expect(ex.errors, map);
|
||||
});
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2026 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:drift/native.dart';
|
||||
@@ -100,19 +118,25 @@ void main() {
|
||||
SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty();
|
||||
|
||||
// Mock categories
|
||||
when(mockBaseProvider.makeUrl(categoryUrl)).thenReturn(tCategoryEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(categoryUrl, query: anyNamed('query')),
|
||||
).thenReturn(tCategoryEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tCategoryEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tCategoryMap['results']));
|
||||
|
||||
// Mock muscles
|
||||
when(mockBaseProvider.makeUrl(muscleUrl)).thenReturn(tMuscleEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(muscleUrl, query: anyNamed('query')),
|
||||
).thenReturn(tMuscleEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tMuscleEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tMuscleMap['results']));
|
||||
|
||||
// Mock equipment
|
||||
when(mockBaseProvider.makeUrl(equipmentUrl)).thenReturn(tEquipmentEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(equipmentUrl, query: anyNamed('query')),
|
||||
).thenReturn(tEquipmentEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tEquipmentEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tEquipmentMap['results']));
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2026 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
@@ -105,19 +123,25 @@ void main() {
|
||||
driftRuntimeOptions.dontWarnAboutMultipleDatabases = true;
|
||||
|
||||
// Mock categories
|
||||
when(mockBaseProvider.makeUrl(categoryUrl)).thenReturn(tCategoryEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(categoryUrl, query: anyNamed('query')),
|
||||
).thenReturn(tCategoryEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tCategoryEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tCategoryMap['results']));
|
||||
|
||||
// Mock muscles
|
||||
when(mockBaseProvider.makeUrl(muscleUrl)).thenReturn(tMuscleEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(muscleUrl, query: anyNamed('query')),
|
||||
).thenReturn(tMuscleEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tMuscleEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tMuscleMap['results']));
|
||||
|
||||
// Mock equipment
|
||||
when(mockBaseProvider.makeUrl(equipmentUrl)).thenReturn(tEquipmentEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.makeUrl(equipmentUrl, query: anyNamed('query')),
|
||||
).thenReturn(tEquipmentEntriesUri);
|
||||
when(
|
||||
mockBaseProvider.fetchPaginated(tEquipmentEntriesUri),
|
||||
).thenAnswer((_) => Future.value(tEquipmentMap['results']));
|
||||
|
||||
135
test/providers/base_provider.dart
Normal file
135
test/providers/base_provider.dart
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2026 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:wger/core/exceptions/http_exception.dart';
|
||||
import 'package:wger/providers/base_provider.dart';
|
||||
|
||||
import '../utils.dart';
|
||||
import 'base_provider.mocks.dart';
|
||||
|
||||
@GenerateMocks([Client])
|
||||
void main() {
|
||||
final Uri testUri = Uri(scheme: 'https', host: 'localhost', path: 'api/v2/test/');
|
||||
|
||||
test('Retry on SocketException then succeeds', () async {
|
||||
// Arrange
|
||||
final mockClient = MockClient();
|
||||
var callCount = 0;
|
||||
when(mockClient.get(testUri, headers: anyNamed('headers'))).thenAnswer((_) {
|
||||
if (callCount == 0) {
|
||||
callCount++;
|
||||
return Future.error(const SocketException('conn fail'));
|
||||
}
|
||||
return Future.value(Response('{"ok": true}', 200));
|
||||
});
|
||||
|
||||
// Act
|
||||
final provider = WgerBaseProvider(testAuthProvider, mockClient);
|
||||
final result = await provider.fetch(testUri, initialDelay: const Duration(milliseconds: 1));
|
||||
|
||||
// Assert
|
||||
expect(result, isA<Map>());
|
||||
expect(result['ok'], isTrue);
|
||||
verify(mockClient.get(testUri, headers: anyNamed('headers'))).called(2);
|
||||
});
|
||||
|
||||
test('Retry on 5xx then succeeds', () async {
|
||||
// Arrange
|
||||
final mockClient = MockClient();
|
||||
var callCount = 0;
|
||||
when(mockClient.get(testUri, headers: anyNamed('headers'))).thenAnswer((_) {
|
||||
if (callCount == 0) {
|
||||
callCount++;
|
||||
return Future.value(Response('{"msg":"error"}', 502));
|
||||
}
|
||||
return Future.value(Response('{"ok": true}', 200));
|
||||
});
|
||||
|
||||
// Act
|
||||
final provider = WgerBaseProvider(testAuthProvider, mockClient);
|
||||
final result = await provider.fetch(testUri, initialDelay: const Duration(milliseconds: 1));
|
||||
|
||||
// Assert
|
||||
expect(result, isA<Map>());
|
||||
expect(result['ok'], isTrue);
|
||||
verify(mockClient.get(testUri, headers: anyNamed('headers'))).called(2);
|
||||
});
|
||||
|
||||
test('Do not retry on 4xx client error', () async {
|
||||
// Arrange
|
||||
final mockClient = MockClient();
|
||||
when(
|
||||
mockClient.get(testUri, headers: anyNamed('headers')),
|
||||
).thenAnswer((_) => Future.value(Response('{"error":"bad"}', 400)));
|
||||
|
||||
// Act
|
||||
final provider = WgerBaseProvider(testAuthProvider, mockClient);
|
||||
|
||||
// Assert
|
||||
await expectLater(
|
||||
provider.fetch(testUri, initialDelay: const Duration(milliseconds: 1)),
|
||||
throwsA(isA<WgerHttpException>()),
|
||||
);
|
||||
verify(mockClient.get(testUri, headers: anyNamed('headers'))).called(1);
|
||||
});
|
||||
|
||||
test('Exceed max retries and rethrow after retries', () async {
|
||||
// Arrange
|
||||
final mockClient = MockClient();
|
||||
when(
|
||||
mockClient.get(testUri, headers: anyNamed('headers')),
|
||||
).thenAnswer((_) => Future.error(ClientException('conn fail')));
|
||||
|
||||
// Act
|
||||
final provider = WgerBaseProvider(testAuthProvider, mockClient);
|
||||
dynamic caught;
|
||||
try {
|
||||
await provider.fetch(testUri, initialDelay: const Duration(milliseconds: 1));
|
||||
} catch (e) {
|
||||
caught = e;
|
||||
}
|
||||
|
||||
// Assert
|
||||
expect(caught, isA<ClientException>());
|
||||
// initial try + 3 retries = 4 calls
|
||||
verify(mockClient.get(testUri, headers: anyNamed('headers'))).called(4);
|
||||
});
|
||||
|
||||
test('Request succeeds without retries', () async {
|
||||
// Arrange
|
||||
final mockClient = MockClient();
|
||||
when(
|
||||
mockClient.get(testUri, headers: anyNamed('headers')),
|
||||
).thenAnswer((_) => Future.value(Response('{"ok": true}', 200)));
|
||||
|
||||
// Act
|
||||
final provider = WgerBaseProvider(testAuthProvider, mockClient);
|
||||
final result = await provider.fetch(testUri);
|
||||
|
||||
// Assert
|
||||
expect(result, isA<Map>());
|
||||
expect(result['ok'], isTrue);
|
||||
verify(mockClient.get(testUri, headers: anyNamed('headers'))).called(1);
|
||||
});
|
||||
}
|
||||
218
test/providers/base_provider.mocks.dart
Normal file
218
test/providers/base_provider.mocks.dart
Normal file
@@ -0,0 +1,218 @@
|
||||
// Mocks generated by Mockito 5.4.6 from annotations
|
||||
// in wger/test/providers/base_provider.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
// ignore_for_file: no_leading_underscores_for_library_prefixes
|
||||
import 'dart:async' as _i3;
|
||||
import 'dart:convert' as _i4;
|
||||
import 'dart:typed_data' as _i6;
|
||||
|
||||
import 'package:http/http.dart' as _i2;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
import 'package:mockito/src/dummies.dart' as _i5;
|
||||
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: deprecated_member_use
|
||||
// ignore_for_file: deprecated_member_use_from_same_package
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: must_be_immutable
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: subtype_of_sealed_class
|
||||
// ignore_for_file: invalid_use_of_internal_member
|
||||
|
||||
class _FakeResponse_0 extends _i1.SmartFake implements _i2.Response {
|
||||
_FakeResponse_0(Object parent, Invocation parentInvocation) : super(parent, parentInvocation);
|
||||
}
|
||||
|
||||
class _FakeStreamedResponse_1 extends _i1.SmartFake implements _i2.StreamedResponse {
|
||||
_FakeStreamedResponse_1(Object parent, Invocation parentInvocation)
|
||||
: super(parent, parentInvocation);
|
||||
}
|
||||
|
||||
/// A class which mocks [Client].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockClient extends _i1.Mock implements _i2.Client {
|
||||
MockClient() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> head(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#head, [url], {#headers: headers}),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(#head, [url], {#headers: headers}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> get(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#get, [url], {#headers: headers}),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(#get, [url], {#headers: headers}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> post(
|
||||
Uri? url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i4.Encoding? encoding,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#post,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#post,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> put(
|
||||
Uri? url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i4.Encoding? encoding,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#put,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#put,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> patch(
|
||||
Uri? url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i4.Encoding? encoding,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#patch,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#patch,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.Response> delete(
|
||||
Uri? url, {
|
||||
Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i4.Encoding? encoding,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#delete,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
returnValue: _i3.Future<_i2.Response>.value(
|
||||
_FakeResponse_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#delete,
|
||||
[url],
|
||||
{#headers: headers, #body: body, #encoding: encoding},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.Response>);
|
||||
|
||||
@override
|
||||
_i3.Future<String> read(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#read, [url], {#headers: headers}),
|
||||
returnValue: _i3.Future<String>.value(
|
||||
_i5.dummyValue<String>(
|
||||
this,
|
||||
Invocation.method(#read, [url], {#headers: headers}),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<String>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i6.Uint8List> readBytes(
|
||||
Uri? url, {
|
||||
Map<String, String>? headers,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#readBytes, [url], {#headers: headers}),
|
||||
returnValue: _i3.Future<_i6.Uint8List>.value(_i6.Uint8List(0)),
|
||||
)
|
||||
as _i3.Future<_i6.Uint8List>);
|
||||
|
||||
@override
|
||||
_i3.Future<_i2.StreamedResponse> send(_i2.BaseRequest? request) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#send, [request]),
|
||||
returnValue: _i3.Future<_i2.StreamedResponse>.value(
|
||||
_FakeStreamedResponse_1(
|
||||
this,
|
||||
Invocation.method(#send, [request]),
|
||||
),
|
||||
),
|
||||
)
|
||||
as _i3.Future<_i2.StreamedResponse>);
|
||||
|
||||
@override
|
||||
void close() => super.noSuchMethod(
|
||||
Invocation.method(#close, []),
|
||||
returnValueForMissingStub: null,
|
||||
);
|
||||
}
|
||||
@@ -1,21 +1,3 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2025 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Mocks generated by Mockito 5.4.6 from annotations
|
||||
// in wger/test/providers/plate_calculator_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* This file is part of wger Workout Manager <https://github.com/wger-project>.
|
||||
* Copyright (c) 2020, 2025 wger Team
|
||||
* Copyright (c) 2020 - 2026 wger Team
|
||||
*
|
||||
* wger Workout Manager is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
@@ -109,12 +109,10 @@ void main() {
|
||||
|
||||
await withClock(Clock.fixed(DateTime(2025, 3, 29, 14, 33)), () async {
|
||||
await tester.pumpWidget(renderGymMode());
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.byType(TextButton));
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
//await tester.ensureVisible(find.byKey(Key(key as String)));
|
||||
|
||||
//
|
||||
// Start page
|
||||
//
|
||||
@@ -306,6 +304,7 @@ void main() {
|
||||
expect(find.byIcon(Icons.chevron_right), findsNothing);
|
||||
});
|
||||
},
|
||||
tags: ['golden'],
|
||||
semanticsEnabled: false,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ void main() {
|
||||
|
||||
// Act
|
||||
notifier.calculatePages();
|
||||
notifier.setCurrentPage(2);
|
||||
|
||||
// Assert
|
||||
expect(notifier.state.getSlotEntryPageByIndex()!.type, SlotPageType.log);
|
||||
@@ -159,6 +160,7 @@ void main() {
|
||||
iteration: 1,
|
||||
);
|
||||
notifier.calculatePages();
|
||||
notifier.setCurrentPage(2);
|
||||
|
||||
// Act
|
||||
// Log page is at index 2
|
||||
@@ -189,15 +191,16 @@ void main() {
|
||||
|
||||
testWidgets('save button calls addLog on RoutinesProvider', (tester) async {
|
||||
// Arrange
|
||||
final gymNotifier = container.read(gymStateProvider.notifier);
|
||||
final notifier = container.read(gymStateProvider.notifier);
|
||||
final routine = testdata.getTestRoutine();
|
||||
gymNotifier.state = gymNotifier.state.copyWith(
|
||||
notifier.state = notifier.state.copyWith(
|
||||
dayId: routine.days.first.id,
|
||||
routine: routine,
|
||||
iteration: 1,
|
||||
);
|
||||
gymNotifier.calculatePages();
|
||||
gymNotifier.state = gymNotifier.state.copyWith(currentPage: 2);
|
||||
notifier.calculatePages();
|
||||
notifier.setCurrentPage(2);
|
||||
notifier.state = notifier.state.copyWith(currentPage: 2);
|
||||
final mockRoutines = MockRoutinesProvider();
|
||||
|
||||
// Act
|
||||
@@ -206,8 +209,8 @@ void main() {
|
||||
final editableFields = find.byType(EditableText);
|
||||
expect(editableFields, findsWidgets);
|
||||
|
||||
await tester.enterText(editableFields.at(0), '7');
|
||||
await tester.enterText(editableFields.at(1), '77');
|
||||
await tester.enterText(editableFields.at(0), '12'); // Reps
|
||||
await tester.enterText(editableFields.at(1), '34'); // Weight
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
Log? capturedLog;
|
||||
@@ -226,13 +229,13 @@ void main() {
|
||||
// Assert
|
||||
verify(mockRoutines.addLog(any)).called(1);
|
||||
expect(capturedLog, isNotNull);
|
||||
expect(capturedLog!.repetitions, equals(7));
|
||||
expect(capturedLog!.weight, equals(77));
|
||||
expect(capturedLog!.repetitions, equals(12));
|
||||
expect(capturedLog!.weight, equals(34));
|
||||
|
||||
final currentSlotPage = gymNotifier.state.getSlotEntryPageByIndex()!;
|
||||
final currentSlotPage = notifier.state.getSlotEntryPageByIndex()!;
|
||||
expect(capturedLog!.slotEntryId, equals(currentSlotPage.setConfigData!.slotEntryId));
|
||||
expect(capturedLog!.routineId, equals(gymNotifier.state.routine.id));
|
||||
expect(capturedLog!.iteration, equals(gymNotifier.state.iteration));
|
||||
expect(capturedLog!.routineId, equals(notifier.state.routine.id));
|
||||
expect(capturedLog!.iteration, equals(notifier.state.iteration));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user