Files
MeshChatX/tests/frontend/CallOverlay.test.js

161 lines
5.6 KiB
JavaScript

import { mount } from "@vue/test-utils";
import { describe, it, expect, vi } from "vitest";
import CallOverlay from "@/components/call/CallOverlay.vue";
describe("CallOverlay.vue", () => {
const defaultProps = {
activeCall: {
remote_identity_hash: "test_hash_long_enough_to_format",
remote_identity_name: "Test User",
status: 6, // Established
is_incoming: false,
is_voicemail: false,
call_start_time: Date.now() / 1000 - 60, // 1 minute ago
tx_bytes: 1024,
rx_bytes: 2048,
},
isEnded: false,
wasDeclined: false,
voicemailStatus: {
is_recording: false,
},
};
const mountCallOverlay = (props = {}) => {
return mount(CallOverlay, {
props: { ...defaultProps, ...props },
global: {
mocks: {
$t: (key) => key,
$router: {
push: vi.fn(),
},
},
stubs: {
MaterialDesignIcon: true,
LxmfUserIcon: true,
AudioWaveformPlayer: true,
},
},
});
};
it("renders when there is an active call", () => {
const wrapper = mountCallOverlay();
expect(wrapper.exists()).toBe(true);
expect(wrapper.text()).toContain("Test User");
expect(wrapper.text()).toContain("call.active_call");
});
it("shows remote hash if name is missing", () => {
const wrapper = mountCallOverlay({
activeCall: {
...defaultProps.activeCall,
remote_identity_name: null,
remote_identity_hash: "deadbeefcafebabe",
},
});
// The formatter produces <deadbeef...cafebabe>
expect(wrapper.text()).toContain("deadbeef");
expect(wrapper.text()).toContain("cafebabe");
});
it("toggles minimization when chevron is clicked", async () => {
const wrapper = mountCallOverlay();
// Initial state
expect(wrapper.vm.isMinimized).toBe(false);
// Find the minimize button - it's the button with chevron icon in the header
// Since MaterialDesignIcon is stubbed, we find it by finding buttons in the header
// The minimize button is the last button in the header section
const header = wrapper.find(".p-3.flex.items-center");
const headerButtons = header.findAll("button");
const minimizeButton = headerButtons[headerButtons.length - 1];
await minimizeButton.trigger("click");
expect(wrapper.vm.isMinimized).toBe(true);
await minimizeButton.trigger("click");
expect(wrapper.vm.isMinimized).toBe(false);
});
it("emits hangup event when hangup button is clicked", async () => {
const wrapper = mountCallOverlay();
// The hangup button has @click="hangupCall"
// Find the button with phone-hangup icon stub
const buttons = wrapper.findAll("button");
const hangupButton = buttons.find((b) => b.attributes("title") === "call.hangup_call");
if (hangupButton) {
await hangupButton.trigger("click");
expect(wrapper.emitted().hangup).toBeTruthy();
} else {
// fallback to finding by class if title stubbing is weird
const redButton = wrapper.find("button.bg-red-600");
await redButton.trigger("click");
expect(wrapper.emitted().hangup).toBeTruthy();
}
});
it("displays 'call.recording_voicemail' when voicemail is active", () => {
const wrapper = mountCallOverlay({
activeCall: {
...defaultProps.activeCall,
is_voicemail: true,
},
});
expect(wrapper.text()).toContain("call.recording_voicemail");
});
it("displays 'call.call_ended' when isEnded is true", () => {
const wrapper = mountCallOverlay({
isEnded: true,
});
expect(wrapper.text()).toContain("call.call_ended");
});
it("displays 'call.call_declined' when wasDeclined is true", () => {
const wrapper = mountCallOverlay({
wasDeclined: true,
});
expect(wrapper.text()).toContain("call.call_declined");
});
it("shows duration timer for active calls", () => {
const wrapper = mountCallOverlay({
activeCall: {
...defaultProps.activeCall,
call_start_time: Math.floor(Date.now() / 1000) - 75, // 1:15 ago
},
});
// 01:15 should be present
expect(wrapper.text()).toContain("01:15");
});
it("handles extremely long names in the overlay", () => {
const extremelyLongName = "Very ".repeat(20) + "Long Name";
const wrapper = mountCallOverlay({
activeCall: {
...defaultProps.activeCall,
remote_identity_name: extremelyLongName,
},
});
const nameElement = wrapper.find(".truncate");
expect(nameElement.exists()).toBe(true);
expect(nameElement.text()).toContain("Long Name");
});
it("handles large transfer statistics", () => {
const wrapper = mountCallOverlay({
activeCall: {
...defaultProps.activeCall,
tx_bytes: 1024 * 1024 * 1024 * 5, // 5 GB
rx_bytes: 1024 * 1024 * 500, // 500 MB
},
});
expect(wrapper.text()).toContain("5 GB");
expect(wrapper.text()).toContain("500 MB");
});
});