← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 14821: Add DataApprovalLevelService.getUserReadApprovalLevels()

 

------------------------------------------------------------
revno: 14821
committer: Jim Grace <jimgrace@xxxxxxxxx>
branch nick: dhis2
timestamp: Sun 2014-04-13 16:43:32 -0400
message:
  Add DataApprovalLevelService.getUserReadApprovalLevels()
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataapproval/DataApprovalLevelService.java
  dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataapproval/DefaultDataApprovalLevelService.java
  dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataapproval/DataApprovalLevelServiceTest.java
  dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataapproval/DataApprovalLevelService.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataapproval/DataApprovalLevelService.java	2014-04-07 11:28:21 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/dataapproval/DataApprovalLevelService.java	2014-04-13 20:43:32 +0000
@@ -28,7 +28,10 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+import org.hisp.dhis.organisationunit.OrganisationUnit;
+
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author Jim Grace
@@ -38,6 +41,28 @@
     String ID = DataApprovalLevelService.class.getName();
 
     /**
+     * Integer that can be used in place of approval level
+     * for data that has not been approved at any level.
+     */
+    public static final int APPROVAL_LEVEL_UNAPPROVED = 999;
+
+    /**
+     * Gets the data approval level with the given id.
+     *
+     * @param id the id.
+     * @return a data approval level.
+     */
+    DataApprovalLevel getDataApprovalLevel( int id );
+
+    /**
+     * Gets the data approval level with the given name.
+     *
+     * @param name the name.
+     * @return a data approval level.
+     */
+    DataApprovalLevel getDataApprovalLevelByName( String name );
+
+    /**
      * Gets a list of all data approval levels.
      *
      * @return List of all data approval levels, ordered from 1 to n.
@@ -45,15 +70,6 @@
     List<DataApprovalLevel> getAllDataApprovalLevels();
 
     /**
-     * Gets a list of the data approval levels for which the user has
-     * permission to perform at least one operation (approve, unapprove,
-     * accept, unaccept) for some selection of data at this approval level.
-     *
-     * @return List of selected user data approval levels, in ascending order.
-     */
-    List<DataApprovalLevel> getUserDataApprovalLevels();
-
-    /**
      * Gets data approval levels by org unit level.
      * 
      * @param orgUnitLevel the org unit level.
@@ -123,33 +139,18 @@
     void deleteDataApprovalLevel( DataApprovalLevel dataApprovalLevel );
 
     /**
-     * Gets the lowest data approval level that the current user may view.
+     * By organisation unit subhierarchy, returns the lowest data approval
+     * level at which the user may see data within that subhierarchy, if
+     * data viewing is being restricted to approved data from lower levels.
+     * <p>
+     * Returns the value APPROVAL_LEVEL_UNAPPROVED for a subhierarchy if
+     * the user may see unapproved data.
+     * <p>
      * (Note that the "lowest" approval level means the "highest" approval
      * level number.)
-     * <p>
-     * Look at all the levels, starting from the lowest level (highest level
-     * number.) If the level has no category option group, or if it has a
-     * category option group where the user can see at least one category
-     * option within the group, then the user may see the level and all
-     * higher levels.
      *
-     * @return level number of the lowest level the user can view.
-     */
-    int getLowestUserViewDataApprovalLevel();
-    
-    /**
-     * Gets the data approval level with the given id.
-     * 
-     * @param id the id.
-     * @return a data approval level.
-     */
-    DataApprovalLevel getDataApprovalLevel( int id );
-    
-    /**
-     * Gets the data approval level with the given name.
-     * 
-     * @param name the name.
-     * @return a data approval level.
-     */
-    DataApprovalLevel getDataApprovalLevelByName( String name );
+     * @return For each organisation unit subhierarchy available to the user,
+     *         the minimum data approval level within that subhierarchy.
+     */
+    Map<OrganisationUnit, Integer> getUserReadApprovalLevels();
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataapproval/DefaultDataApprovalLevelService.java'
--- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataapproval/DefaultDataApprovalLevelService.java	2014-04-10 22:52:55 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/dataapproval/DefaultDataApprovalLevelService.java	2014-04-13 20:43:32 +0000
@@ -29,6 +29,7 @@
  */
 
 import org.hisp.dhis.dataelement.CategoryOptionGroup;
+import org.hisp.dhis.dataelement.CategoryOptionGroupSet;
 import org.hisp.dhis.organisationunit.OrganisationUnit;
 import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
