Page MenuHomePhorge

tst_EventView.qml
No OneTemporary

Size
19 KB
Referenced Files
None
Subscribers
None

tst_EventView.qml

/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import QtQuick 2.3
import QtQuick.Layouts 1.15
import QtTest 1.0
import moe.kazv.mxc.kazv 0.0 as MK
import org.kde.kirigami 2.13 as Kirigami
import '../../contents/ui' as Kazv
import 'test-helpers.js' as Helpers
import 'test-helpers' as QmlHelpers
QmlHelpers.TestItem {
id: item
property var activateUserPage: mockHelper.noop()
property var paginateBackRequested: mockHelper.noop()
property var viewEventHistoryRequested: mockHelper.noop()
property var pinEventRequested: mockHelper.noop()
property var unpinEventRequested: mockHelper.noop()
property var deleteEventRequested: mockHelper.noop()
property var timeline: ({
gaps: {},
})
property var pinnedEvents: ({
count: 2,
eventIds: {
'$123': true,
'$456': true,
},
})
property var room: ({
resendMessage: mockHelper.promise(),
removeLocalEcho: mockHelper.promise(),
ensureStateEvent: mockHelper.promise(),
messageById: (_id) => item.textEvent,
member: (_id) => ({}),
})
property var localEcho: ({
eventId: '',
sender: '',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.text',
body: 'some body',
},
encrypted: false,
isState: false,
unsignedData: {},
isLocalEcho: true,
isSending: true,
isFailed: false,
txnId: 'some-txn-id',
})
property var failedLocalEcho: Object.assign({}, item.localEcho, { isSending: false, isFailed: true, })
property var textEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.text',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var htmlEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.text',
body: '**some body**',
format: 'org.matrix.custom.html',
formatted_body: '<strong>some body</strong>',
},
formattedTime: '4:06 P.M.',
})
property var replyHtmlEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
replyingToEventId: '$xxx',
content: {
msgtype: 'm.text',
body: '> some quote\n**some body**',
format: 'org.matrix.custom.html',
formatted_body: '<mx-reply><blockquote>some quote</blockquote></mx-reply><strong>some body</strong>',
},
formattedTime: '4:06 P.M.',
})
property var replyNoQuoteHtmlEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
replyingToEventId: '$xxx',
content: {
msgtype: 'm.text',
body: '**some body**',
format: 'org.matrix.custom.html',
formatted_body: '<strong>some body</strong>',
},
formattedTime: '4:06 P.M.',
})
property var redactedEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {},
redacted: true,
formattedTime: '4:06 P.M.',
})
property var imageEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.image',
body: 'some body',
info: {
h: Kirigami.Units.gridUnit * 10,
w: Kirigami.Units.gridUnit * 10,
}
},
formattedTime: '4:06 P.M.',
})
property var stickerEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.sticker',
stateKey: '',
content: {
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var eventBySomeoneElse: ({
eventId: '',
sender: '@bar:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.image',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var eventTextBySomeoneElse: ({
eventId: '',
sender: '@bar:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.text',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var ignoredEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
relationType: 'm.replace',
stateKey: '',
content: {
msgtype: 'm.image',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var unknownTypeEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'moe.kazv.mxc.unknown.event',
stateKey: '',
content: {
msgtype: 'm.image',
body: 'some body',
},
})
property var unknownMsgtypeEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'moe.kazv.mxc.unknown.msgtype',
body: 'some body',
},
})
property var cannotDecryptEvent: ({
eventId: '',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'moe.kazv.mxc.cannot.decrypt',
body: 'some body',
},
})
property var editedEvent: ({
eventId: '!some-event-id',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
stateKey: '',
content: {
msgtype: 'm.text',
body: 'some body',
},
formattedTime: '4:06 P.M.',
isEdited: true,
})
property var pinnedEvent: ({
eventId: '$123',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
content: {
msgtype: 'm.text',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var notPinnedEvent: ({
eventId: '$789',
sender: '@foo:tusooa.xyz',
type: 'm.room.message',
content: {
msgtype: 'm.text',
body: 'some body',
},
formattedTime: '4:06 P.M.',
})
property var sender: ({
membership: 'join',
userId: '@foo:tusooa.xyz',
name: 'foo',
avatarMxcUri: '',
})
property var senderOther: ({
membership: 'join',
userId: '@bar:tusooa.xyz',
name: 'bar',
avatarMxcUri: '',
})
property var eventViewComp: Component {
Kazv.EventView {
Layout.fillWidth: true
event: QtObject {
property var eventId: '$some-event-id'
function readers() { return 0; }
}
sender: item.sender
isGapped: true
}
}
property var eventComp: Component {
QtObject {
property var eventId: '$some-event-id'
function readers() { return 0; }
}
}
ColumnLayout {
anchors.fill: parent
Kazv.EventView {
Layout.fillWidth: true
id: eventView
event: item.localEcho
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewFailed
event: item.failedLocalEcho
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewText
event: item.textEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewHtml
event: item.htmlEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewHtmlReply
event: item.replyHtmlEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewHtmlReplyNoQuote
event: item.replyNoQuoteHtmlEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewRedacted
event: item.redactedEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewUnknownType
event: item.unknownTypeEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewUnknownMsgtype
event: item.unknownMsgtypeEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewCannotDecrypt
event: item.cannotDecryptEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewCollapseSameSender
event: item.imageEvent
sender: item.sender
prevEvent: item.redactedEvent
}
Kazv.EventView {
id: eventViewCollapseLocalEcho
event: item.localEcho
sender: item.sender
prevEvent: item.redactedEvent
}
Kazv.EventView {
id: eventViewDontCollapseDifferentSender
event: item.imageEvent
sender: item.sender
prevEvent: item.eventBySomeoneElse
}
Kazv.EventView {
id: eventViewDontCollapseLocalEchoDifferentSender
event: item.localEcho
sender: item.sender
prevEvent: item.eventBySomeoneElse
}
Kazv.EventView {
id: eventViewDontCollapseIgnoredEvent
event: item.imageEvent
sender: item.sender
prevEvent: item.ignoredEvent
}
Kazv.EventView {
id: eventViewTextBySomeoneElse
event: item.eventTextBySomeoneElse
sender: item.senderOther
}
Kazv.EventView {
id: eventViewImage
event: item.imageEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewImageCompact
compactMode: true
event: item.imageEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewSticker
event: item.stickerEvent
sender: item.sender
}
Kazv.EventView {
id: eventViewStickerCompact
compactMode: true
event: item.stickerEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewEdited
event: item.editedEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewPinned
event: item.pinnedEvent
sender: item.sender
}
Kazv.EventView {
Layout.fillWidth: true
id: eventViewNotPinned
event: item.notPinnedEvent
sender: item.sender
}
}
TestCase {
id: eventViewTest
name: 'EventViewTest'
when: windowShown
function init() {
item.matrixSdk.userId = '@foo:tusooa.xyz';
eventView.event = item.localEcho;
mockHelper.clearAll();
}
function test_localEcho() {
const indicator = findChild(eventView, 'localEchoIndicator');
verify(indicator);
verify(indicator.icon.name === 'state-sync');
verify(indicator.Accessible.name === l10n.get('event-sending'));
const resendButton = findChild(eventView, 'localEchoIndicator');
verify(resendButton);
verify(!resendButton.enabled);
verify(!findChild(eventView, 'timeIndicator').visible);
}
function test_localEchoFailedRemove() {
const indicator = findChild(eventViewFailed, 'localEchoIndicator');
verify(indicator);
verify(indicator.visible);
verify(indicator.icon.name === 'state-warning');
verify(indicator.Accessible.name === l10n.get('event-resend'));
const menuComp = findChild(eventViewFailed, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const deleteAction = findChild(menu, 'deleteMenuItem');
verify(deleteAction.enabled);
deleteAction.trigger();
compare(deleteEventRequested.calledTimes(), 1);
}
function test_sentMessage() {
const indicator = findChild(eventViewText, 'localEchoIndicator');
verify(indicator);
verify(!indicator.visible);
verify(findChild(eventViewText, 'timeIndicator').visible);
}
function test_htmlMessage() {
const text = findChild(eventViewHtml, 'eventViewMainItem');
verify(text.textFormat === TextEdit.RichText);
verify(text.text.includes('some body'));
}
function test_htmlMessageReply() {
const text = findChild(eventViewHtmlReply, 'eventViewMainItem');
verify(text.textFormat === TextEdit.RichText);
verify(!text.text.includes('<blockquote>'));
}
function test_htmlMessageReplyNoQuote() {
const text = findChild(eventViewHtmlReplyNoQuote, 'eventViewMainItem');
verify(text.textFormat === TextEdit.RichText);
verify(!text.text.includes('<blockquote>'));
verify(text.text.includes('some body'));
}
function test_menuText() {
const menuComp = findChild(eventViewText, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
verify(menu);
tryVerify(() => findChild(menu, 'replyToMenuItem').enabled);
tryVerify(() => findChild(menu, 'editMenuItem').enabled);
tryVerify(() => findChild(menu, 'deleteMenuItem').enabled);
}
function test_menuRedacted() {
const menuComp = findChild(eventViewRedacted, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
verify(menu);
tryVerify(() => !findChild(menu, 'replyToMenuItem').enabled);
tryVerify(() => !findChild(menu, 'deleteMenuItem').enabled);
}
function test_fallback() {
verify(findChild(eventViewUnknownType, 'fallbackIcon'));
verify(findChild(eventViewUnknownType, 'textEventContent').text ===
l10n.get('event-fallback-text', { type: unknownTypeEvent.type }));
verify(findChild(eventViewUnknownMsgtype, 'fallbackIcon'));
verify(findChild(eventViewUnknownMsgtype, 'textEventContent').text ===
l10n.get('event-msgtype-fallback-text', { msgtype: unknownMsgtypeEvent.content.msgtype }));
verify(findChild(eventViewCannotDecrypt, 'fallbackIcon'));
verify(findChild(eventViewCannotDecrypt, 'textEventContent').text ===
l10n.get('event-cannot-decrypt-text'));
}
function test_collapseSender() {
verify(!findChild(eventViewCollapseSameSender, 'senderAvatar').visible);
verify(findChild(eventViewCollapseSameSender, 'senderCollapsedPlaceholder').visible);
verify(!findChild(eventViewCollapseLocalEcho, 'senderAvatar').visible);
verify(findChild(eventViewCollapseLocalEcho, 'senderCollapsedPlaceholder').visible);
verify(findChild(eventViewDontCollapseDifferentSender, 'senderAvatar').visible);
verify(!findChild(eventViewDontCollapseDifferentSender, 'senderCollapsedPlaceholder').visible);
verify(findChild(eventViewDontCollapseLocalEchoDifferentSender, 'senderAvatar').visible);
verify(!findChild(eventViewDontCollapseLocalEchoDifferentSender, 'senderCollapsedPlaceholder').visible);
verify(findChild(eventViewDontCollapseIgnoredEvent, 'senderAvatar').visible);
verify(!findChild(eventViewDontCollapseIgnoredEvent, 'senderCollapsedPlaceholder').visible);
}
function test_eventByOther() {
const menuComp = findChild(eventViewTextBySomeoneElse, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
verify(menu);
tryVerify(() => !findChild(menu, 'editMenuItem').enabled);
}
function test_menuSelfDestruct() {
const menuComp = findChild(eventViewTextBySomeoneElse, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
verify(menu);
menu.popup(item);
menu.dismiss();
const menu2 = menuComp.createObject(menuComp.parent);
menu2.popup(item);
menu2.dismiss();
}
function test_userLink() {
const text = findChild(eventViewText, 'textEventContent');
text.linkActivated('https://matrix.to/#/@mew:example.com');
tryVerify(() => item.room.ensureStateEvent.calledTimes());
verify(Helpers.deepEqual(
item.room.ensureStateEvent.lastArgs(),
['m.room.member', '@mew:example.com']));
item.room.ensureStateEvent.lastRetVal().resolve(true, {});
tryVerify(() => item.activateUserPage.calledTimes());
}
function test_senderNameOverrided() {
const name = findChild(eventViewText, 'userNicknameText');
compare(name.text, l10n.get(
'user-name-overrided',
{ overridedName: 'something', globalName: 'foo' }));
}
function test_senderNameNotOverrided() {
const name = findChild(eventViewTextBySomeoneElse, 'userNicknameText');
compare(name.text, 'bar');
}
function test_paginateBack() {
const obj = item.eventViewComp.createObject(item);
tryVerify(() => item.paginateBackRequested.calledTimes());
verify(item.paginateBackRequested.lastArgs()[0] === '$some-event-id');
item.paginateBackRequested.clear();
obj.event.eventId = '$some-other-event-id';
tryVerify(() => item.paginateBackRequested.calledTimes() === 1);
verify(item.paginateBackRequested.lastArgs()[0] === '$some-other-event-id');
item.paginateBackRequested.clear();
const newEvent = eventComp.createObject(item);
obj.event = newEvent;
tryVerify(() => item.paginateBackRequested.calledTimes() === 1);
verify(item.paginateBackRequested.lastArgs()[0] === '$some-event-id');
item.paginateBackRequested.clear();
obj.isGapped = false;
verify(item.paginateBackRequested.calledTimes() === 0);
}
function test_avatarClick() {
const avatar = findChild(eventViewText, 'senderAvatar');
mouseClick(avatar);
tryVerify(() => item.activateUserPage.calledTimes() === 1);
// verify that the user id is passed
verify(item.activateUserPage.lastArgs()[2] === '@foo:tusooa.xyz');
}
function test_imageEvent() {
verify(!findChild(eventViewImage, 'summaryLabel').visible);
verify(findChild(eventViewImage, 'bodyLabel').visible);
verify(findChild(eventViewImageCompact, 'summaryLabel').visible);
verify(!findChild(eventViewImageCompact, 'bodyLabel').visible);
verify(!findChild(eventViewSticker, 'summaryLabel').visible);
verify(findChild(eventViewSticker, 'bodyLabel').visible);
verify(findChild(eventViewStickerCompact, 'summaryLabel').visible);
verify(!findChild(eventViewStickerCompact, 'bodyLabel').visible);
const image = findChild(eventViewImageCompact, 'mainImage');
verify(image.height <= Kirigami.Units.gridUnit * 5);
}
function test_history() {
{
const menuComp = findChild(eventViewText, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const action = findChild(menu, 'viewHistoryMenuItem');
verify(!action.enabled);
}
{
const menuComp = findChild(eventViewEdited, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const action = findChild(menu, 'viewHistoryMenuItem');
verify(action.enabled);
action.trigger();
compare(viewEventHistoryRequested.calledTimes(), 1);
compare(viewEventHistoryRequested.lastArgs()[0], '!some-event-id');
}
}
function test_pinned() {
{
const menuComp = findChild(eventViewPinned, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const action = findChild(menu, 'pinUnpinMenuItem');
verify(action.enabled);
action.trigger();
compare(unpinEventRequested.calledTimes(), 1);
compare(unpinEventRequested.lastArgs()[0], '$123');
compare(pinEventRequested.calledTimes(), 0);
}
{
const menuComp = findChild(eventViewNotPinned, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const action = findChild(menu, 'pinUnpinMenuItem');
verify(action.enabled);
action.trigger();
compare(pinEventRequested.calledTimes(), 1);
compare(pinEventRequested.lastArgs()[0], '$789');
compare(pinEventRequested.calledTimes(), 1);
}
{
const menuComp = findChild(eventView, 'bubble').menuComp;
const menu = menuComp.createObject(menuComp.parent);
const action = findChild(menu, 'pinUnpinMenuItem');
verify(!action.enabled);
}
}
}
}

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 19, 5:18 PM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55346
Default Alt Text
tst_EventView.qml (19 KB)

Event Timeline