diff --git a/src/core/singletons/tests/time.test.ts b/src/core/singletons/tests/time.test.ts new file mode 100644 index 000000000..b5f2122f8 --- /dev/null +++ b/src/core/singletons/tests/time.test.ts @@ -0,0 +1,69 @@ +// (C) Copyright 2015 Moodle Pty Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { mockTranslate } from '@/testing/utils'; +import { CoreTime } from '@singletons/time'; + +describe('CoreTime singleton', () => { + + it('formats time in a human readable format', () => { + mockTranslate({ + 'core.days': 'days', + 'core.day': 'day', + 'core.hours': 'hours', + 'core.hour': 'hour', + 'core.mins': 'mins', + 'core.min': 'min', + 'core.now': 'now', + 'core.secs': 'secs', + 'core.sec': 'sec', + 'core.years': 'years', + 'core.year': 'year', + }); + + expect(CoreTime.formatTime(0)).toEqual('now'); + expect(CoreTime.formatTime(-5)).toEqual('5 secs'); + expect(CoreTime.formatTime(61)).toEqual('1 min 1 sec'); + expect(CoreTime.formatTime(7321)).toEqual('2 hours 2 mins'); + expect(CoreTime.formatTime(352861)).toEqual('4 days 2 hours'); + expect(CoreTime.formatTime(31888861)).toEqual('1 year 4 days'); + expect(CoreTime.formatTime(-31888861)).toEqual('1 year 4 days'); + + // Test different precisions. + expect(CoreTime.formatTime(31888861, 1)).toEqual('1 year'); + expect(CoreTime.formatTime(31888861, 3)).toEqual('1 year 4 days 2 hours'); + expect(CoreTime.formatTime(31888861, 4)).toEqual('1 year 4 days 2 hours 1 min'); + expect(CoreTime.formatTime(31888861, 5)).toEqual('1 year 4 days 2 hours 1 min 1 sec'); + }); + + it('formats time in a "short" human readable format', () => { + expect(CoreTime.formatTimeShort(0)).toEqual('0\'\''); + expect(CoreTime.formatTimeShort(61)).toEqual('1\' 1\'\''); + expect(CoreTime.formatTimeShort(7321)).toEqual('122\' 1\'\''); + }); + + it('calls a function only once', () => { + const testFunction = jest.fn(); + const onceFunction = CoreTime.once(testFunction); + + expect(testFunction).not.toHaveBeenCalled(); + + onceFunction('foo', 'bar'); + expect(testFunction).toHaveBeenCalledWith('foo', 'bar'); + + onceFunction('baz'); + expect(testFunction).toHaveBeenCalledTimes(1); + }); + +}); diff --git a/src/core/singletons/time.ts b/src/core/singletons/time.ts index 5c95ed837..fd855b383 100644 --- a/src/core/singletons/time.ts +++ b/src/core/singletons/time.ts @@ -39,7 +39,7 @@ export class CoreTime { let remainder = totalSecs - (years * CoreConstants.SECONDS_YEAR); const days = Math.floor(remainder / CoreConstants.SECONDS_DAY); - remainder = totalSecs - (days * CoreConstants.SECONDS_DAY); + remainder = remainder - (days * CoreConstants.SECONDS_DAY); const hours = Math.floor(remainder / CoreConstants.SECONDS_HOUR); remainder = remainder - (hours * CoreConstants.SECONDS_HOUR); diff --git a/src/testing/utils.ts b/src/testing/utils.ts index 4f097a35a..4b9091735 100644 --- a/src/testing/utils.ts +++ b/src/testing/utils.ts @@ -19,7 +19,7 @@ import { Observable, Subject } from 'rxjs'; import { sep } from 'path'; import { CORE_SITE_SCHEMAS } from '@services/sites'; -import { CoreSingletonProxy, Network, Platform } from '@singletons'; +import { CoreSingletonProxy, Network, Platform, Translate } from '@singletons'; import { CoreTextUtilsProvider } from '@services/utils/text'; import { TranslatePipeStub } from './stubs/pipes/translate'; @@ -269,3 +269,14 @@ export function wait(time: number): Promise { }, time); }); } + +/** + * Mocks translate service with certain translations. + * + * @param translations List of translations. + */ +export function mockTranslate(translations: Record): void { + mockSingleton(Translate, { + instant: (key) => translations[key] ?? key, + }); +}