-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cd97bc5
commit e85ee4c
Showing
2 changed files
with
108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
const isUrlAbsolute = (url) => { | ||
// the URL constructor will throw for relative URLs | ||
try { | ||
new URL(url) | ||
return true | ||
} catch { | ||
return false | ||
} | ||
} | ||
|
||
/** | ||
* Deduces the base URL for the DHIS2 instance from the location at which this | ||
* app is hosted. Returns an absolute URL | ||
* @param {string} defaultBaseUrl a fallback URL that will be used if the base | ||
* URL can't be deduced from the window location | ||
* @returns {string} an absolute base URL for the DHIS2 instance | ||
*/ | ||
export const getBaseUrl = (defaultBaseUrl) => { | ||
// if defaultBaseUrl is absolute, use that | ||
if (isUrlAbsolute(defaultBaseUrl)) { | ||
return defaultBaseUrl | ||
} | ||
|
||
const { location } = window | ||
const path = location.pathname | ||
|
||
// get penultimate 3 path elements (don't need anything before), | ||
// e.g. /dev/api/apps/app-name/index.html => ['api', 'apps', 'app-name']. | ||
const splitPath = path.split('/').slice(-4, -1) | ||
// could be shorter than 3 elements for e.g. /dhis-web-maps/ | ||
const l = splitPath.length | ||
|
||
// test for core apps | ||
if (/dhis-web-.+/.test(splitPath[l - 1])) { | ||
return new URL('..', location.href).href | ||
} | ||
|
||
// test for custom apps | ||
if (splitPath[l - 3] === 'api' && splitPath[l - 2] === 'apps') { | ||
return new URL('../../..', location.href).href | ||
} | ||
|
||
// todo: handle path for global shell | ||
|
||
// otherwise, return absolute version of default | ||
return new URL(defaultBaseUrl, location.href).href | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { getBaseUrl } from './getBaseUrl.js' | ||
|
||
const testOrigin = 'https://debug.dhis2.org' | ||
// { [testPath]: expectedPath } | ||
const testPaths = { | ||
'/dev/api/apps/simple-app/index.html': '/dev/', | ||
'/analytics_dev/dhis-web-maps/plugin.html': '/analytics_dev/', | ||
'/dhis-web-line-listing/index.html': '/', | ||
'/dhis-web-user-settings/': '/', | ||
'/hmis/staging/v41/api/apps/WHO-Data-Quality-App/app.html': | ||
'/hmis/staging/v41/', | ||
} | ||
|
||
const windowLocationMock = jest | ||
.spyOn(window, 'location', 'get') | ||
.mockImplementation(() => ({ | ||
href: 'https://debug.dhis2.org/dev/', | ||
pathname: '/dev/', | ||
})) | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
test('an absolute URL is used if provided as the default', () => { | ||
const testBaseUrl = 'http://localhost:8080/hmis/long/path/dev' | ||
|
||
const url = getBaseUrl(testBaseUrl) | ||
|
||
expect(url).toBe(testBaseUrl) | ||
}) | ||
|
||
describe('location variants', () => { | ||
const defaultRelativeBaseUrl = '..' | ||
|
||
for (const [testPath, expectedPath] of Object.entries(testPaths)) { | ||
test(testPath, () => { | ||
windowLocationMock.mockImplementation(() => ({ | ||
pathname: testPath, | ||
href: testOrigin + testPath, | ||
})) | ||
|
||
const url = getBaseUrl(defaultRelativeBaseUrl) | ||
|
||
expect(url).toBe(testOrigin + expectedPath) | ||
}) | ||
} | ||
}) | ||
|
||
test("if the function doesn't match a pattern, it falls back to the provided default", () => { | ||
const relativeDefaultBaseUrl = '../../..' | ||
const testPath = '/not/a/recognized/path/index.html' | ||
windowLocationMock.mockImplementation(() => ({ | ||
pathname: testPath, | ||
href: testOrigin + testPath, | ||
})) | ||
|
||
const url = getBaseUrl(relativeDefaultBaseUrl) | ||
|
||
expect(url).toBe(testOrigin + '/not/') | ||
}) |