From 48042f405e2cd4d7ecb3ba753afe5291a8078636 Mon Sep 17 00:00:00 2001 From: Carlos Cuesta Date: Sun, 1 Aug 2021 11:55:08 +0200 Subject: [PATCH] :sparkles: Fetch Contributors using `getStaticProps` (#828) --- package.json | 1 + .../__snapshots__/pages.spec.js.snap | 16 ++++++- src/__tests__/pages.spec.js | 26 +++++++++- src/__tests__/stubs.js | 17 +++++++ .../ContributorsList/Contributor/index.js | 4 +- .../contributorsList.spec.js.snap | 19 ++++++-- .../__tests__/contributorsList.spec.js | 6 ++- .../ContributorsList/__tests__/stubs.js | 9 +++- src/components/ContributorsList/index.js | 47 +++++++------------ src/pages/contributors.js | 28 ++++++++++- yarn.lock | 20 ++++++++ 11 files changed, 150 insertions(+), 43 deletions(-) diff --git a/package.json b/package.json index c3394355cf..5d412c25b3 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "husky": "^7.0.0", "identity-obj-proxy": "^3.0.0", "jest": "^27.0.1", + "jest-fetch-mock": "^3.0.3", "jsonlint": "^1.6.3", "lint-staged": "^11.0.0", "next": "^11.0.0", diff --git a/src/__tests__/__snapshots__/pages.spec.js.snap b/src/__tests__/__snapshots__/pages.spec.js.snap index 0882d0854c..e3df15fe86 100644 --- a/src/__tests__/__snapshots__/pages.spec.js.snap +++ b/src/__tests__/__snapshots__/pages.spec.js.snap @@ -469,7 +469,21 @@ exports[`Pages Contributors should render the page 1`] = `
+ > + +
`; diff --git a/src/__tests__/pages.spec.js b/src/__tests__/pages.spec.js index 1377f3f054..5b244668a2 100644 --- a/src/__tests__/pages.spec.js +++ b/src/__tests__/pages.spec.js @@ -1,9 +1,12 @@ import renderer from 'react-test-renderer' +import { enableFetchMocks } from 'jest-fetch-mock' import App from '../pages/_app' import Index from '../pages/index' import About from '../pages/about' -import Contributors from '../pages/contributors' +import Contributors, { + getStaticProps as getContributorsStaticProps, +} from '../pages/contributors' import RelatedTools from '../pages/related-tools' import GitmojisApi from '../pages/api/gitmojis' import gitmojisData from '../data/gitmojis.json' @@ -44,8 +47,27 @@ describe('Pages', () => { }) describe('Contributors', () => { + beforeAll(() => { + enableFetchMocks() + }) + + it('should fetch contributos from GitHub', async () => { + fetch.mockResponseOnce(JSON.stringify(stubs.contributorsMock)) + + const props = await getContributorsStaticProps() + + expect(props).toEqual({ + props: { + contributors: stubs.contributors, + }, + revalidate: 3600 * 3, + }) + }) + it('should render the page', () => { - const wrapper = renderer.create() + const wrapper = renderer.create( + + ) expect(wrapper).toMatchSnapshot() }) }) diff --git a/src/__tests__/stubs.js b/src/__tests__/stubs.js index f82792df36..5619cbb44e 100644 --- a/src/__tests__/stubs.js +++ b/src/__tests__/stubs.js @@ -16,3 +16,20 @@ export const response = () => { return response } + +export const contributors = [ + { + url: 'https://github.com/profile', + avatar: 'https://github.com/avatar', + id: 'contributor-id-123', + }, +] + +export const contributorsMock = [ + { + html_url: 'https://github.com/profile', + avatar_url: 'https://github.com/avatar', + id: 'contributor-id-123', + login: 'carloscuesta', + }, +] diff --git a/src/components/ContributorsList/Contributor/index.js b/src/components/ContributorsList/Contributor/index.js index 590916e932..2bab782dd2 100644 --- a/src/components/ContributorsList/Contributor/index.js +++ b/src/components/ContributorsList/Contributor/index.js @@ -3,11 +3,11 @@ import React, { type Element } from 'react' import styles from './styles.module.css' -type Props = { profile: string, avatar: string } +type Props = { avatar: string, url: string } const Contributor = (props: Props): Element<'article'> => ( diff --git a/src/components/ContributorsList/__tests__/__snapshots__/contributorsList.spec.js.snap b/src/components/ContributorsList/__tests__/__snapshots__/contributorsList.spec.js.snap index 6115d1ee95..00f9699a86 100644 --- a/src/components/ContributorsList/__tests__/__snapshots__/contributorsList.spec.js.snap +++ b/src/components/ContributorsList/__tests__/__snapshots__/contributorsList.spec.js.snap @@ -5,11 +5,10 @@ exports[`ContributorsList Contributor should render the component 1`] = ` className="col-xs-3 col-sm-2" > @@ -18,5 +17,19 @@ exports[`ContributorsList Contributor should render the component 1`] = ` exports[`ContributorsList should render the component 1`] = `
+> + +
`; diff --git a/src/components/ContributorsList/__tests__/contributorsList.spec.js b/src/components/ContributorsList/__tests__/contributorsList.spec.js index bd8b6df959..e0a093cef2 100644 --- a/src/components/ContributorsList/__tests__/contributorsList.spec.js +++ b/src/components/ContributorsList/__tests__/contributorsList.spec.js @@ -7,13 +7,15 @@ import * as stubs from './stubs' describe('ContributorsList', () => { describe('Contributor', () => { it('should render the component', () => { - const wrapper = renderer.create() + const wrapper = renderer.create( + + ) expect(wrapper).toMatchSnapshot() }) }) it('should render the component', () => { - const wrapper = renderer.create() + const wrapper = renderer.create() expect(wrapper).toMatchSnapshot() }) }) diff --git a/src/components/ContributorsList/__tests__/stubs.js b/src/components/ContributorsList/__tests__/stubs.js index d563e533e2..aadc7e7df0 100644 --- a/src/components/ContributorsList/__tests__/stubs.js +++ b/src/components/ContributorsList/__tests__/stubs.js @@ -1,4 +1,9 @@ -export const props = { - profile: 'https://github.com/profile', +export const contributor = { + url: 'https://github.com/profile', avatar: 'https://github.com/avatar', + id: 'contributor-id-123', +} + +export const props = { + contributors: [contributor], } diff --git a/src/components/ContributorsList/index.js b/src/components/ContributorsList/index.js index 7b7ce55016..b4495b6b46 100644 --- a/src/components/ContributorsList/index.js +++ b/src/components/ContributorsList/index.js @@ -3,35 +3,24 @@ import React, { type Element } from 'react' import Contributor from './Contributor' -const ContributorsList = (): Element<'div'> => { - const [contributors, setContributors] = React.useState([]) - - React.useEffect(() => { - const fetchContributors = async () => { - const response = await fetch( - 'https://api.github.com/repos/carloscuesta/gitmoji/contributors' - ) - const contributors = await response.json() - - setContributors( - contributors.filter((contributor) => !contributor.login.includes('bot')) - ) - } - - fetchContributors() - }, []) - - return ( -
- {contributors.map((contributor) => ( - - ))} -
- ) +type Props = { + contributors: Array<{ + avatar: string, + id: string, + url: string, + }>, } +const ContributorsList = (props: Props): Element<'div'> => ( +
+ {props.contributors.map((contributor) => ( + + ))} +
+) + export default ContributorsList diff --git a/src/pages/contributors.js b/src/pages/contributors.js index d859f73553..525a263d82 100644 --- a/src/pages/contributors.js +++ b/src/pages/contributors.js @@ -4,7 +4,11 @@ import ContributorsList from 'src/components/ContributorsList' import CarbonAd from 'src/components/CarbonAd' import SEO from 'src/components/SEO' -const Contributors = () => ( +type Props = { + contributors: Array<{ avatar: string, url: string, id: string }>, +} + +const Contributors = (props: Props) => ( <> @@ -13,10 +17,30 @@ const Contributors = () => (

Contributors

- +
) +export const getStaticProps = async (): Promise => { + const response = await fetch( + 'https://api.github.com/repos/carloscuesta/gitmoji/contributors' + ) + const contributors = await response.json() + + return { + props: { + contributors: contributors + .filter((contributor) => !contributor.login.includes('bot')) + .map((contributor) => ({ + avatar: contributor.avatar_url, + id: contributor.id, + url: contributor.html_url, + })), + }, + revalidate: 3600 * 3, + } +} + export default Contributors diff --git a/yarn.lock b/yarn.lock index aac5d04766..6f492c3207 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1598,6 +1598,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-fetch@^3.0.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" + integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== + dependencies: + node-fetch "2.6.1" + cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -2698,6 +2705,14 @@ jest-environment-node@^27.0.6: jest-mock "^27.0.6" jest-util "^27.0.6" +jest-fetch-mock@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz#31749c456ae27b8919d69824f1c2bd85fe0a1f3b" + integrity sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw== + dependencies: + cross-fetch "^3.0.4" + promise-polyfill "^8.1.3" + jest-get-type@^27.0.6: version "27.0.6" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" @@ -3718,6 +3733,11 @@ process@0.11.10, process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +promise-polyfill@^8.1.3: + version "8.2.0" + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.0.tgz#367394726da7561457aba2133c9ceefbd6267da0" + integrity sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g== + prompts@^2.0.1: version "2.2.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.2.1.tgz#f901dd2a2dfee080359c0e20059b24188d75ad35"