on xenial help sign in
Merge josh's ported-session-test
d31f301Michael Terry
qml/Greeter/LoginList.qml−2
@@ -36,12 +36,10 @@ StyledItem {
36 readonly property int cellHeight: units.gu(5)
36 readonly property int cellHeight: units.gu(5)
37 readonly property int highlightedHeight: units.gu(15)
37 readonly property int highlightedHeight: units.gu(15)
38 readonly property int moveDuration: UbuntuAnimation.FastDuration
38 readonly property int moveDuration: UbuntuAnimation.FastDuration
39− property string selectedSession
40 property string currentSession
39 property string currentSession
41 readonly property string currentUser: userList.currentItem.username
40 readonly property string currentUser: userList.currentItem.username
42 property bool wasPrompted: false
41 property bool wasPrompted: false
43
42
44− signal loginListSessionChanged(string session)
45 signal responded(string response)
43 signal responded(string response)
46 signal selected(int index)
44 signal selected(int index)
47 signal sessionChooserButtonClicked()
45 signal sessionChooserButtonClicked()
qml/Greeter/WideView.qml+1−4
@@ -125,8 +125,6 @@ FocusScope {
125 id: loginList
125 id: loginList
126 objectName: "loginList"
126 objectName: "loginList"
127
127
128− property int selectedUserIndex: 0
129−
130 width: units.gu(40)
128 width: units.gu(40)
131 anchors {
129 anchors {
132 left: parent.left
130 left: parent.left
@@ -141,11 +139,10 @@ FocusScope {
141 Behavior on boxVerticalOffset { UbuntuNumberAnimation {} }
139 Behavior on boxVerticalOffset { UbuntuNumberAnimation {} }
142
140
143 model: root.userModel
141 model: root.userModel
144− currentSession: LightDMService.users.data(selectedUserIndex, LightDMService.userRoles.SessionRole);
145 onResponded: root.responded(response)
142 onResponded: root.responded(response)
146 onSelected: {
143 onSelected: {
147 root.selected(index)
144 root.selected(index)
148− loginList.selectedUserIndex = index;
145+ currentSession = LightDMService.users.data(index, LightDMService.userRoles.SessionRole);
149 }
146 }
150 onSessionChooserButtonClicked: parent.state = "SessionsList"
147 onSessionChooserButtonClicked: parent.state = "SessionsList"
151
148
tests/mocks/liblightdm/MockController.cpp+24
@@ -124,6 +124,30 @@ void MockController::setUserMode(const QString &userMode)
124 }
124 }
125}
125}
126
126
127+QString MockController::sessionName() const
128+{
129+ return QString("INVALID - Please read directly from the UserModel");
130+}
131+
132+void MockController::setSessionName(const QString &sessionName)
133+{
134+ // Let the user model deal with this
135+ Q_EMIT sessionNameChanged(sessionName, m_currentUsername);
136+}
137+
138+QString MockController::currentUsername() const
139+{
140+ return m_currentUsername;
141+}
142+
143+void MockController::setCurrentUsername(const QString &username)
144+{
145+ if (m_currentUsername != username) {
146+ m_currentUsername = username;
147+ Q_EMIT currentUsernameChanged();
148+ }
149+}
150+
127QString MockController::sessionMode() const
151QString MockController::sessionMode() const
128{
152{
129 return m_sessionMode;
153 return m_sessionMode;
tests/mocks/liblightdm/MockController.h+15
@@ -36,6 +36,11 @@ class Q_DECL_EXPORT MockController : public QObject
36 // single, none, full
36 // single, none, full
37 Q_PROPERTY(QString sessionMode READ sessionMode WRITE setSessionMode NOTIFY sessionModeChanged)
37 Q_PROPERTY(QString sessionMode READ sessionMode WRITE setSessionMode NOTIFY sessionModeChanged)
38
38
39+ // This would be best as a Q_INVOKABLE, but using a property allows for
40+ // keeping the mock cleaner
41+ Q_PROPERTY(QString sessionName READ sessionName WRITE setSessionName NOTIFY sessionNameChanged)
42+ Q_PROPERTY(QString currentUsername READ currentUsername WRITE setCurrentUsername NOTIFY currentUsernameChanged)
43+
39 Q_PROPERTY(int numAvailableSessions READ numFullSessions CONSTANT)
44 Q_PROPERTY(int numAvailableSessions READ numFullSessions CONSTANT)
40 Q_PROPERTY(int numSessions READ numSessions WRITE setNumSessions NOTIFY numSessionsChanged)
45 Q_PROPERTY(int numSessions READ numSessions WRITE setNumSessions NOTIFY numSessionsChanged)
41
46
@@ -60,6 +65,12 @@ public:
60 QString sessionMode() const;
65 QString sessionMode() const;
61 void setSessionMode(const QString &sessionMode);
66 void setSessionMode(const QString &sessionMode);
62
67
68+ QString sessionName() const;
69+ void setSessionName(const QString &userIndex);
70+
71+ QString currentUsername() const;
72+ void setCurrentUsername(const QString &username);
73+
63 class SessionItem
74 class SessionItem
64 {
75 {
65 public:
76 public:
@@ -73,16 +84,20 @@ public:
73 void setNumSessions(int numSessions);
84 void setNumSessions(int numSessions);
74
85
75Q_SIGNALS:
86Q_SIGNALS:
87+ void currentUsernameChanged();
76 void selectUserHintChanged();
88 void selectUserHintChanged();
77 void selectGuestHintChanged();
89 void selectGuestHintChanged();
78 void hasGuestAccountHintChanged();
90 void hasGuestAccountHintChanged();
79 void userModeChanged();
91 void userModeChanged();
80 void sessionModeChanged();
92 void sessionModeChanged();
81 void numSessionsChanged();
93 void numSessionsChanged();
94+ void sessionNameChanged(const QString &sessionName, const QString &username);
82
95
83private:
96private:
84 explicit MockController(QObject* parent=0);
97 explicit MockController(QObject* parent=0);
85
98
99+ QString m_currentUsername;
100+ QString m_sessionName;
86 QString m_selectUserHint;
101 QString m_selectUserHint;
87 bool m_selectGuestHint;
102 bool m_selectGuestHint;
88 bool m_hasGuestAccountHint;
103 bool m_hasGuestAccountHint;
tests/mocks/liblightdm/MockUsersModel.cpp+37−14
@@ -69,6 +69,8 @@ UsersModel::UsersModel(QObject *parent)
69 this, &UsersModel::resetEntries);
69 this, &UsersModel::resetEntries);
70 connect(MockController::instance(), &MockController::userModeChanged,
70 connect(MockController::instance(), &MockController::userModeChanged,
71 this, &UsersModel::resetEntries);
71 this, &UsersModel::resetEntries);
72+ connect(MockController::instance(), &MockController::sessionNameChanged,
73+ this, &UsersModel::setCurrentSessionName);
72 resetEntries();
74 resetEntries();
73}
75}
74
76
@@ -77,6 +79,22 @@ UsersModel::~UsersModel()
77 delete d_ptr;
79 delete d_ptr;
78}
80}
79
81
82+void UsersModel::setCurrentSessionName(const QString &sessionName, const QString &username)
83+{
84+ Q_D(UsersModel);
85+
86+ int usersIndex = 0;
87+ for (auto &entry : d->entries) {
88+ if (username == entry.username) {
89+ entry.session = sessionName;
90+ break;
91+ }
92+ usersIndex++;
93+ }
94+
95+ dataChanged(index(usersIndex, 0), index(usersIndex, 0), QVector<int>(SessionRole));
96+}
97+
80int UsersModel::rowCount(const QModelIndex &parent) const
98int UsersModel::rowCount(const QModelIndex &parent) const
81{
99{
82 Q_D(const UsersModel);
100 Q_D(const UsersModel);
@@ -140,28 +158,33 @@ void UsersModel::resetEntries()
140 } else if (userMode == "single-pin") {
158 } else if (userMode == "single-pin") {
141 d->entries = {{"has-pin", "Has PIN", "", 0, false, false, "ubuntu", 0}};
159 d->entries = {{"has-pin", "Has PIN", "", 0, false, false, "ubuntu", 0}};
142 } else if (userMode == "full") {
160 } else if (userMode == "full") {
161+ /*
162+ * Since the real model sorts these entries alphabetically, the model indices
163+ * don't line up correctly. The easiest way to fix this is to ensure that this
164+ * list of entries REMAINS IN ALPHABETICAL ORDER at all times.
165+ */
143 d->entries = {
166 d->entries = {
167+ { "active", "Active Account", 0, 0, true, false, "ubuntu", 0 },
168+ { "auth-error", "Auth Error", 0, 0, false, false, "ubuntu", 0 },
169+ { "black-background", "Black Background", "#000000", 0, false, false, "ubuntu", 0 },
170+ { "color-background", "Color Background", "#E95420", 0, false, false, "ubuntu", 0 },
171+ { "different-prompt", "Different Prompt", 0, 0, false, false, "ubuntu", 0 },
172+ { "empty-name", "", 0, 0, false, false, "ubuntu", 0 },
144 { "has-password", "Has Password", 0, 0, false, false, "ubuntu", 0 },
173 { "has-password", "Has Password", 0, 0, false, false, "ubuntu", 0 },
145 { "has-pin", "Has PIN", 0, 0, false, false, "ubuntu", 0 },
174 { "has-pin", "Has PIN", 0, 0, false, false, "ubuntu", 0 },
146− { "different-prompt", "Different Prompt", 0, 0, false, false, "ubuntu", 0 },
147− { "no-password", "No Password", 0, 0, false, false, "ubuntu", 0 },
148− { "auth-error", "Auth Error", 0, 0, false, false, "ubuntu", 0 },
149− { "two-factor", "Two Factor", 0, 0, false, false, "ubuntu", 0 },
150− { "info-prompt", "Info Prompt", 0, 0, false, false, "ubuntu", 0 },
151 { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, "ubuntu", 0 },
175 { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, "ubuntu", 0 },
176+ { "info-prompt", "Info Prompt", 0, 0, false, false, "ubuntu", 0 },
152 { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, "ubuntu", 0 },
177 { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, "ubuntu", 0 },
153− { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, "ubuntu", 0 },
154− { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, "ubuntu", 0 },
155 { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, "ubuntu", 0 },
178 { "long-name", "Long name (far far too long to fit, seriously this would never fit on the screen, you will never see this part of the name)", 0, 0, false, false, "ubuntu", 0 },
156− { "color-background", "Color Background", "#E95420", 0, false, false, "ubuntu", 0 },
179+ { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, "ubuntu", 0 },
157− // white and black are a bit redundant, but useful for manually testing if UI is still readable
158− { "white-background", "White Background", "#ffffff", 0, false, false, "ubuntu", 0 },
159− { "black-background", "Black Background", "#000000", 0, false, false, "ubuntu", 0 },
160 { "no-background", "No Background", "", 0, false, false, "ubuntu", 0 },
180 { "no-background", "No Background", "", 0, false, false, "ubuntu", 0 },
161− { "unicode", "가나다라마", 0, 0, false, false, "ubuntu", 0 },
181+ { "no-password", "No Password", 0, 0, false, false, "ubuntu", 0 },
162 { "no-response", "No Response", 0, 0, false, false, "ubuntu", 0 },
182 { "no-response", "No Response", 0, 0, false, false, "ubuntu", 0 },
163− { "empty-name", "", 0, 0, false, false, "ubuntu", 0 },
183+ { "two-factor", "Two Factor", 0, 0, false, false, "ubuntu", 0 },
164− { "active", "Active Account", 0, 0, true, false, "ubuntu", 0 },
184+ { "unicode", "가나다라마", 0, 0, false, false, "ubuntu", 0 },
185+ // white and black are a bit redundant, but useful for manually testing if UI is still readable
186+ { "white-background", "White Background", "#ffffff", 0, false, false, "ubuntu", 0 },
187+ { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, "ubuntu", 0 }
165 };
188 };
166 }
189 }
167
190
tests/mocks/liblightdm/MockUsersModel.h+2
@@ -48,6 +48,8 @@ public:
48 int rowCount(const QModelIndex &parent) const override;
48 int rowCount(const QModelIndex &parent) const override;
49 QVariant data(const QModelIndex &index, int role) const override;
49 QVariant data(const QModelIndex &index, int role) const override;
50
50
51+ void setCurrentSessionName(const QString &sessionName, const QString &username);
52+
51private Q_SLOTS:
53private Q_SLOTS:
52 void resetEntries();
54 void resetEntries();
53
55
tests/qmltests/Greeter/tst_WideView.qml+31
@@ -411,6 +411,37 @@ StyledItem {
411 waitForRendering(view);
411 waitForRendering(view);
412 }
412 }
413
413
414+ function test_changingSessionSticksToUser() {
415+ LightDMController.sessionMode = "full";
416+
417+ var loginList = findChild(view, "loginList");
418+ var fakeSession1 = "ASessionWillNeverBeCalledThis";
419+ var fakeSession2 = "ASessionWillAlsoNeverBeCalledThis";
420+
421+ // For this test to work, a user has to be selected and the
422+ // mock must be made aware of that user
423+ selectUser("has-password")
424+ LightDMController.currentUsername = "has-password"
425+ compare(LightDM.Sessions.count > 1, true);
426+ compare(loginList.currentSession != fakeSession1, true);
427+ LightDMController.sessionName = fakeSession1;
428+
429+ selectUser("has-pin")
430+ LightDMController.currentUsername = "has-pin"
431+ compare(loginList.currentSession != fakeSession2, true);
432+ LightDMController.sessionName = fakeSession2;
433+
434+ selectUser("has-password")
435+ tryCompare(loginList, "currentSession", fakeSession1);
436+
437+ selectUser("has-pin")
438+ tryCompare(loginList, "currentSession", fakeSession2);
439+
440+ // Force a model reset
441+ LightDMController.userMode = "single";
442+ LightDMController.userMode = "full";
443+ }
444+
414 function test_tease_data() {
445 function test_tease_data() {
415 return [
446 return [
416 {tag: "locked", x: 0, offset: 0, count: 0, locked: true},
447 {tag: "locked", x: 0, offset: 0, count: 0, locked: true},