@@ -38,9 +39,12 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -86,6 +90,16 @@
     // DataApprovalLevel
     // -------------------------------------------------------------------------
 
+    public DataApprovalLevel getDataApprovalLevel( int id )
+    {
+        return dataApprovalLevelStore.get( id );
+    }
+
+    public DataApprovalLevel getDataApprovalLevelByName( String name )
+    {
+        return dataApprovalLevelStore.getByName( name );
+    }
+
     public List<DataApprovalLevel> getAllDataApprovalLevels()
     {
         List<DataApprovalLevel> dataApprovalLevels = dataApprovalLevelStore.getAllDataApprovalLevels();
@@ -104,7 +118,7 @@
         return dataApprovalLevels;
     }
 
-    public List<DataApprovalLevel> getUserDataApprovalLevels()
+    public List<DataApprovalLevel> getUserDataApprovalLevels_OLD()
     {
         List<DataApprovalLevel> userDataApprovalLevels = new ArrayList<DataApprovalLevel>();
 
@@ -296,39 +310,43 @@
         }
     }
 
-    public int getLowestUserViewDataApprovalLevel()
-    {
-        List<DataApprovalLevel> levels = getAllDataApprovalLevels();
-
-        for ( int i = levels.size() - 1; i <= 0; i-- )
-        {
-            DataApprovalLevel level = levels.get( i );
-
-            if ( level.getCategoryOptionGroupSet() == null || level.getCategoryOptionGroupSet().getMembers() == null )
-            {
-                return level.getLevel();
-            }
-
-            for ( CategoryOptionGroup group : level.getCategoryOptionGroupSet().getMembers() )
-            {
-                if ( securityService.canRead( group ) )
-                {
-                    return level.getLevel();
-                }
-            }
-        }
-
-        return 0;
-    }
-    
-    public DataApprovalLevel getDataApprovalLevel( int id )
-    {
-        return dataApprovalLevelStore.get( id );
-    }
-    
-    public DataApprovalLevel getDataApprovalLevelByName( String name )
-    {
-        return dataApprovalLevelStore.getByName( name );
+    public Map<OrganisationUnit, Integer> getUserReadApprovalLevels()
+    {
+        Map<OrganisationUnit, Integer> map = new HashMap<OrganisationUnit, Integer>();
+
+        User user = currentUserService.getCurrentUser();
+
+        if ( user.getUserCredentials().isAuthorized( DataApproval.AUTH_APPROVE_LOWER_LEVELS ) )
+        {
+            for ( OrganisationUnit orgUnit : user.getOrganisationUnits() )
+            {
+                map.put( orgUnit, APPROVAL_LEVEL_UNAPPROVED );
+            }
+        }
+        else
+        {
+            for ( OrganisationUnit orgUnit : user.getOrganisationUnits() )
+            {
+                map.put( orgUnit, requiredApprovalLevel( orgUnit ) );
+            }
+        }
+
+        Collection<OrganisationUnit> dataViewOrgUnits = user.getDataViewOrganisationUnits();
+
+        if ( dataViewOrgUnits == null || dataViewOrgUnits.isEmpty() )
+        {
+            dataViewOrgUnits = organisationUnitService.getRootOrganisationUnits();
+        }
+
+        for ( OrganisationUnit orgUnit : dataViewOrgUnits )
+        {
+            if ( !map.containsKey( orgUnit ) )
+            {
+                map.put(orgUnit, requiredApprovalLevel( orgUnit ) );
+            }
+        }
+
+        return map;
     }
 
     // -------------------------------------------------------------------------
@@ -414,4 +432,55 @@
         }
         return i + 1;
     }
