@@ -0,0 +1,236 @@
1+/*
2+ * Copyright 2013 Canonical Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.1
18+import QtQuick.Layouts 1.1
19+import QtTest 1.0
20+import Unity.Test 0.1 as UT
21+import Ubuntu.Components 0.1
22+import Unity.Indicators 0.1 as Indicators
23+import Ubuntu.Telephony 0.1 as Telephony
24+import "../../../qml/Panel"
25+
26+IndicatorTest {
27+ id: root
28+ width: units.gu(100)
29+ height: units.gu(71)
30+ color: "white"
31+
32+ property string indicatorProfile: "phone"
33+
34+ RowLayout {
35+ anchors.fill: parent
36+ anchors.margins: units.gu(1)
37+ clip: true
38+
39+ Rectangle {
40+ Layout.fillWidth: true
41+ Layout.fillHeight: true
42+
43+ id: itemArea
44+ color: "blue"
45+
46+ Panel {
47+ id: panel
48+ anchors.fill: parent
49+ indicators {
50+ width: parent.width > units.gu(60) ? units.gu(40) : parent.width
51+ indicatorsModel: root.indicatorsModel
52+ }
53+
54+ property real panelAndSeparatorHeight: panel.indicators.minimizedPanelHeight + units.dp(2)
55+ }
56+ }
57+
58+ ColumnLayout {
59+ Layout.alignment: Qt.AlignTop
60+ Layout.fillWidth: false
61+
62+ Button {
63+ Layout.fillWidth: true
64+ text: panel.indicators.shown ? "Hide" : "Show"
65+ onClicked: {
66+ if (panel.indicators.shown) {
67+ panel.indicators.hide();
68+ } else {
69+ panel.indicators.show();
70+ }
71+ }
72+ }
73+
74+ Button {
75+ text: panel.fullscreenMode ? "Maximize" : "FullScreen"
76+ Layout.fillWidth: true
77+ onClicked: panel.fullscreenMode = !panel.fullscreenMode
78+ }
79+
80+ Button {
81+ Layout.fillWidth: true
82+ text: callManager.hasCalls ? "Called" : "No Calls"
83+ onClicked: {
84+ if (callManager.foregroundCall) {
85+ callManager.foregroundCall = null;
86+ } else {
87+ callManager.foregroundCall = phoneCall;
88+ }
89+ }
90+ }
91+
92+ Rectangle {
93+ Layout.preferredHeight: units.dp(1);
94+ Layout.fillWidth: true;
95+ color: "black"
96+ }
97+
98+ Repeater {
99+ model: indicatorsModel.originalModelData
100+ RowLayout {
101+ CheckBox {
102+ checked: true
103+ onCheckedChanged: checked ? insertIndicator(index) : removeIndicator(index);
104+ }
105+ Label { text: modelData["identifier"] }
106+ }
107+ }
108+ }
109+ }
110+
111+ Telephony.CallEntry {
112+ id: phoneCall
113+ phoneNumber: "+447812221111"
114+ }
115+
116+ UT.UnityTestCase {
117+ name: "Panel"
118+ when: windowShown
119+
120+ function init() {
121+ panel.fullscreenMode = false;
122+ callManager.foregroundCall = null;
123+
124+ panel.indicators.hide();
125+ // Wait for animation to complete
126+ tryCompare(panel.indicators.hideAnimation, "running", false);
127+
128+ // Wait for the indicators to get into position.
129+ // (switches between normal and fullscreen modes are animated)
130+ var indicatorArea = findChild(panel, "indicatorArea");
131+ tryCompare(indicatorArea, "y", 0);
132+ }
133+
134+ function get_indicator_item(index) {
135+ var indicatorItem = findChild(panel, indicatorsModel.originalModelData[index]["identifier"]+"-panelItem");
136+ verify(indicatorItem !== null);
137+
138+ return indicatorItem;
139+ }
140+
141+ function test_drag_show_data() {
142+ return [
143+ { tag: "pinned", fullscreen: false, call: null,
144+ indicatorY: 0 },
145+ { tag: "fullscreen", fullscreen: true, call: null,
146+ indicatorY: -panel.panelAndSeparatorHeight },
147+ { tag: "pinned-callActive", fullscreen: false, call: phoneCall,
148+ indicatorY: 0},
149+ { tag: "fullscreen-callActive", fullscreen: true, call: phoneCall,
150+ indicatorY: -panel.panelAndSeparatorHeight }
151+ ];
152+ }
153+
154+ // Dragging from a indicator item in the panel will gradually expose the
155+ // indicators, first by running the hint animation, then after dragging down will
156+ // expose more of the panel, binding it to the selected indicator and opening it's menu.
157+ function test_drag_show(data) {
158+ panel.fullscreenMode = data.fullscreen;
159+ callManager.foregroundCall = data.call;
160+
161+ var indicatorRow = findChild(panel.indicators, "indicatorItemRow");
162+ verify(indicatorRow !== null);
163+
164+ var menuContent = findChild(panel.indicators, "menuContent");
165+ verify(menuContent !== null);
166+
167+ var indicatorArea = findChild(panel, "indicatorArea");
168+ verify(indicatorArea !== null);
169+
170+ // Wait for the indicators to get into position.
171+ // (switches between normal and fullscreen modes are animated)
172+ tryCompareFunction(function() { return indicatorArea.y }, data.indicatorY);
173+
174+ for (var i = 0; i < indicatorsModel.originalModelData.length; i++) {
175+ var indicatorItem = get_indicator_item(i);
176+ var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, indicatorItem.height / 2);
177+
178+ touchFlick(panel,
179+ mappedPosition.x, panel.indicators.minimizedPanelHeight / 2,
180+ mappedPosition.x, panel.height,
181+ true /* beginTouch */, false /* endTouch */, units.gu(5), 15);
182+
183+ // Indicators height should follow the drag, and therefore increase accordingly.
184+ // They should be at least half-way through the screen
185+ tryCompareFunction(
186+ function() {return panel.indicators.height >= panel.height * 0.5},
187+ true);
188+
189+ touchRelease(panel, mappedPosition.x, panel.height);
190+
191+ compare(indicatorRow.currentItemIndex, i, "Indicator item should be activated at position " + i);
192+ compare(menuContent.currentMenuIndex, i, "Menu conetent should be activated for item at position " + i);
193+
194+ // init for next indicatorItem
195+ panel.indicators.hide();
196+ tryCompare(panel.indicators.hideAnimation, "running", false);
197+ tryCompare(panel.indicators, "state", "initial");
198+ }
199+ }
200+
201+ function test_hint_data() {
202+ return [
203+ { tag: "normal", fullscreen: false, call: null, hintExpected: true},
204+ { tag: "fullscreen", fullscreen: true, call: null, hintExpected: false},
205+ { tag: "call hint", fullscreen: false, call: phoneCall, hintExpected: false},
206+ ];
207+ }
208+
209+ function test_hint(data) {
210+ panel.fullscreenMode = data.fullscreen;
211+ callManager.foregroundCall = data.call;
212+
213+ if (data.fullscreen) {
214+ // Wait for the indicators to get into position.
215+ // (switches between normal and fullscreen modes are animated)
216+ var indicatorArea = findChild(panel, "indicatorArea");
217+ tryCompare(indicatorArea, "y", -panel.panelHeight);
218+ }
219+
220+ var indicatorItem = get_indicator_item(0);
221+ var mappedPosition = root.mapFromItem(indicatorItem, indicatorItem.width / 2, indicatorItem.height / 2);
222+
223+ touchPress(panel, mappedPosition.x, panel.indicators.minimizedPanelHeight / 2);
224+
225+ // Give some time for a hint animation to change things, if any
226+ wait(500);
227+
228+ // no hint animation when fullscreen
229+ compare(panel.indicators.fullyClosed, !data.hintExpected, "Indicator should be fully closed");
230+ compare(panel.indicators.partiallyOpened, data.hintExpected, "Indicator should be partialy opened");
231+ compare(panel.indicators.fullyOpened, false, "Indicator should not be fully opened");
232+
233+ touchRelease(panel, mappedPosition.x, panel.minimizedPanelHeight / 2);
234+ }
235+ }
236+}