Skip to content
idelcano edited this page Dec 5, 2017 · 35 revisions

Welcome to the dhis2-android-sdk wiki!


Sections:


[Functions]:

The first step for all the calls is create the d2 object

        ConfigurationModel config = ConfigurationModel.builder()
                .serverUrl(HttpUrl.parse("https://play.dhis2.org/dev/api/"))
                .build();

        d2 = new D2.Builder()
                .configuration(config)
                .databaseAdapter(databaseAdapter())
                .okHttpClient(
                        new OkHttpClient.Builder()
                                .addInterceptor(BasicAuthenticatorFactory.create(databaseAdapter()))
                                .build()
                ).build();

Example

Login

d2.logIn("user", "password").call();

Example

Pull metadata

d2.syncMetaData().call();

Example

Sync events

d2.syncSingleEvents().call();

Sync tracked entity instances

d2.syncTrackedEntityInstances().call();

Logout

d2.logOut().call();

Up


[Sync methodology]:

The synchronization methodology is incremental. When a synchronization is successful, the date of the last update is saved in the sdk shared preferences, and the following synchronization calls only get new or updated data or metadata filtering by the lastUpdate date.

Up


[Installation/configuration]:

Steps:

Add a .gitmodules file with the follow content:

 [submodule "sdk"]

          path = sdk
          url = https://github.com/EyeSeeTea/dhis2-android-sdk
          branch = development

then run: git submodule update

This should clone the repository in a "sdk"folder and "development" branch in the root path of your project.

Add in your settings.gradle the follow lines:

include ':app', ':core'
project(':core').projectDir = new File(settingsDir, 'sdk/core')

And add in app/build.gradle:

dependencies {
     compile project(':core')
}

Up


[Debug]:

How enable http log:

It's necessary to have the logging-interceptor library androidTestCompile "com.squareup.okhttp3:logging-interceptor:${libraries.okhttp}"

It's necessary to add a logging interceptor in OkHttpClient builder.

Example

loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
d2 = new D2.Builder()
       .configuration(config)
       .databaseAdapter(databaseAdapter())
       .okHttpClient(
              new OkHttpClient.Builder()
                        .addInterceptor(BasicAuthenticatorFactory.create(databaseAdapter()))
                        .addInterceptor(loggingInterceptor)
                        .build()
              ).build();
How extract DB

In the case of the test, you need add a database name, replacing the null parameter by a string in the line: Example

Add a breakpoint before database changes for example in this line: Example

and pull the database using adb, enter on terminal:

adb pull /data/user/0/org.hisp.dhis.android.test/databases/databasename.db /your/path/

In some android versions could be permissions problem, you can try this sequence of commands:

adb pull

su

adb cp /data/user/0/org.hisp.dhis.android.test/databases/databasename.db /mnt/sdcard/databasename.db

exit

exit

adb pull /mnt/sdcard/databasename.db /your/path/

Extra: if you uses data grip...

datagrip:

pragma foreign_keys = on;

pragma foreign_key_check;

Up


[Test]:

Before run tests

The instrumental tests needs a real android device, or a android emulator connected.

The instrumental tests are placed in the folder androidTest, and the unit test in the folder test.

How run tests

Using android studio

You can select "Whole project" in the ide to run all the tests. Or select a specify test, class, package, or module, clicking on the right button of the mouse and selecting "run test".

For the instrumental test you need open a virtual machine. (Click on tool, android, and open AVD manager, to configure and launch a android emulator).

Using gradle command
gradlew test connectedAndroidTest --info

or run only tests of a specific project:

./gradlew core:test --info
How see results

To see detailed results, you can view the generated html reports.

core-rules-android result:

dhis2-android-sdk/core-rules-android/build/reports/androidTests/connected/index.html

core results:

dhis2-android-sdk/core/build/reports/tests/testDebugUnitTest/index.html dhis2-android-sdk/core/build/reports/androidTests/testDebugUnitTest/index.html

core-rules result:

dhis2-android-sdk/core-rules/build/reports/tests/test/index.html

External libraries:

Mockserver

MockServer can be used for mocking any system you integrate with via HTTP or HTTPS (i.e. services, web sites, etc).

MockServer

The mockserver can return a "mock" response when a request matches an expectation.

Forward a request when the request matches an expectation (i.e. a dynamic port forwarding proxy).