+
+    /**
+     * Get the approval level for an organisation unit that is required
+     * in order for the user to see the data -- if user is limited to seeing
+     * approved data only from lower approval levels.
+     *
+     * @param orgUnit organisation unit to test.
+     * @return required approval level for user to see the data.
+     */
+    private int requiredApprovalLevel( OrganisationUnit orgUnit )
+    {
+        int orgUnitLevel = orgUnit.getLevel() != 0 ?
+                orgUnit.getLevel() :
+                organisationUnitService.getLevelOfOrganisationUnit( orgUnit.getUid() );
+
+        int required = APPROVAL_LEVEL_UNAPPROVED;
+
+        for ( DataApprovalLevel level : getAllDataApprovalLevels() )
+        {
+            if ( level.getOrgUnitLevel() >= orgUnitLevel
+                    && securityService.canRead( level )
+                    && ( level.getCategoryOptionGroupSet() == null || canReadSomeCategory( level.getCategoryOptionGroupSet() ) )
+                    && level.getLevel() < getAllDataApprovalLevels().size() )
+            {
+                required = level.getLevel() + 1;
+                break;
+            }
+        }
+
+        return required;
+    }
+
+    /**
+     * Can the user read at least one category from inside a category option
+     * group set?
+     *
+     * @param cogs The category option group set to test
+     * @return true if user can read at least one category option group.
+     */
+    private boolean canReadSomeCategory( CategoryOptionGroupSet cogs )
+    {
+        for ( CategoryOptionGroup cog : cogs.getMembers() )
+        {
+            if ( securityService.canRead(cog) )
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
 }

=== modified file 'dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataapproval/DataApprovalLevelServiceTest.java'
--- dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataapproval/DataApprovalLevelServiceTest.java	2014-04-07 10:18:57 +0000
+++ dhis-2/dhis-services/dhis-service-core/src/test/java/org/hisp/dhis/dataapproval/DataApprovalLevelServiceTest.java	2014-04-13 20:43:32 +0000
@@ -30,13 +30,17 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
+import static org.hisp.dhis.dataapproval.DataApprovalLevelService.APPROVAL_LEVEL_UNAPPROVED;
+
 import org.hisp.dhis.DhisSpringTest;
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.dataelement.CategoryOptionGroupSet;
@@ -96,10 +100,19 @@
     private DataApprovalLevel level4C;
     private DataApprovalLevel level4D;
 
+    private DataApprovalLevel level5;
+
     private OrganisationUnit organisationUnitA;
     private OrganisationUnit organisationUnitB;
     private OrganisationUnit organisationUnitC;
     private OrganisationUnit organisationUnitD;
+    private OrganisationUnit organisationUnitE;
+    private OrganisationUnit organisationUnitF;
+    private OrganisationUnit organisationUnitG;
+    private OrganisationUnit organisationUnitH;
+    private OrganisationUnit organisationUnitI;
+    private OrganisationUnit organisationUnitJ;
+    private OrganisationUnit organisationUnitK;
 
     // -------------------------------------------------------------------------
     // Set up/tear down
@@ -149,10 +162,38 @@
         level4C = new DataApprovalLevel( "4C", 4, setC );
         level4D = new DataApprovalLevel( "4D", 4, setD );
 
+        level5 = new DataApprovalLevel( "5", 5, null );
+
+        //
+        // Org       Organisation
+        // unit      unit
+        // level:    hierarchy:
+        //
+        //   1           A
+        //               |
+        //   2           B
+        //             / | \
+        //   3       C   F   I
+        //           |   |   |
+        //   4       D   G   J
+        //           |   |   |
+        //   5       E   H   K
+        //
+        // Note: E through K are optionally added by the test if desired.
+
         organisationUnitA = createOrganisationUnit( 'A' );
         organisationUnitB = createOrganisationUnit( 'B', organisationUnitA );
         organisationUnitC = createOrganisationUnit( 'C', organisationUnitB );
         organisationUnitD = createOrganisationUnit( 'D', organisationUnitC );
+        organisationUnitE = createOrganisationUnit( 'E', organisationUnitD );
+
+        organisationUnitF = createOrganisationUnit( 'F', organisationUnitB );
+        organisationUnitG = createOrganisationUnit( 'G', organisationUnitF );
+        organisationUnitH = createOrganisationUnit( 'H', organisationUnitG );
+
+        organisationUnitI = createOrganisationUnit( 'I', organisationUnitB );
+        organisationUnitJ = createOrganisationUnit( 'J', organisationUnitI );
+        organisationUnitK = createOrganisationUnit( 'K', organisationUnitJ );
 
         organisationUnitService.addOrganisationUnit( organisationUnitA );
         organisationUnitService.addOrganisationUnit( organisationUnitB );
@@ -435,27 +476,180 @@
     }
 
     @Test
