Skip to content

Commit

Permalink
Merge c252e9d into e9ed2b6
Browse files Browse the repository at this point in the history
  • Loading branch information
julienben committed Jul 12, 2020
2 parents e9ed2b6 + c252e9d commit ee0001a
Show file tree
Hide file tree
Showing 105 changed files with 1,034 additions and 1,006 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.js
Expand Up @@ -81,11 +81,19 @@ module.exports = {
},
overrides: [
{
/* internals and server folder are for dev */
files: ['internals/**/*.*', 'server/**/*.*'],
rules: {
'import/no-extraneous-dependencies': 0,
},
},
{
/* slice.js files contain immer-based reducers where param reassignment is a requirement */
files: ['**/slice.js', '**/slice.test.js'],
rules: {
'no-param-reassign': 0,
},
},
],
settings: {
'import/resolver': {
Expand Down
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
@@ -1,2 +1,2 @@
# Global owners
* @julienben @gretzky @justingreenberg @jwinn @Mensae
* @julienben @gretzky @justingreenberg @jwinn
30 changes: 30 additions & 0 deletions app/components/Header/tests/HeaderLink.test.js
@@ -0,0 +1,30 @@
import React from 'react';
import { render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import 'jest-styled-components';

import HeaderLink from '../HeaderLink';

const renderComponent = (props = {}) => {
const utils = render(
<MemoryRouter>
<HeaderLink to="/test" {...props}>
HeaderLink
</HeaderLink>
</MemoryRouter>,
);
const headerLink = utils.queryByText('HeaderLink');
return { ...utils, headerLink };
};

describe('<HeaderLink />', () => {
it('should match the snapshot', () => {
const { container } = renderComponent();
expect(container.firstChild).toMatchSnapshot();
});

it('should have a class attribute', () => {
const { headerLink } = renderComponent();
expect(headerLink).toHaveAttribute('class');
});
});
27 changes: 27 additions & 0 deletions app/components/Header/tests/NavBar.test.js
@@ -0,0 +1,27 @@
import React from 'react';
import { render } from '@testing-library/react';
import 'jest-styled-components';

import NavBar from '../NavBar';

const renderComponent = (props = {}) => {
const { container } = render(<NavBar {...props} />);
return container;
};

describe('<NavBar />', () => {
it('should match the snapshot', () => {
const container = renderComponent();
expect(container.firstChild).toMatchSnapshot();
});

it('should have a class attribute', () => {
const container = renderComponent();
expect(container.firstChild).toHaveAttribute('class');
});

it('should not adopt an invalid attribute', () => {
const container = renderComponent({ attribute: 'test' });
expect(container.firstChild).not.toHaveAttribute('attribute');
});
});
40 changes: 40 additions & 0 deletions app/components/Header/tests/__snapshots__/HeaderLink.test.js.snap
@@ -0,0 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<HeaderLink /> should match the snapshot 1`] = `
.c0 {
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
padding: 0.25em 2em;
margin: 1em;
-webkit-text-decoration: none;
text-decoration: none;
border-radius: 4px;
-webkit-font-smoothing: antialiased;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
cursor: pointer;
outline: 0;
font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;
font-weight: bold;
font-size: 16px;
border: 2px solid #41addd;
color: #41addd;
}
.c0:active {
background: #41addd;
color: #fff;
}
<a
class="c0"
href="/test"
>
HeaderLink
</a>
`;
11 changes: 11 additions & 0 deletions app/components/Header/tests/__snapshots__/NavBar.test.js.snap
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<NavBar /> should match the snapshot 1`] = `
.c0 {
text-align: center;
}
<div
class="c0"
/>
`;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Expand Up @@ -6,36 +6,28 @@

import React from 'react';
import PropTypes from 'prop-types';
import { useSelector } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { FormattedNumber } from 'react-intl';

import { makeSelectCurrentUser } from 'containers/App/selectors';
import ListItem from 'components/ListItem';
import IssueIcon from './IssueIcon';
import IssueLink from './IssueLink';
import RepoLink from './RepoLink';
import Wrapper from './Wrapper';

const stateSelector = createStructuredSelector({
currentUser: makeSelectCurrentUser(),
});

export default function RepoListItem({ item }) {
const { currentUser } = useSelector(stateSelector);
let nameprefix = '';
let namePrefix = '';

// If the repository is owned by a different person than we got the data for
// it's a fork and we should show the name of the owner
if (item.owner.login !== currentUser) {
nameprefix = `${item.owner.login}/`;
// If the repository is owned by a different user then the submitted
// username, it's a fork and we will show the name of the owner
if (!item.isOwnRepo) {
namePrefix = `${item.owner.login}/`;
}

// Put together the content of the repository
const content = (
<Wrapper>
<RepoLink href={item.html_url} target="_blank">
{nameprefix + item.name}
{namePrefix + item.name}
</RepoLink>
<IssueLink href={`${item.html_url}/issues`} target="_blank">
<IssueIcon />
Expand Down
Expand Up @@ -8,22 +8,22 @@ exports[`<RepoListItem /> should render a ListItem 1`] = `
class="Item-sc-3y9mie-0 fKXSkT"
>
<div
class="Wrapper-sc-17s0rao-0 dlZQhZ"
class="Wrapper-sc-13xnchy-0 kxxMFK"
>
<a
class="A-br8h0y-0 RepoLink-pvpwpn-0 eEveIZ"
href="https://github.com/react-boilerplate/react-boilerplate"
class="A-br8h0y-0 RepoLink-sc-1x99nq5-0 cUSWhT"
href="https://github.com/repo-owner/repo_name"
target="_blank"
>
react-boilerplate/react-boilerplate
repo-owner/repo_name
</a>
<a
class="A-br8h0y-0 IssueLink-uyzonb-0 kUUUnc"
href="https://github.com/react-boilerplate/react-boilerplate/issues"
class="A-br8h0y-0 IssueLink-sc-16kygqm-0 giwGlR"
href="https://github.com/repo-owner/repo_name/issues"
target="_blank"
>
<svg
class="IssueIcon-s8m34y-0 jEBeEF"
class="IssueIcon-k8snxy-0 GsPBd"
height="1em"
width="0.875em"
>
Expand Down
86 changes: 86 additions & 0 deletions app/components/RepoListItem/tests/index.test.js
@@ -0,0 +1,86 @@
/**
* Test the repo list item
*/

import React from 'react';
import { getByText, render } from '@testing-library/react';
import { IntlProvider } from 'react-intl';

import RepoListItem from '../index';

const renderComponent = item =>
render(
<IntlProvider locale="en">
<RepoListItem item={item} />
</IntlProvider>,
);

describe('<RepoListItem />', () => {
let ownedItem;
let notOwnedItem;

// Before each test reset the item data for safety
beforeEach(() => {
// Repo owned by the user whose account we're querying
ownedItem = {
isOwnRepo: true,
owner: {
login: 'repo-owner',
},
html_url: 'https://github.com/repo-owner/repo_name',
name: 'repo_name',
open_issues_count: 20,
full_name: 'repo-owner/repo-name',
};

// Repo NOT owned by the user whose account we're querying
notOwnedItem = {
isOwnRepo: false,
owner: {
login: 'repo-owner',
},
html_url: 'https://github.com/repo-owner/repo_name',
name: 'repo_name',
open_issues_count: 20,
full_name: 'repo-owner/repo-name',
};
});

it('should render a ListItem', () => {
const { container } = renderComponent(notOwnedItem);
expect(container.firstChild).toMatchSnapshot();
});

it('should not render the username if repo is owned by user', () => {
const { queryByText } = renderComponent(ownedItem);
expect(queryByText(ownedItem.owner.login)).toBeNull();
});

it('should render username if the repo belongs to a differet user or org', () => {
const { container } = renderComponent(notOwnedItem);
expect(
getByText(container, content =>
content.startsWith(notOwnedItem.owner.login),
),
).not.toBeNull();
});

it('should render the repo name', () => {
const { container } = renderComponent(ownedItem);
expect(
getByText(container, content => content.endsWith(ownedItem.name)),
).not.toBeNull();
});

it('should render the issue count', () => {
const { container } = renderComponent(ownedItem);
expect(
getByText(container, ownedItem.open_issues_count.toString(10)),
).not.toBeNull();
});

it('should render the IssueIcon', () => {
const { container } = renderComponent(ownedItem);
expect(container.querySelector('svg')).not.toBeNull();
});
});
2 changes: 1 addition & 1 deletion app/components/ReposList/index.js
Expand Up @@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import List from 'components/List';
import ListItem from 'components/ListItem';
import LoadingIndicator from 'components/LoadingIndicator';
import RepoListItem from 'containers/RepoListItem';
import RepoListItem from 'components/RepoListItem';

function ReposList({ loading, error, repos }) {
if (loading) {
Expand Down
Expand Up @@ -65,22 +65,22 @@ exports[`<ReposList /> should render the repositories if loading was successful
class="Item-sc-3y9mie-0 fKXSkT"
>
<div
class="Wrapper-sc-17s0rao-0 dlZQhZ"
class="Wrapper-sc-13xnchy-0 kxxMFK"
>
<a
class="A-br8h0y-0 RepoLink-pvpwpn-0 eEveIZ"
class="A-br8h0y-0 RepoLink-sc-1x99nq5-0 cUSWhT"
href="https://github.com/react-boilerplate/react-boilerplate"
target="_blank"
>
react-boilerplate
</a>
<a
class="A-br8h0y-0 IssueLink-uyzonb-0 kUUUnc"
class="A-br8h0y-0 IssueLink-sc-16kygqm-0 giwGlR"
href="https://github.com/react-boilerplate/react-boilerplate/issues"
target="_blank"
>
<svg
class="IssueIcon-s8m34y-0 jEBeEF"
class="IssueIcon-k8snxy-0 GsPBd"
height="1em"
width="0.875em"
>
Expand Down
12 changes: 4 additions & 8 deletions app/components/ReposList/tests/index.test.js
@@ -1,10 +1,8 @@
import React from 'react';
import { IntlProvider } from 'react-intl';
import { Provider } from 'react-redux';
import { render } from '@testing-library/react';

import ReposList from '../index';
import configureStore from '../../../configureStore';

describe('<ReposList />', () => {
it('should render the loading indicator when its loading', () => {
Expand All @@ -22,9 +20,9 @@ describe('<ReposList />', () => {
});

it('should render the repositories if loading was successful', () => {
const store = configureStore({ global: { currentUser: 'mxstbr' } });
const repos = [
{
isOwnRepo: true,
owner: {
login: 'mxstbr',
},
Expand All @@ -35,11 +33,9 @@ describe('<ReposList />', () => {
},
];
const { container } = render(
<Provider store={store}>
<IntlProvider locale="en">
<ReposList repos={repos} error={false} />
</IntlProvider>
</Provider>,
<IntlProvider locale="en">
<ReposList repos={repos} error={false} />
</IntlProvider>,
);

expect(container.firstChild).toMatchSnapshot();
Expand Down

0 comments on commit ee0001a

Please sign in to comment.