feat: enhance duty information handling with contact details and current duty view
- Added `bot_username` to settings for dynamic retrieval of the bot's username. - Implemented `_resolve_bot_username` function to fetch the bot's username if not set, improving user experience in group chats. - Updated `DutyWithUser` schema to include optional `phone` and `username` fields for enhanced duty information. - Enhanced API responses to include contact details for users, ensuring better communication. - Introduced a new current duty view in the web app, displaying active duty information along with contact options. - Updated CSS styles for better presentation of contact information in duty cards. - Added unit tests to verify the inclusion of contact details in API responses and the functionality of the current duty view.
This commit is contained in:
92
webapp/js/dutyList.test.js
Normal file
92
webapp/js/dutyList.test.js
Normal file
@@ -0,0 +1,92 @@
|
||||
/**
|
||||
* Unit tests for dutyList (dutyTimelineCardHtml, contact rendering).
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeAll } from "vitest";
|
||||
import { dutyTimelineCardHtml } from "./dutyList.js";
|
||||
|
||||
describe("dutyList", () => {
|
||||
beforeAll(() => {
|
||||
document.body.innerHTML =
|
||||
'<div id="calendar"></div><div id="monthTitle"></div>' +
|
||||
'<div id="dutyList"></div><div id="loading"></div><div id="error"></div>' +
|
||||
'<div id="accessDenied"></div><div class="header"></div><div class="weekdays"></div>' +
|
||||
'<button id="prevMonth"></button><button id="nextMonth"></button>';
|
||||
});
|
||||
|
||||
describe("dutyTimelineCardHtml", () => {
|
||||
it("renders duty with full_name and time range (no flip when no contacts)", () => {
|
||||
const d = {
|
||||
event_type: "duty",
|
||||
full_name: "Иванов",
|
||||
start_at: "2025-02-25T09:00:00",
|
||||
end_at: "2025-02-25T18:00:00",
|
||||
};
|
||||
const html = dutyTimelineCardHtml(d, false);
|
||||
expect(html).toContain("Иванов");
|
||||
expect(html).toContain("duty-item");
|
||||
expect(html).toContain("duty-timeline-card");
|
||||
expect(html).not.toContain("duty-flip-card");
|
||||
expect(html).not.toContain("duty-flip-btn");
|
||||
});
|
||||
|
||||
it("uses flip-card wrapper with front and back when phone or username present", () => {
|
||||
const d = {
|
||||
event_type: "duty",
|
||||
full_name: "Alice",
|
||||
start_at: "2025-03-01T09:00:00",
|
||||
end_at: "2025-03-01T17:00:00",
|
||||
phone: "+79991234567",
|
||||
username: "alice_dev",
|
||||
};
|
||||
const html = dutyTimelineCardHtml(d, false);
|
||||
expect(html).toContain("Alice");
|
||||
expect(html).toContain("duty-flip-card");
|
||||
expect(html).toContain("duty-flip-inner");
|
||||
expect(html).toContain("duty-flip-front");
|
||||
expect(html).toContain("duty-flip-back");
|
||||
expect(html).toContain("duty-flip-btn");
|
||||
expect(html).toContain('data-flipped="false"');
|
||||
expect(html).toContain("duty-contact-row");
|
||||
expect(html).toContain('href="tel:');
|
||||
expect(html).toContain("+79991234567");
|
||||
expect(html).toContain("https://t.me/");
|
||||
expect(html).toContain("alice_dev");
|
||||
});
|
||||
|
||||
it("front face contains name and time; back face contains contact links", () => {
|
||||
const d = {
|
||||
event_type: "duty",
|
||||
full_name: "Bob",
|
||||
start_at: "2025-03-02T08:00:00",
|
||||
end_at: "2025-03-02T16:00:00",
|
||||
phone: "+79001112233",
|
||||
};
|
||||
const html = dutyTimelineCardHtml(d, false);
|
||||
const frontStart = html.indexOf("duty-flip-front");
|
||||
const backStart = html.indexOf("duty-flip-back");
|
||||
const frontSection = html.slice(frontStart, backStart);
|
||||
const backSection = html.slice(backStart);
|
||||
expect(frontSection).toContain("Bob");
|
||||
expect(frontSection).toContain("time");
|
||||
expect(frontSection).not.toContain("duty-contact-row");
|
||||
expect(backSection).toContain("Bob");
|
||||
expect(backSection).toContain("duty-contact-row");
|
||||
expect(backSection).toContain("tel:");
|
||||
});
|
||||
|
||||
it("omits flip wrapper and button when phone and username are missing", () => {
|
||||
const d = {
|
||||
event_type: "duty",
|
||||
full_name: "Bob",
|
||||
start_at: "2025-03-02T08:00:00",
|
||||
end_at: "2025-03-02T16:00:00",
|
||||
};
|
||||
const html = dutyTimelineCardHtml(d, false);
|
||||
expect(html).toContain("Bob");
|
||||
expect(html).not.toContain("duty-flip-card");
|
||||
expect(html).not.toContain("duty-flip-btn");
|
||||
expect(html).not.toContain("duty-contact-row");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user