-    public void testGetUserDataApprovalLevelsNoAuthorities() throws Exception
-    {
-        dataApprovalLevelService.addDataApprovalLevel( level4B );
-        dataApprovalLevelService.addDataApprovalLevel( level4A );
-        dataApprovalLevelService.addDataApprovalLevel( level4 );
-        dataApprovalLevelService.addDataApprovalLevel( level3B );
-        dataApprovalLevelService.addDataApprovalLevel( level3A );
-        dataApprovalLevelService.addDataApprovalLevel( level3 );
-        dataApprovalLevelService.addDataApprovalLevel( level2B );
-        dataApprovalLevelService.addDataApprovalLevel( level2A );
-        dataApprovalLevelService.addDataApprovalLevel( level2 );
-        dataApprovalLevelService.addDataApprovalLevel( level1B );
-        dataApprovalLevelService.addDataApprovalLevel( level1A );
-        dataApprovalLevelService.addDataApprovalLevel( level1 );
-
-        Set<OrganisationUnit> units = new HashSet<OrganisationUnit>();
-        units.add( organisationUnitB );
-        createUserAndInjectSecurityContext( units, false );
-
-        List<DataApprovalLevel> levels = dataApprovalLevelService.getUserDataApprovalLevels();
-        assertEquals( 0, levels.size() );
+    public void testGetUserReadApprovalLevels_1A() throws Exception
+    {
+        //
+        // Test 1: Like when a user may capture data within their own district
+        // but view data in other districts within their province.
+        //
+        // Variation A: User does *not* have approval at lower levels authority.
+        //
+        organisationUnitService.addOrganisationUnit( organisationUnitE );
+        organisationUnitService.addOrganisationUnit( organisationUnitF );
+        organisationUnitService.addOrganisationUnit( organisationUnitG );
+        organisationUnitService.addOrganisationUnit( organisationUnitH );
+
+        dataApprovalLevelService.addDataApprovalLevel( level1 );
+        dataApprovalLevelService.addDataApprovalLevel( level2 );
+        dataApprovalLevelService.addDataApprovalLevel( level3 );
+        dataApprovalLevelService.addDataApprovalLevel( level4 );
+        dataApprovalLevelService.addDataApprovalLevel( level5 );
+
+        Set<OrganisationUnit> assignedOrgUnits = new HashSet<OrganisationUnit>();
+        assignedOrgUnits.add( organisationUnitC );
+
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>();
+        dataViewOrgUnits.add( organisationUnitB );
+
+        createUserAndInjectSecurityContext( assignedOrgUnits, dataViewOrgUnits, false );
+
+        Map<OrganisationUnit, Integer> readApprovalLevels = dataApprovalLevelService.getUserReadApprovalLevels();
+        assertEquals( 2, readApprovalLevels.size() );
+
+        assertEquals( 4, (int) readApprovalLevels.get( organisationUnitC ) );
+        assertEquals( 3, (int) readApprovalLevels.get( organisationUnitB ) );
+    }
+
+    @Test
+    public void testGetUserReadApprovalLevels_1B() throws Exception
+    {
+        //
+        // Test 1: Like when a user may capture data within their own district
+        // but view data in other districts within their province.
+        //
+        // Variation B: User *has* approval at lower levels authority.
+        //
+        organisationUnitService.addOrganisationUnit( organisationUnitE );
+        organisationUnitService.addOrganisationUnit( organisationUnitF );
+        organisationUnitService.addOrganisationUnit( organisationUnitG );
+        organisationUnitService.addOrganisationUnit( organisationUnitH );
+
+        dataApprovalLevelService.addDataApprovalLevel( level1 );
+        dataApprovalLevelService.addDataApprovalLevel( level2 );
+        dataApprovalLevelService.addDataApprovalLevel( level3 );
+        dataApprovalLevelService.addDataApprovalLevel( level4 );
+        dataApprovalLevelService.addDataApprovalLevel( level5 );
+
+        Set<OrganisationUnit> assignedOrgUnits = new HashSet<OrganisationUnit>();
+        assignedOrgUnits.add( organisationUnitC );
+
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>();
+        dataViewOrgUnits.add( organisationUnitB );
+
+        createUserAndInjectSecurityContext( assignedOrgUnits, dataViewOrgUnits, false, DataApproval.AUTH_APPROVE_LOWER_LEVELS );
+
+        Map<OrganisationUnit, Integer> readApprovalLevels = dataApprovalLevelService.getUserReadApprovalLevels();
+        assertEquals( 2, readApprovalLevels.size() );
+
+        assertEquals( APPROVAL_LEVEL_UNAPPROVED, (int) readApprovalLevels.get( organisationUnitC ) );
+        assertEquals( 3, (int) readApprovalLevels.get( organisationUnitB ) );
+    }
+
+    @Test
+    public void testGetUserReadApprovalLevels_1C() throws Exception
+    {
+        //
+        // Test 1: Like when a user may capture data within their own district
+        // but view data in other districts within their province.
+        //
+        // Variation C: No approval level for org unit level 4.
+        //
+        organisationUnitService.addOrganisationUnit( organisationUnitE );
+        organisationUnitService.addOrganisationUnit( organisationUnitF );
+        organisationUnitService.addOrganisationUnit( organisationUnitG );
+        organisationUnitService.addOrganisationUnit( organisationUnitH );
+
+        dataApprovalLevelService.addDataApprovalLevel( level1 ); // 1st approval level
+        dataApprovalLevelService.addDataApprovalLevel( level2 ); // 2nd approval level
+        dataApprovalLevelService.addDataApprovalLevel( level3 ); // 3rd approval level
+        dataApprovalLevelService.addDataApprovalLevel( level5 ); // 4th approval level
+
+        Set<OrganisationUnit> assignedOrgUnits = new HashSet<OrganisationUnit>();
+        assignedOrgUnits.add( organisationUnitC );
+
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>();
+        dataViewOrgUnits.add( organisationUnitB );
+
+        createUserAndInjectSecurityContext( assignedOrgUnits, dataViewOrgUnits, false );
+
+        Map<OrganisationUnit, Integer> readApprovalLevels = dataApprovalLevelService.getUserReadApprovalLevels();
+        assertEquals( 2, readApprovalLevels.size() );
+
+        assertEquals( 4, (int) readApprovalLevels.get( organisationUnitC ) );
+        assertEquals( 3, (int) readApprovalLevels.get( organisationUnitB ) );
+    }
+
+    @Test
+    public void testGetUserReadApprovalLevels_1D() throws Exception
+    {
+        //
+        // Test 1: Like when a user may capture data within their own district
+        // but view data in other districts within their province.
+        //
+        // Variation D: User is assigned to two districts
+        //
+        organisationUnitService.addOrganisationUnit( organisationUnitE );
+        organisationUnitService.addOrganisationUnit( organisationUnitF );
+        organisationUnitService.addOrganisationUnit( organisationUnitG );
+        organisationUnitService.addOrganisationUnit( organisationUnitH );
+        organisationUnitService.addOrganisationUnit( organisationUnitI );
+        organisationUnitService.addOrganisationUnit( organisationUnitJ );
+        organisationUnitService.addOrganisationUnit( organisationUnitK );
+
+        dataApprovalLevelService.addDataApprovalLevel( level1 );
+        dataApprovalLevelService.addDataApprovalLevel( level2 );
+        dataApprovalLevelService.addDataApprovalLevel( level3 );
+        dataApprovalLevelService.addDataApprovalLevel( level4 );
+        dataApprovalLevelService.addDataApprovalLevel( level5 );
+
+        Set<OrganisationUnit> assignedOrgUnits = new HashSet<OrganisationUnit>();
+        assignedOrgUnits.add( organisationUnitC );
+        assignedOrgUnits.add( organisationUnitF );
+
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>();
+        dataViewOrgUnits.add( organisationUnitB );
+
+        createUserAndInjectSecurityContext( assignedOrgUnits, dataViewOrgUnits, false );
+
+        Map<OrganisationUnit, Integer> readApprovalLevels = dataApprovalLevelService.getUserReadApprovalLevels();
+        assertEquals( 3, readApprovalLevels.size() );
+
+        assertEquals( 4, (int) readApprovalLevels.get( organisationUnitC ) );
+        assertEquals( 4, (int) readApprovalLevels.get( organisationUnitF ) );
+        assertEquals( 3, (int) readApprovalLevels.get( organisationUnitB ) );
+    }
+
+    /*
+    @Test
+    public void testGetUserReadApprovalLevels_2A() throws Exception
+    {
+        //
+        // Test 2... TBD
+        //
+        organisationUnitService.addOrganisationUnit( organisationUnitE );
+        organisationUnitService.addOrganisationUnit( organisationUnitF );
+        organisationUnitService.addOrganisationUnit( organisationUnitG );
+        organisationUnitService.addOrganisationUnit( organisationUnitH );
+
+        dataApprovalLevelService.addDataApprovalLevel( level1 );
+        dataApprovalLevelService.addDataApprovalLevel( level2 );
+        dataApprovalLevelService.addDataApprovalLevel( level3 );
+        dataApprovalLevelService.addDataApprovalLevel( level4 );
+        dataApprovalLevelService.addDataApprovalLevel( level5 );
+
+        Set<OrganisationUnit> assignedOrgUnits = new HashSet<OrganisationUnit>();
+        assignedOrgUnits.add( organisationUnitC );
+
+        Set<OrganisationUnit> dataViewOrgUnits = new HashSet<OrganisationUnit>();
+        dataViewOrgUnits.add( organisationUnitB );
+
+        createUserAndInjectSecurityContext( assignedOrgUnits, dataViewOrgUnits, false );
+
+        Map<OrganisationUnit, Integer> readApprovalLevels = dataApprovalLevelService.getUserReadApprovalLevels();
+        assertEquals( 2, readApprovalLevels.size() );
+
+        assertEquals( 4, (int) readApprovalLevels.get( organisationUnitC ) );
+        assertEquals( 3, (int) readApprovalLevels.get( organisationUnitB ) );
     }
 
     @Test
@@ -581,4 +775,6 @@
         assertEquals( "2B", levels.get( 1 ).getName() );
         assertEquals( "3", levels.get( 2 ).getName() );
     }
+    */
+
 }

