diff --git a/.env b/.env deleted file mode 100644 index 7cc86b701e..0000000000 --- a/.env +++ /dev/null @@ -1,4 +0,0 @@ -# Copy this file to `.env` and replace "1000:1000" with -# your user id/group id -# Linux/OSX/Windows run `id -u` and `id -g` -CURRENT_USER=1000:1000 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000000..75c8e926c9 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Copy this file to `.env` and replace "1000:1000" with +# your user id/group id. `.env` is used by docker-compose +# making files created in the docker container owned by +# your host user (instead of root). +# Linux/OSX run `id -u` and `id -g` +CURRENT_USER=1000:1000 diff --git a/.gitignore b/.gitignore index d21db6dfc0..c70e2905bf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ reports node_modules coverage .DS_Store -.env.dev +.env +junit.xml +frontend/build diff --git a/README.md b/README.md index da7a241125..218fa8e41e 100644 --- a/README.md +++ b/README.md @@ -9,14 +9,24 @@ Getting Started Make sure Docker is installed. To check run `docker ps` -Run `yarn docker:deps`. This builds the frontend and backend docker containers and install dependencies. You only need to run this step the first time you fire up the app and when dependencies are added/updated/removed. Running `yarn docker:start` starts the backend and frontend, browse to `http://localhost:3000` to hit the frontend and `http://localhost:3000/api` to hit the backend. Copying `.env` to `.env.dev`, substituting in your user id and group id will cause any files created in docker containers to be owned by your user on your host. +Run `yarn docker:deps`. This builds the frontend and backend docker containers and install dependencies. You only need to run this step the first time you fire up the app and when dependencies are added/updated/removed. Running `yarn docker:start` starts the backend and frontend, browse to `http://localhost:3000` to hit the frontend and `http://localhost:3000/api` to hit the backend. Copying `.env.example` to `.env`, substituting in your user id and group id will cause any files created in docker containers to be owned by your user on your host. + +You can also run build commands directly on your host (without docker). Make sure you install dependencies when changing execution method. You could see some odd errors if you install dependencies for docker and then run yarn commands directly on the host, especially if you are developing on windows. If you want to use the host yarn commands be sure to run `yarn deps` before any other yarn commands. Likewise if you want to use docker make sure you run `yarn docker:deps`. The frontend [proxies requests](https://create-react-app.dev/docs/proxying-api-requests-in-development/) to paths it doesn't recognize to the backend. Running Tests ------------- -Run `yarn docker:deps` to install dependencies. Run `yarn docker:test` to run all tests +Run `yarn docker:deps` to install dependencies. Run `yarn docker:test` to run all tests for the frontend and backend. + +Docker on Windows +----------------- + +You may run into some issues running the docker commands on Windows: + + * If you run into `Permission Denied` errors see [this issue](https://github.com/docker/for-win/issues/3385#issuecomment-501931980) + * You can try to speed up execution time on windows with solutions posted to [this issue](https://github.com/docker/for-win/issues/1936) Other Commands -------------- @@ -28,15 +38,16 @@ Other Commands | `yarn docker:stop` | Stops the backend and frontend docker containers | | `yarn docker:test` | Runs tests for the frontend and backend in docker containers | | `yarn docker:lint` | Runs the linter for the frontend and backend in docker containers | -| `yarn docker:audit` | Runs `yarn audit` against frontend and backend dependencies | | `yarn deps` | Install dependencies for the frontend and backend | | `yarn start` | Starts the backend and frontend | | `yarn server` | Starts the backend | | `yarn client` | Start the frontend | -| `yarn test` | Run tests for the backend and frontend | -| `yarn eslint` | Run the linter for the backend and frontend | -| `yarn lint:ci` | Run the linter in outputting results to the `reports` directory | -| `yarn test:ci` | Run backend tests outputting results to the `reports` directory | +| `yarn test` | Run tests for only the backend | +| `yarn test:ci` | Run tests for the backend with coverage and output results to xml files| +| `yarn test:all` | Run `yarn test:ci` for both the frontend and backend | +| `yarn lint` | Run the linter only for the backend | +| `yarn lint:ci` | Run the linter for the the backend with results output to xml files | +| `yarn lint:all` | Run `yarn lint:ci` for both the frontend and backend | Deployment ---------- diff --git a/docker-compose.yml b/docker-compose.yml index 39d5d3914f..b28fb7a593 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,8 +6,6 @@ services: dockerfile: Dockerfile.dev command: yarn server user: ${CURRENT_USER:-root} - env_file: - - .env ports: - "3001:3001" volumes: @@ -18,8 +16,6 @@ services: dockerfile: Dockerfile.dev command: yarn start user: ${CURRENT_USER:-root} - env_file: - - .env stdin_open: true ports: - "3000:3000" @@ -27,6 +23,4 @@ services: - "./frontend:/app:rw" - "./scripts:/app/scripts" environment: - - JEST_JUNIT_OUTPUT_DIR=reports - - JEST_JUNIT_OUTPUT_NAME=unit.xml - BACKEND_PROXY=http://backend:3001 diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000000..a934261acd --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,52 @@ +# TTADP Frontend + +A React frontend initialized with Create React App + +## Getting Started + +There are yarn commands for starting/testing/linting the frontend defined a directory up. `yarn start` or `yarn docker:start` a directory up will start both the backend and frontend. `yarn docker:test` or `yarn test:all` will test the frontend and the backend. However if you want to just run the frontend tests/linter you can run yarn commands in this directory. Install dependencies with `yarn install`. `yarn start` will fire up the development server. Use `yarn test` and `yarn lint` for running tests and the linter. + +### Yarn Commands + +| Yarn Command | Description | +|-|-| +| `yarn start` | Start the frontend development server | +| `yarn build` | Build a production bundle | +| `yarn test` | Start the test watcher | +| `yarn test:ci` | Run unit tests a single time outputting results to xml files | +| `yarn lint` | Run the linter | +| `yarn lint:ci` | Run the linter outputting results to xml files | + +## Create React App + +This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). + +## Learn More + +You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). + +To learn React, check out the [React documentation](https://reactjs.org/). + +### Code Splitting + +This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting + +### Analyzing the Bundle Size + +This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size + +### Making a Progressive Web App + +This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app + +### Advanced Configuration + +This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration + +### Deployment + +This section has moved here: https://facebook.github.io/create-react-app/docs/deployment + +### `yarn build` fails to minify + +This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify \ No newline at end of file diff --git a/frontend/build/favicon.ico b/frontend/build/favicon.ico deleted file mode 100644 index bcd5dfd67c..0000000000 Binary files a/frontend/build/favicon.ico and /dev/null differ diff --git a/frontend/build/logo192.png b/frontend/build/logo192.png deleted file mode 100644 index fc44b0a379..0000000000 Binary files a/frontend/build/logo192.png and /dev/null differ diff --git a/frontend/build/logo512.png b/frontend/build/logo512.png deleted file mode 100644 index a4e47a6545..0000000000 Binary files a/frontend/build/logo512.png and /dev/null differ diff --git a/frontend/build/manifest.json b/frontend/build/manifest.json deleted file mode 100644 index 080d6c77ac..0000000000 --- a/frontend/build/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "React App", - "name": "Create React App Sample", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/frontend/build/robots.txt b/frontend/build/robots.txt deleted file mode 100644 index e9e57dc4d4..0000000000 --- a/frontend/build/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/frontend/package.json b/frontend/package.json index a2e046a058..49d7455cda 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,9 +14,11 @@ "scripts": { "start": "react-scripts start", "build": "react-scripts build", - "test": "react-scripts test", "eject": "react-scripts eject", - "test:ci": "CI=true yarn test --coverage --reporters=default --reporters=jest-junit" + "test": "react-scripts test", + "test:ci": "cross-env JEST_JUNIT_OUTPUT_DIR=reports JEST_JUNIT_OUTPUT_NAME=unit.xml CI=true yarn test --coverage --reporters=default --reporters=jest-junit", + "lint": "eslint src", + "lint:ci": "eslint -f eslint-formatter-multiple src" }, "eslintConfig": { "root": true, @@ -37,13 +39,27 @@ ".jsx" ] } - ] + ], + "linebreak-style": 0 }, "env": { "jest/globals": true, "browser": true } }, + "eslint-formatter-multiple": { + "formatters": [ + { + "name": "stylish", + "output": "console" + }, + { + "name": "junit", + "output": "file", + "path": "reports/lint.xml" + } + ] + }, "babel": { "presets": [ "@babel/preset-react" @@ -65,8 +81,10 @@ "@testing-library/dom": "^7.21.7", "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", + "cross-env": "^7.0.2", "eslint": "^6.8.0", "eslint-config-airbnb": "^18.2.0", + "eslint-formatter-multiple": "^1.0.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-jest": "^23.20.0", "eslint-plugin-jsx-a11y": "^6.3.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 8a394830a1..24d3b3fe31 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3405,6 +3405,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-env@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" @@ -3425,6 +3432,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -4261,6 +4277,11 @@ eslint-config-react-app@^5.2.1: dependencies: confusing-browser-globals "^1.0.9" +eslint-formatter-multiple@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-formatter-multiple/-/eslint-formatter-multiple-1.0.0.tgz#223db63a682038b001763c5d36d32975be4bdbb3" + integrity sha512-0Jv8gn7LmXj9c20E9BNAI1Wn3Lxw2v3nCvYRpk30kBLhc3wBees6DIXkJgaY2hoeOjvSq8n4peQ6KJstk5gmKQ== + eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.3: version "0.3.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" diff --git a/package.json b/package.json index 9df55bd423..5aab36f0b8 100644 --- a/package.json +++ b/package.json @@ -8,20 +8,20 @@ "start": "concurrently \"yarn server\" \"yarn client\"", "server": "nodemon src/index.js --ignore './frontend/' --exec babel-node", "client": "yarn --cwd frontend start", - "test": "jest src && yarn --cwd frontend test --watchAll=false", - "eslint": "eslint src", - "lint:ci": "eslint src -f junit -o reports/lint.xml src", - "test:ci": "jest src --coverage --reporters=default --reporters=jest-junit", + "test": "jest src", + "test:ci": "cross-env JEST_JUNIT_OUTPUT_DIR=reports JEST_JUNIT_OUTPUT_NAME=unit.xml CI=true jest src --coverage --reporters=default --reporters=jest-junit", + "test:all": "yarn test:ci && yarn --cwd frontend test:ci", + "lint": "eslint src", + "lint:ci": "eslint -f eslint-formatter-multiple src", + "lint:all": "yarn lint:ci && yarn --cwd frontend lint:ci", "clean": "rm -rf coverage reports frontend/coverage frontend/reports frontend/build", - - "docker:shell:frontend": "docker-compose run --rm frontend /bin/bash", - "docker:shell:backend": "docker-compose run --rm backend /bin/bash", "docker:deps": "docker-compose run --rm backend yarn install && docker-compose run --rm frontend yarn install", "docker:start": "docker-compose up -d", "docker:stop": "docker-compose down", "docker:test": "docker-compose run --rm backend yarn test:ci && docker-compose run --rm frontend yarn test:ci", - "docker:lint": "docker-compose run --rm backend yarn lint:ci", - "docker:audit": "docker-compose run --rm backend ./scripts/audit.sh && docker-compose run --rm frontend ./scripts/audit.sh" + "docker:lint": "docker-compose run --rm backend yarn lint:ci && docker-compose run --rm frontend yarn lint:ci", + "docker:shell:frontend": "docker-compose run --rm frontend /bin/bash", + "docker:shell:backend": "docker-compose run --rm backend /bin/bash" }, "repository": { "type": "git", @@ -34,6 +34,22 @@ ], "ignorePatterns": [ "node_modules/*" + ], + "rules": { + "linebreak-style": 0 + } + }, + "eslint-formatter-multiple": { + "formatters": [ + { + "name": "stylish", + "output": "console" + }, + { + "name": "junit", + "output": "file", + "path": "reports/lint.xml" + } ] }, "jest": { @@ -54,8 +70,10 @@ "@babel/plugin-transform-runtime": "^7.11.0", "@babel/preset-env": "^7.11.0", "concurrently": "^5.3.0", + "cross-env": "^7.0.2", "eslint": "^6.6.0", "eslint-config-airbnb-base": "^14.2.0", + "eslint-formatter-multiple": "^1.0.0", "eslint-plugin-import": "^2.22.0", "eslint-plugin-jest": "^23.20.0", "eslint-plugin-jsx-a11y": "^6.3.1", diff --git a/src/index.test.js b/src/index.test.js index 688e93b998..fa87a62455 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -2,7 +2,7 @@ import request from 'supertest'; import app from './app'; describe('Root', () => { - test('Returns a 200', async () => { + test('Successfully returns the page', async () => { const response = await request(app).get('/'); expect(response.status).toBe(200); }); diff --git a/yarn.lock b/yarn.lock index 0d38b84159..d3b1320163 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1901,6 +1901,13 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +cross-env@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.2.tgz#bd5ed31339a93a3418ac4f3ca9ca3403082ae5f9" + integrity sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw== + dependencies: + cross-spawn "^7.0.1" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -1912,6 +1919,15 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + crypto-random-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" @@ -2222,6 +2238,11 @@ eslint-config-airbnb-base@^14.2.0: object.assign "^4.1.0" object.entries "^1.1.2" +eslint-formatter-multiple@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-formatter-multiple/-/eslint-formatter-multiple-1.0.0.tgz#223db63a682038b001763c5d36d32975be4bdbb3" + integrity sha512-0Jv8gn7LmXj9c20E9BNAI1Wn3Lxw2v3nCvYRpk30kBLhc3wBees6DIXkJgaY2hoeOjvSq8n4peQ6KJstk5gmKQ== + eslint-import-resolver-node@^0.3.3: version "0.3.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" @@ -4523,6 +4544,11 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + path-parse@^1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" @@ -5163,11 +5189,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -5917,6 +5955,13 @@ which@^1.2.9, which@^1.3.0: dependencies: isexe "^2.0.0" +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"