Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions public/mobile-app/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
await initializeData(page.url.searchParams, userStore);
if (page.url.searchParams.get('user_first_login') === 'true') {
goto('/#/notifications-welcome-page');
/* to be replaced by:
* goto('/#/welcome/notifications');
* if app mobile is ready to intercept this new url
*/
} else {
goto('/');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,101 +1,10 @@
<script lang="ts">
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { runOrNativeEvent } from '$lib/nativeEvents';
import { enableNotificationsAndUpdateLocalStorage } from '$lib/notifications';
import { toastStore } from '$lib/state/toast.svelte';
import { userStore } from '$lib/state/User.svelte';

onMount(async () => {
if (!userStore.connected) {
goto('/');
}
onMount(() => {
goto('/#/welcome/notifications', {
replaceState: true,
});
});

const enableNotificationsFunc = async () => {
await enableNotificationsAndUpdateLocalStorage();
toastStore.addToast('Les notifications ont été activées', 'success', 3000, false);
goto('/');
};

const clickOnEnable = async () => {
runOrNativeEvent(enableNotificationsFunc, 'notification_permission_requested');
};

const goToHomepage = () => {
goto('/');
};
</script>

<div class="notifications-welcome-page">
<div class="image-wrapper">
<img
class="address-icon"
src="/remixicons/notification.svg"
alt="Icône de notification"
>
</div>
<h1>Activez les notifications pour suivre vos démarches</h1>
<div class="descriptive-text">
<p>
Recevez des alertes de suivi et des rappels utiles quand vous en avez besoin. Vous
pourrez les désactiver à tout moment.
</p>
</div>

<div class="action-buttons">
<button
class="fr-btn fr-btn--lg"
type="button"
onclick="{clickOnEnable}"
data-testid="enable-button"
>
Activer
</button>
<button
class="fr-btn fr-btn--lg fr-btn--tertiary"
type="button"
onclick="{goToHomepage}"
data-testid="skip-button"
>
Peut-être plus tard
</button>
</div>
</div>

<style>
.notifications-welcome-page {
padding: 1.5rem 1rem;
margin-top: 9rem;

.image-wrapper {
display: flex;
justify-content: center;
margin-bottom: 1rem;
}
h1 {
margin-bottom: 0.5rem;
font-size: 22px;
line-height: 1.75rem;
font-weight: 700;
}
.descriptive-text {
margin-bottom: 2.5rem;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 400;
}

.action-buttons {
display: flex;
flex-direction: column;
gap: 1rem;

button {
display: flex;
justify-content: center;
width: 100%;
}
}
}
</style>
Original file line number Diff line number Diff line change
@@ -1,108 +1,24 @@
import { fireEvent, render, screen, waitFor } from '@testing-library/svelte';
import { beforeEach, describe, expect, test, vi } from 'vitest';
import { render, waitFor } from '@testing-library/svelte';
import { describe, expect, test, vi } from 'vitest';
import '@testing-library/jest-dom/vitest';
import * as navigationMethods from '$app/navigation';
import * as notificationsMethods from '$lib/notifications';
import { toastStore } from '$lib/state/toast.svelte';
import { userStore } from '$lib/state/User.svelte';
import { mockUserInfo } from '$tests/utils';
import Page from './+page.svelte';

describe('/+page.svelte', () => {
beforeEach(() => {
vi.mock('$lib/notifications', () => ({
enableNotificationsAndUpdateLocalStorage: vi.fn().mockReturnValue(true),
}));
});

test('user has to be connected', async () => {
// Given
const spy = vi
.spyOn(navigationMethods, 'goto')
.mockImplementation(() => Promise.resolve());

// When
render(Page);

// Then
await waitFor(() => {
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledWith('/');
});
});

test('should enable notifications when user clicks on Activer button', async () => {
// Given
await userStore.login(mockUserInfo);
const spy = vi.spyOn(
notificationsMethods,
'enableNotificationsAndUpdateLocalStorage'
);
render(Page);

// When
const button = screen.getByTestId('enable-button');
await fireEvent.click(button);

// Then
await waitFor(async () => {
expect(spy).toHaveBeenCalled();
});
});

test('should add toast when user clicks on Activer button', async () => {
// Given
await userStore.login(mockUserInfo);
const spy = vi.spyOn(toastStore, 'addToast');
render(Page);

// When
const button = screen.getByTestId('enable-button');
await fireEvent.click(button);

// Then
await waitFor(async () => {
expect(spy).toHaveBeenCalledWith(
'Les notifications ont été activées',
'success',
3000,
false
);
});
});

test('should navigate to the homepage when user clicks on Activer button', async () => {
test('should redirect to new page', async () => {
// Given
await userStore.login(mockUserInfo);
const spy = vi
.spyOn(navigationMethods, 'goto')
.mockImplementation(() => Promise.resolve());
render(Page);

// When
const button = screen.getByTestId('enable-button');
await fireEvent.click(button);

// Then
await waitFor(() => {
expect(spy).toHaveBeenCalledWith('/');
});
});

test('should navigate to the homepage when user clicks on Skip button', async () => {
// Given
await userStore.login(mockUserInfo);
const spy = vi
.spyOn(navigationMethods, 'goto')
.mockImplementation(() => Promise.resolve());
render(Page);

// When
const button = screen.getByTestId('skip-button');
await fireEvent.click(button);

// Then
await waitFor(() => {
expect(spy).toHaveBeenCalledWith('/');
expect(spy).toHaveBeenCalledWith('/#/welcome/notifications', {
replaceState: true,
});
});
});
});
101 changes: 101 additions & 0 deletions public/mobile-app/src/routes/welcome/notifications/+page.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<script lang="ts">
import { onMount } from 'svelte';
import { goto } from '$app/navigation';
import { runOrNativeEvent } from '$lib/nativeEvents';
import { enableNotificationsAndUpdateLocalStorage } from '$lib/notifications';
import { toastStore } from '$lib/state/toast.svelte';
import { userStore } from '$lib/state/User.svelte';

onMount(async () => {
if (!userStore.connected) {
goto('/');
}
});

const enableNotificationsFunc = async () => {
await enableNotificationsAndUpdateLocalStorage();
toastStore.addToast('Les notifications ont été activées', 'success', 3000, false);
goToZonePreferences();
};

const clickOnEnable = async () => {
runOrNativeEvent(enableNotificationsFunc, 'notification_permission_requested');
};

const goToZonePreferences = () => {
goto('/#/welcome/zones');
};
</script>

<div class="notifications-welcome-page">
<div class="image-wrapper">
<img
class="address-icon"
src="/remixicons/notification.svg"
alt="Icône de notification"
>
</div>
<h1>Activez les notifications pour suivre vos démarches</h1>
<div class="descriptive-text">
<p>
Recevez des alertes de suivi et des rappels utiles quand vous en avez besoin. Vous
pourrez les désactiver à tout moment.
</p>
</div>

<div class="action-buttons">
<button
class="fr-btn fr-btn--lg"
type="button"
onclick="{clickOnEnable}"
data-testid="enable-button"
>
Activer
</button>
<button
class="fr-btn fr-btn--lg fr-btn--tertiary"
type="button"
onclick="{goToZonePreferences}"
data-testid="skip-button"
>
Peut-être plus tard
</button>
</div>
</div>

<style>
.notifications-welcome-page {
padding: 1.5rem 1rem;
margin-top: 9rem;

.image-wrapper {
display: flex;
justify-content: center;
margin-bottom: 1rem;
}
h1 {
margin-bottom: 0.5rem;
font-size: 22px;
line-height: 1.75rem;
font-weight: 700;
}
.descriptive-text {
margin-bottom: 2.5rem;
font-size: 1rem;
line-height: 1.5rem;
font-weight: 400;
}

.action-buttons {
display: flex;
flex-direction: column;
gap: 1rem;

button {
display: flex;
justify-content: center;
width: 100%;
}
}
}
</style>
Loading
Loading