test: write tests for Project molecule

During testing I realised that the buttons are not accessible.
While I was adding text I also ensured that it can be translated.

Signed-off-by: André Jaenisch <andre.jaenisch@posteo.de>
This commit is contained in:
André Jaenisch 2024-06-15 19:08:37 +02:00
parent acc76294f3
commit 0d7e02afdd
No known key found for this signature in database
GPG key ID: 5A668E771F1ED854
8 changed files with 192 additions and 5 deletions

View file

@ -12,6 +12,7 @@ You should have received a copy of the GNU Affero General Public License along w
--> -->
<script> <script>
import { _ } from 'svelte-i18n';
import { import {
EyeClosed16, EyeClosed16,
Person24, Person24,
@ -21,15 +22,26 @@ You should have received a copy of the GNU Affero General Public License along w
TriangleDown16 TriangleDown16
} from 'svelte-octicons'; } from 'svelte-octicons';
/**
* Translation keys.
*/
export let i18n = {
buttons: {
fork: 'page.profile.projects.actions.fork',
star: 'page.profile.projects.actions.star',
watch: 'page.profile.projects.actions.watch'
}
};
/** /**
* Collaborators to this project. * Collaborators to this project.
*/ */
export let collaborators = []; export let collaborators = [];
/** /**
* A followed project. * A software project.
*/ */
export let following = { export let project = {
name: '', name: '',
summary: '' summary: ''
}; };
@ -41,7 +53,7 @@ You should have received a copy of the GNU Affero General Public License along w
<!-- Name + Icon --> <!-- Name + Icon -->
<div class="flex -ms-10"> <div class="flex -ms-10">
<Repo24 fill="currentColor" /> <Repo24 fill="currentColor" />
{following.name} {project.name}
<!-- Members --> <!-- Members -->
<ul class="ms-2 gap-4"> <ul class="ms-2 gap-4">
{#each collaborators as member} {#each collaborators as member}
@ -56,7 +68,7 @@ You should have received a copy of the GNU Affero General Public License along w
<!-- Description --> <!-- Description -->
<!-- Compensate padding with negative margin --> <!-- Compensate padding with negative margin -->
<div class="flex -ms-4"> <div class="flex -ms-4">
{following.summary} {project.summary}
</div> </div>
<!-- Tags --> <!-- Tags -->
<div class="flex"></div> <div class="flex"></div>
@ -66,12 +78,15 @@ You should have received a copy of the GNU Affero General Public License along w
<!-- Star Fork Watch --> <!-- Star Fork Watch -->
<div class="flex gap-4"> <div class="flex gap-4">
<button type="button" class="btn-icon border rounded-none"> <button type="button" class="btn-icon border rounded-none">
<span class="sr-only">{$_(i18n.buttons.fork)}</span>
<RepoForked16 fill="currentColor" /> <RepoForked16 fill="currentColor" />
</button> </button>
<button type="button" class="btn-icon border rounded-none"> <button type="button" class="btn-icon border rounded-none">
<span class="sr-only">{$_(i18n.buttons.star)}</span>
<Star16 fill="currentColor" /> <Star16 fill="currentColor" />
</button> </button>
<button type="button" class="btn-icon border rounded-none"> <button type="button" class="btn-icon border rounded-none">
<span class="sr-only">{$_(i18n.buttons.watch)}</span>
<EyeClosed16 fill="currentColor" /> <EyeClosed16 fill="currentColor" />
<TriangleDown16 fill="currentColor" /> <TriangleDown16 fill="currentColor" />
</button> </button>

View file

@ -25,6 +25,11 @@ You should have received a copy of the GNU Affero General Public License along w
* Translation keys. * Translation keys.
*/ */
const i18n = { const i18n = {
buttons: {
fork: 'page.profile.projects.actions.fork',
star: 'page.profile.projects.actions.star',
watch: 'page.profile.projects.actions.watch'
},
heading: 'page.profile.heading' heading: 'page.profile.heading'
}; };
@ -111,7 +116,8 @@ You should have received a copy of the GNU Affero General Public License along w
data.user.collaboratorsMap, data.user.collaboratorsMap,
following.id following.id
)} )}
{following} {i18n}
project={following}
/> />
</li> </li>
{/if} {/if}

View file

