diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 35fb4728..c3eac779 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -5,7 +5,7 @@ import { MercureInfoType } from '../mercure/reducers/mercureInfo'; import { bindToMercureTopic } from '../mercure/helpers'; import { SettingsType } from '../settings/reducers/settings'; import { shortUrlVisitsType } from './reducers/shortUrlVisits'; -import VisitsHeader from './VisitsHeader'; +import ShortUrlVisitsHeader from './ShortUrlVisitsHeader'; import { shortUrlDetailType } from './reducers/shortUrlDetail'; const propTypes = { @@ -67,7 +67,7 @@ const ShortUrlVisits = (VisitsStats) => { return ( - + ); }; diff --git a/src/visits/ShortUrlVisitsHeader.js b/src/visits/ShortUrlVisitsHeader.js new file mode 100644 index 00000000..13b381a0 --- /dev/null +++ b/src/visits/ShortUrlVisitsHeader.js @@ -0,0 +1,52 @@ +import { UncontrolledTooltip } from 'reactstrap'; +import Moment from 'react-moment'; +import React from 'react'; +import PropTypes from 'prop-types'; +import { ExternalLink } from 'react-external-link'; +import { shortUrlDetailType } from './reducers/shortUrlDetail'; +import { shortUrlVisitsType } from './reducers/shortUrlVisits'; +import VisitsHeader from './VisitsHeader'; +import './ShortUrlVisitsHeader.scss'; + +const propTypes = { + shortUrlDetail: shortUrlDetailType.isRequired, + shortUrlVisits: shortUrlVisitsType.isRequired, + goBack: PropTypes.func.isRequired, +}; + +export default function ShortUrlVisitsHeader({ shortUrlDetail, shortUrlVisits, goBack }) { + const { shortUrl, loading } = shortUrlDetail; + const { visits } = shortUrlVisits; + const shortLink = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; + const longLink = shortUrl && shortUrl.longUrl ? shortUrl.longUrl : ''; + + const renderDate = () => ( + + + {shortUrl.dateCreated} + + + {shortUrl.dateCreated} + + + ); + const visitsStatsTitle = ( + + Visits for + + ); + + return ( + +
+
Created: {renderDate()}
+
+ Long URL:{' '} + {loading && Loading...} + {!loading && } +
+
+ ); +} + +ShortUrlVisitsHeader.propTypes = propTypes; diff --git a/src/visits/ShortUrlVisitsHeader.scss b/src/visits/ShortUrlVisitsHeader.scss new file mode 100644 index 00000000..cb223b60 --- /dev/null +++ b/src/visits/ShortUrlVisitsHeader.scss @@ -0,0 +1,3 @@ +.short-url-visits-header__created-at { + cursor: default; +} diff --git a/src/visits/VisitsHeader.js b/src/visits/VisitsHeader.js index 84752c1c..9c6d1c78 100644 --- a/src/visits/VisitsHeader.js +++ b/src/visits/VisitsHeader.js @@ -1,67 +1,41 @@ -import { Button, Card, UncontrolledTooltip } from 'reactstrap'; -import Moment from 'react-moment'; +import { Button, Card } from 'reactstrap'; import React from 'react'; import PropTypes from 'prop-types'; -import { ExternalLink } from 'react-external-link'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faArrowLeft } from '@fortawesome/free-solid-svg-icons'; import ShortUrlVisitsCount from '../short-urls/helpers/ShortUrlVisitsCount'; -import { shortUrlDetailType } from './reducers/shortUrlDetail'; -import { shortUrlVisitsType } from './reducers/shortUrlVisits'; -import './VisitsHeader.scss'; +import { shortUrlType } from '../short-urls/reducers/shortUrlsList'; +import { VisitType } from './types'; const propTypes = { - shortUrlDetail: shortUrlDetailType.isRequired, - shortUrlVisits: shortUrlVisitsType.isRequired, + visits: PropTypes.arrayOf(VisitType).isRequired, goBack: PropTypes.func.isRequired, + title: PropTypes.node.isRequired, + children: PropTypes.node, + shortUrl: shortUrlType, }; -export default function VisitsHeader({ shortUrlDetail, shortUrlVisits, goBack }) { - const { shortUrl, loading } = shortUrlDetail; - const { visits } = shortUrlVisits; - const shortLink = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; - const longLink = shortUrl && shortUrl.longUrl ? shortUrl.longUrl : ''; - - const renderDate = () => ( - - {shortUrl.dateCreated} - - {shortUrl.dateCreated} - - - ); - const visitsStatsTitle = ( - - Visit stats for - - ); - - return ( -
- -

- - - {visitsStatsTitle} - - - Visits:{' '} - - -

-

{visitsStatsTitle}

-
-
Created: {renderDate()}
-
- Long URL:{' '} - {loading && Loading...} - {!loading && } -
-
-
- ); -} +const VisitsHeader = ({ visits, goBack, shortUrl, children, title }) => ( +
+ +

+ + + {title} + + + Visits:{' '} + + +

+

{title}

+ {children} +
+
+); VisitsHeader.propTypes = propTypes; + +export default VisitsHeader; diff --git a/src/visits/VisitsHeader.scss b/src/visits/VisitsHeader.scss deleted file mode 100644 index 51dcc29f..00000000 --- a/src/visits/VisitsHeader.scss +++ /dev/null @@ -1,3 +0,0 @@ -.visits-header__created-at { - cursor: default; -} diff --git a/test/visits/ShortUrlVisits.test.js b/test/visits/ShortUrlVisits.test.js index 72d2c06b..615db013 100644 --- a/test/visits/ShortUrlVisits.test.js +++ b/test/visits/ShortUrlVisits.test.js @@ -2,7 +2,7 @@ import React from 'react'; import { shallow } from 'enzyme'; import { identity } from 'ramda'; import createShortUrlVisits from '../../src/visits/ShortUrlVisits'; -import VisitsHeader from '../../src/visits/VisitsHeader'; +import ShortUrlVisitsHeader from '../../src/visits/ShortUrlVisitsHeader'; describe('', () => { let wrapper; @@ -41,7 +41,7 @@ describe('', () => { it('renders visit stats and visits header', () => { const visitStats = wrapper.find(VisitsStats); - const visitHeader = wrapper.find(VisitsHeader); + const visitHeader = wrapper.find(ShortUrlVisitsHeader); expect(visitStats).toHaveLength(1); expect(visitHeader).toHaveLength(1); diff --git a/test/visits/ShortUrlVisitsHeader.test.js b/test/visits/ShortUrlVisitsHeader.test.js new file mode 100644 index 00000000..763efc57 --- /dev/null +++ b/test/visits/ShortUrlVisitsHeader.test.js @@ -0,0 +1,40 @@ +import React from 'react'; +import { shallow } from 'enzyme'; +import Moment from 'react-moment'; +import { ExternalLink } from 'react-external-link'; +import ShortUrlVisitsHeader from '../../src/visits/ShortUrlVisitsHeader'; + +describe('', () => { + let wrapper; + const shortUrlDetail = { + shortUrl: { + shortUrl: 'https://doma.in/abc123', + longUrl: 'https://foo.bar/bar/foo', + dateCreated: '2018-01-01T10:00:00+01:00', + }, + loading: false, + }; + const shortUrlVisits = { + visits: [{}, {}, {}], + }; + const goBack = jest.fn(); + + beforeEach(() => { + wrapper = shallow( + + ); + }); + afterEach(() => wrapper.unmount()); + + it('shows when the URL was created', () => { + const moment = wrapper.find(Moment).first(); + + expect(moment.prop('children')).toEqual(shortUrlDetail.shortUrl.dateCreated); + }); + + it('shows the long URL', () => { + const longUrlLink = wrapper.find(ExternalLink).last(); + + expect(longUrlLink.prop('href')).toEqual(shortUrlDetail.shortUrl.longUrl); + }); +}); diff --git a/test/visits/VisitsHeader.test.js b/test/visits/VisitsHeader.test.js index 8c151c4b..ade980e8 100644 --- a/test/visits/VisitsHeader.test.js +++ b/test/visits/VisitsHeader.test.js @@ -1,46 +1,35 @@ import React from 'react'; import { shallow } from 'enzyme'; -import Moment from 'react-moment'; -import { ExternalLink } from 'react-external-link'; import VisitsHeader from '../../src/visits/VisitsHeader'; describe('', () => { let wrapper; - const shortUrlDetail = { - shortUrl: { - shortUrl: 'https://doma.in/abc123', - longUrl: 'https://foo.bar/bar/foo', - dateCreated: '2018-01-01T10:00:00+01:00', - }, - loading: false, - }; - const shortUrlVisits = { - visits: [{}, {}, {}], - }; + const visits = [{}, {}, {}]; + const title = 'My header title'; const goBack = jest.fn(); beforeEach(() => { - wrapper = shallow(); + wrapper = shallow( + + ); }); + afterEach(() => wrapper.unmount()); + afterEach(jest.resetAllMocks); it('shows the amount of visits', () => { const visitsBadge = wrapper.find('.badge'); expect(visitsBadge.html()).toContain( - `Visits: ${shortUrlVisits.visits.length}` + `Visits: ${visits.length}` ); }); - it('shows when the URL was created', () => { - const moment = wrapper.find(Moment).first(); + it('shows the title in two places', () => { + const titles = wrapper.find('.text-center'); - expect(moment.prop('children')).toEqual(shortUrlDetail.shortUrl.dateCreated); - }); - - it('shows the long URL', () => { - const longUrlLink = wrapper.find(ExternalLink).last(); - - expect(longUrlLink.prop('href')).toEqual(shortUrlDetail.shortUrl.longUrl); + expect(titles).toHaveLength(2); + expect(titles.at(0).html()).toContain(title); + expect(titles.at(1).html()).toContain(title); }); });