diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..a04a17570a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,8 @@ +[submodule "DBFlowORM"] + path = DBFlowORM + url = https://github.com/EyeSeeTea/DBFlow.git + +[submodule "sdk"] + path = sdk + url = https://github.com/EyeSeeTea/dhis2-android-sdk.git + branch = 2.22_EyeSeeTea diff --git a/DBFlowORM b/DBFlowORM new file mode 160000 index 0000000000..d297a68fcb --- /dev/null +++ b/DBFlowORM @@ -0,0 +1 @@ +Subproject commit d297a68fcb215c4ad9fbb980cf2d1cb20abf4a09 diff --git a/README.md b/README.md index 4989ca6a28..e148f176a6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,6 @@ We’d love to hear your thoughts on the initiative in general, improvements, ne This app is compatible with SDK API version 15+. -## License +## License This app is licensed under GPLv3. Please respect the terms of that license. diff --git a/app/build.gradle b/app/build.gradle index d68cb14e26..142855d544 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,10 +1,12 @@ buildscript { repositories { maven { url 'https://maven.fabric.io/public' } + mavenCentral() } dependencies { classpath 'io.fabric.tools:gradle:1.+' + classpath 'com.github.dcendents:android-maven-plugin:1.2' } } apply plugin: 'com.android.application' @@ -13,17 +15,17 @@ apply plugin: 'io.fabric' repositories { maven { url 'https://maven.fabric.io/public' } } -apply plugin: 'com.neenbedankt.android-apt' +//apply plugin: 'com.neenbedankt.android-apt' android { compileSdkVersion 21 buildToolsVersion "22.0.1" defaultConfig { - applicationId 'org.eyeseetea.pictureapp' + applicationId 'org.eyeseetea.surveillance_kh' minSdkVersion 15 targetSdkVersion 21 - versionCode 6 - versionName "3.0" + versionCode 1 + versionName "1.0" multiDexEnabled true testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -39,29 +41,47 @@ android { } //TODO This config is related to a known issue: http://stackoverflow.com/questions/20827885/android-studio-0-4-duplicate-files-copied-in-apk-meta-inf-license-txt packagingOptions { - exclude 'LICENSE.txt' + // gradle requires to exclude these files both + // with .txt extension and without. + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/LICENSE.txt' + + // without .txt + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' } productFlavors { } + + lintOptions { + disable 'RtlSymmetry', 'RtlHardcoded' + } } dependencies { + apply plugin: 'android-apt' + apply plugin: 'com.github.dcendents.android-maven' + compile 'com.android.support:support-v4:21.1.1' compile 'com.android.support:appcompat-v7:21.1.1' compile 'com.android.support:support-annotations:21.1.0' // App dependencies - compile 'com.github.satyan:sugar:1.3' compile 'com.opencsv:opencsv:3.3' compile 'com.google.android.gms:play-services:8.1.0' compile 'com.google.guava:guava:18.0' compile 'com.squareup.okhttp:okhttp:2.2.0' compile 'com.googlecode.libphonenumber:libphonenumber:7.0.9' compile 'com.android.support:multidex:1.0.1' - apt 'com.raizlabs.android:DBFlow-Compiler:2.2.1' - compile 'com.raizlabs.android:DBFlow-Core:2.2.1' - compile 'com.raizlabs.android:DBFlow:2.2.1' +// apt 'com.raizlabs.android:DBFlow-Compiler:2.2.1' +// compile 'com.raizlabs.android:DBFlow-Core:2.2.1' +// compile 'com.raizlabs.android:DBFlow:2.2.1' + apt project(':DBFlowORM:DBFlow-Compiler') + compile project(':DBFlowORM:DBFlow-Core') + compile project(':DBFlowORM:DBFlow') + compile project(':sdk:app') + compile('com.crashlytics.sdk.android:crashlytics:2.5.1@aar') { transitive = true; } diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/CreateSurveyEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/CreateSurveyEspressoTest.java index 9127c9437a..0d4956f94b 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/CreateSurveyEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/CreateSurveyEspressoTest.java @@ -1,116 +1,116 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; - -import org.eyeseetea.malariacare.CreateSurveyActivity; -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.database.utils.Session; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.intent.Intents.intended; -import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertNotNull; - -/** - * - */ -@RunWith(AndroidJUnit4.class) -public class CreateSurveyEspressoTest extends MalariaEspressoTest{ - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - CreateSurveyActivity.class); - - @BeforeClass - public static void init(){ - populateData(InstrumentationRegistry.getTargetContext().getAssets()); - mockSurveys(1); - } - - @Before - public void setup(){ - super.setup(); - } - - @Test - public void form_views() { - onView(withId(R.id.org_unit)).check(matches(isDisplayed())); - onView(withId(R.id.program)).check(matches(isDisplayed())); - onView(withId(R.id.create_form_button)).check(matches(isDisplayed())); - } - - @Test - public void no_selection_no_survey(){ - - //WHEN - onView(withId(R.id.create_form_button)).perform(click()); - - //THEN - onView(withText("Missing selection")).check(matches(isDisplayed())).perform(click()); - } - - @Test - public void select_data_create_survey(){ - - //WHEN - onView(withId(R.id.org_unit)).perform(click()); - onView(withText("Health Facility 2")).perform(click()); - - onView(withId(R.id.program)).perform(click()); - onView(withText("Clinical Case Management")).perform(click()); - - onView(withId(R.id.create_form_button)).perform(click()); - - //THEN - intended(anyIntent()); - assertNotNull(Session.getSurvey()); - } - - @Test - public void select_repeated_data_no_survey(){ - - //WHEN - onView(withId(R.id.org_unit)).perform(click()); - onView(withText("Health Facility 0")).perform(click()); - - onView(withId(R.id.program)).perform(click()); - onView(withText("Clinical Case Management")).perform(click()); - - onView(withId(R.id.create_form_button)).perform(click()); - - //THEN - onView(withText("Existing Survey")).check(matches(isDisplayed())).perform(click()); - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.support.test.InstrumentationRegistry; +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +// +//import org.eyeseetea.malariacare.CreateSurveyActivity; +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.database.utils.Session; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.intent.Intents.intended; +//import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertNotNull; +// +///** +// * +// */ +//@RunWith(AndroidJUnit4.class) +//public class CreateSurveyEspressoTest extends MalariaEspressoTest{ +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// CreateSurveyActivity.class); +// +// @BeforeClass +// public static void init(){ +// populateData(InstrumentationRegistry.getTargetContext().getAssets()); +// mockSurveys(1); +// } +// +// @Before +// public void setup(){ +// super.setup(); +// } +// +// @Test +// public void form_views() { +// onView(withId(R.id.org_unit)).check(matches(isDisplayed())); +// onView(withId(R.id.program)).check(matches(isDisplayed())); +// onView(withId(R.id.create_form_button)).check(matches(isDisplayed())); +// } +// +// @Test +// public void no_selection_no_survey(){ +// +// //WHEN +// onView(withId(R.id.create_form_button)).perform(click()); +// +// //THEN +// onView(withText("Missing selection")).check(matches(isDisplayed())).perform(click()); +// } +// +// @Test +// public void select_data_create_survey(){ +// +// //WHEN +// onView(withId(R.id.org_unit)).perform(click()); +// onView(withText("Health Facility 2")).perform(click()); +// +// onView(withId(R.id.program)).perform(click()); +// onView(withText("Clinical Case Management")).perform(click()); +// +// onView(withId(R.id.create_form_button)).perform(click()); +// +// //THEN +// intended(anyIntent()); +// assertNotNull(Session.getSurvey()); +// } +// +// @Test +// public void select_repeated_data_no_survey(){ +// +// //WHEN +// onView(withId(R.id.org_unit)).perform(click()); +// onView(withText("Health Facility 0")).perform(click()); +// +// onView(withId(R.id.program)).perform(click()); +// onView(withText("Clinical Case Management")).perform(click()); +// +// onView(withId(R.id.create_form_button)).perform(click()); +// +// //THEN +// onView(withText("Existing Survey")).check(matches(isDisplayed())).perform(click()); +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/DashboardActivityExpressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/DashboardActivityExpressoTest.java index f7b8b1d621..a268b14048 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/DashboardActivityExpressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/DashboardActivityExpressoTest.java @@ -1,181 +1,181 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.app.Instrumentation; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.util.Log; - -import org.eyeseetea.malariacare.DashboardActivity; -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.SurveyActivity; -import org.eyeseetea.malariacare.fragments.DashboardUnsentFragment; -import org.eyeseetea.malariacare.services.SurveyService; -import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.swipeRight; -import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; -import static android.support.test.espresso.intent.Intents.intended; -import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; -import static android.support.test.espresso.matcher.ViewMatchers.withChild; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertEquals; -import static org.eyeseetea.malariacare.test.utils.MalariaEspressoActions.waitId; -import static org.hamcrest.Matchers.allOf; - -/** - * - */ -@RunWith(AndroidJUnit4.class) -public class DashboardActivityExpressoTest extends MalariaEspressoTest{ - - private static String TAG=".DDActivityExpressoTest"; - - private final static int _EXPECTED_SURVEYS=2; - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - DashboardActivity.class); - - @BeforeClass - public static void init(){ - populateData(InstrumentationRegistry.getTargetContext().getAssets()); - mockSessionSurvey(_EXPECTED_SURVEYS, 1, 0); - } - - @Before - public void registerIntentServiceIdlingResource(){ - Log.i(TAG,"---BEFORE---"); - super.setup(); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); - Espresso.registerIdlingResources(idlingResource); - } - - @After - public void unregisterIntentServiceIdlingResource(){ - Log.i(TAG,"---AFTER---"); - Espresso.unregisterIdlingResources(idlingResource); - unregisterSurveyReceiver(); - getActivityInstance().finish(); - } - - @Test - public void form_views() { - Log.i(TAG,"------form_views------"); - onView(isRoot()).perform(waitId(R.id.plusButton, 3000)); - } - - @Test - public void survey_selected(){ - Log.i(TAG,"------survey_selected------"); - //WHEN - whenAssessmentSelected("Health Facility 1", "ICM"); - - //THEN - assertEquals(SurveyActivity.class, getActivityInstance().getClass()); - } - - @Test - public void new_survey_launches_intent(){ - Log.i(TAG,"------new_survey_launches_intent------"); - //WHEN - onView(withId(R.id.plusButton)).perform(click()); - - //THEN - intended(anyIntent()); - } - - @Test - public void delete_survey(){ - Log.i(TAG,"------delete_survey------"); - //WHEN - whenAssessmentSwipeAndOk("Health Facility 0", "ICM"); - - //THEN: Check font size has properly changed - checkAssessmentDoesntExist("Health Facility 0", "ICM"); - } - - /** - * From Dashboard delete survey - * @param orgUnit orgUnit of the survey we want to delete - * @param program program of the survey we want to delete - */ - private void whenAssessmentSwipeAndOk(String orgUnit, String program) { - onView(allOf(withId(R.id.assessment_row), - withChild(allOf( - withChild(allOf(withId(R.id.facility), withText(orgUnit))), - withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))) - .perform(swipeRight()); - - //Espresso is NOT waiting for the SwipeListener to finish, thus some forced waiting is required - try { - Thread.sleep(1000); - onView(withText(android.R.string.ok)).perform(click()); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - - /** - * From Dashboard access survey - * @param orgUnit orgUnit of the survey we want to access - * @param program program of the survey we want to access - */ - private void whenAssessmentSelected(String orgUnit, String program) { - onView(allOf(withId(R.id.assessment_row), - withChild(allOf( - withChild(allOf(withId(R.id.facility), withText(orgUnit))), - withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))) - .perform(click()); - } - - private void checkAssessmentDoesntExist(String orgUnit, String program) { - onView(allOf(withId(R.id.assessment_row), - withChild(allOf( - withChild(allOf(withId(R.id.facility), withText(orgUnit))), - withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))).check(doesNotExist()); - } - - - private void unregisterSurveyReceiver(){ - try{ - DashboardActivity dashboardActivity =(DashboardActivity)getActivityInstance(); - DashboardUnsentFragment dashboardUnsentFragment =(DashboardUnsentFragment) dashboardActivity.getFragmentManager().findFragmentById(R.id.dashboard_details_fragment); - dashboardUnsentFragment.unregisterSurveysReceiver(); - }catch(Exception ex){ - Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); - } - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.app.Instrumentation; +//import android.support.test.InstrumentationRegistry; +//import android.support.test.espresso.Espresso; +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.util.Log; +// +//import org.eyeseetea.malariacare.DashboardActivity; +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.SurveyActivity; +//import org.eyeseetea.malariacare.fragments.DashboardUnsentFragment; +//import org.eyeseetea.malariacare.services.SurveyService; +//import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.action.ViewActions.swipeRight; +//import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; +//import static android.support.test.espresso.intent.Intents.intended; +//import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; +//import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +//import static android.support.test.espresso.matcher.ViewMatchers.withChild; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertEquals; +//import static org.eyeseetea.malariacare.test.utils.MalariaEspressoActions.waitId; +//import static org.hamcrest.Matchers.allOf; +// +///** +// * +// */ +//@RunWith(AndroidJUnit4.class) +//public class DashboardActivityExpressoTest extends MalariaEspressoTest{ +// +// private static String TAG=".DDActivityExpressoTest"; +// +// private final static int _EXPECTED_SURVEYS=2; +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// DashboardActivity.class); +// +// @BeforeClass +// public static void init(){ +// populateData(InstrumentationRegistry.getTargetContext().getAssets()); +// mockSessionSurvey(_EXPECTED_SURVEYS, 1, 0); +// } +// +// @Before +// public void registerIntentServiceIdlingResource(){ +// Log.i(TAG,"---BEFORE---"); +// super.setup(); +// Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); +// idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); +// Espresso.registerIdlingResources(idlingResource); +// } +// +// @After +// public void unregisterIntentServiceIdlingResource(){ +// Log.i(TAG,"---AFTER---"); +// Espresso.unregisterIdlingResources(idlingResource); +// unregisterSurveyReceiver(); +// getActivityInstance().finish(); +// } +// +// @Test +// public void form_views() { +// Log.i(TAG,"------form_views------"); +// onView(isRoot()).perform(waitId(R.id.plusButton, 3000)); +// } +// +// @Test +// public void survey_selected(){ +// Log.i(TAG,"------survey_selected------"); +// //WHEN +// whenAssessmentSelected("Health Facility 1", "ICM"); +// +// //THEN +// assertEquals(SurveyActivity.class, getActivityInstance().getClass()); +// } +// +// @Test +// public void new_survey_launches_intent(){ +// Log.i(TAG,"------new_survey_launches_intent------"); +// //WHEN +// onView(withId(R.id.plusButton)).perform(click()); +// +// //THEN +// intended(anyIntent()); +// } +// +// @Test +// public void delete_survey(){ +// Log.i(TAG,"------delete_survey------"); +// //WHEN +// whenAssessmentSwipeAndOk("Health Facility 0", "ICM"); +// +// //THEN: Check font size has properly changed +// checkAssessmentDoesntExist("Health Facility 0", "ICM"); +// } +// +// /** +// * From Dashboard delete survey +// * @param orgUnit orgUnit of the survey we want to delete +// * @param program program of the survey we want to delete +// */ +// private void whenAssessmentSwipeAndOk(String orgUnit, String program) { +// onView(allOf(withId(R.id.assessment_row), +// withChild(allOf( +// withChild(allOf(withId(R.id.facility), withText(orgUnit))), +// withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))) +// .perform(swipeRight()); +// +// //Espresso is NOT waiting for the SwipeListener to finish, thus some forced waiting is required +// try { +// Thread.sleep(1000); +// onView(withText(android.R.string.ok)).perform(click()); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// } +// +// /** +// * From Dashboard access survey +// * @param orgUnit orgUnit of the survey we want to access +// * @param program program of the survey we want to access +// */ +// private void whenAssessmentSelected(String orgUnit, String program) { +// onView(allOf(withId(R.id.assessment_row), +// withChild(allOf( +// withChild(allOf(withId(R.id.facility), withText(orgUnit))), +// withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))) +// .perform(click()); +// } +// +// private void checkAssessmentDoesntExist(String orgUnit, String program) { +// onView(allOf(withId(R.id.assessment_row), +// withChild(allOf( +// withChild(allOf(withId(R.id.facility), withText(orgUnit))), +// withChild(allOf(withId(R.id.survey_type), withText("- " + program))))))).check(doesNotExist()); +// } +// +// +// private void unregisterSurveyReceiver(){ +// try{ +// DashboardActivity dashboardActivity =(DashboardActivity)getActivityInstance(); +// DashboardUnsentFragment dashboardUnsentFragment =(DashboardUnsentFragment) dashboardActivity.getFragmentManager().findFragmentById(R.id.dashboard_details_fragment); +// dashboardUnsentFragment.unregisterSurveysReceiver(); +// }catch(Exception ex){ +// Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); +// } +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/LoginActivityEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/LoginActivityEspressoTest.java index 9d6aa51c10..ea0f38736c 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/LoginActivityEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/LoginActivityEspressoTest.java @@ -1,105 +1,105 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; - -import org.eyeseetea.malariacare.LoginActivity; -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.database.utils.Session; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; -import static android.support.test.espresso.action.ViewActions.typeText; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.intent.Intents.intended; -import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertNotNull; -import static org.eyeseetea.malariacare.test.utils.ErrorTextMatcher.hasErrorText; - -/** - * - */ -@RunWith(AndroidJUnit4.class) -public class LoginActivityEspressoTest extends MalariaEspressoTest{ - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - LoginActivity.class); - - - @BeforeClass - public static void init(){ - MalariaEspressoTest.init(); - } - - @Before - public void setup(){ - super.setup(); - } - - @Test - public void form_views() { - onView(withId(R.id.user)).check(matches(isDisplayed())); - onView(withId(R.id.password)).check(matches(isDisplayed())); - } - - @Test - public void login_bad_credentials(){ - //GIVEN - onView(withId(R.id.user)).perform(typeText("bad"), closeSoftKeyboard()); - onView(withId(R.id.password)).perform(typeText("bad"), closeSoftKeyboard()); - - //WHEN - onView(withId(R.id.email_sign_in_button)).perform(click()); - - //THEN - onView(withId(R.id.user)).check(matches(hasErrorText(res.getString(R.string.login_error_bad_credentials)))); - } - - @Test - @LargeTest - public void login_with_good_credentials(){ - //GIVEN - cleanDB(); - onView(withId(R.id.user)).perform(typeText("user"), closeSoftKeyboard()); - onView(withId(R.id.password)).perform(typeText("user"), closeSoftKeyboard()); - - //WHEN - onView(withId(R.id.email_sign_in_button)).perform(click()); - - //THEN - intended(anyIntent()); - assertNotNull(Session.getUser()); - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.test.suitebuilder.annotation.LargeTest; +// +//import org.eyeseetea.malariacare.LoginActivity; +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.database.utils.Session; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.Espresso.pressBack; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.action.ViewActions.closeSoftKeyboard; +//import static android.support.test.espresso.action.ViewActions.typeText; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.intent.Intents.intended; +//import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertNotNull; +//import static org.eyeseetea.malariacare.test.utils.ErrorTextMatcher.hasErrorText; +// +///** +// * +// */ +//@RunWith(AndroidJUnit4.class) +//public class LoginActivityEspressoTest extends MalariaEspressoTest{ +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// LoginActivity.class); +// +// +// @BeforeClass +// public static void init(){ +// MalariaEspressoTest.init(); +// } +// +// @Before +// public void setup(){ +// super.setup(); +// } +// +// @Test +// public void form_views() { +// onView(withId(R.id.user)).check(matches(isDisplayed())); +// onView(withId(R.id.password)).check(matches(isDisplayed())); +// } +// +// @Test +// public void login_bad_credentials(){ +// //GIVEN +// onView(withId(R.id.user)).perform(typeText("bad"), closeSoftKeyboard()); +// onView(withId(R.id.password)).perform(typeText("bad"), closeSoftKeyboard()); +// +// //WHEN +// onView(withId(R.id.email_sign_in_button)).perform(click()); +// +// //THEN +// onView(withId(R.id.user)).check(matches(hasErrorText(res.getString(R.string.login_error_bad_credentials)))); +// } +// +// @Test +// @LargeTest +// public void login_with_good_credentials(){ +// //GIVEN +// cleanDB(); +// onView(withId(R.id.user)).perform(typeText("user"), closeSoftKeyboard()); +// onView(withId(R.id.password)).perform(typeText("user"), closeSoftKeyboard()); +// +// //WHEN +// onView(withId(R.id.email_sign_in_button)).perform(click()); +// +// //THEN +// intended(anyIntent()); +// assertNotNull(Session.getUser()); +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/MalariaEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/MalariaEspressoTest.java index 81f990acec..899c65a977 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/MalariaEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/MalariaEspressoTest.java @@ -1,197 +1,197 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.app.Activity; -import android.app.Instrumentation; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.AssetManager; -import android.content.res.Resources; -import android.database.sqlite.SQLiteDatabase; -import android.preference.PreferenceManager; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; -import android.support.test.runner.lifecycle.Stage; -import android.util.Log; - -import org.eyeseetea.malariacare.database.model.Answer; -import org.eyeseetea.malariacare.database.model.CompositeScore; -import org.eyeseetea.malariacare.database.model.Header; -import org.eyeseetea.malariacare.database.model.Option; -import org.eyeseetea.malariacare.database.model.OrgUnit; -import org.eyeseetea.malariacare.database.model.Program; -import org.eyeseetea.malariacare.database.model.Question; -import org.eyeseetea.malariacare.database.model.Survey; -import org.eyeseetea.malariacare.database.model.Tab; -import org.eyeseetea.malariacare.database.model.User; -import org.eyeseetea.malariacare.database.model.Value; -import org.eyeseetea.malariacare.database.utils.PopulateDB; -import org.eyeseetea.malariacare.database.utils.Session; -import org.eyeseetea.malariacare.layout.adapters.dashboard.AssessmentUnsentAdapter; -import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; - -import java.util.Collection; -import java.util.List; - -import static android.support.test.espresso.matcher.ViewMatchers.withId; - -/** - * Created by arrizabalaga on 25/05/15. - */ -public class MalariaEspressoTest { - - protected IntentServiceIdlingResource idlingResource; - protected Resources res; - public static final String DATABASE_NAME="malariacare.db"; - public static final String DATABASE_FULL_PATH = "/data/data/org.eyeseetea.pictureapp/databases/"+DATABASE_NAME; - - public static void init(){ - cleanAll(); - } - - public void setup(){ - res = InstrumentationRegistry.getTargetContext().getResources(); - } - - public static void cleanAll(){ - cleanDB(); - cleanSession(); - cleanSettings(); - } - - public static void cleanSession(){ - Session.setUser(null); - Session.setSurvey(null); - Session.setAdapterUncompleted(null); - } - - public static void cleanDB(){ - if(!databaseExists()){ - return; - } - Question.deleteAll(Question.class); - CompositeScore.deleteAll(CompositeScore.class); - Option.deleteAll(Option.class); - Answer.deleteAll(Answer.class); - Header.deleteAll(Header.class); - Tab.deleteAll(Tab.class); - Program.deleteAll(Program.class); - OrgUnit.deleteAll(OrgUnit.class); - User.deleteAll(User.class); - Value.deleteAll(Value.class); - Survey.deleteAll(Survey.class); - } - - public static void cleanSettings(){ - Context activity = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity); - SharedPreferences.Editor editor = settings.edit(); - editor.clear(); - editor.commit(); - } - - - public static boolean databaseExists() { - SQLiteDatabase checkDB = null; - try { - checkDB = SQLiteDatabase.openDatabase(DATABASE_FULL_PATH, null, SQLiteDatabase.OPEN_READONLY); - checkDB.close(); - checkDB.releaseReference(); - } catch (Exception e) { - return false; - } - return checkDB != null; - } - - public static void populateData(AssetManager assetManager){ - try { - cleanAll(); - PopulateDB.populateDummyData(); - PopulateDB.populateDB(assetManager); - }catch(Exception ex){ - Log.e(".MalariaEspressoTest", ex.getMessage()); - } - } - - public static Survey mockSessionSurvey(int numSurvey, int numProgram, int select){ - List surveys=mockSurveys(numSurvey, numProgram); - Survey survey=surveys.get(select); - Session.setSurvey(survey); - return survey; - } - - public static void mockSessionSurvey(int num, int select){ - mockSessionSurvey(num, 0, select); - } - - public static List mockSurveys(int numOrgs, int numPrograms){ - List orgUnitList=OrgUnit.find(OrgUnit.class, null, null); - List programList=Program.find(Program.class,null,null); - Program program=programList.get(numPrograms); - User user =getSafeUser(); - - for(int i=0;i surveys= Survey.find(Survey.class, "user=?", user.getId().toString()); - Session.setAdapterUncompleted(new AssessmentUnsentAdapter(surveys, InstrumentationRegistry.getTargetContext())); - return surveys; - } - - public static List mockSurveys(int num){ - return mockSurveys(num, 0); - } - - private static User getSafeUser(){ - User user=Session.getUser(); - if(user!=null){ - return user; - } - user = new User("user", "user"); - user.save(); - Session.setUser(user); - return user; - } - - protected Activity getActivityInstance(){ - final Activity[] activity = new Activity[1]; - Instrumentation instrumentation=InstrumentationRegistry.getInstrumentation(); - instrumentation.waitForIdleSync(); - instrumentation.runOnMainSync(new Runnable() { - public void run() { - Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED); - if (resumedActivities.iterator().hasNext()) { - activity[0] = (Activity) resumedActivities.iterator().next(); - } - } - }); - - return activity[0]; - } - - protected static void clearSharedPreferences(){ - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext()); - sharedPreferences.edit().clear().commit(); - } - -} - +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.app.Activity; +//import android.app.Instrumentation; +//import android.content.Context; +//import android.content.SharedPreferences; +//import android.content.res.AssetManager; +//import android.content.res.Resources; +//import android.database.sqlite.SQLiteDatabase; +//import android.preference.PreferenceManager; +//import android.support.test.InstrumentationRegistry; +//import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; +//import android.support.test.runner.lifecycle.Stage; +//import android.util.Log; +// +//import org.eyeseetea.malariacare.database.model.Answer; +//import org.eyeseetea.malariacare.database.model.CompositeScore; +//import org.eyeseetea.malariacare.database.model.Header; +//import org.eyeseetea.malariacare.database.model.Option; +//import org.eyeseetea.malariacare.database.model.OrgUnit; +//import org.eyeseetea.malariacare.database.model.Program; +//import org.eyeseetea.malariacare.database.model.Question; +//import org.eyeseetea.malariacare.database.model.Survey; +//import org.eyeseetea.malariacare.database.model.Tab; +//import org.eyeseetea.malariacare.database.model.User; +//import org.eyeseetea.malariacare.database.model.Value; +//import org.eyeseetea.malariacare.database.utils.PopulateDB; +//import org.eyeseetea.malariacare.database.utils.Session; +//import org.eyeseetea.malariacare.layout.adapters.dashboard.AssessmentUnsentAdapter; +//import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; +// +//import java.util.Collection; +//import java.util.List; +// +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +// +///** +// * Created by arrizabalaga on 25/05/15. +// */ +//public class MalariaEspressoTest { +// +// protected IntentServiceIdlingResource idlingResource; +// protected Resources res; +// public static final String DATABASE_NAME="malariacare.db"; +// public static final String DATABASE_FULL_PATH = "/data/data/org.eyeseetea.pictureapp/databases/"+DATABASE_NAME; +// +// public static void init(){ +// cleanAll(); +// } +// +// public void setup(){ +// res = InstrumentationRegistry.getTargetContext().getResources(); +// } +// +// public static void cleanAll(){ +// cleanDB(); +// cleanSession(); +// cleanSettings(); +// } +// +// public static void cleanSession(){ +// Session.setUser(null); +// Session.setSurvey(null); +// Session.setAdapterUncompleted(null); +// } +// +// public static void cleanDB(){ +// if(!databaseExists()){ +// return; +// } +// Question.deleteAll(Question.class); +// CompositeScore.deleteAll(CompositeScore.class); +// Option.deleteAll(Option.class); +// Answer.deleteAll(Answer.class); +// Header.deleteAll(Header.class); +// Tab.deleteAll(Tab.class); +// Program.deleteAll(Program.class); +// OrgUnit.deleteAll(OrgUnit.class); +// User.deleteAll(User.class); +// Value.deleteAll(Value.class); +// Survey.deleteAll(Survey.class); +// } +// +// public static void cleanSettings(){ +// Context activity = InstrumentationRegistry.getInstrumentation().getTargetContext().getApplicationContext(); +// SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(activity); +// SharedPreferences.Editor editor = settings.edit(); +// editor.clear(); +// editor.commit(); +// } +// +// +// public static boolean databaseExists() { +// SQLiteDatabase checkDB = null; +// try { +// checkDB = SQLiteDatabase.openDatabase(DATABASE_FULL_PATH, null, SQLiteDatabase.OPEN_READONLY); +// checkDB.close(); +// checkDB.releaseReference(); +// } catch (Exception e) { +// return false; +// } +// return checkDB != null; +// } +// +// public static void populateData(AssetManager assetManager){ +// try { +// cleanAll(); +// PopulateDB.populateDummyData(); +// PopulateDB.populateDB(assetManager); +// }catch(Exception ex){ +// Log.e(".MalariaEspressoTest", ex.getMessage()); +// } +// } +// +// public static Survey mockSessionSurvey(int numSurvey, int numProgram, int select){ +// List surveys=mockSurveys(numSurvey, numProgram); +// Survey survey=surveys.get(select); +// Session.setSurvey(survey); +// return survey; +// } +// +// public static void mockSessionSurvey(int num, int select){ +// mockSessionSurvey(num, 0, select); +// } +// +// public static List mockSurveys(int numOrgs, int numPrograms){ +// List orgUnitList=OrgUnit.find(OrgUnit.class, null, null); +// List programList=Program.find(Program.class,null,null); +// Program program=programList.get(numPrograms); +// User user =getSafeUser(); +// +// for(int i=0;i surveys= Survey.find(Survey.class, "user=?", user.getId().toString()); +// Session.setAdapterUncompleted(new AssessmentUnsentAdapter(surveys, InstrumentationRegistry.getTargetContext())); +// return surveys; +// } +// +// public static List mockSurveys(int num){ +// return mockSurveys(num, 0); +// } +// +// private static User getSafeUser(){ +// User user=Session.getUser(); +// if(user!=null){ +// return user; +// } +// user = new User("user", "user"); +// user.save(); +// Session.setUser(user); +// return user; +// } +// +// protected Activity getActivityInstance(){ +// final Activity[] activity = new Activity[1]; +// Instrumentation instrumentation=InstrumentationRegistry.getInstrumentation(); +// instrumentation.waitForIdleSync(); +// instrumentation.runOnMainSync(new Runnable() { +// public void run() { +// Collection resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED); +// if (resumedActivities.iterator().hasNext()) { +// activity[0] = (Activity) resumedActivities.iterator().next(); +// } +// } +// }); +// +// return activity[0]; +// } +// +// protected static void clearSharedPreferences(){ +// SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getTargetContext()); +// sharedPreferences.edit().clear().commit(); +// } +// +//} +// diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/PushEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/PushEspressoTest.java index c5d2cf10a4..18c407edaf 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/PushEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/PushEspressoTest.java @@ -1,189 +1,189 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.app.Instrumentation; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.ViewInteraction; -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.util.Log; - -import org.eyeseetea.malariacare.DashboardActivity; -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.SurveyActivity; -import org.eyeseetea.malariacare.database.model.Option; -import org.eyeseetea.malariacare.database.model.Question; -import org.eyeseetea.malariacare.database.model.Survey; -import org.eyeseetea.malariacare.database.utils.PreferencesState; -import org.eyeseetea.malariacare.fragments.DashboardUnsentFragment; -import org.eyeseetea.malariacare.services.SurveyService; -import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; -import org.eyeseetea.malariacare.utils.Constants; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.List; - -import static android.support.test.espresso.Espresso.onData; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.action.ViewActions.longClick; -import static android.support.test.espresso.action.ViewActions.swipeRight; -import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.intent.Intents.intended; -import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isRoot; -import static android.support.test.espresso.matcher.ViewMatchers.withChild; -import static android.support.test.espresso.matcher.ViewMatchers.withClassName; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withTagValue; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertEquals; -import static org.eyeseetea.malariacare.test.utils.MalariaEspressoActions.waitId; -import static org.eyeseetea.malariacare.test.utils.TextCardScaleMatcher.hasTextCardScale; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; - -/** - * - */ -@RunWith(AndroidJUnit4.class) -public class PushEspressoTest extends MalariaEspressoTest{ - - private static String TAG=".PushEspressoTest"; - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - DashboardActivity.class); - - @BeforeClass - public static void init(){ - populateData(InstrumentationRegistry.getTargetContext().getAssets()); -// mockSessionSurvey(_EXPECTED_SURVEYS, 1, 0); - } - - @Before - public void registerIntentServiceIdlingResource(){ - Log.i(TAG,"---BEFORE---"); - super.setup(); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); - Espresso.registerIdlingResources(idlingResource); - } - - @After - public void unregisterIntentServiceIdlingResource(){ - Log.i(TAG,"---AFTER---"); - Espresso.unregisterIdlingResources(idlingResource); - unregisterSurveyReceiver(); - getActivityInstance().finish(); - } - - @Test - public void form_views() { - Log.i(TAG, "------form_views------"); - onView(isRoot()).perform(waitId(R.id.plusButton, 3000)); - } - - @Test - public void org_unit_ko_push_ko() { - Log.i(TAG, "------org_unit_ko_push_ko------"); - //GIVEN - onView(withId(R.id.plusButton)).perform(click()); - SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); - - //WHEN - chooseOptionWithText(surveyActivity, "No"); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - //THEN - onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); - - //WHEN - onRowWithSurvey(Survey.getUnsentSurveys(1).get(0)).perform(longClick()); - onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); - - //THEN - onView(withText(surveyActivity.getString(R.string.dialog_error_push_no_org_unit))).check(matches(isDisplayed())); - } - - @Test - public void org_unit_ok_location_ko_push_ko() { - Log.i(TAG, "------org_unit_ok_location_ko_push_ko------"); - //GIVEN - PreferencesState.getInstance().setOrgUnit("KH_Cambodia"); - onView(withId(R.id.plusButton)).perform(click()); - SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); - - //WHEN - chooseOptionWithText(surveyActivity, "No"); - - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - //THEN - onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); - - //WHEN - onRowWithSurvey(Survey.getUnsentSurveys(1).get(0)).perform(longClick()); - onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); - - //THEN - onView(withText(surveyActivity.getString(R.string.dialog_error_push_no_location))).check(matches(isDisplayed())); - } - - private void chooseOptionWithText(SurveyActivity activity,String text){ - Option noOption=activity.findOptionByText(text); - onView(withTagValue(is((Object)noOption))).perform(click()); - } - - private ViewInteraction onRowWithSurvey(Survey survey){ - return onView(allOf(withClassName(endsWith("TableRow")),withTagValue(is((Object)survey.getId())))); - } - - private void unregisterSurveyReceiver(){ - try{ - DashboardActivity dashboardActivity =(DashboardActivity)getActivityInstance(); - DashboardUnsentFragment dashboardUnsentFragment =(DashboardUnsentFragment) dashboardActivity.getFragmentManager().findFragmentById(R.id.dashboard_details_fragment); - dashboardUnsentFragment.unregisterSurveysReceiver(); - }catch(Exception ex){ - Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); - } - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.app.Instrumentation; +//import android.support.test.InstrumentationRegistry; +//import android.support.test.espresso.Espresso; +//import android.support.test.espresso.ViewInteraction; +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.util.Log; +// +//import org.eyeseetea.malariacare.DashboardActivity; +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.SurveyActivity; +//import org.eyeseetea.malariacare.database.model.Option; +//import org.eyeseetea.malariacare.database.model.Question; +//import org.eyeseetea.malariacare.database.model.Survey; +//import org.eyeseetea.malariacare.database.utils.PreferencesState; +//import org.eyeseetea.malariacare.fragments.DashboardUnsentFragment; +//import org.eyeseetea.malariacare.services.SurveyService; +//import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; +//import org.eyeseetea.malariacare.utils.Constants; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import java.util.List; +// +//import static android.support.test.espresso.Espresso.onData; +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.action.ViewActions.longClick; +//import static android.support.test.espresso.action.ViewActions.swipeRight; +//import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.intent.Intents.intended; +//import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.isRoot; +//import static android.support.test.espresso.matcher.ViewMatchers.withChild; +//import static android.support.test.espresso.matcher.ViewMatchers.withClassName; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withTagValue; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertEquals; +//import static org.eyeseetea.malariacare.test.utils.MalariaEspressoActions.waitId; +//import static org.eyeseetea.malariacare.test.utils.TextCardScaleMatcher.hasTextCardScale; +//import static org.hamcrest.Matchers.allOf; +//import static org.hamcrest.Matchers.endsWith; +//import static org.hamcrest.Matchers.instanceOf; +//import static org.hamcrest.Matchers.is; +// +///** +// * +// */ +//@RunWith(AndroidJUnit4.class) +//public class PushEspressoTest extends MalariaEspressoTest{ +// +// private static String TAG=".PushEspressoTest"; +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// DashboardActivity.class); +// +// @BeforeClass +// public static void init(){ +// populateData(InstrumentationRegistry.getTargetContext().getAssets()); +//// mockSessionSurvey(_EXPECTED_SURVEYS, 1, 0); +// } +// +// @Before +// public void registerIntentServiceIdlingResource(){ +// Log.i(TAG,"---BEFORE---"); +// super.setup(); +// Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); +// idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); +// Espresso.registerIdlingResources(idlingResource); +// } +// +// @After +// public void unregisterIntentServiceIdlingResource(){ +// Log.i(TAG,"---AFTER---"); +// Espresso.unregisterIdlingResources(idlingResource); +// unregisterSurveyReceiver(); +// getActivityInstance().finish(); +// } +// +// @Test +// public void form_views() { +// Log.i(TAG, "------form_views------"); +// onView(isRoot()).perform(waitId(R.id.plusButton, 3000)); +// } +// +// @Test +// public void org_unit_ko_push_ko() { +// Log.i(TAG, "------org_unit_ko_push_ko------"); +// //GIVEN +// onView(withId(R.id.plusButton)).perform(click()); +// SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); +// +// //WHEN +// chooseOptionWithText(surveyActivity, "No"); +// +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// //THEN +// onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); +// +// //WHEN +// onRowWithSurvey(Survey.getUnsentSurveys(1).get(0)).perform(longClick()); +// onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); +// +// //THEN +// onView(withText(surveyActivity.getString(R.string.dialog_error_push_no_org_unit))).check(matches(isDisplayed())); +// } +// +// @Test +// public void org_unit_ok_location_ko_push_ko() { +// Log.i(TAG, "------org_unit_ok_location_ko_push_ko------"); +// //GIVEN +// PreferencesState.getInstance().setOrgUnit("KH_Cambodia"); +// onView(withId(R.id.plusButton)).perform(click()); +// SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); +// +// //WHEN +// chooseOptionWithText(surveyActivity, "No"); +// +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// //THEN +// onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); +// +// //WHEN +// onRowWithSurvey(Survey.getUnsentSurveys(1).get(0)).perform(longClick()); +// onView(withText(surveyActivity.getString(android.R.string.ok))).check(matches(isDisplayed())).perform(click()); +// +// //THEN +// onView(withText(surveyActivity.getString(R.string.dialog_error_push_no_location))).check(matches(isDisplayed())); +// } +// +// private void chooseOptionWithText(SurveyActivity activity,String text){ +// Option noOption=activity.findOptionByText(text); +// onView(withTagValue(is((Object)noOption))).perform(click()); +// } +// +// private ViewInteraction onRowWithSurvey(Survey survey){ +// return onView(allOf(withClassName(endsWith("TableRow")),withTagValue(is((Object)survey.getId())))); +// } +// +// private void unregisterSurveyReceiver(){ +// try{ +// DashboardActivity dashboardActivity =(DashboardActivity)getActivityInstance(); +// DashboardUnsentFragment dashboardUnsentFragment =(DashboardUnsentFragment) dashboardActivity.getFragmentManager().findFragmentById(R.id.dashboard_details_fragment); +// dashboardUnsentFragment.unregisterSurveysReceiver(); +// }catch(Exception ex){ +// Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); +// } +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SettingsEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SettingsEspressoTest.java index fd89f418a9..a35e71f1f4 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SettingsEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SettingsEspressoTest.java @@ -1,120 +1,120 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Health Network QIS App. - * - * Health Network QIS App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Health Network QIS App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; - -import junit.framework.Assert; - -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.SettingsActivity; -import org.eyeseetea.malariacare.database.utils.PreferencesState; -import org.eyeseetea.malariacare.utils.Constants; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertEquals; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - - -/** - * Espresso tests for the survey that contains scores, compositeScores - */ -@RunWith(AndroidJUnit4.class) -@LargeTest -public class SettingsEspressoTest extends MalariaEspressoTest{ - - private static String TAG=".SettingsEspressoTest"; - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - SettingsActivity.class); - - @BeforeClass - public static void init(){ - clearSharedPreferences(); - } - - @Test - public void form_views() { - Log.i(TAG,"------form_views------"); - //THEN - onView(withText("Show num/dems")).check(matches(isDisplayed())); - onView(withText("Customize fonts?")).check(matches(isDisplayed())); - } - - @Test - public void change_font(){ - Log.i(TAG, "------change_font------"); - - //WHEN - whenFontSizeChange(3); - pressBack(); - - //THEN - Assert.assertEquals(Constants.FONTS_LARGE, PreferencesState.getInstance().getScale()); - } - - @Test - public void change_num_den(){ - Log.i(TAG, "------change_num_den------"); - - //WHEN - whenToggleShowHideNumDem(); - pressBack(); - - //THEN - Assert.assertEquals(true, PreferencesState.getInstance().isShowNumDen()); - } - - /** - * Change font size - * @param num font size in a discrete int scale [0: xsmall - 1: small - 2: medium - 3: large - 4: xlarge] - */ - private void whenFontSizeChange(int num) { - SettingsActivity settingsActivity=(SettingsActivity)getActivityInstance(); - onView(withText(settingsActivity.getString(R.string.settings_checkbox_customize_fonts))).perform(click()); - onView(withText(settingsActivity.getString(R.string.settings_list_font_sizes))).perform(click()); - onView(withText((settingsActivity.getResources().getStringArray(R.array.settings_array_titles_font_sizes))[num])).perform(click()); - } - - /** - * Change show/hide num/dem preference - */ - private void whenToggleShowHideNumDem() { - SettingsActivity settingsActivity=(SettingsActivity)getActivityInstance(); - onView(withText(settingsActivity.getString(R.string.settings_checkbox_show_num_dems))).perform(click()); - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App App. +// * +// * QIS Surveillance App App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.test.suitebuilder.annotation.LargeTest; +//import android.util.Log; +// +//import junit.framework.Assert; +// +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.SettingsActivity; +//import org.eyeseetea.malariacare.database.utils.PreferencesState; +//import org.eyeseetea.malariacare.utils.Constants; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.Espresso.pressBack; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertEquals; +//import static org.hamcrest.Matchers.allOf; +//import static org.hamcrest.Matchers.is; +//import static org.hamcrest.Matchers.not; +// +// +///** +// * Espresso tests for the survey that contains scores, compositeScores +// */ +//@RunWith(AndroidJUnit4.class) +//@LargeTest +//public class SettingsEspressoTest extends MalariaEspressoTest{ +// +// private static String TAG=".SettingsEspressoTest"; +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// SettingsActivity.class); +// +// @BeforeClass +// public static void init(){ +// clearSharedPreferences(); +// } +// +// @Test +// public void form_views() { +// Log.i(TAG,"------form_views------"); +// //THEN +// onView(withText("Show num/dems")).check(matches(isDisplayed())); +// onView(withText("Customize fonts?")).check(matches(isDisplayed())); +// } +// +// @Test +// public void change_font(){ +// Log.i(TAG, "------change_font------"); +// +// //WHEN +// whenFontSizeChange(3); +// pressBack(); +// +// //THEN +// Assert.assertEquals(Constants.FONTS_LARGE, PreferencesState.getInstance().getScale()); +// } +// +// @Test +// public void change_num_den(){ +// Log.i(TAG, "------change_num_den------"); +// +// //WHEN +// whenToggleShowHideNumDem(); +// pressBack(); +// +// //THEN +// Assert.assertEquals(true, PreferencesState.getInstance().isShowNumDen()); +// } +// +// /** +// * Change font size +// * @param num font size in a discrete int scale [0: xsmall - 1: small - 2: medium - 3: large - 4: xlarge] +// */ +// private void whenFontSizeChange(int num) { +// SettingsActivity settingsActivity=(SettingsActivity)getActivityInstance(); +// onView(withText(settingsActivity.getString(R.string.settings_checkbox_customize_fonts))).perform(click()); +// onView(withText(settingsActivity.getString(R.string.settings_list_font_sizes))).perform(click()); +// onView(withText((settingsActivity.getResources().getStringArray(R.array.settings_array_titles_font_sizes))[num])).perform(click()); +// } +// +// /** +// * Change show/hide num/dem preference +// */ +// private void whenToggleShowHideNumDem() { +// SettingsActivity settingsActivity=(SettingsActivity)getActivityInstance(); +// onView(withText(settingsActivity.getString(R.string.settings_checkbox_show_num_dems))).perform(click()); +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyChecksEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyChecksEspressoTest.java index f59688c212..10ff1024ac 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyChecksEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyChecksEspressoTest.java @@ -1,143 +1,143 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Health Network QIS App. - * - * Health Network QIS App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Health Network QIS App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.app.Instrumentation; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; - -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.SurveyActivity; -import org.eyeseetea.malariacare.database.model.Question; -import org.eyeseetea.malariacare.database.model.Survey; -import org.eyeseetea.malariacare.database.model.Tab; -import org.eyeseetea.malariacare.database.utils.PreferencesState; -import org.eyeseetea.malariacare.services.SurveyService; -import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; -import org.eyeseetea.malariacare.utils.Constants; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onData; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertEquals; -import static org.eyeseetea.malariacare.test.utils.TextCardScaleMatcher.hasTextCardScale; -import static org.eyeseetea.malariacare.test.utils.UncheckeableRadioButtonScaleMatcher.hasRadioButtonScale; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - - -/** - * - */ -@RunWith(AndroidJUnit4.class) -@LargeTest -public class SurveyChecksEspressoTest extends MalariaEspressoTest{ - - private static String TAG=".SurveyChecksEspressoTest"; - - private static Survey icmSurvey; - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - SurveyActivity.class); - - @BeforeClass - public static void init(){ - populateData(InstrumentationRegistry.getTargetContext().getAssets()); - icmSurvey=mockSessionSurvey(1,1,0);//1 ICM - } - - @Before - public void registerIntentServiceIdlingResource(){ - super.setup(); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); - Espresso.registerIdlingResources(idlingResource); - } - - @After - public void unregisterIntentServiceIdlingResource(){ - Espresso.unregisterIdlingResources(idlingResource); - } - - @Test - public void form_views() { - //THEN - onView(withId(R.id.tabSpinner)).check(matches(isDisplayed())); - onView(withText("Inquiry and Physical Examination")).check(matches(isDisplayed())); - } - - @Test - public void radiobutton_textsize_changes(){ - Log.i(TAG, "------radiobutton_textsize_changes------"); - //GIVEN: Some special font size set - PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); - - //WHEN: Select survey again from dashboard - whenTabSelected(1); - - //THEN: Check font size has properly changed - onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(5) - .onChildView(withId(R.id.answer)) - .onChildView(withText(res.getString(R.string.yes))) - .check(matches(hasRadioButtonScale(res.getString(R.string.font_size_level3)))); - } - - @Test - public void textcard_textsize_changes(){ - Log.i(TAG, "------textcard_textsize_changes------"); - //GIVEN: Some special font size set - PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); - - //WHEN: Select survey again from dashboard - whenTabSelected(1); - - //THEN - onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(1) - .onChildView(withId(R.id.statement)) - .check(matches(hasTextCardScale(res.getString(R.string.font_size_level3)))); - } - - /** - * Select the tab number 'x' - * @param num Index of the tab to select - */ - private void whenTabSelected(int num){ - onView(withId(R.id.tabSpinner)).perform(click()); - onData(is(instanceOf(Tab.class))).atPosition(num).perform(click()); - } - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App App. +// * +// * QIS Surveillance App App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.app.Instrumentation; +//import android.support.test.InstrumentationRegistry; +//import android.support.test.espresso.Espresso; +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.test.suitebuilder.annotation.LargeTest; +//import android.util.Log; +// +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.SurveyActivity; +//import org.eyeseetea.malariacare.database.model.Question; +//import org.eyeseetea.malariacare.database.model.Survey; +//import org.eyeseetea.malariacare.database.model.Tab; +//import org.eyeseetea.malariacare.database.utils.PreferencesState; +//import org.eyeseetea.malariacare.services.SurveyService; +//import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; +//import org.eyeseetea.malariacare.utils.Constants; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onData; +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertEquals; +//import static org.eyeseetea.malariacare.test.utils.TextCardScaleMatcher.hasTextCardScale; +//import static org.eyeseetea.malariacare.test.utils.UncheckeableRadioButtonScaleMatcher.hasRadioButtonScale; +//import static org.hamcrest.Matchers.allOf; +//import static org.hamcrest.Matchers.instanceOf; +//import static org.hamcrest.Matchers.is; +//import static org.hamcrest.Matchers.not; +// +// +///** +// * +// */ +//@RunWith(AndroidJUnit4.class) +//@LargeTest +//public class SurveyChecksEspressoTest extends MalariaEspressoTest{ +// +// private static String TAG=".SurveyChecksEspressoTest"; +// +// private static Survey icmSurvey; +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// SurveyActivity.class); +// +// @BeforeClass +// public static void init(){ +// populateData(InstrumentationRegistry.getTargetContext().getAssets()); +// icmSurvey=mockSessionSurvey(1,1,0);//1 ICM +// } +// +// @Before +// public void registerIntentServiceIdlingResource(){ +// super.setup(); +// Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); +// idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); +// Espresso.registerIdlingResources(idlingResource); +// } +// +// @After +// public void unregisterIntentServiceIdlingResource(){ +// Espresso.unregisterIdlingResources(idlingResource); +// } +// +// @Test +// public void form_views() { +// //THEN +// onView(withId(R.id.tabSpinner)).check(matches(isDisplayed())); +// onView(withText("Inquiry and Physical Examination")).check(matches(isDisplayed())); +// } +// +// @Test +// public void radiobutton_textsize_changes(){ +// Log.i(TAG, "------radiobutton_textsize_changes------"); +// //GIVEN: Some special font size set +// PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); +// +// //WHEN: Select survey again from dashboard +// whenTabSelected(1); +// +// //THEN: Check font size has properly changed +// onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(5) +// .onChildView(withId(R.id.answer)) +// .onChildView(withText(res.getString(R.string.yes))) +// .check(matches(hasRadioButtonScale(res.getString(R.string.font_size_level3)))); +// } +// +// @Test +// public void textcard_textsize_changes(){ +// Log.i(TAG, "------textcard_textsize_changes------"); +// //GIVEN: Some special font size set +// PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); +// +// //WHEN: Select survey again from dashboard +// whenTabSelected(1); +// +// //THEN +// onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(1) +// .onChildView(withId(R.id.statement)) +// .check(matches(hasTextCardScale(res.getString(R.string.font_size_level3)))); +// } +// +// /** +// * Select the tab number 'x' +// * @param num Index of the tab to select +// */ +// private void whenTabSelected(int num){ +// onView(withId(R.id.tabSpinner)).perform(click()); +// onData(is(instanceOf(Tab.class))).atPosition(num).perform(click()); +// } +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyScoresEspressoTest.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyScoresEspressoTest.java index d93fd1ea55..19690a36f3 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyScoresEspressoTest.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/SurveyScoresEspressoTest.java @@ -1,259 +1,259 @@ -/* - * Copyright (c) 2015. - * - * This file is part of Facility QA Tool App. - * - * Facility QA Tool App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Facility QA Tool App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . - */ - -package org.eyeseetea.malariacare.test; - -import android.app.Instrumentation; -import android.support.test.InstrumentationRegistry; -import android.support.test.espresso.Espresso; -import android.support.test.espresso.intent.rule.IntentsTestRule; -import android.support.test.runner.AndroidJUnit4; -import android.test.suitebuilder.annotation.LargeTest; -import android.util.Log; - -import org.eyeseetea.malariacare.DashboardActivity; -import org.eyeseetea.malariacare.R; -import org.eyeseetea.malariacare.SurveyActivity; -import org.eyeseetea.malariacare.database.model.Option; -import org.eyeseetea.malariacare.database.model.Question; -import org.eyeseetea.malariacare.database.model.Tab; -import org.eyeseetea.malariacare.database.utils.PreferencesState; -import org.eyeseetea.malariacare.services.SurveyService; -import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; -import org.eyeseetea.malariacare.utils.Constants; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; - -import static android.support.test.espresso.Espresso.onData; -import static android.support.test.espresso.Espresso.onView; -import static android.support.test.espresso.Espresso.pressBack; -import static android.support.test.espresso.action.ViewActions.click; -import static android.support.test.espresso.assertion.ViewAssertions.matches; -import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static junit.framework.Assert.assertEquals; -import static org.eyeseetea.malariacare.test.utils.EditCardScaleMatcher.hasEditCardScale; -import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.not; - - -/** - * Espresso tests for the survey that contains scores, compositeScores - */ -@RunWith(AndroidJUnit4.class) -@LargeTest -public class SurveyScoresEspressoTest extends MalariaEspressoTest{ - - private static String TAG=".SurveyScoresEspressoTest"; - - @Rule - public IntentsTestRule mActivityRule = new IntentsTestRule<>( - SurveyActivity.class); - - @BeforeClass - public static void init(){ - populateData(InstrumentationRegistry.getTargetContext().getAssets()); - mockSessionSurvey(1,0,0);//1 Clinical Case Management, select this one - } - - @Before - public void registerIntentServiceIdlingResource(){ - Log.i(TAG,"---BEFORE---"); - super.setup(); - Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); - idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); - Espresso.registerIdlingResources(idlingResource); - } - - @After - public void unregisterIntentServiceIdlingResource(){ - Log.i(TAG,"---AFTER---"); - Espresso.unregisterIdlingResources(idlingResource); - unregisterSurveyReceiver(); - } - - @Test - public void form_views() { - Log.i(TAG,"------form_views------"); - //THEN - onView(withId(R.id.tabSpinner)).check(matches(isDisplayed())); - onView(withText("General Info")).check(matches(isDisplayed())); - } - - @Test - public void back_shows_dialog(){ - Log.i(TAG,"------back_shows_dialog------"); - //GIVEN - pressBack(); - - //THEN - onView(withText(android.R.string.no)).check(matches(isDisplayed())); - onView(withText(android.R.string.yes)).check(matches(isDisplayed())); - } - - @Test - public void back_yes_intent(){ - Log.i(TAG,"------back_yes_intent------"); - //GIVEN - pressBack(); - - //WHEN - onView(withText(android.R.string.yes)).perform(click()); - - //THEN - assertEquals(DashboardActivity.class, getActivityInstance().getClass()); - } - - @Test - public void change_to_scored_tab(){ - Log.i(TAG,"------change_to_scored_tab------"); - //WHEN: Select 'Profile' tab - whenTabSelected(1); - - //THEN - onView(withText("HR - Nurses")).check(matches(isDisplayed())); - onView(withId(R.id.subtotalScoreText)).check(matches(isDisplayed())); - } - - @Test - public void change_to_score(){ - Log.i(TAG,"------change_to_score------"); - //WHEN: Select 'Score' tab - whenTabSelected(10); - - //THEN - onView(withText(R.string.score_info_case1)).check(matches(isDisplayed())); - onView(withText(R.string.score_info_case2)).check(matches(isDisplayed())); - onView(withText(R.string.score_info_case3)).check(matches(isDisplayed())); - } - - @Test - public void change_to_composite_score(){ - Log.i(TAG,"------change_to_composite_score------"); - //WHEN: Select 'Composite Score' tab - whenTabSelected(11); - - //THEN - onView(withText("Malaria reference materials")).check(matches(isDisplayed())); - } - - @Test - public void in_c1_rdt_score_some_points() { - Log.i(TAG,"------in_c1_rdt_score_some_points------"); - //WHEN: Select 'C1-RDT' tab - whenTabSelected(3); - - //WHEN: Some answers 'Yes' - for(int i=6;i<=16;i++){ - whenDropDownAnswered(i,true); - } - - //THEN - onView(withId(R.id.score)).check(matches(withText("66 % "))); - onView(withId(R.id.qualitativeScore)).check(matches(withText(getActivityInstance().getString(R.string.fair)))); - } - - @Test - public void global_scores_are_calculated(){ - Log.i(TAG,"------global_scores_are_calculated------"); - //WHEN: Select 'C1-RDT' tab | Some answers 'Yes' - whenTabSelected(3); - - for(int i=6;i<=16;i++){ - whenDropDownAnswered(i,true); - } - - //WHEN: Select 'Score' tab - whenTabSelected(10); - - //THEN - onView(withId(R.id.totalScore)).check(matches(withText("4"))); - onView(withId(R.id.rdtAvg)).check(matches(withText("22"))); - } - - @Test - public void textsize_editcard_changes(){ - Log.i(TAG, "------textsize_editcard_changes------"); - //GIVEN: Some special font size set - PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); - - //WHEN: Select survey again from dashboard - whenTabSelected(1); - - //THEN: Check font size has properly changed - onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(1) - .onChildView(withId(R.id.answer)) - .check(matches(hasEditCardScale(res.getString(R.string.font_size_level3)))); - } - - @Test - public void num_dem_show_hide(){ - Log.i(TAG, "------num_dem_show_hide------"); - //GIVEN: Preferences set to show num/den - PreferencesState.getInstance().setShowNumDen(true); - - //WHEN: Select 'profile' tab - whenTabSelected(1); - - //THEN: Check that num/dems are now being shown - onView(withId(R.id.totalNum)).check(matches(isDisplayed())); - } - - /** - * Select the tab number 'x' - * @param num Index of the tab to select - */ - private void whenTabSelected(int num){ - onView(withId(R.id.tabSpinner)).perform(click()); - onData(is(instanceOf(Tab.class))).atPosition(num).perform(click()); - } - - /** - * Answers the question at position 'x'. - * @param position Index of the question to answer - * @param answer True (Yes), False (No) - */ - private void whenDropDownAnswered(int position,boolean answer){ - onData(is(instanceOf(Question.class))). - inAdapterView(withId(R.id.listView)). - atPosition(position). - onChildView(withId(R.id.answer)) - .perform(click()); - int indexAnswer=answer?1:2; - onData(is(instanceOf(Option.class))).atPosition(indexAnswer).perform(click()); - } - - private void unregisterSurveyReceiver(){ - try{ - SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); - surveyActivity.unregisterReceiver(); - }catch(Exception ex){ - Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); - } - } - - -} \ No newline at end of file +///* +// * Copyright (c) 2015. +// * +// * This file is part of QIS Surveillance App. +// * +// * QIS Surveillance App is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * QIS Surveillance App 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 General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with QIS Surveillance App. If not, see . +// */ +// +//package org.eyeseetea.malariacare.test; +// +//import android.app.Instrumentation; +//import android.support.test.InstrumentationRegistry; +//import android.support.test.espresso.Espresso; +//import android.support.test.espresso.intent.rule.IntentsTestRule; +//import android.support.test.runner.AndroidJUnit4; +//import android.test.suitebuilder.annotation.LargeTest; +//import android.util.Log; +// +//import org.eyeseetea.malariacare.DashboardActivity; +//import org.eyeseetea.malariacare.R; +//import org.eyeseetea.malariacare.SurveyActivity; +//import org.eyeseetea.malariacare.database.model.Option; +//import org.eyeseetea.malariacare.database.model.Question; +//import org.eyeseetea.malariacare.database.model.Tab; +//import org.eyeseetea.malariacare.database.utils.PreferencesState; +//import org.eyeseetea.malariacare.services.SurveyService; +//import org.eyeseetea.malariacare.test.utils.IntentServiceIdlingResource; +//import org.eyeseetea.malariacare.utils.Constants; +//import org.junit.After; +//import org.junit.Before; +//import org.junit.BeforeClass; +//import org.junit.Rule; +//import org.junit.Test; +//import org.junit.runner.RunWith; +// +//import static android.support.test.espresso.Espresso.onData; +//import static android.support.test.espresso.Espresso.onView; +//import static android.support.test.espresso.Espresso.pressBack; +//import static android.support.test.espresso.action.ViewActions.click; +//import static android.support.test.espresso.assertion.ViewAssertions.matches; +//import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +//import static android.support.test.espresso.matcher.ViewMatchers.withId; +//import static android.support.test.espresso.matcher.ViewMatchers.withText; +//import static junit.framework.Assert.assertEquals; +//import static org.eyeseetea.malariacare.test.utils.EditCardScaleMatcher.hasEditCardScale; +//import static org.hamcrest.Matchers.allOf; +//import static org.hamcrest.Matchers.instanceOf; +//import static org.hamcrest.Matchers.is; +//import static org.hamcrest.Matchers.not; +// +// +///** +// * Espresso tests for the survey that contains scores, compositeScores +// */ +//@RunWith(AndroidJUnit4.class) +//@LargeTest +//public class SurveyScoresEspressoTest extends MalariaEspressoTest{ +// +// private static String TAG=".SurveyScoresEspressoTest"; +// +// @Rule +// public IntentsTestRule mActivityRule = new IntentsTestRule<>( +// SurveyActivity.class); +// +// @BeforeClass +// public static void init(){ +// populateData(InstrumentationRegistry.getTargetContext().getAssets()); +// mockSessionSurvey(1,0,0);//1 Clinical Case Management, select this one +// } +// +// @Before +// public void registerIntentServiceIdlingResource(){ +// Log.i(TAG,"---BEFORE---"); +// super.setup(); +// Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); +// idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext(), SurveyService.class); +// Espresso.registerIdlingResources(idlingResource); +// } +// +// @After +// public void unregisterIntentServiceIdlingResource(){ +// Log.i(TAG,"---AFTER---"); +// Espresso.unregisterIdlingResources(idlingResource); +// unregisterSurveyReceiver(); +// } +// +// @Test +// public void form_views() { +// Log.i(TAG,"------form_views------"); +// //THEN +// onView(withId(R.id.tabSpinner)).check(matches(isDisplayed())); +// onView(withText("General Info")).check(matches(isDisplayed())); +// } +// +// @Test +// public void back_shows_dialog(){ +// Log.i(TAG,"------back_shows_dialog------"); +// //GIVEN +// pressBack(); +// +// //THEN +// onView(withText(android.R.string.no)).check(matches(isDisplayed())); +// onView(withText(android.R.string.yes)).check(matches(isDisplayed())); +// } +// +// @Test +// public void back_yes_intent(){ +// Log.i(TAG,"------back_yes_intent------"); +// //GIVEN +// pressBack(); +// +// //WHEN +// onView(withText(android.R.string.yes)).perform(click()); +// +// //THEN +// assertEquals(DashboardActivity.class, getActivityInstance().getClass()); +// } +// +// @Test +// public void change_to_scored_tab(){ +// Log.i(TAG,"------change_to_scored_tab------"); +// //WHEN: Select 'Profile' tab +// whenTabSelected(1); +// +// //THEN +// onView(withText("HR - Nurses")).check(matches(isDisplayed())); +// onView(withId(R.id.subtotalScoreText)).check(matches(isDisplayed())); +// } +// +// @Test +// public void change_to_score(){ +// Log.i(TAG,"------change_to_score------"); +// //WHEN: Select 'Score' tab +// whenTabSelected(10); +// +// //THEN +// onView(withText(R.string.score_info_case1)).check(matches(isDisplayed())); +// onView(withText(R.string.score_info_case2)).check(matches(isDisplayed())); +// onView(withText(R.string.score_info_case3)).check(matches(isDisplayed())); +// } +// +// @Test +// public void change_to_composite_score(){ +// Log.i(TAG,"------change_to_composite_score------"); +// //WHEN: Select 'Composite Score' tab +// whenTabSelected(11); +// +// //THEN +// onView(withText("Malaria reference materials")).check(matches(isDisplayed())); +// } +// +// @Test +// public void in_c1_rdt_score_some_points() { +// Log.i(TAG,"------in_c1_rdt_score_some_points------"); +// //WHEN: Select 'C1-RDT' tab +// whenTabSelected(3); +// +// //WHEN: Some answers 'Yes' +// for(int i=6;i<=16;i++){ +// whenDropDownAnswered(i,true); +// } +// +// //THEN +// onView(withId(R.id.score)).check(matches(withText("66 % "))); +// onView(withId(R.id.qualitativeScore)).check(matches(withText(getActivityInstance().getString(R.string.fair)))); +// } +// +// @Test +// public void global_scores_are_calculated(){ +// Log.i(TAG,"------global_scores_are_calculated------"); +// //WHEN: Select 'C1-RDT' tab | Some answers 'Yes' +// whenTabSelected(3); +// +// for(int i=6;i<=16;i++){ +// whenDropDownAnswered(i,true); +// } +// +// //WHEN: Select 'Score' tab +// whenTabSelected(10); +// +// //THEN +// onView(withId(R.id.totalScore)).check(matches(withText("4"))); +// onView(withId(R.id.rdtAvg)).check(matches(withText("22"))); +// } +// +// @Test +// public void textsize_editcard_changes(){ +// Log.i(TAG, "------textsize_editcard_changes------"); +// //GIVEN: Some special font size set +// PreferencesState.getInstance().setScale(Constants.FONTS_LARGE); +// +// //WHEN: Select survey again from dashboard +// whenTabSelected(1); +// +// //THEN: Check font size has properly changed +// onData(is(instanceOf(Question.class))).inAdapterView(withId(R.id.listView)).atPosition(1) +// .onChildView(withId(R.id.answer)) +// .check(matches(hasEditCardScale(res.getString(R.string.font_size_level3)))); +// } +// +// @Test +// public void num_dem_show_hide(){ +// Log.i(TAG, "------num_dem_show_hide------"); +// //GIVEN: Preferences set to show num/den +// PreferencesState.getInstance().setShowNumDen(true); +// +// //WHEN: Select 'profile' tab +// whenTabSelected(1); +// +// //THEN: Check that num/dems are now being shown +// onView(withId(R.id.totalNum)).check(matches(isDisplayed())); +// } +// +// /** +// * Select the tab number 'x' +// * @param num Index of the tab to select +// */ +// private void whenTabSelected(int num){ +// onView(withId(R.id.tabSpinner)).perform(click()); +// onData(is(instanceOf(Tab.class))).atPosition(num).perform(click()); +// } +// +// /** +// * Answers the question at position 'x'. +// * @param position Index of the question to answer +// * @param answer True (Yes), False (No) +// */ +// private void whenDropDownAnswered(int position,boolean answer){ +// onData(is(instanceOf(Question.class))). +// inAdapterView(withId(R.id.listView)). +// atPosition(position). +// onChildView(withId(R.id.answer)) +// .perform(click()); +// int indexAnswer=answer?1:2; +// onData(is(instanceOf(Option.class))).atPosition(indexAnswer).perform(click()); +// } +// +// private void unregisterSurveyReceiver(){ +// try{ +// SurveyActivity surveyActivity=(SurveyActivity)getActivityInstance(); +// surveyActivity.unregisterReceiver(); +// }catch(Exception ex){ +// Log.e(TAG,"unregisterSurveyReceiver(): "+ex.getMessage()); +// } +// } +// +// +//} \ No newline at end of file diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/EditCardScaleMatcher.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/EditCardScaleMatcher.java index 2a2c5663af..121bd985ec 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/EditCardScaleMatcher.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/EditCardScaleMatcher.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/ErrorTextMatcher.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/ErrorTextMatcher.java index 1fd27e5e94..c4676518b5 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/ErrorTextMatcher.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/ErrorTextMatcher.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Facility QA Tool App. + * This file is part of QIS Surveillance App. * - * Facility QA Tool App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Facility QA Tool App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/IntentServiceIdlingResource.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/IntentServiceIdlingResource.java index 5238ea4ceb..ed891dd916 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/IntentServiceIdlingResource.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/IntentServiceIdlingResource.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/MalariaEspressoActions.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/MalariaEspressoActions.java index 139e24480f..432cc498ee 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/MalariaEspressoActions.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/MalariaEspressoActions.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/SurveyAssessmentMatcher.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/SurveyAssessmentMatcher.java index 7db38c1011..378d019201 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/SurveyAssessmentMatcher.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/SurveyAssessmentMatcher.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/TextCardScaleMatcher.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/TextCardScaleMatcher.java index e02e98aa23..caed47725a 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/TextCardScaleMatcher.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/TextCardScaleMatcher.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/UncheckeableRadioButtonScaleMatcher.java b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/UncheckeableRadioButtonScaleMatcher.java index 7285683e88..a4c9367df4 100644 --- a/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/UncheckeableRadioButtonScaleMatcher.java +++ b/app/src/androidTest/java/org/eyeseetea/malariacare/test/utils/UncheckeableRadioButtonScaleMatcher.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of Health Network QIS App. + * This file is part of QIS Surveillance App App. * - * Health Network QIS App is free software: you can redistribute it and/or modify + * QIS Surveillance App App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * Health Network QIS App is distributed in the hope that it will be useful, + * QIS Surveillance App App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with Foobar. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.test.utils; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e844d667e6..a4f6b6df9b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,6 +32,7 @@ android:theme="@style/EyeSeeTheme" tools:replace="android:icon" > + @@ -58,16 +59,6 @@ - - - + + + + + + + + + + + + + . + --> + + + + + + + + +
+ + +
+
+
+ + + + + + + diff --git a/app/src/main/assets/monitor/monitor.js b/app/src/main/assets/monitor/monitor.js new file mode 100644 index 0000000000..287be44008 --- /dev/null +++ b/app/src/main/assets/monitor/monitor.js @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2016. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ +function Monitor() { + //Map of i18n messages + this.messages = {}; + + //Map of tables + this.tables = {}; + + //Current TimeUnit + this.timeUnit = "months"; +} + +//Update timeUnit dinamically +Monitor.prototype.updateTimeUnit = function(sel){ + //Update current timeUnit + this.timeUnit = sel.value; + //Reload tables + this.drawTables(); +}; + +//Updates messages map +Monitor.prototype.updateMessages = function(msg) { + this.messages = msg; + + //Replace dom element values with the right ones + for (var key in this.messages) { + if (this.messages.hasOwnProperty(key)) { + var element = document.getElementById(key); + if (element) { + element.innerHTML = this.messages[key]; + } + } + } +}; + +//Add new table +Monitor.prototype.addTable = function(title) { + //Table has already been added + if (this.tables[title]) { + return; + } + + //Adds new item to map + this.tables[title] = { + title: title, + rows: [] + }; +}; + +//Add new table +Monitor.prototype.addRow = function(title,row) { + var table=this.tables[title]; + //Table has already been added + if (!table) { + return; + } + + table.rows.push(row); +}; + +//Reloads tables from data according to current timeUnit +Monitor.prototype.drawTables = function(){ + document.getElementById("statsContainer").innerHTML=""; + + //Loop over tables and repaint + for (var tableKey in this.tables) { + if (this.tables.hasOwnProperty(tableKey)) { + this.drawTable(tableKey); + } + } +}; + +//Draws table into page +Monitor.prototype.drawTable = function(title){ + var table=this.tables[title]; + //Table has already been added + if (!table) { + return; + } + + //Add table container + this.drawTableContainer(table); + + //Add each row to the table + var tableHashCode = table.title.hashCode(); + var tbodyDOM=document.getElementById("tbody"+tableHashCode); + for(var i=0;i"; + return rowHtml; +}; + +//Builds td markup for each table row +Monitor.prototype.buildColumn = function (row, i){ + var columnHtml = "" + columnHtml = columnHtml + row.columnData[this.timeUnit][i]; + columnHtml = columnHtml+""; + return columnHtml; +}; + +//Adds a hashCode to String so you can generate a table Id from its title +String.prototype.hashCode = function() { + var hash = 0, i, chr, len; + if (this.length === 0) return hash; + for (i = 0, len = this.length; i < len; i++) { + chr = this.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; +}; + +var monitor = new Monitor(); diff --git a/app/src/main/assets/monitor/static.html b/app/src/main/assets/monitor/static.html new file mode 100644 index 0000000000..fa4a40ff11 --- /dev/null +++ b/app/src/main/assets/monitor/static.html @@ -0,0 +1,244 @@ + + + + + + + + + +
+ + +
+
+
+ Suspected and Positive cases +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Period + + Jan + + Feb + + Mar + + Apr + + May + + Jun +
+ Suspected cases + + 7 + + 3 + + 7 + + 8 + + 10 + + 10 +
+   Pf/Pv + + 7 + + 3 + + 7 + + 8 + + 10 + + 10 +
+ Positivity rate + + 57% + + 67% + + 86% + + 63% + + 70% + + 30% +
+
+
+
+ Stock consumption +
+ + + + + + + + + + + + + + + + + + + + + +
+ Period + + Jan + + Feb + + Mar + + Apr + + May + + Jun +
+ AS/MQ + + 0 + + 3 + + 4 + + 3 + + 2 + + 0 +
+
+
+
+ + + diff --git a/app/src/main/assets/question_images/rdt_negative.png b/app/src/main/assets/question_images/rdt_negative.png index b57427f512..ada4d203d8 100644 Binary files a/app/src/main/assets/question_images/rdt_negative.png and b/app/src/main/assets/question_images/rdt_negative.png differ diff --git a/app/src/main/assets/question_images/rdt_no_tested.png b/app/src/main/assets/question_images/rdt_no_tested.png index 6b6c640551..3bb6677566 100644 Binary files a/app/src/main/assets/question_images/rdt_no_tested.png and b/app/src/main/assets/question_images/rdt_no_tested.png differ diff --git a/app/src/main/assets/question_images/rdt_positive.png b/app/src/main/assets/question_images/rdt_positive.png index a86cd2b363..3aaf4b4fdb 100644 Binary files a/app/src/main/assets/question_images/rdt_positive.png and b/app/src/main/assets/question_images/rdt_positive.png differ diff --git a/app/src/main/assets/question_images/risk_group_another_country.png b/app/src/main/assets/question_images/risk_group_another_country.png index 7e5fe12617..690a514886 100644 Binary files a/app/src/main/assets/question_images/risk_group_another_country.png and b/app/src/main/assets/question_images/risk_group_another_country.png differ diff --git a/app/src/main/assets/question_images/risk_group_forest.png b/app/src/main/assets/question_images/risk_group_forest.png index 18d0d32d1e..c35636c1bd 100644 Binary files a/app/src/main/assets/question_images/risk_group_forest.png and b/app/src/main/assets/question_images/risk_group_forest.png differ diff --git a/app/src/main/assets/question_images/risk_group_none.png b/app/src/main/assets/question_images/risk_group_none.png index dcb2275ff4..addbd68c4b 100644 Binary files a/app/src/main/assets/question_images/risk_group_none.png and b/app/src/main/assets/question_images/risk_group_none.png differ diff --git a/app/src/main/assets/question_images/risk_group_plantation.png b/app/src/main/assets/question_images/risk_group_plantation.png index e3270642ba..05561ec1d0 100644 Binary files a/app/src/main/assets/question_images/risk_group_plantation.png and b/app/src/main/assets/question_images/risk_group_plantation.png differ diff --git a/app/src/main/assets/question_images/sex_female.png b/app/src/main/assets/question_images/sex_female.png index 40cb9242a3..dd77f584b6 100644 Binary files a/app/src/main/assets/question_images/sex_female.png and b/app/src/main/assets/question_images/sex_female.png differ diff --git a/app/src/main/assets/question_images/sex_male.png b/app/src/main/assets/question_images/sex_male.png index 831c5f5700..8c387544ec 100644 Binary files a/app/src/main/assets/question_images/sex_male.png and b/app/src/main/assets/question_images/sex_male.png differ diff --git a/app/src/main/assets/question_images/specie_mix.png b/app/src/main/assets/question_images/specie_mix.png index dc73e15ab7..95eb5d29fc 100644 Binary files a/app/src/main/assets/question_images/specie_mix.png and b/app/src/main/assets/question_images/specie_mix.png differ diff --git a/app/src/main/assets/question_images/specie_pf.png b/app/src/main/assets/question_images/specie_pf.png index 29e163e2bf..8931b6988f 100644 Binary files a/app/src/main/assets/question_images/specie_pf.png and b/app/src/main/assets/question_images/specie_pf.png differ diff --git a/app/src/main/assets/question_images/specie_pv.png b/app/src/main/assets/question_images/specie_pv.png index 9f5846a374..0b8a6c91aa 100644 Binary files a/app/src/main/assets/question_images/specie_pv.png and b/app/src/main/assets/question_images/specie_pv.png differ diff --git a/app/src/main/assets/question_images/treatment_adolescent.png b/app/src/main/assets/question_images/treatment_adolescent.png index 5fb848aead..d9c122b38f 100644 Binary files a/app/src/main/assets/question_images/treatment_adolescent.png and b/app/src/main/assets/question_images/treatment_adolescent.png differ diff --git a/app/src/main/assets/question_images/treatment_adult.png b/app/src/main/assets/question_images/treatment_adult.png index 0db6924c86..9be4fab918 100644 Binary files a/app/src/main/assets/question_images/treatment_adult.png and b/app/src/main/assets/question_images/treatment_adult.png differ diff --git a/app/src/main/assets/question_images/treatment_as_mq.png b/app/src/main/assets/question_images/treatment_as_mq.png new file mode 100644 index 0000000000..9d262d3279 Binary files /dev/null and b/app/src/main/assets/question_images/treatment_as_mq.png differ diff --git a/app/src/main/assets/question_images/treatment_child.png b/app/src/main/assets/question_images/treatment_child.png index ae2cf90446..8b31378d36 100644 Binary files a/app/src/main/assets/question_images/treatment_child.png and b/app/src/main/assets/question_images/treatment_child.png differ diff --git a/app/src/main/assets/question_images/treatment_heavy_adult.png b/app/src/main/assets/question_images/treatment_heavy_adult.png new file mode 100644 index 0000000000..8319f9e00c Binary files /dev/null and b/app/src/main/assets/question_images/treatment_heavy_adult.png differ diff --git a/app/src/main/assets/question_images/treatment_referral.png b/app/src/main/assets/question_images/treatment_referral.png index e43dc7dfab..0a4000d254 100644 Binary files a/app/src/main/assets/question_images/treatment_referral.png and b/app/src/main/assets/question_images/treatment_referral.png differ diff --git a/app/src/main/java/org/eyeseetea/malariacare/BaseActivity.java b/app/src/main/java/org/eyeseetea/malariacare/BaseActivity.java index 91652da882..efada851d3 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/BaseActivity.java +++ b/app/src/main/java/org/eyeseetea/malariacare/BaseActivity.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare; @@ -47,6 +47,7 @@ import org.eyeseetea.malariacare.database.model.Program; import org.eyeseetea.malariacare.database.model.Program$Table; import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.database.model.TabGroup; import org.eyeseetea.malariacare.database.utils.LocationMemory; import org.eyeseetea.malariacare.database.utils.PreferencesState; import org.eyeseetea.malariacare.database.utils.Session; @@ -65,9 +66,7 @@ public abstract class BaseActivity extends ActionBarActivity { */ public static final String SETTINGS_CALLER_ACTIVITY = "SETTINGS_CALLER_ACTIVITY"; - private static String TAG=".BaseActivity"; - - private SurveyLocationListener locationListener; + protected static String TAG=".BaseActivity"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -91,6 +90,19 @@ private void initView(Bundle savedInstanceState){ } } + /** + * Adds actionbar to the activity + */ + public void createActionBar(){ + Program program = Program.getFirstProgram(); + + if (program != null) { + android.support.v7.app.ActionBar actionBar = this.getSupportActionBar(); + LayoutUtils.setActionBarLogo(actionBar); + LayoutUtils.setActionBarText(actionBar, PreferencesState.getInstance().getOrgUnit(), program.getName()); + } + } + /** * Customize transitions for these activities */ @@ -114,6 +126,10 @@ public boolean onOptionsItemSelected(MenuItem item) { debugMessage("User asked for settings"); goSettings(); break; + case R.id.action_monitoring: + debugMessage("User asked for monitor"); + goMonitor(); + break; case R.id.action_license: debugMessage("User asked for license"); showAlertWithMessage(R.string.settings_menu_licence, R.raw.gpl); @@ -171,27 +187,14 @@ protected void goSettings(){ startActivity(new Intent(this, SettingsActivity.class)); } - /** - * Closes current session and goes back to loginactivity - */ - protected void logout(){ - new AlertDialog.Builder(this) - .setTitle(getApplicationContext().getString(R.string.settings_menu_logout)) - .setMessage(getApplicationContext().getString(R.string.dialog_content_logout_confirmation)) - .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface arg0, int arg1) { - Session.logout(); - finishAndGo(DashboardActivity.class); - } - }) - .setNegativeButton(android.R.string.no, null).create().show(); + protected void goMonitor(){ + startActivity(new Intent(this, MonitorActivity.class)); } public void newSurvey(View v){ - //Get Programs from database - List firstProgram = new Select().from(Program.class).where(Condition.column(Program$Table.ID_PROGRAM).eq(1)).queryList(); + TabGroup tabGroup = new Select().from(TabGroup.class).querySingle(); // Put new survey in session - Survey survey = new Survey(null, firstProgram.get(0), Session.getUser()); + Survey survey = new Survey(null, tabGroup, Session.getUser()); survey.save(); Session.setSurvey(survey); @@ -202,9 +205,10 @@ public void newSurvey(View v){ finishAndGo(SurveyActivity.class); } + private void prepareLocationListener(Survey survey){ - locationListener = new SurveyLocationListener(survey.getId_survey()); + SurveyLocationListener locationListener = new SurveyLocationListener(survey.getId_survey()); LocationManager locationManager = (LocationManager) LocationMemory.getContext().getSystemService(Context.LOCATION_SERVICE); if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { Log.d(TAG, "requestLocationUpdates via GPS"); diff --git a/app/src/main/java/org/eyeseetea/malariacare/CreateSurveyActivity.java b/app/src/main/java/org/eyeseetea/malariacare/CreateSurveyActivity.java deleted file mode 100644 index c848c80adb..0000000000 --- a/app/src/main/java/org/eyeseetea/malariacare/CreateSurveyActivity.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2015. - * - * This file is part of QIS Survelliance App. - * - * QIS Survelliance App is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * QIS Survelliance App 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . - */ - -package org.eyeseetea.malariacare; - -import android.app.AlertDialog; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.Spinner; - -import com.raizlabs.android.dbflow.sql.language.Select; - -import org.eyeseetea.malariacare.database.model.OrgUnit; -import org.eyeseetea.malariacare.database.model.Program; -import org.eyeseetea.malariacare.database.model.Survey; -import org.eyeseetea.malariacare.database.model.User; -import org.eyeseetea.malariacare.database.utils.Session; -import org.eyeseetea.malariacare.layout.adapters.general.OrgUnitArrayAdapter; -import org.eyeseetea.malariacare.layout.adapters.general.ProgramArrayAdapter; -import org.eyeseetea.malariacare.layout.utils.LayoutUtils; -import org.eyeseetea.malariacare.utils.Constants; - -import java.util.List; - - -public class CreateSurveyActivity extends BaseActivity { - - // UI references. - private Spinner orgUnitView; - private Spinner programView; - private OrgUnit orgUnitDefaultOption; - private Program programDefaultOption; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // Manage uncaught exceptions that may occur - //Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this)); - setContentView(R.layout.activity_create_survey); - - android.support.v7.app.ActionBar actionBar = this.getSupportActionBar(); - LayoutUtils.setActionBarLogo(actionBar); - - //Create default options - this.orgUnitDefaultOption = new OrgUnit(Constants.DEFAULT_SELECT_OPTION); - this.programDefaultOption = new Program(Constants.DEFAULT_SELECT_OPTION); - - //Populate Organization Unit DDL - List orgUnitList = new Select().all().from(OrgUnit.class).queryList(); - orgUnitList.add(0, orgUnitDefaultOption); - orgUnitView = (Spinner) findViewById(R.id.org_unit); - orgUnitView.setAdapter(new OrgUnitArrayAdapter(this, orgUnitList)); - - //Populate Program View DDL - List programList = new Select().all().from(Program.class).queryList(); - programList.add(0, programDefaultOption); - programView = (Spinner) findViewById(R.id.program); - programView.setAdapter(new ProgramArrayAdapter(this, programList)); - - } - - public boolean checkEverythingFilled() { - try { - return (!orgUnitView.getSelectedItem().equals(this.orgUnitDefaultOption) && !programView.getSelectedItem().equals(this.programDefaultOption)); - } catch (Exception ex) { - return false; - } - } - - public boolean checkSurveyDoesntExist() { - // Read Selected Items - OrgUnit orgUnit = (OrgUnit) orgUnitView.getSelectedItem(); - Program program = (Program) programView.getSelectedItem(); - - List existing = Survey.getUnsentSurveys(orgUnit, program); - return (existing == null || existing.size() == 0); - } - - /** - * Called when the user clicks the Send button - */ - public void createSurvey(View view) { - Log.i(".CreateSurveyActivity", "Saving survey and saving in session"); - - // Read Selected Items - OrgUnit orgUnit = (OrgUnit) orgUnitView.getSelectedItem(); - Program program = (Program) programView.getSelectedItem(); - - if (!checkEverythingFilled()) { - new AlertDialog.Builder(this) - .setTitle(getApplicationContext().getString(R.string.dialog_title_missing_selection)) - .setMessage(getApplicationContext().getString(R.string.dialog_content_missing_selection)) - .setPositiveButton(android.R.string.ok, null).create().show(); - } else if (!checkSurveyDoesntExist()) { - new AlertDialog.Builder(this) - .setTitle(getApplicationContext().getString(R.string.dialog_title_existing_survey)) - .setMessage(getApplicationContext().getString(R.string.dialog_content_existing_survey)) - .setPositiveButton(android.R.string.ok, null).create().show(); - } else { - // Put new survey in session - Survey survey = new Survey(orgUnit, program, Session.getUser()); - survey.save(); - Session.setSurvey(survey); - - //Call Survey Activity - finishAndGo(SurveyActivity.class); - } - } - - -} diff --git a/app/src/main/java/org/eyeseetea/malariacare/DashboardActivity.java b/app/src/main/java/org/eyeseetea/malariacare/DashboardActivity.java index eb51674755..7c3b89defe 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/DashboardActivity.java +++ b/app/src/main/java/org/eyeseetea/malariacare/DashboardActivity.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare; @@ -50,6 +50,8 @@ public class DashboardActivity extends BaseActivity { protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); + createActionBar(); + setContentView(R.layout.fragment_dashboard); if (savedInstanceState == null) { DashboardUnsentFragment detailsFragment = new DashboardUnsentFragment(); diff --git a/app/src/main/java/org/eyeseetea/malariacare/EyeSeeTeaApplication.java b/app/src/main/java/org/eyeseetea/malariacare/EyeSeeTeaApplication.java index dbb5f992e3..dd5f1e2b04 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/EyeSeeTeaApplication.java +++ b/app/src/main/java/org/eyeseetea/malariacare/EyeSeeTeaApplication.java @@ -1,43 +1,57 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare; +import android.app.Activity; import android.app.Application; import android.content.Context; +import android.content.res.AssetManager; import android.support.multidex.MultiDex; import android.telephony.TelephonyManager; import com.crashlytics.android.Crashlytics; import com.raizlabs.android.dbflow.config.FlowManager; +import com.raizlabs.android.dbflow.sql.index.Index; +import org.eyeseetea.malariacare.database.migrations.Migration2Database; +import org.eyeseetea.malariacare.database.model.Match; +import org.eyeseetea.malariacare.database.model.Match$Table; +import org.eyeseetea.malariacare.database.model.QuestionOption; +import org.eyeseetea.malariacare.database.model.QuestionOption$Table; +import org.eyeseetea.malariacare.database.model.QuestionRelation; +import org.eyeseetea.malariacare.database.model.QuestionRelation$Table; +import org.eyeseetea.malariacare.database.model.Value; +import org.eyeseetea.malariacare.database.model.Value$Table; import org.eyeseetea.malariacare.database.utils.LocationMemory; import org.eyeseetea.malariacare.database.utils.PreferencesState; import org.eyeseetea.malariacare.database.utils.Session; import org.eyeseetea.malariacare.phonemetadata.PhoneMetaData; +import org.eyeseetea.malariacare.utils.Constants; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; import io.fabric.sdk.android.Fabric; /** * Created by nacho on 04/08/15. */ -public class EyeSeeTeaApplication extends Application { +public class EyeSeeTeaApplication extends Dhis2Application { @Override public void onCreate() { @@ -50,9 +64,21 @@ public void onCreate() { PhoneMetaData phoneMetaData=this.getPhoneMetadata(); Session.setPhoneMetaData(phoneMetaData); - FlowManager.init(this); + FlowManager.init(this, "_EyeSeeTeaDB"); + createDBIndexes(); + Migration2Database.postMigrate(); } + private void createDBIndexes(){ + new Index(Constants.QUESTION_OPTION_IDX).on(QuestionOption.class, QuestionOption$Table.ID_QUESTION).enable(); + new Index(Constants.QUESTION_RELATION_IDX).on(QuestionRelation.class, QuestionRelation$Table.OPERATION).enable(); + //XXX This should be reviewed + new Index(Constants.QUESTION_RELATION_IDX).on(QuestionRelation.class, QuestionRelation$Table.ID_QUESTION).enable(); + new Index(Constants.MATCH_IDX).on(Match.class, Match$Table.ID_QUESTION_RELATION).enable(); + new Index(Constants.VALUE_IDX).on(Value.class, Value$Table.ID_SURVEY).enable(); + } + + PhoneMetaData getPhoneMetadata(){ PhoneMetaData phoneMetaData=new PhoneMetaData(); TelephonyManager phoneManagerMetaData=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); @@ -68,6 +94,12 @@ PhoneMetaData getPhoneMetadata(){ @Override public void onTerminate() { super.onTerminate(); + FlowManager.destroy(); + } + + @Override + public Class getMainActivity() { + return new DashboardActivity().getClass(); } @Override @@ -75,4 +107,7 @@ protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } + + + } diff --git a/app/src/main/java/org/eyeseetea/malariacare/LoginActivity.java b/app/src/main/java/org/eyeseetea/malariacare/LoginActivity.java index 2f4a1e43c2..8eef2d22dd 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/LoginActivity.java +++ b/app/src/main/java/org/eyeseetea/malariacare/LoginActivity.java @@ -1,404 +1,135 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ -package org.eyeseetea.malariacare; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.annotation.TargetApi; +package org.eyeseetea.malariacare; -import android.app.Activity; import android.app.LoaderManager.LoaderCallbacks; -import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; +import android.content.SharedPreferences; import android.database.Cursor; -import android.net.Uri; -import android.os.AsyncTask; - -import android.os.Build; import android.os.Bundle; -import android.provider.ContactsContract; +import android.preference.PreferenceManager; import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.inputmethod.EditorInfo; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.Button; import android.widget.EditText; -import android.widget.TextView; -import com.raizlabs.android.dbflow.sql.language.Select; +import com.squareup.otto.Subscribe; -import org.eyeseetea.malariacare.database.model.Tab; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.PullController; import org.eyeseetea.malariacare.database.model.User; import org.eyeseetea.malariacare.database.utils.PopulateDB; +import org.eyeseetea.malariacare.database.utils.PreferencesState; import org.eyeseetea.malariacare.database.utils.Session; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import org.eyeseetea.malariacare.network.ServerAPIController; +import org.hisp.dhis.android.sdk.job.NetworkJob; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; +import org.hisp.dhis.android.sdk.persistence.preferences.ResourceType; /** * Login Screen. * It shows only when the user has an open session. */ -public class LoginActivity extends Activity implements LoaderCallbacks { +public class LoginActivity extends org.hisp.dhis.android.sdk.ui.activities.LoginActivity implements LoaderCallbacks { + private static final String TAG = ".LoginActivity"; /** - * A dummy authentication store containing known user names and passwords. - * TODO: remove after connecting to a real authentication system. + * DHIS server URL */ + private String serverUrl; - private static final Map DUMMY_CREDENTIALS; - static { - Map aMap = new HashMap(); - aMap.put("user", "user"); - aMap.put("admin", "admin"); - DUMMY_CREDENTIALS = Collections.unmodifiableMap(aMap); - } /** - * Keep track of the login task to ensure we can cancel it if requested. + * DHIS username account */ - private UserLoginTask mAuthTask = null; - - // UI references. - private AutoCompleteTextView mUserView; - private EditText mPasswordView; - private View mProgressView; - private View mUserLoginFormView; - private View mLoginFormView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - Log.d(".LoginActivity","onCreate"); - super.onCreate(savedInstanceState); - - //User already logged in --> dashboard - Iterator users = new Select().all().from(User.class).queryList().iterator(); - if (users.hasNext()) { - goDashBoard(users.next()); - return; - } - - //Show form - initView(); - } + private String username; /** - * Initialize login form and listeners + * DHIS password (required since push is done natively instead of using sdk) */ - private void initView(){ - setContentView(R.layout.login_layout); - // Set up the login form. - mUserView = (AutoCompleteTextView) findViewById(R.id.user); - populateAutoComplete(); - - mPasswordView = (EditText) findViewById(R.id.password); - mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() { - @Override - public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) { - if (id == R.id.login || id == EditorInfo.IME_NULL) { - attemptLogin(); - return true; - } - return false; - } - }); - - Button mUserSignInButton = (Button) findViewById(R.id.email_sign_in_button); - mUserSignInButton.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View view) { - attemptLogin(); - } - }); - - mLoginFormView = findViewById(R.id.login_form); - mProgressView = findViewById(R.id.login_progress); - } - - private void goDashBoard(User user) { - Log.i(".LoginActivity", "User already logged in --> Dashboard"); - Session.setUser(user); - startActivity(new Intent(LoginActivity.this, DashboardActivity.class)); - } + private String password; - - /** - * Attempts to sign in or register the account specified by the login form. - * If there are form errors (invalid email, missing fields, etc.), the - * errors are presented and no actual login attempt is made. - */ - public void attemptLogin() { - Log.i(".LoginActivity", "attempt!!"); - - if (mAuthTask != null) { - return; - } - - // Reset errors. - mUserView.setError(null); - - // Store values at the time of the login attempt. - String user = mUserView.getText().toString(); - String password = mPasswordView.getText().toString(); - - if(!hasGoodCredentials(user,password)){ - mUserView.requestFocus(); - mUserView.setError(getString(R.string.login_error_bad_credentials)); - return; - } - - showProgress(true); - mAuthTask = new UserLoginTask(user); - mAuthTask.execute((Void) null); - } - - /** - * Login form is cleaned when the activity is back to foreground - */ @Override - public void onResume(){ - cleanForm(); - super.onResume(); - } - - /** - * Checks if the pair user/password matches any dummy credentials. - * @param user - * @param password - * @return - */ - private boolean hasGoodCredentials(String user, String password){String expectedPassword=DUMMY_CREDENTIALS.get(user); - if(null==expectedPassword || expectedPassword.isEmpty()){ - return false; - } - return expectedPassword.equals(password); - } - - /** - * Cleans form before launching intent to dashboard - */ - private void cleanForm(){ - if(mUserView!=null) { - mUserView.setError(null); - mUserView.setText(null); - } - if(mPasswordView!=null) { - mPasswordView.setText(null); - } - } - - /** - * Shows the progress UI and hides the login form. - */ - @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) - public void showProgress(final boolean show) { - // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow - // for very easy animations. If available, use these APIs to fade-in - // the progress spinner. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { - int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime); - - mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); - mLoginFormView.animate().setDuration(shortAnimTime).alpha( - show ? 0 : 1).setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); - } - }); + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); - mProgressView.animate().setDuration(shortAnimTime).alpha( - show ? 1 : 0).setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); - } - }); - } else { - // The ViewPropertyAnimator APIs are not available, so simply show - // and hide the relevant UI components. - mProgressView.setVisibility(show ? View.VISIBLE : View.GONE); - mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE); - } - } + //Populate server with the current value + EditText serverText = (EditText) findViewById(org.hisp.dhis.android.sdk.R.id.server_url); + serverText.setText(ServerAPIController.getServerUrl()); + //Readonly + //serverText.setEnabled(false); - /*************************** - * FIXME: Not required so far - ***************************/ - private void populateAutoComplete() { - getLoaderManager().initLoader(0, null, this); + //Username, Password blanks to force real login + EditText usernameEditText = (EditText) findViewById(R.id.username); + usernameEditText.setText(""); + EditText passwordEditText = (EditText) findViewById(R.id.password); + passwordEditText.setText(""); } @Override - public Loader onCreateLoader(int i, Bundle bundle) { - return new CursorLoader(this, - // Retrieve data rows for the device user's 'profile' contact. - Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI, - ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION, - - // Select only email addresses. - ContactsContract.Contacts.Data.MIMETYPE + - " = ?", new String[]{ContactsContract.CommonDataKinds.Email - .CONTENT_ITEM_TYPE}, - - // Show primary email addresses first. Note that there won't be - // a primary email address if the user hasn't specified one. - ContactsContract.Contacts.Data.IS_PRIMARY + " DESC"); + public Loader onCreateLoader(int id, Bundle args) { + return null; } @Override - public void onLoadFinished(Loader cursorLoader, Cursor cursor) { - List emails = new ArrayList(); - cursor.moveToFirst(); - while (!cursor.isAfterLast()) { - emails.add(cursor.getString(ProfileQuery.ADDRESS)); - cursor.moveToNext(); - } + public void onLoadFinished(Loader loader, Cursor data) { - addEmailsToAutoComplete(emails); } @Override - public void onLoaderReset(Loader cursorLoader) { + public void onLoaderReset(Loader loader) { } - private interface ProfileQuery { - String[] PROJECTION = { - ContactsContract.CommonDataKinds.Email.ADDRESS, - ContactsContract.CommonDataKinds.Email.IS_PRIMARY, - }; - - int ADDRESS = 0; - int IS_PRIMARY = 1; + @Subscribe + public void onLoginFinished(NetworkJob.NetworkJobResult result) { + if(result!=null && result.getResourceType().equals(ResourceType.USERS)) { + if(result.getResponseHolder().getApiException() == null) { + goSettingsWithRightExtras(); + } else { + onLoginFail(result.getResponseHolder().getApiException()); + } + } } + private void goSettingsWithRightExtras(){ - private void addEmailsToAutoComplete(List emailAddressCollection) { - //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list. - ArrayAdapter adapter = - new ArrayAdapter(LoginActivity.this, - android.R.layout.simple_dropdown_item_1line, emailAddressCollection); + Intent intent = new Intent(LoginActivity.this,SettingsActivity.class); + intent = propagateExtra(intent); - mUserView.setAdapter(adapter); + finish(); + startActivity(intent); } - /** - * Represents an asynchronous login/registration task used to authenticate - * the user. - */ - public class UserLoginTask extends AsyncTask { - - private final String mUser; - private User user; - - UserLoginTask(String user) { - mUser = user; + private Intent propagateExtra(Intent intent){ + if(getIntent().getBooleanExtra(SettingsActivity.SETTINGS_CHANGING_ORGUNIT,false)){ + Log.i(TAG, "propagateExtra -> Changing orgunit"); + intent.putExtra(SettingsActivity.SETTINGS_CHANGING_ORGUNIT,true); } - @Override - protected Boolean doInBackground(Void... params) { - // TODO: attempt authentication against a network service. - try { - initUser(); - initDataIfRequired(); - }catch(Exception ex) { - Log.e(".LoginActivity", "Error doInBackground login -> dashboard", ex); - return false; - } - - return true; + if(getIntent().getBooleanExtra(SettingsActivity.SETTINGS_CHANGING_SERVER,false)){ + Log.i(TAG, "propagateExtra -> Changing server"); + intent.putExtra(SettingsActivity.SETTINGS_CHANGING_SERVER,true); } - @Override - protected void onPostExecute(final Boolean success) { - stopProgress(); - //something went wrong - if(!success){ - mUserView.requestFocus(); - mUserView.setError(getString(R.string.login_error_bad_credentials)); - return; - } - //finishAndGo dashboard - Log.i(".LoginActivity", "Logged in!"); - // Get the not-sent surveys ordered by date - goDashBoard(user); - } - - @Override - protected void onCancelled() { - stopProgress(); - } - - /** - * Add user to table and session - */ - private void initUser() { - // In case no user was previously set in the database we create one. Otherwise we update it - List users = new Select().all().from(User.class).queryList(); - if (users.size() == 0) { - this.user = new User(mUser, mUser); - this.user.save(); - } else { - this.user = users.get(0); - this.user.setName(mUser); - this.user.setUid(mUser); - this.user.update(); - } - } - - private void initDataIfRequired() throws IOException { - if (new Select().count().from(Tab.class).count()!=0) { - return; - } - - Log.i(".LoginActivity", "Populating DB"); - - // As this is only executed the first time the app is loaded, and we still don't have a way to create users, surveys, etc, here - // we will create a dummy user, survey, orgUnit, program, etc. To be used in local save - PopulateDB.populateDummyData(); - try { - PopulateDB.populateDB(getAssets()); - } catch (IOException e) { - Log.e(".LoginActivity", "Error populating DB", e); - throw e; - } - Log.i(".LoginActivity", "DB populated"); - } - - /** - * Stops task and progress spinner - */ - private void stopProgress(){ - mAuthTask = null; - showProgress(false); - } + intent.putExtra(SettingsActivity.LOGIN_BEFORE_CHANGE_DONE,true); + return intent; } + } diff --git a/app/src/main/java/org/eyeseetea/malariacare/MonitorActivity.java b/app/src/main/java/org/eyeseetea/malariacare/MonitorActivity.java new file mode 100644 index 0000000000..1bad970dd2 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/MonitorActivity.java @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.content.LocalBroadcastManager; +import android.util.Log; +import android.view.View; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.Spinner; + +import com.raizlabs.android.dbflow.sql.language.Select; + +import org.eyeseetea.malariacare.database.model.OrgUnit; +import org.eyeseetea.malariacare.database.model.Program; +import org.eyeseetea.malariacare.database.utils.Session; +import org.eyeseetea.malariacare.layout.adapters.general.OrgUnitArrayAdapter; +import org.eyeseetea.malariacare.layout.adapters.general.ProgramArrayAdapter; +import org.eyeseetea.malariacare.layout.utils.LayoutUtils; +import org.eyeseetea.malariacare.monitor.MonitorBuilder; +import org.eyeseetea.malariacare.services.MonitorService; +import org.eyeseetea.malariacare.utils.Constants; + +import java.util.List; + + +/** + * Activity that shows summary info related to the surveys that have been sent + * @author ivan.arrizabalaga + */ +public class MonitorActivity extends BaseActivity { + + /** + * Local monitor html + */ + public static final String FILE_ANDROID_ASSET_MONITOR_MONITOR_HTML = "file:///android_asset/monitor/monitor.html"; + + /** + * Reference to webview ui + */ + private WebView webView; + + /** + * Monitor receiver to reload monitor view after calculation + */ + private MonitorReceiver monitorReceiver; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_monitor); + createActionBar(); + } + + @Override + public void onResume(){ + Log.d(TAG, "onResume"); + //Listen for data + registerMonitorReceiver(); + + //Ask for data + Intent surveysIntent=new Intent(this, MonitorService.class); + surveysIntent.putExtra(MonitorService.SERVICE_METHOD, MonitorService.PREPARE_MONITOR_DATA); + this.startService(surveysIntent); + + //Go on with resume + super.onResume(); + } + + @Override + public void onStop(){ + Log.d(TAG, "onStop"); + unregisterMonitorReceiver(); + stopMonitor(); + super.onStop(); + } + + /** + * Register a monitor receiver to load monitor data into webview + */ + private void registerMonitorReceiver() { + Log.d(TAG, "registerMonitorReceiver"); + + if (monitorReceiver == null) { + monitorReceiver= new MonitorReceiver(); + LocalBroadcastManager.getInstance(this).registerReceiver(monitorReceiver, new IntentFilter(MonitorService.PREPARE_MONITOR_DATA)); + } + } + /** + * Unregisters the monitor receiver. + * It really important to do this, otherwise each receiver will invoke its code. + */ + public void unregisterMonitorReceiver() { + if (monitorReceiver != null) { + LocalBroadcastManager.getInstance(this).unregisterReceiver(monitorReceiver); + monitorReceiver = null; + } + } + + public void reloadMonitor(final MonitorBuilder monitorBuilder) { + initMonitor(); + //onPageFinish load data + webView.setWebViewClient(new WebViewClient() { + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + monitorBuilder.addDataToView(webView); + } + }); + //Load html + webView.loadUrl(FILE_ANDROID_ASSET_MONITOR_MONITOR_HTML); + } + + private WebView initMonitor() { + webView = (WebView) findViewById(R.id.dashboard_monitor); + //Init webView settings + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + webView.getSettings().setAllowUniversalAccessFromFileURLs(true); + webView.getSettings().setAllowFileAccessFromFileURLs(true); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + WebView.setWebContentsDebuggingEnabled(true); + } + webView.getSettings().setJavaScriptEnabled(true); + + return webView; + } + + /** + * Stops webView gracefully + */ + private void stopMonitor(){ + try{ + if(webView!=null){ + webView.stopLoading(); + webView=null; + } + }catch(Exception e){ + e.printStackTrace(); + } + } + + /** + * Inner private class that receives the result from the service + */ + private class MonitorReceiver extends BroadcastReceiver { + private MonitorReceiver() { + } + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive"); + //Listening only intents from this method + if (MonitorService.PREPARE_MONITOR_DATA.equals(intent.getAction())) { + MonitorBuilder monitorBuilder = (MonitorBuilder) Session.popServiceValue(MonitorService.PREPARE_MONITOR_DATA); + reloadMonitor(monitorBuilder); + } + } + } + + +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/ProgressActivity.java b/app/src/main/java/org/eyeseetea/malariacare/ProgressActivity.java new file mode 100644 index 0000000000..1fac1a45c8 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/ProgressActivity.java @@ -0,0 +1,437 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.squareup.otto.Subscribe; + +import org.eyeseetea.malariacare.database.iomodules.dhis.exporter.PushController; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.PullController; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.SyncProgressStatus; +import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.database.utils.Session; +import org.hisp.dhis.android.sdk.controllers.DhisService; +import org.hisp.dhis.android.sdk.events.UiEvent; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; + +import java.util.ArrayList; +import java.util.List; + +public class ProgressActivity extends Activity { + + private static final String TAG=".ProgressActivity"; + + /** + * Intent param that tells what to do (push, pull or push before pull) + */ + public static final String TYPE_OF_ACTION="TYPE_OF_ACTION"; + + /** + * Intent param that tells what do before push + */ + public static final String AFTER_ACTION="AFTER_ACTION"; + /** + * To pull data from server + */ + public static final int ACTION_PULL=0; + + /** + * To push a single survey to server + */ + public static final int ACTION_PUSH=1; + + /** + * To dont show the survey pushed feedback + */ + public static final int DONT_SHOW_FEEDBACK = 1; + + /** + * To show the survey pushed feedback + */ + public static final int SHOW_FEEDBACK = 2; + /** + * To push every unsent data to server before pulling metadata + */ + public static final int ACTION_PUSH_BEFORE_PULL=2; + + /** + * Num of expected steps while pulling + */ + private static final int MAX_PULL_STEPS=7; + + /** + * Num of expected steps while pushing + */ + private static final int MAX_PUSH_STEPS=4; + /** + * Used for control new steps + */ + public static Boolean PULL_IS_ACTIVE =false; + + /** + * Used for control autopull from login + */ + public static Boolean PULL_CANCEL =false; + + ProgressBar progressBar; + TextView textView; + boolean pullAfterPushInProgress; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_progress); + PULL_CANCEL = false; + PULL_IS_ACTIVE = true; + prepareUI(); + } + + private void cancellPull() { + if(PULL_IS_ACTIVE) { + PULL_CANCEL = true; + PULL_IS_ACTIVE = false; + step(getBaseContext().getResources().getString(R.string.cancellingPull)); + if(PullController.getInstance().finishPullJob()) + finishAndGo(LoginActivity.class); + } + } + + @Override + public void onResume() { + super.onResume(); + try { + Dhis2Application.bus.register(this); + }catch(Exception e){ + e.printStackTrace(); + Dhis2Application.bus.unregister(this); + Dhis2Application.bus.register(this); + } + launchAction(); + } + + @Override + public void onPause() { + super.onPause(); + unregisterBus(); + //TODO this is not expected in pictureapp + if(PULL_CANCEL==true) { + finishAndGo(LoginActivity.class); + } + } + + private void unregisterBus(){ + try { + Dhis2Application.bus.unregister(this); + }catch(Exception e){ + Log.e(TAG,e.getMessage()); + } + } + + private void prepareUI(){ + progressBar=(ProgressBar)findViewById(R.id.pull_progress); + progressBar.setMax(isAPush() ? MAX_PUSH_STEPS : MAX_PULL_STEPS); + textView=(TextView)findViewById(R.id.pull_text); + final Button button = (Button) findViewById(R.id.cancelPullButton); + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + cancellPull(); + } + }); + } + + @Subscribe + public void onProgressChange(final SyncProgressStatus syncProgressStatus) { + if(syncProgressStatus ==null){ + return; + } + runOnUiThread(new Runnable() { + @Override + public void run() { + if (syncProgressStatus.hasError()) { + showException(syncProgressStatus.getException().getMessage()); + return; + } + + //Step + if (syncProgressStatus.hasProgress()) { + step(syncProgressStatus.getMessage()); + return; + } + + //Finish + if (syncProgressStatus.isFinish()) { + showAndMoveOn(); + } + } + }); + } + + /** + * Launches a pull or push according to an intent extra + */ + private void launchAction(){ + + //Clear flag + pullAfterPushInProgress=false; + + //Push or Pull according to extra param from intent + if(isAPush()){ + launchPush(); + }else { + launchPull(); + } + } + + /** + * Shows a dialog with the given message y move to login after showing error + * @param msg + */ + private void showException(String msg){ + final boolean isAPush=isAPush(); + String title=getDialogTitle(isAPush); + + new AlertDialog.Builder(this) + .setCancelable(false) + .setTitle(title) + .setMessage(msg) + .setNeutralButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + //A crash during a push might be recoverable -> dashboard + if (isAPush) { + Log.d(TAG, "Push crashed, moving to dashboard..."); + finishAndGo(DashboardActivity.class); + } else { + //A crash during a pull requires to start from scratch -> logout + Log.d(TAG, "Logging out from sdk..."); + DhisService.logOutUser(ProgressActivity.this); + } + } + }) + .create() + .show(); + } + + /** + * Prints the step in the progress bar + * @param msg + */ + private void step(final String msg) { + final int currentProgress = progressBar.getProgress(); + progressBar.setProgress(currentProgress + 1); + textView.setText(msg); + } + + /** + * Shows a dialog to tell that pull is done and then moves into the dashboard. + * + */ + private void showAndMoveOn() { + final boolean isAPush=isAPush(); + + //Annotate pull is done + if(!isAPush) { + //If is not active, we need restart the process + if(!PULL_IS_ACTIVE) { + try{ + Dhis2Application.bus.unregister(this);} + catch(Exception e) { + } + finishAndGo(LoginActivity.class); + return; + } + else + annotateFirstPull(true); + } + + //Show final step -> done + step(getString(R.string.progress_pull_done)); + + String title=getDialogTitle(isAPush); + + final int msg=getDoneMessage(); + + new AlertDialog.Builder(this) + .setCancelable(false) + .setTitle(title) + .setMessage(msg) + .setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface arg0, int arg1) { + //Pull -> Settings + if (!isAPush()) { + //Move back to setting with extras + Intent intent = new Intent(ProgressActivity.this,SettingsActivity.class); + intent.putExtra(SettingsActivity.SETTINGS_CHANGING_SERVER, true); + intent.putExtra(SettingsActivity.LOGIN_BEFORE_CHANGE_DONE, true); + finish(); + startActivity(intent); + return; + } + + //Push before pull -> Dashboard + if (!hasAPullAfterPush()){ + finishAndGo(DashboardActivity.class); + return; + } + + //Start pull after push + pullAfterPushInProgress = true; + + launchPull(); + + return; + + } + }).create().show(); + + } + + /** + * Once an action is over there is a message that changes depending on the kind of action: + * -Pull: Pull ok, let's move to dashboard + * -Push (single): Push ok, let's move to dashboard + * -Push (before pull): Push ok, let's start with the pull + * + * @return + */ + private int getDoneMessage(){ + boolean isAPush=isAPush(); + + //Pull + if(!isAPush){ + return R.string.dialog_pull_success; + } + + //Push before pull + if(hasAPullAfterPush()){ + return R.string.dialog_push_before_pull_success; + } + + //Push (single) + return R.string.dialog_push_success; + } + + private void annotateFirstPull(boolean value) { +// SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); +// SharedPreferences.Editor editor = sharedPreferences.edit(); +// editor.putBoolean(getString(R.string.pull_metadata), value); +// editor.commit(); + } + + /** + * Tells if a push is required + * @return + */ + private boolean isAPush() { + //A push before pull + if(pullAfterPushInProgress){ + return false; + } + + //Check intent params + Intent intent=getIntent(); + //Not a pull -> is a Push + return (intent!=null && intent.getIntExtra(TYPE_OF_ACTION,ACTION_PULL)!=ACTION_PULL); + } + + + /** + * Tells is the intent requires a Pull after the push is done + * @return + */ + private boolean hasAPullAfterPush(){ + Intent intent=getIntent(); + return (intent!=null && intent.getIntExtra(TYPE_OF_ACTION,ACTION_PULL)==ACTION_PUSH_BEFORE_PULL); + } + + private String getDialogTitle(boolean isAPush){ + int stringId=isAPush?R.string.dialog_title_push_response:R.string.dialog_title_pull_response; + return getString(stringId); + } + + private void launchPull(){ + annotateFirstPull(false); + progressBar.setProgress(0); + progressBar.setMax(MAX_PULL_STEPS); + PullController.getInstance().pull(this); + } + + /** + * Launches a push using the PushController according to the intent params + */ + private void launchPush(){ + annotateFirstPull(true); + progressBar.setProgress(0); + progressBar.setMax(MAX_PUSH_STEPS); + + List surveys=findSurveysToPush(); + PushController.getInstance().push(this, surveys); + } + + /** + * Find the surveys that are going to be pushed + * @return + */ + private List findSurveysToPush(){ + if(hasAPullAfterPush()){ + return Survey.getAllUnsentSurveys(); + } + + List surveys=new ArrayList<>(); + surveys.add(Session.getSurvey()); + return surveys; + } + + @Subscribe + public void onLogoutFinished(UiEvent uiEvent){ + //No event or not a logout event -> done + if(uiEvent==null || !uiEvent.getEventType().equals(UiEvent.UiEventType.USER_LOG_OUT)){ + return; + } + Log.d(TAG,"Logging out from sdk...OK"); + Session.logout(); + //Go to login + finishAndGo(LoginActivity.class); + } + + /** + * Finish current activity and launches an activity with the given class + * @param targetActivityClass Given target activity class + */ + public void finishAndGo(Class targetActivityClass){ + Intent targetActivityIntent = new Intent(this,targetActivityClass); + finish(); + startActivity(targetActivityIntent); + } + +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/SettingsActivity.java b/app/src/main/java/org/eyeseetea/malariacare/SettingsActivity.java index 4146f73522..bc01a9bcf4 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/SettingsActivity.java +++ b/app/src/main/java/org/eyeseetea/malariacare/SettingsActivity.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare; @@ -27,20 +27,32 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Configuration; +import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; -import android.preference.EditTextPreference; import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceFragment; import android.preference.PreferenceManager; +import android.preference.PreferenceScreen; import android.util.Log; +import com.squareup.okhttp.HttpUrl; +import com.squareup.otto.Subscribe; + +import org.eyeseetea.malariacare.database.utils.PopulateDB; import org.eyeseetea.malariacare.database.utils.PreferencesState; import org.eyeseetea.malariacare.network.PushClient; +import org.eyeseetea.malariacare.network.ServerAPIController; +import org.eyeseetea.malariacare.network.ServerInfo; import org.eyeseetea.malariacare.services.SurveyService; +import org.eyeseetea.malariacare.utils.Constants; import org.eyeseetea.malariacare.views.AutoCompleteEditTextPreference; +import org.hisp.dhis.android.sdk.controllers.DhisService; +import org.hisp.dhis.android.sdk.job.NetworkJob; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; +import org.hisp.dhis.android.sdk.persistence.preferences.ResourceType; import java.util.List; @@ -63,12 +75,41 @@ public class SettingsActivity extends PreferenceActivity implements SharedPrefer * shown on tablets. */ private static final boolean ALWAYS_SIMPLE_PREFS = false; + private static final String TAG = ".Settings"; private AutoCompleteEditTextPreference autoCompleteEditTextPreference; + + /** + * Intent extra param that states that the login before changing critical info has been done + */ + public static final String LOGIN_BEFORE_CHANGE_DONE="LOGIN_BEFORE_CHANGE_DONE"; + + /** + * Intent extra param that states that the login is being done due to an attempt to change the orgunit + */ + public static final String SETTINGS_CHANGING_ORGUNIT="SETTINGS_CHANGING_ORGUNIT"; + + /** + * Intent extra param that states that the login is being done due to an attempt to change the server + */ + public static final String SETTINGS_CHANGING_SERVER="SETTINGS_CHANGING_SERVER"; + + protected void onCreate(Bundle savedInstanceState) { + Dhis2Application.bus.register(this); super.onCreate(savedInstanceState); } + @Override + public void onStop(){ + try{ + Dhis2Application.bus.unregister(this); + }catch(IllegalArgumentException ex){ + Log.e(TAG,"Unregistering SettingsActivity before it is register"); + } + super.onStop(); + } + @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); @@ -76,6 +117,10 @@ protected void onPostCreate(Bundle savedInstanceState) { setupSimplePreferencesScreen(); } + void setAutoCompleteEditTextPreference(AutoCompleteEditTextPreference autoCompleteEditTextPreference){ + this.autoCompleteEditTextPreference=autoCompleteEditTextPreference; + } + /** * Shows the simplified settings UI if the device configuration if the * device configuration dictates that a simplified, single-pane UI should be @@ -86,9 +131,6 @@ private void setupSimplePreferencesScreen() { return; } - // In the simplified UI, fragments are not used at all and we instead - // use the older PreferenceActivity APIs. - // Add 'general' preferences. addPreferencesFromResource(R.xml.pref_general); @@ -102,31 +144,235 @@ private void setupSimplePreferencesScreen() { // Set the ClickListener to the android:key"remove_sent_surveys" preference. autoCompleteEditTextPreference= (AutoCompleteEditTextPreference) findPreference(getApplicationContext().getString(R.string.org_unit)); - Preference button = (Preference)findPreference(getApplicationContext().getString(R.string.remove_sent_surveys)); - button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + autoCompleteEditTextPreference.setOnPreferenceClickListener(new LoginRequiredOnPreferenceClickListener(this,true)); + autoCompleteEditTextPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override - public boolean onPreferenceClick(Preference preference) { - askRemoveSentSurveys(); + public boolean onPreferenceChange(Preference preference, Object newValue) { + + //Save preference new value + PreferencesState.getInstance().saveStringPreference(R.string.org_unit, newValue.toString()); + + // Now, manually update it's value to next value + // Now, if you click on the item, you'll see the value you've just set here + preference.setSummary(newValue.toString()); + + //Reload preference in memory + PreferencesState.getInstance().reloadPreferences(); + + //Reload orgunits according to server version + initReloadByServerVersionWhenOrgUnitChanged(); + return true; + } }); - Preference button2 = (Preference)findPreference(getApplicationContext().getResources().getString(R.string.dhis_url)); - button2.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { +// Preference removeSentPreference = (Preference)findPreference(getApplicationContext().getString(R.string.remove_sent_surveys)); +// removeSentPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { +// @Override +// public boolean onPreferenceClick(Preference preference) { +// askRemoveSentSurveys(); +// return true; +// } +// }); + + Preference serverUrlPreference = (Preference)findPreference(getApplicationContext().getResources().getString(R.string.dhis_url)); + serverUrlPreference.setOnPreferenceClickListener(new LoginRequiredOnPreferenceClickListener(this, false)); + serverUrlPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); - SharedPreferences.Editor prefEditor = sharedPref.edit(); // Get preference in editor mode - prefEditor.putString(getResources().getString(R.string.dhis_url), newValue.toString()); // set your default value here (could be empty as well) - prefEditor.commit(); // finally save changes + + //Save preference new value + PreferencesState.getInstance().saveStringPreference(R.string.dhis_url, newValue.toString()); + // Now, manually update it's value to next value - preference.setSummary(newValue.toString()); // Now, if you click on the item, you'll see the value you've just set here + // Now, if you click on the item, you'll see the value you've just set here + preference.setSummary(newValue.toString()); + + //Reload preference in memory PreferencesState.getInstance().reloadPreferences(); - PushClient.newOrgUnitOrServer(); - autoCompleteEditTextPreference.pullOrgUnits(); + + //Reload orgunits according to server version + initReloadByServerVersionWhenUrlChanged(newValue.toString()); + return true; + } }); + + //Check current server version to populate orgunits + initPopulateOrgUnitsByServerVersion(PreferencesState.getInstance().getDhisURL()); + + //XXX Open preference that was being edited, (to review) + //openClickedPreference(); + } + + /** + * Opens the preference that is being edited before login + */ + void openClickedPreference(){ + //No login -> nothing to open + if(!getIntent().getBooleanExtra(LOGIN_BEFORE_CHANGE_DONE,false)){ + return; + } + + //Login done -> open right preference + PreferenceScreen screen = (PreferenceScreen) findPreference("pref_screen"); + + //Find key to press + int key=-1; + if(getIntent().getBooleanExtra(SETTINGS_CHANGING_ORGUNIT,false)){ + key = R.string.org_unit; + } + if(getIntent().getBooleanExtra(SETTINGS_CHANGING_SERVER,false)){ + key = R.string.dhis_url; + } + + //Nothing to show up + if(key==-1){ + return; + } + + //Find order in screen + int pos = findPreference(getApplicationContext().getString(key)).getOrder(); + + //Simulate click on that one + screen.onItemClick( null, null, pos, 0 ); + } + + /** + * Checks server version after creating activity (in order to repopulate options in orgunits editor) + * @param url + */ + public void initPopulateOrgUnitsByServerVersion(String url){ + CheckServerVersionAsync serverVersionAsync = new CheckServerVersionAsync(this); + serverVersionAsync.execute(url); + } + + private void callbackPopulateOrgUnitsByServerVersion(ServerInfo serverInfo){ + Log.d(TAG, "callbackPopulateOrgUnitsByServerVersion " + serverInfo.getVersion()); + autoCompleteEditTextPreference.pullOrgUnits(serverInfo.getVersion()); + } + + /** + * Launches an async task that resolved the current server version when the org unit has changed. + */ + private void initReloadByServerVersionWhenOrgUnitChanged() { + CheckServerVersionAsync serverVersionAsync = new CheckServerVersionAsync(this,true,true); + serverVersionAsync.execute(PreferencesState.getInstance().getDhisURL()); + } + + + /** + * Reloads organisationUnits according to the server version: + * - 2.20: Manually via API + * - 2.21|2.22: Via sdk (which requires a login to initialize DHIS sdk) + * - Else: Error + */ + private void callbackReloadByServerVersionWhenOrgUnitChanged(ServerInfo serverInfo) { + Log.d(TAG, "callbackReloadByServerVersionWhenOrgUnitChanged " + serverInfo.getVersion()); + + //After changing to a new server survey data is always removed + PopulateDB.wipeSurveys(); + + String serverVersion=serverInfo.getVersion(); + + //2.20 -> nothing to do (since orgunits are already loaded) + if(ServerAPIController.isAPIVersion(serverVersion)){ + return; + } + + //2.21, 2.22 -> surveys + if(Constants.DHIS_SDK_221_SERVER.equals(serverVersion) || Constants.DHIS_SDK_222_SERVER.equals(serverVersion)){ + initLoginPrePull(serverInfo); + return; + } + + //Server version not supported -> Error + new AlertDialog.Builder(this) + .setTitle(R.string.dhis_url_error) + .setMessage(R.string.dhis_url_error_bad_version) + .setNeutralButton(android.R.string.yes, null) + .create() + .show(); + } + + /** + * Launches an async task that resolved the current server version. + * @param url + */ + private void initReloadByServerVersionWhenUrlChanged(String url) { + CheckServerVersionAsync serverVersionAsync = new CheckServerVersionAsync(this,true); + serverVersionAsync.execute(url); + } + + /** + * Reloads organisationUnits according to the server version: + * - 2.20: Manually via API + * - 2.21|2.22: Via sdk (which requires a login to initialize DHIS sdk) + * - Else: Error + */ + private void callbackReloadByServerVersionWhenUrlChanged(ServerInfo serverInfo) { + Log.d(TAG, "callbackReloadByServerVersionWhenUrlChanged " + serverInfo.getVersion()); + + //After changing to a new server survey data is always removed + PopulateDB.wipeSurveys(); + + //And the orgUnit too + PreferencesState.getInstance().saveStringPreference(R.string.org_unit,""); + + String serverVersion=serverInfo.getVersion(); + + //2.20 -> reload orgunits from server via api + if(ServerAPIController.isAPIVersion(serverVersion)){ + autoCompleteEditTextPreference.pullOrgUnits(Constants.DHIS_API_SERVER); + return; + } + + //2.21, 2.22 -> pull orgunits + surveys + if(Constants.DHIS_SDK_221_SERVER.equals(serverVersion) || Constants.DHIS_SDK_222_SERVER.equals(serverVersion)){ + initLoginPrePull(serverInfo); + return; + } + + //Server version not supported -> Error + new AlertDialog.Builder(this) + .setTitle(R.string.dhis_url_error) + .setMessage(R.string.dhis_url_error_bad_version) + .setNeutralButton(android.R.string.yes, null) + .create() + .show(); + } + + /** + * Logins programatically into new server to initialize sdk api + * @param serverInfo + */ + private void initLoginPrePull(ServerInfo serverInfo){ + HttpUrl serverUri = HttpUrl.parse(serverInfo.getUrl()); + DhisService.logInUser(serverUri, ServerAPIController.getSDKCredentials()); + } + + @Subscribe + public void callbackLoginPrePull(NetworkJob.NetworkJobResult result) { + //Nothing to check + if(result==null || !result.getResourceType().equals(ResourceType.USERS)){ + return; + } + + //Login failed + if(result.getResponseHolder().getApiException()!=null){ + new AlertDialog.Builder(this) + .setTitle(R.string.dhis_url_error) + .setMessage(R.string.dhis_url_error_bad_credentials) + .setNeutralButton(android.R.string.yes, null) + .create() + .show(); + } + + //Login successful start reload + finish(); + startActivity(new Intent(this, ProgressActivity.class)); } //ask if the Sent Surveys @@ -260,7 +506,6 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin @TargetApi(Build.VERSION_CODES.HONEYCOMB) public static class GeneralPreferenceFragment extends PreferenceFragment { - private AutoCompleteEditTextPreference autoCompleteEditTextPreference; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -274,35 +519,64 @@ public void onCreate(Bundle savedInstanceState) { bindPreferenceSummaryToValue(findPreference(getString(R.string.dhis_url))); bindPreferenceSummaryToValue(findPreference(getString(R.string.org_unit))); + SettingsActivity settingsActivity = (SettingsActivity) getActivity(); + AutoCompleteEditTextPreference autoCompleteEditTextPreference = (AutoCompleteEditTextPreference) findPreference(getString(R.string.org_unit)); + autoCompleteEditTextPreference.setOnPreferenceClickListener(new LoginRequiredOnPreferenceClickListener(settingsActivity, true)); + autoCompleteEditTextPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { - autoCompleteEditTextPreference= (AutoCompleteEditTextPreference) findPreference(getString(R.string.org_unit)); + //Save preference new value + PreferencesState.getInstance().saveStringPreference(R.string.org_unit, newValue.toString()); + + // Now, manually update it's value to next value + // Now, if you click on the item, you'll see the value you've just set here + preference.setSummary(newValue.toString()); + + //Reload preference in memory + PreferencesState.getInstance().reloadPreferences(); + + //Reload orgunits according to server version + ((SettingsActivity) getActivity()).initReloadByServerVersionWhenOrgUnitChanged(); - Preference button = (Preference)findPreference(getString(R.string.remove_sent_surveys)); - button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - askRemoveSentSurveys(getActivity()); return true; + } }); - - Preference button2 = (Preference)findPreference(getResources().getString(R.string.dhis_url)); - - button2.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + settingsActivity.setAutoCompleteEditTextPreference(autoCompleteEditTextPreference); + +// Preference removeSentPreference = (Preference)findPreference(getString(R.string.remove_sent_surveys)); +// removeSentPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { +// @Override +// public boolean onPreferenceClick(Preference preference) { +// askRemoveSentSurveys(getActivity()); +// return true; +// } +// }); + + Preference serverUrlPreference = (Preference)findPreference(getResources().getString(R.string.dhis_url)); + serverUrlPreference.setOnPreferenceClickListener(new LoginRequiredOnPreferenceClickListener(settingsActivity, false)); + serverUrlPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext()); - SharedPreferences.Editor prefEditor = sharedPref.edit(); // Get preference in editor mode - prefEditor.putString(getResources().getString(R.string.dhis_url), newValue.toString()); // set your default value here (could be empty as well) - prefEditor.commit(); // finally save changes - preference.setSummary(newValue.toString()); // Now, if you click on the item, you'll see the value you've just set here + //Save preference new value + PreferencesState.getInstance().saveStringPreference(R.string.dhis_url, newValue.toString()); + + // Now, manually update it's value to next value + // Now, if you click on the item, you'll see the value you've just set here + preference.setSummary(newValue.toString()); + + //Reload preference in memory PreferencesState.getInstance().reloadPreferences(); - PushClient.newOrgUnitOrServer(); - autoCompleteEditTextPreference.pullOrgUnits(); + + //Reload orgunits according to server version + ((SettingsActivity) getActivity()).initReloadByServerVersionWhenUrlChanged(newValue.toString()); + return true; } }); - + ((SettingsActivity)getActivity()).initPopulateOrgUnitsByServerVersion(PreferencesState.getInstance().getDhisURL()); +// ((SettingsActivity)getActivity()).openClickedPreference(); } } @@ -347,7 +621,7 @@ protected void onResume() { @Override protected void onPause() { - super.onResume(); + super.onPause(); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); sharedPreferences.unregisterOnSharedPreferenceChangeListener(this); @@ -358,7 +632,6 @@ protected void onPause() { @Override public void onBackPressed() { PreferencesState.getInstance().reloadPreferences(); - PushClient.newOrgUnitOrServer(); Class callerActivityClass=getCallerActivity(); Intent returnIntent=new Intent(this,callerActivityClass); startActivity(returnIntent); @@ -378,4 +651,140 @@ private Class getCallerActivity(){ return callerActivity; } + /** + * AsyncTask that resolves the server version before pulling orgunits from it + */ + class CheckServerVersionAsync extends AsyncTask { + + Context context; + ServerInfo serverInfo; + /** + * True: The server url has changed, a pull is required + * False: Need to check server version in order to populate orgunits + */ + boolean pullRequired; + + /** + * Flag that tells if this check corresponds to a change in the orgunit + */ + boolean orgUnitChanged; + + /** + * Constructor used to check orgunits after activity creation + * @param context + */ + public CheckServerVersionAsync(Context context) { + this.context = context; + this.pullRequired = false; + } + + /** + * Constructor used to pull metadata after url change + * @param context + * @param pullRequired + */ + public CheckServerVersionAsync(Context context,boolean pullRequired) { + this(context); + this.pullRequired = pullRequired; + } + + /** + * Constructor used to pull events after orgunit change + * @param context + * @param pullRequired + * @param orgUnitChanged + */ + public CheckServerVersionAsync(Context context,boolean pullRequired, boolean orgUnitChanged) { + this(context,pullRequired); + this.orgUnitChanged = orgUnitChanged; + } + + @Override + protected void onPreExecute() {} + + protected ServerInfo doInBackground(String... params) { + serverInfo = new ServerInfo(params[0]); + + PushClient pushClient=new PushClient(context); + String serverVersion= ServerAPIController.getServerVersion(serverInfo.getUrl()); + + serverInfo.setVersion(serverVersion); + return serverInfo; + } + + @Override + protected void onPostExecute(ServerInfo serverInfo) { + + //OrgUnit has change -> init pull (orgunits not reloaded) + if(orgUnitChanged){ + callbackReloadByServerVersionWhenOrgUnitChanged(serverInfo); + return; + } + + //Url has change -> init pull (orgunits reloaded) + if(pullRequired) { + callbackReloadByServerVersionWhenUrlChanged(serverInfo); + return; + } + + //Orgunits will be reloaded + callbackPopulateOrgUnitsByServerVersion(serverInfo); + } + + } + +} + +/** + * Listener that moves to the LoginActivity before changing orgunit|server. + * If login has already been done simply pass through + */ +class LoginRequiredOnPreferenceClickListener implements Preference.OnPreferenceClickListener{ + + /** + * Reference to the activity so you can use this from the activity or the fragment + */ + SettingsActivity activity; + + /** + * Flag to indicate if you are changing orgunit or server + */ + boolean changingOrgUnit; + + LoginRequiredOnPreferenceClickListener(SettingsActivity activity, boolean changingOrgUnit){ + this.activity=activity; + this.changingOrgUnit=changingOrgUnit; + } + + @Override + public boolean onPreferenceClick(Preference preference) { + + //Login already done -> move on + if(isLoginDone()){ + return false; + } + + //Launch login with the right extra param + launchLoginPreChange(); + return true; + } + + /** + * Checks if login is required + * @return + */ + boolean isLoginDone(){ + return activity.getIntent().getBooleanExtra(SettingsActivity.LOGIN_BEFORE_CHANGE_DONE,false); + } + + /** + * Launches Login activity with the right extra params + */ + void launchLoginPreChange(){ + String extraKey = changingOrgUnit?SettingsActivity.SETTINGS_CHANGING_ORGUNIT:SettingsActivity.SETTINGS_CHANGING_SERVER; + Intent intent = new Intent(activity,LoginActivity.class); + intent.putExtra(extraKey,true); + activity.finish(); + activity.startActivity(intent); + } } diff --git a/app/src/main/java/org/eyeseetea/malariacare/SurveyActivity.java b/app/src/main/java/org/eyeseetea/malariacare/SurveyActivity.java index 6ac76ac532..af475cd202 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/SurveyActivity.java +++ b/app/src/main/java/org/eyeseetea/malariacare/SurveyActivity.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare; @@ -24,42 +24,28 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.view.LayoutInflater; -import android.view.Menu; import android.view.View; -import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.ProgressBar; -import android.widget.Spinner; import org.eyeseetea.malariacare.database.model.CompositeScore; import org.eyeseetea.malariacare.database.model.Option; -import org.eyeseetea.malariacare.database.model.Program; import org.eyeseetea.malariacare.database.model.Question; import org.eyeseetea.malariacare.database.model.Survey; import org.eyeseetea.malariacare.database.model.Tab; -import org.eyeseetea.malariacare.database.utils.PreferencesState; import org.eyeseetea.malariacare.database.utils.Session; -import org.eyeseetea.malariacare.layout.adapters.general.TabArrayAdapter; -import org.eyeseetea.malariacare.layout.adapters.survey.AutoTabAdapter; -import org.eyeseetea.malariacare.layout.adapters.survey.CompositeScoreAdapter; -import org.eyeseetea.malariacare.layout.adapters.survey.CustomAdherenceAdapter; -import org.eyeseetea.malariacare.layout.adapters.survey.CustomIQTABAdapter; import org.eyeseetea.malariacare.layout.adapters.survey.DynamicTabAdapter; import org.eyeseetea.malariacare.layout.adapters.survey.ITabAdapter; import org.eyeseetea.malariacare.layout.score.ScoreRegister; -import org.eyeseetea.malariacare.layout.utils.LayoutUtils; import org.eyeseetea.malariacare.services.SurveyService; import org.eyeseetea.malariacare.utils.Constants; -import org.eyeseetea.malariacare.utils.Utils; -import org.eyeseetea.malariacare.views.TextCard; import java.util.ArrayList; import java.util.HashMap; @@ -119,20 +105,13 @@ public void onResume(){ prepareSurveyInfo(); } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - // Inflate the menu; this adds items to the action bar if it is present. - getMenuInflater().inflate(R.menu.menu_survey, menu); - return super.onCreateOptionsMenu(menu); - } - @Override public void onBackPressed() { Log.d(TAG, "onBackPressed"); Survey survey=Session.getSurvey(); int infoMessage=survey.isInProgress()?R.string.survey_info_exit_delete:R.string.survey_info_exit; new AlertDialog.Builder(this) - .setTitle(R.string.survey_title_exit) + .setTitle(R.string.survey_info_exit) .setMessage(infoMessage) .setNegativeButton(android.R.string.no, null) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @@ -233,7 +212,7 @@ protected void onPostExecute(View viewContent) { content.removeAllViews(); content.addView(viewContent); ITabAdapter tabAdapter = tabAdaptersCache.findAdapter(tab); - if ( tab.getType() == Constants.TAB_AUTOMATIC_SCORED || + if ( tab.getType() == Constants.TAB_AUTOMATIC || tab.getType() == Constants.TAB_ADHERENCE || tab.getType() == Constants.TAB_IQATAB || tab.getType() == Constants.TAB_SCORE_SUMMARY) { @@ -248,21 +227,6 @@ protected void onPostExecute(View viewContent) { } } - - - /** - * Adds actionbar to the activity - */ - private void createActionBar(){ - Survey survey=Session.getSurvey(); - Program program = survey.getProgram(); - - android.support.v7.app.ActionBar actionBar = this.getSupportActionBar(); - LayoutUtils.setActionBarLogo(actionBar); - LayoutUtils.setActionBarText(actionBar, PreferencesState.getInstance().getOrgUnit(), program.getName()); - } - - /** * Gets a reference to the progress view in order to stop it later */ @@ -467,27 +431,10 @@ public void cacheAllTabs(){ * @return */ private ITabAdapter buildAdapter(Tab tab){ - if (tab.isCompositeScore()) - return new CompositeScoreAdapter(this.compositeScores, SurveyActivity.this, R.layout.composite_score_tab, tab.getName()); - - if (tab.isAdherenceTab()) { - Log.d(TAG, "Creating an Adherence Adapter"); - return CustomAdherenceAdapter.build(tab, SurveyActivity.this); - } - - if (tab.isIQATab()) - return CustomIQTABAdapter.build(tab, SurveyActivity.this); - - - if(tab.isGeneralScore()){ - return null; - } - - if (tab.isDynamicTab()){ + if (tab.isDynamicTab()) return new DynamicTabAdapter(tab,SurveyActivity.this); - } - return AutoTabAdapter.build(tab,SurveyActivity.this); + return null; } } } diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/AppDatabase.java b/app/src/main/java/org/eyeseetea/malariacare/database/AppDatabase.java index 9cec93d8a3..fe2b8a5275 100644 --- a/app/src/main/java/org/eyeseetea/malariacare/database/AppDatabase.java +++ b/app/src/main/java/org/eyeseetea/malariacare/database/AppDatabase.java @@ -1,20 +1,20 @@ /* * Copyright (c) 2015. * - * This file is part of QIS Survelliance App. + * This file is part of QIS Surveillance App. * - * QIS Survelliance App is free software: you can redistribute it and/or modify + * QIS Surveillance App is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * - * QIS Survelliance App is distributed in the hope that it will be useful, + * QIS Surveillance App 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 General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with QIS Survelliance App. If not, see . + * along with QIS Surveillance App. If not, see . */ package org.eyeseetea.malariacare.database; @@ -24,9 +24,10 @@ /** * Created by arrizabalaga on 19/10/15. */ -@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION, foreignKeysSupported = true) +@Database(name = AppDatabase.NAME, version = AppDatabase.VERSION, foreignKeysSupported = true, holderClassSuffix = AppDatabase.HOLDERCLASSSUFFIX) public class AppDatabase { public static final String NAME = "EyeSeeTeaDB"; - public static final int VERSION = 1; + public static final int VERSION = 2; + public static final String HOLDERCLASSSUFFIX = "_EyeSeeTeaDB"; } diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/ConvertToSDKVisitor.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/ConvertToSDKVisitor.java new file mode 100644 index 0000000000..d3e583c030 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/ConvertToSDKVisitor.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.exporter; + +import android.content.Context; +import android.location.Location; +import android.util.Log; + +import org.eyeseetea.malariacare.R; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.EventExtended; +import org.eyeseetea.malariacare.database.model.CompositeScore; +import org.eyeseetea.malariacare.database.model.OrgUnit; +import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.database.model.Value; +import org.eyeseetea.malariacare.database.utils.LocationMemory; +import org.eyeseetea.malariacare.database.utils.PreferencesState; +import org.eyeseetea.malariacare.database.utils.Session; +import org.eyeseetea.malariacare.layout.score.ScoreRegister; +import org.eyeseetea.malariacare.network.PushClient; +import org.eyeseetea.malariacare.phonemetadata.PhoneMetaData; +import org.eyeseetea.malariacare.utils.Constants; +import org.eyeseetea.malariacare.utils.Utils; +import org.hisp.dhis.android.sdk.persistence.models.DataValue; +import org.hisp.dhis.android.sdk.persistence.models.Event; +import org.hisp.dhis.android.sdk.persistence.models.ImportSummary; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * Turns a given survey into its corresponding events+datavalues. + */ +public class ConvertToSDKVisitor implements IConvertToSDKVisitor { + + private final static String TAG=".ConvertToSDKVisitor"; + + /** + * Context required to recover magic UID for mainScore dataElements + */ + Context context; + + /** + * List of surveys that are going to be pushed + */ + List surveys; + + /** + * List of events that are going to be pushed + */ + List events; + + /** + * The last survey that it is being translated + */ + Survey currentSurvey; + + /** + * The generated event + */ + Event currentEvent; + + ConvertToSDKVisitor(Context context){ + this.context=context; + surveys = new ArrayList<>(); + events = new ArrayList<>(); + } + + @Override + public void visit(Survey survey) throws Exception{ + //Turn survey into an event + this.currentSurvey=survey; + + Log.d(TAG,String.format("Creating event for survey (%d) ...",survey.getId_survey())); + this.currentEvent=buildEvent(); + + //Calculates scores and update survey + Log.d(TAG,"Registering scores..."); + List compositeScores = ScoreRegister.loadCompositeScores(survey); + updateSurvey(compositeScores); + + //Turn question values into dataValues + Log.d(TAG,"Creating datavalues from questions..."); + for(Value value:survey.getValues()){ + value.accept(this); + } + + //Add phoneMetaData as a value + addPhoneMetaData(); + + //Annotate both objects to update its state once the process is over + annotateSurveyAndEvent(); + } + + /** + * Adds phonemetaData as a value + */ + private void addPhoneMetaData() { + PhoneMetaData phoneMetaData= Session.getPhoneMetaData(); + DataValue dataValue=new DataValue(); + dataValue.setDataElement(PushClient.TAG_PHONEMETADA); + dataValue.setLocalEventId(currentEvent.getLocalId()); + dataValue.setEvent(currentEvent.getEvent()); + dataValue.setProvidedElsewhere(false); + dataValue.setStoredBy(Session.getUser().getName()); + dataValue.setValue(phoneMetaData.getPhone_metaData()); + dataValue.save(); + } + + @Override + public void visit(CompositeScore compositeScore) { + DataValue dataValue=new DataValue(); + dataValue.setDataElement(compositeScore.getUid()); + dataValue.setLocalEventId(currentEvent.getLocalId()); + dataValue.setEvent(currentEvent.getEvent()); + dataValue.setProvidedElsewhere(false); + dataValue.setStoredBy(Session.getUser().getName()); + dataValue.setValue(Utils.round(ScoreRegister.getCompositeScore(compositeScore))); + dataValue.save(); + } + + @Override + public void visit(Value value) { + DataValue dataValue=new DataValue(); + dataValue.setDataElement(value.getQuestion().getUid()); + dataValue.setLocalEventId(currentEvent.getLocalId()); + dataValue.setEvent(currentEvent.getEvent()); + dataValue.setProvidedElsewhere(false); + dataValue.setStoredBy(Session.getUser().getName()); + //XXX In pictureapp always value since option.code is Khmer value + dataValue.setValue(value.getValue()); + dataValue.save(); + } + + /** + * Builds an event from a survey + * @return + */ + private Event buildEvent()throws Exception{ + currentEvent=new Event(); + + currentEvent.setStatus(Event.STATUS_COMPLETED); + currentEvent.setFromServer(false); + currentEvent.setOrganisationUnitId(getSafeOrgUnitUID(currentSurvey)); + currentEvent.setProgramId(currentSurvey.getTabGroup().getProgram().getUid()); + currentEvent.setProgramStageId(currentSurvey.getTabGroup().getUid()); + updateEventLocation(); + updateEventDates(); + Log.d(TAG, "Saving event " + currentEvent.toString()); + currentEvent.save(); + return currentEvent; + } + + private String getSafeOrgUnitUID(Survey survey){ + OrgUnit orgUnit=survey.getOrgUnit(); + if(orgUnit!=null){ + return orgUnit.getUid(); + } + + //A survey might be created with a 2.20 (no orgunit) but push into a 2.22 + return OrgUnit.findUIDByName(PreferencesState.getInstance().getOrgUnit()); + } + + /** + * Fulfills the dates of the event + */ + private void updateEventDates() { + + //Sent date 'now' (this change will be saves after successful push) + currentSurvey.setEventDate(new Date()); + + //Creation date is null because it is used by sdk to POST|PUT we always POST a new survey + currentEvent.setLastUpdated(EventExtended.format(currentSurvey.getCompletionDate())); + currentEvent.setEventDate(EventExtended.format(currentSurvey.getEventDate())); + currentEvent.setDueDate(EventExtended.format(currentSurvey.getScheduledDate())); + } + + /** + * Several properties must be updated when a survey is about to be sent. + * This changes will be saved just when process finish successfully. + * @param compositeScores + */ + private void updateSurvey(List compositeScores){ + currentSurvey.setStatus(Constants.SURVEY_SENT); + } + + /** + * Updates the location of the current event that it is being processed + * @throws Exception + */ + private void updateEventLocation() throws Exception{ + Location lastLocation = LocationMemory.get(currentSurvey.getId_survey()); + + //No location + not required -> done + if(lastLocation==null){ + return; + } + + //location -> set lat/lng + currentEvent.setLatitude(lastLocation.getLatitude()); + currentEvent.setLongitude(lastLocation.getLongitude()); + } + + /** + * Annotates the survey and event that has been processed + */ + private void annotateSurveyAndEvent() { + surveys.add(currentSurvey); + events.add(currentEvent); + + Log.d(TAG, String.format("%d surveys converted so far", surveys.size())); + } + + /** + * Saves changes in the survey (supposedly after a successfull push) + * @param importSummaryMap + */ + public void saveSurveyStatus(Map importSummaryMap){ + for(int i=0;i. + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.exporter; + +import org.eyeseetea.malariacare.database.model.CompositeScore; +import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.database.model.Value; + +public interface IConvertToSDKVisitor { + void visit(Survey survey) throws Exception; + void visit(CompositeScore compositeScore); + void visit(Value value); +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/PushController.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/PushController.java new file mode 100644 index 0000000000..3282524cab --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/PushController.java @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.exporter; + +import android.content.Context; +import android.util.Log; + +import com.squareup.otto.Subscribe; + +import org.eyeseetea.malariacare.R; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.SyncProgressStatus; +import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.network.PushClient; +import org.eyeseetea.malariacare.network.ServerAPIController; +import org.hisp.dhis.android.sdk.controllers.DhisService; +import org.hisp.dhis.android.sdk.job.NetworkJob; +import org.hisp.dhis.android.sdk.network.ResponseHolder; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; +import org.hisp.dhis.android.sdk.persistence.models.ImportSummary; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A static controller that orchestrate the push process + * Created by arrizabalaga on 4/11/15. + */ +public class PushController { + private final String TAG=".PushController"; + + private static PushController instance; + + /** + * Context required to i18n error messages while pulling + */ + private Context context; + + /** + * The stateful converter used to turn a survey into its corresponding event + datavalues; + */ + ConvertToSDKVisitor converter; + + /** + * Constructs and register this pull controller to the event bus + */ + PushController(){ + } + + private void register(){ + Dhis2Application.bus.register(this); + } + + /** + * Unregister pull controller from bus events + */ + private void unregister(){ + Dhis2Application.bus.unregister(this); + } + + /** + * Singleton constructor + * @return + */ + public static PushController getInstance(){ + if(instance==null){ + instance=new PushController(); + } + return instance; + } + + /** + * Launches the push process + * @param ctx + */ + public void push(Context ctx,List surveys){ + Log.d(TAG, "Starting PUSH process..."); + context=ctx; + + //No survey no push + if(surveys==null || surveys.size()==0){ + postException(new Exception(context.getString(R.string.progress_push_no_survey))); + return; + } + + try { + //Register for event bus + register(); + + //Converts app data into sdk events + postProgress(context.getString(R.string.progress_push_preparing_survey)); + Log.d(TAG, "Preparing survey for pushing..."); + convertToSDK(surveys); + + //Asks sdk to push localdata + postProgress(context.getString(R.string.progress_push_posting_survey)); + Log.d(TAG, "Pushing survey data to server..."); + DhisService.sendEventChanges(); + + }catch (Exception ex){ + Log.e(TAG,"push: "+ex.getLocalizedMessage()); + unregister(); + postException(ex); + } + } + + @Subscribe + public void onSendDataFinished(final NetworkJob.NetworkJobResult> result) { + new Thread(){ + @Override + public void run(){ + try { + if (result == null) { + Log.e(TAG, "onSendDataFinished with null"); + return; + } + + //Error while pulling + if (result.getResponseHolder() != null && result.getResponseHolder().getApiException() != null) { + Log.e(TAG, result.getResponseHolder().getApiException().getMessage()); + postException(new Exception(context.getString(R.string.dialog_pull_error))); + return; + } + //Ok: Updates + check ban server + postProgress(context.getString(R.string.progress_push_updating_survey)); + Log.d(TAG, "Updating pushed survey data..."); + converter.saveSurveyStatus(getImportSummaryMap(result)); + + Log.d(TAG, "Checking if server must be closed..."); + ServerAPIController.banOrgUnitIfRequired(); + + Log.d(TAG, "PUSH process...OK"); + }catch (Exception ex){ + Log.e(TAG,"onSendDataFinished: "+ex.getLocalizedMessage()); + postException(ex); + }finally { + postFinish(); + unregister(); + } + } + }.start(); + } + + /** + * Launches visitor that turns an APP survey into a SDK event + */ + private void convertToSDK(List surveys)throws Exception{ + Log.d(TAG,"Converting APP survey into a SDK event"); + converter =new ConvertToSDKVisitor(context); + for(Survey survey:surveys){ + survey.accept(converter); + } + } + + /** + * Gets full importSummary for every Event that has been pushed to the server + * @param result + * @return + */ + private Map getImportSummaryMap(NetworkJob.NetworkJobResult> result){ + Map emptyImportSummaryMap=new HashMap<>(); + //No result -> no details + if(result==null){ + return emptyImportSummaryMap; + } + + //General exception -> no details + if (result.getResponseHolder() != null && result.getResponseHolder().getApiException() != null) { + return emptyImportSummaryMap; + } + + ResponseHolder> responseHolder=result.getResponseHolder(); + if(responseHolder==null || responseHolder.getItem()==null){ + return emptyImportSummaryMap; + } + + return responseHolder.getItem(); + } + + /** + * Notifies a progress into the bus (the caller activity will be listening) + * @param msg + */ + private void postProgress(String msg){ + Dhis2Application.getEventBus().post(new SyncProgressStatus(msg)); + } + + /** + * Notifies an exception while pulling + * @param ex + */ + private void postException(Exception ex){ + ex.printStackTrace(); + Dhis2Application.getEventBus().post(new SyncProgressStatus(ex)); + } + + /** + * Notifies that the pull is over + */ + private void postFinish(){ + try { + Log.i(TAG,"postFinish"); + Dhis2Application.getEventBus().post(new SyncProgressStatus()); + } + catch(Exception e){ + e.printStackTrace(); + } + } + + +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/VisitableToSDK.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/VisitableToSDK.java new file mode 100644 index 0000000000..fec73182c7 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/exporter/VisitableToSDK.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.exporter; + +public interface VisitableToSDK { + void accept(IConvertToSDKVisitor IConvertToSDKVisitor) throws Exception; +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/ConvertFromSDKVisitor.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/ConvertFromSDKVisitor.java new file mode 100644 index 0000000000..6306be322c --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/ConvertFromSDKVisitor.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer; + +import org.eyeseetea.malariacare.R; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.DataValueExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.EventExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.OrganisationUnitExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.UserAccountExtended; +import org.eyeseetea.malariacare.database.model.CompositeScore; +import org.eyeseetea.malariacare.database.model.OrgUnit; +import org.eyeseetea.malariacare.database.model.Program; +import org.eyeseetea.malariacare.database.model.Question; +import org.eyeseetea.malariacare.database.model.Survey; +import org.eyeseetea.malariacare.database.model.TabGroup; +import org.eyeseetea.malariacare.database.model.User; +import org.eyeseetea.malariacare.database.model.Value; +import org.eyeseetea.malariacare.database.utils.PreferencesState; +import org.eyeseetea.malariacare.network.PushClient; +import org.eyeseetea.malariacare.utils.Constants; +import org.hisp.dhis.android.sdk.persistence.models.DataValue; +import org.hisp.dhis.android.sdk.persistence.models.Event; +import org.hisp.dhis.android.sdk.persistence.models.OrganisationUnit; +import org.hisp.dhis.android.sdk.persistence.models.UserAccount; + +import java.util.HashMap; +import java.util.Map; + +public class ConvertFromSDKVisitor implements IConvertFromSDKVisitor { + + private final static String TAG=".ConvertFromSDKVisitor"; + + + TabGroup tabgroup; + Map appMapObjects; + + + + public ConvertFromSDKVisitor(){ + Program firstProgram = Program.getFirstProgram(); + tabgroup = firstProgram.getTabGroups().get(0); + appMapObjects = new HashMap(); + } + + /** + * Turns a sdk organisationUnit into an app OrgUnit + * + * @param sdkOrganisationUnitExtended + */ + @Override + public void visit(OrganisationUnitExtended sdkOrganisationUnitExtended) { + //Create and save OrgUnitLevel + OrganisationUnit organisationUnit=sdkOrganisationUnitExtended.getOrgUnit(); + org.eyeseetea.malariacare.database.model.OrgUnitLevel orgUnitLevel = new org.eyeseetea.malariacare.database.model.OrgUnitLevel(); + if(!appMapObjects.containsKey(String.valueOf(organisationUnit.getLevel()))) { + orgUnitLevel.setName(PreferencesState.getInstance().getContext().getResources().getString(R.string.create_info_zone)); + orgUnitLevel.save(); + appMapObjects.put(String.valueOf(organisationUnit.getLevel()), orgUnitLevel); + } + //create the orgUnit + org.eyeseetea.malariacare.database.model.OrgUnit appOrgUnit= new org.eyeseetea.malariacare.database.model.OrgUnit(); + //Set name + appOrgUnit.setName(organisationUnit.getLabel()); + //Set uid + appOrgUnit.setUid(organisationUnit.getId()); + //Set orgUnitLevel + appOrgUnit.setOrgUnitLevel((org.eyeseetea.malariacare.database.model.OrgUnitLevel) appMapObjects.get(String.valueOf(organisationUnit.getLevel()))); + //Set the parent + //At this moment, the parent is a UID of a not pulled Org_unit , without the full org_unit the OrgUnit.orgUnit(parent) is null. + String parent_id=null; + parent_id = organisationUnit.getParent(); + if(parent_id!=null && !parent_id.equals("")) { + appOrgUnit.setOrgUnit((org.eyeseetea.malariacare.database.model.OrgUnit) appMapObjects.get(String.valueOf(parent_id))); + } + else + appOrgUnit.setOrgUnit((OrgUnit)null); + appOrgUnit.save(); + //Annotate built orgunit + appMapObjects.put(organisationUnit.getId(), appOrgUnit); + } + + /** + * Turns a sdk userAccount into a User + * @param sdkUserAccountExtended + */ + @Override + public void visit(UserAccountExtended sdkUserAccountExtended) { + UserAccount userAccount=sdkUserAccountExtended.getUserAccount(); + User appUser = new User(); + appUser.setUid(userAccount.getUId()); + appUser.setName(userAccount.getName()); + appUser.save(); + } + + /** + * Turns an event into a sent survey + * @param sdkEventExtended + */ + @Override + public void visit(EventExtended sdkEventExtended) { + Event event=sdkEventExtended.getEvent(); + OrgUnit orgUnit =(OrgUnit)appMapObjects.get(event.getOrganisationUnitId()); + + Survey survey=new Survey(); + //Any survey that comes from the pull has been sent + survey.setStatus(Constants.SURVEY_SENT); + //Set dates + survey.setCreationDate(sdkEventExtended.getCreationDate()); + survey.setCompletionDate(sdkEventExtended.getCompletionDate()); + survey.setEventDate(sdkEventExtended.getEventDate()); + survey.setScheduledDate(sdkEventExtended.getScheduledDate()); + //Set fks + survey.setOrgUnit(orgUnit); + survey.setTabGroup(tabgroup); + survey.save(); + + //Annotate object in map + appMapObjects.put(event.getUid(), survey); + + //Visit its values + for(DataValue dataValue:event.getDataValues()){ + DataValueExtended dataValueExtended=new DataValueExtended(dataValue); + dataValueExtended.accept(this); + } + + } + + @Override + public void visit(DataValueExtended sdkDataValueExtended) { + + DataValue dataValue=sdkDataValueExtended.getDataValue(); + Survey survey=(Survey)appMapObjects.get(dataValue.getEvent()); + String questionUID=dataValue.getDataElement(); + + //Data value is a value from compositeScore -> ignore + if(appMapObjects.get(questionUID) instanceof CompositeScore){ + return; + } + + //Phone metadata -> ignore + if(PushClient.TAG_PHONEMETADA.equals(questionUID)){ + return; + } + + //Datavalue is a value from a question + Question question=Question.findByUID(questionUID); + + Value value=new Value(); + value.setQuestion(question); + value.setSurvey(survey); + + org.eyeseetea.malariacare.database.model.Option option=sdkDataValueExtended.findOptionByQuestion(question); + value.setOption(option); + //No option -> text question (straight value) + if(option==null){ + value.setValue(dataValue.getValue()); + }else{ + //Option -> extract value from code + value.setValue(sdkDataValueExtended.extractValue()); + } + value.save(); + } + +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/IConvertFromSDKVisitor.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/IConvertFromSDKVisitor.java new file mode 100644 index 0000000000..a75c3d54f5 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/IConvertFromSDKVisitor.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer; + +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.DataValueExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.EventExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.OrganisationUnitExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.UserAccountExtended; + +public interface IConvertFromSDKVisitor { + void visit(OrganisationUnitExtended organisationUnit); + void visit(UserAccountExtended userAccount); + void visit(EventExtended sdkEventExtended); + void visit(DataValueExtended sdkDataValueExtended); +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/PullController.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/PullController.java new file mode 100644 index 0000000000..0a54086ba4 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/PullController.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer; + +import android.content.Context; +import android.util.Log; + +import com.squareup.otto.Subscribe; + +import org.eyeseetea.malariacare.ProgressActivity; +import org.eyeseetea.malariacare.R; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.EventExtended; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.models.OrganisationUnitExtended; +import org.eyeseetea.malariacare.database.model.Program; +import org.eyeseetea.malariacare.database.model.User; +import org.eyeseetea.malariacare.database.utils.PopulateDB; +import org.eyeseetea.malariacare.database.utils.PreferencesState; +import org.eyeseetea.malariacare.database.utils.Session; +import org.hisp.dhis.android.sdk.controllers.DhisService; +import org.hisp.dhis.android.sdk.controllers.LoadingController; +import org.hisp.dhis.android.sdk.controllers.metadata.MetaDataController; +import org.hisp.dhis.android.sdk.controllers.tracker.TrackerController; +import org.hisp.dhis.android.sdk.job.Job; +import org.hisp.dhis.android.sdk.job.JobExecutor; +import org.hisp.dhis.android.sdk.job.NetworkJob; +import org.hisp.dhis.android.sdk.persistence.Dhis2Application; +import org.hisp.dhis.android.sdk.persistence.models.Event; +import org.hisp.dhis.android.sdk.persistence.models.OrganisationUnit; +import org.hisp.dhis.android.sdk.persistence.preferences.ResourceType; +import org.hisp.dhis.android.sdk.utils.api.ProgramType; + +import java.util.List; + +/** + * A static controller that orchestrate the pull process + * Created by arrizabalaga on 4/11/15. + */ +public class PullController { + public static final int MAX_EVENTS_X_ORGUNIT_PROGRAM = 600; + private final String TAG = ".PullController"; + + private static PullController instance; + + private static Job job; + /** + * Context required to i18n error messages while pulling + */ + private Context context; + + /** + * Constructs and register this pull controller to the event bus + */ + PullController() { + } + + private void register() { + try { + Dhis2Application.bus.register(this); + } catch (Exception e) { + unregister(); + Dhis2Application.bus.register(this); + } + } + + /** + * Unregister pull controller from bus events + */ + public void unregister() { + try { + Dhis2Application.bus.unregister(this); + } catch (Exception e) { + } + } + + /** + * Singleton constructor + * + * @return + */ + public static PullController getInstance() { + if (instance == null) { + instance = new PullController(); + } + return instance; + } + + /** + * Launches the pull process: + * - Loads metadata from dhis2 server + * - Wipes app database + * - Turns SDK into APP data + * + * @param ctx + */ + public void pull(Context ctx) { + Log.d(TAG, "Starting PULL process..."); + context = ctx; + try { + + //Register for event bus + register(); + //Enabling resources to pull + enableMetaDataFlags(); + //Delete previous metadata + TrackerController.setMaxEvents(MAX_EVENTS_X_ORGUNIT_PROGRAM); + MetaDataController.clearMetaDataLoadedFlags(); + MetaDataController.wipe(); + //Pull new metadata + postProgress(context.getString(R.string.progress_pull_downloading)); + try { + job = DhisService.loadData(context); + } catch (Exception ex) { + Log.e(TAG, "pullS: " + ex.getLocalizedMessage()); + ex.printStackTrace(); + } + } catch (Exception ex) { + Log.e(TAG, "pull: " + ex.getLocalizedMessage()); + unregister(); + postException(ex); + } + } + + /** + * Enables loading all metadata + */ + private void enableMetaDataFlags() { + LoadingController.enableLoading(context, ResourceType.ASSIGNEDPROGRAMS); + LoadingController.enableLoading(context, ResourceType.PROGRAMS); + LoadingController.enableLoading(context, ResourceType.OPTIONSETS); + LoadingController.enableLoading(context, ResourceType.EVENTS); + } + + @Subscribe + public void onLoadMetadataFinished(final NetworkJob.NetworkJobResult result) { + new Thread() { + @Override + public void run() { + try { + if (result == null) { + Log.e(TAG, "onLoadMetadataFinished with null"); + return; + } + + //Error while pulling + if (result.getResponseHolder() != null && result.getResponseHolder().getApiException() != null) { + Log.e(TAG, result.getResponseHolder().getApiException().getMessage()); + postException(new Exception(context.getString(R.string.dialog_pull_error))); + return; + } + + //Ok + wipeDatabase(); + convertFromSDK(); + if (ProgressActivity.PULL_IS_ACTIVE) { + Log.d(TAG, "PULL process...OK"); + } + } catch (Exception ex) { + Log.e(TAG, "onLoadMetadataFinished: " + ex.getLocalizedMessage()); + postException(ex); + } finally { + postFinish(); + unregister(); + } + } + }.start(); + } + + /** + * Erase data from app database + */ + public void wipeDatabase() { + if (!ProgressActivity.PULL_IS_ACTIVE) return; + Log.d(TAG, "Deleting app database..."); + PopulateDB.wipeDatabase(); + } + + /** + * Launches visitor that turns SDK data into APP data + */ + private void convertFromSDK() { + if (!ProgressActivity.PULL_IS_ACTIVE) return; + Log.d(TAG, "Converting SDK into APP data"); + + //One shared converter to match parents within the hierarchy + ConvertFromSDKVisitor converter = new ConvertFromSDKVisitor(); + convertMetaData(converter); + if (!ProgressActivity.PULL_IS_ACTIVE) return; + convertDataValues(converter); + + } + + /** + * Turns sdk metadata into app metadata + * + * @param converter + */ + private void convertMetaData(ConvertFromSDKVisitor converter) { + //OrganisationUnits + if (!ProgressActivity.PULL_IS_ACTIVE) return; + postProgress(context.getString(R.string.progress_pull_preparing_orgs)); + Log.i(TAG, "Converting organisationUnits..."); + List assignedOrganisationsUnits = MetaDataController.getAssignedOrganisationUnits(); + for (OrganisationUnit assignedOrganisationsUnit : assignedOrganisationsUnits) { + if (!ProgressActivity.PULL_IS_ACTIVE) return; + OrganisationUnitExtended organisationUnitExtended = new OrganisationUnitExtended(assignedOrganisationsUnit); + organisationUnitExtended.accept(converter); + } + + } + + /** + * Turns events and datavalues into + * + * @param converter + */ + private void convertDataValues(ConvertFromSDKVisitor converter) { + if (!ProgressActivity.PULL_IS_ACTIVE) return; + Program appProgram = Program.getFirstProgram(); + String orgUnitName = PreferencesState.getInstance().getOrgUnit(); + + postProgress(context.getString(R.string.progress_pull_surveys)); + //XXX This is the right place to apply additional filters to data conversion (only predefined orgunit for instance) + //For each unit + for (OrganisationUnit organisationUnit : MetaDataController.getAssignedOrganisationUnits()) { + + //Only events for the right ORGUNIT are loaded + if(!organisationUnit.getLabel().equals(orgUnitName)){ + continue; + } + + //Each assigned program + for (org.hisp.dhis.android.sdk.persistence.models.Program program : MetaDataController.getProgramsForOrganisationUnit(organisationUnit.getId(), ProgramType.WITHOUT_REGISTRATION)) { + + //Only events for the right PROGRAM are loaded + if(!appProgram.getUid().equals(program.getUid())){ + continue; + } + + List events = TrackerController.getEvents(organisationUnit.getId(), program.getUid()); + Log.i(TAG, String.format("Converting surveys and values for orgUnit: %s | program: %s", organisationUnit.getLabel(), program.getDisplayName())); + for (Event event : events) { + if (!ProgressActivity.PULL_IS_ACTIVE) return; + EventExtended eventExtended = new EventExtended(event); + + //Only last X months + if(eventExtended.isTooOld()) return; + eventExtended.accept(converter); + } + } + } + + } + + /** + * Notifies a progress into the bus (the caller activity will be listening) + * + * @param msg + */ + private void postProgress(String msg) { + Dhis2Application.getEventBus().post(new SyncProgressStatus(msg)); + } + + /** + * Notifies an exception while pulling + * + * @param ex + */ + private void postException(Exception ex) { + Dhis2Application.getEventBus().post(new SyncProgressStatus(ex)); + } + + /** + * Notifies that the pull is over + */ + private void postFinish() { + //Fixme maybe it is not the best place to reload the logged user.(Without reload the user after pull, the user had diferent id and application crash). + User user = User.getLoggedUser(); + Session.setUser(user); + Dhis2Application.getEventBus().post(new SyncProgressStatus()); + } + + //Returns true if the pull thead is finish + public boolean finishPullJob() { + if (JobExecutor.isJobRunning(job.getJobId())) { + Log.d(TAG, "Job " + job.getJobId() + " is running"); + job.cancel(true); + try { + try { + JobExecutor.getInstance().dequeueRunningJob(job);} catch (Exception e) {e.printStackTrace();} + job.cancel(true); + } catch (Exception e) { + e.printStackTrace(); + } finally { + return true; + } + } + return false; + + } + +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/SyncProgressStatus.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/SyncProgressStatus.java new file mode 100644 index 0000000000..5651326286 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/SyncProgressStatus.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer; + +/** + * A simple VO that contains the progress of the pull sync + * Created by arrizabalaga on 19/11/15. + */ +public class SyncProgressStatus { + private String message; + private Exception exception; + private boolean finish; + + /** + * Builds a step progress + * @param message + */ + public SyncProgressStatus(String message){ + this.message=message; + } + + /** + * Builds an error progress + * @param exception + */ + public SyncProgressStatus(Exception exception){ + this.exception=exception; + } + + /** + * Builds a progress that notifies the process is done + */ + public SyncProgressStatus(){ + this.finish=true; + } + + /** + * Tells if this status represents an ordinary step + * @return + */ + public boolean hasProgress(){ + return this.message!=null; + } + + /** + * Tells if this status represents an error step + * @return + */ + public boolean hasError(){ + return this.exception!=null; + } + + /** + * Tells if this status represents a process that has finished + * @return + */ + public boolean isFinish(){ + return this.finish; + } + + /** + * Getter for the message + * @return + */ + public String getMessage(){ + return message; + } + + /** + * Getter for the exception + * @return + */ + public Exception getException(){ + return exception; + } +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/VisitableFromSDK.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/VisitableFromSDK.java new file mode 100644 index 0000000000..3624e5eab9 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/VisitableFromSDK.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer; + +public interface VisitableFromSDK { + void accept(IConvertFromSDKVisitor IConvertFromSDKVisitor); +} diff --git a/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/models/DataValueExtended.java b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/models/DataValueExtended.java new file mode 100644 index 0000000000..7e985e5512 --- /dev/null +++ b/app/src/main/java/org/eyeseetea/malariacare/database/iomodules/dhis/importer/models/DataValueExtended.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2015. + * + * This file is part of QIS Surveillance App. + * + * QIS Surveillance App is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * QIS Surveillance App 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with QIS Surveillance App. If not, see . + */ + +package org.eyeseetea.malariacare.database.iomodules.dhis.importer.models; + +import android.util.Log; + +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.IConvertFromSDKVisitor; +import org.eyeseetea.malariacare.database.iomodules.dhis.importer.VisitableFromSDK; +import org.eyeseetea.malariacare.database.model.Answer; +import org.eyeseetea.malariacare.database.model.Option; +import org.eyeseetea.malariacare.database.model.Question; +import org.hisp.dhis.android.sdk.persistence.models.DataValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created by arrizabalaga on 5/11/15. + */ +public class DataValueExtended implements VisitableFromSDK { + + private final static String TAG=".DataValueExtended"; + private final static String REGEXP_FACTOR=".*\\[([0-9]*)\\]"; + + DataValue dataValue; + + public DataValueExtended(){} + + public DataValueExtended(DataValue dataValue){ + this.dataValue =dataValue; + } + + @Override + public void accept(IConvertFromSDKVisitor visitor) { + visitor.visit(this); + } + + public DataValue getDataValue() { + return dataValue; + } + + public Option findOptionByQuestion(Question question) { + if(question==null){ + return null; + } + + Answer answer=question.getAnswer(); + if(answer==null){ + return null; + } + + List