Skip to content

Upgrade codebase #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 83 commits into from
Apr 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
d63d1d8
Configure the store with Redux Toolkit
leosuncin Jun 12, 2021
3e8e7de
remove superagent dependency
leosuncin Jun 12, 2021
f131052
replace marked with snarkdown
leosuncin Jun 12, 2021
d0974df
convert article reducer to slice
leosuncin Jun 12, 2021
14b693c
convert auth reducer to slice
leosuncin Jun 13, 2021
6157cf9
Fix ListError component
leosuncin Jun 13, 2021
e5fc376
convert settings reducer to slice
leosuncin Jun 14, 2021
7fc69d9
convert profile reducer to slice
leosuncin Jun 14, 2021
5128756
install and setup Cypress
leosuncin Jun 14, 2021
52a677c
add e2e test for home page
leosuncin Jun 17, 2021
1c320b7
add e2e test for app navigation
leosuncin Jun 17, 2021
da11ef6
add e2e test for register page
leosuncin Jun 17, 2021
d068f09
add e2e test for login page
leosuncin Jun 17, 2021
ef7c858
add e2e test for editor page
leosuncin Jun 17, 2021
caa71f8
add more e2e test for editor page
leosuncin Jun 18, 2021
130e2b2
add e2e test for settings page
leosuncin Jun 18, 2021
7538550
add e2e test for article page
leosuncin Jun 18, 2021
d4c5e21
generate a markdown with faker
leosuncin Jun 18, 2021
e6880e3
add e2e test for profile page
leosuncin Jun 19, 2021
5723b0e
add more e2e test for app navigation
leosuncin Jun 19, 2021
26988be
add more e2e test for home page
leosuncin Jun 19, 2021
2d3d759
fix generated markdown
leosuncin Jun 19, 2021
e2880b7
stop using markdown because causes issues with compare strings
leosuncin Jun 19, 2021
3276166
ignore .nyc_output directory
leosuncin Jun 19, 2021
803d263
Merge branch 'e2e-tests' into redux-toolkit
leosuncin Jun 19, 2021
b64cd12
fix generate valid values
leosuncin Jun 19, 2021
8d56d5e
Merge branch 'e2e-tests' into redux-toolkit
leosuncin Jun 19, 2021
3a31da0
fix login custom command
leosuncin Jun 19, 2021
4c0bd15
fix comment actions
leosuncin Jun 25, 2021
587bb27
add more e2e test for article page
leosuncin Jun 25, 2021
b6e6562
remove editor reducer
leosuncin Jun 26, 2021
a138c71
change the type of the action dispatched when create an article
leosuncin Jun 26, 2021
65ce979
document API client methods
leosuncin Jun 28, 2021
488f8f7
Merge remote-tracking branch 'khaled/master' into redux-toolkit
khaledosman Jul 2, 2021
e1b46b9
merge & update app component to function component
khaledosman Jul 2, 2021
5bb3aca
convert class components to function components
khaledosman Jul 2, 2021
1124ec7
convert articleList reducer to slice
leosuncin Jun 30, 2021
dcd1856
convert common reducer to slice
leosuncin Jun 30, 2021
7895e82
Remove promiseMiddleware
leosuncin Jun 30, 2021
2f0bc55
fix fetch favorite articles in profile
leosuncin Jul 2, 2021
b45af50
regenerate NPM lock-file with npm v6
leosuncin Jul 2, 2021
4d6daeb
fix load article in editor
leosuncin Jul 2, 2021
29f4bca
document API client methods
leosuncin Jun 28, 2021
461515d
convert articleList reducer to slice
leosuncin Jun 30, 2021
3db31a2
convert common reducer to slice
leosuncin Jun 30, 2021
d709847
Remove promiseMiddleware
leosuncin Jun 30, 2021
7a498a3
fix fetch favorite articles in profile
leosuncin Jul 2, 2021
ab503d4
regenerate NPM lock-file with npm v6
leosuncin Jul 2, 2021
c340e90
fix load article in editor
leosuncin Jul 2, 2021
4d50cc2
Merge branch 'khaledosman-redux-toolkit' into redux-toolkit
leosuncin Jul 2, 2021
76425da
fix syntax error in articleList
leosuncin Jul 2, 2021
75fa8c0
refactor login component to use hooks instead of connect
leosuncin Jul 3, 2021
884bed5
refactor list error component
leosuncin Jul 3, 2021
db6e60e
refactor register component to use hooks instead of connect
leosuncin Jul 3, 2021
3a6259a
refactor settings components to use hooks instead of connect
leosuncin Jul 3, 2021
d6c612a
fix profile screen component
leosuncin Jul 3, 2021
2d3e47c
refactor editor component to use hooks instead of connect
leosuncin Jul 5, 2021
bcf3a69
refactor article component to use hooks instead of connect
leosuncin Jul 6, 2021
9ab13ab
refactor to avoid prop drilling in ArticleList
leosuncin Jul 6, 2021
5db3ef2
refactor home component to use hooks instead of connect
leosuncin Jul 6, 2021
ad2ac93
refactor app component to use hooks instead of connect
leosuncin Jul 6, 2021
ace84e0
chore: setup git hooks
leosuncin Jul 26, 2021
658114a
refactor(tags): add tags slice
leosuncin Jul 26, 2021
923f70d
test(tags): add unit tests
leosuncin Jul 26, 2021
55b59ba
refactor(tags): sidebar component
leosuncin Jul 26, 2021
0cf8177
refactor: add function to create the store
leosuncin Jul 26, 2021
869c2ae
chore: setup tests
leosuncin Jul 26, 2021
a6e8452
test(tags): sidebar component
leosuncin Jul 26, 2021
5be270b
refactor(tags): tag list component
leosuncin Jul 26, 2021
e989c78
refactor(auth): auth slice
leosuncin Jul 26, 2021
e860ce5
test(auth): auth slice
leosuncin Jul 26, 2021
fa9de44
refactor(auth): combine Login and Register into AuthScreen
leosuncin Jul 26, 2021
705f987
fix: call next action after the side effects
leosuncin Jul 26, 2021
84057d5
test(auth): login and register forms
leosuncin Jul 26, 2021
d2aaf5e
refactor(settings): remove settings reducer
leosuncin Jul 26, 2021
6b12ff0
refactor(auth): update settings component
leosuncin Jul 26, 2021
527485a
test(auth): add tests for settings screen
leosuncin Jul 26, 2021
a335bce
refactor(comments): add comments slice
leosuncin Jul 27, 2021
d3a48a3
test(comments): add tests for comments slice
leosuncin Jul 27, 2021
228458c
refactor(comments): arrange components
leosuncin Jul 27, 2021
1d889c6
test(comments): add tests for components
leosuncin Jul 27, 2021
9292e4e
migrate to react v18, getrid of history & connected-react-router, upg…
Apr 13, 2022
dd3492c
Merge remote-tracking branch 'leo/redux-toolkit' into upgrade-codebase
Apr 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules

