]> git.r.bdr.sh - rbdr/forum/commitdiff
Add tests for first batch of components
authorRuben Beltran del Rio <redacted>
Mon, 19 Apr 2021 19:04:59 +0000 (21:04 +0200)
committerRuben Beltran del Rio <redacted>
Mon, 19 Apr 2021 19:04:59 +0000 (21:04 +0200)
- Glyph
- Forum List
- Error Block
- Post

jest.config.json
src/components/error_block/error_block.test.js [new file with mode: 0644]
src/components/forum_list/forum_list.svelte
src/components/forum_list/forum_list.test.js [new file with mode: 0644]
src/components/glyph/glyph.svelte
src/components/glyph/glyph.test.js [new file with mode: 0644]
src/components/post/post.svelte
src/components/post/post.test.js [new file with mode: 0644]
src/components/post_content/post_content.svelte [deleted file]
src/routes/$layout.svelte

index 49074845bf82321065cafafafe6d2098976820c0..46f62f4a66b3befab4d25df0b985ecccfc9e23f2 100644 (file)
@@ -7,5 +7,8 @@
     "^\\$lib(.*)$": "<rootDir>/src/lib$1",
     "^\\$app(.*)$": [".svelte/dev/runtime/app/*", ".svelte/build/runtime/app/*"]
   },
     "^\\$lib(.*)$": "<rootDir>/src/lib$1",
     "^\\$app(.*)$": [".svelte/dev/runtime/app/*", ".svelte/build/runtime/app/*"]
   },
-  "moduleFileExtensions": ["js", "svelte"]
+  "moduleFileExtensions": ["js", "svelte"],
+  "moduleNameMapper": {
+    "^\\$(.*)$": "<rootDir>/src$1"
+  }
 }
 }
diff --git a/src/components/error_block/error_block.test.js b/src/components/error_block/error_block.test.js
new file mode 100644 (file)
index 0000000..bd2fe7a
--- /dev/null
@@ -0,0 +1,20 @@
+import '@testing-library/jest-dom/extend-expect';
+
+import { render } from '@testing-library/svelte';
+import '$/config/i18n';
+
+import ErrorBlock from './error_block.svelte';
+
+describe('Glyph component', () => {
+
+  test('Should act as an image', () => {
+
+    const results = render(ErrorBlock, { props: {
+      message: 'An error has, sadly, destroyed everything.'
+    } });
+
+    expect(results.getByText('An error has, sadly, destroyed everything.'))
+      .toBeVisible();
+  });
+});
+
index 7bfb7b238148d66e718b71773de189680302cfcf..a33358cbbac92876cd1b65b44583210939e1b7fa 100644 (file)
@@ -1,36 +1,22 @@
 <script>
 <script>
-       import { _ } from 'svelte-i18n';
-       import { forums } from '$/stores/forums';
-       import Loader from '$/components/loader/loader.svelte';
-       import ErrorBlock from '$/components/error_block/error_block.svelte';
+import { _ } from 'svelte-i18n';
+export let forums;
+
+$: sortedForums = forums.sort((a, b) => a.position - b.position);
 </script>
 
 </script>
 
