diff --git a/.eslintrc.js b/.eslintrc.js index 842a24fc9..19d6f58e5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -173,12 +173,6 @@ const appConfig = { ], 'id-match': 'error', 'jsdoc/check-alignment': 'error', - 'jsdoc/check-indentation': [ - 'error', - { - excludeTags: ['param'], - }, - ], 'jsdoc/newline-after-description': 'error', 'linebreak-style': [ 'error', @@ -274,7 +268,7 @@ module.exports = { files: ['*.html'], extends: ['plugin:@angular-eslint/template/recommended'], rules: { - 'max-len': ['error', { code: 140 }], + 'max-len': ['warn', { code: 140 }], }, }, { diff --git a/config/utils.js b/config/utils.js index 00f16c041..e2d482c8f 100644 --- a/config/utils.js +++ b/config/utils.js @@ -15,7 +15,7 @@ const { execSync } = require('child_process'); const { resolve } = require('path'); -export function getConfig(environment) { +function getConfig(environment) { const { parse: parseJsonc } = require('jsonc-parser'); const { readFileSync, existsSync } = require('fs'); const envSuffixesMap = { @@ -38,11 +38,14 @@ export function getConfig(environment) { return config; } -export function getBuild(environment) { +function getBuild(environment) { return { - environment, isProduction: environment === 'production', + isTesting: environment === 'testing', + isDevelopment: environment === 'development', lastCommitHash: execSync('git log -1 --pretty=format:"%H"').toString(), compilationTime: Date.now(), }; } + +module.exports = { getConfig, getBuild }; diff --git a/src/app/app.component.test.ts b/src/app/app.component.test.ts index dd2ac8283..619c8faf9 100644 --- a/src/app/app.component.test.ts +++ b/src/app/app.component.test.ts @@ -12,13 +12,23 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { createComponent, prepareComponentTest } from '@/tests/utils'; +import { createComponent, createMock, prepareComponentTest } from '@/tests/utils'; import { AppComponent } from '@app/app.component'; +import { CoreLangProvider } from '@services/lang'; +import { CoreEvents } from '@singletons/events'; describe('App component', () => { - beforeEach(() => prepareComponentTest(AppComponent)); + let langProvider: CoreLangProvider; + + beforeEach(() => { + langProvider = createMock(['clearCustomStrings']); + + prepareComponentTest(AppComponent, [ + { provide: CoreLangProvider, useValue: langProvider }, + ]); + }); it('should render', () => { const fixture = createComponent(AppComponent); @@ -27,4 +37,13 @@ describe('App component', () => { expect(fixture.nativeElement.querySelector('ion-router-outlet')).toBeTruthy(); }); + it('clears custom strings on logout', async () => { + const fixture = createComponent(AppComponent); + + fixture.componentInstance.ngOnInit(); + CoreEvents.trigger(CoreEvents.LOGOUT); + + expect(langProvider.clearCustomStrings).toHaveBeenCalled(); + }); + }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 48afedd0e..7a18e7723 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -14,7 +14,7 @@ import { Component, OnInit } from '@angular/core'; import { CoreLangProvider } from '@services/lang'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; @Component({ selector: 'app-root', @@ -32,7 +32,7 @@ export class AppComponent implements OnInit { * Component being initialized. */ ngOnInit(): void { - CoreEvents.instance.on(CoreEventsProvider.LOGOUT, () => { + CoreEvents.on(CoreEvents.LOGOUT, () => { // Go to sites page when user is logged out. // Due to DeepLinker, we need to use the ViewCtrl instead of name. // Otherwise some pages are re-created when they shouldn't. diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c91cd54f6..03e57faf0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -28,7 +28,6 @@ import { CoreAppProvider } from '@services/app'; import { CoreConfigProvider } from '@services/config'; import { CoreCronDelegate } from '@services/cron'; import { CoreDbProvider } from '@services/db'; -import { CoreEventsProvider } from '@services/events'; import { CoreFileHelperProvider } from '@services/file-helper'; import { CoreFileSessionProvider } from '@services/file-session'; import { CoreFileProvider, CoreFile } from '@services/file'; @@ -90,7 +89,6 @@ export function createTranslateLoader(http: HttpClient): TranslateHttpLoader { CoreConfigProvider, CoreCronDelegate, CoreDbProvider, - CoreEventsProvider, CoreFileHelperProvider, CoreFileSessionProvider, CoreFileProvider, diff --git a/src/app/classes/delegate.ts b/src/app/classes/delegate.ts index 48a86308c..29dbbec7c 100644 --- a/src/app/classes/delegate.ts +++ b/src/app/classes/delegate.ts @@ -13,7 +13,7 @@ // limitations under the License. import { CoreSites } from '@services/sites'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreSite } from '@classes/site'; import { CoreLogger } from '@singletons/logger'; @@ -95,9 +95,9 @@ export class CoreDelegate { if (listenSiteEvents) { // Update handlers on this cases. - CoreEvents.instance.on(CoreEventsProvider.LOGIN, this.updateHandlers.bind(this)); - CoreEvents.instance.on(CoreEventsProvider.SITE_UPDATED, this.updateHandlers.bind(this)); - CoreEvents.instance.on(CoreEventsProvider.SITE_PLUGINS_LOADED, this.updateHandlers.bind(this)); + CoreEvents.on(CoreEvents.LOGIN, this.updateHandlers.bind(this)); + CoreEvents.on(CoreEvents.SITE_UPDATED, this.updateHandlers.bind(this)); + CoreEvents.on(CoreEvents.SITE_PLUGINS_LOADED, this.updateHandlers.bind(this)); } } diff --git a/src/app/classes/site.ts b/src/app/classes/site.ts index e798c2a64..53e66669e 100644 --- a/src/app/classes/site.ts +++ b/src/app/classes/site.ts @@ -17,7 +17,7 @@ import { Md5 } from 'ts-md5/dist/md5'; import { CoreApp } from '@services/app'; import { CoreDB } from '@services/db'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreFile } from '@services/file'; import { CoreWS, CoreWSPreSets, CoreWSFileUploadOptions, CoreWSAjaxPreSets, CoreWSExternalWarning } from '@services/ws'; import { CoreDomUtils } from '@services/utils/dom'; @@ -576,26 +576,26 @@ export class CoreSite { } // Session expired, trigger event. - CoreEvents.instance.trigger(CoreEventsProvider.SESSION_EXPIRED, {}, this.id); + CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, {}, this.id); // Change error message. Try to get data from cache, the event will handle the error. error.message = Translate.instance.instant('core.lostconnection'); } else if (error.errorcode === 'userdeleted') { // User deleted, trigger event. - CoreEvents.instance.trigger(CoreEventsProvider.USER_DELETED, { params: data }, this.id); + CoreEvents.trigger(CoreEvents.USER_DELETED, { params: data }, this.id); error.message = Translate.instance.instant('core.userdeleted'); throw new CoreWSError(error); } else if (error.errorcode === 'forcepasswordchangenotice') { // Password Change Forced, trigger event. Try to get data from cache, the event will handle the error. - CoreEvents.instance.trigger(CoreEventsProvider.PASSWORD_CHANGE_FORCED, {}, this.id); + CoreEvents.trigger(CoreEvents.PASSWORD_CHANGE_FORCED, {}, this.id); error.message = Translate.instance.instant('core.forcepasswordchangenotice'); } else if (error.errorcode === 'usernotfullysetup') { // User not fully setup, trigger event. Try to get data from cache, the event will handle the error. - CoreEvents.instance.trigger(CoreEventsProvider.USER_NOT_FULLY_SETUP, {}, this.id); + CoreEvents.trigger(CoreEvents.USER_NOT_FULLY_SETUP, {}, this.id); error.message = Translate.instance.instant('core.usernotfullysetup'); } else if (error.errorcode === 'sitepolicynotagreed') { // Site policy not agreed, trigger event. - CoreEvents.instance.trigger(CoreEventsProvider.SITE_POLICY_NOT_AGREED, {}, this.id); + CoreEvents.trigger(CoreEvents.SITE_POLICY_NOT_AGREED, {}, this.id); error.message = Translate.instance.instant('core.login.sitepolicynotagreederror'); throw new CoreWSError(error); @@ -1100,7 +1100,7 @@ export class CoreSite { try { await this.db.updateRecords(CoreSite.WS_CACHE_TABLE, { expirationTime: 0 }); } finally { - CoreEvents.instance.trigger(CoreEventsProvider.WS_CACHE_INVALIDATED, {}, this.getId()); + CoreEvents.trigger(CoreEvents.WS_CACHE_INVALIDATED, {}, this.getId()); } } diff --git a/src/app/components/loading/loading.ts b/src/app/components/loading/loading.ts index 6ce15ee24..31298fa19 100644 --- a/src/app/components/loading/loading.ts +++ b/src/app/components/loading/loading.ts @@ -14,7 +14,7 @@ import { Component, Input, OnInit, OnChanges, SimpleChange, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; -import { CoreEventLoadingChangedData, CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEventLoadingChangedData, CoreEvents } from '@singletons/events'; import { CoreUtils } from '@services/utils/utils'; import { Translate } from '@singletons/core.singletons'; @@ -109,7 +109,7 @@ export class CoreLoadingComponent implements OnInit, OnChanges, AfterViewInit { // Trigger the event after a timeout since the elements inside ngIf haven't been added to DOM yet. setTimeout(() => { - CoreEvents.instance.trigger(CoreEventsProvider.CORE_LOADING_CHANGED, { + CoreEvents.trigger(CoreEvents.CORE_LOADING_CHANGED, { loaded: !!this.hideUntil, uniqueId: this.uniqueId, }); diff --git a/src/app/core/login/pages/credentials/credentials.page.ts b/src/app/core/login/pages/credentials/credentials.page.ts index 6bb45942c..6e399917f 100644 --- a/src/app/core/login/pages/credentials/credentials.page.ts +++ b/src/app/core/login/pages/credentials/credentials.page.ts @@ -22,10 +22,10 @@ import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreUtils } from '@services/utils/utils'; import { CoreLoginHelper, CoreLoginHelperProvider } from '@core/login/services/helper'; -import CoreConfigConstants from '@app/config.json'; +import { CoreConstants } from '@/app/core/constants'; import { Translate } from '@singletons/core.singletons'; import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@/app/classes/site'; -import { CoreEvents, CoreEventsProvider } from '@/app/services/events'; +import { CoreEvents } from '@singletons/events'; /** * Page that displays a "splash screen" while the app is being initialized. @@ -66,10 +66,10 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { const canScanQR = CoreUtils.instance.canScanQR(); if (canScanQR) { - if (typeof CoreConfigConstants['displayqroncredentialscreen'] == 'undefined') { + if (typeof CoreConstants.CONFIG.displayqroncredentialscreen == 'undefined') { this.showScanQR = CoreLoginHelper.instance.isFixedUrlSet(); } else { - this.showScanQR = !!CoreConfigConstants['displayqroncredentialscreen']; + this.showScanQR = !!CoreConstants.CONFIG.displayqroncredentialscreen; } } else { this.showScanQR = false; @@ -83,7 +83,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { this.route.queryParams.subscribe(params => { this.siteUrl = params['siteUrl']; this.siteName = params['siteName'] || undefined; - this.logoUrl = !CoreConfigConstants.forceLoginLogo && params['logoUrl'] || undefined; + this.logoUrl = !CoreConstants.CONFIG.forceLoginLogo && params['logoUrl'] || undefined; this.siteConfig = params['siteConfig']; this.urlToOpen = params['urlToOpen']; @@ -160,7 +160,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { */ protected treatSiteConfig(): void { if (this.siteConfig) { - this.siteName = CoreConfigConstants.sitename ? CoreConfigConstants.sitename : this.siteConfig.sitename; + this.siteName = CoreConstants.CONFIG.sitename ?? this.siteConfig.sitename; this.logoUrl = CoreLoginHelper.instance.getLogoUrl(this.siteConfig); this.authInstructions = this.siteConfig.authinstructions || Translate.instance.instant('core.login.loginsteps'); @@ -172,7 +172,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { if (!this.eventThrown && !this.viewLeft) { this.eventThrown = true; - CoreEvents.instance.trigger(CoreEventsProvider.LOGIN_SITE_CHECKED, { config: this.siteConfig }); + CoreEvents.trigger(CoreEvents.LOGIN_SITE_CHECKED, { config: this.siteConfig }); } } else { this.authInstructions = undefined; @@ -330,7 +330,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy { */ ngOnDestroy(): void { this.viewLeft = true; - CoreEvents.instance.trigger(CoreEventsProvider.LOGIN_SITE_UNCHECKED, { config: this.siteConfig }, this.siteId); + CoreEvents.trigger(CoreEvents.LOGIN_SITE_UNCHECKED, { config: this.siteConfig }, this.siteId); } } diff --git a/src/app/core/login/pages/site/site.page.ts b/src/app/core/login/pages/site/site.page.ts index 783f77060..cfd05ec96 100644 --- a/src/app/core/login/pages/site/site.page.ts +++ b/src/app/core/login/pages/site/site.page.ts @@ -24,7 +24,7 @@ import { CoreDomUtils } from '@services/utils/dom'; import { CoreLoginHelper, CoreLoginHelperProvider } from '@core/login/services/helper'; import { CoreSite } from '@classes/site'; import { CoreError } from '@classes/errors/error'; -import CoreConfigConstants from '@app/config.json'; +import { CoreConstants } from '@/app/core/constants'; import { Translate } from '@singletons/core.singletons'; import { CoreUrl } from '@singletons/url'; import { CoreUrlUtils } from '@/app/services/utils/url'; @@ -63,9 +63,9 @@ export class CoreLoginSitePage implements OnInit { ) { let url = ''; - this.siteSelector = CoreConfigConstants.multisitesdisplay; + this.siteSelector = CoreConstants.CONFIG.multisitesdisplay; - const siteFinderSettings: Partial = CoreConfigConstants['sitefindersettings'] || {}; + const siteFinderSettings: Partial = CoreConstants.CONFIG.sitefindersettings || {}; this.siteFinderSettings = { displaysitename: true, displayimage: true, @@ -79,12 +79,12 @@ export class CoreLoginSitePage implements OnInit { // Load fixed sites if they're set. if (CoreLoginHelper.instance.hasSeveralFixedSites()) { url = this.initSiteSelector(); - } else if (CoreConfigConstants.enableonboarding && !CoreApp.instance.isIOS() && !CoreApp.instance.isMac()) { + } else if (CoreConstants.CONFIG.enableonboarding && !CoreApp.instance.isIOS() && !CoreApp.instance.isMac()) { this.initOnboarding(); } - this.showScanQR = CoreUtils.instance.canScanQR() && (typeof CoreConfigConstants['displayqronsitescreen'] == 'undefined' || - !!CoreConfigConstants['displayqronsitescreen']); + this.showScanQR = CoreUtils.instance.canScanQR() && (typeof CoreConstants.CONFIG.displayqronsitescreen == 'undefined' || + !!CoreConstants.CONFIG.displayqronsitescreen); this.siteForm = this.formBuilder.group({ siteUrl: [url, this.moodleUrlValidator()], diff --git a/src/app/core/login/services/helper.ts b/src/app/core/login/services/helper.ts index c01d9caf8..e510e487f 100644 --- a/src/app/core/login/services/helper.ts +++ b/src/app/core/login/services/helper.ts @@ -20,16 +20,15 @@ import { Md5 } from 'ts-md5/dist/md5'; import { CoreApp, CoreStoreConfig } from '@services/app'; import { CoreConfig } from '@services/config'; -import { CoreEvents, CoreEventSessionExpiredData, CoreEventsProvider } from '@services/events'; +import { CoreEvents, CoreEventSessionExpiredData } from '@singletons/events'; import { CoreSites, CoreLoginSiteInfo } from '@services/sites'; import { CoreWS, CoreWSExternalWarning } from '@services/ws'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUrlParams, CoreUrlUtils } from '@services/utils/url'; import { CoreUtils } from '@services/utils/utils'; -import CoreConfigConstants from '@app/config.json'; import { CoreConstants } from '@core/constants'; -import { CoreSite, CoreSiteConfig, CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site'; +import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site'; import { CoreError } from '@classes/errors/error'; import { CoreWSError } from '@classes/errors/wserror'; import { makeSingleton, Translate } from '@singletons/core.singletons'; @@ -60,7 +59,7 @@ export class CoreLoginHelperProvider { ) { this.logger = CoreLogger.getInstance('CoreLoginHelper'); - CoreEvents.instance.on(CoreEventsProvider.MAIN_MENU_OPEN, () => { + CoreEvents.on(CoreEvents.MAIN_MENU_OPEN, () => { /* If there is any page pending to be opened, do it now. Don't open pages stored more than 5 seconds ago, probably the function to open the page was called when it shouldn't. */ if (this.pageToLoad && Date.now() - this.pageToLoad.time < 5000) { @@ -304,7 +303,7 @@ export class CoreLoginHelperProvider { * @return Logo URL. */ getLogoUrl(config: CoreSitePublicConfigResponse): string | undefined { - return !CoreConfigConstants.forceLoginLogo && config ? (config.logourl || config.compactlogourl) : undefined; + return !CoreConstants.CONFIG.forceLoginLogo && config ? (config.logourl || config.compactlogourl) : undefined; } /** @@ -368,7 +367,7 @@ export class CoreLoginHelperProvider { * @return Fixed site or list of fixed sites. */ getFixedSites(): string | CoreLoginSiteInfo[] { - return CoreConfigConstants.siteurl; + return CoreConstants.CONFIG.siteurl; } /** @@ -448,6 +447,7 @@ export class CoreLoginHelperProvider { * @param params Params of the page. * @return Promise resolved when done. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars goToNoSitePage(navCtrl: NavController, page: string, params?: Params): Promise { // @todo return Promise.resolve(); @@ -463,6 +463,7 @@ export class CoreLoginHelperProvider { * @param url URL to open once the main menu is loaded. * @return Promise resolved when done. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars goToSiteInitialPage(navCtrl?: NavController, page?: string, params?: Params, options?: any, url?: string): Promise { // @todo return Promise.resolve(); @@ -489,8 +490,8 @@ export class CoreLoginHelperProvider { * @return Whether there are several fixed URLs. */ hasSeveralFixedSites(): boolean { - return !!(CoreConfigConstants.siteurl && Array.isArray(CoreConfigConstants.siteurl) && - CoreConfigConstants.siteurl.length > 1); + return !!(CoreConstants.CONFIG.siteurl && Array.isArray(CoreConstants.CONFIG.siteurl) && + CoreConstants.CONFIG.siteurl.length > 1); } /** @@ -528,11 +529,11 @@ export class CoreLoginHelperProvider { * @return Whether there is 1 fixed URL. */ isFixedUrlSet(): boolean { - if (Array.isArray(CoreConfigConstants.siteurl)) { - return CoreConfigConstants.siteurl.length == 1; + if (Array.isArray(CoreConstants.CONFIG.siteurl)) { + return CoreConstants.CONFIG.siteurl.length == 1; } - return !!CoreConfigConstants.siteurl; + return !!CoreConstants.CONFIG.siteurl; } /** @@ -560,7 +561,7 @@ export class CoreLoginHelperProvider { } if (site.isLoggedOut()) { - CoreEvents.instance.trigger(CoreEventsProvider.SESSION_EXPIRED, { + CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, { pageName, params, }, site.getId()); @@ -585,7 +586,7 @@ export class CoreLoginHelperProvider { const sites = this.getFixedSites(); return sites.some((site) => CoreUrl.sameDomainAndPath(siteUrl, site.url)); - } else if (CoreConfigConstants.multisitesdisplay == 'sitefinder' && CoreConfigConstants.onlyallowlistedsites) { + } else if (CoreConstants.CONFIG.multisitesdisplay == 'sitefinder' && CoreConstants.CONFIG.onlyallowlistedsites) { // Call the sites finder to validate the site. const result = await CoreSites.instance.findSites(siteUrl.replace(/^https?:\/\/|\.\w{2,3}\/?$/g, '')); @@ -629,6 +630,7 @@ export class CoreLoginHelperProvider { * @param siteId Site to load. * @return Promise resolved when done. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars protected loadSiteAndPage(page: string, params: Params, siteId: string): Promise { // @todo return Promise.resolve(); @@ -655,7 +657,7 @@ export class CoreLoginHelperProvider { if (page == CoreLoginHelperProvider.OPEN_COURSE) { // @todo Use the openCourse function. } else { - CoreEvents.instance.trigger(CoreEventsProvider.LOAD_PAGE_MAIN_MENU, { redirectPage: page, redirectParams: params }); + CoreEvents.trigger(CoreEvents.LOAD_PAGE_MAIN_MENU, { redirectPage: page, redirectParams: params }); } } @@ -669,6 +671,7 @@ export class CoreLoginHelperProvider { * @param url URL to open once the main menu is loaded. * @return Promise resolved when done. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars protected openMainMenu(navCtrl: NavController, page: string, params: Params, options?: any, url?: string): Promise { // @todo return Promise.resolve(); @@ -828,6 +831,7 @@ export class CoreLoginHelperProvider { * * @param siteId The site ID. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars passwordChangeForced(siteId: string): void { // @todo } @@ -852,14 +856,14 @@ export class CoreLoginHelperProvider { urlParams?: CoreUrlParams, ): string { - service = service || CoreConfigConstants.wsextservice; + service = service || CoreConstants.CONFIG.wsextservice; launchUrl = launchUrl || siteUrl + '/local/mobile/launch.php'; const passport = Math.random() * 1000; let loginUrl = launchUrl + '?service=' + service; loginUrl += '&passport=' + passport; - loginUrl += '&urlscheme=' + CoreConfigConstants.customurlscheme; + loginUrl += '&urlscheme=' + CoreConstants.CONFIG.customurlscheme; if (urlParams) { loginUrl = CoreUrlUtils.instance.addParamsToUrl(loginUrl, urlParams); @@ -886,6 +890,7 @@ export class CoreLoginHelperProvider { * @param siteId Site to load. If not defined, current site. * @return Promise resolved when done. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars async redirect(page: string, params?: Params, siteId?: string): Promise { // @todo } @@ -1033,7 +1038,7 @@ export class CoreLoginHelperProvider { */ shouldShowSSOConfirm(typeOfLogin: number): boolean { return !this.isSSOEmbeddedBrowser(typeOfLogin) && - (!CoreConfigConstants.skipssoconfirmation || String(CoreConfigConstants.skipssoconfirmation) === 'false'); + (!CoreConstants.CONFIG.skipssoconfirmation || String(CoreConstants.CONFIG.skipssoconfirmation) === 'false'); } /** @@ -1053,7 +1058,7 @@ export class CoreLoginHelperProvider { * @param message The warning message. */ protected showMoodleAppNoticeModal(message: string): void { - const storesConfig: CoreStoreConfig = CoreConfigConstants.appstores; + const storesConfig: CoreStoreConfig = CoreConstants.CONFIG.appstores; storesConfig.desktop = 'https://download.moodle.org/desktop/'; storesConfig.mobile = 'https://download.moodle.org/mobile/'; storesConfig.default = 'https://download.moodle.org/mobile/'; diff --git a/src/app/core/login/tests/init.page.test.ts b/src/app/core/login/tests/init.page.test.ts index fad3fed51..f5ddfce3c 100644 --- a/src/app/core/login/tests/init.page.test.ts +++ b/src/app/core/login/tests/init.page.test.ts @@ -38,13 +38,13 @@ describe('CoreLogin Init Page', () => { expect(fixture.nativeElement.querySelector('ion-spinner')).toBeTruthy(); }); - it('navigates to site page after loading', async () => { + it('navigates to sites page after loading', async () => { const fixture = createComponent(CoreLoginInitPage); fixture.componentInstance.ngOnInit(); await CoreInit.instance.ready(); - expect(mocks.router.navigate).toHaveBeenCalledWith(['/login/site']); + expect(mocks.navController.navigateRoot).toHaveBeenCalledWith('/login/sites'); }); }); diff --git a/src/app/directives/format-text.ts b/src/app/directives/format-text.ts index e12d6479d..56ac42cee 100644 --- a/src/app/directives/format-text.ts +++ b/src/app/directives/format-text.ts @@ -15,7 +15,7 @@ import { Directive, ElementRef, Input, Output, EventEmitter, OnChanges, SimpleChange, Optional } from '@angular/core'; import { NavController, IonContent } from '@ionic/angular'; -import { CoreEventLoadingChangedData, CoreEventObserver, CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEventLoadingChangedData, CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreSites } from '@services/sites'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreIframeUtils, CoreIframeUtilsProvider } from '@services/utils/iframe'; @@ -46,9 +46,6 @@ export class CoreFormatTextDirective implements OnChanges { @Input() adaptImg?: boolean | string = true; // Whether to adapt images to screen width. @Input() clean?: boolean | string; // Whether all the HTML tags should be removed. @Input() singleLine?: boolean | string; // Whether new lines should be removed (all text in single line). Only if clean=true. - @Input() maxHeight?: number; // Max height in pixels to render the content box. It should be 50 at least to make sense. - // Using this parameter will force display: block to calculate height better. - // If you want to avoid this use class="inline" at the same time to use display: inline-block. @Input() fullOnClick?: boolean | string; // Whether it should open a new page with the full contents on click. @Input() fullTitle?: string; // Title to use in full view. Defaults to "Description". @Input() highlight?: string; // Text to highlight. @@ -57,6 +54,14 @@ export class CoreFormatTextDirective implements OnChanges { @Input() contextInstanceId?: number; // The instance ID related to the context. @Input() courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters. @Input() wsNotFiltered?: boolean | string; // If true it means the WS didn't filter the text for some reason. + + /** + * Max height in pixels to render the content box. It should be 50 at least to make sense. + * Using this parameter will force display: block to calculate height better. + * If you want to avoid this use class="inline" at the same time to use display: inline-block. + */ + @Input() maxHeight?: number; + @Output() afterRender: EventEmitter; // Called when the data is rendered. protected element: HTMLElement; @@ -350,7 +355,7 @@ export class CoreFormatTextDirective implements OnChanges { if (!this.loadingChangedListener) { // Recalculate the height if a parent core-loading displays the content. this.loadingChangedListener = - CoreEvents.instance.on(CoreEventsProvider.CORE_LOADING_CHANGED, (data: CoreEventLoadingChangedData) => { + CoreEvents.on(CoreEvents.CORE_LOADING_CHANGED, (data: CoreEventLoadingChangedData) => { if (data.loaded && CoreDomUtils.instance.closest(this.element.parentElement, '#' + data.uniqueId)) { // The format-text is inside the loading, re-calculate the height. this.calculateHeight(); diff --git a/src/app/services/app.ts b/src/app/services/app.ts index 8d52f1267..2862dc336 100644 --- a/src/app/services/app.ts +++ b/src/app/services/app.ts @@ -17,7 +17,7 @@ import { Params } from '@angular/router'; import { Connection } from '@ionic-native/network/ngx'; import { CoreDB } from '@services/db'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb'; import { CoreConstants } from '@core/constants'; @@ -86,7 +86,7 @@ export class CoreAppProvider { this.setKeyboardShown(true); // Error on iOS calculating size. // More info: https://github.com/ionic-team/ionic-plugin-keyboard/issues/276 . - CoreEvents.instance.trigger(CoreEventsProvider.KEYBOARD_CHANGE, data.keyboardHeight); + CoreEvents.trigger(CoreEvents.KEYBOARD_CHANGE, data.keyboardHeight); }); }); Keyboard.instance.onKeyboardHide().subscribe(() => { @@ -94,7 +94,7 @@ export class CoreAppProvider { zone.run(() => { document.body.classList.remove('keyboard-is-open'); this.setKeyboardShown(false); - CoreEvents.instance.trigger(CoreEventsProvider.KEYBOARD_CHANGE, 0); + CoreEvents.trigger(CoreEvents.KEYBOARD_CHANGE, 0); }); }); Keyboard.instance.onKeyboardWillShow().subscribe(() => { @@ -481,7 +481,7 @@ export class CoreAppProvider { setMainMenuOpen(id: number, open: boolean): void { if (open) { this.mainMenuOpen = id; - CoreEvents.instance.trigger(CoreEventsProvider.MAIN_MENU_OPEN); + CoreEvents.trigger(CoreEvents.MAIN_MENU_OPEN); } else if (this.mainMenuOpen == id) { delete this.mainMenuOpen; } diff --git a/src/app/services/file-helper.ts b/src/app/services/file-helper.ts index ae7842ebd..336c6cc91 100644 --- a/src/app/services/file-helper.ts +++ b/src/app/services/file-helper.ts @@ -174,7 +174,15 @@ export class CoreFileHelperProvider { } else { // Outdated but offline, so we return the local URL. return CoreFilepool.instance.getUrlByUrl( - siteId, fileUrl, component, componentId, timemodified, false, false, file); + siteId, + fileUrl, + component, + componentId, + timemodified, + false, + false, + file, + ); } } @@ -220,8 +228,17 @@ export class CoreFileHelperProvider { } try { - return await CoreFilepool.instance.downloadUrl(siteId, fileUrl, false, component, componentId, timemodified, - onProgress, undefined, file); + return await CoreFilepool.instance.downloadUrl( + siteId, + fileUrl, + false, + component, + componentId, + timemodified, + onProgress, + undefined, + file, + ); } catch (error) { // Download failed, check the state again to see if the file was downloaded before. const state = await CoreFilepool.instance.getFileStateByUrl(siteId, fileUrl, timemodified); @@ -405,4 +422,3 @@ export class CoreFileHelperProvider { export class CoreFileHelper extends makeSingleton(CoreFileHelperProvider) {} export type CoreFileHelperOnProgress = (event?: ProgressEvent | { calculating: true }) => void; - diff --git a/src/app/services/filepool.ts b/src/app/services/filepool.ts index dd602a123..f1b2ec9f2 100644 --- a/src/app/services/filepool.ts +++ b/src/app/services/filepool.ts @@ -16,7 +16,7 @@ import { Injectable } from '@angular/core'; import { Md5 } from 'ts-md5/dist/md5'; import { CoreApp, CoreAppSchema } from '@services/app'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreFile } from '@services/file'; import { CoreInit } from '@services/init'; import { CorePluginFile } from '@services/plugin-file-delegate'; @@ -2455,7 +2455,7 @@ export class CoreFilepoolProvider { componentId: link.componentId, }, eventData); - CoreEvents.instance.trigger(CoreEventsProvider.COMPONENT_FILE_ACTION, data, siteId); + CoreEvents.trigger(CoreEvents.COMPONENT_FILE_ACTION, data, siteId); }); } @@ -2472,7 +2472,7 @@ export class CoreFilepoolProvider { action: CoreFilepoolFileActions.DELETED, }; - CoreEvents.instance.trigger(this.getFileEventName(siteId, fileId), data); + CoreEvents.trigger(this.getFileEventName(siteId, fileId), data); this.notifyFileActionToComponents(siteId, data, links); } @@ -2490,7 +2490,7 @@ export class CoreFilepoolProvider { success: true, }; - CoreEvents.instance.trigger(this.getFileEventName(siteId, fileId), data); + CoreEvents.trigger(this.getFileEventName(siteId, fileId), data); this.notifyFileActionToComponents(siteId, data, links); } @@ -2508,7 +2508,7 @@ export class CoreFilepoolProvider { success: false, }; - CoreEvents.instance.trigger(this.getFileEventName(siteId, fileId), data); + CoreEvents.trigger(this.getFileEventName(siteId, fileId), data); this.notifyFileActionToComponents(siteId, data, links); } @@ -2525,7 +2525,7 @@ export class CoreFilepoolProvider { action: CoreFilepoolFileActions.DOWNLOADING, }; - CoreEvents.instance.trigger(this.getFileEventName(siteId, fileId), data); + CoreEvents.trigger(this.getFileEventName(siteId, fileId), data); this.notifyFileActionToComponents(siteId, data, links); } @@ -2542,7 +2542,7 @@ export class CoreFilepoolProvider { action: CoreFilepoolFileActions.OUTDATED, }; - CoreEvents.instance.trigger(this.getFileEventName(siteId, fileId), data); + CoreEvents.trigger(this.getFileEventName(siteId, fileId), data); this.notifyFileActionToComponents(siteId, data, links); } @@ -3121,7 +3121,7 @@ export class CoreFilepoolProvider { status, }; - CoreEvents.instance.trigger(CoreEventsProvider.PACKAGE_STATUS_CHANGED, data, siteId); + CoreEvents.trigger(CoreEvents.PACKAGE_STATUS_CHANGED, data, siteId); } /** diff --git a/src/app/services/local-notifications.ts b/src/app/services/local-notifications.ts index 6db15b711..2c38641f7 100644 --- a/src/app/services/local-notifications.ts +++ b/src/app/services/local-notifications.ts @@ -18,7 +18,7 @@ import { ILocalNotification } from '@ionic-native/local-notifications'; import { CoreApp, CoreAppSchema } from '@services/app'; import { CoreConfig } from '@services/config'; -import { CoreEventObserver, CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreTextUtils } from '@services/utils/text'; import { CoreUtils, PromiseDefer } from '@services/utils/utils'; import { SQLiteDB } from '@classes/sqlitedb'; @@ -159,7 +159,7 @@ export class CoreLocalNotificationsProvider { this.createDefaultChannel(); }); - CoreEvents.instance.on(CoreEventsProvider.SITE_DELETED, (site: CoreSite) => { + CoreEvents.on(CoreEvents.SITE_DELETED, (site: CoreSite) => { if (site) { this.cancelSiteNotifications(site.id!); } diff --git a/src/app/services/sites.ts b/src/app/services/sites.ts index d589c941b..ed32a9dbc 100644 --- a/src/app/services/sites.ts +++ b/src/app/services/sites.ts @@ -17,7 +17,7 @@ import { Md5 } from 'ts-md5/dist/md5'; import { timeout } from 'rxjs/operators'; import { CoreApp, CoreAppSchema, CoreStoreConfig } from '@services/app'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreWS } from '@services/ws'; import { CoreDomUtils } from '@services/utils/dom'; import { CoreTextUtils } from '@services/utils/text'; @@ -660,7 +660,7 @@ export class CoreSitesProvider { this.login(siteId); } - CoreEvents.instance.trigger(CoreEventsProvider.SITE_ADDED, info, siteId); + CoreEvents.trigger(CoreEvents.SITE_ADDED, info, siteId); return siteId; } catch (error) { @@ -966,7 +966,7 @@ export class CoreSitesProvider { if (site.isLoggedOut()) { // Logged out, trigger session expired event and stop. - CoreEvents.instance.trigger(CoreEventsProvider.SESSION_EXPIRED, { + CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, { pageName, params, }, site.getId()); @@ -979,7 +979,7 @@ export class CoreSitesProvider { await site.checkIfLocalMobileInstalledAndNotUsed(); // Local mobile was added. Throw invalid session to force reconnect and create a new token. - CoreEvents.instance.trigger(CoreEventsProvider.SESSION_EXPIRED, { + CoreEvents.trigger(CoreEvents.SESSION_EXPIRED, { pageName, params, }, siteId); @@ -1093,7 +1093,7 @@ export class CoreSitesProvider { // Site deleted from sites list, now delete the folder. await site.deleteFolder(); - CoreEvents.instance.trigger(CoreEventsProvider.SITE_DELETED, site, siteId); + CoreEvents.trigger(CoreEvents.SITE_DELETED, site, siteId); } /** @@ -1301,7 +1301,7 @@ export class CoreSitesProvider { await this.appDB.insertRecord(CURRENT_SITE_TABLE, entry); - CoreEvents.instance.trigger(CoreEventsProvider.LOGIN, {}, siteId); + CoreEvents.trigger(CoreEvents.LOGIN, {}, siteId); } /** @@ -1331,7 +1331,7 @@ export class CoreSitesProvider { try { await Promise.all(promises); } finally { - CoreEvents.instance.trigger(CoreEventsProvider.LOGOUT, {}, siteId); + CoreEvents.trigger(CoreEvents.LOGOUT, {}, siteId); } } @@ -1473,7 +1473,7 @@ export class CoreSitesProvider { try { await this.appDB.updateRecords(SITES_TABLE, newValues, { id: siteId }); } finally { - CoreEvents.instance.trigger(CoreEventsProvider.SITE_UPDATED, info, siteId); + CoreEvents.trigger(CoreEvents.SITE_UPDATED, info, siteId); } } catch (error) { // Ignore that we cannot fetch site info. Probably the auth token is invalid. diff --git a/src/app/services/sync.ts b/src/app/services/sync.ts index fae730556..2246f5cbe 100644 --- a/src/app/services/sync.ts +++ b/src/app/services/sync.ts @@ -13,7 +13,7 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreSites, CoreSiteSchema } from '@services/sites'; import { makeSingleton } from '@singletons/core.singletons'; @@ -64,7 +64,7 @@ export class CoreSyncProvider { CoreSites.instance.registerSiteSchema(this.siteSchema); // Unblock all blocks on logout. - CoreEvents.instance.on(CoreEventsProvider.LOGOUT, (data: {siteId: string}) => { + CoreEvents.on(CoreEvents.LOGOUT, (data: {siteId: string}) => { this.clearAllBlocks(data.siteId); }); } diff --git a/src/app/services/utils/dom.ts b/src/app/services/utils/dom.ts index b2e617bb6..5dfa487d2 100644 --- a/src/app/services/utils/dom.ts +++ b/src/app/services/utils/dom.ts @@ -20,7 +20,7 @@ import { Md5 } from 'ts-md5'; import { CoreApp } from '@services/app'; import { CoreConfig } from '@services/config'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreFile } from '@services/file'; import { CoreWSExternalWarning } from '@services/ws'; import { CoreTextUtils, CoreTextErrorObject } from '@services/utils/text'; @@ -86,7 +86,7 @@ export class CoreDomUtilsProvider { if (!element) { return null; } - + // Try to use closest if the browser supports it. if (typeof element.closest == 'function') { return element.closest(selector); @@ -363,8 +363,8 @@ export class CoreDomUtilsProvider { fixHtml(html: string): string { this.template.innerHTML = html; - const attrNameRegExp = /[^\x00-\x20\x7F-\x9F"'>\/=]+/; - + // eslint-disable-next-line no-control-regex + const attrNameRegExp = /[^\x00-\x20\x7F-\x9F"'>/=]+/; const fixElement = (element: Element): void => { // Remove attributes with an invalid name. Array.from(element.attributes).forEach((attr) => { @@ -1547,6 +1547,7 @@ export class CoreDomUtilsProvider { * @param placeholder Placeholder of the input element if any. * @return Promise resolved when modal presented. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars showTextareaPrompt(title: string, message: string, buttons: (string | any)[], placeholder?: string): Promise { // @todo return Promise.resolve(); @@ -1661,6 +1662,7 @@ export class CoreDomUtilsProvider { * @param componentId An ID to use in conjunction with the component. * @param fullScreen Whether the modal should be full screen. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars viewImage(image: string, title?: string | null, component?: string, componentId?: string | number, fullScreen?: boolean): void { // @todo } @@ -1721,7 +1723,7 @@ export class CoreDomUtilsProvider { return; } - CoreEvents.instance.trigger(CoreEventsProvider.FORM_ACTION, { + CoreEvents.trigger(CoreEvents.FORM_ACTION, { action: 'cancel', form: formRef.nativeElement, }, siteId); @@ -1739,7 +1741,7 @@ export class CoreDomUtilsProvider { return; } - CoreEvents.instance.trigger(CoreEventsProvider.FORM_ACTION, { + CoreEvents.trigger(CoreEvents.FORM_ACTION, { action: 'submit', form: formRef.nativeElement, online: !!online, diff --git a/src/app/services/utils/utils.ts b/src/app/services/utils/utils.ts index eb77397e0..84f793f3e 100644 --- a/src/app/services/utils/utils.ts +++ b/src/app/services/utils/utils.ts @@ -18,7 +18,7 @@ import { FileEntry } from '@ionic-native/file'; import { Subscription } from 'rxjs'; import { CoreApp } from '@services/app'; -import { CoreEvents, CoreEventsProvider } from '@services/events'; +import { CoreEvents } from '@singletons/events'; import { CoreFile } from '@services/file'; import { CoreLang } from '@services/lang'; import { CoreWS, CoreWSExternalFile } from '@services/ws'; @@ -973,7 +973,7 @@ export class CoreUtilsProvider { loadStartUrls.shift(); } - CoreEvents.instance.trigger(CoreEventsProvider.IAB_LOAD_START, event); + CoreEvents.trigger(CoreEvents.IAB_LOAD_START, event); }); }); @@ -984,7 +984,7 @@ export class CoreUtilsProvider { this.zone.run(() => { if (loadStartUrls.indexOf(event.url) == -1) { // The URL was stopped but not started, probably a custom URL scheme. - CoreEvents.instance.trigger(CoreEventsProvider.IAB_LOAD_START, event); + CoreEvents.trigger(CoreEvents.IAB_LOAD_START, event); } }); }); @@ -996,7 +996,7 @@ export class CoreUtilsProvider { loadStartSubscription.unsubscribe(); loadStopSubscription && loadStopSubscription.unsubscribe(); exitSubscription.unsubscribe(); - CoreEvents.instance.trigger(CoreEventsProvider.IAB_EXIT, event); + CoreEvents.trigger(CoreEvents.IAB_EXIT, event); }); }); } @@ -1491,7 +1491,9 @@ export class CoreUtilsProvider { * @param title Title of the modal. Defaults to "QR reader". * @return Promise resolved with the captured text or undefined if cancelled or error. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars scanQR(title?: string): Promise { + // eslint-disable-next-line @typescript-eslint/no-unused-vars return new Promise((resolve, reject): void => { // @todo }); diff --git a/src/app/services/events.ts b/src/app/singletons/events.ts similarity index 89% rename from src/app/services/events.ts rename to src/app/singletons/events.ts index 195fde5a9..51152d929 100644 --- a/src/app/services/events.ts +++ b/src/app/singletons/events.ts @@ -12,12 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Injectable } from '@angular/core'; import { Params } from '@angular/router'; import { Subject } from 'rxjs'; import { CoreLogger } from '@singletons/logger'; -import { makeSingleton } from '@singletons/core.singletons'; /** * Observer instance to stop listening to an event. @@ -32,8 +30,7 @@ export interface CoreEventObserver { /* * Service to send and listen to events. */ -@Injectable() -export class CoreEventsProvider { +export class CoreEvents { static readonly SESSION_EXPIRED = 'session_expired'; static readonly PASSWORD_CHANGE_FORCED = 'password_change_forced'; @@ -72,13 +69,9 @@ export class CoreEventsProvider { static readonly FORM_ACTION = 'form_action'; static readonly ACTIVITY_DATA_SENT = 'activity_data_sent'; - protected logger: CoreLogger; - protected observables: { [eventName: string]: Subject } = {}; - protected uniqueEvents: { [eventName: string]: {data: unknown} } = {}; - - constructor() { - this.logger = CoreLogger.getInstance('CoreEventsProvider'); - } + protected static logger = CoreLogger.getInstance('CoreEvents'); + protected static observables: { [eventName: string]: Subject } = {}; + protected static uniqueEvents: { [eventName: string]: {data: unknown} } = {}; /** * Listen for a certain event. To stop listening to the event: @@ -91,7 +84,7 @@ export class CoreEventsProvider { * @param siteId Site where to trigger the event. Undefined won't check the site. * @return Observer to stop listening. */ - on(eventName: string, callBack: (value: unknown) => void, siteId?: string): CoreEventObserver { + static on(eventName: string, callBack: (value: unknown) => void, siteId?: string): CoreEventObserver { // If it's a unique event and has been triggered already, call the callBack. // We don't need to create an observer because the event won't be triggered again. if (this.uniqueEvents[eventName]) { @@ -138,7 +131,7 @@ export class CoreEventsProvider { * @param siteId Site where to trigger the event. Undefined won't check the site. * @return Observer to stop listening. */ - onMultiple(eventNames: string[], callBack: (value: unknown) => void, siteId?: string): CoreEventObserver { + static onMultiple(eventNames: string[], callBack: (value: unknown) => void, siteId?: string): CoreEventObserver { const observers = eventNames.map((name) => this.on(name, callBack, siteId)); // Create and return a CoreEventObserver. @@ -158,7 +151,7 @@ export class CoreEventsProvider { * @param data Data to pass to the observers. * @param siteId Site where to trigger the event. Undefined means no Site. */ - trigger(eventName: string, data?: unknown, siteId?: string): void { + static trigger(eventName: string, data?: unknown, siteId?: string): void { this.logger.debug(`Event '${eventName}' triggered.`); if (this.observables[eventName]) { if (siteId) { @@ -175,7 +168,7 @@ export class CoreEventsProvider { * @param data Data to pass to the observers. * @param siteId Site where to trigger the event. Undefined means no Site. */ - triggerUnique(eventName: string, data: unknown, siteId?: string): void { + static triggerUnique(eventName: string, data: unknown, siteId?: string): void { if (this.uniqueEvents[eventName]) { this.logger.debug(`Unique event '${eventName}' ignored because it was already triggered.`); } else { @@ -199,8 +192,6 @@ export class CoreEventsProvider { } -export class CoreEvents extends makeSingleton(CoreEventsProvider) {} - /** * Data passed to SESSION_EXPIRED event. */ diff --git a/src/app/singletons/logger.ts b/src/app/singletons/logger.ts index 0c49642f0..fab03132b 100644 --- a/src/app/singletons/logger.ts +++ b/src/app/singletons/logger.ts @@ -56,10 +56,12 @@ export class CoreLogger { * @return Instance. */ static getInstance(className: string): CoreLogger { - // Disable log on production. - if (CoreConstants.BUILD.isProduction) { - // eslint-disable-next-line no-console - console.warn('Log is disabled in production app'); + // Disable log on production and testing. + if (CoreConstants.BUILD.isProduction || CoreConstants.BUILD.isTesting) { + if (CoreConstants.BUILD.isProduction) { + // eslint-disable-next-line no-console + console.warn('Log is disabled in production app'); + } // eslint-disable-next-line @typescript-eslint/no-empty-function const muted = () => {}; diff --git a/src/tests/utils.ts b/src/tests/utils.ts index 6747a41df..9adc3bdd6 100644 --- a/src/tests/utils.ts +++ b/src/tests/utils.ts @@ -14,7 +14,7 @@ import { CUSTOM_ELEMENTS_SCHEMA, Type } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { Router } from '@angular/router'; +import { NavController } from '@ionic/angular'; import { CoreSingletonClass } from '@app/classes/singletons-factory'; export interface ComponentTestMocks { @@ -22,7 +22,7 @@ export interface ComponentTestMocks { }; export interface PageTestMocks extends ComponentTestMocks { - router: Router; + navController: NavController; } export function createMock(methods: string[] = [], properties: Record = {}): T { @@ -57,12 +57,12 @@ export async function prepareComponentTest(component: Type, providers: unk export async function preparePageTest(component: Type, providers: unknown[] = []): Promise { const mocks = { - router: createMock(['navigate']), + navController: createMock(['navigateRoot']), }; const componentTestMocks = await prepareComponentTest(component, [ ...providers, - { provide: Router, useValue: mocks.router }, + { provide: NavController, useValue: mocks.navController }, ]); return { diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 2e42b5cb4..26369b55c 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -38,7 +38,7 @@ declare global { languages: Record; wsservice: string; wsextservice: string; - demo_sites: Record>; + demo_sites: Record; font_sizes: number[]; customurlscheme: string; siteurl: string; @@ -64,11 +64,14 @@ declare global { forceLoginLogo: boolean; ioswebviewscheme: string; appstores: Record; + displayqroncredentialscreen?: boolean; + displayqronsitescreen?: boolean; }; BUILD: { - environment: string; isProduction: boolean; + isTesting: boolean; + isDevelopment: boolean; lastCommitHash: string; compilationTime: number; };