snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
import { expect } from 'chai';
|
||||
import proxyquire from 'proxyquire';
|
||||
import sinon from 'sinon';
|
||||
|
||||
const formatStub = sinon.stub().returns('00:00');
|
||||
const isSameStub = sinon.stub().returns(true);
|
||||
const isDSTStub = sinon.stub().returns(true);
|
||||
|
||||
const momentStub = sinon.stub().returns({
|
||||
utc: () => ({
|
||||
tz: () => ({
|
||||
format: formatStub,
|
||||
isSame: isSameStub,
|
||||
isDST: isDSTStub,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const findActiveBusinessHoursStub = sinon.stub().returns([]);
|
||||
const LivechatBusinessHoursStub = {
|
||||
findActiveBusinessHours: findActiveBusinessHoursStub,
|
||||
};
|
||||
const saveBusinessHourStub = sinon.stub();
|
||||
const loggerStub = sinon.stub();
|
||||
|
||||
const { BusinessHourManager } = proxyquire.noCallThru().load('../../../../../../server/lib/omnichannel/business-hour/BusinessHourManager', {
|
||||
'../../../settings': {},
|
||||
'../../callbacks': {},
|
||||
'./AbstractBusinessHour': {},
|
||||
'moment-timezone': momentStub,
|
||||
'@rocket.chat/models': {
|
||||
LivechatBusinessHours: LivechatBusinessHoursStub,
|
||||
},
|
||||
'../logger': {
|
||||
businessHourLogger: {
|
||||
error: loggerStub,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const cronAddStub = sinon.stub();
|
||||
const cronRemoveStub = sinon.stub();
|
||||
|
||||
describe('[OC] BusinessHourManager', () => {
|
||||
afterEach(() => sinon.restore());
|
||||
describe('hasDaylightSavingTimeChanged()', () => {
|
||||
const manager = new BusinessHourManager({} as any);
|
||||
|
||||
it('should return false if the provided timezone is equal to the current one (No changes in the timezone)', () => {
|
||||
formatStub.returns('00:00');
|
||||
expect(manager.hasDaylightSavingTimeChanged({ name: 'test', utc: '00:00' })).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if the provided timezone is different to the current one, the current time is in DST but there is no difference between times (current, stored)', () => {
|
||||
isDSTStub.returns(true);
|
||||
formatStub.returns('01:00');
|
||||
isSameStub.returns(true);
|
||||
expect(manager.hasDaylightSavingTimeChanged({ name: 'test', utc: '00:00' })).to.be.false;
|
||||
});
|
||||
|
||||
it('should return false if the provided timezone is different to the current one, the current time is NOT in DST but there is no difference between times (current, stored)', () => {
|
||||
isDSTStub.returns(false);
|
||||
formatStub.returns('01:00');
|
||||
isSameStub.returns(true);
|
||||
expect(manager.hasDaylightSavingTimeChanged({ name: 'test', utc: '00:00' })).to.be.false;
|
||||
});
|
||||
|
||||
it('should return true if the provided timezone is different to the current one, the current time is in DST and the current time is different than the stored one', () => {
|
||||
isDSTStub.returns(true);
|
||||
formatStub.returns('01:00');
|
||||
isSameStub.returns(false);
|
||||
expect(manager.hasDaylightSavingTimeChanged({ name: 'test', utc: '00:00' })).to.be.true;
|
||||
});
|
||||
|
||||
it('should return true if the provided timezone is different to the current one, the current time is NOT in DST and the current time is different than the stored one', () => {
|
||||
isDSTStub.returns(false);
|
||||
formatStub.returns('01:00');
|
||||
isSameStub.returns(false);
|
||||
expect(manager.hasDaylightSavingTimeChanged({ name: 'test', utc: '00:00' })).to.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
describe('startDaylightSavingTimeVerifier()', () => {
|
||||
const cronStub = {
|
||||
add: cronAddStub,
|
||||
remove: cronRemoveStub,
|
||||
};
|
||||
const manager = new BusinessHourManager(cronStub);
|
||||
manager.registerBusinessHourBehavior({
|
||||
onStartBusinessHours: () => {},
|
||||
onDisableBusinessHours: () => {},
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
loggerStub.resetHistory();
|
||||
});
|
||||
|
||||
it('should call the verifier when the manager starts', async () => {
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'setupCallbacks');
|
||||
sinon.stub(manager, 'cleanupDisabledDepartmentReferences');
|
||||
sinon.stub(manager, 'startDaylightSavingTimeVerifier');
|
||||
await manager.startManager();
|
||||
expect(manager.startDaylightSavingTimeVerifier.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should register the cron job for the DST verifier when the manager starts', async () => {
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'setupCallbacks');
|
||||
sinon.stub(manager, 'cleanupDisabledDepartmentReferences');
|
||||
sinon.stub(manager, 'startDaylightSavingTimeVerifier');
|
||||
await manager.startManager();
|
||||
expect(cronAddStub.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should remove the cron job for the DST verifier when the manager stops', async () => {
|
||||
sinon.stub(manager, 'removeCronJobs');
|
||||
sinon.stub(manager, 'clearCronJobsCache');
|
||||
sinon.stub(manager, 'removeCallbacks');
|
||||
sinon.stub(manager, 'startDaylightSavingTimeVerifier');
|
||||
await manager.stopManager();
|
||||
expect(cronRemoveStub.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should remove and add back the cron job for the DST verifier when the manager restarts', async () => {
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'setupCallbacks');
|
||||
sinon.stub(manager, 'cleanupDisabledDepartmentReferences');
|
||||
sinon.stub(manager, 'startDaylightSavingTimeVerifier');
|
||||
sinon.stub(manager, 'removeCronJobs');
|
||||
sinon.stub(manager, 'clearCronJobsCache');
|
||||
sinon.stub(manager, 'removeCallbacks');
|
||||
await manager.restartManager();
|
||||
expect(cronRemoveStub.called).to.be.true;
|
||||
expect(cronAddStub.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should NOT save business hours when there is no active business hours', async () => {
|
||||
sinon.stub(manager, 'getBusinessHourType').returns({ saveBusinessHour: saveBusinessHourStub });
|
||||
findActiveBusinessHoursStub.resolves([]);
|
||||
await manager.startDaylightSavingTimeVerifier();
|
||||
expect(saveBusinessHourStub.called).to.be.false;
|
||||
});
|
||||
|
||||
it('should NOT save business hours when there is no timezone with DST changes', async () => {
|
||||
sinon.stub(manager, 'getBusinessHourType').returns({ saveBusinessHour: saveBusinessHourStub });
|
||||
sinon.stub(manager, 'hasDaylightSavingTimeChanged').returns(false);
|
||||
findActiveBusinessHoursStub.resolves([{ timezone: 'test' }]);
|
||||
await manager.startDaylightSavingTimeVerifier();
|
||||
expect(saveBusinessHourStub.called).to.be.false;
|
||||
});
|
||||
|
||||
it('should save business hours AND recreate the cron jobs for the work hours when there is a timezone with DST changes', async () => {
|
||||
sinon.stub(manager, 'getBusinessHourType').returns({ saveBusinessHour: saveBusinessHourStub });
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'hasDaylightSavingTimeChanged').returns(true);
|
||||
findActiveBusinessHoursStub.resolves([
|
||||
{ timezone: { name: 'timezoneName' }, workHours: [{ start: { time: 'startTime' }, finish: { time: 'finishTime' } }] },
|
||||
]);
|
||||
await manager.startDaylightSavingTimeVerifier();
|
||||
expect(
|
||||
saveBusinessHourStub.calledWith({
|
||||
timezone: { name: 'timezoneName' },
|
||||
timezoneName: 'timezoneName',
|
||||
workHours: [{ start: 'startTime', finish: 'finishTime' }],
|
||||
}),
|
||||
).to.be.true;
|
||||
expect(manager.createCronJobsForWorkHours.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should log any error on the updating process', async () => {
|
||||
sinon.stub(manager, 'getBusinessHourType').returns({ saveBusinessHour: saveBusinessHourStub });
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'hasDaylightSavingTimeChanged').returns(true);
|
||||
findActiveBusinessHoursStub.resolves([
|
||||
{ timezone: { name: 'timezoneName' }, workHours: [{ start: { time: 'startTime' }, finish: { time: 'finishTime' } }] },
|
||||
{ timezone: { name: 'timezoneName2' }, workHours: [{ start: { time: 'startTime' }, finish: { time: 'finishTime' } }] },
|
||||
]);
|
||||
const error = new Error('update error');
|
||||
saveBusinessHourStub.onSecondCall().rejects(error);
|
||||
await manager.startDaylightSavingTimeVerifier();
|
||||
expect(loggerStub.calledWith(sinon.match({ msg: 'Failed to update business hours with new timezone' }))).to.be.true;
|
||||
expect(manager.createCronJobsForWorkHours.called).to.be.true;
|
||||
});
|
||||
|
||||
it('should NOT throw any error even if the business hour has an invalid type', async () => {
|
||||
sinon.stub(manager, 'getBusinessHourType').returns({ saveBusinessHour: saveBusinessHourStub });
|
||||
sinon.stub(manager, 'createCronJobsForWorkHours');
|
||||
sinon.stub(manager, 'hasDaylightSavingTimeChanged').returns(true);
|
||||
findActiveBusinessHoursStub.resolves([
|
||||
{
|
||||
type: 'invalid',
|
||||
timezone: { name: 'timezoneName' },
|
||||
workHours: [{ start: { time: 'startTime' }, finish: { time: 'finishTime' } }],
|
||||
},
|
||||
]);
|
||||
await expect(manager.startDaylightSavingTimeVerifier()).not.to.be.rejected;
|
||||
expect(loggerStub.called).to.be.false;
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user