mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 21:33:18 +01:00
* WIP vue3 * WIP vue3 * WIP vue3 * Migrates to vitejs * Fixes js tests and removes not needed modules * Fixes unmount * Updates to use css instead for space * Fixes tests and rebases one more time * Uses orgua * Fixes migrations bugs with oruga and fixes scroll * Fixes v-deep * Fixes icons to prod * Fixes icons to prod * Adds favicon back * Transitions some to composition api * Updates another component to comp api * Cleans defineProps * Updates log messages * Moves more to compose api * Cleans up styles and rewrites event source * Tries to fix DOMPurify * Removes postcss * WIP typescript * Improves importing * Converts all to ts * Converts main to ts * Makes changes for tsconfig * Moves more to ts * Adds typing to store * More typing * Updates to ts * Updates the rest to ts * Fixes computes * Fixes unmount * Adds cypress with custom base fixed * Fixes jest tests * Fixes golang tests * Adds gitignore for cypress * Removes int in favor of e2e with cypress * Tries to fix int tests again * Adds title * Updates e2e tests * Uses vue for isMobile * Removes app spec * Cleans up docker * Adds drop down for settings * Fixes bug with restart * Fixes scroll up bug * Adds tests for light mode
237 lines
8.7 KiB
TypeScript
237 lines
8.7 KiB
TypeScript
import { mount } from "@vue/test-utils";
|
|
import { createStore } from "vuex";
|
|
// @ts-ignore
|
|
import EventSource, { sources } from "eventsourcemock";
|
|
import debounce from "lodash.debounce";
|
|
import LogEventSource from "./LogEventSource.vue";
|
|
import LogViewer from "./LogViewer.vue";
|
|
import { mocked } from "ts-jest/utils";
|
|
|
|
jest.mock("lodash.debounce", () =>
|
|
jest.fn((fn) => {
|
|
fn.cancel = () => {};
|
|
return fn;
|
|
})
|
|
);
|
|
|
|
jest.mock("../store/config.ts", () => ({ base: "" }));
|
|
|
|
describe("<LogEventSource />", () => {
|
|
beforeEach(() => {
|
|
// @ts-ignore
|
|
global.EventSource = EventSource;
|
|
window.scrollTo = jest.fn();
|
|
global.IntersectionObserver = jest.fn().mockImplementation(() => ({
|
|
observe: jest.fn(),
|
|
disconnect: jest.fn(),
|
|
}));
|
|
|
|
mocked(debounce).mockClear();
|
|
});
|
|
|
|
function createLogEventSource({
|
|
hourStyle = "auto",
|
|
searchFilter = null,
|
|
}: { hourStyle?: string; searchFilter?: string | null } = {}) {
|
|
const store = createStore({
|
|
state: { searchFilter, settings: { size: "medium", showTimestamp: true, hourStyle } },
|
|
getters: {
|
|
allContainersById() {
|
|
return {
|
|
abc: { state: "running" },
|
|
};
|
|
},
|
|
},
|
|
});
|
|
|
|
return mount(LogEventSource, {
|
|
global: {
|
|
plugins: [store],
|
|
components: {
|
|
LogViewer,
|
|
},
|
|
},
|
|
slots: {
|
|
default: `
|
|
<template #scoped="params"><log-viewer :messages="params.messages"></log-viewer></template>
|
|
`,
|
|
},
|
|
props: { id: "abc" },
|
|
});
|
|
}
|
|
|
|
test("renders correctly", async () => {
|
|
const wrapper = createLogEventSource();
|
|
expect(wrapper.html()).toMatchSnapshot();
|
|
});
|
|
|
|
test("should connect to EventSource", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
expect(sources["/api/logs/stream?id=abc&lastEventId="].readyState).toBe(1);
|
|
wrapper.unmount();
|
|
});
|
|
|
|
test("should close EventSource", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
wrapper.unmount();
|
|
expect(sources["/api/logs/stream?id=abc&lastEventId="].readyState).toBe(2);
|
|
});
|
|
|
|
test("should parse messages", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z "This is a message."`,
|
|
});
|
|
|
|
const [message, _] = wrapper.vm.messages;
|
|
const { key, ...messageWithoutKey } = message;
|
|
|
|
expect(key).toBe("2019-06-12T10:55:42.459034602Z");
|
|
expect(messageWithoutKey).toMatchInlineSnapshot(`
|
|
Object {
|
|
"date": 2019-06-12T10:55:42.459Z,
|
|
"message": "\\"This is a message.\\"",
|
|
}
|
|
`);
|
|
});
|
|
|
|
test("should parse messages with loki's timestamp format", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({ data: `2020-04-27T12:35:43.272974324+02:00 xxxxx` });
|
|
|
|
const [message, _] = wrapper.vm.messages;
|
|
const { key, ...messageWithoutKey } = message;
|
|
|
|
expect(key).toBe("2020-04-27T12:35:43.272974324+02:00");
|
|
expect(messageWithoutKey).toMatchInlineSnapshot(`
|
|
Object {
|
|
"date": 2020-04-27T10:35:43.272Z,
|
|
"message": "xxxxx",
|
|
}
|
|
`);
|
|
});
|
|
|
|
test("should pass messages to slot", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z "This is a message."`,
|
|
});
|
|
const [message, _] = wrapper.getComponent(LogViewer).vm.messages;
|
|
|
|
const { key, ...messageWithoutKey } = message;
|
|
|
|
expect(key).toBe("2019-06-12T10:55:42.459034602Z");
|
|
|
|
expect(messageWithoutKey).toMatchInlineSnapshot(`
|
|
Object {
|
|
"date": 2019-06-12T10:55:42.459Z,
|
|
"message": "\\"This is a message.\\"",
|
|
}
|
|
`);
|
|
});
|
|
|
|
describe("render html correctly", () => {
|
|
const RealDate = Date;
|
|
beforeAll(() => {
|
|
// @ts-ignore
|
|
global.Date = class extends RealDate {
|
|
constructor(arg: any | number) {
|
|
super(arg);
|
|
if (arg) {
|
|
return new RealDate(arg);
|
|
} else {
|
|
return new RealDate(1560336936000);
|
|
}
|
|
}
|
|
};
|
|
});
|
|
afterAll(() => (global.Date = RealDate));
|
|
|
|
test("should render messages", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z "This is a message."`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\">today at 10:55:42 AM</time></span><span class=\\"text\\">\\"This is a message.\\"</span></li></ul>"`
|
|
);
|
|
});
|
|
|
|
test("should render messages with color", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z \x1b[30mblack\x1b[37mwhite`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\">today at 10:55:42 AM</time></span><span class=\\"text\\"><span style=\\"color:#000\\">black<span style=\\"color:#AAA\\">white</span></span></span></li></ul>"`
|
|
);
|
|
});
|
|
|
|
test("should render messages with html entities", async () => {
|
|
const wrapper = createLogEventSource();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z <test>foo bar</test>`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\">today at 10:55:42 AM</time></span><span class=\\"text\\"><test>foo bar</test></span></li></ul>"`
|
|
);
|
|
});
|
|
|
|
test("should render dates with 12 hour style", async () => {
|
|
const wrapper = createLogEventSource({ hourStyle: "12" });
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T23:55:42.459034602Z <test>foo bar</test>`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T23:55:42.459Z\\">today at 11:55:42 PM</time></span><span class=\\"text\\"><test>foo bar</test></span></li></ul>"`
|
|
);
|
|
});
|
|
|
|
test("should render dates with 24 hour style", async () => {
|
|
const wrapper = createLogEventSource({ hourStyle: "24" });
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T23:55:42.459034602Z <test>foo bar</test>`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T23:55:42.459Z\\">today at 23:55:42</time></span><span class=\\"text\\"><test>foo bar</test></span></li></ul>"`
|
|
);
|
|
});
|
|
|
|
test("should render messages with filter", async () => {
|
|
const wrapper = createLogEventSource({ searchFilter: "test" });
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitOpen();
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-11T10:55:42.459034602Z Foo bar`,
|
|
});
|
|
sources["/api/logs/stream?id=abc&lastEventId="].emitMessage({
|
|
data: `2019-06-12T10:55:42.459034602Z This is a test <hi></hi>`,
|
|
});
|
|
|
|
await wrapper.vm.$nextTick();
|
|
expect(wrapper.find("ul.events").html()).toMatchInlineSnapshot(
|
|
`"<ul class=\\"events medium\\"><li><span class=\\"date\\"><time datetime=\\"2019-06-12T10:55:42.459Z\\">today at 10:55:42 AM</time></span><span class=\\"text\\">This is a <mark>test</mark> <hi></hi></span></li></ul>"`
|
|
);
|
|
});
|
|
});
|
|
});
|