mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-02 03:57:52 +00:00
# Pull Request Template ## Description **This PR includes:** * Refactored two legacy mixins (`availability.js`, `nextAvailability.js`) into a Vue 3 composable (`useAvailability`), helper module and component based rendering logic. * Fixed an issue where the widget wouldn't load if business hours were enabled but all days were unchecked. * Fixed translation issue [[#11280](https://github.com/chatwoot/chatwoot/issues/11280)](https://github.com/chatwoot/chatwoot/issues/11280). * Reduced code complexity and size. * Added test coverage for both the composable and helper functions. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? ### Loom video https://www.loom.com/share/2bc3ed694b4349419505e275d14d0b98?sid=22d585e4-0dc7-4242-bcb6-e3edc16e3aee ### Story <img width="995" height="442" alt="image" src="https://github.com/user-attachments/assets/d6340738-07db-41d5-86fa-a8ecf734cc70" /> ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [x] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules Fixes https://github.com/chatwoot/chatwoot/issues/12012 --------- Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com> Co-authored-by: Pranav <pranav@chatwoot.com> Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
import { ref } from 'vue';
|
|
import { useAvailability } from '../useAvailability';
|
|
|
|
const mockIsOnline = vi.fn();
|
|
const mockIsInWorkingHours = vi.fn();
|
|
const mockUseCamelCase = vi.fn(obj => obj);
|
|
|
|
vi.mock('widget/helpers/availabilityHelpers', () => ({
|
|
isOnline: (...args) => mockIsOnline(...args),
|
|
isInWorkingHours: (...args) => mockIsInWorkingHours(...args),
|
|
}));
|
|
|
|
vi.mock('dashboard/composables/useTransformKeys', () => ({
|
|
useCamelCase: obj => mockUseCamelCase(obj),
|
|
}));
|
|
|
|
describe('useAvailability', () => {
|
|
const originalWindow = window.chatwootWebChannel;
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
|
|
// Reset mocks to return true by default
|
|
mockIsOnline.mockReturnValue(true);
|
|
mockIsInWorkingHours.mockReturnValue(true);
|
|
mockUseCamelCase.mockImplementation(obj => obj);
|
|
|
|
window.chatwootWebChannel = {
|
|
workingHours: [],
|
|
workingHoursEnabled: false,
|
|
timezone: 'UTC',
|
|
utcOffset: 'UTC',
|
|
replyTime: 'in_a_few_minutes',
|
|
};
|
|
});
|
|
|
|
afterEach(() => {
|
|
window.chatwootWebChannel = originalWindow;
|
|
});
|
|
|
|
describe('initial state', () => {
|
|
it('should initialize with default values', () => {
|
|
const { availableAgents, hasOnlineAgents, isInWorkingHours, isOnline } =
|
|
useAvailability();
|
|
|
|
expect(availableAgents.value).toEqual([]);
|
|
expect(hasOnlineAgents.value).toBe(false);
|
|
expect(isInWorkingHours.value).toBe(true);
|
|
expect(isOnline.value).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('with agents', () => {
|
|
it('should handle agents array', () => {
|
|
const agents = [{ id: 1 }, { id: 2 }];
|
|
const { availableAgents, hasOnlineAgents } = useAvailability(agents);
|
|
|
|
expect(availableAgents.value).toEqual(agents);
|
|
expect(hasOnlineAgents.value).toBe(true);
|
|
});
|
|
|
|
it('should handle reactive agents', () => {
|
|
const agents = ref([{ id: 1 }]);
|
|
const { hasOnlineAgents } = useAvailability(agents);
|
|
|
|
expect(hasOnlineAgents.value).toBe(true);
|
|
|
|
agents.value = [];
|
|
expect(hasOnlineAgents.value).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('working hours', () => {
|
|
const workingHours = [{ dayOfWeek: 1, openHour: 9, closeHour: 17 }];
|
|
|
|
beforeEach(() => {
|
|
window.chatwootWebChannel = {
|
|
workingHours,
|
|
workingHoursEnabled: true,
|
|
utcOffset: '+05:30',
|
|
};
|
|
});
|
|
|
|
it('should check working hours', () => {
|
|
mockIsInWorkingHours.mockReturnValueOnce(true);
|
|
const { isInWorkingHours } = useAvailability();
|
|
const result = isInWorkingHours.value;
|
|
|
|
expect(result).toBe(true);
|
|
expect(mockIsInWorkingHours).toHaveBeenCalledWith(
|
|
expect.any(Date),
|
|
'+05:30',
|
|
workingHours
|
|
);
|
|
});
|
|
|
|
it('should determine online status based on working hours and agents', () => {
|
|
mockIsOnline.mockReturnValueOnce(true);
|
|
const { isOnline } = useAvailability([{ id: 1 }]);
|
|
const result = isOnline.value;
|
|
|
|
expect(result).toBe(true);
|
|
expect(mockIsOnline).toHaveBeenCalledWith(
|
|
true,
|
|
expect.any(Date),
|
|
'+05:30',
|
|
workingHours,
|
|
true
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('config changes', () => {
|
|
it('should react to window.chatwootWebChannel changes', () => {
|
|
const { inboxConfig } = useAvailability();
|
|
|
|
window.chatwootWebChannel = {
|
|
...window.chatwootWebChannel,
|
|
replyTime: 'in_a_day',
|
|
};
|
|
|
|
expect(inboxConfig.value.replyTime).toBe('in_a_day');
|
|
});
|
|
});
|
|
});
|