From f9335c7a4eee3ea3ae1585be7230d241b363b310 Mon Sep 17 00:00:00 2001 From: richard-dds Date: Tue, 26 Jun 2018 10:31:39 -0400 Subject: [PATCH] Use black for formatting --- Pipfile | 1 + Pipfile.lock | 72 +++++++++++++++++++---- app.py | 4 +- atst/api_client.py | 38 ++++++------ atst/app.py | 60 ++++++++++--------- atst/forms/date.py | 7 ++- atst/forms/funding.py | 1 + atst/forms/organization_info.py | 1 + atst/forms/readiness.py | 1 + atst/forms/request.py | 93 ++++++++++++++++++++---------- atst/forms/review.py | 1 + atst/handler.py | 29 +++++----- atst/handlers/dev.py | 3 +- atst/handlers/home.py | 4 +- atst/handlers/login.py | 1 - atst/handlers/main.py | 4 +- atst/handlers/request.py | 73 ++++++++++++----------- atst/handlers/request_new.py | 89 +++++++++++++--------------- atst/handlers/workspace.py | 14 ++--- atst/home.py | 2 +- pyproject.toml | 18 ++++++ tests/conftest.py | 6 +- tests/forms/test_request.py | 4 +- tests/handlers/test_request_new.py | 24 +++++--- tests/mocks.py | 34 +++++------ tests/test_api_client.py | 2 +- tests/test_auth.py | 11 ++-- tests/test_routes.py | 20 +++---- 28 files changed, 362 insertions(+), 255 deletions(-) create mode 100644 pyproject.toml diff --git a/Pipfile b/Pipfile index d82be36b..b3246515 100644 --- a/Pipfile +++ b/Pipfile @@ -15,6 +15,7 @@ pytest-tornado = "==0.5.0" ipython = "*" ipdb = "*" pylint = "*" +black = "*" [requires] python_version = "3.6" diff --git a/Pipfile.lock b/Pipfile.lock index b613f8c2..85273860 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3ee82a3d0081be8881d2c211c6d0333b179e78754e953b609e10a51a4ab87c88" + "sha256": "4792f21af3f461ea6eb1c7c2f7387a545cb5cfaedaf5f27694e16b6ba0a042fd" }, "pipfile-spec": 6, "requires": { @@ -58,6 +58,13 @@ } }, "develop": { + "appdirs": { + "hashes": [ + "sha256:9e5896d1372858f8dd3344faf4e5014d21849c756c8d5701f78f8a103b372d92", + "sha256:d8b24664561d0d34ddfaec54636d502d7cea6e29c3eaf68f3df6180863e2166e" + ], + "version": "==1.4.3" + }, "appnope": { "hashes": [ "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", @@ -68,10 +75,10 @@ }, "astroid": { "hashes": [ - "sha256:0ef2bf9f07c3150929b25e8e61b5198c27b0dca195e156f0e4d5bdd89185ca1a", - "sha256:fc9b582dba0366e63540982c3944a9230cbc6f303641c51483fa547dcc22393a" + "sha256:ae61ddd0290963f4cf3bd74e6dffce807466bfe25438b2b3598471a1ce40a635", + "sha256:f447b5c8b7bd5cba229fb73890ea8088380c8c37ff33417c29a53a553f857419" ], - "version": "==1.6.5" + "version": "==2.0.0.dev3" }, "atomicwrites": { "hashes": [ @@ -94,6 +101,21 @@ ], "version": "==0.1.0" }, + "black": { + "hashes": [ + "sha256:22158b89c1a6b4eb333a1e65e791a3f8b998cf3b11ae094adb2570f31f769a44", + "sha256:4b475bbd528acce094c503a3d2dbc2d05a4075f6d0ef7d9e7514518e14cc5191" + ], + "index": "pypi", + "version": "==18.6b4" + }, + "click": { + "hashes": [ + "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d", + "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b" + ], + "version": "==6.7" + }, "decorator": { "hashes": [ "sha256:2c51dff8ef3c447388fe5e4453d24a2bf128d3a4c32af3fabef1f01c6851ab82", @@ -227,10 +249,10 @@ }, "ptyprocess": { "hashes": [ - "sha256:e64193f0047ad603b71f202332ab5527c5e52aa7c8b609704fc28c0dc20c4365", - "sha256:e8c43b5eee76b2083a9badde89fd1bbce6c8942d1045146e100b7b5e014f4f1a" + "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", + "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" ], - "version": "==0.5.2" + "version": "==0.6.0" }, "py": { "hashes": [ @@ -248,11 +270,11 @@ }, "pylint": { "hashes": [ - "sha256:a48070545c12430cfc4e865bf62f5ad367784765681b3db442d8230f0960aa3c", - "sha256:fff220bcb996b4f7e2b0f6812fd81507b72ca4d8c4d05daf2655c333800cb9b3" + "sha256:0990347c0f605927fadb2a9366a0b3d40bd19eb44e4312f0a1ef729a389b2f40", + "sha256:19b902f93f2dc3fa45565e54b88702b28379be40107f509a8516dde152460d1f" ], "index": "pypi", - "version": "==1.9.2" + "version": "==2.0.0.dev1" }, "pytest": { "hashes": [ @@ -283,6 +305,12 @@ ], "version": "==1.11.0" }, + "toml": { + "hashes": [ + "sha256:8e86bd6ce8cc11b9620cb637466453d94f5d57ad86f17e98a98d1f73e3baab2d" + ], + "version": "==0.9.4" + }, "tornado": { "hashes": [ "sha256:1b83d5c10550f2653380b4c77331d6f8850f287c4f67d7ce1e1c639d9222fbc7", @@ -301,6 +329,30 @@ ], "version": "==4.3.2" }, + "typed-ast": { + "hashes": [ + "sha256:0948004fa228ae071054f5208840a1e88747a357ec1101c17217bfe99b299d58", + "sha256:25d8feefe27eb0303b73545416b13d108c6067b846b543738a25ff304824ed9a", + "sha256:29464a177d56e4e055b5f7b629935af7f49c196be47528cc94e0a7bf83fbc2b9", + "sha256:2e214b72168ea0275efd6c884b114ab42e316de3ffa125b267e732ed2abda892", + "sha256:3e0d5e48e3a23e9a4d1a9f698e32a542a4a288c871d33ed8df1b092a40f3a0f9", + "sha256:519425deca5c2b2bdac49f77b2c5625781abbaf9a809d727d3a5596b30bb4ded", + "sha256:57fe287f0cdd9ceaf69e7b71a2e94a24b5d268b35df251a88fef5cc241bf73aa", + "sha256:668d0cec391d9aed1c6a388b0d5b97cd22e6073eaa5fbaa6d2946603b4871efe", + "sha256:68ba70684990f59497680ff90d18e756a47bf4863c604098f10de9716b2c0bdd", + "sha256:6de012d2b166fe7a4cdf505eee3aaa12192f7ba365beeefaca4ec10e31241a85", + "sha256:79b91ebe5a28d349b6d0d323023350133e927b4de5b651a8aa2db69c761420c6", + "sha256:8550177fa5d4c1f09b5e5f524411c44633c80ec69b24e0e98906dd761941ca46", + "sha256:a8034021801bc0440f2e027c354b4eafd95891b573e12ff0418dec385c76785c", + "sha256:bc978ac17468fe868ee589c795d06777f75496b1ed576d308002c8a5756fb9ea", + "sha256:c05b41bc1deade9f90ddc5d988fe506208019ebba9f2578c622516fd201f5863", + "sha256:c9b060bd1e5a26ab6e8267fd46fc9e02b54eb15fffb16d112d4c7b1c12987559", + "sha256:edb04bdd45bfd76c8292c4d9654568efaedf76fe78eb246dde69bdb13b2dad87", + "sha256:f19f2a4f547505fe9072e15f6f4ae714af51b5a681a97f187971f50c283193b6" + ], + "markers": "python_version < '3.7' and implementation_name == 'cpython'", + "version": "==1.1.0" + }, "wcwidth": { "hashes": [ "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", diff --git a/app.py b/app.py index 766f0caa..b6d66f53 100755 --- a/app.py +++ b/app.py @@ -8,8 +8,8 @@ config = make_config() deps = make_deps(config) app = make_app(config, deps) -if __name__ == '__main__': - port = int(config['default']['PORT']) +if __name__ == "__main__": + port = int(config["default"]["PORT"]) app.listen(port) print("Listening on http://localhost:%i" % port) tornado.ioloop.IOLoop.current().start() diff --git a/atst/api_client.py b/atst/api_client.py index b5edfbcb..7a8926b0 100644 --- a/atst/api_client.py +++ b/atst/api_client.py @@ -4,54 +4,52 @@ from json import dumps, loads class ApiClient(object): - def __init__(self, base_url, api_version=None, validate_cert=True): self.base_url = base_url if api_version: - self.base_url = f'{base_url}/api/{api_version}' + self.base_url = f"{base_url}/api/{api_version}" self.client = AsyncHTTPClient() self.validate_cert = validate_cert @tornado.gen.coroutine def get(self, path, **kwargs): - return (yield self.make_request('GET', self.base_url + path, **kwargs)) + return (yield self.make_request("GET", self.base_url + path, **kwargs)) @tornado.gen.coroutine def put(self, path, **kwargs): - return (yield self.make_request('PUT', self.base_url + path, **kwargs)) + return (yield self.make_request("PUT", self.base_url + path, **kwargs)) @tornado.gen.coroutine def post(self, path, **kwargs): - return (yield self.make_request('POST', self.base_url + path, **kwargs)) + return (yield self.make_request("POST", self.base_url + path, **kwargs)) @tornado.gen.coroutine def patch(self, path, **kwargs): - return (yield self.make_request('PATCH', self.base_url + path, **kwargs)) + return (yield self.make_request("PATCH", self.base_url + path, **kwargs)) @tornado.gen.coroutine def delete(self, path, **kwargs): - return (yield self.make_request('DELETE', self.base_url + path, **kwargs)) + return (yield self.make_request("DELETE", self.base_url + path, **kwargs)) @tornado.gen.coroutine def make_request(self, method, url, **kwargs): # If 'json' kwarg is specified, serialize it to 'body' and update # the Content-Type. - if 'json' in kwargs: - kwargs['body'] = dumps(kwargs['json']) - del kwargs['json'] - headers = kwargs.get('headers', {}) - headers['Content-Type'] = 'application/json' - kwargs['headers'] = headers - if not 'validate_cert' in kwargs: - kwargs['validate_cert'] = self.validate_cert + if "json" in kwargs: + kwargs["body"] = dumps(kwargs["json"]) + del kwargs["json"] + headers = kwargs.get("headers", {}) + headers["Content-Type"] = "application/json" + kwargs["headers"] = headers + if not "validate_cert" in kwargs: + kwargs["validate_cert"] = self.validate_cert - response = yield self.client.fetch( - url, method=method, **kwargs) + response = yield self.client.fetch(url, method=method, **kwargs) return self.adapt_response(response) def adapt_response(self, response): - if 'application/json' in response.headers['Content-Type']: + if "application/json" in response.headers["Content-Type"]: json = loads(response.body) - setattr(response, 'json', json) - setattr(response, 'ok', 200 <= response.code < 300) + setattr(response, "json", json) + setattr(response, "ok", 200 <= response.code < 300) return response diff --git a/atst/app.py b/atst/app.py index 55be1c50..5e2bb0ff 100644 --- a/atst/app.py +++ b/atst/app.py @@ -20,14 +20,14 @@ def make_app(config, deps, **kwargs): routes = [ url(r"/", Home, {"page": "login"}, name="main"), - url( - r"/login", - Login, - {"authnid_client": deps["authnid_client"]}, - name="login", - ), + url(r"/login", Login, {"authnid_client": deps["authnid_client"]}, name="login"), url(r"/home", MainHandler, {"page": "home"}, name="home"), - url( r"/workspaces/blank", MainHandler, {'page': 'workspaces_blank'}, name='workspaces_blank' ), + url( + r"/workspaces/blank", + MainHandler, + {"page": "workspaces_blank"}, + name="workspaces_blank", + ), url( r"/workspaces", Workspace, @@ -37,13 +37,15 @@ def make_app(config, deps, **kwargs): url( r"/requests", Request, - {"page": "requests", 'requests_client': deps['requests_client']}, - name="requests"), + {"page": "requests", "requests_client": deps["requests_client"]}, + name="requests", + ), url( r"/requests/new", RequestNew, {"page": "requests_new", "requests_client": deps["requests_client"]}, - name="request_new"), + name="request_new", + ), url( r"/requests/new/([0-9])", RequestNew, @@ -67,12 +69,11 @@ def make_app(config, deps, **kwargs): app = tornado.web.Application( routes, login_url="/", - - template_path = home.child('templates'), - static_path = home.child('static'), + template_path=home.child("templates"), + static_path=home.child("static"), cookie_secret=config["default"]["COOKIE_SECRET"], - debug=config['default'].getboolean('DEBUG'), - **kwargs + debug=config["default"].getboolean("DEBUG"), + **kwargs, ) app.config = config return app @@ -80,23 +81,30 @@ def make_app(config, deps, **kwargs): def make_deps(config): # we do not want to do SSL verify services in test and development - validate_cert = ENV == 'production' + validate_cert = ENV == "production" return { - 'authz_client': ApiClient(config["default"]["AUTHZ_BASE_URL"], api_version='v1', validate_cert=validate_cert), - 'authnid_client': ApiClient(config["default"]["AUTHNID_BASE_URL"], api_version='v1', validate_cert=validate_cert), - 'requests_client': ApiClient(config["default"]["REQUESTS_QUEUE_BASE_URL"], api_version='v1', validate_cert=validate_cert) + "authz_client": ApiClient( + config["default"]["AUTHZ_BASE_URL"], + api_version="v1", + validate_cert=validate_cert, + ), + "authnid_client": ApiClient( + config["default"]["AUTHNID_BASE_URL"], + api_version="v1", + validate_cert=validate_cert, + ), + "requests_client": ApiClient( + config["default"]["REQUESTS_QUEUE_BASE_URL"], + api_version="v1", + validate_cert=validate_cert, + ), } def make_config(): - BASE_CONFIG_FILENAME = os.path.join( - os.path.dirname(__file__), - "../config/base.ini" - ) + BASE_CONFIG_FILENAME = os.path.join(os.path.dirname(__file__), "../config/base.ini") ENV_CONFIG_FILENAME = os.path.join( - os.path.dirname(__file__), - "../config/", - "{}.ini".format(ENV.lower()) + os.path.dirname(__file__), "../config/", "{}.ini".format(ENV.lower()) ) config = ConfigParser() diff --git a/atst/forms/date.py b/atst/forms/date.py index 8a270cef..01d599f9 100644 --- a/atst/forms/date.py +++ b/atst/forms/date.py @@ -2,7 +2,8 @@ from wtforms.fields.html5 import IntegerField from wtforms.validators import Required, ValidationError from wtforms_tornado import Form + class DateForm(Form): - month = IntegerField('Month', validators=[Required()]) - day = IntegerField('Day', validators=[Required()]) - year = IntegerField('Year', validators=[Required()]) + month = IntegerField("Month", validators=[Required()]) + day = IntegerField("Day", validators=[Required()]) + year = IntegerField("Year", validators=[Required()]) diff --git a/atst/forms/funding.py b/atst/forms/funding.py index fe2194cf..104ff7cf 100644 --- a/atst/forms/funding.py +++ b/atst/forms/funding.py @@ -1,4 +1,5 @@ from wtforms_tornado import Form + class FundingForm(Form): pass diff --git a/atst/forms/organization_info.py b/atst/forms/organization_info.py index 4d478634..37e9ac99 100644 --- a/atst/forms/organization_info.py +++ b/atst/forms/organization_info.py @@ -1,4 +1,5 @@ from wtforms_tornado import Form + class OrganizationInfoForm(Form): pass diff --git a/atst/forms/readiness.py b/atst/forms/readiness.py index 8417bfef..e12a61be 100644 --- a/atst/forms/readiness.py +++ b/atst/forms/readiness.py @@ -1,4 +1,5 @@ from wtforms_tornado import Form + class ReadinessForm(Form): pass diff --git a/atst/forms/request.py b/atst/forms/request.py index eae0e0a9..d50b40ba 100644 --- a/atst/forms/request.py +++ b/atst/forms/request.py @@ -1,44 +1,73 @@ from wtforms.fields.html5 import IntegerField -from wtforms.fields import RadioField, StringField, SelectField, TextAreaField, FormField +from wtforms.fields import ( + RadioField, + StringField, + SelectField, + TextAreaField, + FormField, +) from wtforms.validators import Required, ValidationError from wtforms_tornado import Form from .date import DateForm + class RequestForm(Form): - application_name = StringField('Application name', validators=[Required()]) - application_description = TextAreaField('Application description', validators=[Required()]) - dollar_value = IntegerField('Estimated dollar value of use', validators=[Required()]) - input_estimate = SelectField('How did you arrive at this estimate?', validators=[Required()], - choices=[('','- Select -'), - ('calculator','CSP usage calculator'), - ('B','Option B'), - ('C','Option C') ]) + application_name = StringField("Application name", validators=[Required()]) + application_description = TextAreaField( + "Application description", validators=[Required()] + ) + dollar_value = IntegerField( + "Estimated dollar value of use", validators=[Required()] + ) + input_estimate = SelectField( + "How did you arrive at this estimate?", + validators=[Required()], + choices=[ + ("", "- Select -"), + ("calculator", "CSP usage calculator"), + ("B", "Option B"), + ("C", "Option C"), + ], + ) # no way to apply a label to a whole nested form like this date_start = FormField(DateForm) - period_of_performance = SelectField('Desired period of performance', validators=[Required()], - choices=[('','- Select -'), - ('value1','30 days'), - ('value2','60 days'), - ('value3','90 days') ]) - classification_level = RadioField('Classification level', validators=[Required()], - choices=[('unclassified', 'Unclassified'), - ('secret', 'Secret'), - ('top-secret', 'Top Secret') ]) - primary_service_branch = StringField('Primary service branch usage', validators=[Required()]) - cloud_model = RadioField('Cloud model service', validators=[Required()], - choices=[('iaas', 'IaaS'), - ('paas', 'PaaS'), - ('both', 'Both') ]) - number_of_cores = IntegerField('Number of cores', validators=[Required()]) - total_ram = IntegerField('Total RAM', validators=[Required()]) - object_storage = IntegerField('Total object storage', validators=[Required()]) - server_storage = IntegerField('Total server storage', validators=[Required()]) - total_active_users = IntegerField('Total active users', validators=[Required()]) - total_peak_users = IntegerField('Total peak users', validators=[Required()]) - total_requests = IntegerField('Total requests', validators=[Required()]) - total_environments = IntegerField('Total environments', validators=[Required()]) + period_of_performance = SelectField( + "Desired period of performance", + validators=[Required()], + choices=[ + ("", "- Select -"), + ("value1", "30 days"), + ("value2", "60 days"), + ("value3", "90 days"), + ], + ) + classification_level = RadioField( + "Classification level", + validators=[Required()], + choices=[ + ("unclassified", "Unclassified"), + ("secret", "Secret"), + ("top-secret", "Top Secret"), + ], + ) + primary_service_branch = StringField( + "Primary service branch usage", validators=[Required()] + ) + cloud_model = RadioField( + "Cloud model service", + validators=[Required()], + choices=[("iaas", "IaaS"), ("paas", "PaaS"), ("both", "Both")], + ) + number_of_cores = IntegerField("Number of cores", validators=[Required()]) + total_ram = IntegerField("Total RAM", validators=[Required()]) + object_storage = IntegerField("Total object storage", validators=[Required()]) + server_storage = IntegerField("Total server storage", validators=[Required()]) + total_active_users = IntegerField("Total active users", validators=[Required()]) + total_peak_users = IntegerField("Total peak users", validators=[Required()]) + total_requests = IntegerField("Total requests", validators=[Required()]) + total_environments = IntegerField("Total environments", validators=[Required()]) # this is just an example validation; obviously this is wrong. - def validate_total_ram(self,field): + def validate_total_ram(self, field): if (field.data % 2) != 0: raise ValidationError("RAM must be in increments of 2.") diff --git a/atst/forms/review.py b/atst/forms/review.py index 3dfe5ab8..6b183dac 100644 --- a/atst/forms/review.py +++ b/atst/forms/review.py @@ -1,4 +1,5 @@ from wtforms_tornado import Form + class ReviewForm(Form): pass diff --git a/atst/handler.py b/atst/handler.py index 011ae3e6..2f96d8ad 100644 --- a/atst/handler.py +++ b/atst/handler.py @@ -2,34 +2,31 @@ from webassets import Environment, Bundle import tornado.web from atst.home import home -assets = Environment( - directory = home.child('scss'), - url = '/static') -css = Bundle( - 'atat.scss', - filters = 'scss', - output = '../static/assets/out.css', - depends = ('**/*.scss')) +assets = Environment(directory=home.child("scss"), url="/static") +css = Bundle( + "atat.scss", + filters="scss", + output="../static/assets/out.css", + depends=("**/*.scss"), +) -assets.register( 'css', css ) -helpers = { - 'assets': assets, -} +assets.register("css", css) +helpers = {"assets": assets} class BaseHandler(tornado.web.RequestHandler): def get_template_namespace(self): ns = super(BaseHandler, self).get_template_namespace() - helpers['config'] = self.application.config + helpers["config"] = self.application.config ns.update(helpers) return ns def get_current_user(self): - if self.get_secure_cookie('atst'): - return '9cb348f0-8102-4962-88c4-dac8180c904c' + if self.get_secure_cookie("atst"): + return "9cb348f0-8102-4962-88c4-dac8180c904c" else: return False # this is a temporary implementation until we have real sessions def _start_session(self): - self.set_secure_cookie('atst', 'valid-user-session') + self.set_secure_cookie("atst", "valid-user-session") diff --git a/atst/handlers/dev.py b/atst/handlers/dev.py index a22fd456..3dbd7653 100644 --- a/atst/handlers/dev.py +++ b/atst/handlers/dev.py @@ -1,11 +1,12 @@ from atst.handler import BaseHandler + class Dev(BaseHandler): def initialize(self, action): self.action = action def get(self): - if self.action == 'login': + if self.action == "login": self._login() def _login(self): diff --git a/atst/handlers/home.py b/atst/handlers/home.py index 4ab45889..483bd161 100644 --- a/atst/handlers/home.py +++ b/atst/handlers/home.py @@ -1,9 +1,9 @@ from atst.handler import BaseHandler -class Home(BaseHandler): +class Home(BaseHandler): def initialize(self, page): self.page = page def get(self): - self.render( '%s.html.to' % self.page, page = self.page ) + self.render("%s.html.to" % self.page, page=self.page) diff --git a/atst/handlers/login.py b/atst/handlers/login.py index 51f4fec5..271a806d 100644 --- a/atst/handlers/login.py +++ b/atst/handlers/login.py @@ -3,7 +3,6 @@ from atst.handler import BaseHandler class Login(BaseHandler): - def initialize(self, authnid_client): self.authnid_client = authnid_client diff --git a/atst/handlers/main.py b/atst/handlers/main.py index 98cf405d..025c3c53 100644 --- a/atst/handlers/main.py +++ b/atst/handlers/main.py @@ -1,11 +1,11 @@ import tornado from atst.handler import BaseHandler -class MainHandler(BaseHandler): +class MainHandler(BaseHandler): def initialize(self, page): self.page = page @tornado.web.authenticated def get(self): - self.render( '%s.html.to' % self.page, page = self.page ) + self.render("%s.html.to" % self.page, page=self.page) diff --git a/atst/handlers/request.py b/atst/handlers/request.py index 3636ae64..40997e06 100644 --- a/atst/handlers/request.py +++ b/atst/handlers/request.py @@ -2,43 +2,45 @@ import tornado from atst.handler import BaseHandler mock_requests = [ - { - 'order_id' : 36552612, - 'date' : '5/17/2018', - 'is_new' : True, - 'full_name' : 'Friedrich Straat', - 'app_count' : 2, - 'status' : 'Pending' - }, - { - 'order_id' : 87362910, - 'date' : '10/2/2017', - 'is_new' : False, - 'full_name' : 'Pietro Quirinis', - 'app_count' : 1, - 'status' : 'Complete' - }, - { - 'order_id' : 29938172, - 'date' : '1/7/2017', - 'is_new' : False, - 'full_name' : 'Marina Borsetti', - 'app_count' : 1, - 'status' : 'Denied' - }, - ] + { + "order_id": 36552612, + "date": "5/17/2018", + "is_new": True, + "full_name": "Friedrich Straat", + "app_count": 2, + "status": "Pending", + }, + { + "order_id": 87362910, + "date": "10/2/2017", + "is_new": False, + "full_name": "Pietro Quirinis", + "app_count": 1, + "status": "Complete", + }, + { + "order_id": 29938172, + "date": "1/7/2017", + "is_new": False, + "full_name": "Marina Borsetti", + "app_count": 1, + "status": "Denied", + }, +] + def map_request(request): return { - 'order_id': request['id'], - 'is_new': False, - 'status': 'Pending', - 'app_count': 1, - 'is_new': False, - 'date': '', - 'full_name': 'Richard Howard' + "order_id": request["id"], + "is_new": False, + "status": "Pending", + "app_count": 1, + "is_new": False, + "date": "", + "full_name": "Richard Howard", } + class Request(BaseHandler): def initialize(self, page, requests_client): self.page = page @@ -48,7 +50,8 @@ class Request(BaseHandler): @tornado.gen.coroutine def get(self): response = yield self.requests_client.get( - '/users/{}/requests'.format(self.get_current_user())) - requests = response.json['requests'] + "/users/{}/requests".format(self.get_current_user()) + ) + requests = response.json["requests"] mapped_requests = [map_request(request) for request in requests] - self.render('requests.html.to', page=self.page, requests=mapped_requests) + self.render("requests.html.to", page=self.page, requests=mapped_requests) diff --git a/atst/handlers/request_new.py b/atst/handlers/request_new.py index 93ee57c8..595c4dd2 100644 --- a/atst/handlers/request_new.py +++ b/atst/handlers/request_new.py @@ -11,35 +11,21 @@ from tornado.httpclient import HTTPError class RequestNew(BaseHandler): screens = [ - { 'title' : 'Details of Use', - 'form' : RequestForm, - 'subitems' : [ - {'title' : 'Application Details', - 'id' : 'application-details'}, - {'title' : 'Computation', - 'id' : 'computation' }, - {'title' : 'Storage', - 'id' : 'storage' }, - {'title' : 'Usage', - 'id' : 'usage' }, - ]}, - { - 'title' : 'Organizational Info', - 'form' : OrganizationInfoForm, - }, - { - 'title' : 'Funding/Contracting', - 'form' : FundingForm, - }, - { - 'title' : 'Readiness Survey', - 'form' : ReadinessForm, - }, - { - 'title' : 'Review & Submit', - 'form' : ReviewForm, - } - ] + { + "title": "Details of Use", + "form": RequestForm, + "subitems": [ + {"title": "Application Details", "id": "application-details"}, + {"title": "Computation", "id": "computation"}, + {"title": "Storage", "id": "storage"}, + {"title": "Usage", "id": "usage"}, + ], + }, + {"title": "Organizational Info", "form": OrganizationInfoForm}, + {"title": "Funding/Contracting", "form": FundingForm}, + {"title": "Readiness Survey", "form": ReadinessForm}, + {"title": "Review & Submit", "form": ReviewForm}, + ] def initialize(self, page, requests_client): self.page = page @@ -50,12 +36,15 @@ class RequestNew(BaseHandler): def post(self, screen=1, request_id=None): self.check_xsrf_cookie() screen = int(screen) - form = self.screens[ screen - 1 ]['form'](self.request.arguments) + form = self.screens[screen - 1]["form"](self.request.arguments) if form.validate(): response = yield self.create_or_update_request(form.data, request_id) if response.ok: where = self.application.default_router.reverse_url( - 'request_form_update', str(screen + 1), request_id or response.json['id']) + "request_form_update", + str(screen + 1), + request_id or response.json["id"], + ) self.redirect(where) else: self.set_status(response.code) @@ -69,39 +58,39 @@ class RequestNew(BaseHandler): if request_id: request = yield self.get_request(request_id) if request.ok: - form_data = request.json['body'] if request else {} - form = self.screens[ int(screen) - 1 ]['form'](data=form_data) + form_data = request.json["body"] if request else {} + form = self.screens[int(screen) - 1]["form"](data=form_data) self.show_form(screen=screen, form=form, request_id=request_id) def show_form(self, screen=1, form=None, request_id=None): if not form: - form = self.screens[ int(screen) - 1 ]['form'](self.request.arguments) - self.render('requests/screen-%d.html.to' % int(screen), - f=form, - page=self.page, - screens=self.screens, - current=int(screen), - next_screen=int(screen) + 1, - request_id=request_id) + form = self.screens[int(screen) - 1]["form"](self.request.arguments) + self.render( + "requests/screen-%d.html.to" % int(screen), + f=form, + page=self.page, + screens=self.screens, + current=int(screen), + next_screen=int(screen) + 1, + request_id=request_id, + ) @tornado.gen.coroutine def get_request(self, request_id): request = yield self.requests_client.get( - '/users/{}/requests/{}'.format(self.get_current_user(), request_id), - raise_error=False) + "/users/{}/requests/{}".format(self.get_current_user(), request_id), + raise_error=False, + ) return request @tornado.gen.coroutine def create_or_update_request(self, form_data, request_id=None): - request_data = { - 'creator_id': self.get_current_user(), - 'request': form_data - } + request_data = {"creator_id": self.get_current_user(), "request": form_data} if request_id: response = yield self.requests_client.patch( - '/requests/{}'.format(request_id), json=request_data) + "/requests/{}".format(request_id), json=request_data + ) else: - response = yield self.requests_client.post( - '/requests', json=request_data) + response = yield self.requests_client.post("/requests", json=request_data) return response diff --git a/atst/handlers/workspace.py b/atst/handlers/workspace.py index 7c6ecd64..d6672843 100644 --- a/atst/handlers/workspace.py +++ b/atst/handlers/workspace.py @@ -3,17 +3,15 @@ import tornado mock_workspaces = [ { - 'name' : 'Unclassified IaaS and PaaS for Defense Digital Service (DDS)', - 'id': '5966187a-eff9-44c3-aa15-4de7a65ac7ff', - 'task_order' : { - 'number' : 123456, - }, - 'user_count' : 23, + "name": "Unclassified IaaS and PaaS for Defense Digital Service (DDS)", + "id": "5966187a-eff9-44c3-aa15-4de7a65ac7ff", + "task_order": {"number": 123456}, + "user_count": 23, } ] -class Workspace(BaseHandler): +class Workspace(BaseHandler): def initialize(self, page, authz_client): self.page = page self.authz_client = authz_client @@ -21,4 +19,4 @@ class Workspace(BaseHandler): @tornado.gen.coroutine @tornado.web.authenticated def get(self): - self.render( 'workspaces.html.to', page = self.page, workspaces = mock_workspaces ) + self.render("workspaces.html.to", page=self.page, workspaces=mock_workspaces) diff --git a/atst/home.py b/atst/home.py index 8d72d7c0..883ec8dd 100644 --- a/atst/home.py +++ b/atst/home.py @@ -1,3 +1,3 @@ from unipath import Path -home = Path( __file__ ).parent.parent +home = Path(__file__).parent.parent diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..efdb8ddd --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[tool.black] +line-length = 88 +py36 = true +include = '\.pyi?$' +exclude = ''' +/( + \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + | node_modules +)/ +''' diff --git a/tests/conftest.py b/tests/conftest.py index 5ad43b74..ad83d6e2 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,9 +7,9 @@ from tests.mocks import MockApiClient, MockRequestsClient @pytest.fixture def app(): TEST_DEPS = { - 'authz_client': MockApiClient('authz'), - 'requests_client': MockRequestsClient('requests'), - 'authnid_client': MockApiClient('authnid'), + "authz_client": MockApiClient("authz"), + "requests_client": MockRequestsClient("requests"), + "authnid_client": MockApiClient("authnid"), } config = make_config() diff --git a/tests/forms/test_request.py b/tests/forms/test_request.py index 34cbbebc..381dd810 100644 --- a/tests/forms/test_request.py +++ b/tests/forms/test_request.py @@ -4,9 +4,11 @@ from atst.forms.request import RequestForm form = RequestForm() + def test_form_has_expected_fields(): label = form.application_name.label - assert label.text == 'Application name' + assert label.text == "Application name" + def test_form_can_validate_total_ram(): form.application_name.data = 5 diff --git a/tests/handlers/test_request_new.py b/tests/handlers/test_request_new.py index 175206df..93660bf3 100644 --- a/tests/handlers/test_request_new.py +++ b/tests/handlers/test_request_new.py @@ -1,13 +1,17 @@ import re import pytest -ERROR_CLASS = 'usa-input-error-message' +ERROR_CLASS = "usa-input-error-message" @pytest.mark.gen_test def test_submit_invalid_request_form(monkeypatch, http_client, base_url): - monkeypatch.setattr('atst.handlers.request_new.RequestNew.get_current_user', lambda s: True) - monkeypatch.setattr('atst.handlers.request_new.RequestNew.check_xsrf_cookie', lambda s: True) + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.get_current_user", lambda s: True + ) + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True + ) # this just needs to send a known invalid form value response = yield http_client.fetch( base_url + "/requests/new", @@ -15,15 +19,19 @@ def test_submit_invalid_request_form(monkeypatch, http_client, base_url): headers={"Content-Type": "application/x-www-form-urlencoded"}, body="total_ram=5", ) - assert response.effective_url == base_url + '/requests/new' + assert response.effective_url == base_url + "/requests/new" assert re.search(ERROR_CLASS, response.body.decode()) @pytest.mark.gen_test def test_submit_valid_request_form(monkeypatch, http_client, base_url): - monkeypatch.setattr('atst.handlers.request_new.RequestNew.get_current_user', lambda s: True) - monkeypatch.setattr('atst.handlers.request_new.RequestNew.check_xsrf_cookie', lambda s: True) - monkeypatch.setattr('atst.forms.request.RequestForm.validate', lambda s: True) + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.get_current_user", lambda s: True + ) + monkeypatch.setattr( + "atst.handlers.request_new.RequestNew.check_xsrf_cookie", lambda s: True + ) + monkeypatch.setattr("atst.forms.request.RequestForm.validate", lambda s: True) # this just needs to send a known invalid form value response = yield http_client.fetch( @@ -32,4 +40,4 @@ def test_submit_valid_request_form(monkeypatch, http_client, base_url): headers={"Content-Type": "application/x-www-form-urlencoded"}, body="meaning=42", ) - assert '/requests/new/2' in response.effective_url + assert "/requests/new/2" in response.effective_url diff --git a/tests/mocks.py b/tests/mocks.py index e378a7ed..be8805c3 100644 --- a/tests/mocks.py +++ b/tests/mocks.py @@ -10,33 +10,34 @@ class MockApiClient(ApiClient): @tornado.gen.coroutine def get(self, path, **kwargs): - return self._get_response('GET', path) + return self._get_response("GET", path) @tornado.gen.coroutine def put(self, path, **kwargs): - return self._get_response('PUT', path) + return self._get_response("PUT", path) @tornado.gen.coroutine def patch(self, path, **kwargs): - return self._get_response('PATCH', path) + return self._get_response("PATCH", path) @tornado.gen.coroutine def post(self, path, **kwargs): - return self._get_response('POST', path) + return self._get_response("POST", path) @tornado.gen.coroutine def delete(self, path, **kwargs): - return self._get_response('DELETE', path) + return self._get_response("DELETE", path) def _get_response(self, verb, path, code=200, json=None): response = HTTPResponse( request=HTTPRequest(path, verb), code=code, - headers={'Content-Type': 'application/json'}) + headers={"Content-Type": "application/json"}, + ) - setattr(response, 'ok', 200 <= code < 300) + setattr(response, "ok", 200 <= code < 300) if json: - setattr(response, 'json', json) + setattr(response, "json", json) return response @@ -45,18 +46,17 @@ class MockRequestsClient(MockApiClient): @tornado.gen.coroutine def get(self, path, **kwargs): json = { - 'id': '66b8ef71-86d3-48ef-abc2-51bfa1732b6b', - 'creator': '49903ae7-da4a-49bf-a6dc-9dff5d004238', - 'body': {} + "id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b", + "creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238", + "body": {}, } - return self._get_response('GET', path, 200, json=json) + return self._get_response("GET", path, 200, json=json) @tornado.gen.coroutine def post(self, path, **kwargs): json = { - 'id': '66b8ef71-86d3-48ef-abc2-51bfa1732b6b', - 'creator': '49903ae7-da4a-49bf-a6dc-9dff5d004238', - 'body': {} + "id": "66b8ef71-86d3-48ef-abc2-51bfa1732b6b", + "creator": "49903ae7-da4a-49bf-a6dc-9dff5d004238", + "body": {}, } - return self._get_response('POST', path, 202, json=json) - + return self._get_response("POST", path, 202, json=json) diff --git a/tests/test_api_client.py b/tests/test_api_client.py index 9e18fad6..5b1880cb 100644 --- a/tests/test_api_client.py +++ b/tests/test_api_client.py @@ -6,5 +6,5 @@ from atst.api_client import ApiClient @pytest.mark.gen_test def test_api_client(http_client, base_url): client = ApiClient(base_url) - response = yield client.get('') + response = yield client.get("") assert response.code == 200 diff --git a/tests/test_auth.py b/tests/test_auth.py index 242083af..e6a49d47 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -9,10 +9,10 @@ def test_redirects_when_not_logged_in(http_client, base_url): response = yield http_client.fetch( base_url + "/home", raise_error=False, follow_redirects=False ) - location = response.headers['Location'] + location = response.headers["Location"] assert response.code == 302 assert response.error - assert re.match('/\??', location) + assert re.match("/\??", location) @pytest.mark.gen_test @@ -22,16 +22,15 @@ def test_login_with_valid_bearer_token(app, monkeypatch, http_client, base_url): return True monkeypatch.setattr( - "atst.handlers.login.Login._validate_login_token", - _validate_login_token + "atst.handlers.login.Login._validate_login_token", _validate_login_token ) response = yield http_client.fetch( base_url + "/login?bearer-token=abc-123", follow_redirects=False, - raise_error=False + raise_error=False, ) assert response.headers["Set-Cookie"].startswith("atst") - assert response.headers['Location'] == '/home' + assert response.headers["Location"] == "/home" assert response.code == 302 diff --git a/tests/test_routes.py b/tests/test_routes.py index 61f5d7cf..e6a9122c 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -4,15 +4,15 @@ import pytest @pytest.mark.gen_test def test_routes(http_client, base_url): for path in ( - '/', - '/home', - '/workspaces', - '/requests', - '/requests/new', - '/requests/new/1', - '/users', - '/reports', - '/calculator' - ): + "/", + "/home", + "/workspaces", + "/requests", + "/requests/new", + "/requests/new/1", + "/users", + "/reports", + "/calculator", + ): response = yield http_client.fetch(base_url + path) assert response.code == 200