Skip to content

Commit

Permalink
Merge pull request #713 from Financial-Times/share-modal-rebrand-release
Browse files Browse the repository at this point in the history
RELEASE: share modal rebrand
  • Loading branch information
jkerr321 authored Jul 6, 2023
2 parents b4c402a + f5e1171 commit ff277bc
Show file tree
Hide file tree
Showing 47 changed files with 1,716 additions and 209 deletions.
207 changes: 87 additions & 120 deletions components/x-gift-article/__tests__/x-gift-article.test.jsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
const fetchMock = require('fetch-mock')
const { h } = require('@financial-times/x-engine')
const { mount } = require('@financial-times/x-test-utils/enzyme')
import fetchMock from 'fetch-mock'
import { h } from '@financial-times/x-engine'
import { mount } from '@financial-times/x-test-utils/enzyme'
import { ShareArticleModal } from '../dist/GiftArticle.cjs'

const { GiftArticle } = require('../dist/GiftArticle.cjs.js')
jest.mock('@financial-times/o-share', () => jest.fn())

const articleId = 'article id'
const articleUrl = 'https://www.ft.com/content/blahblahblah'
const articleUrlRedeemed = 'https://gift-url-redeemed'
const nonGiftArticleUrl = `${articleUrl}?shareType=nongift`

const baseArgs = {
title: 'Title',
title: 'Share this article:',
isFreeArticle: false,
article: {
title: 'Article Title Blah Blah Blah',
id: articleId,
url: articleUrl
url: articleUrl,
title: 'Equinor and Daimler Truck cut Russia ties as Volvo and JLR halt car deliveries'
},
id: 'base-gift-article-static-id',
enterpriseApiBaseUrl: `https://enterprise-sharing-api.ft.com`
}