@ -74,6 +74,11 @@
"heading": "" "heading": ""
}, },
"projects": { "projects": {
"actions": {
"fork": "",
"star": "",
"watch": ""
},
"add_or_import": "", "add_or_import": "",
"empty": "", "empty": "",
"heading": "" "heading": ""

View file

@ -74,6 +74,11 @@
"heading": "Aktivitäten" "heading": "Aktivitäten"
}, },
"projects": { "projects": {
"actions": {
"fork": "",
"star": "",
"watch": ""
},
"add_or_import": "{addElementOpen}Ein Projekt hinzufügen{addElementClose} oder {importElementOpen}Ein Projekt importieren{importElementClose}.", "add_or_import": "{addElementOpen}Ein Projekt hinzufügen{addElementClose} oder {importElementOpen}Ein Projekt importieren{importElementClose}.",
"empty": "Bisher keine Projekte hinzugefügt.", "empty": "Bisher keine Projekte hinzugefügt.",
"heading": "Projekte" "heading": "Projekte"

View file

@ -74,6 +74,11 @@
"heading": "Activities" "heading": "Activities"
}, },
"projects": { "projects": {
"actions": {
"fork": "Fork",
"star": "Star",
"watch": "Watch"
},
"add_or_import": "{addElementOpen}Add a project{addElementClose} or {importElementOpen}import a project{importElementClose}.", "add_or_import": "{addElementOpen}Add a project{addElementClose} or {importElementOpen}import a project{importElementClose}.",
"empty": "No projects added yet.", "empty": "No projects added yet.",
"heading": "Projects" "heading": "Projects"

View file

@ -74,6 +74,11 @@
"heading": "פעילות" "heading": "פעילות"
}, },
"projects": { "projects": {
"actions": {
"fork": "",
"star": "",
"watch": ""
},
"add_or_import": "", "add_or_import": "",
"empty": "עדיין אין כאן פרוייקטים.", "empty": "עדיין אין כאן פרוייקטים.",
"heading": "פרויקטים" "heading": "פרויקטים"

View file

@ -74,6 +74,11 @@
"heading": "Aktywność" "heading": "Aktywność"
}, },
"projects": { "projects": {
"actions": {
"fork": "",
"star": "",
"watch": ""
},
"add_or_import": "{addElementOpen}Dodaj{addElementClose} lub {importElementOpen}zaimportuj projekt{importElementClose}.", "add_or_import": "{addElementOpen}Dodaj{addElementClose} lub {importElementOpen}zaimportuj projekt{importElementClose}.",
"empty": "Nie dodano jeszcze żadnego projektu.", "empty": "Nie dodano jeszcze żadnego projektu.",
"heading": "Projekty" "heading": "Projekty"

View file

@ -0,0 +1,141 @@
/* Component test for Project molecule.
* Copyright (C) 2024 André Jaenisch
* SPDX-FileCopyrightText: 2024 André Jaenisch
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/svelte';
import { init, locale, register } from 'svelte-i18n';
import Project from '../../../src/lib/components/molecules/Project.svelte';
import enMessages from '../../../src/lib/i18n/locales/en.json';
describe('Project.svelte', () => {
beforeEach(() => {
register('en', () => import('../../../src/lib/i18n/locales/en.json'));
init({ fallbackLocale: 'en', initialLocale: 'en' });
locale.set('en');
});
it('should mount', () => {
// Arrange
// Nothing to prepare
// Act
const { container } = render(Project);
// Assert
expect(container).toBeTruthy();
});
it("should show the project's name", () => {
// Arrange
const collaborators = [];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const projectName = screen.getByText(new RegExp(project.name));
// Assert
expect(projectName).toBeInTheDocument();
});
it("should show the project's summary", () => {
// Arrange
const collaborators = [];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const projectSummary = screen.getByText(new RegExp(project.summary));
// Assert
expect(projectSummary).toBeInTheDocument();
});
it('should show each collaborator', () => {
// Arrange
const collaborators = [
{
preferredUsername: 'Your favourite Project Manager'
}
];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const renderedCollaborators = screen.getAllByRole('listitem');
const renderedCollaborator = screen.getByRole('listitem');
// Assert
expect(renderedCollaborators).toBeDefined();
expect(renderedCollaborator).toBeDefined();
expect(renderedCollaborators).toHaveLength(collaborators.length);
expect(renderedCollaborator).toHaveAttribute('title', collaborators[0].preferredUsername);
});
it('should have a button to fork the project', () => {
// Arrange
const collaborators = [];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const forkButton = screen.getByRole('button', { name: 'Fork' });
// Assert
expect(forkButton).toBeInTheDocument();
});
it('should have a button to star the project', () => {
// Arrange
const collaborators = [];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const starButton = screen.getByRole('button', { name: 'Star' });
// Assert
expect(starButton).toBeInTheDocument();
});
it('should have a button to watch the project', () => {
// Arrange
const collaborators = [];
const project = {
name: 'Test battery',
summary: 'Making sure Anvil is rock solid!'
};
// Act
render(Project, { collaborators, project });
const watchButton = screen.getByRole('button', { name: 'Watch' });
// Assert
expect(watchButton).toBeInTheDocument();
});
});