# testing
coverage
.nyc_output

# production
build
Expand All @@ -16,3 +17,6 @@ npm-debug.log
.idea

.eslintcache

cypress/videos
cypress/screenshots
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx pretty-quick --staged
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"singleQuote": true
}
9 changes: 9 additions & 0 deletions cypress.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"baseUrl": "http://localhost:4100",
"env": {
"apiUrl": "https://conduit.productionready.io/api",
"username": "warren_boyd",
"email": "[email protected]",
"password": "Pa$$w0rd!"
}
}
22 changes: 22 additions & 0 deletions cypress/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Cypress.io end-to-end tests 🚀

[Cypress.io](https://www.cypress.io) is an open source, MIT licensed end-to-end test runner

## Folder structure

These folders hold the end-to-end tests and supporting files for the [Cypress Test Runner](https://github.com/cypress-io/cypress).

- [fixtures](fixtures) folder holds optional JSON data for mocking, [read more](https://on.cypress.io/fixture)
- [integration](integration) holds the actual test files, [read more](https://on.cypress.io/writing-and-organizing-tests)
- [plugins](plugins) allow you to customize how tests are loaded, [read more](https://on.cypress.io/plugins)
- [support](support) file runs before all tests and is a great place to write or load additional custom commands, [read more](https://on.cypress.io/writing-and-organizing-tests#Support-file)

## `cypress.json` file

You can configure project options in the [../cypress.json](../cypress.json) file, see [Cypress configuration doc](https://on.cypress.io/configuration).

## More information

- [https://github.com/cypress.io/cypress](https://github.com/cypress.io/cypress)
- [https://docs.cypress.io/](https://docs.cypress.io/)
- [Writing your first Cypress test](https://on.cypress.io/intro)
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
177 changes: 177 additions & 0 deletions cypress/integration/article-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// enables intelligent code completion for Cypress commands
// https://on.cypress.io/intelligent-code-completion
/// <reference types="cypress" />
/// <reference types="@testing-library/cypress" />
import faker from 'faker';

describe('Article page', () => {
beforeEach(() => {
cy.intercept('GET', '**/articles?*')
.as('getAllArticles')
.intercept('GET', '**/articles/*/comments')
.as('getCommentsForArticle')
.intercept('GET', '**/articles/*')
.as('getArticle')
.visit('/');

cy.wait('@getAllArticles').get('.preview-link').first().click();
});

it('should show the article', () => {
cy.wait('@getArticle')
.its('response.body.article')
.then((article) => {
cy.location('pathname').should('equal', `/article/${article.slug}`);

cy.findByRole('heading', { name: article.title }).should('be.visible');

cy.get('.article-meta').within(() => {
cy.findByRole('img', { name: article.author.username }).should(
'be.visible'
);

cy.findByText(article.author.username).should('be.visible');
});

cy.get('.article-content .col-xs-12')
.children()
.first()
.should('not.be.empty');

cy.get('.tag-list')
.children()
.should('have.length', article.tagList.length);
});
});

it('should require to be logged to comment', () => {
cy.findByText(/to add comments on this article/i).should('be.visible');
});
});

describe('Article page (authenticated)', () => {
const commentPlaceholder = 'Write a comment...';
const postCommentButton = 'Post Comment';

beforeEach(() => {
cy.intercept('GET', '**/articles?*')
.as('getAllArticles')
.intercept('GET', '**/articles/*/comments')
.as('getCommentsForArticle')
.intercept('GET', '**/articles/*')
.as('getArticle')
.intercept('POST', '**/articles/*/comments')
.as('createComment')
.intercept('DELETE', '**/articles/*/comments/*')
.as('deleteComment')
.visit('/')
.login();

cy.wait('@getAllArticles').get('.preview-link').first().click();
});

it('should show the comment box', () => {
cy.wait(['@getArticle', '@getCommentsForArticle']);

cy.get('.comment-form').should('exist');
});

it('should add a new comment', () => {
const comment = faker.lorem.paragraph();

cy.wait(['@getArticle', '@getCommentsForArticle']);

cy.findByPlaceholderText(commentPlaceholder).type(comment);

cy.findByRole('button', { name: postCommentButton }).click();

cy.wait('@createComment').its('response.statusCode').should('equal', 200);

cy.wait(100)
.get('.card:not(form)')
.first()
.within(() => {
cy.findByText(comment).should('exist');
});
});

it('should validate the comment box', () => {
cy.wait(['@getArticle', '@getCommentsForArticle']);

cy.findByRole('button', { name: postCommentButton }).click();

cy.wait('@createComment').its('response.statusCode').should('equal', 422);

cy.get('.error-messages').within(() => {
cy.findAllByRole('listitem').should('have.length', 1);
});
});

it('should remove my own comment', () => {
const comment = faker.lorem.sentence();

cy.wait(['@getArticle', '@getCommentsForArticle']);

cy.findByPlaceholderText(commentPlaceholder).type(comment);

cy.findByRole('button', { name: postCommentButton }).click();

cy.wait('@createComment');

cy.findByText(comment)
.as('comment')
.parent()
.parent()
.find('.mod-options i')
.click();

cy.wait('@deleteComment').its('response.statusCode').should('equal', 200);

cy.findByText(comment).should('not.exist');
});
});

describe('Article page (author)', () => {
const commentPlaceholder = 'Write a comment...';
const postCommentButton = 'Post Comment';

beforeEach(() => {
cy.intercept('GET', '**/articles/*')
.as('getArticle')
.intercept('GET', '**/articles/*/comments')
.as('getCommentsForArticle')
.intercept('POST', '**/articles/*/comments')
.as('createComment')
.intercept('DELETE', '**/articles/*')
.as('deleteArticle');

cy.visit('/')
.login()
.createArticle()
.then((article) => {
cy.visit(`/article/${article.slug}`);

cy.wait(['@getArticle', '@getCommentsForArticle']);
});
});

it('should add a new comment', () => {
const comment = faker.lorem.paragraph();

cy.findByPlaceholderText(commentPlaceholder).type(comment);

cy.findByRole('button', { name: postCommentButton }).click();

cy.wait('@createComment').its('response.statusCode').should('equal', 200);
});

it('should remove my article', () => {
cy.findByRole('button', {
name: /delete article/i,
}).click();

cy.wait('@deleteArticle').its('response.statusCode').should('equal', 200);

cy.location('pathname').should('equal', '/');
});
});
Loading