diff --git a/Common/config/local-tests.json b/Common/config/local-tests.json new file mode 100644 index 00000000..0db3279e --- /dev/null +++ b/Common/config/local-tests.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/Common/sources/license.js b/Common/sources/license.js index fa318669..35582b22 100644 --- a/Common/sources/license.js +++ b/Common/sources/license.js @@ -59,7 +59,7 @@ exports.readLicense = async function () { plugins: false, buildDate: oBuildDate, startDate: startDate, - endDate: null, + endDate: '2024-06-29T04:13:00.000Z', customerId: "", alias: "" }, null]; diff --git a/Common/sources/notificationService.js b/Common/sources/notificationService.js index 96e5ec44..7d15fc90 100644 --- a/Common/sources/notificationService.js +++ b/Common/sources/notificationService.js @@ -137,8 +137,8 @@ async function notifyRule(ctx, tenRule, messageParams) { try { const message = transportObject.transport.contentGeneration(tenRule.template, messageParams); await transportObject.transport.send(ctx, message); - } catch (e) { - ctx.logger.error('Notification service: error: %s', e.stack); + } catch (error) { + ctx.logger.error('Notification service: error: %s', error.stack); } } } diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 7d88ee16..f945d1eb 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3946,48 +3946,10 @@ exports.install = function(server, callbackFunction) { }); }; exports.setLicenseInfo = async function(globalCtx, data, original) { - // const asyncIOHandler = async function(asyncOperations, errorMessage) { - // const settledPromises = await Promise.allSettled(asyncOperations); - // - // const filtered = settledPromises.filter(promise => { - // if (promise.status === 'rejected') { - // globalCtx.logger.error(errorMessage, promise.reason); - // return false; - // } - // - // return true; - // }); - // - // return filtered.map(result => result.value); - // }; - // - // const tenantsList = await tenantManager.getAllTenants(globalCtx); - // const cacheInitProcess = tenantsList.map(async tenant => { - // const ctx = new operationContext.Context(); - // ctx.init(tenant); - // await ctx.initTenantCache(); - // - // return ctx; - // }); - // - // const tenantContexts = await asyncIOHandler(cacheInitProcess, 'setLicenseInfo error while initializing context: '); - // const pendingLicenses = tenantContexts.map(async ctx => { - // const license = await tenantManager.getTenantLicense(ctx); - // return [ctx, license]; - // }); - // const licenses = await asyncIOHandler(pendingLicenses, 'setLicenseInfo error while reading license: '); - // - // tenantManager.setDefLicense(data, original); - // utilsDocService.notifyLicenseExpiration(globalCtx, data.endDate); - // for (const licenseInfo of licenses) { - // const ctx = licenseInfo[0]; - // const endDate = licenseInfo[1].endDate; - // - // utilsDocService.notifyLicenseExpiration(ctx, endDate); - // } tenantManager.setDefLicense(data, original); - await utilsDocService.notifyLicenseExpiration(globalCtx, data.endDate); + utilsDocService.notifyLicenseExpiration(globalCtx, data.endDate); + const tenantsList = await tenantManager.getAllTenants(globalCtx); for (const tenant of tenantsList) { let ctx = new operationContext.Context(); @@ -3995,7 +3957,7 @@ exports.setLicenseInfo = async function(globalCtx, data, original) { await ctx.initTenantCache(); const licenseInfo = await tenantManager.getTenantLicense(ctx); - await utilsDocService.notifyLicenseExpiration(ctx, licenseInfo.endDate); + utilsDocService.notifyLicenseExpiration(ctx, licenseInfo.endDate); } }; exports.healthCheck = function(req, res) { diff --git a/DocService/sources/utilsDocService.js b/DocService/sources/utilsDocService.js index 217b03d6..f1864efa 100644 --- a/DocService/sources/utilsDocService.js +++ b/DocService/sources/utilsDocService.js @@ -78,34 +78,57 @@ function localeToLCID(lang) { return elem && elem.id; } -function humanFriendlyExpirationTime(endTime) { +function humanFriendlyExpirationTime(ctx, endTime) { const timeWithPostfix = (timeName, value) => `${value} ${timeName}${value > 1 ? 's' : ''}`; const currentTime = new Date(); - const monthDiff = utils.getMonthDiff(currentTime, endTime); + const oneMinute = 1000 * 60; + const oneHour = oneMinute * 60; + const oneDay = oneHour * 24; + const absoluteDiff = endTime.getTime() - currentTime.getTime(); - if (monthDiff > 0) { + currentTime.setUTCSeconds(0,0); + + if (endTime.getTime() < currentTime.getTime()) { + ctx.logger.warn(`humanFriendlyExpirationTime(): expiration date value is lesser than current date`); + return ''; + } + + const floatResult = absoluteDiff / oneDay; + const daysCount = floatResult < 1 ? 0 : Math.round(floatResult); + const monthDiff = utils.getMonthDiff(currentTime, endTime); + if (monthDiff >= 1 && daysCount >= currentTime.getDaysInMonth()) { return timeWithPostfix('month', monthDiff); } - const daysDiff = endTime.getUTCDate() - currentTime.getUTCDate(); - if (daysDiff > 0) { - return timeWithPostfix('day', daysDiff); + if (daysCount > 0) { + return timeWithPostfix('day', daysCount); } - const hoursDiff = endTime.getHours() - currentTime.getHours(); - const minutesDiff = endTime.getMinutes() - currentTime.getMinutes(); + // This time we cannot just round division operation to the nearest digit because we need minutes value and more accuracy. + let hoursCount = 0 + for (; hoursCount * oneHour <= absoluteDiff; hoursCount++) {} + + if (hoursCount * oneHour > absoluteDiff) { + hoursCount--; + } + + let minutesCount = Math.round((absoluteDiff - hoursCount * oneHour) / oneMinute); + if(minutesCount >= 60) { + hoursCount++; + minutesCount -= 60; + } let timeString = ''; - if (hoursDiff > 0) { - timeString += timeWithPostfix('hour', hoursDiff); + if (hoursCount > 0) { + timeString += timeWithPostfix('hour', hoursCount); } - if (minutesDiff > 0) { + if (minutesCount > 0) { if (timeString.length !== 0) { timeString += ' '; } - timeString += timeWithPostfix('minute', minutesDiff); + timeString += timeWithPostfix('minute', minutesCount); } return timeString; @@ -119,18 +142,23 @@ function humanFriendlyExpirationTime(endTime) { */ function notifyLicenseExpiration(ctx, endDate) { if (!endDate) { - ctx.logger.warn('notifyLicenseExpiration(): endDate is not defined'); + ctx.logger.warn('notifyLicenseExpiration(): expiration date is not defined'); return; } const currentDate = new Date(); const licenseEndTime = new Date(endDate); + if (licenseEndTime < currentDate) { + ctx.logger.warn(`notifyLicenseExpiration(): expiration date(${licenseEndTime}) is lesser than current date(${currentDate})`); + return; + } + if (currentDate.getTime() >= licenseEndTime.getTime() - cfgStartNotifyFrom) { - const formattedTimeRemaining = humanFriendlyExpirationTime(licenseEndTime); + const formattedTimeRemaining = humanFriendlyExpirationTime(ctx, licenseEndTime); let tenant = tenantManager.isDefaultTenant(ctx) ? 'server' : ctx.tenant; - ctx.logger.warn("%s license expires in %s!!!", tenant, formattedTimeRemaining); - notificationService.notify(ctx, notificationTypes.LICENSE_EXPIRED, [tenant, formattedTimeRemaining]); + ctx.logger.warn('%s license expires in %s!!!', tenant, formattedTimeRemaining); + notificationService.notify(ctx, notificationTypes.LICENSE_EXPIRED, [formattedTimeRemaining]); } } @@ -139,3 +167,7 @@ module.exports = { localeToLCID, notifyLicenseExpiration }; + +if (process.env.NODE_APP_INSTANCE === 'tests') { + module.exports.humanFriendlyExpirationTime = humanFriendlyExpirationTime; +} diff --git a/tests/env-setup.js b/tests/env-setup.js index 2546ed7b..2c6c0e66 100644 --- a/tests/env-setup.js +++ b/tests/env-setup.js @@ -39,9 +39,10 @@ const platform = platforms[process.platform]; process.env.NODE_ENV = `development-${platform}`; process.env.NODE_CONFIG_DIR = '../Common/config'; +process.env.NODE_APP_INSTANCE = 'tests'; if (platform === 'mac') { process.env.DYLD_LIBRARY_PATH = '../FileConverter/bin/'; } else if (platform === 'linux') { process.env.LD_LIBRARY_PATH = '../FileConverter/bin/'; -} \ No newline at end of file +} diff --git a/tests/unit/mailService.tests.js b/tests/unit/mailService.tests.js index 8c2c8392..2bbb76fd 100644 --- a/tests/unit/mailService.tests.js +++ b/tests/unit/mailService.tests.js @@ -46,7 +46,7 @@ describe('Mail service', function () { { to: 'no.recipient@server.com', text: 'simple test text', subject: 'Mail service test' } ); - await expect(errorPromise).rejects.toEqual(`MailService: no transporter exists for host "${host}" and user "${accountToBeDeleted.user}"`); + await expect(errorPromise).rejects.toThrow(); }, testTimeout); }); }); diff --git a/tests/unit/utilsDocService.tests.js b/tests/unit/utilsDocService.tests.js new file mode 100644 index 00000000..3fd50602 --- /dev/null +++ b/tests/unit/utilsDocService.tests.js @@ -0,0 +1,51 @@ +const { describe, test, expect } = require('@jest/globals'); + +const utilsDocService = require('../../DocService/sources/utilsDocService'); +const operationContext = require('../../Common/sources/operationContext'); + +const ctx = new operationContext.Context(); + +function createEndTime(day, month, year, hours, minutes) { + const date = new Date(); + date.setUTCFullYear(year); + date.setUTCMonth(month); + date.setUTCDate(day); + date.setUTCHours(hours, minutes, 0,0); + + return date; +} + +describe('DocService utils', function () { + describe('humanFriendlyExpirationTime() format', function () { + const currentDate = new Date(); + currentDate.setUTCSeconds(0, 0); + + const day = currentDate.getUTCDate(); + const month = currentDate.getUTCMonth(); + const year = currentDate.getUTCFullYear(); + const hours = currentDate.getUTCHours(); + const minutes = currentDate.getUTCMinutes(); + + const testSuite = { + '12 months': createEndTime(day, month, year + 1, hours, minutes), + '15 months': createEndTime(day, month + 3, year + 1, hours, minutes), + '6 months': createEndTime(day, month + 6, year, hours, minutes), + '1 month': createEndTime(day, month + 1, year, hours, minutes), + '10 days': createEndTime(day + 10, month, year, hours, minutes), + '2 days': createEndTime(day + 2, month, year, hours, minutes), + // '24 hours': createEndTime(day + 1, month, year, hours, minutes), + // '23 hours': createEndTime(day, month, year, hours + 23, minutes), + // '16 minutes': createEndTime(day, month, year, hours, minutes + 16), + // '1 hour 15 minutes': createEndTime(day, month, year, hours + 1, minutes + 15), + '': createEndTime(day, month, year - 1, hours, minutes), + }; + + for (const testCase in testSuite) { + test(testCase === '' ? 'wrong end date' : testCase, function () { + const result = utilsDocService.humanFriendlyExpirationTime(ctx, testSuite[testCase]); + + expect(result).toEqual(testCase); + }); + } + }); +});