Skip to content

Commit 51a0e87

Browse files
committed
Correctly show any errors from the server on the registration page
Also, add some tests
1 parent dd12e04 commit 51a0e87

File tree

8 files changed

+575
-156
lines changed

8 files changed

+575
-156
lines changed

lib/exceptions/http_exception.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class WgerHttpException implements Exception {
2929
errors = {'unknown_error': 'An unknown error occurred, no further information available'};
3030
} else {
3131
try {
32-
errors = {'unknown_error': json.decode(responseBody)};
32+
final response = json.decode(responseBody);
33+
errors = (response is Map ? response : {'unknown_error': response}).cast<String, dynamic>();
3334
} catch (e) {
3435
errors = {'unknown_error': responseBody};
3536
}

lib/helpers/ui.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ import 'package:wger/models/workouts/log.dart';
2828
import 'package:wger/providers/workout_plans.dart';
2929

3030
void showErrorDialog(dynamic exception, BuildContext context) {
31-
log('showErrorDialog: ');
32-
log(exception.toString());
33-
log('=====================');
31+
// log('showErrorDialog: ');
32+
// log(exception.toString());
33+
// log('=====================');
3434

3535
showDialog(
3636
context: context,
@@ -55,6 +55,7 @@ void showHttpExceptionErrorDialog(WgerHttpException exception, BuildContext cont
5555
log('-------------------');
5656

5757
final List<Widget> errorList = [];
58+
5859
for (final key in exception.errors!.keys) {
5960
// Error headers
6061
// Ensure that the error heading first letter is capitalized.

lib/providers/auth.dart

Lines changed: 68 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ class AuthProvider with ChangeNotifier {
8383
/// Server application version
8484
Future<void> setServerVersion() async {
8585
final response = await client.get(makeUri(serverUrl!, SERVER_VERSION_URL));
86-
final responseData = json.decode(response.body);
87-
serverVersion = responseData;
86+
serverVersion = json.decode(response.body);
8887
}
8988

9089
Future<void> initData(String serverUrl) async {
@@ -115,41 +114,39 @@ class AuthProvider with ChangeNotifier {
115114
}
116115

117116
/// Registers a new user
118-
Future<Map<String, LoginActions>> register(
119-
{required String username,
120-
required String password,
121-
required String email,
122-
required String serverUrl}) async {
117+
Future<Map<String, LoginActions>> register({
118+
required String username,
119+
required String password,
120+
required String email,
121+
required String serverUrl,
122+
String locale = 'en',
123+
}) async {
123124
// Register
124-
try {
125-
final Map<String, String> data = {'username': username, 'password': password};
126-
if (email != '') {
127-
data['email'] = email;
128-
}
129-
final response = await client.post(
130-
makeUri(serverUrl, REGISTRATION_URL),
131-
headers: {
132-
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
133-
HttpHeaders.authorizationHeader: 'Token ${metadata[MANIFEST_KEY_API]}',
134-
HttpHeaders.userAgentHeader: getAppNameHeader(),
135-
},
136-
body: json.encode(data),
137-
);
138-
final responseData = json.decode(response.body);
139-
140-
if (response.statusCode >= 400) {
141-
throw WgerHttpException(responseData);
142-
}
143-
144-
// If update is required don't log in user
145-
if (await applicationUpdateRequired()) {
146-
return {'action': LoginActions.update};
147-
}
148-
149-
return login(username, password, serverUrl);
150-
} catch (error) {
151-
rethrow;
125+
final Map<String, String> data = {'username': username, 'password': password};
126+
if (email != '') {
127+
data['email'] = email;
128+
}
129+
final response = await client.post(
130+
makeUri(serverUrl, REGISTRATION_URL),
131+
headers: {
132+
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
133+
HttpHeaders.authorizationHeader: 'Token ${metadata[MANIFEST_KEY_API]}',
134+
HttpHeaders.userAgentHeader: getAppNameHeader(),
135+
HttpHeaders.acceptLanguageHeader: locale
136+
},
137+
body: json.encode(data),
138+
);
139+
140+
if (response.statusCode >= 400) {
141+
throw WgerHttpException(response.body);
142+
}
143+
144+
// If update is required don't log in user
145+
if (await applicationUpdateRequired()) {
146+
return {'action': LoginActions.update};
152147
}
148+
149+
return login(username, password, serverUrl);
153150
}
154151

155152
/// Authenticates a user
@@ -160,48 +157,44 @@ class AuthProvider with ChangeNotifier {
160157
) async {
161158
await logout(shouldNotify: false);
162159

163-
try {
164-
final response = await client.post(
165-
makeUri(serverUrl, LOGIN_URL),
166-
headers: <String, String>{
167-
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
168-
HttpHeaders.userAgentHeader: getAppNameHeader(),
169-
},
170-
body: json.encode({'username': username, 'password': password}),
171-
);
172-
final responseData = json.decode(response.body);
173-
174-
if (response.statusCode >= 400) {
175-
throw WgerHttpException(responseData);
176-
}
177-
178-
await initData(serverUrl);
179-
180-
// If update is required don't log in user
181-
if (await applicationUpdateRequired()) {
182-
return {'action': LoginActions.update};
183-
}
184-
185-
// Log user in
186-
token = responseData['token'];
187-
notifyListeners();
160+
final response = await client.post(
161+
makeUri(serverUrl, LOGIN_URL),
162+
headers: <String, String>{
163+
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
164+
HttpHeaders.userAgentHeader: getAppNameHeader(),
165+
},
166+
body: json.encode({'username': username, 'password': password}),
167+
);
168+
final responseData = json.decode(response.body);
188169

189-
// store login data in shared preferences
190-
final prefs = await SharedPreferences.getInstance();
191-
final userData = json.encode({
192-
'token': token,
193-
'serverUrl': this.serverUrl,
194-
});
195-
final serverData = json.encode({
196-
'serverUrl': this.serverUrl,
197-
});
198-
199-
prefs.setString('userData', userData);
200-
prefs.setString('lastServer', serverData);
201-
return {'action': LoginActions.proceed};
202-
} catch (error) {
203-
rethrow;
170+
if (response.statusCode >= 400) {
171+
throw WgerHttpException(response.body);
204172
}
173+
174+
await initData(serverUrl);
175+
176+
// If update is required don't log in user
177+
if (await applicationUpdateRequired()) {
178+
return {'action': LoginActions.update};
179+
}
180+
181+
// Log user in
182+
token = responseData['token'];
183+
notifyListeners();
184+
185+
// store login data in shared preferences
186+
final prefs = await SharedPreferences.getInstance();
187+
final userData = json.encode({
188+
'token': token,
189+
'serverUrl': this.serverUrl,
190+
});
191+
final serverData = json.encode({
192+
'serverUrl': this.serverUrl,
193+
});
194+
195+
prefs.setString('userData', userData);
196+
prefs.setString('lastServer', serverData);
197+
return {'action': LoginActions.proceed};
205198
}
206199

207200
/// Loads the last server URL from which the user successfully logged in

lib/providers/base_provider.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class WgerBaseProvider {
3737
this.client = client ?? http.Client();
3838
}
3939

40-
Map<String, String> getDefaultHeaders({includeAuth = false}) {
40+
Map<String, String> getDefaultHeaders({bool includeAuth = false}) {
4141
final out = {
4242
HttpHeaders.contentTypeHeader: 'application/json; charset=UTF-8',
4343
HttpHeaders.userAgentHeader: auth.getAppNameHeader(),

lib/screens/auth_screen.dart

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,16 +177,21 @@ class _AuthCardState extends State<AuthCard> {
177177
// Login existing user
178178
late Map<String, LoginActions> res;
179179
if (_authMode == AuthMode.Login) {
180-
res = await Provider.of<AuthProvider>(context, listen: false)
181-
.login(_authData['username']!, _authData['password']!, _authData['serverUrl']!);
180+
res = await Provider.of<AuthProvider>(context, listen: false).login(
181+
_authData['username']!,
182+
_authData['password']!,
183+
_authData['serverUrl']!,
184+
);
182185

183186
// Register new user
184187
} else {
185188
res = await Provider.of<AuthProvider>(context, listen: false).register(
186-
username: _authData['username']!,
187-
password: _authData['password']!,
188-
email: _authData['email']!,
189-
serverUrl: _authData['serverUrl']!);
189+
username: _authData['username']!,
190+
password: _authData['password']!,
191+
email: _authData['email']!,
192+
serverUrl: _authData['serverUrl']!,
193+
locale: Localizations.localeOf(context).languageCode,
194+
);
190195
}
191196

192197
// Check if update is required else continue normally

test/auth/auth_provider_test.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ void main() {
2626
group('min application version check', () {
2727
test('app version higher than min version', () async {
2828
// arrange
29-
3029
when(mockClient.get(tVersionUri)).thenAnswer((_) => Future(() => Response('"1.2.0"', 200)));
3130
final updateNeeded = await authProvider.applicationUpdateRequired('1.3.0', testMetadata);
3231

0 commit comments

Comments
 (0)