Chat is rendering

This commit is contained in:
Max Leiter 2022-05-23 12:17:10 -07:00
parent 52c13f49c1
commit f189e9766c
No known key found for this signature in database
GPG key ID: A3512F2F2F17EBDA
12 changed files with 151 additions and 159 deletions

View file

@ -14,7 +14,10 @@
id="context-menu" id="context-menu"
ref="contextMenu" ref="contextMenu"
role="menu" role="menu"
:style="style" :style="{
top: style.top + 'px',
left: style.left + 'px',
}"
tabindex="-1" tabindex="-1"
@mouseleave="activeItem = -1" @mouseleave="activeItem = -1"
@keydown.enter.prevent="clickActiveItem" @keydown.enter.prevent="clickActiveItem"

View file

@ -24,11 +24,6 @@ export default defineComponent({
}, },
focused: Boolean, focused: Boolean,
}, },
// methods: {
// forceUpdate(){
// this.$forceUpdate()
// }
// },
setup(props) { setup(props) {
const localeDate = computed(() => dayjs(props.message.time).format("D MMMM YYYY")); const localeDate = computed(() => dayjs(props.message.time).format("D MMMM YYYY"));

View file

@ -66,6 +66,7 @@ import Message from "./Message.vue";
import MessageCondensed from "./MessageCondensed.vue"; import MessageCondensed from "./MessageCondensed.vue";
import DateMarker from "./DateMarker.vue"; import DateMarker from "./DateMarker.vue";
import { import {
defineExpose,
computed, computed,
defineComponent, defineComponent,
nextTick, nextTick,
@ -247,7 +248,7 @@ export default defineComponent({
message: Msg | ClientMessage | CondensedMessageContainer, message: Msg | ClientMessage | CondensedMessageContainer,
id: number id: number
) => { ) => {
const previousMessage = condensedMessages[id - 1]; const previousMessage = condensedMessages.value[id - 1];
if (!previousMessage) { if (!previousMessage) {
return true; return true;
@ -431,6 +432,7 @@ export default defineComponent({
shouldDisplayUnreadMarker, shouldDisplayUnreadMarker,
keepScrollPosition, keepScrollPosition,
isPreviousSource, isPreviousSource,
jumpToBottom,
onLinkPreviewToggle, onLinkPreviewToggle,
}; };
}, },

View file

@ -46,7 +46,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import {defineComponent, PropType} from "vue"; import {computed, defineComponent, PropType} from "vue";
import collapseNetwork from "../js/helpers/collapseNetwork"; import collapseNetwork from "../js/helpers/collapseNetwork";
import roundBadgeNumber from "../js/helpers/roundBadgeNumber"; import roundBadgeNumber from "../js/helpers/roundBadgeNumber";
import ChannelWrapper from "./ChannelWrapper.vue"; import ChannelWrapper from "./ChannelWrapper.vue";
@ -68,24 +68,34 @@ export default defineComponent({
isFiltering: Boolean, isFiltering: Boolean,
}, },
emits: ["toggle-join-channel"], emits: ["toggle-join-channel"],
computed: { setup(props) {
channel(): ClientChan { const channel = computed(() => {
return this.network.channels[0]; return props.network.channels[0];
}, });
joinChannelLabel(): string {
return this.isJoinChannelShown ? "Cancel" : "Join a channel…"; const joinChannelLabel = computed(() => {
}, return props.isJoinChannelShown ? "Cancel" : "Join a channel…";
unreadCount(): string { });
return roundBadgeNumber(this.channel.unread);
}, const unreadCount = computed(() => {
}, return roundBadgeNumber(channel.value.unread);
methods: { });
onCollapseClick(): void {
collapseNetwork(this.network, !this.network.isCollapsed); const onCollapseClick = () => {
}, collapseNetwork(props.network, !props.network.isCollapsed);
getExpandLabel(network: ClientNetwork): string { };
const getExpandLabel = (network: ClientNetwork) => {
return network.isCollapsed ? "Expand" : "Collapse"; return network.isCollapsed ? "Expand" : "Collapse";
}, };
return {
channel,
joinChannelLabel,
unreadCount,
onCollapseClick,
getExpandLabel,
};
}, },
}); });
</script> </script>

View file

@ -19,7 +19,7 @@
<script lang="ts"> <script lang="ts">
import ParsedMessage from "../ParsedMessage.vue"; import ParsedMessage from "../ParsedMessage.vue";
import localetime from "../../js/helpers/localetime"; import localeTime from "../../js/helpers/localetime";
import {defineComponent, PropType} from "vue"; import {defineComponent, PropType} from "vue";
import type {ClientNetwork, ClientChan} from "../../js/types"; import type {ClientNetwork, ClientChan} from "../../js/types";
@ -32,10 +32,14 @@ export default defineComponent({
network: {type: Object as PropType<ClientNetwork>, required: true}, network: {type: Object as PropType<ClientNetwork>, required: true},
channel: {type: Object as PropType<ClientChan>, required: true}, channel: {type: Object as PropType<ClientChan>, required: true},
}, },
methods: { setup() {
localetime(date: number | Date): string { const localetime = (date: number | Date) => {
return localetime(date); return localeTime(date);
}, };
return {
localetime,
};
}, },
}); });
</script> </script>

