Skip to content

Commit

Permalink
feat(shared): leverage geo informations
Browse files Browse the repository at this point in the history
  • Loading branch information
clemlatz committed Sep 5, 2024
1 parent 7e3e715 commit b28cfb1
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 61 deletions.
7 changes: 5 additions & 2 deletions pix-site/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { ref } from 'vue';
const showBanner = ref(false);
const { origin } = useRequestURL();
const currentUrl = useRequestURL();
const config = useAppConfig();
const domainOrg = config.domainOrg;
Expand All @@ -38,7 +38,10 @@ const head = useLocaleHead({
});
onMounted(async () => {
const { showOutOfFranceBanner, shouldRedirectToFrFr } = await useGeolocationActions(origin, $fetch);
const { showOutOfFranceBanner, shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, $fetch);
console.log('showOutOfFranceBanner', showOutOfFranceBanner);
console.log('shouldRedirectToFrFr', shouldRedirectToFrFr);
showBanner.value = showOutOfFranceBanner;
Expand Down
17 changes: 8 additions & 9 deletions shared/composables/useGeolocationActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ const FR_FR_SUBSECTION_ROOT_PATH = '/fr-fr';

const config = useRuntimeConfig();

async function _getUserCountryFromGeolocationService(currentUrl, $fetch) {
async function _getUserCountryFromGeolocationService(origin, $fetch) {
console.log('_getUserCountryFromGeolocationService');
const geolocationApiUrl = new URL('/geolocate', currentUrl);
const geolocationApiUrl = new URL('/geolocate', origin);
console.log('_getUserCountryFromGeolocationService url:', geolocationApiUrl);

const data = await $fetch(geolocationApiUrl);
Expand All @@ -23,21 +23,20 @@ function _shouldShowBannerForCountry(country) {
}

export default async function useGeolocationActions(currentUrl, useFetch) {
console.log('useGeolocationActions');
const country = await _getUserCountryFromGeolocationService(currentUrl, useFetch);
console.log({ country });

const isUserInFranceOrDomtom = FRANCE_AND_DOMTOM_COUNTRIES_CODES.includes(country);
const isUrlInFrFrSubsection = new URL(currentUrl).pathname.startsWith(FR_FR_SUBSECTION_ROOT_PATH);
const shouldRedirectToFrFr = isUserInFranceOrDomtom && !isUrlInFrFrSubsection;
const isPathEmpty = new URL(currentUrl).pathname === '/';

const shouldRedirectToFrFr = isUserInFranceOrDomtom && isPathEmpty;

const showOutOfFranceBanner = () => {
const showOutOfFranceBanner = (function () {
console.log('config.public.siteDomain:', config.public.siteDomain);
if (config.public.siteDomain !== 'FR') return false;

if (!country) return false;

return _shouldShowBannerForCountry(country);
};
})();

return {
showOutOfFranceBanner,
Expand Down
263 changes: 213 additions & 50 deletions shared/tests/composables/useGeolocationActions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,90 +15,253 @@ mockNuxtImport('useFetch', () => {

describe('#useGeolocationActions', () => {
describe('#shouldRedirectToFrFr', () => {
describe('when in France', () => {
describe('when domain is pix.fr', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'FR',
};
mockNuxtImport('useRuntimeConfig', () => {
return () => ({
public: {
siteDomain: 'FR',
},
});
});
});

describe('when path is /fr-fr', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr';
describe('when user is in France', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'FR',
};
});
});

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);
describe('when path is /fr-fr', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr';

// then
expect(shouldRedirectToFrFr).toBe(false);
// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});
});

describe('when path is not /fr-fr', () => {
test('tells to redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-be';
describe('when user is in Belgium', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'BE',
};
});
});

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);
describe('when path is /fr-fr', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr';

// then
expect(shouldRedirectToFrFr).toBe(true);
// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});

describe('when path is not /fr-fr', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-be';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});
});
});

describe('when in Belgium', () => {
describe('when domain is pix.org', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'BE',
};
mockNuxtImport('useRuntimeConfig', () => {
return () => ({
public: {
siteDomain: 'ORG',
},
});
});
});

describe('when path is /fr-fr', () => {
test('tells to not redirect', async () => {
describe('when user is in France', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'FR',
};
});
});

describe('when user is on locale selection page', () => {
test('tells to redirect', async () => {
// given
const currentUrl = 'https://example.net/';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(true);
});
});

describe('when user is on french home page', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr/';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});

describe('when user is on another "fr-fr" page', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr/les-tests';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});

describe('when user is on a "en" page', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/en/the-tests';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});
});

describe('when user is in Belgium', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'BE',
};
});
});

describe('when path is locale selection page', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-fr';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});

describe('when path is not /fr-fr', () => {
test('tells to not redirect', async () => {
// given
const currentUrl = 'https://example.net/fr-be';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
});
});
});
});
});

describe('#showOutOfFranceBanner', () => {
describe('when domain is pix.fr', () => {
beforeEach(() => {
mockNuxtImport('useRuntimeConfig', () => {
return () => ({
public: {
siteDomain: 'FR',
},
});
});
});

describe('when user is in France', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'FR',
};
});
});

test('tells to display a banner', async () => {
// given
const currentUrl = 'https://example.net/fr-fr';
const currentUrl = 'https://example.net/whatever-url';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);
const { showOutOfFranceBanner } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
expect(showOutOfFranceBanner).toBe(false);
});
});

describe('when path is not /fr-fr', () => {
test('tells to not redirect', async () => {
describe('when user is in Belgium', () => {
beforeEach(() => {
useFetchMock.mockImplementation(async () => {
return {
pending: false,
error: undefined,
country: 'BE',
};
});
});

test('tells to not display a banner', async () => {
// given
const currentUrl = 'https://example.net/fr-be';
const currentUrl = 'https://example.net/whatever-url';

// when
const { shouldRedirectToFrFr } = await useGeolocationActions(currentUrl, useFetch);
const { showOutOfFranceBanner } = await useGeolocationActions(currentUrl, useFetch);

// then
expect(shouldRedirectToFrFr).toBe(false);
expect(showOutOfFranceBanner).toBe(true);
});
});
});
});

describe('#showOutOfFranceBanner', () => {
describe('when in France', () => {
test('tells to display a banner', () => {});
});

describe('when in Belgium', () => {
test('tells to not display a banner', () => {});
});
});
});

0 comments on commit b28cfb1

Please sign in to comment.