Home | History | Annotate | Download | only in documentsui
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.documentsui;
     18 
     19 import static junit.framework.Assert.assertEquals;
     20 import static junit.framework.Assert.fail;
     21 
     22 import android.database.Cursor;
     23 import android.database.MatrixCursor;
     24 import android.database.MergeCursor;
     25 import android.provider.DocumentsContract.Document;
     26 import android.support.test.filters.SmallTest;
     27 import android.support.test.runner.AndroidJUnit4;
     28 
     29 import com.android.documentsui.base.DocumentInfo;
     30 import com.android.documentsui.roots.RootCursorWrapper;
     31 import com.android.documentsui.testing.TestEventListener;
     32 import com.android.documentsui.testing.TestFeatures;
     33 
     34 import org.junit.Before;
     35 import org.junit.Test;
     36 import org.junit.runner.RunWith;
     37 
     38 import java.util.BitSet;
     39 import java.util.Random;
     40 
     41 @RunWith(AndroidJUnit4.class)
     42 @SmallTest
     43 public class ModelTest {
     44 
     45     private static final int ITEM_COUNT = 10;
     46     private static final String AUTHORITY = "test_authority";
     47 
     48     private static final String[] COLUMNS = new String[]{
     49         RootCursorWrapper.COLUMN_AUTHORITY,
     50         Document.COLUMN_DOCUMENT_ID,
     51         Document.COLUMN_FLAGS,
     52         Document.COLUMN_DISPLAY_NAME,
     53         Document.COLUMN_SIZE,
     54         Document.COLUMN_LAST_MODIFIED,
     55         Document.COLUMN_MIME_TYPE
     56     };
     57 
     58     private static final String[] NAMES = new String[] {
     59             "4",
     60             "foo",
     61             "1",
     62             "bar",
     63             "*(Ljifl;a",
     64             "0",
     65             "baz",
     66             "2",
     67             "3",
     68             "%$%VD"
     69         };
     70 
     71     private Cursor cursor;
     72     private Model model;
     73     private TestFeatures features;
     74 
     75     @Before
     76     public void setUp() {
     77         features = new TestFeatures();
     78 
     79         Random rand = new Random();
     80 
     81         MatrixCursor c = new MatrixCursor(COLUMNS);
     82         for (int i = 0; i < ITEM_COUNT; ++i) {
     83             MatrixCursor.RowBuilder row = c.newRow();
     84             row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
     85             row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
     86             row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
     87             // Generate random document names and sizes. This forces the model's internal sort code
     88             // to actually do something.
     89             row.add(Document.COLUMN_DISPLAY_NAME, NAMES[i]);
     90             row.add(Document.COLUMN_SIZE, rand.nextInt());
     91         }
     92         cursor = c;
     93 
     94         DirectoryResult r = new DirectoryResult();
     95         r.cursor = cursor;
     96 
     97         // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
     98         model = new Model(features);
     99         // not sure why we add a listener here at all.
    100         model.addUpdateListener(new TestEventListener<>());
    101         model.update(r);
    102     }
    103 
    104     // Tests that the item count is correct.
    105     @Test
    106     public void testItemCount() {
    107         assertEquals(ITEM_COUNT, model.getItemCount());
    108     }
    109 
    110     // Tests multiple authorities with clashing document IDs.
    111     @Test
    112     public void testModelIdIsUnique() {
    113         MatrixCursor cIn1 = new MatrixCursor(COLUMNS);
    114         MatrixCursor cIn2 = new MatrixCursor(COLUMNS);
    115 
    116         // Make two sets of items with the same IDs, under different authorities.
    117         final String AUTHORITY0 = "auth0";
    118         final String AUTHORITY1 = "auth1";
    119 
    120         for (int i = 0; i < ITEM_COUNT; ++i) {
    121             MatrixCursor.RowBuilder row0 = cIn1.newRow();
    122             row0.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY0);
    123             row0.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
    124 
    125             MatrixCursor.RowBuilder row1 = cIn2.newRow();
    126             row1.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY1);
    127             row1.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
    128         }
    129 
    130         Cursor cIn = new MergeCursor(new Cursor[] { cIn1, cIn2 });
    131 
    132         // Update the model, then make sure it contains all the expected items.
    133         DirectoryResult r = new DirectoryResult();
    134         r.cursor = cIn;
    135         model.update(r);
    136 
    137         assertEquals(ITEM_COUNT * 2, model.getItemCount());
    138         BitSet b0 = new BitSet(ITEM_COUNT);
    139         BitSet b1 = new BitSet(ITEM_COUNT);
    140 
    141         for (String id: model.getModelIds()) {
    142             Cursor cOut = model.getItem(id);
    143             String authority =
    144                     DocumentInfo.getCursorString(cOut, RootCursorWrapper.COLUMN_AUTHORITY);
    145             String docId = DocumentInfo.getCursorString(cOut, Document.COLUMN_DOCUMENT_ID);
    146 
    147             switch (authority) {
    148                 case AUTHORITY0:
    149                     b0.set(Integer.parseInt(docId));
    150                     break;
    151                 case AUTHORITY1:
    152                     b1.set(Integer.parseInt(docId));
    153                     break;
    154                 default:
    155                     fail("Unrecognized authority string");
    156             }
    157         }
    158 
    159         assertEquals(ITEM_COUNT, b0.cardinality());
    160         assertEquals(ITEM_COUNT, b1.cardinality());
    161     }
    162 
    163     // Tests the base case for Model.getItem.
    164     @Test
    165     public void testGetItem() {
    166         String[] ids = model.getModelIds();
    167         assertEquals(ITEM_COUNT, ids.length);
    168         for (int i = 0; i < ITEM_COUNT; ++i) {
    169             Cursor c = model.getItem(ids[i]);
    170             assertEquals(i, c.getPosition());
    171         }
    172     }
    173 
    174     @Test
    175     public void testResetAfterGettingException() {
    176         DirectoryResult result = new DirectoryResult();
    177         result.exception = new Exception();
    178 
    179         model.update(result);
    180 
    181         assertEquals(0, model.getItemCount());
    182     }
    183 }
    184