1/*
2 * Copyright (C) 2016 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
17package com.android.documentsui.dirlist;
18
19import static junit.framework.Assert.assertFalse;
20import static junit.framework.Assert.assertTrue;
21import static junit.framework.TestCase.fail;
22
23import android.provider.DocumentsContract;
24import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
26import android.view.MotionEvent;
27import android.view.View;
28
29import com.android.documentsui.MenuManager;
30import com.android.documentsui.MenuManager.SelectionDetails;
31import com.android.documentsui.base.DocumentInfo;
32import com.android.documentsui.base.Providers;
33import com.android.documentsui.base.State;
34import com.android.documentsui.dirlist.DragStartListener.ActiveListener;
35import com.android.documentsui.base.Events.InputEvent;
36import com.android.documentsui.selection.SelectionManager;
37import com.android.documentsui.selection.Selection;
38import com.android.documentsui.testing.TestDragAndDropManager;
39import com.android.documentsui.testing.TestEvent;
40import com.android.documentsui.testing.SelectionManagers;
41import com.android.documentsui.testing.TestSelectionDetails;
42import com.android.documentsui.testing.Views;
43
44import org.junit.Before;
45import org.junit.Test;
46import org.junit.runner.RunWith;
47
48import java.util.ArrayList;
49
50@RunWith(AndroidJUnit4.class)
51@SmallTest
52public class DragStartListenerTest {
53
54    private ActiveListener mListener;
55    private TestEvent.Builder mEvent;
56    private SelectionManager mMultiSelectManager;
57    private SelectionDetails mSelectionDetails;
58    private String mViewModelId;
59    private TestDragAndDropManager mManager;
60
61    @Before
62    public void setUp() throws Exception {
63        mMultiSelectManager = SelectionManagers.createTestInstance();
64        mManager = new TestDragAndDropManager();
65        mSelectionDetails = new TestSelectionDetails();
66
67        DocumentInfo doc = new DocumentInfo();
68        doc.authority = Providers.AUTHORITY_STORAGE;
69        doc.documentId = "id";
70        doc.derivedUri = DocumentsContract.buildDocumentUri(doc.authority, doc.documentId);
71
72        State state = new State();
73        state.stack.push(doc);
74        mListener = new DragStartListener.ActiveListener(
75                null, // icon helper
76                state,
77                mMultiSelectManager,
78                mSelectionDetails,
79                // view finder
80                (float x, float y) -> {
81                    return Views.createTestView(x, y);
82                },
83                // model id finder
84                (View view) -> {
85                    return mViewModelId;
86                },
87                // docInfo Converter
88                (Selection selection) -> {
89                    return new ArrayList<DocumentInfo>();
90                },
91                mManager);
92
93        mViewModelId = "1234";
94
95        mEvent = TestEvent.builder()
96                .action(MotionEvent.ACTION_MOVE)
97                .mouse()
98                .at(1)
99                .inDragHotspot()
100                .primary();
101    }
102
103    @Test
104    public void testDragStarted_OnMouseMove() {
105        assertTrue(mListener.onMouseDragEvent(mEvent.build()));
106        mManager.startDragHandler.assertCalled();
107    }
108
109    @Test
110    public void testDragNotStarted_NonModelBackedView() {
111        mViewModelId = null;
112        assertFalse(mListener.onMouseDragEvent(mEvent.build()));
113        mManager.startDragHandler.assertNotCalled();
114    }
115
116    @Test
117    public void testThrows_OnNonMouseMove() {
118        TestEvent e = TestEvent.builder()
119                .at(1)
120                .action(MotionEvent.ACTION_MOVE).build();
121        assertThrows(e);
122    }
123
124    @Test
125    public void testThrows_OnNonPrimaryMove() {
126        assertThrows(mEvent.pressButton(MotionEvent.BUTTON_PRIMARY).build());
127    }
128
129    @Test
130    public void testThrows_OnNonMove() {
131        assertThrows(mEvent.action(MotionEvent.ACTION_UP).build());
132    }
133
134    @Test
135    public void testThrows_WhenNotOnItem() {
136        assertThrows(mEvent.at(-1).build());
137    }
138
139    @Test
140    public void testDragStart_nonSelectedItem() {
141        Selection selection = mListener.getSelectionToBeCopied("1234",
142                mEvent.action(MotionEvent.ACTION_MOVE).build());
143        assertTrue(selection.size() == 1);
144        assertTrue(selection.contains("1234"));
145    }
146
147    @Test
148    public void testDragStart_selectedItem() {
149        Selection selection = new Selection();
150        selection.add("1234");
151        selection.add("5678");
152        mMultiSelectManager.replaceSelection(selection);
153
154        selection = mListener.getSelectionToBeCopied("1234",
155                mEvent.action(MotionEvent.ACTION_MOVE).build());
156        assertTrue(selection.size() == 2);
157        assertTrue(selection.contains("1234"));
158        assertTrue(selection.contains("5678"));
159    }
160
161    @Test
162    public void testDragStart_newNonSelectedItem() {
163        Selection selection = new Selection();
164        selection.add("5678");
165        mMultiSelectManager.replaceSelection(selection);
166
167        selection = mListener.getSelectionToBeCopied("1234",
168                mEvent.action(MotionEvent.ACTION_MOVE).build());
169        assertTrue(selection.size() == 1);
170        assertTrue(selection.contains("1234"));
171        // After this, selection should be cleared
172        assertFalse(mMultiSelectManager.hasSelection());
173    }
174
175    @Test
176    public void testCtrlDragStart_newNonSelectedItem() {
177        Selection selection = new Selection();
178        selection.add("5678");
179        mMultiSelectManager.replaceSelection(selection);
180
181        selection = mListener.getSelectionToBeCopied("1234",
182                mEvent.action(MotionEvent.ACTION_MOVE).ctrl().build());
183        assertTrue(selection.size() == 2);
184        assertTrue(selection.contains("1234"));
185        assertTrue(selection.contains("5678"));
186    }
187
188    private void assertThrows(InputEvent e) {
189        try {
190            assertFalse(mListener.onMouseDragEvent(e));
191            fail();
192        } catch (AssertionError expected) {}
193    }
194}
195