Expand All @@ -27,70 +29,55 @@ describe('x-gift-article', () => {
actions = {}

fetchMock
.get('/article/gift-credits', {
.get('path:/article/gift-credits', {
allowance: 20,
consumedCredits: 5,
remainingCredits: 15,
renewalDate: '2018-08-01T00:00:00Z'
})
.get(`/article/shorten-url/${encodeURIComponent(articleUrlRedeemed)}`, {
.get(`path:/article/shorten-url/${encodeURIComponent(articleUrlRedeemed)}`, {
shortenedUrl: 'https://shortened-gift-url'
})
.get(`/article/shorten-url/${encodeURIComponent(nonGiftArticleUrl)}`, {
.get(`path:/article/shorten-url/${encodeURIComponent(nonGiftArticleUrl)}`, {
shortenedUrl: 'https://shortened-non-gift-url'
})
.get(`/article/gift-link/${encodeURIComponent(articleId)}`, {
.get(`path:/article/gift-link/${encodeURIComponent(articleId)}`, {
redemptionUrl: articleUrlRedeemed,
redemptionLimit: 3,
remainingAllowance: 1
})
.get('https://enterprise-sharing-api.ft.com/v1/users/me/allowance', {
.get('path:/v1/users/me/allowance', {
limit: 120,
hasCredits: true,
firstTimeUser: true
firstTimeUser: false
})
.post('https://enterprise-sharing-api.ft.com/v1/shares', {
.post('path:/v1/shares', {
url: articleUrlRedeemed,
redeemLimit: 120
})
.post('path:/v1/copy-annotations', {
annotationsCopyResult: []
})
})

afterEach(() => {
fetchMock.reset()
})

it('displays the correct title', async () => {
it('displays the article title', async () => {
const args = {
...baseArgs,
title: 'A given test title'
...baseArgs
}

const subject = mount(<GiftArticle {...args} />)

expect(subject.find('h2').text()).toEqual('A given test title')
})
args.article.title = 'A given test article title'

it('displays the mobile share links when showMobileShareLinks is true', async () => {
const args = {
...baseArgs,
showMobileShareLinks: true
}
const subject = mount(<GiftArticle {...args} />)
const subject = mount(<ShareArticleModal {...args} />)

expect(subject.find('div.x-gift-article-mobile-share-buttons').length).toEqual(1)
})

it('does not display the mobile share links when showMobileShareLinks is false', async () => {
const args = {
...baseArgs,
showMobileShareLinks: false
}
const subject = mount(<GiftArticle {...args} />)

expect(subject.find('div.x-gift-article-mobile-share-buttons').length).toEqual(0)
expect(subject.find('h2').text()).toEqual('A given test article title')
})

it('should call correct endpoints on activate', async () => {
mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()

Expand All @@ -100,126 +87,106 @@ describe('x-gift-article', () => {
expect(fetchMock.called('/article/gift-credits')).toBe(true)
})

it('should call showGiftUrlSection and show correct html element', async () => {
const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
it('should call shortenNonGiftUrl and display correct url', async () => {
const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()
await actions.showNonGiftUrlSection()
await actions.shortenNonGiftUrl()

expect(actions.showGiftUrlSection).toBeDefined()
await actions.showGiftUrlSection()
subject.update()

expect(subject.find('div[data-section-id="giftLink"]')).toHaveLength(1)
const input = subject.find('input#share-link')
expect(input.prop('value')).toEqual('https://shortened-non-gift-url')
})

it('should call showEnterpriseUrlSection and show correct html element', async () => {
const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
it('should call createGiftUrl and display correct url', async () => {
const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()
await actions.createGiftUrl()

expect(actions.showEnterpriseUrlSection).toBeDefined()
await actions.showEnterpriseUrlSection()
subject.update()

expect(subject.find('div[data-section-id="enterpriseLink"]')).toHaveLength(1)
})

it('enterpriseLink radio button is not shown for non-enterprise users', async () => {
const args = {
...baseArgs,
enterpriseApiBaseUrl: undefined
}

const subject = mount(<GiftArticle {...args} actionsRef={(a) => Object.assign(actions, a)} />)
const input = subject.find('input#share-link')

expect(subject.find('input#enterpriseLink')).toHaveLength(0)
expect(subject.find('input#giftLink')).toHaveLength(1)
expect(subject.find('input#nonGiftLink')).toHaveLength(1)
expect(input.prop('value')).toEqual('https://shortened-gift-url')
})

it('should call showNonGiftUrlSection and show correct html element', async () => {
const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
await actions.activate()

expect(actions.showNonGiftUrlSection).toBeDefined()
await actions.showNonGiftUrlSection()
it('should call createEnterpriseUrl and display correct url', async () => {
const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
expect(actions.createEnterpriseUrl).toBeDefined()
await actions.createEnterpriseUrl()

subject.update()

expect(subject.find('div[data-section-id="nonGiftLink"]')).toHaveLength(1)
const input = subject.find('input#share-link')
expect(input.prop('value')).toEqual('https://gift-url-redeemed')
})

it('should call createGiftUrl and display correct url', async () => {
const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
expect(actions.createGiftUrl).toBeDefined()
await actions.createGiftUrl()
it('when credits are available, an alert is not shown', async () => {
const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()

subject.update()

const input = subject.find('input#share-link')
expect(input.prop('value')).toEqual('https://shortened-gift-url')
expect(subject.find('#no-credit-alert')).not.toExist()
})

it('should call createEnterpriseUrl and display correct url', async () => {
const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
expect(actions.createEnterpriseUrl).toBeDefined()
await actions.createEnterpriseUrl()
it('when no credits are available, an alert is shown', async () => {
fetchMock
.get(
'path:/article/gift-credits',
{
allowance: 20,
consumedCredits: 20,
remainingCredits: 0,
renewalDate: '2018-08-01T00:00:00Z'
},
{ overwriteRoutes: true }
)
.get(
'path:/v1/users/me/allowance',
{
limit: 120,
hasCredits: false,
firstTimeUser: false
},
{ overwriteRoutes: true }
)

const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

await actions.activate()

subject.update()

const input = subject.find('input#share-link')
expect(input.prop('value')).toEqual('https://gift-url-redeemed')
expect(subject.find('#no-credit-alert')).toExist()
})

it('when no gift-credits are available, a message is shown', async () => {
fetchMock.get(
'/article/gift-credits',
{
allowance: 20,
consumedCredits: 20,
remainingCredits: 0,
renewalDate: '2018-08-01T00:00:00Z'
},
{ overwriteRoutes: true }
)
it('displays the social share buttons', async () => {
const subject = mount(<ShareArticleModal {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)

const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
await actions.activate()

expect(actions.showGiftUrlSection).toBeDefined()
await actions.showGiftUrlSection()
await actions.shortenNonGiftUrl()

subject.update()

expect(subject.find('input#share-link')).toHaveLength(0)
expect(
subject.find('div.x-gift-article-message').text().includes('You’ve used all your gift article credits')
).toBe(true)
expect(subject.find('#social-share-buttons')).toExist()
})

it('when no enterprise credits are available, a message is shown', async () => {
fetchMock.get(
`https://enterprise-sharing-api.ft.com/v1/users/me/allowance`,
{
limit: 120,
hasCredits: false,
firstTimeUser: false
},
{ overwriteRoutes: true }
)
it('should display the free article message when isFreeArticle is true', async () => {
const args = {
...baseArgs,
isFreeArticle: true
}
const subject = mount(<ShareArticleModal {...args} actionsRef={(a) => Object.assign(actions, a)} />)

const subject = mount(<GiftArticle {...baseArgs} actionsRef={(a) => Object.assign(actions, a)} />)
await actions.activate()

expect(actions.showEnterpriseUrlSection).toBeDefined()
await actions.showEnterpriseUrlSection()
subject.update()

expect(subject.find('input#share-link')).toHaveLength(0)
expect(
subject
.find('div.x-gift-article-message')
.text()
.includes('Your organisation has run out of share credits')
).toBe(true)
expect(subject.find('#free-article-alert')).toExist()
expect(subject.find('#share-with-non-subscribers-checkbox')).not.toExist()
})
})
11 changes: 6 additions & 5 deletions components/x-gift-article/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "dist/GiftArticle.cjs.js",
"browser": "dist/GiftArticle.es5.js",
"module": "dist/GiftArticle.esm.js",
"style": "src/GiftArticle.scss",
"style": "src/main.scss",
"scripts": {
"build": "node rollup.js",
"start": "node rollup.js --watch",
Expand All @@ -23,10 +23,10 @@
},
"devDependencies": {
"@financial-times/o-buttons": "^7.2.2",
"@financial-times/o-forms": "^9.2.3",
"@financial-times/o-forms": "^9.11.0",
"@financial-times/o-labels": "^6.2.2",
"@financial-times/o-loading": "^5.2.1",
"@financial-times/o-message": "^5.2.1",
"@financial-times/o-message": "^5.4.2",
"@financial-times/o-normalise": "^3.2.2",
"@financial-times/o-typography": "^7.4.1",
"@financial-times/x-rollup": "file:../../packages/x-rollup",
Expand All @@ -44,11 +44,12 @@
"@financial-times/o-banner": "^4.4.9",
"@financial-times/o-buttons": "^7.2.2",
"@financial-times/o-colors": "^6.6.0",
"@financial-times/o-forms": "^9.2.3",
"@financial-times/o-forms": "^9.11.0",
"@financial-times/o-labels": "^6.2.2",
"@financial-times/o-loading": "^5.2.1",
"@financial-times/o-message": "^5.2.1",
"@financial-times/o-message": "^5.4.2",
"@financial-times/o-normalise": "^3.2.2",
"@financial-times/o-share": "^9.0.2",
"@financial-times/o-typography": "^7.4.1"
}
}
1 change: 0 additions & 1 deletion components/x-gift-article/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ Property | Type | Required | Note
--------------------------|---------|----------|----
`isFreeArticle` | Boolean | yes | Only non gift form is displayed when this value is `true`.
`article` | Object | yes | Must contain `id`, `title` and `url` properties
`showMobileShareLinks` | Boolean | no | For ft.com on mobile sharing.
`nativeShare` | Boolean | no | This is a property for App to display Native Sharing.
`apiProtocol` | String | no | The protocol to use when making requests to the gift article and URL shortening services. Ignored if `apiDomain` is not set.
`apiDomain` | String | no | The domain to use when making requests to the gift article and URL shortening services.
Expand Down
10 changes: 7 additions & 3 deletions components/x-gift-article/src/CopyConfirmation.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { h } from '@financial-times/x-engine'

export default ({ hideCopyConfirmation }) => (
export default ({ hideCopyConfirmation, isArticleSharingUxUpdates }) => (
<div
className="o-message o-message--alert o-message--success x-gift-article__copy-confirmation"
className="o-message o-message--alert o-message--success share-article-dialog__copy-confirmation-alert"
role="alert"
>
<div className="o-message__container">
<div className="o-message__content">
<p className="o-message__content-main">
<span className="o-message__content-highlight">The link has been copied to your clipboard</span>
{isArticleSharingUxUpdates ? (
<span>Link copied to clipboard.</span>
) : (
<span className="o-message__content-highlight">Link copied to clipboard.</span>
)}
</p>
</div>

Expand Down
4 changes: 2 additions & 2 deletions components/x-gift-article/src/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default (props) => (
shareType={props.shareType}
hasHighlights={props.hasHighlights}
includeHighlights={props.includeHighlights}
includeHighlightsHandler={props.actions.includeHighlightsHandler}
setIncludeHighlights={props.actions.setIncludeHighlights}
isGiftUrlCreated={props.isGiftUrlCreated}
saveHighlightsHandler={props.actions.saveHighlightsHandler}
showHighlightsRecipientMessage={props.showHighlightsRecipientMessage}
Expand Down Expand Up @@ -60,6 +60,6 @@ export default (props) => (
</div>
)}

{props.showMobileShareLinks && <MobileShareButtons mobileShareLinks={props.mobileShareLinks} />}
<MobileShareButtons mobileShareLinks={props.mobileShareLinks} />
</div>
)
Loading

0 comments on commit ff277bc

Please sign in to comment.