View file

@ -59,48 +59,65 @@
import storage from "../../js/localStorage"; import storage from "../../js/localStorage";
import socket from "../../js/socket"; import socket from "../../js/socket";
import RevealPassword from "../RevealPassword.vue"; import RevealPassword from "../RevealPassword.vue";
import {defineComponent} from "vue"; import {defineComponent, onBeforeUnmount, onMounted, ref} from "vue";
export default defineComponent({ export default defineComponent({
name: "SignIn", name: "SignIn",
components: { components: {
RevealPassword, RevealPassword,
}, },
data() { setup() {
return { const inFlight = ref(false);
inFlight: false, const errorShown = ref(false);
errorShown: false,
const username = ref<HTMLInputElement | null>(null);
const password = ref<HTMLInputElement | null>(null);
const onAuthFailed = () => {
inFlight.value = false;
errorShown.value = true;
}; };
},
mounted() { const onSubmit = (event: Event) => {
socket.on("auth:failed", this.onAuthFailed);
},
beforeUnmount() {
socket.off("auth:failed", this.onAuthFailed);
},
methods: {
onAuthFailed() {
this.inFlight = false;
this.errorShown = true;
},
onSubmit(event) {
event.preventDefault(); event.preventDefault();
this.inFlight = true; if (!username.value || !password.value) {
this.errorShown = false; return;
}
inFlight.value = true;
errorShown.value = false;
const values = { const values = {
user: this.$refs.username.value, user: username.value?.value,
password: this.$refs.password.value, password: password.value?.value,
}; };
storage.set("user", values.user); storage.set("user", values.user);
socket.emit("auth:perform", values); socket.emit("auth:perform", values);
}, };
getStoredUser() {
const getStoredUser = () => {
return storage.get("user"); return storage.get("user");
}, };
onMounted(() => {
socket.on("auth:failed", onAuthFailed);
});
onBeforeUnmount(() => {
socket.off("auth:failed", onAuthFailed);
});
return {
inFlight,
errorShown,
username,
password,
onSubmit,
getStoredUser,
};
}, },
}); });
</script> </script>

View file

@ -587,6 +587,12 @@ p {
/* End icons */ /* End icons */
#app {
height: 100%;
width: 100%;
}
#viewport { #viewport {
display: flex; display: flex;
height: 100%; height: 100%;

View file

@ -1,5 +1,5 @@
// Generates a string from "color-1" to "color-32" based on an input string // Generates a string from "color-1" to "color-32" based on an input string
export default (str) => { export default (str: string) => {
let hash = 0; let hash = 0;
for (let i = 0; i < str.length; i++) { for (let i = 0; i < str.length; i++) {
@ -11,5 +11,5 @@ export default (str) => {
due to A being ascii 65 (100 0001) due to A being ascii 65 (100 0001)
while a being ascii 97 (110 0001) while a being ascii 97 (110 0001)
*/ */
return "color-" + (1 + (hash % 32)); return "color-" + (1 + (hash % 32)).toString();
}; };

View file

@ -120,7 +120,7 @@ function parse(text: string, message?: ClientMessage, network?: ClientNetwork) {
rel: "noopener", rel: "noopener",
}, },
}, },
fragments () => fragments
); );
if (!preview) { if (!preview) {
@ -159,8 +159,9 @@ function parse(text: string, message?: ClientMessage, network?: ClientNetwork) {
dir: "auto", dir: "auto",
}, },
}, },
linkEls () => linkEls
); );
// @ts-ignore // @ts-ignore
} else if (textPart.channel) { } else if (textPart.channel) {
return createElement( return createElement(
@ -171,8 +172,9 @@ function parse(text: string, message?: ClientMessage, network?: ClientNetwork) {
channel: textPart.channel, channel: textPart.channel,
}, },
}, },
fragments () => fragments
); );
// @ts-ignore // @ts-ignore
} else if (textPart.emoji) { } else if (textPart.emoji) {
// @ts-ignore // @ts-ignore
@ -191,7 +193,7 @@ function parse(text: string, message?: ClientMessage, network?: ClientNetwork) {
title: title, title: title,
}, },
}, },
fragments () => fragments
); );
// @ts-ignore // @ts-ignore
} else if (textPart.nick) { } else if (textPart.nick) {
@ -205,14 +207,14 @@ function parse(text: string, message?: ClientMessage, network?: ClientNetwork) {
nick: textPart.nick, nick: textPart.nick,
}, },
// @ts-ignore // @ts-ignore
channel: messageChannel, channel: textPart.channel,
network, network,
}, },
attrs: { attrs: {
dir: "auto", dir: "auto",
}, },
}, },
fragments () => fragments
); );
} }

