refactor: extract form into organism
I want to explore how I could potentially reuse components. Therefore I extract the form into a component. Given its complexity it could either be a molecule or an organism. I went with the latter here. I have to explore how I pass around Objects and Arrays in Svelte so that I can move server logic up in the component tree. When I reuse components, I potentially want to define the labels and placeholders. Therefore the hard-coded strings have to become variables. Eventually I will define the key on the template level and use the real values on page level and pass it down. That would break tests currently so I'm not doing it in this refactoring. Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
This commit is contained in:
parent
db1b8822e8
commit
dd50af1764
6 changed files with 546 additions and 200 deletions
56
src/lib/components/organisms/LoginForm.svelte
Normal file
56
src/lib/components/organisms/LoginForm.svelte
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { _ } from 'svelte-i18n';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form handling by SvelteKit
|
||||||
|
*/
|
||||||
|
export let form: unknown = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translation keys to enable reuse
|
||||||
|
*/
|
||||||
|
export let i18n: null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available servers for signin
|
||||||
|
*/
|
||||||
|
export let servers: Array = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form class="space-y-4" name="login" method="POST" action="?/login">
|
||||||
|
{#if form?.missing}
|
||||||
|
<p class="error">{$_(i18n.validation.missing)}</p>
|
||||||
|
{/if}
|
||||||
|
{#if form?.incorrect}
|
||||||
|
<p class="error">{$_(i18n.validation.incorrect)}</p>
|
||||||
|
{/if}
|
||||||
|
<label class="label">
|
||||||
|
<span>{$_(i18n.fields.server.label)}</span>
|
||||||
|
<select class="select" name="server">
|
||||||
|
<option value="1">fig.fr33domlover.site</option>
|
||||||
|
<option value="2">grape.fr33domlover.site</option>
|
||||||
|
<option value="3">walnut.fr33domlover.site</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label class="label">
|
||||||
|
<span>{$_(i18n.fields.account.label)}</span>
|
||||||
|
<input class="input" name="account" type="text" value={form?.account ?? ''} />
|
||||||
|
</label>
|
||||||
|
<label class="label">
|
||||||
|
<span>{$_(i18n.fields.passphrase.label)}</span>
|
||||||
|
<input
|
||||||
|
class="input"
|
||||||
|
name="passphrase"
|
||||||
|
type="password"
|
||||||
|
placeholder={$_(i18n.fields.passphrase.placeholder)}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div class="text-right">
|
||||||
|
<a href="/" class="btn btn-bg-initial">
|
||||||
|
{$_(i18n.reset)}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="w-full btn variant-filled-primary">
|
||||||
|
{$_(i18n.submit)}
|
||||||
|
</button>
|
||||||
|
</form>
|
|
@ -1,47 +1,43 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
|
|
||||||
|
import LoginForm from '../organisms/LoginForm.svelte';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form handling by SvelteKit
|
* Form handling by SvelteKit
|
||||||
*/
|
*/
|
||||||
export let form: unknown = null;
|
export let form: unknown = null;
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: 'page.login.form.fields.account.label'
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: 'page.login.form.fields.passphrase.label',
|
||||||
|
placeholder: 'page.login.form.fields.passphrase.placeholder'
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: 'page.login.form.fields.server.label'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reset: 'page.login.form.reset',
|
||||||
|
submit: 'page.login.form.submit',
|
||||||
|
validation: {
|
||||||
|
incorrect: 'page.login.form.validation.incorrect',
|
||||||
|
missing: 'page.login.form.validation.missing'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = {
|
||||||
|
'1': 'fig.fr33domlover.site',
|
||||||
|
'2': 'grape.fr33domlover.site',
|
||||||
|
'3': 'walnut.fr33domlover.site'
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="w-full max-w-md h-full mx-auto flex justify-center items-center py-10">
|
<div class="w-full max-w-md h-full mx-auto flex justify-center items-center py-10">
|
||||||
<div class="space-y-10">
|
<div class="space-y-10">
|
||||||
<h1 class="h1 font-bold">{$_('page.login.heading')}</h1>
|
<h1 class="h1 font-bold">{$_('page.login.heading')}</h1>
|
||||||
<p>{$_('page.login.intro')}</p>
|
<p>{$_('page.login.intro')}</p>
|
||||||
<form class="space-y-4" name="login" method="POST" action="?/login">
|
<LoginForm {form} {i18n} {servers} />
|
||||||
{#if form?.missing}
|
|
||||||
<p class="error">{$_('page.login.form.validation.missing')}</p>
|
|
||||||
{/if}
|
|
||||||
{#if form?.incorrect}
|
|
||||||
<p class="error">{$_('page.login.form.validation.incorrect')}</p>
|
|
||||||
{/if}
|
|
||||||
<label class="label">
|
|
||||||
<span>{$_('page.login.form.fields.server.label')}</span>
|
|
||||||
<select class="select" name="server">
|
|
||||||
<option value="1">fig.fr33domlover.site</option>
|
|
||||||
<option value="2">grape.fr33domlover.site</option>
|
|
||||||
<option value="3">walnut.fr33domlover.site</option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<label class="label">
|
|
||||||
<span>{$_('page.login.form.fields.account.label')}</span>
|
|
||||||
<input class="input" name="account" type="text" value={form?.account ?? ''} />
|
|
||||||
</label>
|
|
||||||
<label class="label">
|
|
||||||
<span>{$_('page.login.form.fields.passphrase.label')}</span>
|
|
||||||
<input class="input" name="passphrase" type="password" placeholder="password" />
|
|
||||||
</label>
|
|
||||||
<div class="text-right">
|
|
||||||
<a href="/" class="btn btn-bg-initial">
|
|
||||||
{$_('page.login.form.reset')}
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<button type="submit" class="w-full btn variant-filled-primary">
|
|
||||||
{$_('page.login.form.submit')}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,83 +1,84 @@
|
||||||
{
|
{
|
||||||
"page": {
|
"page": {
|
||||||
"import_project": {
|
"import_project": {
|
||||||
"form": {
|
"form": {
|
||||||
"avatar": "Avatar",
|
"avatar": "Avatar",
|
||||||
"components": "Komponenten",
|
"components": "Komponenten",
|
||||||
"fields": {
|
"fields": {
|
||||||
"avatar": {
|
"avatar": {
|
||||||
"label": "Bild hochladen"
|
"label": "Bild hochladen"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"label": "Beschreibung",
|
"label": "Beschreibung",
|
||||||
"placeholder": "Beschreibe das Projekt in unter 100 Zeichen..."
|
"placeholder": "Beschreibe das Projekt in unter 100 Zeichen..."
|
||||||
},
|
},
|
||||||
"issues": {
|
"issues": {
|
||||||
"label": "Issues"
|
"label": "Issues"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"error": "Dieses Feld ist erforderlich",
|
"error": "Dieses Feld ist erforderlich",
|
||||||
"label": "Name",
|
"label": "Name",
|
||||||
"placeholder": "Name des Projekts..."
|
"placeholder": "Name des Projekts..."
|
||||||
},
|
},
|
||||||
"pr": {
|
"pr": {
|
||||||
"label": "Pullrequest"
|
"label": "Pullrequest"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"hint": "optional: von Git-Repository importieren",
|
"hint": "optional: von Git-Repository importieren",
|
||||||
"label": "Repository",
|
"label": "Repository",
|
||||||
"placeholder": "URL des Git-Repositorys"
|
"placeholder": "URL des Git-Repositorys"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"submit": "Projekt erstellen"
|
"submit": "Projekt erstellen"
|
||||||
},
|
},
|
||||||
"heading": "Projekt erstellen",
|
"heading": "Projekt erstellen",
|
||||||
"intro": "Neues F2-Projekt zu Anvil hinzufügen."
|
"intro": "Neues F2-Projekt zu Anvil hinzufügen."
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"form": {
|
"form": {
|
||||||
"validation": {
|
"fields": {
|
||||||
"incorrect": "Accountname oder Kennwort sind falsch.",
|
"account": {
|
||||||
"missing": "Das Account-Feld ist verbindlich."
|
"label": "Accountname"
|
||||||
},
|
},
|
||||||
"fields": {
|
"passphrase": {
|
||||||
"account": {
|
"label": "Passwort",
|
||||||
"label": "Accountname"
|
"placeholder": ""
|
||||||
},
|
},
|
||||||
"passphrase": {
|
"server": {
|
||||||
"label": "Passwort"
|
"label": "F2-Server"
|
||||||
},
|
}
|
||||||
"server": {
|
},
|
||||||
"label": "F2-Server"
|
"reset": "Passwort zurücksetzen",
|
||||||
}
|
"submit": "Einloggen",
|
||||||
},
|
"validation": {
|
||||||
"reset": "Passwort zurücksetzen",
|
"incorrect": "Accountname oder Kennwort sind falsch.",
|
||||||
"submit": "Einloggen"
|
"missing": "Das Account-Feld ist verbindlich."
|
||||||
},
|
}
|
||||||
"heading": "Einloggen",
|
},
|
||||||
"intro": "Die Einwahldaten ausfüllen um Anvil mit deinem F2-Account zu benutzen."
|
"heading": "Einloggen",
|
||||||
},
|
"intro": "Die Einwahldaten ausfüllen um Anvil mit deinem F2-Account zu benutzen."
|
||||||
"profile": {
|
},
|
||||||
"activities": {
|
"profile": {
|
||||||
"block_or_report": "{blockElementOpen}blockieren{blockElementClose} oder {reportElementOpen}melden{reportElementClose}",
|
"activities": {
|
||||||
"like": "Gefällt mir"
|
"block_or_report": "{blockElementOpen}blockieren{blockElementClose} oder {reportElementOpen}melden{reportElementClose}",
|
||||||
},
|
"like": "Gefällt mir"
|
||||||
"heading": "Profil für",
|
},
|
||||||
"history": {
|
"heading": "Profil für",
|
||||||
"activities": {
|
"history": {
|
||||||
"setup": {
|
"activities": {
|
||||||
"description": "Das F2-Konto @{username}@{instance} wurde erfolgreich innerhalb von {created_with} erstellt",
|
"setup": {
|
||||||
"summary": "Kontoeinstellungen"
|
"description": "Das F2-Konto @{username}@{instance} wurde erfolgreich innerhalb von {created_with} erstellt",
|
||||||
}
|
"summary": "Kontoeinstellungen"
|
||||||
},
|
}
|
||||||
"heading": "Aktivitäten"
|
},
|
||||||
},
|
"heading": "Aktivitäten"
|
||||||
"projects": {
|
},
|
||||||
"add_or_import": "{addElementOpen}Ein Projekt hinzufügen{addElementClose} oder {importElementOpen}Ein Projekt importieren{importElementClose}.",
|
"projects": {
|
||||||
"empty": "Bisher keine Projekte hinzugefügt.",
|
"add_or_import": "{addElementOpen}Ein Projekt hinzufügen{addElementClose} oder {importElementOpen}Ein Projekt importieren{importElementClose}.",
|
||||||
"heading": "Projekte"
|
"empty": "Bisher keine Projekte hinzugefügt.",
|
||||||
}
|
"heading": "Projekte"
|
||||||
},
|
}
|
||||||
"welcome": "Willkommen bei Anvil!"
|
},
|
||||||
}
|
"welcome": "Willkommen bei Anvil!"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,23 +36,24 @@
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"form": {
|
"form": {
|
||||||
"validation": {
|
|
||||||
"incorrect": "Account or password wrong.",
|
|
||||||
"missing": "The account field is required."
|
|
||||||
},
|
|
||||||
"fields": {
|
"fields": {
|
||||||
"account": {
|
"account": {
|
||||||
"label": "Account name"
|
"label": "Account name"
|
||||||
},
|
},
|
||||||
"passphrase": {
|
"passphrase": {
|
||||||
"label": "Passphrase"
|
"label": "Passphrase",
|
||||||
|
"placeholder": "password"
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"label": "F2 server"
|
"label": "F2 server"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"reset": "Reset passphrase",
|
"reset": "Reset passphrase",
|
||||||
"submit": "Log in"
|
"submit": "Log in",
|
||||||
|
"validation": {
|
||||||
|
"incorrect": "Account or password wrong.",
|
||||||
|
"missing": "The account field is required."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"heading": "Log in",
|
"heading": "Log in",
|
||||||
"intro": "To use Anvil with your F2 account, fill in your credentials."
|
"intro": "To use Anvil with your F2 account, fill in your credentials."
|
||||||
|
|
|
@ -1,83 +1,84 @@
|
||||||
{
|
{
|
||||||
"page": {
|
"page": {
|
||||||
"import_project": {
|
"import_project": {
|
||||||
"form": {
|
"form": {
|
||||||
"avatar": "תמונה",
|
"avatar": "תמונה",
|
||||||
"components": "רכיבים",
|
"components": "רכיבים",
|
||||||
"fields": {
|
"fields": {
|
||||||
"avatar": {
|
"avatar": {
|
||||||
"label": "להעלות תמונה?"
|
"label": "להעלות תמונה?"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"label": "תיאור",
|
"label": "תיאור",
|
||||||
"placeholder": "על הפרויקט בפחות מ-100 אותיות…"
|
"placeholder": "על הפרויקט בפחות מ-100 אותיות…"
|
||||||
},
|
},
|
||||||
"issues": {
|
"issues": {
|
||||||
"label": "סוגיות"
|
"label": "סוגיות"
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"error": "חובה",
|
"error": "חובה",
|
||||||
"label": "שם",
|
"label": "שם",
|
||||||
"placeholder": "שם הפרויקט…"
|
"placeholder": "שם הפרויקט…"
|
||||||
},
|
},
|
||||||
"pr": {
|
"pr": {
|
||||||
"label": "פרים"
|
"label": "פרים"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"hint": "אפשר לייבא קוד מקופסת גיט",
|
"hint": "אפשר לייבא קוד מקופסת גיט",
|
||||||
"label": "קופסת קוד",
|
"label": "קופסת קוד",
|
||||||
"placeholder": "לינק לקופסת קוד של גיט"
|
"placeholder": "לינק לקופסת קוד של גיט"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"submit": "ליצור פרויקט"
|
"submit": "ליצור פרויקט"
|
||||||
},
|
},
|
||||||
"heading": "יצירת פרויקט",
|
"heading": "יצירת פרויקט",
|
||||||
"intro": ""
|
"intro": ""
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"form": {
|
"form": {
|
||||||
"validation": {
|
"fields": {
|
||||||
"incorrect": "שם המשתמש או הסיסמה שגויים.",
|
"account": {
|
||||||
"missing": "שם המשתמש חובה."
|
"label": "שם משתמש"
|
||||||
},
|
},
|
||||||
"fields": {
|
"passphrase": {
|
||||||
"account": {
|
"label": "סיסמה",
|
||||||
"label": "שם משתמש"
|
"placeholder": ""
|
||||||
},
|
},
|
||||||
"passphrase": {
|
"server": {
|
||||||
"label": "סיסמה"
|
"label": ""
|
||||||
},
|
}
|
||||||
"server": {
|
},
|
||||||
"label": ""
|
"reset": "לשנות סיסמה?",
|
||||||
}
|
"submit": "להיכנס",
|
||||||
},
|
"validation": {
|
||||||
"reset": "לשנות סיסמה?",
|
"incorrect": "שם המשתמש או הסיסמה שגויים.",
|
||||||
"submit": "להיכנס"
|
"missing": "שם המשתמש חובה."
|
||||||
},
|
}
|
||||||
"heading": "כניסה",
|
},
|
||||||
"intro": ""
|
"heading": "כניסה",
|
||||||
},
|
"intro": ""
|
||||||
"profile": {
|
},
|
||||||
"activities": {
|
"profile": {
|
||||||
"block_or_report": "{blockElementOpen}לחסום{blockElementClose} או {reportElementOpen}לדווח{reportElementClose}",
|
"activities": {
|
||||||
"like": "אהבתי"
|
"block_or_report": "{blockElementOpen}לחסום{blockElementClose} או {reportElementOpen}לדווח{reportElementClose}",
|
||||||
},
|
"like": "אהבתי"
|
||||||
"heading": "הפרופיל של",
|
},
|
||||||
"history": {
|
"heading": "הפרופיל של",
|
||||||
"activities": {
|
"history": {
|
||||||
"setup": {
|
"activities": {
|
||||||
"description": "",
|
"setup": {
|
||||||
"summary": ""
|
"description": "",
|
||||||
}
|
"summary": ""
|
||||||
},
|
}
|
||||||
"heading": "פעילות"
|
},
|
||||||
},
|
"heading": "פעילות"
|
||||||
"projects": {
|
},
|
||||||
"add_or_import": "",
|
"projects": {
|
||||||
"empty": "עדיין אין כאן פרוייקטים.",
|
"add_or_import": "",
|
||||||
"heading": "פרויקטים"
|
"empty": "עדיין אין כאן פרוייקטים.",
|
||||||
}
|
"heading": "פרויקטים"
|
||||||
},
|
}
|
||||||
"welcome": ""
|
},
|
||||||
}
|
"welcome": ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
291
tests/components/organisms/LoginForm.test.ts
Normal file
291
tests/components/organisms/LoginForm.test.ts
Normal file
|
@ -0,0 +1,291 @@
|
||||||
|
import '@testing-library/jest-dom';
|
||||||
|
import { render, screen } from '@testing-library/svelte';
|
||||||
|
import { init, locale, register } from 'svelte-i18n';
|
||||||
|
|
||||||
|
import LoginForm from '../../../src/lib/components/organisms/LoginForm.svelte';
|
||||||
|
import enMessages from '../../../src/lib/i18n/locales/en.json';
|
||||||
|
|
||||||
|
describe('LoginForm.svelte', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
register('en', () => import('../../../src/lib/i18n/locales/en.json'));
|
||||||
|
init({ fallbackLocale: 'en', initialLocale: 'en' });
|
||||||
|
locale.set('en');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mount', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const { container } = render(LoginForm, { form, i18n, servers });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(container).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a form', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const formElement = screen.getByRole('form');
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(formElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a server select control', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const server = screen.getByLabelText(enMessages.page.login.form.fields.server.label);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(server).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a account input control', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const account = screen.getByLabelText(enMessages.page.login.form.fields.account.label);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(account).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a passphrase input control', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const passphrase = screen.getByLabelText(enMessages.page.login.form.fields.passphrase.label);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(passphrase).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a reset passphrase link', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reset: enMessages.page.login.form.reset
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const reset = screen.getByRole('link', { name: enMessages.page.login.form.reset });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(reset).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a submit button', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
submit: enMessages.page.login.form.submit
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const submit = screen.getByRole('button', { name: enMessages.page.login.form.submit });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(submit).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have no validation errors', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(
|
||||||
|
screen.queryByText(enMessages.page.login.form.validation.incorrect)
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.queryByText(enMessages.page.login.form.validation.missing)
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when validation failed', () => {
|
||||||
|
it('should show an error on required inputs', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {
|
||||||
|
missing: true
|
||||||
|
};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validation: {
|
||||||
|
missing: enMessages.page.login.form.validation.missing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const intro = screen.getByText(enMessages.page.login.form.validation.missing);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(intro).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show an error on invalid inputs', () => {
|
||||||
|
// Arrange
|
||||||
|
const form = {
|
||||||
|
incorrect: true
|
||||||
|
};
|
||||||
|
const i18n = {
|
||||||
|
fields: {
|
||||||
|
account: {
|
||||||
|
label: enMessages.page.login.form.fields.account.label
|
||||||
|
},
|
||||||
|
passphrase: {
|
||||||
|
label: enMessages.page.login.form.fields.passphrase.label
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
label: enMessages.page.login.form.fields.server.label
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validation: {
|
||||||
|
incorrect: enMessages.page.login.form.validation.incorrect
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const servers = [];
|
||||||
|
|
||||||
|
// Act
|
||||||
|
render(LoginForm, { form, i18n, servers });
|
||||||
|
const intro = screen.getByText(enMessages.page.login.form.validation.incorrect);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(intro).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue