Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clickable.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ clickable_minimum_required: 8.0.0
builder: cmake
kill: qmlscene
skip_review: true
test: qmltestrunner -input tests/qml
test: qmltestrunner -input tests/qml -import tests/qml
dependencies_target:
- libatomic1
dependencies_host:
Expand Down
9 changes: 9 additions & 0 deletions tests/qml/Pparent/Notifications/NotificationHelper.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import QtQuick 2.7

Item {
property string push_app_id: ""
property int count: 0
function updateCount(c) {
count = c;
}
}
2 changes: 2 additions & 0 deletions tests/qml/Pparent/Notifications/qmldir
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module Pparent.Notifications
NotificationHelper 1.0 NotificationHelper.qml
9 changes: 9 additions & 0 deletions tests/qml/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,20 @@ tests/
│ │ ├── tst_logger.qml # Test suite for logger levels, formatting, and PII sanitization
│ │ ├── tst_timer_service.qml # Test suite for timer service state transitions and duration
│ │ └── tst_utils.qml # Test suite for date, time, duration, and URL utilities
│ ├── tst_accountselectordialog.qml # Test suite for AccountSelectorDialog picker and account switch
│ ├── tst_colorpicker.qml # Test suite for ColorPicker palette and custom color
│ ├── tst_contentpickerdialog.qml # Test suite for ContentPickerDialog single/multi selection
│ ├── tst_assigneefiltermenu.qml # Test suite for AssigneeFilterMenu selector component
│ ├── tst_customdatepicker.qml # Test suite for CustomDatePicker picker component
│ ├── tst_globaltimerwidget.qml # Test suite for GlobalTimerWidget system component
│ ├── tst_infobar.qml # Test suite for InfoBar feedback component
│ ├── tst_loadingindicator.qml # Test suite for LoadingIndicator running state and visibility
│ ├── tst_loadmorefooter.qml # Test suite for LoadMoreFooter loading state and retry trigger
│ ├── tst_notificationbell.qml # Test suite for NotificationBell unread counter badge and navigation
│ ├── tst_notificationpopup.qml # Test suite for NotificationPopup message, dismiss, and timeout
│ ├── tst_outlinedtextfield.qml # Test suite for OutlinedTextField text input component
│ ├── tst_savediscarddialog.qml # Test suite for SaveDiscardDialog save, discard, and cancel signals
│ ├── tst_timepickerpopup.qml # Test suite for TimePickerPopup time selection and confirmation
│ ├── tst_tsbutton.qml # Test suite for TSButton action button component
│ ├── tst_tsiconbutton.qml # Test suite for TSIconButton circular icon button component
│ ├── tst_tslabel.qml # Test suite for TSLabel styled text component
Expand Down
6 changes: 3 additions & 3 deletions tests/qml/models/tst_dbinit.qml
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ Item {

var db = Sql.LocalStorage.openDatabaseSync(DBCommon.NAME, DBCommon.VERSION, DBCommon.DISPLAY_NAME, DBCommon.SIZE);
db.transaction(function(tx) {
var resInterval = tx.executeSql("SELECT value FROM app_settings WHERE key = 'auto_sync_interval'");
var resInterval = tx.executeSql("SELECT value FROM app_settings WHERE key = 'sync_interval_minutes'");
verify(resInterval.rows.length > 0);
compare(resInterval.rows.item(0).value, "15");

var resEnabled = tx.executeSql("SELECT value FROM app_settings WHERE key = 'auto_sync_enabled'");
var resEnabled = tx.executeSql("SELECT value FROM app_settings WHERE key = 'autosync_enabled'");
verify(resEnabled.rows.length > 0);
compare(resEnabled.rows.item(0).value, "false");
compare(resEnabled.rows.item(0).value, "true");
});
}

Expand Down
24 changes: 13 additions & 11 deletions tests/qml/models/tst_draft_manager.qml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Item {
verify(DraftManager.valuesAreEqual(null, null));
verify(DraftManager.valuesAreEqual(undefined, undefined));
verify(DraftManager.valuesAreEqual(null, undefined));
verify(DraftManager.valuesAreEqual(null, ""));
verify(DraftManager.valuesAreEqual(undefined, ""));
verify(!DraftManager.valuesAreEqual(null, ""));
verify(!DraftManager.valuesAreEqual(undefined, ""));
}

function test_valuesAreEqualArrays() {
Expand Down Expand Up @@ -109,14 +109,15 @@ Item {
pageIdentifier: "task_edit_page"
};

var loaded = DraftManager.loadDraft(loadParams);
verify(loaded !== null);
compare(loaded.draft_type, "task");
compare(loaded.record_id, 501);
var loadRes = DraftManager.loadDraft(loadParams);
verify(loadRes.success);
verify(loadRes.draft !== null);
compare(loadRes.draft.draftType, "task");
compare(loadRes.draft.recordId, 501);

var parsedData = typeof loaded.draft_data === "string" ? JSON.parse(loaded.draft_data) : loaded.draft_data;
compare(parsedData.name, "My Draft Task");
compare(parsedData.priority, 3);
var formData = loadRes.draft.formData;
compare(formData.name, "My Draft Task");
compare(formData.priority, 3);
}