11
client/js/types.d.ts vendored
View file

@ -79,13 +79,10 @@ declare module "*.vue" {
} }
declare module "vue" { declare module "vue" {
interface ComponentCustomProperties { // interface ComponentCustomProperties {
// vue-router should do this for us // // TODO: Vue struggles with typing using the options API, so we should switch to composition API
$router: import("vue-router").Router; // // $root
// }
// TODO: Vue struggles with typing using the options API, so we should switch to composition API
// $root
}
} }
declare module "vue-router" { declare module "vue-router" {

View file

@ -43,7 +43,7 @@ self.addEventListener("fetch", function (event) {
return; return;
} }
event.respondWith(networkOrCache(event)); return event.respondWith(networkOrCache(event));
}); });
async function putInCache(request, response) { async function putInCache(request, response) {

View file

@ -1,29 +1,27 @@
import {expect} from "chai"; import {expect} from "chai";
import {renderToString} from "@vue/server-test-utils"; import {mount} from "@vue/test-utils";
import ParsedMessageTestWrapper from "../../components/ParsedMessageTestWrapper.vue"; import ParsedMessage from "../../../../client/components/ParsedMessage.vue";
import {ClientMessage} from "../../../../client/js/types";
async function getParsedMessageContents(text: any, message: any) { function getParsedMessageContents(text: string, message?: any) {
let contents = await renderToString(ParsedMessageTestWrapper, { const wrapper = mount(ParsedMessage, {
propsData: { props: {
text, text,
message, message,
}, },
}); });
// The wrapper adds a surrounding div to the message html, so we clean that out here return wrapper.html();
contents = contents.replace(/^<div data-server-rendered="true">([^]+)<\/div>$/m, "$1");
return contents;
} }
describe("IRC formatted message parser", () => { describe("IRC formatted message parser", () => {
it("should not introduce xss", async () => { it("should not introduce xss", () => {
const testCases = [ const testCases = [
{ {
input: "<img onerror='location.href=\"//youtube.com\"'>", input: "<img onerror='location.href=\"//youtube.com\"'>",
expected: expected:
'&lt;img onerror=\'location.href=&quot;<a href="http://youtube.com" dir="auto" target="_blank" rel="noopener">//youtube.com</a>&quot;\'&gt;', '&lt;img onerror=\'location.href="<a href="http://youtube.com" dir="auto" target="_blank" rel="noopener">//youtube.com</a>"\'&gt;',
}, },
{ {
input: '#&">bug', input: '#&">bug',
@ -32,16 +30,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should skip all <32 ASCII codes except linefeed", async () => { it("should skip all <32 ASCII codes except linefeed", () => {
const testCases = [ const testCases = [
{ {
input: "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1B\x1D\x1D\x1E\x1Ftext\x0Awithcontrolcodestest", input: "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1B\x1D\x1D\x1E\x1Ftext\x0Awithcontrolcodestest",
@ -50,16 +45,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should find urls", async () => { it("should find urls", () => {
const testCases = [ const testCases = [
{ {
input: "irc://irc.example.com/thelounge", input: "irc://irc.example.com/thelounge",
@ -102,16 +94,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("url with a dot parsed correctly", async () => { it("url with a dot parsed correctly", () => {
const input = const input =
"bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx"; "bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx";
const correctResult = const correctResult =
@ -120,13 +109,12 @@ describe("IRC formatted message parser", () => {
"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" + "https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
"</a>"; "</a>";
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const actual = getParsedMessageContents(input);
const actual = await getParsedMessageContents(input);
expect(actual).to.deep.equal(correctResult); expect(actual).to.deep.equal(correctResult);
}); });
it("should balance brackets", async () => { it("should balance brackets", () => {
const testCases = [ const testCases = [
{ {
input: "<https://theos.kyriasis.com/~kyrias/stats/archlinux.html>", input: "<https://theos.kyriasis.com/~kyrias/stats/archlinux.html>",
@ -162,16 +150,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should not find urls", async () => { it("should not find urls", () => {
const testCases = [ const testCases = [
{ {
input: "text www. text", input: "text www. text",
@ -183,16 +168,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should find channels", async () => { it("should find channels", () => {
const testCases = [ const testCases = [
{ {
input: "#a", input: "#a",
@ -241,16 +223,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should not find channels", async () => { it("should not find channels", () => {
const testCases = [ const testCases = [
{ {
input: "hi#test", input: "hi#test",
@ -262,10 +241,7 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
@ -362,9 +338,8 @@ describe("IRC formatted message parser", () => {
'<span class="irc-bold">bold</span>' + " " + '<span class="irc-bold">bold</span>', '<span class="irc-bold">bold</span>' + " " + '<span class="irc-bold">bold</span>',
}, },
].forEach(({name, input, expected}) => { ].forEach(({name, input, expected}) => {
it(`should handle style characters: ${name}`, async () => { it(`should handle style characters: ${name}`, () => {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. expect(getParsedMessageContents(input)).to.equal(expected);
expect(await getParsedMessageContents(input)).to.equal(expected);
}); });
}); });
@ -391,7 +366,7 @@ describe("IRC formatted message parser", () => {
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should not find nicks", async () => { it("should not find nicks", () => {
const testCases = [ const testCases = [
{ {
users: ["MaxLeiter, test"], users: ["MaxLeiter, test"],
@ -411,16 +386,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should go bonkers like mirc", async () => { it("should go bonkers like mirc", () => {
const testCases = [ const testCases = [
{ {
input: "\x02irc\x0f://\x1dirc.example.com\x0f/\x034,8thelounge", input: "\x02irc\x0f://\x1dirc.example.com\x0f/\x034,8thelounge",
@ -443,10 +415,7 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
@ -521,13 +490,12 @@ describe("IRC formatted message parser", () => {
'<span dir="auto" role="button" tabindex="0" class="inline-channel">#i❤thelounge</span>', '<span dir="auto" role="button" tabindex="0" class="inline-channel">#i❤thelounge</span>',
}, },
].forEach(({name, input, expected}) => { ].forEach(({name, input, expected}) => {
it(`should find emoji: ${name}`, async () => { it(`should find emoji: ${name}`, () => {
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. expect(getParsedMessageContents(input)).to.equal(expected);
expect(await getParsedMessageContents(input)).to.equal(expected);
}); });
}); });
it("should optimize generated html", async () => { it("should optimize generated html", () => {
const testCases = [ const testCases = [
{ {
input: 'test \x0312#\x0312\x0312"te\x0312st\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312a', input: 'test \x0312#\x0312\x0312"te\x0312st\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312a',
@ -539,16 +507,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should trim common protocols", async () => { it("should trim common protocols", () => {
const testCases = [ const testCases = [
{ {
input: "like..http://example.com", input: "like..http://example.com",
@ -568,16 +533,13 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should not find channel in fragment", async () => { it("should not find channel in fragment", () => {
const testCases = [ const testCases = [
{ {
input: "http://example.com/#hash", input: "http://example.com/#hash",
@ -588,19 +550,15 @@ describe("IRC formatted message parser", () => {
}, },
]; ];
const actual = await Promise.all( const actual = testCases.map((testCase) => getParsedMessageContents(testCase.input));
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1.
testCases.map((testCase) => getParsedMessageContents(testCase.input))
);
const expected = testCases.map((testCase) => testCase.expected); const expected = testCases.map((testCase) => testCase.expected);
expect(actual).to.deep.equal(expected); expect(actual).to.deep.equal(expected);
}); });
it("should not overlap parts", async () => { it("should not overlap parts", () => {
const input = "Url: http://example.com/path Channel: ##channel"; const input = "Url: http://example.com/path Channel: ##channel";
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const actual = getParsedMessageContents(input);
const actual = await getParsedMessageContents(input);
expect(actual).to.equal( expect(actual).to.equal(
'Url: <a href="http://example.com/path" dir="auto" target="_blank" rel="noopener">http://example.com/path</a> ' + 'Url: <a href="http://example.com/path" dir="auto" target="_blank" rel="noopener">http://example.com/path</a> ' +
@ -608,10 +566,9 @@ describe("IRC formatted message parser", () => {
); );
}); });
it("should handle overlapping parts by using first starting", async () => { it("should handle overlapping parts by using first starting", () => {
const input = "#test-https://example.com"; const input = "#test-https://example.com";
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const actual = getParsedMessageContents(input);
const actual = await getParsedMessageContents(input);
expect(actual).to.equal( expect(actual).to.equal(
'<span dir="auto" role="button" tabindex="0" class="inline-channel">' + '<span dir="auto" role="button" tabindex="0" class="inline-channel">' +
@ -620,10 +577,9 @@ describe("IRC formatted message parser", () => {
); );
}); });
it("should find links separated by tab character", async () => { it("should find links separated by tab character", () => {
const input = "example.com\texample.org"; const input = "example.com\texample.org";
// @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. const actual = getParsedMessageContents(input);
const actual = await getParsedMessageContents(input);
expect(actual).to.equal( expect(actual).to.equal(
'<a href="http://example.com" dir="auto" target="_blank" rel="noopener">example.com</a>' + '<a href="http://example.com" dir="auto" target="_blank" rel="noopener">example.com</a>' +