Skip to content

Commit

Permalink
Merge 9a7e224 into 362e4cb
Browse files Browse the repository at this point in the history
  • Loading branch information
davilima6 committed Sep 8, 2018
2 parents 362e4cb + 9a7e224 commit 2e929a8
Show file tree
Hide file tree
Showing 8 changed files with 373 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,7 @@
### Added

* Upgrade React to 16.4.2 to fix a server-side vunerability @tisto
* Add Album view @davilima6

### Changes

Expand Down
1 change: 1 addition & 0 deletions src/components/index.js
Expand Up @@ -33,6 +33,7 @@ export Logout from './theme/Logout/Logout';
export NotFound from './theme/NotFound/NotFound';
export Pagination from './theme/Pagination/Pagination';
export SummaryView from './theme/View/SummaryView';
export AlbumView from './theme/View/AlbumView';
export Search from './theme/Search/Search';
export SearchTags from './theme/Search/SearchTags';
export TabularView from './theme/View/TabularView';
Expand Down
105 changes: 105 additions & 0 deletions src/components/theme/View/AlbumView.jsx
@@ -0,0 +1,105 @@
/**
* Album view component.
* @module components/theme/View/AlbumView
*/

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Helmet from 'react-helmet';
import { Link } from 'react-router';
import { Card, Image } from 'semantic-ui-react';

/**
* AlbumView view component class.
* @class AlbumView
* @extends Component
*/
export default class AlbumView extends Component {
/**
* Property types.
* @property {Object} propTypes Property types.
* @static
*/
static propTypes = {
content: PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
items: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
url: PropTypes.string,
image: PropTypes.object,
'@type': PropTypes.string,
}),
),
}).isRequired,
getCardHeader: PropTypes.func,
getCardDescription: PropTypes.func,
getCardExtra: PropTypes.func,
};

/**
* Default properties
* @property {Object} defaultProps Default properties.
* @static
*/
static defaultProps = {
getCardHeader: item => <Card.Header content={item.title} />,
getCardDescription: item => <Card.Description content={item.description} />,
getCardExtra: () => null,
};

/**
* Render method.
* @method render
* @returns {string} Markup for the component.
*/
render() {
return (
<div id="page-home">
<Helmet title={this.props.content.title} />
<article id="content">
<header>
<h1 className="documentFirstHeading">{this.props.content.title}</h1>
{this.props.content.description && (
<p className="description">{this.props.content.description}</p>
)}
</header>
<section id="content-core">
<Card.Group stackable doubling>
{this.props.content.items.map(item => (
<Card
as={Link}
to={item.url}
title={item.title}
key={item.url}
centered
>
<div className="image-wrapper">
{item.image && (
<Image
src={item.image.scales.preview.download}
alt={
item.image_caption ? item.image_caption : item.title
}
/>
)}
</div>
<Card.Content
header={this.props.getCardHeader(item)}
description={this.props.getCardDescription(item)}
textAlign="center"
/>
{this.props.getCardExtra(item)}
</Card>
))}
{/* Workaround while Flexbox 2.0 doesn't implement last row alignment */}
{[...Array(3)].map((e, i) => <Card key={`item-${i}`} />)}
</Card.Group>
</section>
</article>
</div>
);
}
}
70 changes: 70 additions & 0 deletions src/components/theme/View/AlbumView.test.jsx
@@ -0,0 +1,70 @@
import React from 'react';
import renderer from 'react-test-renderer';

import AlbumView from './AlbumView';

describe('AlbumView', () => {
it('renders a AlbumView view component', () => {
const component = renderer.create(
<AlbumView
content={{
title: 'Hello World!',
description: 'Hi',
items: [
{
title: 'My item',
description: 'My item description',
url: 'http://item',
image: {
height: 100,
width: 100,
download: 'file:///image.jpg',
scales: {
preview: {
download: 'file:///preview.jpg',
},
},
},
image_caption: 'My image caption',
'@type': 'News Item',
},
],
}}
/>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a AlbumView view component with SVGs', () => {
const component = renderer.create(
<AlbumView
content={{
title: 'Hello World!',
description: 'Hi',
items: [
{
title: 'My item',
description: 'My item description',
url: 'http://item',
image: {
height: -1,
width: -1,
download: 'file:///image.svg',
scales: {
preview: {
download: 'file:///preview.svg',
},
},
},
image_caption: 'My image caption',
'@type': 'News Item',
},
],
}}
/>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});
});
23 changes: 23 additions & 0 deletions src/components/theme/View/View.test.jsx
Expand Up @@ -20,6 +20,11 @@ jest.mock('./TabularView', () => {
dummyComponent.displayName = 'dummyComponent';
return dummyComponent;
});
jest.mock('./AlbumView', () => {
const dummyComponent = jest.fn(() => <div id="AlbumView" />);
dummyComponent.displayName = 'dummyComponent';
return dummyComponent;
});
jest.mock('./DocumentView', () => {
const dummyComponent = jest.fn(() => <div id="DocumentView" />);
dummyComponent.displayName = 'dummyComponent';
Expand Down Expand Up @@ -184,6 +189,24 @@ describe('View', () => {
expect(json).toMatchSnapshot();
});

it('renders an album view', () => {
const store = mockStore({
actions: { actions },
content: { data: { layout: 'album_view' }, get: { error: null } },
intl: {
locale: 'en',
messages: {},
},
});
const component = renderer.create(
<Provider store={store}>
<View location={{ pathname: '/test' }} />
</Provider>,
);
const json = component.toJSON();
expect(json).toMatchSnapshot();
});

it('renders a document view', () => {
const store = mockStore({
actions: { actions },
Expand Down
155 changes: 155 additions & 0 deletions src/components/theme/View/__snapshots__/AlbumView.test.jsx.snap
@@ -0,0 +1,155 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`AlbumView renders a AlbumView view component 1`] = `
<div
id="page-home"
>
<article
id="content"
>
<header>
<h1
className="documentFirstHeading"
>
Hello World!
</h1>
<p
className="description"
>
Hi
</p>
</header>
<section
id="content-core"
>
<div
className="ui doubling stackable cards"
>
<a
className="ui centered card"
href={undefined}
onClick={[Function]}
style={Object {}}
title="My item"
>
<div
className="image-wrapper"
>
<img
alt="My image caption"
className="ui image"
src="file:///preview.jpg"
/>
</div>
<div
className="center aligned content"
>
<div
className="header"
>
My item
</div>
<div
className="description"
>
My item description
</div>
</div>
</a>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
</div>
</section>
</article>
</div>
`;

exports[`AlbumView renders a AlbumView view component with SVGs 1`] = `
<div
id="page-home"
>
<article
id="content"
>
<header>
<h1
className="documentFirstHeading"
>
Hello World!
</h1>
<p
className="description"
>
Hi
</p>
</header>
<section
id="content-core"
>
<div
className="ui doubling stackable cards"
>
<a
className="ui centered card"
href={undefined}
onClick={[Function]}
style={Object {}}
title="My item"
>
<div
className="image-wrapper"
>
<img
alt="My image caption"
className="ui image"
src="file:///preview.svg"
/>
</div>
<div
className="center aligned content"
>
<div
className="header"
>
My item
</div>
<div
className="description"
>
My item description
</div>
</div>
</a>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
<div
className="ui card"
href={undefined}
onClick={[Function]}
/>
</div>
</section>
</article>
</div>
`;

0 comments on commit 2e929a8

Please sign in to comment.