-<nav title={$_('forum_list.title')}>
-       {#if $forums.loading}
-               <Loader />
-       {/if}
-       {#if $forums.error}
-               <ErrorBlock message={$_('forum_list.error.unavailable')} />
-       {/if}
-       <ul>
-               {#each $forums.data as forum}
-                       <li>
-                               <a href="/f/{forum.id}">
-                                       <span aria-hidden="true" class="navigation-glyph {forum.glyph}">{forum.glyph}</span>
-                                       <span class="navigation-label">{$_(forum.label)}</span>
-                               </a>
-                       </li>
-               {/each}
-       </ul>
-</nav>
+<ul>
+  {#each sortedForums as forum}
+    <li>
+      <a href="/f/{forum.id}">
+        <span aria-hidden="true" class="navigation-glyph {forum.glyph}">{forum.glyph}</span>
+        <span class="navigation-label">{$_(forum.label)}</span>
+      </a>
+    </li>
+  {/each}
+</ul>
 
 <style>
 
 <style>
-       nav {
-               grid-column: col-start 1;
-               grid-row: 2;
-               border-right: 1px solid black;
-       }
-
        ul {
                padding: 0;
        }
        ul {
                padding: 0;
        }
diff --git a/src/components/forum_list/forum_list.test.js b/src/components/forum_list/forum_list.test.js
new file mode 100644 (file)
index 0000000..3066e8a
--- /dev/null
@@ -0,0 +1,90 @@
+import '@testing-library/jest-dom/extend-expect';
+
+import { render } from '@testing-library/svelte';
+import '$/config/i18n';
+
+import { addMessages } from 'svelte-i18n';
+
+import ForumList from './forum_list.svelte';
+
+const internals = {
+  results: null
+};
+
+describe('Glyph component', () => {
+
+  beforeAll(() => {
+
+    addMessages('en', {
+      'test_forums.yes': 'Absolutely yes',
+      'test_forums.no': 'No, not at all',
+      'test_forums.maybe': 'OK, maybe...'
+    });
+  });
+
+  beforeEach(() => {
+
+    internals.results = render(ForumList, { props: {
+      forums: [
+        {
+          id: 'yes',
+          glyph: '☆',
+          label: 'test_forums.yes',
+          position: 2
+        },
+        {
+          id: 'no',
+          glyph: '◯',
+          label: 'test_forums.no',
+          position: 0
+        },
+        {
+          id: 'maybe',
+          glyph: '⏀',
+          label: 'test_forums.maybe',
+          position: 1
+        }
+      ]
+    } });
+  });
+
+  test('It should display each forum according to their position', () => {
+
+    expect(internals.results.container)
+      .toHaveTextContent(/^◯.+⏀.+☆.+$/);
+  });
+
+  test('It should translate forum labels', () => {
+
+    expect(internals.results.getByText('Absolutely yes')).toBeVisible();
+    expect(internals.results.getByText('No, not at all')).toBeVisible();
+    expect(internals.results.getByText('OK, maybe...')).toBeVisible();
+  });
+
+  test('It should display forum glyphs', () => {
+
+    expect(internals.results.getByText('☆')).toBeVisible();
+    expect(internals.results.getByText('◯')).toBeVisible();
+    expect(internals.results.getByText('⏀')).toBeVisible();
+  });
+
+  test('Label should be a permalink to the forum', () => {
+
+    expect(internals.results.getByText('Absolutely yes').closest('a'))
+      .toHaveAttribute('href', '/f/yes');
+    expect(internals.results.getByText('No, not at all').closest('a'))
+      .toHaveAttribute('href', '/f/no');
+    expect(internals.results.getByText('OK, maybe...').closest('a'))
+      .toHaveAttribute('href', '/f/maybe');
+  });
+
+  test('Glyph should be a permalink to the forum', () => {
+
+    expect(internals.results.getByText('☆').closest('a'))
+      .toHaveAttribute('href', '/f/yes');
+    expect(internals.results.getByText('◯').closest('a'))
+      .toHaveAttribute('href', '/f/no');
+    expect(internals.results.getByText('⏀').closest('a'))
+      .toHaveAttribute('href', '/f/maybe');
+  });
+});
index e430d428bc39e9d78888ab2f522f4c303d45b354..60f99ebf8efb9cea546438fe2cbb57cab4e425d3 100644 (file)
@@ -5,7 +5,7 @@
        export let uuid;
 </script>
 
        export let uuid;
 </script>
 
-<div class="glyphicon" aria-hidden="true" title={$_('glyph.title')}>
+<div class="glyphicon" role="img" aria-label={$_('glyph.title')} title={$_('glyph.title')}>
        {#each getGlyphHash(uuid) as fragment}
                <span class={fragment.glyph} style="color: {fragment.color} ">
                        {fragment.glyph}
        {#each getGlyphHash(uuid) as fragment}
                <span class={fragment.glyph} style="color: {fragment.color} ">
                        {fragment.glyph}
diff --git a/src/components/glyph/glyph.test.js b/src/components/glyph/glyph.test.js
new file mode 100644 (file)
index 0000000..93ddc8a
--- /dev/null
@@ -0,0 +1,32 @@
+import '@testing-library/jest-dom/extend-expect';
+
+import { render } from '@testing-library/svelte';
+import '$/config/i18n';
+
+import Glyph from './glyph.svelte';
+
+const internals = {
+  results: null
+};
+
+describe('Glyph component', () => {
+
+  beforeEach(() => {
+
+    internals.results = render(Glyph, { props: {
+      uuid: '9fb14ebc-bc64-400b-915f-d429ec44b8fe'
+    } });
+  });
+
+  test('Should act as an image', () => {
+
+    expect(internals.results.getByRole('img'))
+      .toBeVisible();
+  });
+
+  test('Should render 4 glyphs', () => {
+
+    expect(internals.results.getByRole('img'))
+      .toHaveTextContent(/^. . . .$/);
+  });
+});
index 5d8ef1cb179d1e1bdf6cc033b1078ec7d6c949fb..fd9e580f906696c68e8e67fe8166b0e43e784453 100644 (file)
                        {timestampToISO(post.created_at)}
                </a>
        </time>
                        {timestampToISO(post.created_at)}
                </a>
        </time>
-       {#if post.topic}
-               <span class="h-card">
-                       ({$_('post.topic_location')} <a href="/t/{post.topic.id}">{post.topic.title}</a>.)
-               </span>
-       {/if}
+  <span>
+    ({$_('post.topic_location')} <a href="/t/{post.topic.id}">{post.topic.title}</a>.)
+  </span>
 </aside>
 <article
        class="e-content"
 </aside>
 <article
        class="e-content"
diff --git a/src/components/post/post.test.js b/src/components/post/post.test.js
new file mode 100644 (file)
index 0000000..3a76482
--- /dev/null
@@ -0,0 +1,85 @@
+import '@testing-library/jest-dom/extend-expect';
+
+import { render } from '@testing-library/svelte';
+import '$/config/i18n';
+
+import Post from './post.svelte';
+
+const internals = {
+  basicPost: {
+    id: 'e5a19d53-4c9a-4be8-afa5-00942ea3afa4',
+    text: 'This is an example post qwerty',
+    created_at: Date.UTC(2021, 3, 19, 6, 6, 6, 666).valueOf(),
+    author: {
+      handle: 'very_cool_user',
+      id: 'b01bdb48-4b5e-46a4-97f3-6db789bcd33b'
+    },
+    topic: {
+      id: '35d3c3eb-e486-42ef-994c-d8ab1f1e167a',
+      title: 'Parent topic, yes'
+    }
+  },
+
+  results: null
+};
+
+describe('Post component', () => {
+
+  beforeEach(() => {
+
+    internals.results = render(Post, { props: {
+      post: internals.basicPost
+    } });
+  });
+
+  test('Should display the text of the post', () => {
+
+    expect(internals.results.getByText('This is an example post qwerty')).toBeVisible();
+  });
+
+  test('Should display date of the post', () => {
+
+    expect(internals.results.getByText('2021-04-19T06:06:06.666Z'))
+      .toBeVisible();
+  });
+
+  test('Date of post should be a permalink to the post', () => {
+
+    expect(internals.results.getByText('2021-04-19T06:06:06.666Z').closest('a'))
+      .toHaveAttribute('href', '/p/e5a19d53-4c9a-4be8-afa5-00942ea3afa4');
+  });
+
+  test('Should display the glyph of the post author', () => {
+
+    const glyphicon = internals.results.getByRole('img');
+
+    expect(glyphicon)
+      .toBeVisible();
+    expect(glyphicon)
+      .toHaveTextContent(/^. . . .$/);
+  });
+
+  test('Should display author handle', () => {
+
+    expect(internals.results.getByText('very_cool_user'))
+      .toBeVisible();
+  });
+
+  test('Author handle should have a permalink to topic', () => {
+
+    expect(internals.results.getByText('very_cool_user').closest('a'))
+      .toHaveAttribute('href', '/a/very_cool_user');
+  });
+
+  test('Should display parent topic title', () => {
+
+    expect(internals.results.getByText('Parent topic, yes'))
+      .toBeVisible();
+  });
+
+  test('Parent topic title should have a permalink to topic', () => {
+
+    expect(internals.results.getByText('Parent topic, yes').closest('a'))
+      .toHaveAttribute('href', '/t/35d3c3eb-e486-42ef-994c-d8ab1f1e167a');
+  });
+});
diff --git a/src/components/post_content/post_content.svelte b/src/components/post_content/post_content.svelte
deleted file mode 100644 (file)
index 5d8ef1c..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-<script>
-       export let post;
-       export let index = 0;
-       export let count = 1;
-
-       import { _ } from 'svelte-i18n';
-       import Glyph from '$/components/glyph/glyph.svelte';
-
-       const timestampToISO = (timestamp) => new Date(timestamp).toISOString();
-</script>
-
-<aside
-       class="post-meta"
-       title={$_('post.metadata_title', { values: { count: index + 1, total: count } })}
->
-       <Glyph uuid={post.author.id} />
-       <span class="h-card">
-               {$_('post.author_credit')}
-               <a href="/a/{post.author.handle}" class="p-nickname u-url">{post.author.handle}</a>.
-       </span>
-       <time role="presentation" class="dt-published" datetime={timestampToISO(post.created_at)}>
-               <a title={$_('post.permalink_title')} href="/p/{post.id}">
-                       {timestampToISO(post.created_at)}
-               </a>
-       </time>
-       {#if post.topic}
-               <span class="h-card">
-                       ({$_('post.topic_location')} <a href="/t/{post.topic.id}">{post.topic.title}</a>.)
-               </span>
-       {/if}
-</aside>
-<article
-       class="e-content"
-       title={$_('post.title', {
-               values: { count: index + 1, total: count, author: post.author.handle }
-       })}
->
-       {post.text}
-</article>
-<hr />
-
-<style>
-       .post-meta * {
-               vertical-align: top;
-       }
-
-       article {
-               white-space: pre;
-       }
-</style>
index 49ceb4921851f8209a9c2dba4796631d8ff85dc3..8fd2ae04c247ac23f8a08af1faf2076335663d6b 100644 (file)
@@ -1,6 +1,12 @@
 <script>
        import '$/config/i18n';
 <script>
        import '$/config/i18n';
+
        import { isLoading } from 'svelte-i18n';
        import { isLoading } from 'svelte-i18n';
+       import { _ } from 'svelte-i18n';
+
+       import { forums } from '$/stores/forums';
+
+       import ErrorBlock from '$/components/error_block/error_block.svelte';
        import ForumList from '$/components/forum_list/forum_list.svelte';
        import Header from '$/components/header/header.svelte';
        import Loader from '$/components/loader/loader.svelte';
        import ForumList from '$/components/forum_list/forum_list.svelte';
        import Header from '$/components/header/header.svelte';
        import Loader from '$/components/loader/loader.svelte';
        <main>
                <slot />
        </main>
        <main>
                <slot />
        </main>
-       <ForumList />
+  <nav title={$_('forum_list.title')}>
+    {#if $forums.loading}
+      <Loader />
+    {/if}
+    {#if $forums.error}
+      <ErrorBlock message={$_('forum_list.error.unavailable')} />
+    {/if}
+    {#if $forums.data}
+      <ForumList forums={$forums.data} />
+    {/if}
+  </nav>
        <Footer />
 {/if}
        <Footer />
 {/if}
+
+<style>
+       nav {
+               grid-column: col-start 1;
+               grid-row: 2;
+               border-right: 1px solid black;
+       }
+</style>