Page MenuHomePhorge

D65.1732319770.diff
No OneTemporary

Size
44 KB
Referenced Files
None
Subscribers
None

D65.1732319770.diff

diff --git a/src/tests/quick-tests/test-helpers.js b/src/tests/quick-tests/test-helpers.js
--- a/src/tests/quick-tests/test-helpers.js
+++ b/src/tests/quick-tests/test-helpers.js
@@ -47,3 +47,49 @@
return false;
}
};
+
+const Mock = {
+ calledTimes() {
+ return this.args.length;
+ },
+ lastArgs() {
+ return this.args[this.args.length - 1];
+ },
+ lastRetVal() {
+ return this.retVals[this.retVals.length - 1];
+ },
+ clear() {
+ this.args = [];
+ this.retVals = [];
+ },
+};
+
+const makeTransform = (t) => {
+ if (t instanceof Function) {
+ return t;
+ } else if (Array.isArray(t)) {
+ return (args) => {
+ return t.reduce((acc, cur, index) => {
+ acc[cur] = args[index];
+ return acc;
+ }, {});
+ };
+ } else {
+ return (args) => args;
+ }
+};
+
+const mockFunction = (f, t) => {
+ const transform = makeTransform(t);
+ function mock() {
+ mock.args.push(transform([...arguments]));
+ const retVal = f.apply(this, arguments);
+ mock.retVals.push(retVal);
+ return retVal;
+ }
+ Object.entries(Mock).forEach(([k, v]) => {
+ mock[k] = v;
+ });
+ mock.clear();
+ return mock;
+};
diff --git a/src/tests/quick-tests/test-helpers/MockHelper.qml b/src/tests/quick-tests/test-helpers/MockHelper.qml
new file mode 100644
--- /dev/null
+++ b/src/tests/quick-tests/test-helpers/MockHelper.qml
@@ -0,0 +1,80 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2024 tusooa <tusooa@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+import QtQuick 2.15
+import '.' as TestHelpers
+import '../test-helpers.js' as Helpers
+
+/**
+ * Helper class for conveniently mocking functions.
+ *
+ * The mocks record the arguments and return values of the functions.
+ *
+ * - `MockHelper.func(f, t)` returns a mock of the function `f`, with
+ * its arguments recorded transformed by `t`.
+ * The transform can be either:
+ * - A function, which means the recorded arguments will be
+ * `t(originalArgs)`.
+ * - An array, which means the recorded arguments will be an
+ * object whose keys are the items of the array and the values are
+ * the recorded arguments.
+ * - For example, if the provided transform is `['foo', 'bar']` and
+ * the mock is called with `(1, 2, 3)`, the recorded arguments
+ * will be `{ foo: 1, bar: 2 }`. (Note that the additional argument
+ * 3 is ignored)
+ * - undefined, which means the arguments will be recorded as-is
+ * (equivalent to providing the identity function).
+ * - `MockHelper.promise(t)` returns a mock of a function returning
+ * a MatrixPromiseMock, with its arguments recorded transformed by `t`.
+ * - `MockHelper.noop(t)` returns a mock of a function doing nothing,
+ * with its arguments recorded transformed by `t`.
+ * - `MockHelper.clearAll()` resets the recorded information of all
+ * mocks *created by this MockHelper*.
+ *
+ * The mocks have the following interface:
+ * - `mock()` calls the function and returns the data.
+ * - `mock.clear()` resets the recorded information (times called,
+ * arguments, return values).
+ * - `mock.calledTimes()` returns the number of times the mock gets called.
+ * - `mock.lastArgs()` returns the arguments of the last call, as an array.
+ * - `mock.args` returns a list of arguments of each call, ordered from the
+ * earliest call to the last call.
+ * - `mock.lastRetVal()` returns the return value of the last call.
+ * - `mock.retVals` returns a list of return values of each call, ordered
+ * from the earliest call to the last call.
+ */
+QtObject {
+ id: mockHelper
+
+ property var promiseComp: Component {
+ TestHelpers.MatrixPromiseMock {}
+ }
+ property var mocks: []
+
+ function clearAll() {
+ mocks.forEach((mock) => {
+ mock.clear();
+ });
+ }
+
+ function func(f, t) {
+ const ret = Helpers.mockFunction(f, t);
+ mocks.push(ret);
+ return ret;
+ }
+
+ function createPromise() {
+ return promiseComp.createObject(mockHelper);
+ }
+
+ function promise(t) {
+ return func(createPromise, t);
+ }
+
+ function noop(t) {
+ return func(() => {}, t);
+ }
+}
diff --git a/src/tests/quick-tests/tst_AddStickerPopup.qml b/src/tests/quick-tests/tst_AddStickerPopup.qml
--- a/src/tests/quick-tests/tst_AddStickerPopup.qml
+++ b/src/tests/quick-tests/tst_AddStickerPopup.qml
@@ -19,25 +19,17 @@
height: 600
property var l10n: Helpers.fluentMock
+ property var mockHelper: TestHelpers.MockHelper {}
property var promiseComp: Component {
TestHelpers.MatrixPromiseMock {}
}
property var matrixSdk: TestHelpers.MatrixSdkMock {
id: matrixSdk
- property var _updateStickerPackCalled: 0
- property var _updateStickerPackLastArg: undefined
- property var _updateStickerPackPromise: undefined
- function updateStickerPack(arg) {
- ++matrixSdk._updateStickerPackCalled;
- matrixSdk._updateStickerPackLastArg = arg;
- matrixSdk._updateStickerPackPromise = promiseComp.createObject(matrixSdk);
- return matrixSdk._updateStickerPackPromise;
- }
+ property var updateStickerPack: mockHelper.promise()
}
Kazv.AddStickerPopup {
id: addStickerPopup
- property var _closeCalled: 0
event: ({
content: {
url: 'mxc://example.org/something',
@@ -57,10 +49,7 @@
};
},
})
-
- function close() {
- ++addStickerPopup._closeCalled;
- }
+ property var close: mockHelper.noop()
}
TestCase {
@@ -73,10 +62,7 @@
}
function cleanup() {
- matrixSdk._updateStickerPackCalled = 0;
- matrixSdk._updateStickerPackLastArg = undefined;
- matrixSdk._updateStickerPackPromise = undefined;
- addStickerPopup._closeCalled = 0;
+ item.mockHelper.clearAll();
}
function test_addSticker() {
@@ -86,18 +72,18 @@
verify(button.enabled);
// tryVerify(() => false, 50000);
mouseClick(button);
- tryVerify(() => matrixSdk._updateStickerPackCalled === 1);
- verify(Helpers.deepEqual(matrixSdk._updateStickerPackLastArg, {
+ tryVerify(() => matrixSdk.updateStickerPack.calledTimes() === 1);
+ verify(Helpers.deepEqual(matrixSdk.updateStickerPack.lastArgs(), [{
'bar': {
url: 'mxc://example.org/something',
}
- }));
+ }]));
tryVerify(() => !button.enabled);
tryVerify(() => findChild(addStickerPopup, 'shortCodeInput').readOnly);
- verify(addStickerPopup._closeCalled === 0);
- matrixSdk._updateStickerPackPromise.resolve(true, {});
- tryVerify(() => addStickerPopup._closeCalled === 1);
+ verify(addStickerPopup.close.calledTimes() === 0);
+ matrixSdk.updateStickerPack.lastRetVal().resolve(true, {});
+ tryVerify(() => addStickerPopup.close.calledTimes() === 1);
}
function test_addStickerFailed() {
@@ -107,15 +93,15 @@
verify(button.enabled);
// tryVerify(() => false, 50000);
mouseClick(button);
- tryVerify(() => matrixSdk._updateStickerPackCalled === 1);
- verify(Helpers.deepEqual(matrixSdk._updateStickerPackLastArg, {
+ tryVerify(() => matrixSdk.updateStickerPack.calledTimes() === 1);
+ verify(Helpers.deepEqual(matrixSdk.updateStickerPack.lastArgs(), [{
'bar': {
url: 'mxc://example.org/something',
}
- }));
- matrixSdk._updateStickerPackPromise.resolve(false, {});
+ }]));
+ matrixSdk.updateStickerPack.lastRetVal().resolve(false, {});
tryVerify(() => button.enabled);
- verify(addStickerPopup._closeCalled === 0);
+ verify(addStickerPopup.close.calledTimes() === 0);
}
function test_addStickerOverride() {
@@ -125,18 +111,18 @@
verify(button.enabled);
// tryVerify(() => false, 50000);
mouseClick(button);
- tryVerify(() => matrixSdk._updateStickerPackCalled === 1);
- verify(Helpers.deepEqual(matrixSdk._updateStickerPackLastArg, {
+ tryVerify(() => matrixSdk.updateStickerPack.calledTimes() === 1);
+ verify(Helpers.deepEqual(matrixSdk.updateStickerPack.lastArgs(), [{
'foo': {
url: 'mxc://example.org/something',
}
- }));
+ }]));
tryVerify(() => !button.enabled);
tryVerify(() => findChild(addStickerPopup, 'shortCodeInput').readOnly);
- verify(addStickerPopup._closeCalled === 0);
- matrixSdk._updateStickerPackPromise.resolve(true, {});
- tryVerify(() => addStickerPopup._closeCalled === 1);
+ verify(addStickerPopup.close.calledTimes() === 0);
+ matrixSdk.updateStickerPack.lastRetVal().resolve(true, {});
+ tryVerify(() => addStickerPopup.close.calledTimes() === 1);
}
}
}
diff --git a/src/tests/quick-tests/tst_ConfirmUploadPopup.qml b/src/tests/quick-tests/tst_ConfirmUploadPopup.qml
--- a/src/tests/quick-tests/tst_ConfirmUploadPopup.qml
+++ b/src/tests/quick-tests/tst_ConfirmUploadPopup.qml
@@ -19,18 +19,14 @@
height: 600
property var l10n: Helpers.fluentMock
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {}
+
+ SignalSpy {
+ id: uploadRequestedSpy
+ signalName: 'uploadRequested'
}
Kazv.ConfirmUploadPopup {
id: confirmUploadPopup
- property var _uploadRequestedCalled: 0
- property var _uploadRequestedLastUrl: undefined
- onUploadRequested: (url) => {
- ++_uploadRequestedCalled;
- _uploadRequestedLastUrl = url;
- }
}
function isSheetOpen(sheet) {
@@ -46,9 +42,9 @@
name: 'ConfirmUploadPopupTest'
when: windowShown
- function cleanup() {
- confirmUploadPopup._uploadRequestedCalled = 0;
- confirmUploadPopup._uploadRequestedLastUrl = undefined;
+ function init() {
+ uploadRequestedSpy.clear();
+ uploadRequestedSpy.target = confirmUploadPopup;
}
function test_singleUpload() {
@@ -60,8 +56,8 @@
tryVerify(() => findChild(confirmUploadPopup, 'imagePreview').visible);
mouseClick(findChild(confirmUploadPopup, 'acceptButton'));
tryVerify(() => !isSheetOpen(confirmUploadPopup));
- verify(confirmUploadPopup._uploadRequestedCalled === 1);
- verify(confirmUploadPopup._uploadRequestedLastUrl === 'file:///tmp/image.png');
+ verify(uploadRequestedSpy.count === 1);
+ verify(uploadRequestedSpy.signalArguments[0][0] === 'file:///tmp/image.png');
}
function test_singleUploadCancelled() {
@@ -73,7 +69,7 @@
tryVerify(() => findChild(confirmUploadPopup, 'imagePreview').visible);
mouseClick(findChild(confirmUploadPopup, 'cancelButton'));
tryVerify(() => !isSheetOpen(confirmUploadPopup));
- verify(confirmUploadPopup._uploadRequestedCalled === 0);
+ verify(uploadRequestedSpy.count === 0);
}
function test_multiUpload() {
@@ -87,14 +83,14 @@
verify(isSheetOpen(confirmUploadPopup));
tryVerify(() => !findChild(confirmUploadPopup, 'imagePreview').visible);
- verify(confirmUploadPopup._uploadRequestedCalled === 1);
- verify(confirmUploadPopup._uploadRequestedLastUrl === 'file:///tmp/image.png');
+ verify(uploadRequestedSpy.count === 1);
+ verify(uploadRequestedSpy.signalArguments[0][0] === 'file:///tmp/image.png');
verify(confirmUploadPopup.currentIndex === 1);
mouseClick(findChild(confirmUploadPopup, 'acceptButton'));
tryVerify(() => !isSheetOpen(confirmUploadPopup));
- verify(confirmUploadPopup._uploadRequestedCalled === 2);
- verify(confirmUploadPopup._uploadRequestedLastUrl === 'file:///tmp/a.txt');
+ verify(uploadRequestedSpy.count === 2);
+ verify(uploadRequestedSpy.signalArguments[1][0] === 'file:///tmp/a.txt');
}
function test_multiUploadCancelled() {
@@ -106,7 +102,7 @@
tryVerify(() => findChild(confirmUploadPopup, 'imagePreview').visible);
mouseClick(findChild(confirmUploadPopup, 'cancelButton'));
tryVerify(() => !isSheetOpen(confirmUploadPopup));
- verify(confirmUploadPopup._uploadRequestedCalled === 0);
+ verify(uploadRequestedSpy.count === 0);
}
}
}
diff --git a/src/tests/quick-tests/tst_CreateRoomPage.qml b/src/tests/quick-tests/tst_CreateRoomPage.qml
--- a/src/tests/quick-tests/tst_CreateRoomPage.qml
+++ b/src/tests/quick-tests/tst_CreateRoomPage.qml
@@ -19,41 +19,20 @@
width: 800
height: 600
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {}
- }
+ property var mockHelper: TestHelpers.MockHelper {}
property var l10n: Helpers.fluentMock
property var matrixSdk: TestHelpers.MatrixSdkMock {
- property var _createRoomCalled: 0
- property var _createRoomArgs: ({})
- property var _createRoomPromise: undefined
-
- function createRoom(
- isPrivate,
- name,
- alias,
- invites,
- isDirect,
- allowFederate,
- topic,
- powerLevelContentOverride,
- preset,
- ) {
- ++item.matrixSdk._createRoomCalled;
- item.matrixSdk._createRoomArgs = {
- isPrivate,
- name,
- alias,
- invites,
- isDirect,
- allowFederate,
- topic,
- powerLevelContentOverride,
- preset,
- };
- item.matrixSdk._createRoomPromise = promiseComp.createObject(item);
- return item.matrixSdk._createRoomPromise;
- }
+ property var createRoom: mockHelper.promise([
+ 'isPrivate',
+ 'name',
+ 'alias',
+ 'invites',
+ 'isDirect',
+ 'allowFederate',
+ 'topic',
+ 'powerLevelContentOverride',
+ 'preset',
+ ])
}
property var sdkVars: ({})
@@ -74,9 +53,7 @@
}
function cleanup() {
- item.matrixSdk._createRoomCalled = 0;
- item.matrixSdk._createRoomArgs = {};
- item.matrixSdk._createRoomPromise = undefined;
+ mockHelper.clearAll();
createRoomPage.inviteUserIds = [];
createRoomPage.creatingRoom = false;
}
@@ -91,8 +68,8 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: false,
name: 'some name',
alias: 'alias',
@@ -115,8 +92,8 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: true,
name: 'some name',
alias: 'alias',
@@ -139,8 +116,8 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: true,
name: 'some name',
alias: 'alias',
@@ -170,8 +147,8 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: true,
name: 'some name',
alias: 'alias',
@@ -205,8 +182,8 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: true,
name: 'some name',
alias: 'alias',
@@ -256,8 +233,8 @@
return label && label.text === '@baz:example.org'
}, 50000);
- tryVerify(() => item.matrixSdk._createRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._createRoomArgs, {
+ tryVerify(() => item.matrixSdk.createRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.createRoom.lastArgs(), {
isPrivate: false,
name: 'some name',
alias: 'alias',
diff --git a/src/tests/quick-tests/tst_EventView.qml b/src/tests/quick-tests/tst_EventView.qml
--- a/src/tests/quick-tests/tst_EventView.qml
+++ b/src/tests/quick-tests/tst_EventView.qml
@@ -19,41 +19,17 @@
width: 800
height: 600
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {
- }
- }
+ property var mockHelper: TestHelpers.MockHelper {}
- property var activateUserPageCalled: 0
- function activateUserPage() {
- ++activateUserPageCalled;
- }
+ property var activateUserPage: mockHelper.noop()
property var timeline: ({
gaps: [],
})
property var room: ({
- test_resendMessageCalled: 0,
- test_resendMessageLastTxnId: '',
- test_removeLocalEchoCalled: 0,
- test_removeLocalEchoLastTxnId: '',
- test_ensureStateEventCalled: 0,
- test_ensureStateEventCalledArgs: [],
- test_ensureStateEventPromise: null,
- resendMessage: (txnId) => {
- ++item.room.test_resendMessageCalled;
- item.room.test_resendMessageLastTxnId = txnId;
- },
- removeLocalEcho: (txnId) => {
- ++item.room.test_removeLocalEchoCalled;
- item.room.test_removeLocalEchoLastTxnId = txnId;
- },
- ensureStateEvent: (type, stateKey) => {
- ++item.room.test_ensureStateEventCalled;
- item.room.test_ensureStateEventCalledArgs = [type, stateKey];
- item.room.test_ensureStateEventPromise = promiseComp.createObject(item);
- return item.room.test_ensureStateEventPromise;
- },
+ resendMessage: mockHelper.promise(),
+ removeLocalEcho: mockHelper.promise(),
+ ensureStateEvent: mockHelper.promise(),
messageById: (_id) => item.textEvent,
member: (_id) => ({}),
})
@@ -369,14 +345,7 @@
function init() {
eventView.event = item.localEcho;
- item.room.test_resendMessageCalled = 0;
- item.room.test_resendMessageLastTxnId = '';
- item.room.test_removeLocalEchoCalled = 0;
- item.room.test_removeLocalEchoLastTxnId = '';
- item.room.test_ensureStateEventCalled = 0;
- item.room.test_ensureStateEventCalledArgs = [];
- item.room.test_ensureStateEventPromise = null;
- item.activateUserPageCalled = 0;
+ mockHelper.clearAll();
}
function test_localEcho() {
@@ -404,10 +373,9 @@
const deleteAction = findChild(menu, 'deleteMenuItem');
deleteAction.trigger();
- tryVerify(() => item.room.test_removeLocalEchoCalled === 1);
- tryVerify(() => item.room.test_removeLocalEchoLastTxnId === 'some-txn-id');
- verify(item.room.test_resendMessageCalled === 0);
- verify(item.room.test_resendMessageLastTxnId === '');
+ tryVerify(() => item.room.removeLocalEcho.calledTimes() === 1);
+ tryVerify(() => item.room.removeLocalEcho.lastArgs()[0] === 'some-txn-id');
+ verify(item.room.resendMessage.calledTimes() === 0);
}
function test_sentMessage() {
@@ -506,12 +474,12 @@
function test_userLink() {
const text = findChild(eventViewText, 'textEventContent');
text.linkActivated('https://matrix.to/#/@mew:example.com');
- tryVerify(() => item.room.test_ensureStateEventCalled);
+ tryVerify(() => item.room.ensureStateEvent.calledTimes());
verify(Helpers.deepEqual(
- item.room.test_ensureStateEventCalledArgs,
+ item.room.ensureStateEvent.lastArgs(),
['m.room.member', '@mew:example.com']));
- item.room.test_ensureStateEventPromise.resolve(true, {});
- tryVerify(() => item.activateUserPageCalled);
+ item.room.ensureStateEvent.lastRetVal().resolve(true, {});
+ tryVerify(() => item.activateUserPage.calledTimes());
}
function test_senderNameOverrided() {
diff --git a/src/tests/quick-tests/tst_EventViewRedacted.qml b/src/tests/quick-tests/tst_EventViewRedacted.qml
--- a/src/tests/quick-tests/tst_EventViewRedacted.qml
+++ b/src/tests/quick-tests/tst_EventViewRedacted.qml
@@ -15,14 +15,6 @@
width: 800
height: 600
- property var room: ({
- test_resendMessageCalled: 0,
- test_resendMessageLastTxnId: '',
- resendMessage: (txnId) => {
- ++item.room.test_resendMessageCalled;
- item.room.test_resendMessageLastTxnId = txnId;
- }
- })
property var l10n: Helpers.fluentMock
property var event: ({
eventId: '',
diff --git a/src/tests/quick-tests/tst_JoinRoomPage.qml b/src/tests/quick-tests/tst_JoinRoomPage.qml
--- a/src/tests/quick-tests/tst_JoinRoomPage.qml
+++ b/src/tests/quick-tests/tst_JoinRoomPage.qml
@@ -19,34 +19,15 @@
width: 800
height: 600
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {}
- }
+ property var mockHelper: TestHelpers.MockHelper {}
property var l10n: Helpers.fluentMock
property var showPassiveNotification: () => {}
property var matrixSdk: TestHelpers.MatrixSdkMock {
- property var _joinRoomCalled: 0
- property var _joinRoomArgs: ({})
- property var _joinRoomPromise: undefined
-
- function joinRoom(
- room, serverNames
- ) {
- ++item.matrixSdk._joinRoomCalled;
- item.matrixSdk._joinRoomArgs = {
- room,
- serverNames,
- };
- item.matrixSdk._joinRoomPromise = promiseComp.createObject(item);
- return item.matrixSdk._joinRoomPromise;
- }
+ property var joinRoom: mockHelper.promise()
}
property var sdkVars: ({})
property var pageStack: ({
- removePage (page) {
- ++item.pageStack._removePageCalled;
- },
- _removePageCalled: 0,
+ removePage: mockHelper.noop(),
})
Kazv.JoinRoomPage {
@@ -59,10 +40,7 @@
when: windowShown
function cleanup() {
- item.matrixSdk._joinRoomCalled = 0;
- item.matrixSdk._joinRoomArgs = {};
- item.matrixSdk._joinRoomPromise = undefined;
- item.pageStack._removePageCalled = 0;
+ mockHelper.clearAll();
}
function test_joinRoomWithServers() {
@@ -72,15 +50,14 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._joinRoomCalled === 1, 1000);
- console.log(JSON.stringify(item.matrixSdk._joinRoomArgs));
- verify(Helpers.deepEqual(item.matrixSdk._joinRoomArgs, {
- room: '#foo:example.com',
- serverNames: ['example.com', 'example.org'],
- }));
+ tryVerify(() => item.matrixSdk.joinRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.joinRoom.lastArgs(), [
+ '#foo:example.com',
+ ['example.com', 'example.org'],
+ ]));
- item.matrixSdk._joinRoomPromise.resolve(true, {});
- tryVerify(() => item.pageStack._removePageCalled === 1);
+ item.matrixSdk.joinRoom.lastRetVal().resolve(true, {});
+ tryVerify(() => item.pageStack.removePage.calledTimes() === 1);
}
function test_joinRoomWithoutServers() {
@@ -90,14 +67,14 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._joinRoomCalled === 1, 1000);
- verify(Helpers.deepEqual(item.matrixSdk._joinRoomArgs, {
- room: '#foo:example.com',
- serverNames: [],
- }));
+ tryVerify(() => item.matrixSdk.joinRoom.calledTimes() === 1, 1000);
+ verify(Helpers.deepEqual(item.matrixSdk.joinRoom.lastArgs(), [
+ '#foo:example.com',
+ [],
+ ]));
- item.matrixSdk._joinRoomPromise.resolve(true, {});
- tryVerify(() => item.pageStack._removePageCalled === 1);
+ item.matrixSdk.joinRoom.lastRetVal().resolve(true, {});
+ tryVerify(() => item.pageStack.removePage.calledTimes() === 1);
}
function test_joinRoomFailure() {
@@ -107,10 +84,10 @@
verify(button.enabled);
mouseClick(button);
- tryVerify(() => item.matrixSdk._joinRoomCalled === 1, 1000);
+ tryVerify(() => item.matrixSdk.joinRoom.calledTimes() === 1, 1000);
- item.matrixSdk._joinRoomPromise.resolve(false, {});
- tryVerify(() => item.pageStack._removePageCalled === 0);
+ item.matrixSdk.joinRoom.lastRetVal().resolve(false, {});
+ tryVerify(() => item.pageStack.removePage.calledTimes() === 0);
}
}
}
diff --git a/src/tests/quick-tests/tst_RoomInvitePage.qml b/src/tests/quick-tests/tst_RoomInvitePage.qml
--- a/src/tests/quick-tests/tst_RoomInvitePage.qml
+++ b/src/tests/quick-tests/tst_RoomInvitePage.qml
@@ -18,31 +18,15 @@
width: 800
height: 600
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {
- }
- }
-
- property var showPassiveNotification: (() => {})
+ property var mockHelper: TestHelpers.MockHelper {}
+ property var showPassiveNotification: mockHelper.noop()
property var pageStack: ({
- removePage (page) {
- ++item.pageStack._removePageCalled;
- },
- _removePageCalled: 0,
+ removePage: mockHelper.noop(),
})
property var room: ({
name: 'room',
- inviteUser (userId) {
- ++item.room._inviteUserCalled;
- item.room._inviteUserUserId = userId;
- const promise = promiseComp.createObject(item.room);
- item.room._inviteUserPromise = promise;
- return promise;
- },
- _inviteUserCalled: 0,
- _inviteUserUserId: undefined,
- _inviteUserPromise: undefined,
+ inviteUser: mockHelper.promise(),
})
property var l10n: Helpers.fluentMock
property var matrixSdk: TestHelpers.MatrixSdkMock {}
@@ -65,10 +49,7 @@
}
function cleanup() {
- item.room._inviteUserCalled = 0;
- item.room._inviteUserPromise = undefined;
- item.room._inviteUserUserId = undefined;
- item.pageStack._removePageCalled = 0;
+ mockHelper.clearAll();
}
function test_roomInvitePage() {
@@ -77,14 +58,14 @@
const button = findChild(roomInvitePage, 'inviteUserButton');
mouseClick(button);
- tryVerify(() => item.room._inviteUserCalled, 1000);
- verify(item.room._inviteUserPromise);
- verify(item.room._inviteUserUserId == '@mew:example.com');
+ tryVerify(() => item.room.inviteUser.calledTimes(), 1000);
+ verify(item.room.inviteUser);
+ verify(item.room.inviteUser.lastArgs()[0] == '@mew:example.com');
verify(!button.enabled);
- const promise = item.room._inviteUserPromise;
+ const promise = item.room.inviteUser.lastRetVal();
promise.resolve(true, {});
tryVerify(() => button.enabled, 1000);
- tryVerify(() => item.pageStack._removePageCalled, 1000);
+ tryVerify(() => item.pageStack.removePage.calledTimes(), 1000);
}
function test_roomInvitePageFailed() {
@@ -93,12 +74,12 @@
const button = findChild(roomInvitePage, 'inviteUserButton');
mouseClick(button);
- tryVerify(() => item.room._inviteUserCalled, 1000);
- verify(item.room._inviteUserPromise);
- const promise = item.room._inviteUserPromise;
+ tryVerify(() => item.room.inviteUser.calledTimes(), 1000);
+ const promise = item.room.inviteUser.lastRetVal();
+ verify(promise);
promise.resolve(false, {});
tryVerify(() => button.enabled, 1000);
- verify(!item.pageStack._removePageCalled);
+ verify(!item.pageStack.removePage.calledTimes());
}
}
}
diff --git a/src/tests/quick-tests/tst_RoomSettingsPage.qml b/src/tests/quick-tests/tst_RoomSettingsPage.qml
--- a/src/tests/quick-tests/tst_RoomSettingsPage.qml
+++ b/src/tests/quick-tests/tst_RoomSettingsPage.qml
@@ -20,20 +20,12 @@
width: 800
height: 600
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {}
- }
+ property var mockHelper: TestHelpers.MockHelper {}
property var roomUnencrypted: Helpers.factory.room({
membership: MK.MatrixRoom.Join,
encrypted: false,
- _sendStatePromise: undefined,
- _sendStateArg: undefined,
- sendStateEvent(event) {
- roomUnencrypted._sendStatePromise = promiseComp.createObject(item);
- roomUnencrypted._sendStateArg = event;
- return roomUnencrypted._sendStatePromise;
- },
+ sendStateEvent: mockHelper.promise(),
})
property var roomEncrypted: Helpers.factory.room({
@@ -41,8 +33,7 @@
encrypted: true,
})
- function showPassiveNotification() {
- }
+ property var showPassiveNotification: mockHelper.noop()
property var l10n: Helpers.fluentMock
property var matrixSdk: TestHelpers.MatrixSdkMock {
@@ -77,10 +68,10 @@
function test_enableEncryption() {
pageUnencrypted.encryptionPopup.accepted();
- tryVerify(() => roomUnencrypted._sendStateArg.type === 'm.room.encryption');
- tryVerify(() => roomUnencrypted._sendStateArg.state_key === '');
+ tryVerify(() => roomUnencrypted.sendStateEvent.lastArgs()[0].type === 'm.room.encryption');
+ tryVerify(() => roomUnencrypted.sendStateEvent.lastArgs()[0].state_key === '');
verify(!findChild(pageUnencrypted, 'enableEncryptionButton').enabled);
- roomUnencrypted._sendStatePromise.resolve(true, {});
+ roomUnencrypted.sendStateEvent.lastRetVal().resolve(true, {});
tryVerify(() => findChild(pageUnencrypted, 'enableEncryptionButton').enabled);
}
}
diff --git a/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml b/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
--- a/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
+++ b/src/tests/quick-tests/tst_SendMessageBoxDrafts.qml
@@ -20,6 +20,7 @@
width: 800
height: 600
+ property var mockHelper: TestHelpers.MockHelper {}
function makeRoom () {
return {
timeline () {
@@ -33,17 +34,10 @@
messageById () { return {}; },
member () { return {}; },
localDraft: '',
- _setLocalDraftCalled: 0,
- _internalLocalDraft: '',
- _updateLocalDraftNowCalled: 0,
- setLocalDraft (localDraft) {
- this._internalLocalDraft = localDraft;
- ++this._setLocalDraftCalled;
- },
- updateLocalDraftNow () {
- this.localDraft = this._internalLocalDraft;
- ++this._updateLocalDraftNowCalled;
- },
+ setLocalDraft: mockHelper.noop(),
+ updateLocalDraftNow: mockHelper.func(function () {
+ this.localDraft = this.setLocalDraft.lastArgs()[0];
+ }),
};
}
@@ -116,7 +110,7 @@
textArea.text = 'foo';
// verify that the draft is saved internally but not propagated
verify(item.room.localDraft === '');
- verify(item.room._internalLocalDraft === 'foo');
+ verify(item.room.setLocalDraft.lastArgs()[0] === 'foo');
// go back to MainPage
window.pageStack.goBack();
@@ -128,7 +122,7 @@
tryVerify(() => findChild(window.pageStack, 'draftMessage').text === '', 1000);
// verify that the draft is propagated
tryVerify(() => item.room.localDraft === 'foo', 1000);
- verify(item.room._updateLocalDraftNowCalled === 1);
+ verify(item.room.updateLocalDraftNow.calledTimes() === 1);
}
}
}
diff --git a/src/tests/quick-tests/tst_StickerPicker.qml b/src/tests/quick-tests/tst_StickerPicker.qml
--- a/src/tests/quick-tests/tst_StickerPicker.qml
+++ b/src/tests/quick-tests/tst_StickerPicker.qml
@@ -57,10 +57,13 @@
}
]
+ SignalSpy {
+ id: sendMessageRequestedSpy
+ signalName: 'sendMessageRequested'
+ }
+
Kazv.StickerPicker {
id: stickerPicker
- property var _sendMessageRequested: 0
- property var _lastEventJson: undefined
stickerPackList: ListModel {
id: stickerPackListModel
ListElement {
@@ -69,11 +72,6 @@
return stickerPacks[index];
}
}
-
- onSendMessageRequested: (eventJson) => {
- ++stickerPicker._sendMessageRequested;
- stickerPicker._lastEventJson = eventJson;
- }
}
TestCase {
@@ -81,9 +79,9 @@
name: 'StickerPickerTest'
when: windowShown
- function cleanup() {
- stickerPicker._sendMessageRequested = 0;
- stickerPicker._lastEventJson = undefined;
+ function init() {
+ sendMessageRequestedSpy.clear();
+ sendMessageRequestedSpy.target = stickerPicker;
}
function test_stickerPicker() {
@@ -92,8 +90,8 @@
verify(findChild(stickerPicker, 'sticker1'));
const stickerButton = findChild(stickerPicker, 'sticker1');
mouseClick(stickerButton);
- tryVerify(() => stickerPicker._sendMessageRequested, 1000);
- verify(Helpers.deepEqual(stickerPicker._lastEventJson, makeSticker(stickerPack0.get(1))));
+ tryVerify(() => sendMessageRequestedSpy.count, 1000);
+ verify(Helpers.deepEqual(sendMessageRequestedSpy.signalArguments[0][0], makeSticker(stickerPack0.get(1))));
}
}
}
diff --git a/src/tests/quick-tests/tst_UserPage.qml b/src/tests/quick-tests/tst_UserPage.qml
--- a/src/tests/quick-tests/tst_UserPage.qml
+++ b/src/tests/quick-tests/tst_UserPage.qml
@@ -22,32 +22,16 @@
property var matrixSdk: TestHelpers.MatrixSdkMock {
property var userId: '@foo:example.com'
}
+ property var mockHelper: TestHelpers.MockHelper {}
property var sdkVars: QtObject {
property var userGivenNicknameMap: QtObject {
id: gnMap
property var map: ({})
- property var _setAndUploadCalled: 0
- property var _setAndUploadArgs: []
- property var _setAndUploadPromise: null
- function setAndUpload(userId, value) {
- ++_setAndUploadCalled;
- _setAndUploadArgs = [userId, value];
- _setAndUploadPromise = promiseComp.createObject(upper);
- return _setAndUploadPromise;
- }
+ property var setAndUpload: mockHelper.promise()
}
}
- property var lastNotification: undefined
-
- function showPassiveNotification(msg) {
- upper.lastNotification = msg;
- }
-
- property var promiseComp: Component {
- TestHelpers.MatrixPromiseMock {
- }
- }
+ property var showPassiveNotification: mockHelper.noop()
property var powerLevelMapping: ({
'@mew:example.com': 100,
@@ -57,49 +41,11 @@
userPowerLevel(userId) {
return powerLevelMapping[userId];
},
- setUserPowerLevel(userId, powerLevel) {
- upper.room._setUserPowerLevelUserId = userId;
- upper.room._setUserPowerLevelPowerLevel = powerLevel;
- upper.room._setUserPowerLevelPromise = promiseComp.createObject(upper.room);
- return upper.room._setUserPowerLevelPromise;
- },
- ensureStateEvent(type, stateKey) {
- const promise = promiseComp.createObject(upper.room);
- console.log('ensureStateEvent', type, stateKey, promise);
- upper.room._ensureStateEventPromises.push(promise);
- console.log(upper.room._ensureStateEventPromises);
- return promise;
- },
- kickUser(userId, reason) {
- upper.room._kickUserUserId = userId;
- upper.room._kickUserReason = reason;
- upper.room._kickUserPromise = promiseComp.createObject(upper.room);
- return upper.room._kickUserPromise;
- },
- banUser(userId, reason) {
- upper.room._banUserUserId = userId;
- upper.room._banUserReason = reason;
- upper.room._banUserPromise = promiseComp.createObject(upper.room);
- return upper.room._banUserPromise;
- },
- unbanUser(userId) {
- upper.room._unbanUserUserId = userId;
- upper.room._unbanUserPromise = promiseComp.createObject(upper.room);
- return upper.room._unbanUserPromise;
- },
-
- _setUserPowerLevelUserId: undefined,
- _setUserPowerLevelPowerLevel: undefined,
- _setUserPowerLevelPromise: undefined,
- _ensureStateEventPromises: [],
- _kickUserUserId: undefined,
- _kickUserReason: undefined,
- _kickUserPromise: undefined,
- _banUserUserId: undefined,
- _banUserReason: undefined,
- _banUserPromise: undefined,
- _unbanUserUserId: undefined,
- _unbanUserPromise: undefined,
+ setUserPowerLevel: mockHelper.promise(),
+ ensureStateEvent: mockHelper.promise(),
+ kickUser: mockHelper.promise(),
+ banUser: mockHelper.promise(),
+ unbanUser: mockHelper.promise(),
})
ColumnLayout {
@@ -129,29 +75,14 @@
}
function cleanupTestCase() {
- upper.room._setUserPowerLevelUserId = undefined;
- upper.room._setUserPowerLevelPowerLevel = undefined;
- upper.room._setUserPowerLevelPromise = undefined;
- upper.room._ensureStateEventPromises = [];
- upper.room._kickUserUserId = undefined;
- upper.room._kickUserReason = undefined;
- upper.room._kickUserPromise = undefined;
- upper.room._banUserUserId = undefined;
- upper.room._banUserReason = undefined;
- upper.room._banUserPromise = undefined;
- upper.room._unbanUserUserId = undefined;
- upper.room._unbanUserPromise = undefined;
+ mockHelper.clearAll();
userPage.submittingPowerLevel = false;
userPage.editingPowerLevel = false;
userPage.powerLevelsLoaded = false;
userPage.banningUser = false;
userPage.unbanningUser = false;
- upper.lastNotification = undefined;
userPage.user = ({});
gnMap.map = {};
- gnMap._setAndUploadCalled = 0;
- gnMap._setAndUploadArgs = [];
- gnMap._setAndUploadPromise = null;
}
function test_powerLevel() {
@@ -162,8 +93,8 @@
const editButton = findChild(userPage, 'editPowerLevelButton');
verify(editButton.visible);
verify(!editButton.enabled);
- tryVerify(() => userPage.room._ensureStateEventPromises[1], 1000);
- userPage.room._ensureStateEventPromises[1].resolve(true, {});
+ tryVerify(() => userPage.room.ensureStateEvent.retVals[1], 1000);
+ userPage.room.ensureStateEvent.retVals[1].resolve(true, {});
tryVerify(() => editButton.enabled);
mouseClick(editButton);
@@ -173,17 +104,17 @@
const saveButton = findChild(userPage, 'savePowerLevelButton');
mouseClick(saveButton);
- tryVerify(() => room._setUserPowerLevelPromise, 1000);
+ tryVerify(() => room.setUserPowerLevel.lastRetVal(), 1000);
// Text field is not closed until the request succeeded
verify(textField.visible);
verify(textField.readOnly);
- verify(room._setUserPowerLevelUserId === '@mew:example.com');
- verify(room._setUserPowerLevelPowerLevel === 50);
+ verify(room.setUserPowerLevel.lastArgs()[0] === '@mew:example.com');
+ verify(room.setUserPowerLevel.lastArgs()[1] === 50);
// the buttons are disabled until the request responded
verify(!saveButton.enabled);
verify(!findChild(userPage, 'discardPowerLevelButton').enabled);
- room._setUserPowerLevelPromise.resolve(true, {});
+ room.setUserPowerLevel.lastRetVal().resolve(true, {});
tryVerify(() => !textField.visible, 1000);
// Text field is editable when we try to edit the power level again
@@ -193,8 +124,8 @@
}
function test_powerLevelEditFailure() {
- tryVerify(() => userPage.room._ensureStateEventPromises[1], 1000);
- userPage.room._ensureStateEventPromises[1].resolve(true, {});
+ tryVerify(() => userPage.room.ensureStateEvent.retVals[1], 1000);
+ userPage.room.ensureStateEvent.retVals[1].resolve(true, {});
const editButton = findChild(userPage, 'editPowerLevelButton');
tryVerify(() => editButton.enabled);
@@ -206,15 +137,15 @@
const saveButton = findChild(userPage, 'savePowerLevelButton');
mouseClick(saveButton);
- tryVerify(() => room._setUserPowerLevelPromise, 1000);
+ tryVerify(() => room.setUserPowerLevel.lastRetVal(), 1000);
// Text field is not closed until the request succeeded
- room._setUserPowerLevelPromise.resolve(false, {});
+ room.setUserPowerLevel.lastRetVal().resolve(false, {});
// text field is no longer readonly if failed
tryVerify(() => !textField.readOnly, 1000);
// show error message
- verify(upper.lastNotification);
+ verify(upper.showPassiveNotification.calledTimes());
// the buttons are enabled when the request responded
verify(saveButton.enabled);
@@ -244,11 +175,11 @@
reasonDialog.accept();
tryVerify(() => !reasonDialog.opened, 1000);
tryVerify(() => !banButton.enabled, 1000);
- tryVerify(() => room._banUserPromise, 1000);
- verify(room._banUserUserId === '@mew:example.com');
- verify(room._banUserReason === 'some reason');
+ tryVerify(() => room.banUser.lastRetVal(), 1000);
+ verify(room.banUser.lastArgs()[0] === '@mew:example.com');
+ verify(room.banUser.lastArgs()[1] === 'some reason');
- room._banUserPromise.resolve(true, {});
+ room.banUser.lastRetVal().resolve(true, {});
tryVerify(() => textField.text === '', 1000);
tryVerify(() => banButton.enabled, 1000);
}
@@ -272,12 +203,12 @@
reasonDialog.accept();
tryVerify(() => !reasonDialog.opened, 1000);
tryVerify(() => !banButton.enabled, 1000);
- tryVerify(() => room._banUserPromise, 1000);
- verify(room._banUserUserId === '@mew:example.com');
- verify(room._banUserReason === 'some reason');
+ tryVerify(() => room.banUser.lastRetVal(), 1000);
+ verify(room.banUser.lastArgs()[0] === '@mew:example.com');
+ verify(room.banUser.lastArgs()[1] === 'some reason');
- room._banUserPromise.resolve(false, {});
- tryVerify(() => upper.lastNotification, 1000);
+ room.banUser.lastRetVal().resolve(false, {});
+ tryVerify(() => upper.showPassiveNotification.calledTimes(), 1000);
// text field is not cleared when failed
tryVerify(() => textField.text === 'some reason', 1000);
tryVerify(() => banButton.enabled, 1000);
@@ -292,10 +223,10 @@
verify(unbanButton.enabled);
mouseClick(unbanButton);
tryVerify(() => !unbanButton.enabled, 1000);
- verify(room._unbanUserUserId == '@mew:example.com');
- verify(room._unbanUserPromise);
+ verify(room.unbanUser.lastArgs()[0] == '@mew:example.com');
+ verify(room.unbanUser.lastRetVal());
- room._unbanUserPromise.resolve(true, {});
+ room.unbanUser.lastRetVal().resolve(true, {});
tryVerify(() => unbanButton.enabled, 1000);
}
@@ -308,11 +239,11 @@
verify(unbanButton.enabled);
mouseClick(unbanButton);
tryVerify(() => !unbanButton.enabled, 1000);
- verify(room._unbanUserUserId == '@mew:example.com');
- verify(room._unbanUserPromise);
+ verify(room.unbanUser.lastArgs()[0] == '@mew:example.com');
+ verify(room.unbanUser.lastRetVal());
- room._unbanUserPromise.resolve(false, {});
- tryVerify(() => upper.lastNotification, 1000);
+ room.unbanUser.lastRetVal().resolve(false, {});
+ tryVerify(() => upper.showPassiveNotification.calledTimes(), 1000);
tryVerify(() => unbanButton.enabled, 1000);
}
}
@@ -335,11 +266,11 @@
reasonDialog.accept();
tryVerify(() => !reasonDialog.opened, 1000);
tryVerify(() => !kickButton.enabled, 1000);
- tryVerify(() => room._kickUserPromise, 1000);
- verify(room._kickUserUserId === '@mew:example.com');
- verify(room._kickUserReason === 'some reason');
+ tryVerify(() => room.kickUser.lastRetVal(), 1000);
+ verify(room.kickUser.lastArgs()[0] === '@mew:example.com');
+ verify(room.kickUser.lastArgs()[1] === 'some reason');
- room._kickUserPromise.resolve(true, {});
+ room.kickUser.lastRetVal().resolve(true, {});
tryVerify(() => textField.text === '', 1000);
// still available only because this is a mock call, no real action
// is performed on the user
@@ -366,9 +297,9 @@
mouseClick(saveButton);
tryVerify(() => !input.enabled);
verify(!saveButton.enabled);
- compare(gnMap._setAndUploadCalled, 1);
- verify(TestHelpers.deepEqual(gnMap._setAndUploadArgs, ['@mew:example.com', 'something']));
- gnMap._setAndUploadPromise.resolve(true, {});
+ compare(gnMap.setAndUpload.calledTimes(), 1);
+ verify(TestHelpers.deepEqual(gnMap.setAndUpload.lastRetVal(), ['@mew:example.com', 'something']));
+ gnMap.setAndUpload.lastRetVal().resolve(true, {});
tryVerify(() => input.enabled);
verify(saveButton.enabled);
}
@@ -383,9 +314,9 @@
mouseClick(saveButton);
tryVerify(() => !input.enabled);
verify(!saveButton.enabled);
- compare(gnMap._setAndUploadCalled, 1);
- verify(TestHelpers.deepEqual(gnMap._setAndUploadArgs, ['@mew:example.com', 'something']));
- gnMap._setAndUploadPromise.resolve(false, {});
+ compare(gnMap.setAndUpload.calledTimes(), 1);
+ verify(TestHelpers.deepEqual(gnMap.setAndUpload.lastArgs(), ['@mew:example.com', 'something']));
+ gnMap.setAndUpload.lastRetVal().resolve(false, {});
tryVerify(() => input.enabled);
verify(saveButton.enabled);
}
@@ -400,9 +331,9 @@
mouseClick(saveButton);
tryVerify(() => !input.enabled);
verify(!saveButton.enabled);
- compare(gnMap._setAndUploadCalled, 1);
- verify(TestHelpers.deepEqual(gnMap._setAndUploadArgs, ['@mew:example.com', null]));
- gnMap._setAndUploadPromise.resolve(true, {});
+ compare(gnMap.setAndUpload.calledTimes(), 1);
+ verify(TestHelpers.deepEqual(gnMap.setAndUpload.lastArgs(), ['@mew:example.com', null]));
+ gnMap.setAndUpload.lastRetVal().resolve(true, {});
tryVerify(() => input.enabled);
verify(saveButton.enabled);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 3:56 PM (11 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39016
Default Alt Text
D65.1732319770.diff (44 KB)

Event Timeline