Skip to content

Commit

Permalink
Posts table (#9)
Browse files Browse the repository at this point in the history
* header task: first commit

* header task: fixed missing default 'javascript'

* header task: fixed default link: '/search/javascript'

* header after first review

* header fixing test

* implemented unit test

* header: before rebase after app-skeleton-review

* resolved conflicts. Fixed unit tests

* footer: initial commit

* implemented Footer.js and Footer.style.js

* footer: completed unit tests

* hero-section: initial commit with with fixes from previous PR

* hero-section: completed unit tests

* hero-section: fixed linting issues in unit tests

* hero-section: fixed Apps to have all unit tests pass

* hero-section: added missing test descriptions in footer.js

* hero-section: refactor components and file structure after review

* info-section: initial commit

* info-section: implemented About and How it works sections

* info-section: fix link to https://ooloo.io/employers

* info-section: implemented react-router-hash-link

* info-section: fixed ooloo.io link

* info-section: implemented unit tests

* info-section: fixed linting errors

* info-section: fixed linting errors

* info-section: fix unit test using this: testing-library/dom-testing-library#477 (comment)

* info-section: commit after review

* subreddit-form: initial commit. Setup folder structure

* subreddit-form: implement tests

* subreddit-form: fix lint error in Header.js

* subreddit-form: completed unit and e2e tests

* subreddit-form: fixes and cleanup after review

* load-the-data: initial commit: added LoadTheData.js

* load-the-data: fetching data implemented. But unit test and e2e test filing

* load-the-data: troubleshooting tests

* load-the-data: continue troubleshooting tests

* load-the-data: fix linting error

* load-the-data: fix the code to fetch top 500 posts

* load-the-data: troubleshooting unit test - 'invalid json response body at  reason: Unexpected end of JSON input'

* load-the-data: integration test passing

* load-the-data: refactor code after review. still 1 test to fix in SearchPage.js

* laod-the-data: all tests pass

* heatmap: first commit: setup heatmap table

* heatmap: implemented heatmap architecture

* heatmap: implemented user timezone

* heatmap: implemented hover, highlit and timezone

* heatmap: completed implementation - start testing

* heatmap: refactor component structure - set test skeleton

* heatmap: complete integration tests

* heatmap: complete. fix user timezone in tests

* heatmap: refactor code after review

* heatmap: fix all test errors. ready to merge pr

* heatmap: fix last test errors. ready to merge pr

* posts-table: e2e tests passing

* posts-table: 2 integration tests remaining

* posts-table: resolved conflicts

* posts-table: fix lint issue

* posts-table: fix lint issue

* posts-table: implemented posts sorted by time created

* post-table: refactor after review
  • Loading branch information
bahobab authored Oct 12, 2020
1 parent 377d3d7 commit 6d6dd0d
Show file tree
Hide file tree
Showing 18 changed files with 5,271 additions and 270 deletions.
68 changes: 67 additions & 1 deletion src/__tests__/SearchPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const setup = (initialPath = '/') => {
return { ...view, history };
};

async function clickFirstCellWithValue(cellValue) {
const heatmap = await screen.findByTestId('heatmap');
const cell = within(heatmap).getAllByText(cellValue)[0]; // first cell
userEvent.click(cell);
}

describe('heatmap', () => {
it('loads top post for subreddit in URL', async () => {
setup('/search/reactjs');
Expand Down Expand Up @@ -108,7 +114,67 @@ describe('subreddit form', () => {
it('no accessibility violation', async () => {
const { container } = setup('/search/reactjs');

expect(await screen.findByTestId('heatmap')).toBeInTheDocument();
// expect(await screen.findByTestId('heatmap')).toBeInTheDocument();
await clickFirstCellWithValue('3');

expect(await axe(container)).toHaveNoViolations();
});
});

describe('posts table', () => {
it('not visible when no cell clicked', async () => {
setup('/search/reactjs');
await screen.findByTestId('heatmap');

expect(screen.queryByRole('table')).not.toBeInTheDocument();
});

it('not visible when cell clicked has value 0', async () => {
setup('/search/reactjs');
await clickFirstCellWithValue('0'); // argument is string

expect(screen.queryByRole('table')).not.toBeInTheDocument();
});

it('shows posts ordered by time acording to cell clicked', async () => {
setup('/search/reactjs');
await clickFirstCellWithValue('3'); // argument is string

const table = screen.getByRole('table');
const tableRows = within(table)
.getAllByRole('row')
.slice(1); // return rows in tbody, exclude header row

const tableContents = tableRows.map((row) => {
const cells = within(row).getAllByRole('cell');
const titleLink = within(cells[0]).getByRole('link');
const authorLink = within(cells[4]).getByRole('link');

return {
title: titleLink.innerHTML,
href: titleLink.href,
time: cells[1].innerHTML,
score: cells[2].innerHTML,
numComments: cells[4].innerHTML,
author: authorLink.innerHTML,
authorLink: authorLink.href,
};
});

expect(tableContents).toMatchSnapshot();
});

it('shows no link for deleted author', async () => {
setup('/search/reactjs');
const heatmap = await screen.findByTestId('heatmap');
const hasDeletedAuthor = within(heatmap).getAllByText('3')[4];
userEvent.click(hasDeletedAuthor);

const table = screen.getByRole('table');
const rowWithDeletedUser = within(table).getAllByRole('row')[2];

const authorCell = within(rowWithDeletedUser).getAllByRole('cell')[4];
expect(within(authorCell).queryByRole('link')).not.toBeInTheDocument();
expect(authorCell.innerHTML).toBe('[deleted]');
});
});
98 changes: 98 additions & 0 deletions src/__tests__/_PostsTable.js_
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from 'react';
import { MemoryRouter, Route } from 'react-router-dom';
import {
render, screen, within,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';

import App from '../app';

const setup = (initialPath = '/') => {
let history;

const view = render(
<MemoryRouter initialEntries={[initialPath]}>
<App />
<Route
path="*"
render={(props) => {
history = props.history;
return null;
}}
/>
</MemoryRouter>,
);
return { ...view, history };
};

describe('post table', () => {
it('shows posts per hour in table', async () => {
setup('/search/reactjs');

let cellToClick;
let numPosts;

screen.getByText('loading-spinner.svg');

const heatmap = await screen.findByTestId('heatmap');

expect(heatmap).toBeInTheDocument();
const cells = await within(heatmap).findAllByRole('button');

// posts table is shown when a box is cliked

// it is not shown when there are no posts for the selected weekday/hour
// eslint-disable-next-line prefer-destructuring
cellToClick = cells[0];
numPosts = Number(cellToClick.innerHTML);

expect(numPosts).toBe(0);
userEvent.click(cellToClick);

// expect(postsTable).not.toBeInTheDocument();
expect(await screen.queryByTestId('postsTable')).toBeNull();

// it is shown when there are posts for the selected weekday/hour
// eslint-disable-next-line prefer-destructuring
cellToClick = cells[28]; // contains a deketed author
numPosts = Number(cellToClick.innerHTML);

expect(numPosts).not.toBe(0);
userEvent.click(cellToClick);

// posts table is shown when a box is cliked
const postsTable = await screen.findByTestId('postsTable');
expect(postsTable).toBeInTheDocument();

const postsRows = await within(postsTable).findAllByTestId('postRow');

expect(postsRows.length).not.toEqual(0);
expect(postsRows.length).toEqual(numPosts);

// links
postsRows.forEach((postRow) => {
// if the author has been deleted it should not be a link
const links = within(postRow).getAllByRole('link');
if (postRow.innerHTML.includes('[deleted]')) {
expect(links.length).toEqual(1);
expect(links[0]).toHaveAttribute('href', expect.not.stringContaining('https://reddit.com/u/'));
} else {
// 'match', /https:\/\/(www.)?reddit.com\/
// r\/javascript\/comments\/er5hqm\/the_new_babel_release_gives_support_for\/?/
// the title links to the post on Reddit
expect(links[0]).toHaveAttribute('href', expect.stringContaining('https://www.reddit.com/r/'));
// the title links opens in a new browser tab
expect(links[0]).toHaveAttribute('target', '_blank');
userEvent.click(links[0]);

// the author links to the author's reddit profile
expect(links[1]).toHaveAttribute('href', expect.stringContaining('https://reddit.com/u/'));
// the author links opens in a new browser tab
expect(links[1]).toHaveAttribute('target', '_blank');
}

// the posts are sorted by the time they have been created
});
});
});
32 changes: 32 additions & 0 deletions src/__tests__/__snapshots__/SearchPage.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,35 @@ Array [
"3",
]
`;

exports[`posts table shows posts ordered by time acording to cell clicked 1`] = `
Array [
Object {
"author": "jherr2016",
"authorLink": "https://reddit.com/u/jherr2016",
"href": "https://reddit.com/r/reactjs/comments/ff55gz/intro_to_federated_modules_in_webpack_5/",
"numComments": "<a href=\\"https://reddit.com/u/jherr2016\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\" class=\\"sc-efHXLn fIzpBR\\">jherr2016</a>",
"score": "127",
"time": "2 am",
"title": "Intro to Federated Modules in Webpack 5",
},
Object {
"author": "albaneso",
"authorLink": "https://reddit.com/u/albaneso",
"href": "https://reddit.com/r/reactjs/comments/du50op/reactinteractivepaycard/",
"numComments": "<a href=\\"https://reddit.com/u/albaneso\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\" class=\\"sc-efHXLn fIzpBR\\">albaneso</a>",
"score": "2070",
"time": "2 am",
"title": "react-interactive-paycard",
},
Object {
"author": "Fizaraz",
"authorLink": "https://reddit.com/u/Fizaraz",
"href": "https://reddit.com/r/reactjs/comments/gpg5xq/i_redesigned_my_personal_website_from_scratch_and/",
"numComments": "<a href=\\"https://reddit.com/u/Fizaraz\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\" class=\\"sc-efHXLn fIzpBR\\">Fizaraz</a>",
"score": "179",
"time": "2 am",
"title": "I redesigned my personal website from scratch, and it is great!",
},
]
`;
Loading

0 comments on commit 6d6dd0d

Please sign in to comment.