Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions packages/web/src/pages/fb-share-page/FbSharePage.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { ReactNode } from 'react'

import { renderToStaticMarkup } from 'react-dom/server'
import { beforeEach, describe, expect, it, vi } from 'vitest'

import { FbSharePage } from './FbSharePage'

const account = vi.hoisted(() => ({ handle: undefined as string | undefined }))

vi.mock('@audius/common/api', () => ({
useCurrentAccountUser: () => ({ data: account.handle })
}))

vi.mock('@audius/common/utils', () => ({
route: { SIGN_IN_PAGE: '/signin', PRIVACY_POLICY: '/legal/privacy-policy' }
}))

vi.mock('@audius/harmony', () => ({
Text: ({ children }: { children: ReactNode }) => <p>{children}</p>,
Button: ({ children }: { children: ReactNode }) => <>{children}</>,
IconFacebook: () => null
}))

vi.mock('services/env', () => ({
env: {
PUBLIC_HOSTNAME: 'audius.co',
FACEBOOK_APP_ID: '3438219622966374'
}
}))

describe('Facebook profile sharing', () => {
beforeEach(() => {
account.handle = undefined
})

it('offers login and a public privacy policy before authentication', () => {
const html = renderToStaticMarkup(<FbSharePage />)
expect(html).toContain('href="/signin"')
expect(html).toContain('href="/legal/privacy-policy"')
expect(html).not.toContain('facebook.com/dialog/share')
})

it('renders a share link when account data becomes available without an SDK', () => {
renderToStaticMarkup(<FbSharePage />)
account.handle = 'review_account'
const html = renderToStaticMarkup(<FbSharePage />)
const href = html.match(/href="(https:\/\/www.facebook.com[^"]+)"/)?.[1]
expect(href).toBeDefined()
const url = new URL(href!.replaceAll('&amp;', '&'))
expect(url.pathname).toBe('/dialog/share')
expect(url.searchParams.get('app_id')).toBe('3438219622966374')
expect(url.searchParams.get('href')).toBe(
'https://audius.co/review_account'
)
expect(url.searchParams.get('redirect_uri')).toBe(
'https://audius.co/fb/share'
)
expect(html).toContain('Share to Facebook')
expect(html).toContain('rel="noopener noreferrer"')
expect(html).toContain('href="/legal/privacy-policy"')
expect(html).not.toContain('<script')
})
})
62 changes: 31 additions & 31 deletions packages/web/src/pages/fb-share-page/FbSharePage.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
import React, { useEffect } from 'react'

import { useCurrentAccountUser } from '@audius/common/api'
import { Text } from '@audius/harmony'
import cn from 'classnames'
import { route } from '@audius/common/utils'
import { Button, IconFacebook, Text } from '@audius/harmony'

import { env } from 'services/env'

import styles from './FbSharePage.module.css'

const PUBLIC_HOSTNAME = env.PUBLIC_HOSTNAME

const messages = {
share: 'Share your profile with your friends on Facebook!'
}

const injectScript = function () {
const scriptElement = document.createElement('script')
scriptElement.innerHTML = `(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v3.0";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));`
document.head.appendChild(scriptElement)
share: 'Share your profile with your friends on Facebook!',
button: 'Share to Facebook',
signIn: 'Log in to share your Audius profile',
privacy: 'Privacy Policy'
}

export const FbSharePage = () => {
useEffect(() => {
injectScript()
}, [])
const { data: handle } = useCurrentAccountUser({
select: (user) => user?.handle
})
const shareParams = new URLSearchParams({
app_id: env.FACEBOOK_APP_ID,
display: 'popup',
href: `https://${env.PUBLIC_HOSTNAME}/${encodeURIComponent(handle ?? '')}`,
redirect_uri: `https://${env.PUBLIC_HOSTNAME}/fb/share`
})

return (
<div className={styles.root}>
<div id='fb-root'></div>
<Text>{messages.share}</Text>
{handle ? (
<div
className={cn('fb-share-button', styles.share)}
data-href={`https://${PUBLIC_HOSTNAME}/${handle}`}
data-layout='button'
data-size='large'
/>
) : null}
<div className={styles.share}>
{handle ? (
<Button asChild iconLeft={IconFacebook}>
<a
href={`https://www.facebook.com/dialog/share?${shareParams}`}
target='_blank'
rel='noopener noreferrer'
>
{messages.button}
</a>
</Button>
) : (
<a href={route.SIGN_IN_PAGE}>{messages.signIn}</a>
)}
</div>
<div className={styles.share}>
<a href={route.PRIVACY_POLICY}>{messages.privacy}</a>
</div>
</div>
)
}
Loading