Merge pull request #2791 from NoelDeMartin/MOBILE-3674
MOBILE-3674: Make url comparison case insensitive
This commit is contained in:
		
						commit
						a1a7866021
					
				| @ -22,6 +22,7 @@ import { Network, Platform, NgZone } from '@singletons'; | ||||
| 
 | ||||
| import { mockSingleton, renderComponent } from '@/testing/utils'; | ||||
| import { CoreNavigator, CoreNavigatorService } from '@services/navigator'; | ||||
| import { CoreSitePlugins } from '@features/siteplugins/services/siteplugins'; | ||||
| 
 | ||||
| describe('AppComponent', () => { | ||||
| 
 | ||||
| @ -33,6 +34,7 @@ describe('AppComponent', () => { | ||||
|         mockSingleton(Network, { onChange: () => new Observable() }); | ||||
|         mockSingleton(Platform, { ready: () => Promise.resolve(), resume: new Subject<void>() }); | ||||
|         mockSingleton(NgZone, { run: jest.fn() }); | ||||
|         mockSingleton(CoreSitePlugins, { hasSitePluginsLoaded: false }); | ||||
| 
 | ||||
|         navigator = mockSingleton(CoreNavigator, ['navigate']); | ||||
|         langProvider = mockSingleton(CoreLang, ['clearCustomStrings']); | ||||
|  | ||||
| @ -78,6 +78,7 @@ import { Md5 } from 'ts-md5/dist/md5'; | ||||
| // Import core classes that can be useful for site plugins.
 | ||||
| import { CoreSyncBaseProvider } from '@classes/base-sync'; | ||||
| import { CoreArray } from '@singletons/array'; | ||||
| import { CoreText } from '@singletons/text'; | ||||
| import { CoreUrl } from '@singletons/url'; | ||||
| import { CoreWindow } from '@singletons/window'; | ||||
| import { CoreCache } from '@classes/cache'; | ||||
| @ -340,6 +341,7 @@ export class CoreCompileProvider { | ||||
|         instance['Md5'] = Md5; | ||||
|         instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; | ||||
|         instance['CoreArray'] = CoreArray; | ||||
|         instance['CoreText'] = CoreText; | ||||
|         instance['CoreUrl'] = CoreUrl; | ||||
|         instance['CoreWindow'] = CoreWindow; | ||||
|         instance['CoreCache'] = CoreCache; | ||||
|  | ||||
| @ -52,6 +52,7 @@ import { CoreArray } from '../singletons/array'; | ||||
| import { CoreNetworkError } from '@classes/errors/network-error'; | ||||
| import { CoreNavigationOptions } from './navigator'; | ||||
| import { CoreSitesFactory } from './sites-factory'; | ||||
| import { CoreText } from '@singletons/text'; | ||||
| 
 | ||||
| export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS'); | ||||
| 
 | ||||
| @ -1635,10 +1636,10 @@ export class CoreSitesProvider { | ||||
|         // If more than one site is returned it usually means there are different users stored. Use any of them.
 | ||||
|         const site = await this.getSite(siteIds[0]); | ||||
| 
 | ||||
|         const siteUrl = CoreTextUtils.removeEndingSlash( | ||||
|         const siteUrl = CoreText.removeEndingSlash( | ||||
|             CoreUrlUtils.removeProtocolAndWWW(site.getURL()), | ||||
|         ); | ||||
|         const treatedUrl = CoreTextUtils.removeEndingSlash(CoreUrlUtils.removeProtocolAndWWW(url)); | ||||
|         const treatedUrl = CoreText.removeEndingSlash(CoreUrlUtils.removeProtocolAndWWW(url)); | ||||
| 
 | ||||
|         if (siteUrl == treatedUrl) { | ||||
|             result.site = site; | ||||
|  | ||||
| @ -25,6 +25,7 @@ import { Locutus } from '@singletons/locutus'; | ||||
| import { CoreViewerTextComponent } from '@features/viewer/components/text/text'; | ||||
| import { CoreFileHelper } from '@services/file-helper'; | ||||
| import { CoreDomUtils } from './dom'; | ||||
| import { CoreText } from '@singletons/text'; | ||||
| 
 | ||||
| /** | ||||
|  * Different type of errors the app can treat. | ||||
| @ -710,21 +711,10 @@ export class CoreTextUtilsProvider { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove ending slash from a path or URL. | ||||
|      * | ||||
|      * @param text Text to treat. | ||||
|      * @return Treated text. | ||||
|      * @deprecated Use CoreText instead. | ||||
|      */ | ||||
|     removeEndingSlash(text?: string): string { | ||||
|         if (!text) { | ||||
|             return ''; | ||||
|         } | ||||
| 
 | ||||
|         if (text.slice(-1) == '/') { | ||||
|             return text.substr(0, text.length - 1); | ||||
|         } | ||||
| 
 | ||||
|         return text; | ||||
|         return CoreText.removeEndingSlash(text); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
							
								
								
									
										59
									
								
								src/core/singletons/tests/url.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/core/singletons/tests/url.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| // (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 { CoreUrl } from '@singletons/url'; | ||||
| 
 | ||||
| describe('CoreUrl singleton', () => { | ||||
| 
 | ||||
|     it('parses standard urls', () => { | ||||
|         expect(CoreUrl.parse('https://my.subdomain.com/path/?query=search#hash')).toEqual({ | ||||
|             protocol: 'https', | ||||
|             domain: 'my.subdomain.com', | ||||
|             path: '/path/', | ||||
|             query: 'query=search', | ||||
|             fragment: 'hash', | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     it('parses domains without TLD', () => { | ||||
|         expect(CoreUrl.parse('ftp://localhost/nested/path')).toEqual({ | ||||
|             protocol: 'ftp', | ||||
|             domain: 'localhost', | ||||
|             path: '/nested/path', | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     it('parses ips', () => { | ||||
|         expect(CoreUrl.parse('http://192.168.1.157:8080/')).toEqual({ | ||||
|             protocol: 'http', | ||||
|             domain: '192.168.1.157', | ||||
|             port: '8080', | ||||
|             path: '/', | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     it('compares domains and paths', () => { | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu', 'https://school.edu')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu', 'HTTPS://SCHOOL.EDU')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'https://school.edu/moodle')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'https://school.edu/moodle/')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'https://school.edu/moodle#about')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'HTTPS://SCHOOL.EDU/MOODLE')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'HTTPS://SCHOOL.EDU/MOODLE/')).toBe(true); | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'HTTPS://SCHOOL.EDU/MOODLE#ABOUT')).toBe(true); | ||||
| 
 | ||||
|         expect(CoreUrl.sameDomainAndPath('https://school.edu/moodle', 'https://school.edu/moodle/about')).toBe(false); | ||||
|     }); | ||||
| 
 | ||||
| }); | ||||
							
								
								
									
										43
									
								
								src/core/singletons/text.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/core/singletons/text.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| // (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.
 | ||||
| 
 | ||||
| /** | ||||
|  * Singleton with helper functions for text manipulation. | ||||
|  */ | ||||
| export class CoreText { | ||||
| 
 | ||||
|     // Avoid creating singleton instances.
 | ||||
|     private constructor() { | ||||
|         // Nothing to do.
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Remove ending slash from a path or URL. | ||||
|      * | ||||
|      * @param text Text to treat. | ||||
|      * @return Treated text. | ||||
|      */ | ||||
|     static removeEndingSlash(text?: string): string { | ||||
|         if (!text) { | ||||
|             return ''; | ||||
|         } | ||||
| 
 | ||||
|         if (text.slice(-1) == '/') { | ||||
|             return text.substr(0, text.length - 1); | ||||
|         } | ||||
| 
 | ||||
|         return text; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -12,7 +12,7 @@ | ||||
| // See the License for the specific language governing permissions and
 | ||||
| // limitations under the License.
 | ||||
| 
 | ||||
| import { CoreTextUtils } from '@services/utils/text'; | ||||
| import { CoreText } from './text'; | ||||
| 
 | ||||
| /** | ||||
|  * Parts contained within a url. | ||||
| @ -196,8 +196,11 @@ export class CoreUrl { | ||||
|         const partsA = CoreUrl.parse(urlA); | ||||
|         const partsB = CoreUrl.parse(urlB); | ||||
| 
 | ||||
|         return partsA?.domain == partsB?.domain && | ||||
|             CoreTextUtils.removeEndingSlash(partsA?.path) == CoreTextUtils.removeEndingSlash(partsB?.path); | ||||
|         partsA && Object.entries(partsA).forEach(([part, value]) => partsA[part] = value?.toLowerCase()); | ||||
|         partsB && Object.entries(partsB).forEach(([part, value]) => partsB[part] = value?.toLowerCase()); | ||||
| 
 | ||||
|         return partsA?.domain === partsB?.domain | ||||
|             && CoreText.removeEndingSlash(partsA?.path) === CoreText.removeEndingSlash(partsB?.path); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -21,6 +21,12 @@ console.debug = () => { | ||||
|     // Silence.
 | ||||
| }; | ||||
| 
 | ||||
| // eslint-disable-next-line no-console, jest/no-jasmine-globals, @typescript-eslint/no-explicit-any
 | ||||
| console.error = (...args: any[]) => fail(args.map(a => a.toString()).join('')); | ||||
| 
 | ||||
| // eslint-disable-next-line jest/no-jasmine-globals
 | ||||
| process.on('unhandledRejection', error => fail(error)); | ||||
| 
 | ||||
| // Override the method to create singleton method proxies in order to facilitate setting up
 | ||||
| // test expectations about method calls.
 | ||||
| setCreateSingletonMethodProxy( | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user