aboutsummaryrefslogtreecommitdiff
path: root/src/lib/components/post
diff options
context:
space:
mode:
authorRuben Beltran del Rio <ruben@unlimited.pizza>2022-05-01 00:56:06 +0200
committerRuben Beltran del Rio <ruben@unlimited.pizza>2022-05-01 00:56:06 +0200
commita7cf03c192470cbab13edeb1aec99e0c66dede10 (patch)
tree581b4430d1de958dcb666bae80a7678332134602 /src/lib/components/post
parent010f307346e525ac2e4239a0549d2c1a4d6d102b (diff)
Update / use typescript
Diffstat (limited to 'src/lib/components/post')
-rw-r--r--src/lib/components/post/post.svelte50
-rw-r--r--src/lib/components/post/post.test.ts128
2 files changed, 178 insertions, 0 deletions
diff --git a/src/lib/components/post/post.svelte b/src/lib/components/post/post.svelte
new file mode 100644
index 0000000..4e6c28f
--- /dev/null
+++ b/src/lib/components/post/post.svelte
@@ -0,0 +1,50 @@
+<script lang="ts">
+ export let post;
+ export let index = 0;
+ export let count = 1;
+
+ import { _ } from 'svelte-i18n';
+ import Glyph from '$lib/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>
+ ({$_('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>
diff --git a/src/lib/components/post/post.test.ts b/src/lib/components/post/post.test.ts
new file mode 100644
index 0000000..d43583e
--- /dev/null
+++ b/src/lib/components/post/post.test.ts
@@ -0,0 +1,128 @@
+/**
+ * @jest-environment jsdom
+ */
+
+import '@testing-library/jest-dom/extend-expect';
+
+import { cleanup, render } from '@testing-library/svelte';
+import '$lib/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'
+ }
+ },
+ postWithoutTopic: {
+ id: '9e52e38e-9007-4a20-bbf1-cea4e2f950f3',
+ text: 'This is a post without a topic',
+ created_at: Date.UTC(2022, 8, 21, 4, 3, 1, 340).valueOf(),
+ author: {
+ handle: 'my_normal_user',
+ id: '121f8f97-de02-4102-b25d-f34fd619009b'
+ }
+ },
+
+ 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');
+ });
+
+ test('Parent topic title should have a permalink to topic', () => {
+
+ cleanup();
+ internals.results = render(Post, { props: {
+ post: internals.postWithoutTopic
+ } });
+
+ expect(internals.results.queryByText('Parent topic, yes'))
+ .toBe(null);
+ });
+
+ test('It should default to 1/1 when no index or count is passed', () => {
+
+ expect(internals.results.getByTitle('Post 1 of 1 by very_cool_user'))
+ .toBeVisible();
+ });
+
+ test('Parent topic title should have a permalink to topic', () => {
+
+ cleanup();
+ internals.results = render(Post, { props: {
+ index: 2,
+ count: 5,
+ post: internals.postWithoutTopic
+ } });
+
+ expect(internals.results.getByTitle('Post 3 of 5 by my_normal_user'))
+ .toBeVisible();
+ });
+});