function test_deleteDraftById() {
Expand All @@ -133,14 +134,15 @@ Item {
var draftId = saveRes.draftId;

var deleteRes = DraftManager.deleteDraft(draftId);
verify(deleteRes);
verify(deleteRes.success);

var loaded = DraftManager.loadDraft({
draftType: "timesheet",
recordId: 601,
accountId: 0
});
compare(loaded, null);
compare(loaded.success, false);
compare(loaded.draft, null);
}

function test_deleteDraftsByParams() {
Expand Down
135 changes: 135 additions & 0 deletions tests/qml/tst_accountselectordialog.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import QtQuick 2.7
import QtTest 1.0
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import "../../qml/components/dialogs"
import "../../models/dbinit.js" as DbInit

MainView {
id: testRoot
width: units.gu(40)
height: units.gu(70)

AccountSelectorDialog {
id: testAccountSelector
}

SignalSpy {
id: acceptedSpy
target: testAccountSelector
signalName: "accepted"
}

SignalSpy {
id: canceledSpy
target: testAccountSelector
signalName: "canceled"
}

TestCase {
name: "AccountSelectorDialogTests"
when: windowShown

function initTestCase() {
DbInit.initializeDatabase();
}

function init() {
testAccountSelector.titleText = "Select Account";
testAccountSelector.restrictToLocalOnly = false;
testAccountSelector.selectedAccountId = -1;
testAccountSelector.selectedAccountName = "";
testAccountSelector.lastRemoteAccountId = -1;
acceptedSpy.clear();
canceledSpy.clear();
}

function cleanup() {
acceptedSpy.clear();
canceledSpy.clear();
}

function test_initialProperties() {
compare(testAccountSelector.titleText, "Select Account");
compare(testAccountSelector.restrictToLocalOnly, false);
compare(acceptedSpy.count, 0);
compare(canceledSpy.count, 0);
}

function test_customTitleText() {
testAccountSelector.titleText = "Switch Active Account";
compare(testAccountSelector.titleText, "Switch Active Account");
}

function test_restrictToLocalOnlyToggle() {
testAccountSelector.restrictToLocalOnly = true;
compare(testAccountSelector.restrictToLocalOnly, true);

testAccountSelector.restrictToLocalOnly = false;
compare(testAccountSelector.restrictToLocalOnly, false);
}

function test_accountListPickAndSignalEmission() {
var targetId = 2;
var targetName = "Acme Corp Odoo";

testAccountSelector.selectedAccountId = targetId;
testAccountSelector.selectedAccountName = targetName;
testAccountSelector.accepted(targetId, targetName);

compare(testAccountSelector.selectedAccountId, targetId);
compare(testAccountSelector.selectedAccountName, targetName);
compare(acceptedSpy.count, 1);
compare(acceptedSpy.signalArguments[0][0], targetId);
compare(acceptedSpy.signalArguments[0][1], targetName);
}

function test_switchSignalMultipleAccounts() {
testAccountSelector.accepted(0, "Local Account");
testAccountSelector.accepted(1, "Dev Server");
testAccountSelector.accepted(-1, "All Accounts");

compare(acceptedSpy.count, 3);
compare(acceptedSpy.signalArguments[0][0], 0);
compare(acceptedSpy.signalArguments[0][1], "Local Account");
compare(acceptedSpy.signalArguments[1][0], 1);
compare(acceptedSpy.signalArguments[1][1], "Dev Server");
compare(acceptedSpy.signalArguments[2][0], -1);
compare(acceptedSpy.signalArguments[2][1], "All Accounts");
}

function test_canceledSignalEmission() {
compare(canceledSpy.count, 0);
testAccountSelector.canceled();
compare(canceledSpy.count, 1);
compare(acceptedSpy.count, 0);
}

function test_toggleLocalModeSwitchesToLocalAndEmitsSignal() {
testAccountSelector.selectedAccountId = 3;
testAccountSelector.selectedAccountName = "Remote Server";

var result = testAccountSelector.toggleLocalMode(true);
verify(result);
compare(testAccountSelector.selectedAccountId, 0);
compare(acceptedSpy.count, 1);
compare(acceptedSpy.signalArguments[0][0], 0);
}

function test_toggleLocalModeWhenAlreadyLocalDoesNotReEmit() {
testAccountSelector.selectedAccountId = 0;
testAccountSelector.selectedAccountName = "Local";
acceptedSpy.clear();

var result = testAccountSelector.toggleLocalMode(true);
verify(result);
compare(acceptedSpy.count, 0);
}

function test_openWithInitialAccountId() {
testAccountSelector.open(5);
// Verify open() sets requested initial id or opens cleanly
verify(testAccountSelector !== null);
}
}
}
130 changes: 130 additions & 0 deletions tests/qml/tst_colorpicker.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import QtQuick 2.7
import QtTest 1.0
import Lomiri.Components 1.3
import Lomiri.Components.Popups 1.3
import "../../qml/components/dialogs"

MainView {
id: testRoot
width: units.gu(40)
height: units.gu(70)

ColorPicker {
id: testColorPicker
}

SignalSpy {
id: colorPickedSpy
target: testColorPicker
signalName: "colorPicked"
}

TestCase {
name: "ColorPickerTests"
when: windowShown

readonly property var defaultPalette: [
"#FFFFFF", "#EB6E67", "#F39C5A", "#F6C342",
"#6CC1E1", "#854D76", "#ED8888", "#2C8397",
"#49597C", "#DE3F7C", "#45C486", "#9B6CC3"
]

function init() {
testColorPicker.selectedColorIndex = -1;
testColorPicker.selectedColor = "";
testColorPicker.odooColors = defaultPalette;
colorPickedSpy.clear();
}

function cleanup() {
testColorPicker.selectedColorIndex = -1;
testColorPicker.selectedColor = "";
testColorPicker.odooColors = defaultPalette;
colorPickedSpy.clear();
}

function test_initialProperties() {
compare(testColorPicker.selectedColorIndex, -1);
compare(testColorPicker.selectedColor, "");
compare(testColorPicker.odooColors.length, 12);
compare(colorPickedSpy.count, 0);
}

function test_getColorByIndexValid() {
compare(testColorPicker.getColorByIndex(0), "#FFFFFF");
compare(testColorPicker.getColorByIndex(1), "#EB6E67");
compare(testColorPicker.getColorByIndex(2), "#F39C5A");
compare(testColorPicker.getColorByIndex(3), "#F6C342");
compare(testColorPicker.getColorByIndex(4), "#6CC1E1");
compare(testColorPicker.getColorByIndex(10), "#45C486");
compare(testColorPicker.getColorByIndex(11), "#9B6CC3");
}

function test_getColorByIndexInvalidReturnsFallback() {
compare(testColorPicker.getColorByIndex(-1), "#FFFFFF");
compare(testColorPicker.getColorByIndex(-10), "#FFFFFF");
compare(testColorPicker.getColorByIndex(12), "#FFFFFF");
compare(testColorPicker.getColorByIndex(100), "#FFFFFF");
}

function test_palettePickUpdatesStateAndEmitsSignal() {
var targetIndex = 4;
var targetColor = testColorPicker.getColorByIndex(targetIndex);

testColorPicker.selectedColorIndex = targetIndex;
testColorPicker.selectedColor = targetColor;
testColorPicker.colorPicked(targetIndex, targetColor);

compare(testColorPicker.selectedColorIndex, 4);
compare(testColorPicker.selectedColor, "#6CC1E1");
compare(colorPickedSpy.count, 1);
compare(colorPickedSpy.signalArguments[0][0], 4);
compare(colorPickedSpy.signalArguments[0][1], "#6CC1E1");
}

function test_customColorValueAssignment() {
var customHex = "#AABBCC";
testColorPicker.selectedColorIndex = 99;
testColorPicker.selectedColor = customHex;

compare(testColorPicker.selectedColorIndex, 99);
compare(testColorPicker.selectedColor, "#AABBCC");

testColorPicker.colorPicked(99, customHex);
compare(colorPickedSpy.count, 1);
compare(colorPickedSpy.signalArguments[0][0], 99);
compare(colorPickedSpy.signalArguments[0][1], "#AABBCC");
}

function test_customPaletteOverride() {
var customPalette = ["#111111", "#222222", "#333333"];
testColorPicker.odooColors = customPalette;

compare(testColorPicker.odooColors.length, 3);
compare(testColorPicker.getColorByIndex(0), "#111111");
compare(testColorPicker.getColorByIndex(1), "#222222");
compare(testColorPicker.getColorByIndex(2), "#333333");
compare(testColorPicker.getColorByIndex(3), "#FFFFFF");
}

function test_multipleSequentialColorPicks() {
testColorPicker.colorPicked(1, "#EB6E67");
testColorPicker.colorPicked(5, "#854D76");
testColorPicker.colorPicked(9, "#DE3F7C");

compare(colorPickedSpy.count, 3);
compare(colorPickedSpy.signalArguments[0][0], 1);
compare(colorPickedSpy.signalArguments[0][1], "#EB6E67");
compare(colorPickedSpy.signalArguments[1][0], 5);
compare(colorPickedSpy.signalArguments[1][1], "#854D76");
compare(colorPickedSpy.signalArguments[2][0], 9);
compare(colorPickedSpy.signalArguments[2][1], "#DE3F7C");
}

function test_openMethodExecution() {
testColorPicker.open();
testColorPicker.open(2);
verify(testColorPicker !== null);
}
}
}
Loading
Loading