diff --git a/src/core/directives/tests/format-text.test.ts b/src/core/directives/tests/format-text.test.ts index 48cb3ca44..0face19cd 100644 --- a/src/core/directives/tests/format-text.test.ts +++ b/src/core/directives/tests/format-text.test.ts @@ -26,7 +26,6 @@ import { CoreSites } from '@services/sites'; import { CoreUtils } from '@services/utils/utils'; import { mock, mockSingleton, RenderConfig, renderTemplate, renderWrapperComponent } from '@/testing/utils'; -import { CoreDB } from '@services/db'; describe('CoreFormatTextDirective', () => { @@ -122,12 +121,7 @@ describe('CoreFormatTextDirective', () => { it('should use external-content directive on images', async () => { // Arrange - mockSingleton(CoreDB, { - getDB: () => undefined, - }); - - let site = new CoreSite('42', 'https://mysite.com', 'token'); - site = mock(site, { + const site = mock(new CoreSite('42', 'https://mysite.com', 'token'), { canDownloadFiles: () => true, }); diff --git a/src/core/features/sitehome/services/handlers/index-link.ts b/src/core/features/sitehome/services/handlers/index-link.ts index 58e7cc299..ac0770424 100644 --- a/src/core/features/sitehome/services/handlers/index-link.ts +++ b/src/core/features/sitehome/services/handlers/index-link.ts @@ -57,7 +57,7 @@ export class CoreSiteHomeIndexLinkHandlerService extends CoreContentLinksHandler const courseId = parseInt(params.id, 10); if (!courseId) { - return url.includes('index.php'); + return url.includes('index.php') || url.includes('?redirect=0'); } const site = await CoreSites.getSite(siteId); diff --git a/src/core/features/sitehome/tests/links.test.ts b/src/core/features/sitehome/tests/links.test.ts new file mode 100644 index 000000000..5c515fb65 --- /dev/null +++ b/src/core/features/sitehome/tests/links.test.ts @@ -0,0 +1,48 @@ +// (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 { mock, mockSingleton } from '@/testing/utils'; +import { CoreSite } from '@classes/site'; +import { CoreContentLinksDelegate } from '@features/contentlinks/services/contentlinks-delegate'; +import { CoreSiteHomeIndexLinkHandlerService } from '@features/sitehome/services/handlers/index-link'; +import { CoreNavigator } from '@services/navigator'; +import { CoreSites } from '@services/sites'; +import { CoreCustomURLSchemes } from '@services/urlschemes'; + +describe('Site Home link handlers', () => { + + it('Handles links ending with /?redirect=0', async () => { + // Arrange. + const siteUrl = 'https://school.moodledemo.net'; + const siteId = CoreSites.createSiteID(siteUrl, 'student'); + + mockSingleton(CoreSites, mock({ + isStoredRootURL: () => Promise.resolve({ siteIds: [siteId] }), + getSite: () => Promise.resolve(new CoreSite(siteId, siteUrl)), + getSiteIdsFromUrl: () => Promise.resolve([siteId]), + })); + + CoreContentLinksDelegate.registerHandler(new CoreSiteHomeIndexLinkHandlerService()); + + // Act. + await CoreCustomURLSchemes.handleCustomURL(`moodlemobile://link=${siteUrl}/?redirect=0`); + + // Assert. + expect(CoreNavigator.navigateToSitePath).toHaveBeenCalledWith('/home/site', { + siteId, + preferCurrentTab: false, + }); + }); + +}); diff --git a/src/testing/utils.ts b/src/testing/utils.ts index 18da2b091..38b091cb8 100644 --- a/src/testing/utils.ts +++ b/src/testing/utils.ts @@ -19,13 +19,16 @@ import { Observable, Subject } from 'rxjs'; import { sep } from 'path'; import { CORE_SITE_SCHEMAS } from '@services/sites'; -import { CoreSingletonProxy, Translate } from '@singletons'; +import { ApplicationInit, CoreSingletonProxy, Translate } from '@singletons'; import { CoreTextUtilsProvider } from '@services/utils/text'; import { TranslatePipeStub } from './stubs/pipes/translate'; import { CoreExternalContentDirectiveStub } from './stubs/directives/core-external-content'; import { CoreNetwork } from '@services/network'; import { CorePlatform } from '@services/platform'; +import { CoreDB } from '@services/db'; +import { CoreNavigator } from '@services/navigator'; +import { CoreDomUtils } from '@services/utils/dom'; abstract class WrapperComponent { @@ -38,13 +41,21 @@ type ServiceInjectionToken = AbstractType | Type | string; let testBedInitialized = false; const textUtils = new CoreTextUtilsProvider(); const DEFAULT_SERVICE_SINGLETON_MOCKS: [CoreSingletonProxy, Record][] = [ + [Translate, mock({ instant: key => key })], + [CoreDB, mock({ getDB: () => mock() })], + [CoreNetwork, mock({ onChange: () => new Observable() })], + [CoreDomUtils, mock({ showModalLoading: () => Promise.resolve(mock({}, ['dismiss'])) })], + [CoreNavigator, mock({ navigateToSitePath: () => Promise.resolve(true) })], + [ApplicationInit, mock({ + donePromise: Promise.resolve(), + runInitializers: () => Promise.resolve(), + })], [CorePlatform, mock({ is: () => false, isMobile: () => false, ready: () => Promise.resolve(), resume: new Subject(), })], - [CoreNetwork, { onChange: () => new Observable() }], ]; async function renderAngularComponent(component: Type, config: RenderConfig): Promise> {