Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85805518
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/contents/ui/KazvIOMenu.qml b/src/contents/ui/KazvIOMenu.qml
index b3fab17..c9ba0d9 100644
--- a/src/contents/ui/KazvIOMenu.qml
+++ b/src/contents/ui/KazvIOMenu.qml
@@ -1,142 +1,150 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2022-2023 nannanko <nannanko@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.13 as Kirigami
import moe.kazv.mxc.kazv 0.0 as MK
ColumnLayout {
id: kazvIOProgressBar
required property var kazvIOJob
required property var jobId
required property bool isUpload
visible: kazvIOJob ? true : false
onKazvIOJobChanged: {
if (kazvIOJob == null) {
progressBarLayout.visible = true
resultMsgLayout.visible = false
return
}
if (kazvIOJob.isResulted()) {
jobSlots.onResult(kazvIOJob.error())
return
}
if (kazvIOJob.isSuspended()) {
pauseAction.suspended = true
}
}
Connections {
id: jobSlots
target: kazvIOJob
function onResult(ec) {
progressBarLayout.visible = false
resultMsgLayout.visible = true
if (ec == MK.KazvIOBaseJob.NoError) {
if (isUpload) {
return
}
resultMsg.text = l10n.get('kazv-io-download-success-prompt')
return
}
let resultL10nId = isUpload ? 'kazv-io-upload-failure-prompt' : 'kazv-io-download-failure-prompt'
let detailL10nId = new Map([
[MK.KazvIOBaseJob.UserCancel, 'kazv-io-failure-detail-user-cancel'],
[MK.KazvIOBaseJob.OpenFileError, 'kazv-io-failure-detail-open-file-error'],
[MK.KazvIOBaseJob.WriteFileError, 'kazv-io-failure-detail-write-file-error'],
[MK.KazvIOBaseJob.KIOError, 'kazv-io-failure-detail-network-error'],
[MK.KazvIOBaseJob.HashError, 'kazv-io-failure-detail-hash-error'],
[MK.KazvIOBaseJob.ResponseError, 'kazv-io-failure-detail-response-error'],
[MK.KazvIOBaseJob.KazvError, 'kazv-io-failure-detail-kazv-error']
])
resultMsg.text = l10n.get(resultL10nId, {detail: l10n.get(detailL10nId.get(ec))})
}
}
Label {
+ objectName: 'fileNamePrompt'
property string l10nId: isUpload ? 'kazv-io-uploading-prompt' : 'kazv-io-downloading-prompt'
text: kazvIOJob ? l10n.get(l10nId, {fileName: kazvIOJob.fileName()}) : ""
wrapMode: Text.Wrap
Layout.preferredWidth: parent.width
}
RowLayout {
id: progressBarLayout
+ objectName: 'progressLayout'
visible: true
Layout.preferredWidth: parent.width
ProgressBar {
id: progressBar
+ objectName: 'progressBar'
Layout.fillWidth: true
value: kazvIOJob ? kazvIOJob.progress : 0
}
Kirigami.Action {
id: pauseAction
text: suspended ? l10n.get("kazv-io-resume") : l10n.get("kazv-io-pause")
icon.name: suspended ? "media-playback-start" : "media-playback-pause"
property var suspended: false
onTriggered: {
if (pauseAction.suspended) {
kazvIOJob.resume()
} else {
kazvIOJob.suspend()
}
suspended = !suspended
}
}
Kirigami.Action {
id: cancelAction
text: l10n.get("kazv-io-cancel")
icon.name: "dialog-cancel"
onTriggered: {
pauseAction.suspended = false
kazvIOJob.cancel()
}
}
RoundButton {
id: pauseBtn
+ objectName: 'pauseBtn'
Accessible.name: pauseAction.suspended ? l10n.get('kazv-io-resume') : l10n.get('kazv-io-pause')
icon.name: pauseAction.suspended ? "media-playback-start" : "media-playback-pause"
onClicked: pauseAction.trigger()
}
RoundButton {
+ objectName: 'cancelBtn'
icon.name: "dialog-cancel"
Accessible.name: l10n.get('kazv-io-cancel')
onClicked: cancelAction.trigger()
}
}
ColumnLayout {
id: resultMsgLayout
+ objectName: 'resultLayout'
visible: false
width: parent.width
Label {
id: resultMsg
+ objectName: 'resultMsg'
wrapMode: Text.Wrap
Layout.preferredWidth: parent.width
}
Button {
+ objectName: 'closeBtn'
text: l10n.get('kazv-io-prompt-close')
onClicked: {
if (isUpload) {
kazvIOManager.deleteUploadJob(jobId, kazvIOJob)
} else {
kazvIOManager.deleteDownloadJob(jobId)
resultMsgLayout.visible = false
progressBarLayout.visible = true
resultMsg.text = null
}
}
}
}
}
diff --git a/src/tests/quick-tests/tst_KazvIOMenu.qml b/src/tests/quick-tests/tst_KazvIOMenu.qml
new file mode 100644
index 0000000..252e441
--- /dev/null
+++ b/src/tests/quick-tests/tst_KazvIOMenu.qml
@@ -0,0 +1,238 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2024 nannanko <nannanko@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQuick
+import QtTest
+
+import '../../contents/ui' as Kazv
+import 'test-helpers' as TestHelpers
+import 'test-helpers.js' as Helpers
+
+import moe.kazv.mxc.kazv 0.0 as MK
+
+Item {
+ id: item
+ width: 800
+ height: 600
+
+ property var mockHelper: TestHelpers.MockHelper {}
+ property var kazvIOManager: QtObject {
+ property var deleteDownloadJob: mockHelper.noop()
+ property var deleteUploadJob: mockHelper.noop()
+ }
+ property var kazvIOJob: QtObject {
+ function isResulted() { return false; }
+ function isSuspended() { return false; }
+ function fileName() { return 'some-file-name'; }
+ property var suspend: mockHelper.noop()
+ property var cancel: mockHelper.noop()
+ property var progress: 0.0
+ signal result(int ec)
+ }
+ property var suspendedJob: QtObject {
+ function isResulted() { return false; }
+ function isSuspended() { return true; }
+ property var resume: mockHelper.noop()
+ }
+ property var resultedJob: QtObject {
+ function isResulted() { return true; }
+ function isSuspended() { return false; }
+ function error() { return MK.KazvIOBaseJob.NoError; }
+ }
+ property var l10n: Helpers.fluentMock
+
+ Kazv.KazvIOMenu {
+ id: progressBar
+ kazvIOJob: null
+ jobId: 'some-job-id'
+ isUpload: false
+ }
+
+ TestCase {
+ id: kazvIOMenuTest
+ name: 'KazvIOMenuTest'
+ when: windowShown
+
+ function init() {
+ progressBar.kazvIOJob = null;
+ progressBar.isUpload = false;
+ }
+
+ function test_progress() {
+ progressBar.kazvIOJob = kazvIOJob;
+ const progress = findChild(progressBar, 'progressBar');
+ compare(progress.value, kazvIOJob.progress);
+ kazvIOJob.progress = Math.random();
+ compare(progress.value, kazvIOJob.progress);
+ }
+
+ function test_progressBarNullJob() {
+ progressBar.kazvIOJob = null;
+ verify(!progressBar.visible);
+ }
+
+ function test_progressBarDownload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = false;
+ verify(progressBar.visible);
+ const prompt = findChild(progressBar, 'fileNamePrompt');
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ verify(prompt.visible);
+ verify(progressLayout.visible);
+ verify(!resultLayout.visible);
+ compare(prompt.text, l10n.get('kazv-io-downloading-prompt', {
+ fileName: kazvIOJob.fileName()}));
+ }
+
+ function test_progressBarUpload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = true;
+ const prompt = findChild(progressBar, 'fileNamePrompt');
+ compare(prompt.text, l10n.get('kazv-io-uploading-prompt', {
+ fileName: kazvIOJob.fileName()}));
+ }
+
+ function test_resume() {
+ progressBar.kazvIOJob = kazvIOJob;
+ const pauseBtn = findChild(progressBar, 'pauseBtn');
+ compare(pauseBtn.icon.name, 'media-playback-pause');
+ mouseClick(pauseBtn);
+ compare(kazvIOJob.suspend.calledTimes(), 1);
+ }
+
+ function test_pause() {
+ progressBar.kazvIOJob = suspendedJob;
+ const pauseBtn = findChild(progressBar, 'pauseBtn');
+ compare(pauseBtn.icon.name, 'media-playback-start');
+ mouseClick(pauseBtn);
+ compare(suspendedJob.resume.calledTimes(), 1);
+ }
+
+ function test_cancel() {
+ progressBar.kazvIOJob = kazvIOJob;
+ const cancelBtn = findChild(progressBar, 'cancelBtn');
+ mouseClick(cancelBtn);
+ compare(kazvIOJob.cancel.calledTimes(), 1);
+ }
+
+ function test_resulted() {
+ progressBar.kazvIOJob = resultedJob;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ }
+
+ /**
+ * ProgressBar is destroyed automatically after a successful upload,
+ * so there is no need to test
+ */
+ function test_resultSuccDownload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = false;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ const resultMsg = findChild(progressBar, 'resultMsg');
+ kazvIOJob.result(MK.KazvIOBaseJob.NoError);
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ compare(resultMsg.text, l10n.get('kazv-io-download-success-prompt'));
+ }
+
+ function test_resultFailDownload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = false;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ const resultMsg = findChild(progressBar, 'resultMsg');
+ kazvIOJob.result(MK.KazvIOBaseJob.UserCancel);
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ const failPromptL10nId = 'kazv-io-download-failure-prompt';
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-user-cancel')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.OpenFileError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-open-file-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.WriteFileError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-write-file-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.KIOError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-network-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.HashError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-hash-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.ResponseError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-response-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.KazvError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-kazv-error')}));
+ }
+
+ function test_resultFailUpload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = true;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ const resultMsg = findChild(progressBar, 'resultMsg');
+ kazvIOJob.result(MK.KazvIOBaseJob.UserCancel);
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ const failPromptL10nId = 'kazv-io-upload-failure-prompt';
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-user-cancel')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.OpenFileError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-open-file-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.WriteFileError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-write-file-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.KIOError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-network-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.HashError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-hash-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.ResponseError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-response-error')}));
+ kazvIOJob.result(MK.KazvIOBaseJob.KazvError);
+ compare(resultMsg.text, l10n.get(failPromptL10nId, {
+ detail: l10n.get('kazv-io-failure-detail-kazv-error')}));
+ }
+
+ function test_closeDownload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = false;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ const closeBtn = findChild(progressBar, 'closeBtn')
+
+ kazvIOJob.result(MK.KazvIOBaseJob.NoError);
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ mouseClick(closeBtn);
+ compare(kazvIOManager.deleteDownloadJob.calledTimes(), 1);
+ }
+
+ function test_closeUpload() {
+ progressBar.kazvIOJob = kazvIOJob;
+ progressBar.isUpload = true;
+ const progressLayout = findChild(progressBar, 'progressLayout');
+ const resultLayout = findChild(progressBar, 'resultLayout');
+ const closeBtn = findChild(progressBar, 'closeBtn')
+
+ kazvIOJob.result(MK.KazvIOBaseJob.NoError);
+ verify(!progressLayout.visible);
+ verify(resultLayout.visible);
+ mouseClick(closeBtn);
+ compare(kazvIOManager.deleteUploadJob.calledTimes(), 1);
+ }
+ }
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Oct 11, 1:25 PM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785819
Default Alt Text
(13 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment