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 android.database.Cursor;
20 import android.database.MatrixCursor;
21 import android.database.MergeCursor;
22 import android.provider.DocumentsContract.Document;
23 import android.support.test.filters.SmallTest;
24 import android.test.AndroidTestCase;
25 
26 import com.android.documentsui.base.DocumentInfo;
27 import com.android.documentsui.roots.RootCursorWrapper;
28 import com.android.documentsui.testing.TestEventListener;
29 import com.android.documentsui.testing.TestFeatures;
30 
31 import java.util.BitSet;
32 import java.util.Random;
33 
34 @SmallTest
35 public class ModelTest extends AndroidTestCase {
36 
37     private static final int ITEM_COUNT = 10;
38     private static final String AUTHORITY = "test_authority";
39 
40     private static final String[] COLUMNS = new String[]{
41         RootCursorWrapper.COLUMN_AUTHORITY,
42         Document.COLUMN_DOCUMENT_ID,
43         Document.COLUMN_FLAGS,
44         Document.COLUMN_DISPLAY_NAME,
45         Document.COLUMN_SIZE,
46         Document.COLUMN_LAST_MODIFIED,
47         Document.COLUMN_MIME_TYPE
48     };
49 
50     private static final String[] NAMES = new String[] {
51             "4",
52             "foo",
53             "1",
54             "bar",
55             "*(Ljifl;a",
56             "0",
57             "baz",
58             "2",
59             "3",
60             "%$%VD"
61         };
62 
63     private Cursor cursor;
64     private Model model;
65     private TestFeatures features;
66 
67     @Override
setUp()68     public void setUp() {
69         features = new TestFeatures();
70 
71         Random rand = new Random();
72 
73         MatrixCursor c = new MatrixCursor(COLUMNS);
74         for (int i = 0; i < ITEM_COUNT; ++i) {
75             MatrixCursor.RowBuilder row = c.newRow();
76             row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
77             row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
78             row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
79             // Generate random document names and sizes. This forces the model's internal sort code
80             // to actually do something.
81             row.add(Document.COLUMN_DISPLAY_NAME, NAMES[i]);
82             row.add(Document.COLUMN_SIZE, rand.nextInt());
83         }
84         cursor = c;
85 
86         DirectoryResult r = new DirectoryResult();
87         r.cursor = cursor;
88 
89         // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
90         model = new Model(features);
91         // not sure why we add a listener here at all.
92         model.addUpdateListener(new TestEventListener<>());
93         model.update(r);
94     }
95 
96     // Tests that the item count is correct.
testItemCount()97     public void testItemCount() {
98         assertEquals(ITEM_COUNT, model.getItemCount());
99     }
100 
101     // Tests multiple authorities with clashing document IDs.
testModelIdIsUnique()102     public void testModelIdIsUnique() {
103         MatrixCursor cIn1 = new MatrixCursor(COLUMNS);
104         MatrixCursor cIn2 = new MatrixCursor(COLUMNS);
105 
106         // Make two sets of items with the same IDs, under different authorities.
107         final String AUTHORITY0 = "auth0";
108         final String AUTHORITY1 = "auth1";
109 
110         for (int i = 0; i < ITEM_COUNT; ++i) {
111             MatrixCursor.RowBuilder row0 = cIn1.newRow();
112             row0.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY0);
113             row0.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
114 
115             MatrixCursor.RowBuilder row1 = cIn2.newRow();
116             row1.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY1);
117             row1.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
118         }
119 
120         Cursor cIn = new MergeCursor(new Cursor[] { cIn1, cIn2 });
121 
122         // Update the model, then make sure it contains all the expected items.
123         DirectoryResult r = new DirectoryResult();
124         r.cursor = cIn;
125         model.update(r);
126 
127         assertEquals(ITEM_COUNT * 2, model.getItemCount());
128         BitSet b0 = new BitSet(ITEM_COUNT);
129         BitSet b1 = new BitSet(ITEM_COUNT);
130 
131         for (String id: model.getModelIds()) {
132             Cursor cOut = model.getItem(id);
133             String authority =
134                     DocumentInfo.getCursorString(cOut, RootCursorWrapper.COLUMN_AUTHORITY);
135             String docId = DocumentInfo.getCursorString(cOut, Document.COLUMN_DOCUMENT_ID);
136 
137             switch (authority) {
138                 case AUTHORITY0:
139                     b0.set(Integer.parseInt(docId));
140                     break;
141                 case AUTHORITY1:
142                     b1.set(Integer.parseInt(docId));
143                     break;
144                 default:
145                     fail("Unrecognized authority string");
146             }
147         }
148 
149         assertEquals(ITEM_COUNT, b0.cardinality());
150         assertEquals(ITEM_COUNT, b1.cardinality());
151     }
152 
153     // Tests the base case for Model.getItem.
testGetItem()154     public void testGetItem() {
155         String[] ids = model.getModelIds();
156         assertEquals(ITEM_COUNT, ids.length);
157         for (int i = 0; i < ITEM_COUNT; ++i) {
158             Cursor c = model.getItem(ids[i]);
159             assertEquals(i, c.getPosition());
160         }
161     }
162 }
163