=== modified file 'dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java'
--- dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2014-03-28 01:54:06 +0000
+++ dhis-2/dhis-support/dhis-support-test/src/main/java/org/hisp/dhis/DhisConvenienceTest.java	2014-04-13 20:43:32 +0000
@@ -1193,7 +1193,7 @@
     }
 
     /**
-     * @param uniqueCharacter A unique character to identify the object.
+     * @param uniqueChar A unique character to identify the object.
      * @return TrackedEntityAttribute
      */
     public static TrackedEntityAttribute createTrackedEntityAttribute( char uniqueChar )
@@ -1208,7 +1208,7 @@
     }
 
     /**
-     * @param uniqueCharacter A unique character to identify the object.
+     * @param uniqueChar A unique character to identify the object.
      * @return TrackedEntityAttribute
      */
     public static TrackedEntityAttribute createTrackedEntityAttribute( char uniqueChar, String type )
@@ -1223,7 +1223,7 @@
     }
 
     /**
-     * @param uniqueCharacter A unique character to identify the object.
+     * @param uniqueChar A unique character to identify the object.
      * @return TrackedEntityAttributeGroup
      */
     public static TrackedEntityAttributeGroup createTrackedEntityAttributeGroup( char uniqueChar, List<TrackedEntityAttribute> attributes )
