diff --git a/src/lib/components/atoms/SettingsSidebar.svelte b/src/lib/components/atoms/SettingsSidebar.svelte index 93fb7ee..b2eb49a 100644 --- a/src/lib/components/atoms/SettingsSidebar.svelte +++ b/src/lib/components/atoms/SettingsSidebar.svelte @@ -12,33 +12,19 @@ You should have received a copy of the GNU Affero General Public License along w --> - - {#if $drawerStore.id === 'profile'} - Profile settings go here - {:else} - {$drawerStore.id} - {/if} - -
- {$_('page.profile.menu.details.repository')} + {$_('page.profile.menu.details.repository')}
@@ -52,7 +53,8 @@ You should have received a copy of the GNU Affero General Public License along w
- {$_('page.profile.menu.details.branches')} + {$_('page.profile.menu.details.branches')}
@@ -70,9 +72,10 @@ You should have received a copy of the GNU Affero General Public License along w
- {$_('page.profile.menu.details.merge_requests')} - {$_('page.profile.menu.details.merge_requests')} + 2
@@ -88,7 +91,9 @@ You should have received a copy of the GNU Affero General Public License along w
- {$_('page.profile.menu.details.moderation')} + {$_('page.profile.menu.details.moderation')}
@@ -98,4 +103,3 @@ You should have received a copy of the GNU Affero General Public License along w
- diff --git a/src/lib/components/molecules/Settings.svelte b/src/lib/components/molecules/Settings.svelte index 30f9776..4fd24d8 100644 --- a/src/lib/components/molecules/Settings.svelte +++ b/src/lib/components/molecules/Settings.svelte @@ -14,9 +14,18 @@ You should have received a copy of the GNU Affero General Public License along w
- - + + + {#if activeSetting === 'profile'} + + {/if}
diff --git a/src/lib/components/templates/Profile.svelte b/src/lib/components/templates/Profile.svelte index 185dbeb..aa1c4aa 100644 --- a/src/lib/components/templates/Profile.svelte +++ b/src/lib/components/templates/Profile.svelte @@ -20,6 +20,7 @@ You should have received a copy of the GNU Affero General Public License along w import Created from '../atoms/Created.svelte'; import DisplayName from '../atoms/DisplayName.svelte'; import History from '../molecules/History.svelte'; + import MainMenu from '../molecules/MainMenu.svelte'; import Project from '../molecules/Project.svelte'; /** @@ -71,129 +72,140 @@ You should have received a copy of the GNU Affero General Public License along w }; -
- -
- -
- -
-
- - -
- -
- -
-
- -
- - {data.user.username}@{data.user.instance} - +
+ +
+
+ +
+
- - -
-
-
-
- -
-
-

- {$_('page.profile.projects.heading')} -

- {#if data?.user?.followingsMap} -
    - {#each data.user.followingsMap as following} - {#if following.type === 'Project'} -
  • - -
  • - {/if} - {/each} -
+ +
+
+ + +
+ +
+ +
+
+ +
+ + {data.user.username}@{data.user.instance} + +
+ + +
+
+
+
+ +
+
+

+ {$_('page.profile.projects.heading')} +

+ {#if data?.user?.followingsMap} +
    + {#each data.user.followingsMap as following} + {#if following.type === 'Project'} +
  • + +
  • + {/if} + {/each} +
-

- {$_('page.profile.repositories.heading')} -

-
- {#each data.user.followingsMap as following} - {#if following.type === 'Repository'} -
- -
- {/if} - {/each} -
-
-

The following is DEBUG information and will be removed in the near future.

- {#if data?.user} -
- Person -
{JSON.stringify(data.user.person, null, 2)}
-
-
- Followings -
{JSON.stringify(data.user.followings, null, 2)}
-
-
- Followings mapped -

These are the contents of the items in the previous dump.

-
{JSON.stringify(data.user.followingsMap, null, 2)}
-
-
- Collaborators mapped -

These are the contents of the items in the previous dump.

-
{JSON.stringify(data.user.collaboratorsMap, null, 2)}
-
-
- Commits -

These are the contents of the items in the previous dump.

-
{JSON.stringify(data.user.commits, null, 2)}
-
-
- Commits mapped -

These are the contents of the items in the previous dump.

-
{JSON.stringify(data.user.commitsMap, null, 2)}
-
+

+ {$_('page.profile.repositories.heading')} +

+
+ {#each data.user.followingsMap as following} + {#if following.type === 'Repository'} +
+ +
+ {/if} + {/each} +
+
+

The following is DEBUG information and will be removed in the near future.

+ {#if data?.user} +
+ Person +
{JSON.stringify(data.user.person, null, 2)}
+
+
+ Followings +
{JSON.stringify(data.user.followings, null, 2)}
+
+
+ Followings mapped +

These are the contents of the items in the previous dump.

+
{JSON.stringify(data.user.followingsMap, null, 2)}
+
+
+ Collaborators mapped +

These are the contents of the items in the previous dump.

+
{JSON.stringify(data.user.collaboratorsMap, null, 2)}
+
+
+ Commits +

These are the contents of the items in the previous dump.

+
{JSON.stringify(data.user.commits, null, 2)}
+
+
+ Commits mapped +

These are the contents of the items in the previous dump.

+
{JSON.stringify(data.user.commitsMap, null, 2)}
+
+ {/if} +
+ {:else} +

+ {$_('page.profile.projects.empty')} + {@html $_('page.profile.projects.add_or_import', { + values: { + addElementOpen: '', + addElementClose: '', + importElementOpen: ``, + importElementClose: '' + } + })} +

{/if}
- {:else} -

- {$_('page.profile.projects.empty')} - {@html $_('page.profile.projects.add_or_import', { - values: { - addElementOpen: '', - addElementClose: '', - importElementOpen: ``, - importElementClose: '' - } - })} -

- {/if} -
-
- -
-
- -
-
-
+ + +
+
+ +
+
+ + + diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 0f1234f..a161053 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -7,8 +7,10 @@ SPDX-License-Identifier: AGPL-3.0-or-later + diff --git a/stories/molecules/Settings.stories.ts b/stories/molecules/Settings.stories.ts new file mode 100644 index 0000000..a57ab25 --- /dev/null +++ b/stories/molecules/Settings.stories.ts @@ -0,0 +1,26 @@ +/* Stories for Settings 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 . + */ + +import type { Meta, StoryObj } from '@storybook/svelte'; + +import Settings from '$lib/components/molecules/Settings.svelte'; + +const meta = { + title: 'Molecules/Settings', + component: Settings, + tags: ['autodocs'] +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Plain: Story = {}; diff --git a/tests/components/atoms/MainMenuSummary.test.ts b/tests/components/atoms/MainMenuSummary.test.ts index 619ed8e..d4b6b10 100644 --- a/tests/components/atoms/MainMenuSummary.test.ts +++ b/tests/components/atoms/MainMenuSummary.test.ts @@ -14,7 +14,7 @@ import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floati import { storePopup } from '@skeletonlabs/skeleton'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/svelte'; -import { get, readable } from 'svelte/store'; +import { readable } from 'svelte/store'; import { init, locale, register } from 'svelte-i18n'; import MainMenuSummary from '../../../src/lib/components/atoms/MainMenuSummary.svelte'; diff --git a/tests/components/atoms/SettingsSidebar.test.ts b/tests/components/atoms/SettingsSidebar.test.ts index d41bcac..4878c1c 100644 --- a/tests/components/atoms/SettingsSidebar.test.ts +++ b/tests/components/atoms/SettingsSidebar.test.ts @@ -27,13 +27,10 @@ describe('SettingsSidebar.svelte', () => { it('should mount', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - const { container } = render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + const { container } = render(SettingsSidebar); // Assert expect(container).toBeTruthy(); @@ -41,13 +38,10 @@ describe('SettingsSidebar.svelte', () => { it('should have a headline', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.headline)).toBeInTheDocument(); @@ -55,13 +49,10 @@ describe('SettingsSidebar.svelte', () => { it('should have a profile tile', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.profile.label)).toBeInTheDocument(); @@ -69,13 +60,10 @@ describe('SettingsSidebar.svelte', () => { it('should have an account tile', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.account.label)).toBeInTheDocument(); @@ -83,13 +71,10 @@ describe('SettingsSidebar.svelte', () => { it('should have a SSH/GPG keys tile', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.ssh_gpg_keys.label)).toBeInTheDocument(); @@ -97,13 +82,10 @@ describe('SettingsSidebar.svelte', () => { it('should have an appearance tile', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.appearance.label)).toBeInTheDocument(); @@ -111,15 +93,48 @@ describe('SettingsSidebar.svelte', () => { it('should have a notifications tile', () => { // Arrange - // See https://testing-library.com/docs/svelte-testing-library/example#contexts - const drawerStore = readable([]); + // Nothing to prepare // Act - render(SettingsSidebar, { - context: new Map([['drawerStore', drawerStore]]) - }); + render(SettingsSidebar); // Assert expect(screen.getByText(enMessages.settings.notifications.label)).toBeInTheDocument(); }); + + describe('when clicking a tile', () => { + it('should dispatch a switch-settings event when clicking a tile', () => { + // Arrange + const listener = vi.fn(); + + // Act + const { component } = render(SettingsSidebar); + component.$on('switch-settings', listener); + const profileTile = screen.getByText(enMessages.settings.profile.label); + expect(profileTile).toBeInTheDocument(); + profileTile.click(); + + // Assert + expect(listener).toHaveBeenCalledOnce(); + }); + + it('should pass the clicked tile in the event', () => { + // Arrange + const listener = vi.fn(); + + // Act + const { component } = render(SettingsSidebar); + component.$on('switch-settings', listener); + const profileTile = screen.getByText(enMessages.settings.profile.label); + expect(profileTile).toBeInTheDocument(); + profileTile.click(); + + // Assert + expect(listener).toHaveBeenCalledWith( + new CustomEvent('switch-settings', { + detail: 'profile' + }) + ); + }); + }); }); diff --git a/tests/components/molecules/MainMenuDetails.test.ts b/tests/components/molecules/MainMenuDetails.test.ts index fcaaa0f..9521e20 100644 --- a/tests/components/molecules/MainMenuDetails.test.ts +++ b/tests/components/molecules/MainMenuDetails.test.ts @@ -109,7 +109,9 @@ describe('MainMenuDetails.svelte', () => { render(MainMenuDetails); // Assert - expect(screen.getByText(enMessages.page.profile.menu.details.merge_requests)).toBeInTheDocument(); + expect( + screen.getByText(enMessages.page.profile.menu.details.merge_requests) + ).toBeInTheDocument(); }); it('should have a people item', () => { diff --git a/tests/components/molecules/Settings.test.ts b/tests/components/molecules/Settings.test.ts new file mode 100644 index 0000000..5ace806 --- /dev/null +++ b/tests/components/molecules/Settings.test.ts @@ -0,0 +1,72 @@ +/* Component test for Settings 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 . + */ + +import '@testing-library/jest-dom'; +import { render, screen } from '@testing-library/svelte'; +import { tick } from 'svelte'; +import { init, locale, register } from 'svelte-i18n'; + +import Settings from '../../../src/lib/components/molecules/Settings.svelte'; +import enMessages from '../../../src/lib/i18n/locales/en.json'; + +describe('Settings.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(Settings); + + // Assert + expect(container).toBeTruthy(); + }); + + it('should have an profile section', () => { + // Arrange + // Nothing to prepare + + // Act + render(Settings); + + // Assert + // There are multiple nodes with that name and I haven't determined the appropriate heading level + expect(screen.getAllByText(enMessages.settings.profile.headline)).not.toHaveLength(0); + }); + + describe('when switching the active setting', () => { + it('should not have an profile section', async () => { + // Arrange + // Nothing to prepare + + // Act + render(Settings); + const profileTileAndSection = screen.getAllByText( + enMessages.settings.profile.headline + ).length; + const notificationTile = screen.getByText(enMessages.settings.notifications.label); + notificationTile.click(); + // Wait for reactivity + await tick(); + + // Assert + expect(screen.queryAllByText(enMessages.settings.profile.headline).length).toBeLessThan( + profileTileAndSection + ); + }); + }); +}); diff --git a/tests/components/pages/Profile.test.ts b/tests/components/pages/Profile.test.ts index 3ae218c..084b840 100644 --- a/tests/components/pages/Profile.test.ts +++ b/tests/components/pages/Profile.test.ts @@ -10,9 +10,12 @@ * You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ +import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom'; +import { storePopup } from '@skeletonlabs/skeleton'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/svelte'; import { init, locale, register } from 'svelte-i18n'; +import { readable } from 'svelte/store'; import Profile from '../../../src/lib/components/pages/Profile.svelte'; import enMessages from '../../../src/lib/i18n/locales/en.json'; @@ -26,12 +29,24 @@ describe('Profile.svelte', () => { it('should mount', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - const { container } = render(Profile, { data }); + const { container } = render(Profile, { context, props }); // Assert expect(container).toBeTruthy(); @@ -39,12 +54,24 @@ describe('Profile.svelte', () => { it('should have a h1', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h1 = screen.getByRole('heading', { level: 1 }); // Assert @@ -54,12 +81,24 @@ describe('Profile.svelte', () => { it('should have a block button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: 'block' }); // Assert @@ -68,12 +107,24 @@ describe('Profile.svelte', () => { it('should have a report button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: 'report' }); // Assert @@ -83,12 +134,24 @@ describe('Profile.svelte', () => { // FIXME: Reenable once emoji was replaced with svelte-octicon it.skip('should have a like button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: enMessages.page.profile.activities.like }); // Assert @@ -98,12 +161,24 @@ describe('Profile.svelte', () => { describe('projects', () => { it('should have a h2', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h2 = screen.getByRole('heading', { level: 2, name: enMessages.page.profile.projects.heading @@ -115,12 +190,24 @@ describe('Profile.svelte', () => { it('should add a project', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const a = screen.getByRole('link', { name: 'Add a project' }); // Assert @@ -129,12 +216,24 @@ describe('Profile.svelte', () => { it('should import a project', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const a = screen.getByRole('link', { name: 'import a project' }); // Assert @@ -146,12 +245,24 @@ describe('Profile.svelte', () => { describe('history', () => { it('should have a h2', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h2 = screen.getByRole('heading', { level: 2, name: enMessages.page.profile.history.heading @@ -163,16 +274,28 @@ describe('Profile.svelte', () => { it('should have an entry for created account', () => { // Arrange - const data = { - user: { - created_with: 'Anvil', - instance: 'domain.example', - username: 'jane_doe' + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: { + created_with: 'Anvil', + instance: 'domain.example', + username: 'jane_doe' + } } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const li = screen.getByRole('listitem'); // Assert @@ -183,9 +306,9 @@ describe('Profile.svelte', () => { expect(li).toHaveTextContent( new RegExp( enMessages.page.profile.history.activities.setup.description - .replace('{username}', data.user.username) - .replace('{instance}', data.user.instance) - .replace('{created_with}', data.user.created_with) + .replace('{username}', props.data.user.username) + .replace('{instance}', props.data.user.instance) + .replace('{created_with}', props.data.user.created_with) ) ); }); diff --git a/tests/components/templates/Profile.test.ts b/tests/components/templates/Profile.test.ts index 944f235..0904ec1 100644 --- a/tests/components/templates/Profile.test.ts +++ b/tests/components/templates/Profile.test.ts @@ -10,9 +10,12 @@ * You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ +import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom'; +import { storePopup } from '@skeletonlabs/skeleton'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/svelte'; import { init, locale, register } from 'svelte-i18n'; +import { readable } from 'svelte/store'; import Profile from '../../../src/lib/components/templates/Profile.svelte'; import enMessages from '../../../src/lib/i18n/locales/en.json'; @@ -26,12 +29,24 @@ describe('Profile.svelte', () => { it('should mount', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - const { container } = render(Profile, { data }); + const { container } = render(Profile, { context, props }); // Assert expect(container).toBeTruthy(); @@ -39,12 +54,24 @@ describe('Profile.svelte', () => { it('should have a h1', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h1 = screen.getByRole('heading', { level: 1 }); // Assert @@ -54,12 +81,24 @@ describe('Profile.svelte', () => { it('should have a block button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: 'block' }); // Assert @@ -68,12 +107,24 @@ describe('Profile.svelte', () => { it('should have a report button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: 'report' }); // Assert @@ -83,12 +134,24 @@ describe('Profile.svelte', () => { // FIXME: Reenable once emoji was replaced with svelte-octicon it.skip('should have a like button', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const button = screen.getByRole('button', { name: enMessages.page.profile.activities.like }); // Assert @@ -98,12 +161,24 @@ describe('Profile.svelte', () => { describe('projects', () => { it('should have a h2', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h2 = screen.getByRole('heading', { level: 2, name: enMessages.page.profile.projects.heading @@ -115,12 +190,24 @@ describe('Profile.svelte', () => { it('should add a project', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const a = screen.getByRole('link', { name: 'Add a project' }); // Assert @@ -129,12 +216,24 @@ describe('Profile.svelte', () => { it('should import a project', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const a = screen.getByRole('link', { name: 'import a project' }); // Assert @@ -146,12 +245,24 @@ describe('Profile.svelte', () => { describe('history', () => { it('should have a h2', () => { // Arrange - const data = { - user: {} + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: {} + } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const h2 = screen.getByRole('heading', { level: 2, name: enMessages.page.profile.history.heading @@ -163,16 +274,28 @@ describe('Profile.svelte', () => { it('should have an entry for created account', () => { // Arrange - const data = { - user: { - created_with: 'Anvil', - instance: 'domain.example', - username: 'jane_doe' + // See https://testing-library.com/docs/svelte-testing-library/example#contexts + const modalStore = readable([]); + // See https://www.skeleton.dev/utilities/popups + storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow }); + + const props = { + data: { + user: { + created_with: 'Anvil', + instance: 'domain.example', + username: 'jane_doe' + } } }; + const context = new Map([ + ['modalStore', modalStore], + ['storePopup', storePopup] + ]); + // Act - render(Profile, { data }); + render(Profile, { context, props }); const li = screen.getByRole('listitem'); // Assert @@ -183,9 +306,9 @@ describe('Profile.svelte', () => { expect(li).toHaveTextContent( new RegExp( enMessages.page.profile.history.activities.setup.description - .replace('{username}', data.user.username) - .replace('{instance}', data.user.instance) - .replace('{created_with}', data.user.created_with) + .replace('{username}', props.data.user.username) + .replace('{instance}', props.data.user.instance) + .replace('{created_with}', props.data.user.created_with) ) ); });