Execute a callback when a request matches an expectation, allowing the response to be created dynamically.

Verify requests have been sent (i.e. as a test assertion).

How use mock server

Replace the real url by the mocked server url on d2 constructors in the test setUp

The server can be set to execute a callback when receiving a particular request. In the example we check the number of downloaded events.

The first step is create the enqueue mock responses:

        dhis2MockServer.enqueueMockResponse("user.json");
        dhis2MockServer.enqueueMockResponse("organisationUnits.json");
        dhis2MockServer.enqueueMockResponse("programs.json");
        dhis2MockServer.enqueueMockResponse("tracked_entities.json");
        dhis2MockServer.enqueueMockResponse("option_sets.json");

After that call the method:

List<OptionSet> optionSets = d2.syncMetaData().call();

And assert result:

assertThat(downloadedEvents.size(), is(57));

Example

Official website

Mockito:

What is mockito?

Mockito is a mocking framework for Java. Mockito allows convenient creation of substitutes of real objects for testing purposes. Enjoy clean tests with mock objects, improved TDD experience and beautiful mocking API.

This is util to mock android components not present during the unit tests.

How use mockito?

example

In that test the mockito is used to mock a user object, and added what should return this class for every method.

Mockito is used to mock the android framework components in our tests to run it without android emulator like a unit tests.

In the follow tests mockito is used to verify what methods are executed, in the example mocks the store response using when()thenReturn(), and after that verify the follow calls. Example

Official website

Up


[Development methodology]:

The sdk is developed using the Test-Driven Development methodology (Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: Requirements are turned into very specific test cases, then the software is improved to pass the new tests, only. Wikipedia).

The repository is a fork of dhis2 android repository and the team is developing following gitflow.

The most important thing about gitflow: the master branch contains the last release, and the development branch contains the new features).

The team is following a standard naming test methods and classes.

The most important points are:

  1. The class and test name should be read as a full sentence.

  2. The class should express what the class should be able to do.

  3. And the test should start with a verb.

You can read more about this standards reading the article codurance article.

The internal structure of the test is simple and have three blocks: Given, When, Then.

The sdk is developed using the Test-Driven Development methodology.

Up


[Advanced]:

Program rule functions already implemented
Ceil
Rounds the input argument up to the nearest whole number.
DaysBetween
Produces the number of days between the first and second argument. If the second argument date is before the first argument the return value will be the negative number of days between the two dates. The static date format is 'yyyy-MM-dd'.
Floor
Rounds the input argument down to the nearest whole number.
HasValue
Evaluates to true of the argument source field contains a value, false if no value is entered.
WeeksBetween
Produces the number of full weeks between two data elements/attributes of type date. The static date format is 'yyyy-MM-dd'.
MonthsBetween
Function which will return the number of months between the two given dates.
Zing
Function which will return zero if the argument is a negative number.
Oizp
Function which will return one if the argument is zero or a positive number, and zero if not.
Zpvc
Function which will return the count of zero or positive values among the given argument values.
Condition
Functions which will return the true value if the condition is true, false value if not.
YearsBetween
Function which will return the number of years between the two given dates.
Modulus
Produces the modulus when dividing the first with the second argument.
Concatenate
Produces a string concatenated string from the input parameters. Supports any number of parameters.
Concatenate
Produces a string concatenated string from the input parameters. Supports any number of parameters.
AddDays
Produces a date based on the first argument date, adding the second argument number of days.
Count
Counts the number of values that is entered for the source field in the argument. The source field parameter is the name of one of the defined source fields in the program.
Validate Pattern
Counts the number of values that is entered for the source field in the argument. The source field parameter is the name of one of the defined source fields in the program.
Substring
Evaluates to the part of a string specified by the start and end character number.
Split
Split the text by delimiter, and keep the nth element(0 is the first).
Round
Rounds the input argument to the nearest whole number.
Right
Evaluates to the right part of a text, num-chars from the last character.
Left
Evaluates to the left part of a text, num-chars from the first character.
Length
Find the length of a string.
LastEventDate
Find the last event date.
CountIfZeroPos
Counts the number of values that is zero or positive entered for the source field in the argument.
CountIfValue
Counts the number of matching values that is entered for the source field in the first argument. Only occurrences that matches the second argument is counted.

Not implemented at the moment of the creation of this wiki: addControlDigits, checkControlDigits.

Up