diff --git a/mpwo_client/.eslintrc.json b/.eslintrc.json similarity index 100% rename from mpwo_client/.eslintrc.json rename to .eslintrc.json diff --git a/.gitignore b/.gitignore index 694f46a6..2495e97d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,8 @@ ############### __pycache__ /mpwo_api/venv/ - +uploads +.cache # MPWO_CLIENT ############### @@ -31,4 +32,3 @@ npm-debug.log* yarn-debug.log* yarn-error.log* .eslintcache -uploads diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..b1ba1bbe --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,3 @@ +[settings] +multi_line_output=5 +default_section=THIRDPARTY diff --git a/Makefile b/Makefile index 5ed4ca74..1a60b062 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,14 @@ install-python: test -d $(VENV) || virtualenv $(VENV) -p $(PYTHON_VERSION) $(PIP) install -r $(REQUIREMENTS) +lint-all: lint-python lint-react + +lint-python: + $(PYTEST) --flake8 --isort -m "flake8 or isort" mpwo_api + +lint-react: + $(NPM) lint + serve-python: $(FLASK) run --with-threads -h $(HOST) -p $(API_PORT) diff --git a/Makefile.config b/Makefile.config index d5a5c193..77f7b0f7 100644 --- a/Makefile.config +++ b/Makefile.config @@ -15,6 +15,7 @@ VENV = $(PWD)/mpwo_api/venv PYTHON = $(VENV)/bin/python PIP = $(VENV)/bin/pip FLASK = $(VENV)/bin/flask +PYTEST = $(VENV)/bin/py.test # Node env NODE_MODULES = $(PWD)/mpwo_client/node_modules diff --git a/mpwo_api/mpwo_api/__init__.py b/mpwo_api/mpwo_api/__init__.py index e4b85613..4ab4bf06 100644 --- a/mpwo_api/mpwo_api/__init__.py +++ b/mpwo_api/mpwo_api/__init__.py @@ -31,9 +31,10 @@ if app.debug: logging.getLogger('sqlalchemy' ).handlers = logging.getLogger('werkzeug').handlers logging.getLogger('sqlalchemy.orm').setLevel(logging.WARNING) + logging.getLogger('flake8').propagate = False appLog.setLevel(logging.DEBUG) -if app.debug : +if app.debug: # Enable CORS @app.after_request def after_request(response): diff --git a/mpwo_api/mpwo_api/config.py b/mpwo_api/mpwo_api/config.py index fa55ee9a..acd73157 100644 --- a/mpwo_api/mpwo_api/config.py +++ b/mpwo_api/mpwo_api/config.py @@ -1,4 +1,5 @@ import os + from flask import current_app diff --git a/mpwo_api/mpwo_api/tests/base.py b/mpwo_api/mpwo_api/tests/base.py index bb095606..23bb6e20 100644 --- a/mpwo_api/mpwo_api/tests/base.py +++ b/mpwo_api/mpwo_api/tests/base.py @@ -1,5 +1,4 @@ from flask_testing import TestCase - from mpwo_api import app, db diff --git a/mpwo_api/mpwo_api/tests/test_auth.py b/mpwo_api/mpwo_api/tests/test_auth.py index 4b363049..b188b1bf 100644 --- a/mpwo_api/mpwo_api/tests/test_auth.py +++ b/mpwo_api/mpwo_api/tests/test_auth.py @@ -62,7 +62,7 @@ class TestAuthBlueprint(BaseTestCase): data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'error') self.assertTrue( - data['message'] == "Errors: Username: 3 to 12 characters required.\n") + data['message'] == "Errors: Username: 3 to 12 characters required.\n") # noqa self.assertTrue(response.content_type == 'application/json') self.assertEqual(response.status_code, 400) @@ -81,7 +81,7 @@ class TestAuthBlueprint(BaseTestCase): data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'error') self.assertTrue( - data['message'] == "Errors: Username: 3 to 12 characters required.\n") + data['message'] == "Errors: Username: 3 to 12 characters required.\n") # noqa self.assertTrue(response.content_type == 'application/json') self.assertEqual(response.status_code, 400) @@ -100,7 +100,7 @@ class TestAuthBlueprint(BaseTestCase): data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'error') self.assertTrue( - data['message'] == "Errors: Valid email must be provided.\n") + data['message'] == "Errors: Valid email must be provided.\n") # noqa self.assertTrue(response.content_type == 'application/json') self.assertEqual(response.status_code, 400) @@ -119,7 +119,7 @@ class TestAuthBlueprint(BaseTestCase): data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'error') self.assertTrue( - data['message'] == "Errors: Password: 8 characters required.\n") + data['message'] == "Errors: Password: 8 characters required.\n") # noqa self.assertTrue(response.content_type == 'application/json') self.assertEqual(response.status_code, 400) @@ -138,7 +138,7 @@ class TestAuthBlueprint(BaseTestCase): data = json.loads(response.data.decode()) self.assertTrue(data['status'] == 'error') self.assertTrue( - data['message'] == "Errors: Password and password confirmation don\'t match.\n") + data['message'] == "Errors: Password and password confirmation don\'t match.\n") # noqa self.assertTrue(response.content_type == 'application/json') self.assertEqual(response.status_code, 400) diff --git a/mpwo_api/mpwo_api/users/auth.py b/mpwo_api/mpwo_api/users/auth.py index 139d631f..e317f507 100644 --- a/mpwo_api/mpwo_api/users/auth.py +++ b/mpwo_api/mpwo_api/users/auth.py @@ -1,11 +1,11 @@ import datetime import os + from flask import Blueprint, current_app, jsonify, request +from mpwo_api import appLog, bcrypt, db from sqlalchemy import exc, or_ from werkzeug.utils import secure_filename -from mpwo_api import appLog, bcrypt, db - from .models import User from .utils import allowed_picture, authenticate, register_controls diff --git a/mpwo_api/mpwo_api/users/models.py b/mpwo_api/mpwo_api/users/models.py index 22bb5363..c8e56217 100644 --- a/mpwo_api/mpwo_api/users/models.py +++ b/mpwo_api/mpwo_api/users/models.py @@ -2,7 +2,6 @@ import datetime import jwt from flask import current_app - from mpwo_api import bcrypt, db diff --git a/mpwo_api/mpwo_api/users/utils.py b/mpwo_api/mpwo_api/users/utils.py index 589950b2..914cae14 100644 --- a/mpwo_api/mpwo_api/users/utils.py +++ b/mpwo_api/mpwo_api/users/utils.py @@ -1,5 +1,5 @@ -from functools import wraps import re +from functools import wraps from flask import current_app, jsonify, request diff --git a/mpwo_api/requirements.txt b/mpwo_api/requirements.txt index 901e92e0..5ae8b231 100644 --- a/mpwo_api/requirements.txt +++ b/mpwo_api/requirements.txt @@ -18,6 +18,11 @@ psycopg2==2.7.3.2 pycodestyle==2.3.1 pycparser==2.18 pyflakes==1.6.0 +pytest==3.3.2 +pytest-cache==1.0 +pytest-flake8==0.9.1 +pytest-isort==0.1.0 +pytest-runner==3.0 PyJWT==1.5.3 six==1.11.0 SQLAlchemy==1.1.15 diff --git a/mpwo_client/src/components/User/UserForm.jsx b/mpwo_client/src/components/User/UserForm.jsx index b206855a..4b627ca2 100644 --- a/mpwo_client/src/components/User/UserForm.jsx +++ b/mpwo_client/src/components/User/UserForm.jsx @@ -3,7 +3,11 @@ import { connect } from 'react-redux' import { Redirect } from 'react-router-dom' import Form from './Form' -import { emptyForm, handleFormChange, handleUserFormSubmit } from '../../actions' +import { + emptyForm, + handleFormChange, + handleUserFormSubmit +} from '../../actions' import { isLoggedIn } from '../../utils' class UserForm extends React.Component { diff --git a/package-lock.json b/package-lock.json index b5a18825..6d11516c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2761,11 +2761,6 @@ "cssom": "0.3.2" } }, - "cuid": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/cuid/-/cuid-2.0.2.tgz", - "integrity": "sha512-dzz/KESlvSRPnAoThLqxHGfW94rtPYrHpQ8OpT5WwfJVlhysPw1U989+3fHrn/FdtuMrFW5dzOVR/CAb90RbNw==" - }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", @@ -4404,7 +4399,8 @@ }, "jsbn": { "version": "0.1.1", - "bundled": true + "bundled": true, + "optional": true }, "json-schema": { "version": "0.2.3", @@ -5070,11 +5066,6 @@ "minimalistic-assert": "1.0.0" } }, - "hashids": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/hashids/-/hashids-1.1.4.tgz", - "integrity": "sha512-U/fnTE3edW0AV92ZI/BfEluMZuVcu3MDOopsN7jS+HqDYcarQo8rXQiWlsBlm0uX48/taYSdxRsfzh2HRg5Z6w==" - }, "hawk": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", @@ -7381,6 +7372,12 @@ "lcid": "1.0.0" } }, + "os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "dev": true + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -9435,6 +9432,28 @@ } } }, + "pre-commit": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz", + "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=", + "dev": true, + "requires": { + "cross-spawn": "5.1.0", + "spawn-sync": "1.0.15", + "which": "1.2.14" + }, + "dependencies": { + "which": { + "version": "1.2.14", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", + "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", + "dev": true, + "requires": { + "isexe": "2.0.0" + } + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -9796,14 +9815,6 @@ "react-side-effect": "1.1.3" } }, - "react-key-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/react-key-index/-/react-key-index-0.1.1.tgz", - "integrity": "sha1-gxnk8JYa5EqOsKT3bkwhDvbTnNo=", - "requires": { - "hashids": "1.1.4" - } - }, "react-redux": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.0.6.tgz", @@ -11646,6 +11657,16 @@ "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", "dev": true }, + "spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "os-shim": "0.1.3" + } + }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", diff --git a/package.json b/package.json index 8283f5ea..7df814b3 100644 --- a/package.json +++ b/package.json @@ -21,14 +21,17 @@ "build": "cd mpwo_client && react-scripts build", "test": "cd mpwo_client && testcafe firefox e2e", "eject": "cd mpwo_client && react-scripts eject", - "lint": "cd mpwo_client && eslint --cache --ext .jsx --ext .js src" + "lint": "eslint --cache --ext .jsx --ext .js mpwo/src", + "lint-all": "make lint-all" }, + "pre-commit": "lint-all", "devDependencies": { "babel-eslint": "^8.0.3", "eslint": "^4.13.1", "eslint-plugin-import": "^2.8.0", "eslint-plugin-react": "^7.5.1", "eslint-plugin-testcafe": "^0.2.1", + "pre-commit": "^1.2.2", "randomstring": "^1.1.5", "testcafe": "^0.18.6" } diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..09621cc4 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +norecursedirs = mpwo_api/venv