@@ -1256,7 +1256,7 @@
     }
 
     /**
-     * @param uniqueCharacter A unique character to identify the object.
+     * @param uniqueChar A unique character to identify the object.
      * @return RelationshipType
      */
     public static RelationshipType createRelationshipType( char uniqueChar )
@@ -1440,6 +1440,22 @@
      */
     public User createUserAndInjectSecurityContext( Set<OrganisationUnit> organisationUnits, boolean allAuth, String... auths )
     {
+        return createUserAndInjectSecurityContext( organisationUnits, null, allAuth, auths );
+    }
+
+    /**
+     * Creates a user and injects into the security context with username
+     * "username". Requires <code>identifiableObjectManager</code> and
+     * <code>userService</code> to be injected into the test.
+     *
+     * @param organisationUnits         the organisation units of the user.
+     * @param dataViewOrganisationUnits user's data view organisation units.
+     * @param allAuth                   whether to grant the ALL authority.
+     * @param auths                     authorities to grant to user.
+     * @return the user.
+     */
+    public User createUserAndInjectSecurityContext( Set<OrganisationUnit> organisationUnits, Set<OrganisationUnit> dataViewOrganisationUnits, boolean allAuth, String... auths )
+    {
         Assert.notNull( identifiableObjectManager, "IdentifiableObjectManager must be injected in test" );
         Assert.notNull( userService, "UserService must be injected in test" );
 
@@ -1468,6 +1484,11 @@
             user.setOrganisationUnits( organisationUnits );
         }
 
+        if ( dataViewOrganisationUnits != null )
+        {
+            user.setDataViewOrganisationUnits( dataViewOrganisationUnits );
+        }
+
         user.getUserCredentials().getUserAuthorityGroups().add( userAuthorityGroup );
         userService.addUser( user );
         user.getUserCredentials().setUser( user );