diff --git a/README.md b/README.md index a84bb61..cde7e28 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,15 @@ A react application using typescript showing the albums of an artist the user is searching for using a GraphQL endpoint. ## Using the app - - Clone the git repo [from here](https://github.com/ruihildt/spoti-search). - - Installing libraries: `yarn install` - - Running the app: `yarn start` + +### Installation +1. Clone the git repo [from here](https://github.com/ruihildt/spoti-search). +2. Install libraries using yarn (can also be run with npm): `yarn install` + +### Usage + - Run the app: `yarn start` - Build the app to deploy it: `yarn build` + - Run the tests: `yarn test` ## Tech Stack - [CRA with Typescript](https://create-react-app.dev/docs/adding-typescript/) diff --git a/src/components/App.tsx b/src/components/App.tsx index 172ec9f..f34da65 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -8,7 +8,7 @@ import { Search } from './Search'; import { Results } from './Results'; import { Artists, Artist } from '../interfaces'; -const QUERY_ARTISTS = gql` +export const QUERY_ARTISTS = gql` query Artist($byName: String!) { queryArtists(byName: $byName) { name diff --git a/src/components/Search.tsx b/src/components/Search.tsx index 47ab20e..d31cb1a 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -31,7 +31,7 @@ export const Search = ({ dropHeight='large' placeholder='Type an artist name' autoFocus - aria-label='Search for an artist name' + aria-label='Search by artist name' /> diff --git a/src/tests/App.test.tsx b/src/tests/App.test.tsx index 5faca08..42ff2fd 100644 --- a/src/tests/App.test.tsx +++ b/src/tests/App.test.tsx @@ -1,15 +1,18 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render, cleanup } from '@testing-library/react'; import App from '../components/App'; describe('App', () => { - test('renders App component', () => { - render(); + + afterEach(cleanup); + it('displays App component', () => { + const { getByText, getByRole } = render(); - // screen.debug(); - expect(screen.getByText('Spoti Search')).toBeInTheDocument(); - expect(screen.getByRole('textbox')).toBeInTheDocument(); - expect(screen.getByPlaceholderText('Type an artist name')).toBeInTheDocument(); + const title = getByText('Spoti Search'); + const input = getByRole('searchbox', { name: 'Search by artist name' }); + + expect(title).toBeInTheDocument(); + expect(input).toBeInTheDocument(); }); }); diff --git a/src/tests/Search.test.tsx b/src/tests/Search.test.tsx new file mode 100644 index 0000000..ac10b27 --- /dev/null +++ b/src/tests/Search.test.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { render, cleanup, fireEvent } from '@testing-library/react'; +import App from '../components/App'; + +describe('Search', () => { + afterEach(cleanup); + it('displays Search component', () => { + const { getByText, getByRole } = render(); + + const title = getByText('Spoti Search'); + const input = getByRole('searchbox', { name: 'Search by artist name' }); + + expect(title).toBeInTheDocument(); + expect(input).toBeInTheDocument(); + }); + + afterEach(cleanup); + it('allows input on the search field', () => { + const { getByRole } = render(); + + const input = getByRole('searchbox', { name: 'Search by artist name' }); + fireEvent.change(input, { target: { value: 'Kendrik' } }); + + expect(input.value).toBe('Kendrik'); + }); + + afterEach(cleanup); + it('loads suggestions based on the searchbox input', async () => { + const { getByRole } = render(); + + const input = getByRole('searchbox', { name: 'Search by artist name' }); + fireEvent.change(input, { target: { value: 'Kendrik' } }); + + // TODO + // const suggestion = getByRole('generic', { name: 'XXXTENTACION' }); + // expect(suggestion).toBe('XXXTENTACION'); + }); +}); diff --git a/src/tests/mock-data/queryResults.ts b/src/tests/mock-data/queryResults.ts new file mode 100644 index 0000000..4f6582b --- /dev/null +++ b/src/tests/mock-data/queryResults.ts @@ -0,0 +1,474 @@ +export const queryResults = { + data: { + queryArtists: [ + { + name: 'Kendrick Lamar', + image: + 'https://i.scdn.co/image/3a836196bfb341f736c7fe2704fb75de53f8dfbb', + id: '2YZyLoL8N0Wb9xBt1NhZWg', + albums: [ + { + name: + 'Black Panther The Album Music From And Inspired By', + image: + 'https://i.scdn.co/image/ab67616d0000b273c027ad28821777b00dcaa888', + id: '3pLdWdkj83EYfDN6H2N8MR', + }, + { + name: + 'Black Panther The Album Music From And Inspired By', + image: + 'https://i.scdn.co/image/ab67616d0000b273a8f9bf75a4f4ba99439800b3', + id: '4Kp52vGJe5oVi0EXNhSDKy', + }, + { + name: + 'Black Panther The Album Music From And Inspired By', + image: + 'https://i.scdn.co/image/ab67616d0000b273132072fa796787ddd6325a6d', + id: '5sOSzueqgCiVpXNcpd6QpL', + }, + { + name: 'DAMN. COLLECTORS EDITION.', + image: + 'https://i.scdn.co/image/ab67616d0000b273add9eb25744782c3717c9368', + id: '4alcGHjstaALJHHiljfy3H', + }, + { + name: 'DAMN. COLLECTORS EDITION.', + image: + 'https://i.scdn.co/image/ab67616d0000b2738b849141229ab227ab397603', + id: '0bDN3eDKOfaeM5vccGu6SI', + }, + { + name: 'DAMN. COLLECTORS EDITION.', + image: + 'https://i.scdn.co/image/ab67616d0000b2732fad9364b7dfca0c2ede0da4', + id: '1LLOGSa5ehwSWrPg1Qc3Vg', + }, + { + name: 'DAMN.', + image: + 'https://i.scdn.co/image/ab67616d0000b2738b52c6b9bc4e43d873869699', + id: '4eLPsYPBmXABThSJ821sqY', + }, + { + name: 'DAMN.', + image: + 'https://i.scdn.co/image/ab67616d0000b2732c6dd664eb1a4c7afb386e47', + id: '2ZsOtrjbcxMhcOcyDzNt1V', + }, + { + name: 'DAMN.', + image: + 'https://i.scdn.co/image/ab67616d0000b2732171b967bef683ab0eaf12e9', + id: '0bLXUfNT34mna9aXq8ex68', + }, + { + name: 'untitled unmastered.', + image: + 'https://i.scdn.co/image/ab67616d0000b2738c697f553a46006a5d8886b2', + id: '0kL3TYRsSXnu0iJvFO3rud', + }, + { + name: 'To Pimp A Butterfly', + image: + 'https://i.scdn.co/image/ab67616d0000b273cdb645498cd3d8a2db4d05e1', + id: '7ycBtnsMtyVbbwTfJwRjSP', + }, + { + name: 'To Pimp A Butterfly', + image: + 'https://i.scdn.co/image/ab67616d0000b273e69c637a33eeb3f072d8f57c', + id: '76cek8jEdNsxH60aUu8Qtj', + }, + { + name: 'To Pimp A Butterfly', + image: + 'https://i.scdn.co/image/ab67616d0000b273c54f244336fd6e0e1518fe77', + id: '6w7lqIsvDPgTChMrPw5oIL', + }, + { + name: 'To Pimp A Butterfly', + image: + 'https://i.scdn.co/image/ab67616d0000b2730ae6645266b8f10619d6b77c', + id: '0CXmtbhJapIH7vw8go2DEb', + }, + { + name: 'good kid, m.A.A.d city (Deluxe)', + image: + 'https://i.scdn.co/image/ab67616d0000b2737468467632649e2f7903d096', + id: '2dnvkiEsLtEMOAmM0DaZVo', + }, + { + name: 'good kid, m.A.A.d city', + image: + 'https://i.scdn.co/image/ab67616d0000b27363dd15c6f117165a13609f62', + id: '2ioBMJIiOANfeCaXP9a7Zn', + }, + { + name: 'good kid, m.A.A.d city', + image: + 'https://i.scdn.co/image/ab67616d0000b273c61fdb864f1a9d77595cc7c3', + id: '21EBAOQBAPvE7bMsz6sGV7', + }, + { + name: 'good kid, m.A.A.d city (Deluxe)', + image: + 'https://i.scdn.co/image/ab67616d0000b27378de8b28de36a74afc0348b5', + id: '748dZDqSZy6aPXKcI9H80u', + }, + { + name: 'good kid, m.A.A.d city (Deluxe)', + image: + 'https://i.scdn.co/image/ab67616d0000b273e202e51d849adb761c0c079c', + id: '1DqhWr73Fh5yoNzKLas0G3', + }, + { + name: 'good kid, m.A.A.d city (Deluxe)', + image: + 'https://i.scdn.co/image/ab67616d0000b27331a8a2bc02a5699616d2e348', + id: '1gItED20w7gVObqo6sSh8y', + }, + ], + }, + { + name: 'Kendrick P.', + image: + 'https://i.scdn.co/image/35e3735c362200e9cd2ab97b474e7e3f665cab34', + id: '0qrHiWumZtqyV65tKmFWFR', + albums: [ + { + name: 'Vibe Slow', + image: + 'https://i.scdn.co/image/ab67616d0000b2736fb4f3e5b1973bde7921952b', + id: '02ODeMJV0SOsW5RhhEEM5w', + }, + { + name: 'Fallen (Live)', + image: + 'https://i.scdn.co/image/ab67616d0000b27386781f804d759ff89a61dfc0', + id: '1SB8V0bkuMpcVLeJ2T7EBd', + }, + { + name: 'Fallen', + image: + 'https://i.scdn.co/image/ab67616d0000b2731f94a4d2228bacd952690c79', + id: '75p0NSt5lwrsu73qhC0xaR', + }, + { + name: 'Fallen', + image: + 'https://i.scdn.co/image/ab67616d0000b2731991a80d0c0dccb4e6f6ac4a', + id: '1y7u8NkBCmmoOdpNzF5Cik', + }, + { + name: 'Blue Hunnas', + image: + 'https://i.scdn.co/image/ab67616d0000b2733251723327e3c272276389c4', + id: '4Asnt1yoFwx6yifBmAcKHj', + }, + { + name: 'All Yours', + image: + 'https://i.scdn.co/image/ab67616d0000b273b92a614512cce17dc10d5265', + id: '3Qg6yFm6ciP2bn6GobYjbP', + }, + { + name: 'Hitkidd For President: 2020', + image: + 'https://i.scdn.co/image/ab67616d0000b273fe726f8dd47485b01b593044', + id: '4rXf2XGJt304bI0DYB1t11', + }, + { + name: 'Blood Sweat and Tears 2', + image: + 'https://i.scdn.co/image/ab67616d0000b27341f994eda9e84489aa34574b', + id: '3wCFMuvP9Td0nA7JKr7x1n', + }, + { + name: 'Off the Deep End', + image: + 'https://i.scdn.co/image/ab67616d0000b273be5b2f0a829d704d806e3de4', + id: '7GcIcPbyuanhA7kCNijnrb', + }, + ], + }, + { + name: 'Anna Kendrick', + image: + 'https://i.scdn.co/image/ab67616d0000b2738f00f06afe95022f6266ba65', + id: '6xfqnpe2HnLVUaYXs2F8YS', + albums: [ + { + name: + 'The Last Five Years (Original Motion Picture Soundtrack)', + image: + 'https://i.scdn.co/image/ab67616d0000b27364c37f1af495b97df395e41f', + id: '6VZ5lJSFcHOKkpVZrxu8ie', + }, + { + name: 'True Colors', + image: + 'https://i.scdn.co/image/ab67616d0000b2738f00f06afe95022f6266ba65', + id: '7M83W7iXqtZ2qjYCOXvgWj', + }, + { + name: 'Cups (Pitch Perfect’s “When I’m Gone”)', + image: + 'https://i.scdn.co/image/ab67616d0000b273bf912e74770477b7464d16b1', + id: '0ADeebtY9ygMEZkuEuTAUu', + }, + { + name: '全部歌えるヒットソング', + image: + 'https://i.scdn.co/image/ab67616d0000b273c29930823243273c575a1e1b', + id: '7rk22W5kurPR0deG93soxM', + }, + { + name: 'Back to the teens', + image: + 'https://i.scdn.co/image/ab67616d0000b273641c9d8f41cdeaf0afb6bb41', + id: '0e36YCuUuMGYrrfBkUryXT', + }, + { + name: 'KIDS PARTY 2020', + image: + 'https://i.scdn.co/image/ab67616d0000b273ea36f36bf08620c8cac317c3', + id: '4KHbrk7K0TOP6weuNURWwd', + }, + { + name: + 'TROLLS World Tour (Original Motion Picture Soundtrack)', + image: + 'https://i.scdn.co/image/ab67616d0000b273392c48a03b57ac9dfb296955', + id: '1jOcKmWE1mUEnyt6JdLTr8', + }, + { + name: + 'TROLLS World Tour (Original Motion Picture Soundtrack)', + image: + 'https://i.scdn.co/image/ab67616d0000b273efa58e65fc9003282883ac51', + id: '28Orm6S3LezppbfYdgA3aI', + }, + { + name: 'Movie Hits', + image: + 'https://i.scdn.co/image/ab67616d0000b27338dc18132c35d8eda2f8fc17', + id: '4Z4M0Tfjwwg55dt3a9uoxr', + }, + { + name: + 'Pitch Perfect 3 (Original Motion Picture Soundtrack)', + image: + 'https://i.scdn.co/image/ab67616d0000b273f4c0ba0254c969da1605bb60', + id: '6gE4FPmxR7mOblqVOpgwuK', + }, + { + name: + 'Pitch Perfect 3 (Original Motion Picture Soundtrack - Special Edition)', + image: + 'https://i.scdn.co/image/ab67616d0000b273e3c4e88fcb8e18ad73645176', + id: '1kJFrRd4OyFXyEtFb7xSUY', + }, + { + name: 'Trolls: Vamos Festejar', + image: + 'https://i.scdn.co/image/ab67616d0000b2735aaf1e38a8035bcaabc5e672', + id: '3Gt1xxnytN9vHYpDEMBVc6', + }, + { + name: 'Les Trolls : spécial fêtes', + image: + 'https://i.scdn.co/image/ab67616d0000b273e98ab760287e26d1b57a3be3', + id: '7osrakyvybxZs6lqQBvrx9', + }, + { + name: 'Trolls - Feiern mit den Trolls', + image: + 'https://i.scdn.co/image/ab67616d0000b273183dacfd6c63701bcb8fc178', + id: '6xMUPuhkQ4bvDdCSPzWoap', + }, + { + name: 'Trolls: Dias de Festa', + image: + 'https://i.scdn.co/image/ab67616d0000b27331672fa56ec5b9c54408aff2', + id: '5psCUpyYD4Lbn8yPCSUux3', + }, + { + name: 'Trolle: Swiateczna misja', + image: + 'https://i.scdn.co/image/ab67616d0000b2736579504175db3e6a39d7a3ec', + id: '42d44TvKyuBEYPycIKMGyM', + }, + { + name: 'Trolls: Vamos a festejar', + image: + 'https://i.scdn.co/image/ab67616d0000b273a673952f7819686d14b24508', + id: '25PenI5LhTus26RSnMRqdP', + }, + { + name: 'Trolls: Jakten på helgdagen', + image: + 'https://i.scdn.co/image/ab67616d0000b273c46624606e5e1358ad36297d', + id: '2Y1cb0Vjv1dhuF8jTzQv7d', + }, + { + name: 'TROLLS Holiday', + image: + 'https://i.scdn.co/image/ab67616d0000b273fd5e83d136ccb55b0a195d8c', + id: '3lo9YzrubM3XXIKjBL1cgf', + }, + { + name: 'TROLLS (Original Motion Picture Soundtrack)', + image: + 'https://i.scdn.co/image/ab67616d0000b2738c8ff59ee259f5151eee2234', + id: '3aFt2keSBET1IlwQ18yskE', + }, + ], + }, + { + name: 'Kendrick', + image: + 'https://i.scdn.co/image/ab67616d0000b27363339248525532fa9c93f748', + id: '18KbIRQdHumKItQ6kNPgNu', + albums: [ + { + name: 'Evil and Illusion', + image: + 'https://i.scdn.co/image/ab67616d0000b27378fd026c53b739a3f9a4006c', + id: '1I6arTUPxvCW6PzLZioPNF', + }, + { + name: "Keep It Bumpin'", + image: + 'https://i.scdn.co/image/ab67616d0000b2737d7a59472e7e22172ad39e15', + id: '6khWQY1ljG4NEyXmaXAF3B', + }, + { + name: 'Taking Pictures', + image: + 'https://i.scdn.co/image/ab67616d0000b273c462b8eae0f8cdcfacc91625', + id: '2giedx9T8jgpmyVGw8bY92', + }, + { + name: 'When the Lights Go Out', + image: + 'https://i.scdn.co/image/ab67616d0000b27363339248525532fa9c93f748', + id: '6Pd1pWNoQeAfM5YpLfo0nK', + }, + { + name: 'Plugtalk', + image: + 'https://i.scdn.co/image/ab67616d0000b2738bfbf953355eb85b5bad8252', + id: '6lpgTLQsMk2Zohr3IMoDih', + }, + ], + }, + { + name: 'Kendrick Scott Oracle', + image: + 'https://i.scdn.co/image/06c0e5fc00346bc76367bf86d90758567a64b4f9', + id: '0IyuDlCVbMa3TAoVaDKEeL', + albums: [ + { + name: 'A Wall Becomes A Bridge', + image: + 'https://i.scdn.co/image/ab67616d0000b273c9bfea422706a9880d13ff6d', + id: '6x36FYMhcxlEjJB97ikwA3', + }, + { + name: 'We Are The Drum', + image: + 'https://i.scdn.co/image/ab67616d0000b273dd3e0fd4978edfc0df4bc3c0', + id: '7aQvkApIn5hkn5Qn16RSdz', + }, + { + name: 'Conviction', + image: + 'https://i.scdn.co/image/ab67616d0000b273d827a88be2c9ef6dc96bdfce', + id: '0oAmwgX5lUaKezX7zzcBIN', + }, + { + name: 'Conviction', + image: + 'https://i.scdn.co/image/ab67616d0000b27395b1034c4f62d4545fec4951', + id: '0gOjMmKqfLZAv0YPuHupup', + }, + { + name: 'THE SOURCE', + image: + 'https://i.scdn.co/image/ab67616d0000b273834ac2e9003c36b3295b3cbc', + id: '1Cry5wSyqn6g2s30Z7DdAP', + }, + { + name: '>>>>>>>>>>>Mocean', + image: + 'https://i.scdn.co/image/ab67616d0000b27345ad7039773ec58a5f198fc5', + id: '07B5duUj0uR6LJe3v3Jusk', + }, + { + name: '>>>>>>>>>Voices', + image: + 'https://i.scdn.co/image/ab67616d0000b273e4f71587b72ebc8e91992cf0', + id: '3zap2LV0tMn1SmBQBg7Vq4', + }, + { + name: 'Modern Jazz', + image: + 'https://i.scdn.co/image/ab67616d0000b27396b7c95054cab489b4a726f9', + id: '20coUJ7K3E3CcsqLhG4RAl', + }, + { + name: 'Jazz para Trabajar', + image: + 'https://i.scdn.co/image/ab67616d0000b273311c4e77efa3cc889a651d76', + id: '2hg9YQ3I1XcvoOb6SmSYuU', + }, + { + name: 'Jazz Hip Hop', + image: + 'https://i.scdn.co/image/ab67616d0000b273ece2c1fc385e3c867049c413', + id: '2H1X1HGQKoG4KXR4Zlhi7Y', + }, + { + name: 'Jazz Hip Hop', + image: + 'https://i.scdn.co/image/ab67616d0000b27391ca5341c64ad647a9ff5144', + id: '4f7yEoRedZPPnnxYmUyWKH', + }, + { + name: 'Modern Jazz', + image: + 'https://i.scdn.co/image/ab67616d0000b27371c75f5f6ab82b33e312d302', + id: '0hipJi7FnukxzssFxqoOBw', + }, + { + name: 'Rhymes 4 Beats (Jazzy Sensation)', + image: + 'https://i.scdn.co/image/ab67616d0000b27376afe19af353d6933a50733d', + id: '12YLss3mbsbtoMzbgY9SC8', + }, + { + name: 'Jazz Now 2016', + image: + 'https://i.scdn.co/image/ab67616d0000b273ea1f2fce9f53dfa61ebea462', + id: '3zeHhrMCZzPWVzI2a0Sphh', + }, + { + name: 'Jazz The New Chapter 2', + image: + 'https://i.scdn.co/image/ab67616d0000b273203be5d323a858de320aad92', + id: '6SbYfFFngnaMtyq6BMmES0', + }, + { + name: 'Next!', + image: + 'https://i.scdn.co/image/ab67616d0000b273869a13ab4c53ee6e3bfeafc7', + id: '0XIPCoXQiNPaVW1g0ktXeT', + }, + ], + }, + ], + }, +};