From 50f1c501a87ef5f5650750dbeca797e833ec7c3a Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Tue, 14 Nov 2023 12:39:09 +0100
Subject: refactor(components): replace Sharing with SharingWidget component

* all the widgets should have a coherent name
* fix mailto uri
* remove useless CSS
* add tests
---
 .../widgets/sharing-widget/sharing-widget.test.tsx | 167 +++++++++++++++++++++
 1 file changed, 167 insertions(+)
 create mode 100644 src/components/organisms/widgets/sharing-widget/sharing-widget.test.tsx

(limited to 'src/components/organisms/widgets/sharing-widget/sharing-widget.test.tsx')

diff --git a/src/components/organisms/widgets/sharing-widget/sharing-widget.test.tsx b/src/components/organisms/widgets/sharing-widget/sharing-widget.test.tsx
new file mode 100644
index 0000000..b8bc702
--- /dev/null
+++ b/src/components/organisms/widgets/sharing-widget/sharing-widget.test.tsx
@@ -0,0 +1,167 @@
+import { describe, expect, it } from '@jest/globals';
+import { render, screen as rtlScreen } from '../../../../../tests/utils';
+import { Heading, type SharingMedium } from '../../../atoms';
+import { SharingWidget, type SharingData } from './sharing-widget';
+
+const data: SharingData = {
+  excerpt: 'A post excerpt',
+  title: 'A post title',
+  url: 'https://sharing-website.test',
+};
+
+describe('SharingWidget', () => {
+  it('renders the widget heading and a list of links', () => {
+    const heading = 'dolorem necessitatibus voluptatem';
+    const headingLvl = 3;
+    const media = ['facebook', 'twitter'] satisfies SharingMedium[];
+
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={headingLvl}>{heading}</Heading>}
+        media={media}
+      />
+    );
+
+    expect(
+      rtlScreen.getByRole('heading', { level: headingLvl })
+    ).toHaveTextContent(heading);
+    expect(rtlScreen.getAllByRole('listitem')).toHaveLength(media.length);
+    expect(rtlScreen.getAllByRole('link')).toHaveLength(media.length);
+  });
+
+  it('can render a link to share on Diaspora', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['diaspora']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+
+    expect(link).toHaveTextContent('Share on Diaspora');
+    expect(link).toHaveAttribute(
+      'href',
+      `https://share.diasporafoundation.org/?title=${encodeURIComponent(
+        data.title
+      )}&url=${encodeURIComponent(data.url)}`
+    );
+  });
+
+  it('can render a link to share on Facebook', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['facebook']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+
+    expect(link).toHaveTextContent('Share on Facebook');
+    expect(link).toHaveAttribute(
+      'href',
+      `https://www.facebook.com/sharer/sharer.php?$u=${encodeURIComponent(
+        data.url
+      )}`
+    );
+  });
+
+  it('can render a link to share on Journal du Hacker', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['journal-du-hacker']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+
+    expect(link).toHaveTextContent('Share on Journal du Hacker');
+    expect(link).toHaveAttribute(
+      'href',
+      `https://www.journalduhacker.net/stories/new?title=${encodeURIComponent(
+        data.title
+      )}&url=${encodeURIComponent(data.url)}`
+    );
+  });
+
+  it('can render a link to share on LinkedIn', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['linkedin']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+
+    expect(link).toHaveTextContent('Share on LinkedIn');
+    expect(link).toHaveAttribute(
+      'href',
+      `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(
+        data.url
+      )}`
+    );
+  });
+
+  it('can render a link to share on Twitter', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['twitter']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+
+    expect(link).toHaveTextContent('Share on Twitter');
+    expect(link).toHaveAttribute(
+      'href',
+      `https://twitter.com/intent/tweet?text=${encodeURIComponent(
+        data.title
+      )}&url=${encodeURIComponent(data.url)}`
+    );
+  });
+
+  it('can render a link to share by Email', () => {
+    render(
+      <SharingWidget
+        data={data}
+        heading={<Heading level={3}>corrupti</Heading>}
+        media={['email']}
+      />
+    );
+
+    const link = rtlScreen.getByRole('link');
+    const subject = `You should read ${data.title}`;
+    const body = `${data.excerpt}\n\nRead more here: ${data.url}`;
+
+    expect(link).toHaveTextContent('Share by Email');
+    expect(link).toHaveAttribute(
+      'href',
+      `mailto:?body=${encodeURIComponent(body)}&subject=${encodeURIComponent(
+        subject
+      )}`
+    );
+  });
+
+  it('throws an error when a medium is invalid', () => {
+    expect(() =>
+      render(
+        <SharingWidget
+          data={data}
+          heading={<Heading level={3}>maxime</Heading>}
+          // @ts-expect-error -- Unsupported medium
+          media={['not-supported']}
+        />
+      )
+    ).toThrowError('Unsupported social media.');
+  });
+});
-- 
cgit v1.2.3

