Fakultas Ilmu Komputer UI

Commit a4dc2b94 authored by Ferdi Salim Sungkar's avatar Ferdi Salim Sungkar
Browse files

[GREEN] finish the api for login and improve coverage

parent 63710dd0
Pipeline #78874 passed with stages
in 7 minutes and 48 seconds
......@@ -668,7 +668,7 @@
"languageVersion": "2.7"
}
],
"generated": "2021-05-25T11:35:11.928633Z",
"generated": "2021-05-25T12:41:54.637412Z",
"generator": "pub",
"generatorVersion": "2.12.0"
}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_keyboard_visibility","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility-5.0.0/","dependencies":[]},{"name":"flutter_secure_storage","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.5/","dependencies":[]},{"name":"image_picker","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.7.4/","dependencies":[]},{"name":"path_provider","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.1/","dependencies":[]}],"android":[{"name":"flutter_keyboard_visibility","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility-5.0.0/","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-2.0.1/","dependencies":[]},{"name":"flutter_secure_storage","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.5/","dependencies":[]},{"name":"image_picker","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.7.4/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.1/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.0/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.0.0/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.0.0/","dependencies":[]}],"web":[{"name":"flutter_keyboard_visibility_web","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility_web-2.0.0/","dependencies":[]},{"name":"image_picker_for_web","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_keyboard_visibility","dependencies":["flutter_keyboard_visibility_web"]},{"name":"flutter_keyboard_visibility_web","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle","image_picker_for_web"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2021-05-25 18:38:53.444174","version":"2.0.1"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"flutter_keyboard_visibility","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility-5.0.0/","dependencies":[]},{"name":"flutter_secure_storage","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.5/","dependencies":[]},{"name":"image_picker","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.7.4/","dependencies":[]},{"name":"path_provider","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.1/","dependencies":[]}],"android":[{"name":"flutter_keyboard_visibility","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility-5.0.0/","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-2.0.1/","dependencies":[]},{"name":"flutter_secure_storage","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_secure_storage-3.3.5/","dependencies":[]},{"name":"image_picker","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker-0.7.4/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-2.0.1/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-2.0.0/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-2.0.0/","dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-2.0.0/","dependencies":[]}],"web":[{"name":"flutter_keyboard_visibility_web","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_keyboard_visibility_web-2.0.0/","dependencies":[]},{"name":"image_picker_for_web","path":"/Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/image_picker_for_web-2.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"flutter_keyboard_visibility","dependencies":["flutter_keyboard_visibility_web"]},{"name":"flutter_keyboard_visibility_web","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"flutter_secure_storage","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle","image_picker_for_web"]},{"name":"image_picker_for_web","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux","path_provider_windows"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2021-05-25 22:15:24.831938","version":"2.0.1"}
\ No newline at end of file
......@@ -3,7 +3,7 @@
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
# Generated by pub on 2021-05-25 18:35:11.904673.
# Generated by pub on 2021-05-25 19:41:54.610592.
_fe_analyzer_shared:file:///Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/_fe_analyzer_shared-14.0.0/lib/
analyzer:file:///Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/analyzer-0.41.2/lib/
args:file:///Users/ferdisungkar/flutter/.pub-cache/hosted/pub.dartlang.org/args-2.0.0/lib/
......
......@@ -18,31 +18,8 @@ class Api {
var jsonData = (jsonObject as Map<String, dynamic>)['data'];
var token = jsonData['token'];
await secureStorage.writeSecureData('token', token);
} else if (apiResult.statusCode == 400) {
var jsonObject = json.decode(apiResult.body);
var jsonData = (jsonObject as Map<String, dynamic>)['data'];
var jsonError = jsonData['errors'];
var jsonErrorMessage = jsonError[0]['message'];
switch (jsonErrorMessage) {
case 'invalid.credential':
{
throw Exception('Invalid Credential');
}
break;
case 'empty.email':
{
throw Exception('Email cannot be empty');
}
break;
case 'empty.password':
{
throw Exception('Password cannot be empty');
}
break;
}
} else {
throw Exception('Failed to Login');
}
return apiResult.statusCode;
}
Future<int> register(String email, String password) async {
......
......@@ -50,6 +50,7 @@ class _LoginState extends State<Login> {
}
final _keyForm = GlobalKey<FormState>();
var statusCode = 0;
Widget _buildEmail() {
return SizedBox(
......@@ -80,6 +81,34 @@ class _LoginState extends State<Login> {
);
}
createAlertDialog(BuildContext context) {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(
'Login gagal',
),
content: Text(
'Email atau password anda salah',
key: Key('alertText'),
),
actions: <Widget>[
MaterialButton(
elevation: 0.5,
child: Text(
'Coba lagi',
key: Key('backButton'),
textAlign: TextAlign.center,
),
onPressed: () {
Navigator.of(context).pop();
})
],
);
});
}
String email;
String password;
......@@ -114,31 +143,37 @@ class _LoginState extends State<Login> {
color: black3))),
Container(
margin: const EdgeInsets.fromLTRB(0, 16, 0, 0),
child: RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: 'Belum Punya Akun? ',
child: Row(
children: [
Text('Belum Punya Akun? ',
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Color.fromRGBO(46, 47, 48, 1.0))),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: 'Daftar',
style: GoogleFonts.inter(
fontSize: 12,
fontWeight: FontWeight.normal,
color: Color.fromRGBO(0, 145, 201, 1.0)),
color:
Color.fromRGBO(0, 145, 201, 1.0)),
recognizer: TapGestureRecognizer()
..onTap = () {
Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext builder) =>
builder:
(BuildContext builder) =>
RegisterPage()));
}),
],
),
key: Key('registerButton'),
),
],
),
),
Container(
......@@ -201,12 +236,14 @@ class _LoginState extends State<Login> {
}
_keyForm.currentState.save();
Api().login(email, password);
statusCode = await Api()
.login(email, password);
if (statusCode == 200) {
Api().otpGet(
await SecureStorage()
.readSecureData(
'token'));
Navigator.push(context,
MaterialPageRoute(
builder: (context) {
......@@ -214,6 +251,9 @@ class _LoginState extends State<Login> {
home:
CancelConfirmation());
}));
} else if (statusCode == 400) {
createAlertDialog(context);
}
},
child: Text(
'Masuk',
......@@ -246,6 +286,7 @@ class _LoginState extends State<Login> {
builder) =>
ForgetPassword()));
}),
key: Key('forgetPasswordButton'),
),
)
],
......
......@@ -20,91 +20,6 @@ void main() {
var login = api.login("test@gmail.com", "password");
expect(true, login is Future);
});
test('Throws exception when no credential found', () async {
//setup the test
final apiProvider = Api();
apiProvider.client = MockClient((request) async {
final mapJson = {
"success": false,
"code": 400,
"message": "error.post_auth_login",
"detail": "There is some problem with the data you submitted.",
"data": {
"errors": [
{"field": "credential", "message": "invalid.credential"}
]
}
};
return Response(json.encode(mapJson), 400);
});
// final token = await apiProvider.login('badtest@gmail.com', 'password');
expect(() => apiProvider.login('badtest@gmail.com', 'password'),
throwsException);
});
test('Throws exception when Email field is empty', () async {
//setup the test
final apiProvider = Api();
apiProvider.client = MockClient((request) async {
final mapJson = {
"success": false,
"code": 400,
"message": "There is some problem with the data you submitted.",
"detail": "There is some problem with the data you submitted.",
"data": {
"errors": [
{"field": "email", "message": "empty.email"}
]
}
};
return Response(json.encode(mapJson), 400);
});
// final token = await apiProvider.login('badtest@gmail.com', 'password');
expect(() => apiProvider.login('', 'password'), throwsException);
});
test('Throws exception when Password field is empty', () async {
//setup the test
final apiProvider = Api();
apiProvider.client = MockClient((request) async {
final mapJson = {
"success": false,
"code": 400,
"message": "There is some problem with the data you submitted.",
"detail": "There is some problem with the data you submitted.",
"data": {
"errors": [
{"field": "password", "message": "empty.password"}
]
}
};
return Response(json.encode(mapJson), 400);
});
// final token = await apiProvider.login('badtest@gmail.com', 'password');
expect(() => apiProvider.login('badtest@gmail.com', ''), throwsException);
});
test('statusCode other than 200 or 400', () async {
//setup the test
final apiProvider = Api();
apiProvider.client = MockClient((request) async {
final mapJson = {
"success": false,
"code": 401,
"message": "There is some problem with the data you submitted.",
"detail": "There is some problem with the data you submitted.",
"data": {
"errors": [
{"field": "password", "message": "empty.password"}
]
}
};
return Response(json.encode(mapJson), 401);
});
// final token = await apiProvider.login('badtest@gmail.com', 'password');
expect(() => apiProvider.login('badtest@gmail.com', ''), throwsException);
});
});
group('register test', () {
......
......@@ -27,34 +27,79 @@ void main() {
expect(loginButton, findsOneWidget);
});
// testWidgets('Login button navigate into next page when pressed',
// (WidgetTester tester) async {
// // initialize
// final emailFormField = find.byKey(Key('emailFormField'));
// final passwordFormField = find.byKey(Key('passwordFormField'));
// final loginButton = find.byKey(Key('loginButton'));
// final welcomeToFluttersText = find.byKey(Key('stringPenawaran'));
// // execute
// await tester.pumpWidget(MaterialApp(
// home: Login(),
// ));
// await tester.tap(emailFormField);
// await tester.enterText(emailFormField, 'wibias.fuad@ui.ac.id');
// await tester.tap(passwordFormField);
// await tester.enterText(passwordFormField, '0Gakpake0');
// await tester.tap(loginButton);
// await tester.pumpAndSettle();
// // check outputs
// expect(welcomeToFluttersText, findsOneWidget);
// });
testWidgets('Login button pops alert up', (WidgetTester tester) async {
// initialize
final emailFormField = find.byKey(Key('emailFormField'));
final passwordFormField = find.byKey(Key('passwordFormField'));
final loginButton = find.byKey(Key('loginButton'));
final alertText = find.byKey(Key('alertText'));
final backButton = find.byKey(Key('backButton'));
// execute
await tester.pumpWidget(MaterialApp(
home: Login(),
));
await tester.tap(emailFormField);
await tester.enterText(emailFormField, 'widdd@ui.ac.id');
await tester.tap(passwordFormField);
await tester.enterText(passwordFormField, '0Gakpake0');
await tester.tap(loginButton);
await tester.pump(Duration(seconds: 5));
// check outputs
expect(alertText, findsOneWidget);
// execute
await tester.tap(backButton);
// check outputs
expect(emailFormField, findsOneWidget);
});
testWidgets('Forget Password will navigate to forget password page',
(WidgetTester tester) async {
// initialize
final forgetPasswordButton = find.byKey(Key('forgetPasswordButton'));
final pageTitleText = find.byKey(Key('pageTitleText'));
// execute
await tester.pumpWidget(MaterialApp(
home: Login(),
));
await tester.tap(forgetPasswordButton);
await tester.pumpAndSettle();
// check outputs
expect(pageTitleText, findsOneWidget);
});
testWidgets('register button will navigate to register page',
(WidgetTester tester) async {
// initialize
final registerButton = find.byKey(Key('registerButton'));
final daftarAkunTitle = find.byKey(Key('daftarAkunTitle'));
// execute
await tester.pumpWidget(MaterialApp(
home: Login(),
));
await tester.tap(registerButton);
await tester.pumpAndSettle();
// check outputs
expect(daftarAkunTitle, findsOneWidget);
});
test('Email field in Login page is not filled', () {
var test = EmailValidator.validate('');
expect(test, 'Email harus di isi');
});
test('Email field in Login page is filled wrong', () {
var test = EmailValidator.validate('sssss');
expect(test, 'Email tidak valid');
});
test('Password field in Login page is not filled', () {
var testPassword = PasswordValidator.validate('');
expect(testPassword, 'Password harus di isi');
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment