on xenial help sign in
Check purchase state to determine if purchase was cancelled and hide progress. Fixes: 1362622, 1370651
b93892fRodney Dawes
plugins/Ubuntu/Payments/Payments.cpp+21−1
@@ -41,13 +41,23 @@ static void observer(PayPackage* /* package */, const char* itemid, PayPackageIt
41 case PAY_PACKAGE_ITEM_STATUS_PURCHASED:
41 case PAY_PACKAGE_ITEM_STATUS_PURCHASED:
42 Q_EMIT self->purchaseCompleted();
42 Q_EMIT self->purchaseCompleted();
43 break;
43 break;
44+ case PAY_PACKAGE_ITEM_STATUS_PURCHASING:
45+ self->setPurchasing(true);
46+ break;
47+ case PAY_PACKAGE_ITEM_STATUS_NOT_PURCHASED:
48+ if (self->purchasing()) {
49+ self->setPurchasing(false);
50+ Q_EMIT self->purchaseCancelled();
51+ }
52+ break;
44 default:
53 default:
45 break;
54 break;
46 }
55 }
47}
56}
48
57
49Payments::Payments(QObject *parent)
58Payments::Payments(QObject *parent)
50− : QObject(parent)
59+ : QObject(parent),
60+ m_purchasing(false)
51{
61{
52 m_package = pay_package_new("click-scope");
62 m_package = pay_package_new("click-scope");
53 pay_package_item_observer_install(m_package, observer, this);
63 pay_package_item_observer_install(m_package, observer, this);
@@ -80,6 +90,11 @@ QString Payments::formattedPrice() const
80 return locale.toCurrencyString(m_price, m_currency);
90 return locale.toCurrencyString(m_price, m_currency);
81}
91}
82
92
93+bool Payments::purchasing() const
94+{
95+ return m_purchasing;
96+}
97+
83void Payments::setCurrency(const QString &currency)
98void Payments::setCurrency(const QString &currency)
84{
99{
85 if(m_currency != currency) {
100 if(m_currency != currency) {
@@ -112,6 +127,11 @@ void Payments::setStoreItemId(const QString &store_item_id)
112 pay_package_item_start_verification(m_package, m_store_item_id.toLocal8Bit().data());
127 pay_package_item_start_verification(m_package, m_store_item_id.toLocal8Bit().data());
113}
128}
114
129
130+void Payments::setPurchasing(bool is_purchasing)
131+{
132+ m_purchasing = is_purchasing;
133+}
134+
115void Payments::start()
135void Payments::start()
116{
136{
117 pay_package_item_start_purchase(m_package, m_store_item_id.toLocal8Bit().data());
137 pay_package_item_start_purchase(m_package, m_store_item_id.toLocal8Bit().data());
plugins/Ubuntu/Payments/Payments.h+4
@@ -39,10 +39,12 @@ public:
39 double price() const;
39 double price() const;
40 QString storeItemId() const;
40 QString storeItemId() const;
41 QString formattedPrice() const;
41 QString formattedPrice() const;
42+ bool purchasing() const;
42
43
43 void setCurrency(const QString& currency);
44 void setCurrency(const QString& currency);
44 void setPrice(const double price);
45 void setPrice(const double price);
45 void setStoreItemId(const QString& store_item_id);
46 void setStoreItemId(const QString& store_item_id);
47+ void setPurchasing(bool is_purchasing);
46 Q_INVOKABLE void start();
48 Q_INVOKABLE void start();
47
49
48Q_SIGNALS:
50Q_SIGNALS:
@@ -53,11 +55,13 @@ Q_SIGNALS:
53
55
54 void purchaseError(const QString &error);
56 void purchaseError(const QString &error);
55 void purchaseCompleted();
57 void purchaseCompleted();
58+ void purchaseCancelled();
56
59
57private:
60private:
58 QString m_currency;
61 QString m_currency;
59 double m_price;
62 double m_price;
60 QString m_store_item_id;
63 QString m_store_item_id;
64+ bool m_purchasing;
61
65
62 PayPackage *m_package;
66 PayPackage *m_package;
63};
67};
qml/Dash/Previews/PreviewPayments.qml+6
@@ -63,6 +63,12 @@ PreviewWidget {
63 paymentButton.opacity = 1;
63 paymentButton.opacity = 1;
64 root.triggered(widgetId, "purchaseError", source);
64 root.triggered(widgetId, "purchaseError", source);
65 }
65 }
66+ onPurchaseCancelled: {
67+ paymentButton.opacity = 1;
68+ // DO NOT emit the signal right now, as it causes a new
69+ // preview to be requested, when that is not what we want.
70+ //root.triggered(widgetId, "purchaseCancelled", source);
71+ }
66 }
72 }
67 }
73 }
68
74
tests/mocks/Ubuntu/Payments/MockPayments.cpp+3−1
@@ -84,7 +84,9 @@ void MockPayments::start()
84
84
85void MockPayments::process()
85void MockPayments::process()
86{
86{
87− if (m_store_item_id == "com.example.invalid") {
87+ if (m_store_item_id == "com.example.cancel") {
88+ Q_EMIT purchaseCancelled();
89+ } else if (m_store_item_id == "com.example.invalid") {
88 Q_EMIT purchaseError("Purchase failed.");
90 Q_EMIT purchaseError("Purchase failed.");
89 } else {
91 } else {
90 Q_EMIT purchaseCompleted();
92 Q_EMIT purchaseCompleted();
tests/mocks/Ubuntu/Payments/MockPayments.h+1
@@ -51,6 +51,7 @@ Q_SIGNALS:
51
51
52 void purchaseError(const QString &error);
52 void purchaseError(const QString &error);
53 void purchaseCompleted();
53 void purchaseCompleted();
54+ void purchaseCancelled();
54
55
55private:
56private:
56 QString m_currency;
57 QString m_currency;
tests/qmltests/Dash/Previews/tst_PreviewPayments.qml+39
@@ -33,6 +33,10 @@ Rectangle {
33 "source": { "price" : 0.99, "currency": "USD", "store_item_id": "com.example.invalid" }
33 "source": { "price" : 0.99, "currency": "USD", "store_item_id": "com.example.invalid" }
34 }
34 }
35
35
36+ property var jsonPurchaseCancel: {
37+ "source": { "price" : 0.99, "currency": "USD", "store_item_id": "com.example.cancel" }
38+ }
39+
36 SignalSpy {
40 SignalSpy {
37 id: spy
41 id: spy
38 target: previewPayments
42 target: previewPayments
@@ -160,5 +164,40 @@ Rectangle {
160 compare(args[1], "purchaseError");
164 compare(args[1], "purchaseError");
161 compare(args[2], jsonPurchaseError["source"]);
165 compare(args[2], jsonPurchaseError["source"]);
162 }
166 }
167+
168+ function test_purchase_cancelled() {
169+ // The mock Payments triggers cancellation when com.example.cancel
170+ // is passed to it as store_item_id. Exercise it here
171+ previewPayments.widgetData = jsonPurchaseCancel;
172+
173+ var button = findChild(previewPayments, "paymentButton");
174+ var progress = findChild(previewPayments, "loadingBar");
175+ verify(button, "Button not found.");
176+ verify(progress, "Progress not found.");
177+
178+ mouseClick(button, button.width / 2, button.height / 2);
179+
180+ tryCompare(progress, "visible", true);
181+ tryCompare(progress, "opacity", 1);
182+ tryCompare(button, "visible", false);
183+ tryCompare(button, "opacity", 0);
184+
185+ paymentClient.process();
186+
187+ // Signal is not used at the moment, to avoid preview refresh.
188+ /*
189+ *spy.wait();
190+ *
191+ * var args = spy.signalArguments[0];
192+ * compare(args[0], "previewPayments");
193+ * compare(args[1], "purchaseCancelled");
194+ * compare(args[2], jsonPurchaseCancel["source"]);
195+ */
196+
197+ tryCompare(progress, "visible", false);
198+ tryCompare(progress, "opacity", 0);
199+ tryCompare(button, "visible", true);
200+ tryCompare(button, "opacity", 1);
201+ }
163 }
202 }
164}
203}