1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-19 22:49:08 -05:00

Refactorization of the app (#31)

* Refactor LoadingTask
* Remove LoadingTask class
* Fix context leak in LoginTask
* Refactorisation GradesFragment
* Refactorization synchronization
* Fix leak in VulcanService
* Update mockito
* Add more tests for EntitiesCompare
* Fix Instant Run
* Add margin to grades
* Update ci android image
This commit is contained in:
Rafał Borcz 2017-11-06 17:25:38 +01:00 committed by Mikołaj Pich
parent 54112f73f1
commit e5ea6e0b41
32 changed files with 374 additions and 284 deletions

View File

@ -7,7 +7,7 @@ references:
container_config: &container_config
docker:
- image: circleci/android:api-26-alpha
- image: circleci/android:api-27-alpha
working_directory: *workspace_root
environment:
environment:

View File

@ -1,4 +1,4 @@
image: circleci/android:api-25-alpha
image: circleci/android:api-27-alpha
before_script:
- export GRADLE_USER_HOME=`pwd`/.gradle

View File

@ -62,10 +62,10 @@ dependencies {
debugCompile 'com.amitshekhar.android:debug-db:1.0.1'
debugCompile 'net.zetetic:android-database-sqlcipher:3.5.7@aar'
androidTestCompile 'org.mockito:mockito-android:2.10.0'
androidTestCompile 'org.mockito:mockito-android:2.11.0'
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:2.10.0'
testCompile 'org.mockito:mockito-core:2.11.0'
androidTestCompile('com.android.support.test.espresso:espresso-core:3.0.1', {
exclude group: 'com.android.support', module: 'support-annotations'

View File

@ -27,10 +27,10 @@ import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.security.Safety;
import io.github.wulkanowy.services.LoginSession;
import io.github.wulkanowy.services.synchronisation.AccountAuthorization;
import io.github.wulkanowy.services.synchronisation.CurrentAccountLogin;
@RunWith(AndroidJUnit4.class)
public class AccountAuthorizationTest {
public class CurrentAccountLoginTest {
private static DaoSession daoSession;
@ -62,8 +62,8 @@ public class AccountAuthorizationTest {
public void emptyUserIdTest() throws CryptoException, BadCredentialsException,
AccountPermissionException, IOException, LoginErrorException {
AccountAuthorization accountAuthorization = new AccountAuthorization(context, daoSession, new Vulcan());
accountAuthorization.loginCurrentUser();
CurrentAccountLogin currentAccountLogin = new CurrentAccountLogin(context, daoSession, new Vulcan());
currentAccountLogin.loginCurrentUser();
}
@Test
@ -82,8 +82,8 @@ public class AccountAuthorizationTest {
Vulcan vulcan = Mockito.mock(Vulcan.class);
Mockito.doNothing().when(vulcan).login("TEST@TEST", "TEST", "TEST_SYMBOL", "TEST_ID");
AccountAuthorization accountAuthorization = new AccountAuthorization(targetContext, daoSession, vulcan);
LoginSession loginSession = accountAuthorization.loginCurrentUser();
CurrentAccountLogin currentAccountLogin = new CurrentAccountLogin(targetContext, daoSession, vulcan);
LoginSession loginSession = currentAccountLogin.loginCurrentUser();
Assert.assertNotNull(loginSession);
Assert.assertEquals(loginSession.getUserId(), userId);

View File

@ -22,9 +22,9 @@ import io.github.wulkanowy.dao.entities.DaoMaster;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.Safety;
import io.github.wulkanowy.services.LoginSession;
import io.github.wulkanowy.services.synchronisation.AccountRegistration;
import io.github.wulkanowy.services.synchronisation.FirstAccountLogin;
public class AccountRegistrationTest {
public class FirstAccountLoginTest {
private static DaoSession daoSession;
@ -55,9 +55,9 @@ public class AccountRegistrationTest {
Login login = Mockito.mock(Login.class);
Mockito.when(login.sendCredentials(Mockito.anyString(), Mockito.anyString(), Mockito.anyString()))
.thenReturn(certificate);
AccountRegistration accountRegistration = new AccountRegistration(login, new Vulcan(), "TEST@TEST", "TEST_PASS", "TEST_SYMBOL");
FirstAccountLogin firstAccountLogin = new FirstAccountLogin(login, new Vulcan(), "TEST@TEST", "TEST_PASS", "TEST_SYMBOL");
Assert.assertEquals(certificate, accountRegistration.connect());
Assert.assertEquals(certificate, firstAccountLogin.connect());
}
@Test
@ -79,8 +79,8 @@ public class AccountRegistrationTest {
Login login = Mockito.mock(Login.class);
Mockito.when(login.sendCertificate(Mockito.anyString(), Mockito.anyString())).thenReturn("TEST-SYMBOL");
AccountRegistration accountRegistration = new AccountRegistration(login, vulcan, "TEST@TEST", "TEST-PASS", "default");
LoginSession loginSession = accountRegistration.login(targetContext, daoSession, "<xml>cert</xml>");
FirstAccountLogin firstAccountLogin = new FirstAccountLogin(login, vulcan, "TEST@TEST", "TEST-PASS", "default");
LoginSession loginSession = firstAccountLogin.login(targetContext, daoSession, "<xml>cert</xml>");
Long userId = targetContext.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("userId", 0);

View File

@ -47,7 +47,7 @@ public class GradeSynchronizationTest {
}
@Test
public void syncGradesEmptyBaseTest() throws Exception {
public void syncGradesEmptyDatabaseTest() throws Exception {
Long userId = daoSession.getAccountDao().insert(new Account().setEmail("TEST@TEST"));
Long subjectId = daoSession.getSubjectDao().insert(new Subject().setName("Matematyka").setUserId(userId));
@ -75,7 +75,7 @@ public class GradeSynchronizationTest {
Assert.assertEquals(subjectId, grade.getSubjectId());
Assert.assertEquals("Matematyka", grade.getSubject());
Assert.assertEquals("5", grade.getValue());
Assert.assertTrue(grade.getIsNew());
Assert.assertFalse(grade.getIsNew());
}
@AfterClass

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.activity.dashboard;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
@ -15,6 +16,8 @@ import io.github.wulkanowy.activity.dashboard.lessonplan.LessonPlanFragment;
public class DashboardActivity extends AppCompatActivity {
private Fragment currentFragment;
private GradesFragment gradesFragment = new GradesFragment();
private AttendanceFragment attendanceFragment = new AttendanceFragment();
@ -28,35 +31,32 @@ public class DashboardActivity extends AppCompatActivity {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (item.getItemId()) {
case R.id.navigation_marks:
setTitle(R.string.grades_text);
transaction.replace(R.id.fragment_container, gradesFragment);
transaction.commit();
return true;
currentFragment = gradesFragment;
break;
case R.id.navigation_attendance:
setTitle(R.string.attendance_text);
transaction.replace(R.id.fragment_container, attendanceFragment);
transaction.commit();
return true;
currentFragment = attendanceFragment;
break;
case R.id.navigation_lessonplan:
setTitle(R.string.lessonplan_text);
transaction.replace(R.id.fragment_container, lessonPlanFragment);
transaction.commit();
return true;
currentFragment = lessonPlanFragment;
break;
case R.id.navigation_dashboard:
default:
setTitle(R.string.dashboard_text);
transaction.replace(R.id.fragment_container, boardFragment);
transaction.commit();
return true;
currentFragment = boardFragment;
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, currentFragment);
transaction.commit();
return true;
}
};
@ -65,14 +65,27 @@ public class DashboardActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
setTitle(R.string.dashboard_text);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setSelectedItemId(R.id.navigation_dashboard);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
if (savedInstanceState != null) {
currentFragment = getSupportFragmentManager().getFragment(savedInstanceState, "currentFragment");
setTitle(savedInstanceState.getString("activityTitle"));
} else {
currentFragment = boardFragment;
setTitle(R.string.dashboard_text);
}
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, boardFragment).commit();
.replace(R.id.fragment_container, currentFragment).commit();
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("activityTitle", getTitle().toString());
getSupportFragmentManager().putFragment(outState, "currentFragment", currentFragment);
}
public void onBackPressed() {

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.activity.dashboard.attendance;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@ -11,7 +12,7 @@ import io.github.wulkanowy.R;
public class AttendanceFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_attendance, container, false);
}

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.activity.dashboard.board;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@ -11,7 +12,7 @@ import io.github.wulkanowy.R;
public class BoardFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_board, container, false);
}

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.activity.dashboard.grades;
import android.app.Dialog;
import android.app.DialogFragment;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -20,6 +21,10 @@ public class GradesDialogFragment extends DialogFragment {
return new GradesDialogFragment().setGrade(grade);
}
public GradesDialogFragment() {
setRetainInstance(true);
}
public GradesDialogFragment setGrade(Grade grade) {
this.grade = grade;
return this;
@ -50,7 +55,7 @@ public class GradesDialogFragment extends DialogFragment {
descriptionText.setText(grade.getSymbol());
}
} else if (!"".equals(grade.getSymbol())) {
descriptionText.setText(grade.getSymbol() + " - " + grade.getDescription());
descriptionText.setText(String.format("%1$s - %2$s", grade.getSymbol(), grade.getDescription()));
} else {
descriptionText.setText(grade.getDescription());
}
@ -69,6 +74,16 @@ public class GradesDialogFragment extends DialogFragment {
return view;
}
@Override
public void onDestroyView() {
Dialog dialog = getDialog();
if (dialog != null && getRetainInstance()) {
dialog.setDismissMessage(null);
}
super.onDestroyView();
}
public static int colorHexToColorName(String hexColor) {
switch (hexColor) {
case "000000": {

View File

@ -1,8 +1,10 @@
package io.github.wulkanowy.activity.dashboard.grades;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
@ -14,6 +16,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@ -33,20 +36,39 @@ import io.github.wulkanowy.utilities.ConnectionUtilities;
public class GradesFragment extends Fragment {
private List<SubjectWithGrades> subjectWithGradesList = new ArrayList<>();
private static List<SubjectWithGrades> subjectWithGradesList = new ArrayList<>();
private SwipeRefreshLayout swipeRefreshLayout;
private View view;
private RefreshTask refreshTask;
private static long userId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_grades, container, false);
DaoSession daoSession;
View view = inflater.inflate(R.layout.fragment_grades, container, false);
if (getActivity() != null) {
daoSession = ((WulkanowyApp) getActivity().getApplication()).getDaoSession();
userId = getActivity().getSharedPreferences("LoginData", Context.MODE_PRIVATE)
.getLong("userId", 0);
prepareRefreshLayout(view, daoSession);
if (subjectWithGradesList.equals(new ArrayList<>())) {
createExpList(view, getActivity());
new GenerateListTask(getActivity(), view, daoSession).execute();
} else {
createExpList(view, getActivity());
view.findViewById(R.id.loadingPanel).setVisibility(View.INVISIBLE);
}
}
return view;
}
private void prepareRefreshLayout(final View mainView, final DaoSession daoSession) {
final SwipeRefreshLayout swipeRefreshLayout = mainView.findViewById(R.id.grade_swipe_refresh);
swipeRefreshLayout = view.findViewById(R.id.grade_swipe_refresh);
swipeRefreshLayout.setColorSchemeResources(android.R.color.black,
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
@ -56,47 +78,27 @@ public class GradesFragment extends Fragment {
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
if (!ConnectionUtilities.isOnline(view.getContext())) {
swipeRefreshLayout.setRefreshing(false);
Toast.makeText(view.getContext(), R.string.noInternet_text, Toast.LENGTH_SHORT).show();
if (ConnectionUtilities.isOnline(getContext())) {
new RefreshTask(getActivity(), mainView, daoSession).execute();
} else {
refreshTask = new RefreshTask();
refreshTask.execute(((WulkanowyApp) getActivity().getApplication()).getDaoSession());
Toast.makeText(mainView.getContext(), R.string.noInternet_text, Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);
}
}
});
if (new ArrayList<>().equals(subjectWithGradesList)) {
createExpListView();
new GradesTask().execute(((WulkanowyApp) getActivity().getApplication()).getDaoSession());
} else if (subjectWithGradesList.size() > 0) {
createExpListView();
view.findViewById(R.id.loadingPanel).setVisibility(View.GONE);
}
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
if (refreshTask != null && refreshTask.getStatus() == AsyncTask.Status.RUNNING) {
refreshTask.cancel(true);
}
}
private static void createExpList(View mainView, Activity activity) {
private void createExpListView() {
RecyclerView recyclerView = view.findViewById(R.id.subject_grade_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
GradesAdapter gradesAdapter = new GradesAdapter(subjectWithGradesList, getActivity());
RecyclerView recyclerView = mainView.findViewById(R.id.subject_grade_recycler);
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
GradesAdapter gradesAdapter = new GradesAdapter(subjectWithGradesList, activity);
recyclerView.setAdapter(gradesAdapter);
}
private void prepareSubjectsWithGradesList(DaoSession daoSession) {
subjectWithGradesList = new ArrayList<>();
private static void downloadGradesFormDatabase(DaoSession daoSession) {
long userId = getContext().getSharedPreferences("LoginData", Context.MODE_PRIVATE)
.getLong("userId", 0);
subjectWithGradesList = new ArrayList<>();
AccountDao accountDao = daoSession.getAccountDao();
Account account = accountDao.load(userId);
@ -110,31 +112,54 @@ public class GradesFragment extends Fragment {
}
}
private class GradesTask extends AsyncTask<DaoSession, Void, Void> {
private static class GenerateListTask extends AsyncTask<Void, Void, Void> {
private WeakReference<View> mainView;
private WeakReference<Activity> activity;
private DaoSession daoSession;
public GenerateListTask(Activity activity, View mainView, DaoSession daoSession) {
this.activity = new WeakReference<>(activity);
this.mainView = new WeakReference<>(mainView);
this.daoSession = daoSession;
}
@Override
protected Void doInBackground(DaoSession... params) {
prepareSubjectsWithGradesList(params[0]);
protected Void doInBackground(Void... params) {
downloadGradesFormDatabase(daoSession);
return null;
}
protected void onPostExecute(Void result) {
super.onPostExecute(result);
createExpListView();
view.findViewById(R.id.loadingPanel).setVisibility(View.GONE);
createExpList(mainView.get(), activity.get());
mainView.get().findViewById(R.id.loadingPanel).setVisibility(View.INVISIBLE);
}
}
private class RefreshTask extends AsyncTask<DaoSession, Void, Boolean> {
private static class RefreshTask extends AsyncTask<Void, Void, Boolean> {
private DaoSession daoSession;
private WeakReference<Activity> activity;
private WeakReference<View> mainView;
public RefreshTask(Activity activity, View mainView, DaoSession daoSession) {
this.activity = new WeakReference<>(activity);
this.daoSession = daoSession;
this.mainView = new WeakReference<>(mainView);
}
@Override
protected Boolean doInBackground(DaoSession... params) {
protected Boolean doInBackground(Void... params) {
VulcanSynchronization vulcanSynchronization = new VulcanSynchronization(new LoginSession());
try {
vulcanSynchronization.loginCurrentUser(getContext(), params[0], new Vulcan());
vulcanSynchronization.loginCurrentUser(activity.get(), daoSession, new Vulcan());
vulcanSynchronization.syncGrades();
prepareSubjectsWithGradesList(params[0]);
downloadGradesFormDatabase(daoSession);
return true;
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "There was a synchronization problem", e);
@ -147,24 +172,27 @@ public class GradesFragment extends Fragment {
super.onPostExecute(result);
if (result) {
prepareSubjectsWithGradesList(((WulkanowyApp) getActivity().getApplication()).getDaoSession());
createExpListView();
swipeRefreshLayout.setRefreshing(false);
if (mainView.get() != null && activity.get() != null) {
createExpList(mainView.get(), activity.get());
}
int volumeGrades = DatabaseAccess.getNewGrades(((WulkanowyApp) getActivity().getApplication()).getDaoSession()).size();
int volumeGrades = DatabaseAccess.getNewGrades(daoSession).size();
if (volumeGrades == 0) {
Snackbar.make(getActivity().findViewById(R.id.fragment_container),
Snackbar.make(activity.get().findViewById(R.id.fragment_container),
R.string.snackbar_no_grades,
Snackbar.LENGTH_SHORT).show();
} else {
Snackbar.make(getActivity().findViewById(R.id.fragment_container),
getString(R.string.snackbar_new_grade, volumeGrades),
Snackbar.make(activity.get().findViewById(R.id.fragment_container),
activity.get().getString(R.string.snackbar_new_grade, volumeGrades),
Snackbar.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getContext(), R.string.refresh_error_text, Toast.LENGTH_SHORT).show();
Toast.makeText(activity.get(), R.string.refresh_error_text, Toast.LENGTH_SHORT).show();
}
if (mainView.get() != null) {
SwipeRefreshLayout swipeRefreshLayout = mainView.get().findViewById(R.id.grade_swipe_refresh);
swipeRefreshLayout.setRefreshing(false);
}
}

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.activity.dashboard.lessonplan;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
@ -14,8 +15,8 @@ public class LessonPlanFragment extends Fragment {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_lessonplan, container, false);
}
}

View File

@ -144,8 +144,8 @@ public class LoginActivity extends Activity {
symbol = "Default";
}
String[] keys = this.getResources().getStringArray(R.array.symbols);
String[] values = this.getResources().getStringArray(R.array.symbols_values);
String[] keys = getResources().getStringArray(R.array.symbols);
String[] values = getResources().getStringArray(R.array.symbols_values);
LinkedHashMap<String, String> map = new LinkedHashMap<>();
for (int i = 0; i < Math.min(keys.length, values.length); ++i) {
@ -198,9 +198,9 @@ public class LoginActivity extends Activity {
float y = ev.getRawY() + view.getTop() - scrcoords[1];
if (x < view.getLeft() || x > view.getRight() || y < view.getTop()
|| y > view.getBottom()) {
((InputMethodManager) this.getSystemService(
((InputMethodManager) getSystemService(
Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
(this.getWindow().getDecorView().getApplicationWindowToken()), 0);
(getWindow().getDecorView().getApplicationWindowToken()), 0);
}
}
}

View File

@ -12,21 +12,19 @@ import android.widget.EditText;
import android.widget.TextView;
import java.io.IOException;
import java.lang.ref.WeakReference;
import io.github.wulkanowy.R;
import io.github.wulkanowy.activity.WulkanowyApp;
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.services.LoginSession;
import io.github.wulkanowy.services.VulcanSynchronization;
import io.github.wulkanowy.services.synchronisation.AccountRegistration;
import io.github.wulkanowy.services.jobs.GradeJob;
import io.github.wulkanowy.utilities.ConnectionUtilities;
/**
@ -41,16 +39,16 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
private final String symbol;
private Activity activity;
private WeakReference<Activity> activity;
private View progressView;
private WeakReference<View> progressView;
private View loginFormView;
private WeakReference<View> loginFormView;
private TextView showText;
private WeakReference<TextView> showText;
public LoginTask(Activity activity, String email, String password, String symbol) {
this.activity = activity;
this.activity = new WeakReference<>(activity);
this.email = email;
this.password = password;
this.symbol = symbol;
@ -58,28 +56,24 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
@Override
protected void onPreExecute() {
showText = activity.findViewById(R.id.login_progress_text);
showText = new WeakReference<>((TextView) activity.get().findViewById(R.id.login_progress_text));
}
@Override
protected Integer doInBackground(Void... params) {
if (ConnectionUtilities.isOnline(activity)) {
AccountRegistration accountRegistration = new AccountRegistration(
new Login(new Cookies()),
new Vulcan(),
email, password, symbol);
if (ConnectionUtilities.isOnline(activity.get())) {
VulcanSynchronization vulcanSynchronization = new VulcanSynchronization(new LoginSession());
DaoSession daoSession = ((WulkanowyApp) activity.getApplication()).getDaoSession();
DaoSession daoSession = ((WulkanowyApp) activity.get().getApplication()).getDaoSession();
try {
publishProgress("1", activity.getResources().getString(R.string.step_connecting));
String certificate = accountRegistration.connect();
publishProgress("1", activity.get().getResources().getString(R.string.step_connecting));
vulcanSynchronization.firstLoginConnectStep(email, password, symbol);
publishProgress("2", activity.getResources().getString(R.string.step_login));
LoginSession loginSession = accountRegistration.login(activity, daoSession, certificate);
publishProgress("2", activity.get().getResources().getString(R.string.step_login));
vulcanSynchronization.firstLoginSignInStep(activity.get(), daoSession);
publishProgress("3", activity.getResources().getString(R.string.step_synchronization));
VulcanSynchronization vulcanSynchronization = new VulcanSynchronization(loginSession);
publishProgress("3", activity.get().getResources().getString(R.string.step_synchronization));
vulcanSynchronization.syncSubjectsAndGrades();
} catch (BadCredentialsException e) {
@ -92,7 +86,8 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
return R.string.login_denied_text;
}
accountRegistration.scheduleSynchronization(activity);
GradeJob gradeJob = new GradeJob();
gradeJob.scheduledJob(activity.get());
return R.string.login_accepted_text;
@ -103,7 +98,7 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
@Override
protected void onProgressUpdate(String... progress) {
showText.setText(progress[0] + "/3 - " + progress[1] + "...");
showText.get().setText(String.format("%1$s/3 - %2$s...", progress[0], progress[1]));
}
@Override
@ -113,33 +108,32 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
switch (messageID) {
// if success
case R.string.login_accepted_text:
Intent intent = new Intent(activity, DashboardActivity.class);
activity.finish();
activity.startActivity(intent);
Intent intent = new Intent(activity.get(), DashboardActivity.class);
activity.get().finish();
activity.get().startActivity(intent);
break;
// if bad credentials entered
case R.string.login_bad_credentials_text:
EditText passwordView = activity.findViewById(R.id.password);
passwordView.setError(activity.getString(R.string.error_incorrect_password));
EditText passwordView = activity.get().findViewById(R.id.password);
passwordView.setError(activity.get().getString(R.string.error_incorrect_password));
passwordView.requestFocus();
break;
// if no permission
case R.string.error_bad_account_permission:
// Change to visible symbol input view
TextInputLayout symbolLayout = activity.findViewById(R.id.to_symbol_input_layout);
TextInputLayout symbolLayout = activity.get().findViewById(R.id.to_symbol_input_layout);
symbolLayout.setVisibility(View.VISIBLE);
EditText symbolView = activity.findViewById(R.id.symbol);
symbolView.setError(activity.getString(R.string.error_bad_account_permission));
EditText symbolView = activity.get().findViewById(R.id.symbol);
symbolView.setError(activity.get().getString(R.string.error_bad_account_permission));
symbolView.requestFocus();
break;
default:
Snackbar
.make(activity.findViewById(R.id.coordinatorLayout), messageID, Snackbar.LENGTH_LONG)
.show();
Snackbar.make(activity.get().findViewById(R.id.coordinatorLayout),
messageID, Snackbar.LENGTH_LONG).show();
break;
}
}
@ -153,33 +147,33 @@ public class LoginTask extends AsyncTask<Void, String, Integer> {
* Shows the progress UI and hides the login form.
*/
public void showProgress(final boolean show) {
loginFormView = activity.findViewById(R.id.login_form);
progressView = activity.findViewById(R.id.login_progress);
loginFormView = new WeakReference<>(activity.get().findViewById(R.id.login_form));
progressView = new WeakReference<>(activity.get().findViewById(R.id.login_progress));
int animTime = activity.getResources().getInteger(android.R.integer.config_shortAnimTime);
int animTime = activity.get().getResources().getInteger(android.R.integer.config_shortAnimTime);
changeLoginFormVisibility(show, animTime);
changeProgressVisibility(show, animTime);
}
private void changeLoginFormVisibility(final boolean show, final int animTime) {
loginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
loginFormView.animate().setDuration(animTime).alpha(
loginFormView.get().setVisibility(show ? View.GONE : View.VISIBLE);
loginFormView.get().animate().setDuration(animTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
loginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
loginFormView.get().setVisibility(show ? View.GONE : View.VISIBLE);
}
});
}
private void changeProgressVisibility(final boolean show, final int animTime) {
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
progressView.animate().setDuration(animTime).alpha(
progressView.get().setVisibility(show ? View.VISIBLE : View.GONE);
progressView.get().animate().setDuration(animTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
progressView.setVisibility(show ? View.VISIBLE : View.GONE);
progressView.get().setVisibility(show ? View.VISIBLE : View.GONE);
}
});
}

View File

@ -1,53 +0,0 @@
package io.github.wulkanowy.activity.splash;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.widget.Toast;
import io.github.wulkanowy.R;
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
import io.github.wulkanowy.activity.login.LoginActivity;
import io.github.wulkanowy.services.jobs.GradeJob;
import io.github.wulkanowy.utilities.ConnectionUtilities;
public class LoadingTask extends AsyncTask<Void, Void, Boolean> {
private Context context;
LoadingTask(Context context) {
this.context = context;
}
@Override
protected Boolean doInBackground(Void... voids) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return ConnectionUtilities.isOnline(context);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (!result) {
Toast.makeText(context, R.string.noInternet_text, Toast.LENGTH_LONG).show();
}
if (context.getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("userId", 0) == 0) {
Intent intent = new Intent(context, LoginActivity.class);
context.startActivity(intent);
} else {
GradeJob gradesSync = new GradeJob();
gradesSync.scheduledJob(context);
Intent intent = new Intent(context, DashboardActivity.class);
context.startActivity(intent);
}
}
}

View File

@ -1,11 +1,17 @@
package io.github.wulkanowy.activity.splash;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import io.github.wulkanowy.BuildConfig;
import io.github.wulkanowy.R;
import io.github.wulkanowy.activity.dashboard.DashboardActivity;
import io.github.wulkanowy.activity.login.LoginActivity;
import io.github.wulkanowy.services.jobs.GradeJob;
public class SplashActivity extends AppCompatActivity {
@ -15,8 +21,26 @@ public class SplashActivity extends AppCompatActivity {
setContentView(R.layout.activity_splash);
TextView versionName = findViewById(R.id.rawText);
versionName.setText(getText(R.string.version_text) + BuildConfig.VERSION_NAME);
versionName.setText(getString(R.string.version_text, BuildConfig.VERSION_NAME));
new LoadingTask(this).execute();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
executeOnRunApp();
}
}, 500);
}
private void executeOnRunApp() {
if (getSharedPreferences("LoginData", Context.MODE_PRIVATE).getLong("userId", 0) == 0) {
Intent intent = new Intent(this, LoginActivity.class);
startActivity(intent);
} else {
GradeJob gradesSync = new GradeJob();
gradesSync.scheduledJob(this);
Intent intent = new Intent(this, DashboardActivity.class);
startActivity(intent);
}
}
}

View File

@ -18,9 +18,9 @@ public abstract class EntitiesCompare {
List<Grade> lastList = new ArrayList<>();
for (Grade grade : addedOrUpdatedGradeList) {
grade.setIsNew(true);
if (oldList.size() != 0) {
grade.setRead(false);
grade.setIsNew(true);
}
updatedList.add(grade);
}

View File

@ -12,13 +12,11 @@ public class Safety extends Scrambler {
public String encrypt(String email, String plainText, Context context) throws CryptoException, UnsupportedOperationException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
loadKeyStore();
generateNewKey(email, context);
return encryptString(email, plainText);
} else {
if (RootUtilities.isRooted()) {
if (!RootUtilities.isRooted()) {
return new String(Base64.encode(plainText.getBytes(), Base64.DEFAULT));
} else {
Log.e(Scrambler.DEBUG_TAG, "Password store in this devices isn't safe because is rooted");
@ -30,7 +28,6 @@ public class Safety extends Scrambler {
public String decrypt(String email, String encryptedText) throws CryptoException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
loadKeyStore();
return decryptString(email, encryptedText);
} else {

View File

@ -36,7 +36,7 @@ public class Scrambler {
private KeyStore keyStore;
public void loadKeyStore() throws CryptoException {
protected void loadKeyStore() throws CryptoException {
try {
keyStore = KeyStore.getInstance(ANDROID_KEYSTORE);

View File

@ -5,14 +5,18 @@ import android.util.Log;
import java.io.IOException;
import io.github.wulkanowy.api.Cookies;
import io.github.wulkanowy.api.Vulcan;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
import io.github.wulkanowy.api.login.Login;
import io.github.wulkanowy.api.login.LoginErrorException;
import io.github.wulkanowy.api.login.NotLoggedInErrorException;
import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.services.jobs.VulcanJobHelper;
import io.github.wulkanowy.services.synchronisation.AccountAuthorization;
import io.github.wulkanowy.services.synchronisation.CurrentAccountLogin;
import io.github.wulkanowy.services.synchronisation.FirstAccountLogin;
import io.github.wulkanowy.services.synchronisation.GradesSynchronisation;
import io.github.wulkanowy.services.synchronisation.SubjectsSynchronisation;
@ -20,38 +24,67 @@ public class VulcanSynchronization {
private LoginSession loginSession;
private FirstAccountLogin firstAccountLogin;
private String certificate;
public VulcanSynchronization(LoginSession loginSession) {
this.loginSession = loginSession;
}
public void firstLoginConnectStep(String email, String password, String symbol)
throws BadCredentialsException, IOException {
firstAccountLogin = new FirstAccountLogin(new Login(new Cookies()), new Vulcan(), email, password, symbol);
certificate = firstAccountLogin.connect();
}
public void firstLoginSignInStep(Context context, DaoSession daoSession)
throws NotLoggedInErrorException, AccountPermissionException, IOException, CryptoException {
if (firstAccountLogin != null && certificate != null) {
loginSession = firstAccountLogin.login(context, daoSession, certificate);
} else {
Log.e(VulcanJobHelper.DEBUG_TAG, "Before first login, should call firstLoginConnectStep",
new UnsupportedOperationException());
}
}
public void loginCurrentUser(Context context, DaoSession daoSession, Vulcan vulcan)
throws CryptoException, BadCredentialsException, AccountPermissionException, LoginErrorException, IOException {
AccountAuthorization accountAuthorization = new AccountAuthorization(context, daoSession, vulcan);
loginSession = accountAuthorization.loginCurrentUser();
CurrentAccountLogin currentAccountLogin = new CurrentAccountLogin(context, daoSession, vulcan);
loginSession = currentAccountLogin.loginCurrentUser();
}
public boolean syncGrades() {
GradesSynchronisation gradesSynchronisation = new GradesSynchronisation();
try {
gradesSynchronisation.sync(loginSession);
return true;
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "Synchronisation of grades failed", e);
if (loginSession != null) {
GradesSynchronisation gradesSynchronisation = new GradesSynchronisation();
try {
gradesSynchronisation.sync(loginSession);
return true;
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "Synchronisation of grades failed", e);
return false;
}
} else {
Log.e(VulcanJobHelper.DEBUG_TAG, "Before synchronization, should login user to log",
new UnsupportedOperationException());
return false;
}
}
public boolean syncSubjectsAndGrades() {
SubjectsSynchronisation subjectsSynchronisation = new SubjectsSynchronisation();
try {
subjectsSynchronisation.sync(loginSession);
syncGrades();
return true;
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "Synchronisation of subjects failed", e);
if (loginSession != null) {
SubjectsSynchronisation subjectsSynchronisation = new SubjectsSynchronisation();
try {
subjectsSynchronisation.sync(loginSession);
syncGrades();
return true;
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "Synchronisation of subjects failed", e);
return false;
}
} else {
Log.e(VulcanJobHelper.DEBUG_TAG, "Before synchronization, should login user to log",
new UnsupportedOperationException());
return false;
}
}

View File

@ -21,11 +21,11 @@ import io.github.wulkanowy.services.VulcanSynchronization;
public class GradeJob extends VulcanJobHelper {
public static final String UNIQUE_TAG = "GradesSync34512";
private static final String UNIQUE_TAG = "GradesSync34512";
public static final int DEFAULT_INTERVAL_START = 60 * 50;
private static final int DEFAULT_INTERVAL_START = 60 * 50;
public static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + (60 * 10);
private static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + (60 * 10);
@Override
protected Job createJob(FirebaseJobDispatcher dispatcher) {

View File

@ -21,11 +21,11 @@ import io.github.wulkanowy.services.VulcanSynchronization;
public class SubjectJob extends VulcanJobHelper {
public static final String UNIQUE_TAG = "SubjectsSync34512";
private static final String UNIQUE_TAG = "SubjectsSync34512";
public static final int DEFAULT_INTERVAL_START = 0;
private static final int DEFAULT_INTERVAL_START = 0;
public static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + 10;
private static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + 10;
@Override
protected Job createJob(FirebaseJobDispatcher dispatcher) {

View File

@ -7,6 +7,7 @@ import com.firebase.jobdispatcher.JobParameters;
import com.firebase.jobdispatcher.JobService;
import java.io.IOException;
import java.lang.ref.WeakReference;
import io.github.wulkanowy.api.login.AccountPermissionException;
import io.github.wulkanowy.api.login.BadCredentialsException;
@ -15,35 +16,47 @@ import io.github.wulkanowy.security.CryptoException;
public abstract class VulcanService extends JobService {
private SyncTask syncTask = new SyncTask();
private SyncTask syncTask;
@Override
public boolean onStartJob(JobParameters params) {
Log.d(VulcanJobHelper.DEBUG_TAG, "Wulkanowy services start");
syncTask.execute(params);
syncTask = new SyncTask(this, params);
syncTask.execute();
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.e(VulcanJobHelper.DEBUG_TAG, "Wulkanowy serives stop");
syncTask.cancel(true);
Log.e(VulcanJobHelper.DEBUG_TAG, "Wulkanowy services stop");
if (syncTask != null) {
syncTask.cancel(true);
}
return true;
}
public abstract void workToBePerformed() throws CryptoException, BadCredentialsException,
NotLoggedInErrorException, AccountPermissionException, IOException;
private class SyncTask extends AsyncTask<JobParameters, Void, Void> {
private static class SyncTask extends AsyncTask<Void, Void, Void> {
private JobParameters jobParameters;
private WeakReference<VulcanService> vulcanService;
public SyncTask(VulcanService vulcanService, JobParameters jobParameters) {
this.jobParameters = jobParameters;
this.vulcanService = new WeakReference<>(vulcanService);
}
@Override
protected Void doInBackground(JobParameters... params) {
protected Void doInBackground(Void... voids) {
try {
workToBePerformed();
vulcanService.get().workToBePerformed();
} catch (Exception e) {
Log.e(VulcanJobHelper.DEBUG_TAG, "User logging in the background failed", e);
} finally {
jobFinished(params[0], false);
vulcanService.get().jobFinished(jobParameters, false);
}
return null;
}

View File

@ -17,7 +17,7 @@ import io.github.wulkanowy.security.Safety;
import io.github.wulkanowy.services.LoginSession;
import io.github.wulkanowy.services.jobs.VulcanJobHelper;
public class AccountAuthorization {
public class CurrentAccountLogin {
private final Context context;
@ -25,7 +25,7 @@ public class AccountAuthorization {
private final Vulcan vulcan;
public AccountAuthorization(Context context, DaoSession daoSession, Vulcan vulcan) {
public CurrentAccountLogin(Context context, DaoSession daoSession, Vulcan vulcan) {
this.context = context;
this.daoSession = daoSession;
this.vulcan = vulcan;

View File

@ -16,9 +16,8 @@ import io.github.wulkanowy.dao.entities.DaoSession;
import io.github.wulkanowy.security.CryptoException;
import io.github.wulkanowy.security.Safety;
import io.github.wulkanowy.services.LoginSession;
import io.github.wulkanowy.services.jobs.GradeJob;
public class AccountRegistration {
public class FirstAccountLogin {
private final Login login;
@ -31,7 +30,7 @@ public class AccountRegistration {
private final String symbol;
public AccountRegistration(Login login, Vulcan vulcan, String email, String password, String symbol) {
public FirstAccountLogin(Login login, Vulcan vulcan, String email, String password, String symbol) {
this.login = login;
this.vulcan = vulcan;
this.email = email;
@ -74,9 +73,4 @@ public class AccountRegistration {
.setUserId(userId)
.setDaoSession(daoSession);
}
public void scheduleSynchronization(Context context) {
GradeJob gradesSync = new GradeJob();
gradesSync.scheduledJob(context);
}
}

View File

@ -9,7 +9,11 @@ public abstract class ConnectionUtilities {
public static boolean isOnline(Context context) {
ConnectivityManager connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnectedOrConnecting();
if (connectivityManager != null) {
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnectedOrConnecting();
} else {
return false;
}
}
}

View File

@ -8,8 +8,6 @@ import java.io.File;
abstract public class RootUtilities {
public static boolean isRooted() {
String buildTags = Build.TAGS;
if (buildTags != null && buildTags.contains("test-keys")) {
return true;
@ -23,7 +21,6 @@ abstract public class RootUtilities {
} catch (Exception e1) {
// ignore
}
return canExecuteCommand("/system/xbin/which su")
|| canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
}
@ -36,7 +33,6 @@ abstract public class RootUtilities {
} catch (Exception e) {
executedSuccesfully = false;
}
return executedSuccesfully;
}
}

View File

@ -5,6 +5,18 @@
android:layout_height="match_parent"
tools:context="io.github.wulkanowy.activity.dashboard.grades.GradesFragment">
<RelativeLayout
android:id="@+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/grade_swipe_refresh"
android:layout_width="match_parent"
@ -15,18 +27,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
<RelativeLayout
android:id="@+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@ -8,7 +8,7 @@
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:foreground="?attr/selectableItemBackgroundBorderless"
card_view:cardElevation="0dp">
@ -19,8 +19,7 @@
android:layout_marginEnd="7dp"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:layout_marginStart="7dp"
android:layout_marginTop="7dp">
android:layout_marginStart="7dp">
<TextView
android:id="@+id/grade_text"

View File

@ -32,7 +32,7 @@
<string name="noInternet_text">Brak połączenia z internetem</string>
<string name="root_failed_text">To urządzenie posiada posiada podwyższone uprawnienia (root). Automatyczne logowanie zosatło wyłączone.</string>
<string name="encrypt_failed_text">Szyfrowanie nie powiodło się. Automatyczne logowanie zostało wyłączone</string>
<string name="version_text">Wersja\u0020</string>
<string name="version_text">Wersja %1$s</string>
<string name="dialog_description_text">Opis</string>
<string name="dialog_weight_text">Waga</string>
<string name="noDescription_text">Brak opisu</string>

View File

@ -23,29 +23,33 @@
<string name="action_create_account">No account yet? Create one</string>
<string name="action_forgot_password">Forgot password?</string>
<string name="color_black_text">Black</string>
<string name="color_red_text">Red</string>
<string name="color_blue_text">Blue</string>
<string name="color_green_text">Green</string>
<string name="noColor_text">No color</string>
<string name="activity_dashboard_text">Dashboard Activity</string>
<string name="dashboard_text">Dashboard</string>
<string name="grades_text">Grades</string>
<string name="attendance_text">Attendance</string>
<string name="lessonplan_text">Lesson Plan</string>
<string name="settings_text">Settings</string>
<string name="noInternet_text">No internet connection</string>
<string name="root_failed_text">This device is rooted. Automatic login has been disabled</string>
<string name="encrypt_failed_text">Encryption failed. Automatic login has been disabled</string>
<string name="version_text">Version\u0020</string>
<string name="version_text">Version %1$s</string>
<string name="refresh_error_text">An error occurred while refreshing the content.</string>
<string name="dialog_description_text">Description</string>
<string name="dialog_weight_text">Weight</string>
<string name="noDescription_text">No description</string>
<string name="dialog_teacher_text">Teacher</string>
<string name="dialog_date_text">Date</string>
<string name="dialog_color_text">Color</string>
<string name="color_black_text">Black</string>
<string name="color_red_text">Red</string>
<string name="color_blue_text">Blue</string>
<string name="color_green_text">Green</string>
<string name="noColor_text">No color</string>
<string name="dialog_close">Close</string>
<string name="refresh_error_text">An error occurred while refreshing the content.</string>
<string name="snackbar_no_grades">No new grades</string>
<string name="snackbar_new_grade">Number of new grades: %1$d</string>

View File

@ -46,16 +46,28 @@ public class EntitiesCompareTest extends EntitiesCompare {
}
@Test
public void testCompareNewGradePositive() {
public void testCompareNewGradeEmptyOldList() {
newList.add(grade1);
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertEquals(true, (updatedList.get(0)).getIsNew());
Assert.assertFalse(updatedList.get(0).getIsNew());
}
@Test
public void testCompareNewGradePositive() {
newList.add(grade1);
newList.add(grade2);
oldList.add(grade2);
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertFalse(updatedList.get(0).getIsNew());
Assert.assertTrue(updatedList.get(1).getIsNew());
}
@Test
public void testCompareNewGradeNegative() {
@ -66,8 +78,8 @@ public class EntitiesCompareTest extends EntitiesCompare {
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertEquals(false, (updatedList.get(0)).getIsNew());
Assert.assertEquals(false, (updatedList.get(1)).getIsNew());
Assert.assertFalse(updatedList.get(0).getIsNew());
Assert.assertFalse(updatedList.get(1).getIsNew());
}
@Test
@ -77,4 +89,18 @@ public class EntitiesCompareTest extends EntitiesCompare {
Assert.assertEquals(new ArrayList<>(), updatedList);
}
@Test
public void testCompareReadGradeTest() {
newList.add(grade1);
newList.add(grade2);
oldList.add(grade2.setRead(true));
List<Grade> updatedList = EntitiesCompare.compareGradeList(newList, oldList);
Assert.assertTrue(updatedList.get(0).getRead());
Assert.assertFalse(updatedList.get(0).getIsNew());
Assert.assertFalse(updatedList.get(1).getRead());
Assert.assertTrue(updatedList.get(1).getIsNew());
}
}