diff --git a/.travis.yml b/.travis.yml index db2448cdb..a0cb85179 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ env: matrix: - TOXENV=lint - TOXENV=bandit + - TOXENV=black matrix: include: - python: 3.6 diff --git a/anitya/__init__.py b/anitya/__init__.py index df41d7b13..8edee3881 100644 --- a/anitya/__init__.py +++ b/anitya/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -__api_version__ = '1.0' -__version__ = '0.14.1' +__api_version__ = "1.0" +__version__ = "0.14.1" diff --git a/anitya/admin.py b/anitya/admin.py index 191252fc0..aafd9c66a 100644 --- a/anitya/admin.py +++ b/anitya/admin.py @@ -18,15 +18,15 @@ def is_admin(user=None): - ''' Check if the provided user, or the user logged in are recognized + """ Check if the provided user, or the user logged in are recognized as being admins. - ''' + """ user = user or flask.g.user if user.is_authenticated: return user.is_admin -@ui_blueprint.route('/distro//edit', methods=['GET', 'POST']) +@ui_blueprint.route("/distro//edit", methods=["GET", "POST"]) @login_required def edit_distro(distro_name): @@ -46,33 +46,28 @@ def edit_distro(distro_name): utilities.log( Session, distro=distro.__json__(), - topic='distro.edit', - message=dict( - agent=flask.g.user.username, - old=distro.name, - new=name, - ) + topic="distro.edit", + message=dict(agent=flask.g.user.username, old=distro.name, new=name), ) distro.name = name Session.add(distro) Session.commit() - message = 'Distribution edited' + message = "Distribution edited" flask.flash(message) - return flask.redirect( - flask.url_for('anitya_ui.distros') - ) + return flask.redirect(flask.url_for("anitya_ui.distros")) return flask.render_template( - 'distro_add_edit.html', - context='Edit', - current='distros', + "distro_add_edit.html", + context="Edit", + current="distros", distro=distro, - form=form) + form=form, + ) -@ui_blueprint.route('/distro//delete', methods=['GET', 'POST']) +@ui_blueprint.route("/distro//delete", methods=["GET", "POST"]) @login_required def delete_distro(distro_name): """ Delete a distro """ @@ -90,26 +85,21 @@ def delete_distro(distro_name): utilities.log( Session, distro=distro.__json__(), - topic='distro.remove', - message=dict( - agent=flask.g.user.username, - distro=distro.name, - ) + topic="distro.remove", + message=dict(agent=flask.g.user.username, distro=distro.name), ) Session.delete(distro) Session.commit() - flask.flash('Distro %s has been removed' % distro_name) - return flask.redirect(flask.url_for('anitya_ui.distros')) + flask.flash("Distro %s has been removed" % distro_name) + return flask.redirect(flask.url_for("anitya_ui.distros")) return flask.render_template( - 'distro_delete.html', - current='distros', - distro=distro, - form=form) + "distro_delete.html", current="distros", distro=distro, form=form + ) -@ui_blueprint.route('/project//delete', methods=['GET', 'POST']) +@ui_blueprint.route("/project//delete", methods=["GET", "POST"]) @login_required def delete_project(project_id): @@ -123,18 +113,15 @@ def delete_project(project_id): project_name = project.name form = anitya.forms.ConfirmationForm() - confirm = flask.request.form.get('confirm', False) + confirm = flask.request.form.get("confirm", False) if form.validate_on_submit(): if confirm: utilities.log( Session, project=project.__json__(), - topic='project.remove', - message=dict( - agent=flask.g.user.username, - project=project.name, - ) + topic="project.remove", + message=dict(agent=flask.g.user.username, project=project.name), ) for version in project.versions_obj: @@ -142,22 +129,21 @@ def delete_project(project_id): Session.delete(project) Session.commit() - flask.flash('Project %s has been removed' % project_name) - return flask.redirect(flask.url_for('anitya_ui.projects')) + flask.flash("Project %s has been removed" % project_name) + return flask.redirect(flask.url_for("anitya_ui.projects")) else: return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id)) + flask.url_for("anitya_ui.project", project_id=project.id) + ) return flask.render_template( - 'project_delete.html', - current='projects', - project=project, - form=form) + "project_delete.html", current="projects", project=project, form=form + ) @ui_blueprint.route( - '/project//delete//', - methods=['GET', 'POST']) + "/project//delete//", methods=["GET", "POST"] +) @login_required def delete_project_mapping(project_id, distro_name, pkg_name): @@ -169,8 +155,7 @@ def delete_project_mapping(project_id, distro_name, pkg_name): if not distro: flask.abort(404) - package = models.Packages.get( - Session, project.id, distro.name, pkg_name) + package = models.Packages.get(Session, project.id, distro.name, pkg_name) if not package: flask.abort(404) @@ -178,38 +163,37 @@ def delete_project_mapping(project_id, distro_name, pkg_name): flask.abort(401) form = anitya.forms.ConfirmationForm() - confirm = flask.request.form.get('confirm', False) + confirm = flask.request.form.get("confirm", False) if form.validate_on_submit(): if confirm: utilities.log( Session, project=project.__json__(), - topic='project.map.remove', + topic="project.map.remove", message=dict( agent=flask.g.user.username, project=project.name, distro=distro.name, - ) + ), ) Session.delete(package) Session.commit() - flask.flash('Mapping for %s has been removed' % project.name) - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id)) + flask.flash("Mapping for %s has been removed" % project.name) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id)) return flask.render_template( - 'regex_delete.html', - current='projects', + "regex_delete.html", + current="projects", project=project, package=package, - form=form) + form=form, + ) -@ui_blueprint.route( - '/project//delete/', methods=['GET', 'POST']) +@ui_blueprint.route("/project//delete/", methods=["GET", "POST"]) @login_required def delete_project_version(project_id, version): @@ -225,27 +209,24 @@ def delete_project_version(project_id, version): if version_obj is None: flask.abort( - 404, - 'Version %s not found for project %s' % (version, project.name) + 404, "Version %s not found for project %s" % (version, project.name) ) if not is_admin(): flask.abort(401) form = anitya.forms.ConfirmationForm() - confirm = flask.request.form.get('confirm', False) + confirm = flask.request.form.get("confirm", False) if form.validate_on_submit(): if confirm: utilities.log( Session, project=project.__json__(), - topic='project.version.remove', + topic="project.version.remove", message=dict( - agent=flask.g.user.username, - project=project.name, - version=version, - ) + agent=flask.g.user.username, project=project.name, version=version + ), ) # Delete the record of the version for this project @@ -256,32 +237,32 @@ def delete_project_version(project_id, version): Session.add(project) Session.commit() - flask.flash('Version for %s has been removed' % version) - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id)) + flask.flash("Version for %s has been removed" % version) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id)) return flask.render_template( - 'version_delete.html', - current='projects', + "version_delete.html", + current="projects", project=project, version=version, - form=form) + form=form, + ) -@ui_blueprint.route('/flags') +@ui_blueprint.route("/flags") @login_required def browse_flags(): if not is_admin(): flask.abort(401) - from_date = flask.request.args.get('from_date', None) - state = flask.request.args.get('state', 'open') - project = flask.request.args.get('project', None) - flags_for_user = flask.request.args.get('user', None) - refresh = flask.request.args.get('refresh', False) - limit = flask.request.args.get('limit', 50) - page = flask.request.args.get('page', 1) + from_date = flask.request.args.get("from_date", None) + state = flask.request.args.get("state", "open") + project = flask.request.args.get("project", None) + flags_for_user = flask.request.args.get("user", None) + refresh = flask.request.args.get("refresh", False) + limit = flask.request.args.get("limit", 50) + page = flask.request.args.get("page", 1) try: page = int(page) @@ -292,14 +273,13 @@ def browse_flags(): int(limit) except ValueError: limit = 50 - flask.flash('Incorrect limit provided, using default', 'errors') + flask.flash("Incorrect limit provided, using default", "errors") if from_date: try: from_date = parser.parse(from_date) except (ValueError, TypeError): - flask.flash( - 'Incorrect from_date provided, using default', 'errors') + flask.flash("Incorrect from_date provided, using default", "errors") from_date = None if from_date: @@ -328,40 +308,40 @@ def browse_flags(): state=state or None, from_date=from_date, user=flags_for_user or None, - count=True + count=True, ) except Exception as err: _log.exception(err) - flask.flash(err, 'errors') + flask.flash(err, "errors") total_page = int(ceil(cnt_flags / float(limit))) form = anitya.forms.ConfirmationForm() return flask.render_template( - 'flags.html', - current='flags', + "flags.html", + current="flags", refresh=refresh, flags=flags, cnt_flags=cnt_flags, total_page=total_page, form=form, page=page, - project=project or '', - from_date=from_date or '', - flags_for_user=flags_for_user or '', - state=state or '' + project=project or "", + from_date=from_date or "", + flags_for_user=flags_for_user or "", + state=state or "", ) -@ui_blueprint.route('/flags//set/', methods=['POST']) +@ui_blueprint.route("/flags//set/", methods=["POST"]) @login_required def set_flag_state(flag_id, state): if not is_admin(): flask.abort(401) - if state not in ('open', 'closed'): + if state not in ("open", "closed"): flask.abort(422) flag = models.ProjectFlag.get(Session, flag_id) @@ -374,34 +354,29 @@ def set_flag_state(flag_id, state): if form.validate_on_submit(): try: utilities.set_flag_state( - Session, - flag=flag, - state=state, - user_id=flask.g.user.username, + Session, flag=flag, state=state, user_id=flask.g.user.username ) - flask.flash('Flag {0} set to {1}'.format(flag.id, state)) + flask.flash("Flag {0} set to {1}".format(flag.id, state)) except anitya.lib.exceptions.AnityaException as err: - flask.flash(str(err), 'errors') + flask.flash(str(err), "errors") - return flask.redirect( - flask.url_for('anitya_ui.browse_flags') - ) + return flask.redirect(flask.url_for("anitya_ui.browse_flags")) -@ui_blueprint.route('/users', methods=['GET']) +@ui_blueprint.route("/users", methods=["GET"]) @login_required def browse_users(): if not is_admin(): flask.abort(401) - user_id = flask.request.args.get('user_id', None) - username = flask.request.args.get('username', None) - email = flask.request.args.get('email', None) - admin = flask.request.args.get('admin', None) - active = flask.request.args.get('active', None) - limit = flask.request.args.get('limit', 50) - page = flask.request.args.get('page', 1) + user_id = flask.request.args.get("user_id", None) + username = flask.request.args.get("username", None) + email = flask.request.args.get("email", None) + admin = flask.request.args.get("admin", None) + active = flask.request.args.get("active", None) + limit = flask.request.args.get("limit", 50) + page = flask.request.args.get("page", 1) try: page = int(page) @@ -428,7 +403,7 @@ def browse_users(): limit = int(limit) except ValueError: limit = 50 - flask.flash('Incorrect limit provided, using default', 'errors') + flask.flash("Incorrect limit provided, using default", "errors") offset = 0 if page is not None and limit is not None and limit > 0: @@ -437,8 +412,7 @@ def browse_users(): users = [] cnt_users = 0 try: - users_query = Session.query( - models.User) + users_query = Session.query(models.User) if user_id: users_query = users_query.filter_by(id=user_id) @@ -464,7 +438,7 @@ def browse_users(): cnt_users = users_query.count() except Exception as err: _log.exception(err) - flask.flash(err, 'errors') + flask.flash(err, "errors") try: total_page = int(ceil(cnt_users / float(limit))) @@ -474,22 +448,22 @@ def browse_users(): form = anitya.forms.ConfirmationForm() return flask.render_template( - 'users.html', - current='users', + "users.html", + current="users", users=users, cnt_users=cnt_users, total_page=total_page, form=form, page=page, - username=username or '', - email=email or '', - user_id=user_id or '', + username=username or "", + email=email or "", + user_id=user_id or "", admin=admin, - active=active + active=active, ) -@ui_blueprint.route('/users//admin/', methods=['POST']) +@ui_blueprint.route("/users//admin/", methods=["POST"]) @login_required def set_user_admin_state(user_id, state): @@ -504,8 +478,7 @@ def set_user_admin_state(user_id, state): flask.abort(422) try: - user = Session.query(models.User).filter( - models.User.id == user_id).one() + user = Session.query(models.User).filter(models.User.id == user_id).one() except Exception as err: _log.exception(err) user = None @@ -521,20 +494,18 @@ def set_user_admin_state(user_id, state): Session.add(user) Session.commit() if state: - flask.flash('User {0} is now admin'.format(user.username)) + flask.flash("User {0} is now admin".format(user.username)) else: - flask.flash('User {0} is not admin anymore'.format(user.username)) + flask.flash("User {0} is not admin anymore".format(user.username)) except Exception as err: _log.exception(err) - flask.flash(str(err), 'errors') + flask.flash(str(err), "errors") Session.rollback() - return flask.redirect( - flask.url_for('anitya_ui.browse_users') - ) + return flask.redirect(flask.url_for("anitya_ui.browse_users")) -@ui_blueprint.route('/users//active/', methods=['POST']) +@ui_blueprint.route("/users//active/", methods=["POST"]) @login_required def set_user_active_state(user_id, state): @@ -549,8 +520,7 @@ def set_user_active_state(user_id, state): flask.abort(422) try: - user = Session.query(models.User).filter( - models.User.id == user_id).one() + user = Session.query(models.User).filter(models.User.id == user_id).one() except Exception as err: _log.exception(err) user = None @@ -566,14 +536,12 @@ def set_user_active_state(user_id, state): Session.add(user) Session.commit() if state: - flask.flash('User {0} is no longer banned'.format(user.username)) + flask.flash("User {0} is no longer banned".format(user.username)) else: - flask.flash('User {0} is banned'.format(user.username)) + flask.flash("User {0} is banned".format(user.username)) except Exception as err: _log.exception(err) - flask.flash(str(err), 'errors') + flask.flash(str(err), "errors") Session.rollback() - return flask.redirect( - flask.url_for('anitya_ui.browse_users') - ) + return flask.redirect(flask.url_for("anitya_ui.browse_users")) diff --git a/anitya/api.py b/anitya/api.py index a53be43d1..63a94b6c8 100644 --- a/anitya/api.py +++ b/anitya/api.py @@ -28,11 +28,11 @@ import anitya.lib.plugins -api_blueprint = flask.Blueprint('anitya_apiv1', __name__) +api_blueprint = flask.Blueprint("anitya_apiv1", __name__) -@api_blueprint.route('/api/') -@api_blueprint.route('/api') +@api_blueprint.route("/api/") +@api_blueprint.route("/api") def api(): """ Retrieve the HTML information page. @@ -40,14 +40,14 @@ def api(): :deprecated: in Anitya 0.12 in favor of simple Sphinx documentation. :statuscode 302: A redirect to the HTML documentation. """ - new_url = flask.url_for('static', filename='docs/api.html') + new_url = flask.url_for("static", filename="docs/api.html") return flask.redirect(new_url) -@api_blueprint.route('/api/version/') -@api_blueprint.route('/api/version') +@api_blueprint.route("/api/version/") +@api_blueprint.route("/api/version") def api_version(): - ''' + """ Display the api version information. :: @@ -64,14 +64,14 @@ def api_version(): "version": "1.0" } - ''' - return flask.jsonify({'version': anitya.__api_version__}) + """ + return flask.jsonify({"version": anitya.__api_version__}) -@api_blueprint.route('/api/projects/') -@api_blueprint.route('/api/projects') +@api_blueprint.route("/api/projects/") +@api_blueprint.route("/api/projects") def api_projects(): - ''' + """ Lists all the projects registered in Anitya. This API accepts GET query strings:: @@ -133,15 +133,15 @@ def api_projects(): "total": 2 } - ''' + """ - pattern = flask.request.args.get('pattern', None) - homepage = flask.request.args.get('homepage', None) - distro = flask.request.args.get('distro', None) + pattern = flask.request.args.get("pattern", None) + homepage = flask.request.args.get("homepage", None) + distro = flask.request.args.get("distro", None) if pattern and homepage: - err = 'pattern and homepage are mutually exclusive. Specify only one.' - output = {'output': 'notok', 'error': [err]} + err = "pattern and homepage are mutually exclusive. Specify only one." + output = {"output": "notok", "error": [err]} jsonout = flask.jsonify(output) jsonout.status_code = 400 return jsonout @@ -149,29 +149,25 @@ def api_projects(): if homepage is not None: project_objs = models.Project.by_homepage(Session, homepage) elif pattern or distro: - if pattern and '*' not in pattern: - pattern += '*' - project_objs = models.Project.search( - Session, pattern=pattern, distro=distro) + if pattern and "*" not in pattern: + pattern += "*" + project_objs = models.Project.search(Session, pattern=pattern, distro=distro) else: project_objs = models.Project.all(Session) projects = [project.__json__() for project in project_objs] - output = { - 'total': len(projects), - 'projects': projects - } + output = {"total": len(projects), "projects": projects} jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout -@api_blueprint.route('/api/packages/wiki/') -@api_blueprint.route('/api/packages/wiki') +@api_blueprint.route("/api/packages/wiki/") +@api_blueprint.route("/api/packages/wiki") def api_packages_wiki_list(): - ''' + """ List all packages in mediawiki format. :deprecated: in Anitya 0.12 due to lack of pagination resulting in @@ -191,29 +187,27 @@ def api_packages_wiki_list(): * 2ping None https://www.finnie.org/software/2ping * 3proxy None https://www.3proxy.ru/download/ - ''' + """ project_objs = models.Project.all(Session) projects = [] for project in project_objs: for package in project.packages: - tmp = '* {name} {regex} {version_url}'.format( + tmp = "* {name} {regex} {version_url}".format( name=package.package_name, regex=project.regex, - version_url=project.version_url) + version_url=project.version_url, + ) projects.append(tmp) - return flask.Response( - "\n".join(projects), - content_type="text/plain;charset=UTF-8" - ) + return flask.Response("\n".join(projects), content_type="text/plain;charset=UTF-8") -@api_blueprint.route('/api/projects/names/') -@api_blueprint.route('/api/projects/names') +@api_blueprint.route("/api/projects/names/") +@api_blueprint.route("/api/projects/names") def api_projects_names(): - ''' + """ Lists the names of all the projects registered in anitya. :query str pattern: pattern to use to restrict the list of names returned. @@ -254,35 +248,31 @@ def api_projects_names(): ], "total": 10 } - ''' + """ - pattern = flask.request.args.get('pattern', None) + pattern = flask.request.args.get("pattern", None) - if pattern and '*' not in pattern: - pattern += '*' + if pattern and "*" not in pattern: + pattern += "*" if pattern: - project_objs = models.Project.search( - Session, pattern=pattern) + project_objs = models.Project.search(Session, pattern=pattern) else: project_objs = models.Project.all(Session) projects = [project.name for project in project_objs] - output = { - 'total': len(projects), - 'projects': projects - } + output = {"total": len(projects), "projects": projects} jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout -@api_blueprint.route('/api/distro/names/') -@api_blueprint.route('/api/distro/names') +@api_blueprint.route("/api/distro/names/") +@api_blueprint.route("/api/distro/names") def api_distro_names(): - ''' + """ Lists the names of all the distributions registered in anitya. :query pattern: pattern to use to restrict the list of distributions returned. @@ -315,34 +305,30 @@ def api_distro_names(): ], "total": 3 } - ''' + """ - pattern = flask.request.args.get('pattern', None) + pattern = flask.request.args.get("pattern", None) - if pattern and '*' not in pattern: - pattern += '*' + if pattern and "*" not in pattern: + pattern += "*" if pattern: - distro_objs = models.Distro.search( - Session, pattern=pattern) + distro_objs = models.Distro.search(Session, pattern=pattern) else: distro_objs = models.Distro.all(Session) distros = [distro.name for distro in distro_objs] - output = { - 'total': len(distros), - 'distro': distros - } + output = {"total": len(distros), "distro": distros} jsonout = flask.jsonify(output) jsonout.status_code = 200 return jsonout -@api_blueprint.route('/api/version/get', methods=['POST']) +@api_blueprint.route("/api/version/get", methods=["POST"]) def api_get_version(): - ''' + """ Forces anitya to retrieve the latest version available from a project upstream. @@ -379,35 +365,34 @@ def api_get_version(): ] } - ''' + """ - project_id = flask.request.form.get('id', None) - test = flask.request.form.get('test', False) + project_id = flask.request.form.get("id", None) + test = flask.request.form.get("test", False) httpcode = 200 if not project_id: errors = [] if not project_id: - errors.append('No project id specified') - output = {'output': 'notok', 'error': errors} + errors.append("No project id specified") + output = {"output": "notok", "error": errors} httpcode = 400 else: - project = models.Project.get( - Session, project_id=project_id) + project = models.Project.get(Session, project_id=project_id) if not project: - output = {'output': 'notok', 'error': 'No such project'} + output = {"output": "notok", "error": "No such project"} httpcode = 404 else: try: version = utilities.check_project_release(project, Session, test=test) if version: - output = {'version': version} + output = {"version": version} else: output = project.__json__(detailed=True) except anitya.lib.exceptions.AnityaException as err: - output = {'output': 'notok', 'error': [str(err)]} + output = {"output": "notok", "error": [str(err)]} httpcode = 400 jsonout = flask.jsonify(output) @@ -415,10 +400,10 @@ def api_get_version(): return jsonout -@api_blueprint.route('/api/project//', methods=['GET']) -@api_blueprint.route('/api/project/', methods=['GET']) +@api_blueprint.route("/api/project//", methods=["GET"]) +@api_blueprint.route("/api/project/", methods=["GET"]) def api_get_project(project_id): - ''' + """ Retrieves a specific project using its identifier in anitya. :: @@ -454,12 +439,12 @@ def api_get_project(project_id): ] } - ''' + """ project = models.Project.get(Session, project_id=project_id) if not project: - output = {'output': 'notok', 'error': 'no such project'} + output = {"output": "notok", "error": "no such project"} httpcode = 404 else: output = project.__json__(detailed=True) @@ -470,10 +455,10 @@ def api_get_project(project_id): return jsonout -@api_blueprint.route('/api/project///', methods=['GET']) -@api_blueprint.route('/api/project//', methods=['GET']) +@api_blueprint.route("/api/project///", methods=["GET"]) +@api_blueprint.route("/api/project//", methods=["GET"]) def api_get_project_distro(distro, package_name): - ''' + """ Retrieves a project in a distribution via the name of the distribution and the name of the package in said distribution. @@ -511,22 +496,20 @@ def api_get_project_distro(distro, package_name): ] } - ''' - package_name = package_name.rstrip('/') + """ + package_name = package_name.rstrip("/") - package = models.Packages.by_package_name_distro( - Session, package_name, distro) + package = models.Packages.by_package_name_distro(Session, package_name, distro) if not package: output = { - 'output': 'notok', - 'error': 'No package "%s" found in distro "%s"' % ( - package_name, distro)} + "output": "notok", + "error": 'No package "%s" found in distro "%s"' % (package_name, distro), + } httpcode = 404 else: - project = models.Project.get( - Session, project_id=package.project.id) + project = models.Project.get(Session, project_id=package.project.id) output = project.__json__(detailed=True) httpcode = 200 @@ -536,10 +519,10 @@ def api_get_project_distro(distro, package_name): return jsonout -@api_blueprint.route('/api/by_ecosystem///', methods=['GET']) -@api_blueprint.route('/api/by_ecosystem//', methods=['GET']) +@api_blueprint.route("/api/by_ecosystem///", methods=["GET"]) +@api_blueprint.route("/api/by_ecosystem//", methods=["GET"]) def api_get_project_ecosystem(ecosystem, project_name): - ''' + """ Retrieves a project in an ecosystem via the name of the ecosystem and the name of the project as registered with Anitya. @@ -589,16 +572,16 @@ def api_get_project_ecosystem(ecosystem, project_name): "1.10.0" ] } - ''' + """ - project = models.Project.by_name_and_ecosystem( - Session, project_name, ecosystem) + project = models.Project.by_name_and_ecosystem(Session, project_name, ecosystem) if not project: output = { - 'output': 'notok', - 'error': 'No project "%s" found in ecosystem "%s"' % ( - project_name, ecosystem)} + "output": "notok", + "error": 'No project "%s" found in ecosystem "%s"' + % (project_name, ecosystem), + } httpcode = 404 else: diff --git a/anitya/api_v2.py b/anitya/api_v2.py index 4d5c8d3d7..307eea43b 100644 --- a/anitya/api_v2.py +++ b/anitya/api_v2.py @@ -38,7 +38,7 @@ def _page_validator(arg): """ arg = int(arg) if arg < 1: - raise ValueError(_('Value must be greater than or equal to 1.')) + raise ValueError(_("Value must be greater than or equal to 1.")) return arg @@ -59,9 +59,9 @@ def _items_per_page_validator(arg): """ arg = int(arg) if arg < 1: - raise ValueError(_('Value must be greater than or equal to 1.')) + raise ValueError(_("Value must be greater than or equal to 1.")) if arg > 250: - raise ValueError(_('Value must be less than or equal to 250.')) + raise ValueError(_("Value must be less than or equal to 250.")) return arg @@ -118,30 +118,34 @@ def get(self): :statuscode 400: If one or more of the query arguments is invalid. """ parser = _BASE_ARG_PARSER.copy() - parser.add_argument('page', type=_page_validator, location='args') - parser.add_argument('items_per_page', type=_items_per_page_validator, location='args') - parser.add_argument('distribution', type=str, location='args') - parser.add_argument('name', type=str, location='args') + parser.add_argument("page", type=_page_validator, location="args") + parser.add_argument( + "items_per_page", type=_items_per_page_validator, location="args" + ) + parser.add_argument("distribution", type=str, location="args") + parser.add_argument("name", type=str, location="args") args = parser.parse_args(strict=True) q = models.Packages.query - distro = args.pop('distribution') - name = args.pop('name') + distro = args.pop("distribution") + name = args.pop("name") if distro: q = q.filter_by(distro_name=distro) if name: q = q.filter_by(package_name=name) page = q.paginate(order_by=models.Packages.package_name, **args) return { - u'items': [ + u"items": [ { - u'distribution': package.distro_name, - u'name': package.package_name, - u'project': package.project.name, - u'ecosystem': package.project.ecosystem_name, - } for package in page.items], - u'page': page.page, - u'items_per_page': page.items_per_page, - u'total_items': page.total_items, + u"distribution": package.distro_name, + u"name": package.package_name, + u"project": package.project.name, + u"ecosystem": package.project.ecosystem_name, + } + for package in page.items + ], + u"page": page.page, + u"items_per_page": page.items_per_page, + u"total_items": page.total_items, } @authentication.require_token @@ -197,49 +201,63 @@ def post(self): :statuscode 401: When your access token is missing or invalid :statuscode 409: When the package already exists. """ - distribution_help = _('The name of the distribution that contains this package.') - package_name_help = _('The name of the package in the distribution repository.') - project_name_help = _('The project name in Anitya.') + distribution_help = _( + "The name of the distribution that contains this package." + ) + package_name_help = _("The name of the package in the distribution repository.") + project_name_help = _("The project name in Anitya.") project_ecosystem_help = _( - 'The ecosystem the project is a part of. If it\'s not part of an ecosystem,' - ' use the homepage used in the Anitya project.') + "The ecosystem the project is a part of. If it's not part of an ecosystem," + " use the homepage used in the Anitya project." + ) parser = _BASE_ARG_PARSER.copy() - parser.add_argument('distribution', type=str, help=distribution_help, required=True) parser.add_argument( - 'package_name', type=str, help=package_name_help, required=True) + "distribution", type=str, help=distribution_help, required=True + ) + parser.add_argument( + "package_name", type=str, help=package_name_help, required=True + ) parser.add_argument( - 'project_name', type=str, help=project_name_help, required=True) + "project_name", type=str, help=project_name_help, required=True + ) parser.add_argument( - 'project_ecosystem', type=str, help=project_ecosystem_help, required=True) + "project_ecosystem", type=str, help=project_ecosystem_help, required=True + ) args = parser.parse_args(strict=True) try: project = models.Project.query.filter_by( - name=args.project_name, ecosystem_name=args.project_ecosystem).one() + name=args.project_name, ecosystem_name=args.project_ecosystem + ).one() except NoResultFound: - return { - 'error': 'Project "{}" in ecosystem "{}" not found'.format( - args.project_name, args.project_ecosystem) - }, 400 + return ( + { + "error": 'Project "{}" in ecosystem "{}" not found'.format( + args.project_name, args.project_ecosystem + ) + }, + 400, + ) try: distro = models.Distro.query.filter_by(name=args.distribution).one() except NoResultFound: - return {'error': 'Distribution "{}" not found'.format(args.distribution)}, 400 + return ( + {"error": 'Distribution "{}" not found'.format(args.distribution)}, + 400, + ) try: package = models.Packages( - distro_name=distro.name, - project=project, - package_name=args.package_name, + distro_name=distro.name, project=project, package_name=args.package_name ) Session.add(package) Session.commit() - return {u'distribution': distro.name, u'name': package.package_name}, 201 + return {u"distribution": distro.name, u"name": package.package_name}, 201 except IntegrityError: Session.rollback() - return {'error': 'package already exists in distribution'}, 409 + return {"error": "package already exists in distribution"}, 409 class ProjectsResource(Resource): @@ -313,20 +331,23 @@ def get(self): :statuscode 400: If one or more of the query arguments is invalid. """ parser = _BASE_ARG_PARSER.copy() - parser.add_argument('page', type=_page_validator, location='args') - parser.add_argument('items_per_page', type=_items_per_page_validator, location='args') - parser.add_argument('ecosystem', type=str, location='args') - parser.add_argument('name', type=str, location='args') + parser.add_argument("page", type=_page_validator, location="args") + parser.add_argument( + "items_per_page", type=_items_per_page_validator, location="args" + ) + parser.add_argument("ecosystem", type=str, location="args") + parser.add_argument("name", type=str, location="args") args = parser.parse_args(strict=True) - ecosystem = args.pop('ecosystem') - name = args.pop('name') + ecosystem = args.pop("ecosystem") + name = args.pop("name") q = models.Project.query if ecosystem: q = q.filter_by(ecosystem_name=ecosystem) if name: q = q.filter_by(name=name) projects_page = q.paginate( - order_by=(models.Project.name, models.Project.ecosystem_name), **args) + order_by=(models.Project.name, models.Project.ecosystem_name), **args + ) return projects_page.as_dict() @authentication.require_token @@ -402,41 +423,44 @@ def post(self): problem. :statuscode 409: When the project already exists. """ - name_help = _('The project name') - homepage_help = _('The project homepage URL') - backend_help = _('The project backend (github, folder, etc.)') - version_url_help = _('The URL to fetch when determining the project ' - 'version (defaults to null)') - version_prefix_help = _('The project version prefix, if any. For ' - 'example, some projects prefix with "v"') - regex_help = _('The regex to use when searching the version_url page') - insecure_help = _('When retrieving the versions via HTTPS, do not ' - 'validate the certificate (defaults to false)') - check_release_help = _('Check the release immediately after creating ' - 'the project.') + name_help = _("The project name") + homepage_help = _("The project homepage URL") + backend_help = _("The project backend (github, folder, etc.)") + version_url_help = _( + "The URL to fetch when determining the project " + "version (defaults to null)" + ) + version_prefix_help = _( + "The project version prefix, if any. For " + 'example, some projects prefix with "v"' + ) + regex_help = _("The regex to use when searching the version_url page") + insecure_help = _( + "When retrieving the versions via HTTPS, do not " + "validate the certificate (defaults to false)" + ) + check_release_help = _( + "Check the release immediately after creating " "the project." + ) parser = _BASE_ARG_PARSER.copy() - parser.add_argument('name', type=str, help=name_help, required=True) - parser.add_argument( - 'homepage', type=str, help=homepage_help, required=True) - parser.add_argument( - 'backend', type=str, help=backend_help, required=True) - parser.add_argument( - 'version_url', type=str, help=version_url_help, default=None) - parser.add_argument( - 'version_prefix', type=str, help=version_prefix_help, default=None) - parser.add_argument('regex', type=str, help=regex_help, default=None) + parser.add_argument("name", type=str, help=name_help, required=True) + parser.add_argument("homepage", type=str, help=homepage_help, required=True) + parser.add_argument("backend", type=str, help=backend_help, required=True) parser.add_argument( - 'insecure', type=bool, help=insecure_help, default=False) + "version_url", type=str, help=version_url_help, default=None + ) parser.add_argument( - 'check_release', type=bool, help=check_release_help) + "version_prefix", type=str, help=version_prefix_help, default=None + ) + parser.add_argument("regex", type=str, help=regex_help, default=None) + parser.add_argument("insecure", type=bool, help=insecure_help, default=False) + parser.add_argument("check_release", type=bool, help=check_release_help) args = parser.parse_args(strict=True) try: project = utilities.create_project( - Session, - user_id=flask_login.current_user.email, - **args + Session, user_id=flask_login.current_user.email, **args ) Session.commit() return project.__json__(), 201 diff --git a/anitya/app.py b/anitya/app.py index 817593fea..673aaa7ee 100644 --- a/anitya/app.py +++ b/anitya/app.py @@ -68,13 +68,13 @@ def create(config=None): login_manager = LoginManager() login_manager.user_loader(authentication.load_user_from_session) login_manager.request_loader(authentication.load_user_from_request) - login_manager.login_view = '/login/' + login_manager.login_view = "/login/" login_manager.init_app(app) # Register the v2 API resources app.api = Api(app) - app.api.add_resource(api_v2.ProjectsResource, '/api/v2/projects/') - app.api.add_resource(api_v2.PackagesResource, '/api/v2/packages/') + app.api.add_resource(api_v2.ProjectsResource, "/api/v2/projects/") + app.api.add_resource(api_v2.PackagesResource, "/api/v2/packages/") # Register all the view blueprints app.register_blueprint(ui.ui_blueprint) @@ -90,14 +90,16 @@ def create(config=None): # subscribe to signals user_logged_in.connect(when_user_log_in, app) - if app.config.get('EMAIL_ERRORS'): + if app.config.get("EMAIL_ERRORS"): # If email logging is configured, set up the anitya logger with an email # handler for any ERROR-level logs. - _anitya_log = logging.getLogger('anitya') - _anitya_log.addHandler(anitya.mail_logging.get_mail_handler( - smtp_server=app.config.get('SMTP_SERVER'), - mail_admin=app.config.get('ADMIN_EMAIL') - )) + _anitya_log = logging.getLogger("anitya") + _anitya_log.addHandler( + anitya.mail_logging.get_mail_handler( + smtp_server=app.config.get("SMTP_SERVER"), + mail_admin=app.config.get("ADMIN_EMAIL"), + ) + ) return app @@ -108,17 +110,17 @@ def global_user(): def shutdown_session(exception=None): - ''' Remove the DB session at the end of each request. ''' + """ Remove the DB session at the end of each request. """ Session.remove() def inject_variable(): - ''' Inject into all templates variables that we would like to have all + """ Inject into all templates variables that we would like to have all the time. - ''' - justedit = flask.session.get('justedit', False) + """ + justedit = flask.session.get("justedit", False) if justedit: # pragma: no cover - flask.session['justedit'] = None + flask.session["justedit"] = None cron_status = utilities.get_last_cron(Session) @@ -128,7 +130,9 @@ def inject_variable(): justedit=justedit, cron_status=cron_status, user=current_user, - available_backends=load_backends(anitya_config['SOCIAL_AUTH_AUTHENTICATION_BACKENDS']), + available_backends=load_backends( + anitya_config["SOCIAL_AUTH_AUTHENTICATION_BACKENDS"] + ), ) @@ -145,13 +149,17 @@ def integrity_error_handler(error): # Because social auth provides the route and raises the exception, this is # the simplest way to turn the error into a nicely formatted error message # for the user. - if 'email' in error.params: + if "email" in error.params: Session.rollback() - other_user = models.User.query.filter_by(email=error.params['email']).one() + other_user = models.User.query.filter_by(email=error.params["email"]).one() try: - social_auth_user = other_user.social_auth.filter_by(user_id=other_user.id).one() - msg = ("Error: There's already an account associated with your email, " - "authenticate with {}.".format(social_auth_user.provider)) + social_auth_user = other_user.social_auth.filter_by( + user_id=other_user.id + ).one() + msg = ( + "Error: There's already an account associated with your email, " + "authenticate with {}.".format(social_auth_user.provider) + ) return msg, 400 # This error happens only if there is account without provider info except NoResultFound: @@ -160,10 +168,11 @@ def integrity_error_handler(error): msg = ( "Error: There was already an existing account with missing provider. " "So we removed it. " - "Please try to log in again.") + "Please try to log in again." + ) return msg, 500 - return 'The server encountered an unexpected error', 500 + return "The server encountered an unexpected error", 500 def auth_error_handler(error): @@ -178,8 +187,10 @@ def auth_error_handler(error): """ # Because social auth openId backend provides route and raises the exceptions, # this is the simplest way to turn error into nicely formatted error message. - msg = ("Error: There was an error during authentication '{}', " - "please check the provided url.".format(error)) + msg = ( + "Error: There was an error during authentication '{}', " + "please check the provided url.".format(error) + ) return msg, 400 @@ -198,5 +209,8 @@ def when_user_log_in(sender, user): missing. """ if user.social_auth.count() == 0: - raise IntegrityError('Missing social_auth table', { - 'social_auth': None, 'email': user.email}, None) + raise IntegrityError( + "Missing social_auth table", + {"social_auth": None, "email": user.email}, + None, + ) diff --git a/anitya/authentication.py b/anitya/authentication.py index be0d5e3de..6793017a7 100644 --- a/anitya/authentication.py +++ b/anitya/authentication.py @@ -77,21 +77,25 @@ def load_user_from_request(request): User: The user associated with the API token, if it exists. Otherwise ``None`` is returned. """ - api_key = request.headers.get('Authorization') + api_key = request.headers.get("Authorization") if api_key: - _log.debug('Attempting to authenticate via user-provided "Authorization" header') + _log.debug( + 'Attempting to authenticate via user-provided "Authorization" header' + ) try: key_type, key_value = api_key.split() except ValueError: return - if key_type.lower() == 'token': + if key_type.lower() == "token": try: api_token = ApiToken.query.filter_by(token=key_value).one() - _log.debug('Successfully authenticated user "%s" via API token', - api_token.user.id) + _log.debug( + 'Successfully authenticated user "%s" via API token', + api_token.user.id, + ) return api_token.user except NoResultFound: - _log.debug('Failed to authenticate user via API token') + _log.debug("Failed to authenticate user via API token") return @@ -109,14 +113,15 @@ def require_token(f): callable: A callable that aborts with an HTTP 401 if the current user is not authenticated. """ + @wraps(f) def _authenticated_api_access(*args, **kwds): if not flask_login.current_user.is_authenticated: error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - return (error_details, 401, {'WWW-Authenticate': 'Token'}) + return (error_details, 401, {"WWW-Authenticate": "Token"}) else: return f(*args, **kwds) diff --git a/anitya/config.py b/anitya/config.py index c4fefc008..80c6191a9 100644 --- a/anitya/config.py +++ b/anitya/config.py @@ -35,66 +35,55 @@ # Set the time after which the session expires PERMANENT_SESSION_LIFETIME=timedelta(seconds=3600), # Secret key used to generate the csrf token in the forms - SECRET_KEY='changeme please', + SECRET_KEY="changeme please", # URL to the database - DB_URL='sqlite:////var/tmp/anitya-dev.sqlite', + DB_URL="sqlite:////var/tmp/anitya-dev.sqlite", # List of admins based on their openid ANITYA_WEB_ADMINS=[], - ADMIN_EMAIL='admin@fedoraproject.org', + ADMIN_EMAIL="admin@fedoraproject.org", ANITYA_LOG_CONFIG={ - 'version': 1, - 'disable_existing_loggers': False, - 'formatters': { - 'simple': { - 'format': '[%(name)s %(levelname)s] %(message)s', - }, - }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'simple', - 'stream': 'ext://sys.stdout', + "version": 1, + "disable_existing_loggers": False, + "formatters": {"simple": {"format": "[%(name)s %(levelname)s] %(message)s"}}, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "formatter": "simple", + "stream": "ext://sys.stdout", } }, - 'loggers': { - 'anitya': { - 'level': 'INFO', - 'propagate': False, - 'handlers': ['console'], - }, + "loggers": { + "anitya": {"level": "INFO", "propagate": False, "handlers": ["console"]} }, # The root logger configuration; this is a catch-all configuration # that applies to all log messages not handled by a different logger - 'root': { - 'level': 'INFO', - 'handlers': ['console'], - }, + "root": {"level": "INFO", "handlers": ["console"]}, }, # The SMTP server to send mail through - SMTP_SERVER='127.0.0.1', + SMTP_SERVER="127.0.0.1", # Whether or not to send emails to MAIL_ADMIN via SMTP_SERVER when HTTP 500 # errors occur. EMAIL_ERRORS=False, BLACKLISTED_USERS=[], - SESSION_PROTECTION='strong', + SESSION_PROTECTION="strong", SOCIAL_AUTH_AUTHENTICATION_BACKENDS=( - 'social_core.backends.fedora.FedoraOpenId', - 'social_core.backends.gitlab.GitLabOAuth2', - 'social_core.backends.github.GithubOAuth2', - 'social_core.backends.google.GoogleOAuth2', - 'social_core.backends.yahoo.YahooOpenId', - 'social_core.backends.open_id.OpenIdAuth', + "social_core.backends.fedora.FedoraOpenId", + "social_core.backends.gitlab.GitLabOAuth2", + "social_core.backends.github.GithubOAuth2", + "social_core.backends.google.GoogleOAuth2", + "social_core.backends.yahoo.YahooOpenId", + "social_core.backends.open_id.OpenIdAuth", ), - SOCIAL_AUTH_STORAGE='social_flask_sqlalchemy.models.FlaskStorage', - SOCIAL_AUTH_USER_MODEL='anitya.db.models.User', + SOCIAL_AUTH_STORAGE="social_flask_sqlalchemy.models.FlaskStorage", + SOCIAL_AUTH_USER_MODEL="anitya.db.models.User", # Force the application to require HTTPS on authentication redirects. SOCIAL_AUTH_REDIRECT_IS_HTTPS=True, - SOCIAL_AUTH_LOGIN_URL='/login/', - SOCIAL_AUTH_LOGIN_REDIRECT_URL='/', - SOCIAL_AUTH_LOGIN_ERROR_URL='/login-error/', + SOCIAL_AUTH_LOGIN_URL="/login/", + SOCIAL_AUTH_LOGIN_REDIRECT_URL="/", + SOCIAL_AUTH_LOGIN_ERROR_URL="/login-error/", LIBRARIESIO_PLATFORM_WHITELIST=[], - DEFAULT_REGEX=r'(?i)%(name)s(?:[-_]?(?:minsrc|src|source))?[-_]([^-/_\s]+?)(?:[-_]'\ - r'(?:minsrc|src|source|asc|release))?\.(?:tar|t[bglx]z|tbz2|zip)', + DEFAULT_REGEX=r"(?i)%(name)s(?:[-_]?(?:minsrc|src|source))?[-_]([^-/_\s]+?)(?:[-_]" + r"(?:minsrc|src|source|asc|release))?\.(?:tar|t[bglx]z|tbz2|zip)", # Token for GitHub API GITHUB_ACCESS_TOKEN=None, LEGACY_MESSAGING=False, # If True, publish with fedmsg instead of fedora_messaging @@ -102,7 +91,7 @@ # Start with a basic logging configuration, which will be replaced by any user- # specified logging configuration when the configuration is loaded. -logging.config.dictConfig(DEFAULTS['ANITYA_LOG_CONFIG']) +logging.config.dictConfig(DEFAULTS["ANITYA_LOG_CONFIG"]) def load(): @@ -116,30 +105,35 @@ def load(): """ config = DEFAULTS.copy() - if 'ANITYA_WEB_CONFIG' in os.environ: - config_path = os.environ['ANITYA_WEB_CONFIG'] + if "ANITYA_WEB_CONFIG" in os.environ: + config_path = os.environ["ANITYA_WEB_CONFIG"] else: - config_path = '/etc/anitya/anitya.toml' + config_path = "/etc/anitya/anitya.toml" if os.path.exists(config_path): - _log.info('Loading Anitya configuration from {}'.format(config_path)) + _log.info("Loading Anitya configuration from {}".format(config_path)) with open(config_path) as fd: try: file_config = pytoml.loads(fd.read()) for key in file_config: config[key.upper()] = file_config[key] except pytoml.core.TomlError as e: - _log.error('Failed to parse {}: {}'.format(config_path, str(e))) + _log.error("Failed to parse {}: {}".format(config_path, str(e))) else: - _log.info('The Anitya configuration file, {}, does not exist.'.format(config_path)) - - if not isinstance(config['PERMANENT_SESSION_LIFETIME'], timedelta): - config['PERMANENT_SESSION_LIFETIME'] = timedelta( - seconds=config['PERMANENT_SESSION_LIFETIME']) - - if config['SECRET_KEY'] == DEFAULTS['SECRET_KEY']: - _log.warning('SECRET_KEY is not configured, falling back to the default. ' - 'This is NOT safe for production deployments!') + _log.info( + "The Anitya configuration file, {}, does not exist.".format(config_path) + ) + + if not isinstance(config["PERMANENT_SESSION_LIFETIME"], timedelta): + config["PERMANENT_SESSION_LIFETIME"] = timedelta( + seconds=config["PERMANENT_SESSION_LIFETIME"] + ) + + if config["SECRET_KEY"] == DEFAULTS["SECRET_KEY"]: + _log.warning( + "SECRET_KEY is not configured, falling back to the default. " + "This is NOT safe for production deployments!" + ) return config @@ -147,4 +141,4 @@ def load(): config = load() # With the full configuration loaded, we can now configure logging properly. -logging.config.dictConfig(config['ANITYA_LOG_CONFIG']) +logging.config.dictConfig(config["ANITYA_LOG_CONFIG"]) diff --git a/anitya/db/__init__.py b/anitya/db/__init__.py index 8300437ed..9dcd269ff 100644 --- a/anitya/db/__init__.py +++ b/anitya/db/__init__.py @@ -23,6 +23,13 @@ from .meta import initialize, Session, Base, Page, BaseQuery # noqa: F401 from .models import ( # noqa: F401 - Distro, Packages, Project, ProjectVersion, ProjectFlag, Run, User, ApiToken + Distro, + Packages, + Project, + ProjectVersion, + ProjectFlag, + Run, + User, + ApiToken, ) from .events import set_ecosystem # noqa: F401 diff --git a/anitya/db/events.py b/anitya/db/events.py index 23a2074b1..b9b3958ff 100644 --- a/anitya/db/events.py +++ b/anitya/db/events.py @@ -26,7 +26,7 @@ _log = logging.getLogger(__name__) -@event.listens_for(Session, 'before_flush') +@event.listens_for(Session, "before_flush") def set_ecosystem(session, flush_context, instances): """ An SQLAlchemy event listener that sets the ecosystem for a project if it's null. @@ -42,18 +42,27 @@ def set_ecosystem(session, flush_context, instances): for new_obj in session.new: if isinstance(new_obj, Project): if new_obj.ecosystem_name is None: - ecosystems = [e for e in plugins.ECOSYSTEM_PLUGINS.get_plugins() - if e.default_backend == new_obj.backend] + ecosystems = [ + e + for e in plugins.ECOSYSTEM_PLUGINS.get_plugins() + if e.default_backend == new_obj.backend + ] if ecosystems: new_obj.ecosystem_name = ecosystems[0].name else: new_obj.ecosystem_name = new_obj.homepage - _log.info('Settings the ecosystem on %r to %s by default', - new_obj, new_obj.ecosystem_name) + _log.info( + "Settings the ecosystem on %r to %s by default", + new_obj, + new_obj.ecosystem_name, + ) else: # Validate the field valid_names = [e.name for e in plugins.ECOSYSTEM_PLUGINS.get_plugins()] valid_names.append(new_obj.homepage) if new_obj.ecosystem_name not in valid_names: - raise ValueError('Invalid ecosystem_name "{}", must be one of {}'.format( - new_obj.ecosystem_name, valid_names)) + raise ValueError( + 'Invalid ecosystem_name "{}", must be one of {}'.format( + new_obj.ecosystem_name, valid_names + ) + ) diff --git a/anitya/db/meta.py b/anitya/db/meta.py index 8e162e123..461be1d8f 100644 --- a/anitya/db/meta.py +++ b/anitya/db/meta.py @@ -58,20 +58,21 @@ def initialize(config): """ #: The SQLAlchemy database engine. This is constructed using the value of #: ``DB_URL`` in :mod:`anitya.config``. - engine = create_engine(config['DB_URL'], echo=config.get('SQL_DEBUG', False)) + engine = create_engine(config["DB_URL"], echo=config.get("SQL_DEBUG", False)) # Source: https://docs.sqlalchemy.org/en/latest/dialects/sqlite.html#foreign-key-support - if config['DB_URL'].startswith('sqlite:'): + if config["DB_URL"].startswith("sqlite:"): event.listen( engine, - 'connect', - lambda db_con, con_record: db_con.execute('PRAGMA foreign_keys=ON') + "connect", + lambda db_con, con_record: db_con.execute("PRAGMA foreign_keys=ON"), ) Session.configure(bind=engine) return engine _Page = collections.namedtuple( - '_Page', ('items', 'page', 'items_per_page', 'total_items')) + "_Page", ("items", "page", "items_per_page", "total_items") +) class Page(_Page): @@ -94,10 +95,10 @@ def as_dict(self): the ``__json__`` method defined on the item objects. """ return { - u'items': [item.__json__() for item in self.items], - u'page': self.page, - u'items_per_page': self.items_per_page, - u'total_items': self.total_items, + "items": [item.__json__() for item in self.items], + "page": self.page, + "items_per_page": self.items_per_page, + "total_items": self.total_items, } @@ -129,9 +130,9 @@ def paginate(self, page=None, items_per_page=None, order_by=None): items_per_page = 25 if page < 1: - raise ValueError('page must be 1 or greater.') + raise ValueError("page must be 1 or greater.") if items_per_page < 1: - raise ValueError('items_per_page must be 1 or greater.') + raise ValueError("items_per_page must be 1 or greater.") if not isinstance(order_by, tuple): order_by = (order_by,) @@ -140,7 +141,11 @@ def paginate(self, page=None, items_per_page=None, order_by=None): total_items = q.count() items = q.limit(items_per_page).offset(items_per_page * (page - 1)).all() return Page( - items=items, page=page, total_items=total_items, items_per_page=items_per_page) + items=items, + page=page, + total_items=total_items, + items_per_page=items_per_page, + ) class _AnityaBase(object): diff --git a/anitya/db/migrations/env.py b/anitya/db/migrations/env.py index c61e16cc0..3f989e6b0 100644 --- a/anitya/db/migrations/env.py +++ b/anitya/db/migrations/env.py @@ -56,15 +56,13 @@ def run_migrations_online(): """ engine = engine_from_config( - config.get_section(config.config_ini_section), - prefix='sqlalchemy.', - poolclass=pool.NullPool) + config.get_section(config.config_ini_section), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) connection = engine.connect() - context.configure( - connection=connection, - target_metadata=target_metadata - ) + context.configure(connection=connection, target_metadata=target_metadata) try: with context.begin_transaction(): diff --git a/anitya/db/migrations/versions/1ab95561edae_convert_date_to_rpm.py b/anitya/db/migrations/versions/1ab95561edae_convert_date_to_rpm.py index 8bb6b52a6..9a55e7a40 100644 --- a/anitya/db/migrations/versions/1ab95561edae_convert_date_to_rpm.py +++ b/anitya/db/migrations/versions/1ab95561edae_convert_date_to_rpm.py @@ -9,17 +9,19 @@ # revision identifiers, used by Alembic. -revision = '1ab95561edae' -down_revision = '6ac0e42df937' +revision = "1ab95561edae" +down_revision = "6ac0e42df937" def upgrade(): """ Any project using Date version scheme should now use RPM version scheme. """ - op.execute(""" + op.execute( + """ UPDATE projects SET version_scheme='RPM' WHERE version_scheme='Date' - """) + """ + ) def downgrade(): diff --git a/anitya/db/migrations/versions/1bf8aead6179_add_check_times.py b/anitya/db/migrations/versions/1bf8aead6179_add_check_times.py index 359bc918b..254afddad 100644 --- a/anitya/db/migrations/versions/1bf8aead6179_add_check_times.py +++ b/anitya/db/migrations/versions/1bf8aead6179_add_check_times.py @@ -11,38 +11,42 @@ # revision identifiers, used by Alembic. -revision = '1bf8aead6179' -down_revision = 'b13662e5d288' +revision = "1bf8aead6179" +down_revision = "b13662e5d288" def upgrade(): """ Add next_check and last_check columns to the projects table. """ op.add_column( - 'projects', + "projects", sa.Column( - 'last_check', + "last_check", sa.TIMESTAMP(timezone=True), default=arrow.utcnow().datetime, - server_default=sa.func.current_timestamp() - ) + server_default=sa.func.current_timestamp(), + ), ) op.add_column( - 'projects', + "projects", sa.Column( - 'next_check', + "next_check", sa.TIMESTAMP(timezone=True), default=arrow.utcnow().datetime, - server_default=sa.func.current_timestamp() - ) + server_default=sa.func.current_timestamp(), + ), + ) + op.create_index( + op.f("ix_projects_last_check"), "projects", ["last_check"], unique=False + ) + op.create_index( + op.f("ix_projects_next_check"), "projects", ["next_check"], unique=False ) - op.create_index(op.f('ix_projects_last_check'), 'projects', ['last_check'], unique=False) - op.create_index(op.f('ix_projects_next_check'), 'projects', ['next_check'], unique=False) def downgrade(): """ Drop next_check and last_check columns to the projects table. """ - op.drop_column('projects', 'last_check') - op.drop_column('projects', 'next_check') - op.drop_index(op.f('ix_projects_next_check'), table_name='projects') - op.drop_index(op.f('ix_projects_last_check'), table_name='projects') + op.drop_column("projects", "last_check") + op.drop_column("projects", "next_check") + op.drop_index(op.f("ix_projects_next_check"), table_name="projects") + op.drop_index(op.f("ix_projects_last_check"), table_name="projects") diff --git a/anitya/db/migrations/versions/24b6734e8565_creation_date_on_version.py b/anitya/db/migrations/versions/24b6734e8565_creation_date_on_version.py index 78279c91b..b0b230fe9 100644 --- a/anitya/db/migrations/versions/24b6734e8565_creation_date_on_version.py +++ b/anitya/db/migrations/versions/24b6734e8565_creation_date_on_version.py @@ -10,21 +10,18 @@ # revision identifiers, used by Alembic. -revision = '24b6734e8565' -down_revision = '34b9bb5fa388' +revision = "24b6734e8565" +down_revision = "34b9bb5fa388" def upgrade(): """ Add `created_on` date column to projects_versions table. """ op.add_column( - 'projects_versions', - sa.Column( - 'created_on', - sa.DateTime, - default=sa.func.current_timestamp()) + "projects_versions", + sa.Column("created_on", sa.DateTime, default=sa.func.current_timestamp()), ) def downgrade(): - ''' Drop the `created_on` column from the projects_version table. ''' - op.drop_column('projects_versions', 'created_on') + """ Drop the `created_on` column from the projects_version table. """ + op.drop_column("projects_versions", "created_on") diff --git a/anitya/db/migrations/versions/27342bce1d0f_populate_project_version_scheme.py b/anitya/db/migrations/versions/27342bce1d0f_populate_project_version_scheme.py index 6ac293b71..258623fa0 100644 --- a/anitya/db/migrations/versions/27342bce1d0f_populate_project_version_scheme.py +++ b/anitya/db/migrations/versions/27342bce1d0f_populate_project_version_scheme.py @@ -9,8 +9,8 @@ # revision identifiers, used by Alembic. -revision = '27342bce1d0f' -down_revision = '24b6734e8565' +revision = "27342bce1d0f" +down_revision = "24b6734e8565" def upgrade(): @@ -18,11 +18,13 @@ def upgrade(): This was the only available version value before this update. In newer version of Anitya you can change the value when editing project. """ - op.execute(""" + op.execute( + """ UPDATE projects SET version_scheme='RPM' WHERE version_scheme is null - """) + """ + ) def downgrade(): diff --git a/anitya/db/migrations/versions/2925648d8cc3_add_a_version_prefix_field.py b/anitya/db/migrations/versions/2925648d8cc3_add_a_version_prefix_field.py index 0d2592a67..3dca0ae1f 100644 --- a/anitya/db/migrations/versions/2925648d8cc3_add_a_version_prefix_field.py +++ b/anitya/db/migrations/versions/2925648d8cc3_add_a_version_prefix_field.py @@ -10,21 +10,17 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '2925648d8cc3' -down_revision = '571bd07533a9' +revision = "2925648d8cc3" +down_revision = "571bd07533a9" def upgrade(): - ''' Add the `version_prefix` column on the projects table. ''' + """ Add the `version_prefix` column on the projects table. """ op.add_column( - 'projects', - sa.Column( - 'version_prefix', - sa.String(200), - nullable=True) + "projects", sa.Column("version_prefix", sa.String(200), nullable=True) ) def downgrade(): - ''' Drop the `version_prefix` column of the projects table. ''' - op.drop_column('projects', 'version_prefix') + """ Drop the `version_prefix` column of the projects table. """ + op.drop_column("projects", "version_prefix") diff --git a/anitya/db/migrations/versions/34b9bb5fa388_make_ecosystem_non_nullable.py b/anitya/db/migrations/versions/34b9bb5fa388_make_ecosystem_non_nullable.py index 5bb54a07a..f0047aada 100644 --- a/anitya/db/migrations/versions/34b9bb5fa388_make_ecosystem_non_nullable.py +++ b/anitya/db/migrations/versions/34b9bb5fa388_make_ecosystem_non_nullable.py @@ -26,27 +26,39 @@ # revision identifiers, used by Alembic. -revision = '34b9bb5fa388' -down_revision = '3fae8239eeec' +revision = "34b9bb5fa388" +down_revision = "3fae8239eeec" def upgrade(): """Make the ecosystem_name non-nullable after setting null instances to the homepage.""" - op.execute(""" + op.execute( + """ UPDATE projects SET ecosystem_name=homepage WHERE ecosystem_name IS NULL - """) + """ + ) op.alter_column( - 'projects', 'ecosystem_name', existing_type=sa.VARCHAR(length=200), nullable=False) + "projects", + "ecosystem_name", + existing_type=sa.VARCHAR(length=200), + nullable=False, + ) def downgrade(): """Make the ecosystem_name nullable.""" op.alter_column( - 'projects', 'ecosystem_name', existing_type=sa.VARCHAR(length=200), nullable=True) - op.execute(""" + "projects", + "ecosystem_name", + existing_type=sa.VARCHAR(length=200), + nullable=True, + ) + op.execute( + """ UPDATE projects SET ecosystem_name=NULL WHERE ecosystem_name=homepage - """) + """ + ) diff --git a/anitya/db/migrations/versions/3fae8239eeec_add_an_api_token_table.py b/anitya/db/migrations/versions/3fae8239eeec_add_an_api_token_table.py index 152c778f6..f572c21b2 100644 --- a/anitya/db/migrations/versions/3fae8239eeec_add_an_api_token_table.py +++ b/anitya/db/migrations/versions/3fae8239eeec_add_an_api_token_table.py @@ -31,8 +31,8 @@ # revision identifiers, used by Alembic. -revision = '3fae8239eeec' -down_revision = 'feeaa70ead67' +revision = "3fae8239eeec" +down_revision = "feeaa70ead67" class GUID(TypeDecorator): @@ -41,6 +41,7 @@ class GUID(TypeDecorator): If PostgreSQL is being used, use its native UUID type, otherwise use a CHAR(32) type. """ + impl = CHAR def load_dialect_impl(self, dialect): @@ -54,7 +55,7 @@ def load_dialect_impl(self, dialect): sqlalchemy.types.TypeEngine: Either a PostgreSQL UUID or a CHAR(32) on other dialects. """ - if dialect.name == 'postgresql': + if dialect.name == "postgresql": return dialect.type_descriptor(UUID()) else: return dialect.type_descriptor(CHAR(32)) @@ -75,7 +76,7 @@ def process_bind_param(self, value, dialect): """ if value is None: return value - elif dialect.name == 'postgresql': + elif dialect.name == "postgresql": return str(value) else: if not isinstance(value, uuid.UUID): @@ -104,16 +105,16 @@ def process_result_value(self, value, dialect): def upgrade(): """Create the ``tokens`` table.""" op.create_table( - 'tokens', - sa.Column('token', sa.String(length=40), nullable=False), - sa.Column('created', sa.DateTime(), nullable=False), - sa.Column('user_id', GUID(), nullable=False), - sa.Column('description', sa.Text(), nullable=True), - sa.ForeignKeyConstraint(['user_id'], ['users.id'], ), - sa.PrimaryKeyConstraint('token') + "tokens", + sa.Column("token", sa.String(length=40), nullable=False), + sa.Column("created", sa.DateTime(), nullable=False), + sa.Column("user_id", GUID(), nullable=False), + sa.Column("description", sa.Text(), nullable=True), + sa.ForeignKeyConstraint(["user_id"], ["users.id"]), + sa.PrimaryKeyConstraint("token"), ) def downgrade(): """Drop the ``tokens`` table.""" - op.drop_table('tokens') + op.drop_table("tokens") diff --git a/anitya/db/migrations/versions/540bdcf7edbc_convert_github_url_to_owner_project.py b/anitya/db/migrations/versions/540bdcf7edbc_convert_github_url_to_owner_project.py index acb9bf2ab..2101511d4 100644 --- a/anitya/db/migrations/versions/540bdcf7edbc_convert_github_url_to_owner_project.py +++ b/anitya/db/migrations/versions/540bdcf7edbc_convert_github_url_to_owner_project.py @@ -9,22 +9,26 @@ # revision identifiers, used by Alembic. -revision = '540bdcf7edbc' -down_revision = '27342bce1d0f' +revision = "540bdcf7edbc" +down_revision = "27342bce1d0f" def upgrade(): """Convert GitHub URL to owner/project to work with the new GitHub backend.""" - op.execute(""" + op.execute( + """ UPDATE projects SET version_url=trim(substr(version_url, 19), '/') WHERE backend = 'GitHub' AND version_url LIKE 'http://github.com/%' - """) - op.execute(""" + """ + ) + op.execute( + """ UPDATE projects SET version_url=trim(substr(version_url, 20), '/') WHERE backend = 'GitHub' AND version_url LIKE 'https://github.com/%' - """) + """ + ) def downgrade(): diff --git a/anitya/db/migrations/versions/571bd07533a9_add_insecure_column_to_projects_table.py b/anitya/db/migrations/versions/571bd07533a9_add_insecure_column_to_projects_table.py index 810393b13..e28cbd877 100644 --- a/anitya/db/migrations/versions/571bd07533a9_add_insecure_column_to_projects_table.py +++ b/anitya/db/migrations/versions/571bd07533a9_add_insecure_column_to_projects_table.py @@ -10,23 +10,24 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '571bd07533a9' +revision = "571bd07533a9" down_revision = None def upgrade(): - ''' Add the `insecure` column on the projects table. ''' + """ Add the `insecure` column on the projects table. """ op.add_column( - 'projects', + "projects", sa.Column( - 'insecure', + "insecure", sa.Boolean, default=False, server_default="FALSE", - nullable=False) + nullable=False, + ), ) def downgrade(): - ''' Drop the `insecure` column of the projects table. ''' - op.drop_column('projects', 'insecure') + """ Drop the `insecure` column of the projects table. """ + op.drop_column("projects", "insecure") diff --git a/anitya/db/migrations/versions/6ac0e42df937_drop_logs_table.py b/anitya/db/migrations/versions/6ac0e42df937_drop_logs_table.py index 245beefa3..3bbb6227c 100644 --- a/anitya/db/migrations/versions/6ac0e42df937_drop_logs_table.py +++ b/anitya/db/migrations/versions/6ac0e42df937_drop_logs_table.py @@ -10,8 +10,8 @@ # revision identifiers, used by Alembic. -revision = '6ac0e42df937' -down_revision = '1bf8aead6179' +revision = "6ac0e42df937" +down_revision = "1bf8aead6179" def upgrade(): @@ -19,30 +19,28 @@ def upgrade(): Drop logs table. Add and fill check_successful column to projects table. """ - op.drop_table('logs') + op.drop_table("logs") - op.add_column( - 'projects', - sa.Column( - 'check_successful', - sa.Boolean, - default=None) - ) + op.add_column("projects", sa.Column("check_successful", sa.Boolean, default=None)) - op.execute(""" + op.execute( + """ UPDATE projects SET check_successful=TRUE WHERE (logs='Version retrieved correctly' OR logs='No new version found') AND check_successful IS NULL - """) + """ + ) - op.execute(""" + op.execute( + """ UPDATE projects SET check_successful=FALSE WHERE logs IS NOT NULL AND check_successful IS NULL - """) + """ + ) def downgrade(): @@ -51,16 +49,16 @@ def downgrade(): Drop updated column from projects table. """ op.create_table( - 'logs', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('user', sa.String(length=200), nullable=False), - sa.Column('project', sa.String(length=200), nullable=True), - sa.Column('distro', sa.String(length=200), nullable=True), - sa.Column('description', sa.Text(), nullable=False), - sa.Column('created_on', sa.DateTime(), nullable=True), - sa.PrimaryKeyConstraint('id') + "logs", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("user", sa.String(length=200), nullable=False), + sa.Column("project", sa.String(length=200), nullable=True), + sa.Column("distro", sa.String(length=200), nullable=True), + sa.Column("description", sa.Text(), nullable=False), + sa.Column("created_on", sa.DateTime(), nullable=True), + sa.PrimaryKeyConstraint("id"), ) - op.create_index(op.f('ix_logs_distro'), 'logs', ['distro'], unique=False) - op.create_index(op.f('ix_logs_project'), 'logs', ['project'], unique=False) - op.create_index(op.f('ix_logs_user'), 'logs', ['user'], unique=False) - op.drop_column('projects', 'check_successful') + op.create_index(op.f("ix_logs_distro"), "logs", ["distro"], unique=False) + op.create_index(op.f("ix_logs_project"), "logs", ["project"], unique=False) + op.create_index(op.f("ix_logs_user"), "logs", ["user"], unique=False) + op.drop_column("projects", "check_successful") diff --git a/anitya/db/migrations/versions/7a8c4aa92678_add_missing_github_owner_project_pairs.py b/anitya/db/migrations/versions/7a8c4aa92678_add_missing_github_owner_project_pairs.py index d095639bc..d79cef109 100644 --- a/anitya/db/migrations/versions/7a8c4aa92678_add_missing_github_owner_project_pairs.py +++ b/anitya/db/migrations/versions/7a8c4aa92678_add_missing_github_owner_project_pairs.py @@ -9,26 +9,30 @@ # revision identifiers, used by Alembic. -revision = '7a8c4aa92678' -down_revision = '540bdcf7edbc' +revision = "7a8c4aa92678" +down_revision = "540bdcf7edbc" def upgrade(): """Populate missing GitHub owner/project pairs from homepage.""" - op.execute(""" + op.execute( + """ UPDATE projects SET version_url=trim(substr(trim(homepage), 19), '/') WHERE backend = 'GitHub' AND trim(homepage) LIKE 'http://github.com/%' AND (version_url IS NULL OR version_url = '') - """) - op.execute(""" + """ + ) + op.execute( + """ UPDATE projects SET version_url=trim(substr(trim(homepage), 20), '/') WHERE backend = 'GitHub' AND trim(homepage) LIKE 'https://github.com/%' AND (version_url IS NULL OR version_url = '') - """) + """ + ) def downgrade(): diff --git a/anitya/db/migrations/versions/8040ef9a9dda_add_a_version_scheme_column_to_projects.py b/anitya/db/migrations/versions/8040ef9a9dda_add_a_version_scheme_column_to_projects.py index eb4f4d125..94e32dc6d 100644 --- a/anitya/db/migrations/versions/8040ef9a9dda_add_a_version_scheme_column_to_projects.py +++ b/anitya/db/migrations/versions/8040ef9a9dda_add_a_version_scheme_column_to_projects.py @@ -10,15 +10,17 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '8040ef9a9dda' -down_revision = 'b9201d816075' +revision = "8040ef9a9dda" +down_revision = "b9201d816075" def upgrade(): """Add the version_scheme column to the projects table.""" - op.add_column('projects', sa.Column('version_scheme', sa.String(length=50), nullable=True)) + op.add_column( + "projects", sa.Column("version_scheme", sa.String(length=50), nullable=True) + ) def downgrade(): """Remove the version_scheme column from the projects table.""" - op.drop_column('projects', 'version_scheme') + op.drop_column("projects", "version_scheme") diff --git a/anitya/db/migrations/versions/921c612ba0da_model_upstream_ecosystems.py b/anitya/db/migrations/versions/921c612ba0da_model_upstream_ecosystems.py index e05ebd448..fdeb52855 100644 --- a/anitya/db/migrations/versions/921c612ba0da_model_upstream_ecosystems.py +++ b/anitya/db/migrations/versions/921c612ba0da_model_upstream_ecosystems.py @@ -10,21 +10,29 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '921c612ba0da' -down_revision = '2925648d8cc3' +revision = "921c612ba0da" +down_revision = "2925648d8cc3" def upgrade(): op.add_column( - 'projects', sa.Column('ecosystem_name', sa.String(length=200), nullable=True)) + "projects", sa.Column("ecosystem_name", sa.String(length=200), nullable=True) + ) op.create_unique_constraint( - 'UNIQ_PROJECT_NAME_PER_ECOSYSTEM', 'projects', ['name', 'ecosystem_name']) + "UNIQ_PROJECT_NAME_PER_ECOSYSTEM", "projects", ["name", "ecosystem_name"] + ) op.create_foreign_key( - 'FK_ECOSYSTEM_FOR_PROJECT', 'projects', 'ecosystems', ['ecosystem_name'], - ['name'], onupdate='cascade', ondelete='set null') + "FK_ECOSYSTEM_FOR_PROJECT", + "projects", + "ecosystems", + ["ecosystem_name"], + ["name"], + onupdate="cascade", + ondelete="set null", + ) def downgrade(): - op.drop_constraint('FK_ECOSYSTEM_FOR_PROJECT', 'projects', type_='foreignkey') - op.drop_constraint('UNIQ_PROJECT_NAME_PER_ECOSYSTEM', 'projects', type_='unique') - op.drop_column('projects', 'ecosystem_name') + op.drop_constraint("FK_ECOSYSTEM_FOR_PROJECT", "projects", type_="foreignkey") + op.drop_constraint("UNIQ_PROJECT_NAME_PER_ECOSYSTEM", "projects", type_="unique") + op.drop_column("projects", "ecosystem_name") diff --git a/anitya/db/migrations/versions/9c29da0af3af_populate_ecosystem_data.py b/anitya/db/migrations/versions/9c29da0af3af_populate_ecosystem_data.py index e4de91cee..ffa1bb1f2 100644 --- a/anitya/db/migrations/versions/9c29da0af3af_populate_ecosystem_data.py +++ b/anitya/db/migrations/versions/9c29da0af3af_populate_ecosystem_data.py @@ -9,14 +9,15 @@ from alembic import op # revision identifiers, used by Alembic. -revision = '9c29da0af3af' -down_revision = '921c612ba0da' +revision = "9c29da0af3af" +down_revision = "921c612ba0da" def upgrade(): # We use a subquery instead of an UPDATE FROM with a table join # due to the fact that SQLite doesn't allow joins in update statements - op.execute(""" + op.execute( + """ UPDATE projects SET ecosystem_name=( SELECT ecosystems.name @@ -26,7 +27,8 @@ def upgrade(): WHERE projects.id = subquery_projects.id ) WHERE ecosystem_name is null - """) + """ + ) def downgrade(): diff --git a/anitya/db/migrations/versions/a52d2fe99d4f_users.py b/anitya/db/migrations/versions/a52d2fe99d4f_users.py index 9c94972da..f3e6915b9 100644 --- a/anitya/db/migrations/versions/a52d2fe99d4f_users.py +++ b/anitya/db/migrations/versions/a52d2fe99d4f_users.py @@ -14,8 +14,8 @@ # revision identifiers, used by Alembic. -revision = 'a52d2fe99d4f' -down_revision = '8040ef9a9dda' +revision = "a52d2fe99d4f" +down_revision = "8040ef9a9dda" class GUID(TypeDecorator): @@ -24,6 +24,7 @@ class GUID(TypeDecorator): If PostgreSQL is being used, use its native UUID type, otherwise use a CHAR(32) type. """ + impl = CHAR def load_dialect_impl(self, dialect): @@ -37,7 +38,7 @@ def load_dialect_impl(self, dialect): sqlalchemy.types.TypeEngine: Either a PostgreSQL UUID or a CHAR(32) on other dialects. """ - if dialect.name == 'postgresql': + if dialect.name == "postgresql": return dialect.type_descriptor(UUID()) else: return dialect.type_descriptor(CHAR(32)) @@ -58,7 +59,7 @@ def process_bind_param(self, value, dialect): """ if value is None: return value - elif dialect.name == 'postgresql': + elif dialect.name == "postgresql": return str(value) else: if not isinstance(value, uuid.UUID): @@ -87,19 +88,19 @@ def process_result_value(self, value, dialect): def upgrade(): """Add a "users" table.""" op.create_table( - 'users', - sa.Column('id', GUID(), nullable=False), - sa.Column('email', sa.String(length=256), nullable=False), - sa.Column('username', sa.String(length=256), nullable=False), - sa.Column('active', sa.Boolean(), nullable=False), - sa.PrimaryKeyConstraint('id') + "users", + sa.Column("id", GUID(), nullable=False), + sa.Column("email", sa.String(length=256), nullable=False), + sa.Column("username", sa.String(length=256), nullable=False), + sa.Column("active", sa.Boolean(), nullable=False), + sa.PrimaryKeyConstraint("id"), ) - op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True) - op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True) + op.create_index(op.f("ix_users_email"), "users", ["email"], unique=True) + op.create_index(op.f("ix_users_username"), "users", ["username"], unique=True) def downgrade(): """Drop the "users" table.""" - op.drop_index(op.f('ix_users_username'), table_name='users') - op.drop_index(op.f('ix_users_email'), table_name='users') - op.drop_table('users') + op.drop_index(op.f("ix_users_username"), table_name="users") + op.drop_index(op.f("ix_users_email"), table_name="users") + op.drop_table("users") diff --git a/anitya/db/migrations/versions/ac10bf3f974c_.py b/anitya/db/migrations/versions/ac10bf3f974c_.py index a48bc3bfb..ded8a2435 100644 --- a/anitya/db/migrations/versions/ac10bf3f974c_.py +++ b/anitya/db/migrations/versions/ac10bf3f974c_.py @@ -6,8 +6,8 @@ """ # revision identifiers, used by Alembic. -revision = 'ac10bf3f974c' -down_revision = ('c8735fa14a0a', '7a8c4aa92678') +revision = "ac10bf3f974c" +down_revision = ("c8735fa14a0a", "7a8c4aa92678") def upgrade(): diff --git a/anitya/db/migrations/versions/b13662e5d288_add_admin_flag.py b/anitya/db/migrations/versions/b13662e5d288_add_admin_flag.py index a5bafeb32..587fc1640 100644 --- a/anitya/db/migrations/versions/b13662e5d288_add_admin_flag.py +++ b/anitya/db/migrations/versions/b13662e5d288_add_admin_flag.py @@ -10,21 +10,15 @@ # revision identifiers, used by Alembic. -revision = 'b13662e5d288' -down_revision = 'ac10bf3f974c' +revision = "b13662e5d288" +down_revision = "ac10bf3f974c" def upgrade(): """ Add 'admin' flag to users table. """ - op.add_column( - 'users', - sa.Column( - 'admin', - sa.Boolean, - default=False) - ) + op.add_column("users", sa.Column("admin", sa.Boolean, default=False)) def downgrade(): """ Drop 'admin' flag from users table. """ - op.drop_column('users', 'admin') + op.drop_column("users", "admin") diff --git a/anitya/db/migrations/versions/b9201d816075_remove_the_backends_and_ecosystems_.py b/anitya/db/migrations/versions/b9201d816075_remove_the_backends_and_ecosystems_.py index f2cf2716a..0bc4f4bf9 100644 --- a/anitya/db/migrations/versions/b9201d816075_remove_the_backends_and_ecosystems_.py +++ b/anitya/db/migrations/versions/b9201d816075_remove_the_backends_and_ecosystems_.py @@ -13,28 +13,29 @@ from anitya.lib import plugins # revision identifiers, used by Alembic. -revision = 'b9201d816075' -down_revision = '9c29da0af3af' +revision = "b9201d816075" +down_revision = "9c29da0af3af" def upgrade(): """Drop the Backends and Ecosystems tables and remove foreign keys.""" - op.drop_constraint(u'projects_backend_fkey', 'projects', type_='foreignkey') - op.drop_constraint(u'FK_ECOSYSTEM_FOR_PROJECT', 'projects', type_='foreignkey') + op.drop_constraint(u"projects_backend_fkey", "projects", type_="foreignkey") + op.drop_constraint(u"FK_ECOSYSTEM_FOR_PROJECT", "projects", type_="foreignkey") op.create_index( - op.f('ix_projects_ecosystem_name'), 'projects', ['ecosystem_name'], unique=False) - op.drop_table('ecosystems') - op.drop_table('backends') + op.f("ix_projects_ecosystem_name"), "projects", ["ecosystem_name"], unique=False + ) + op.drop_table("ecosystems") + op.drop_table("backends") def downgrade(): """Restore the Backends and Ecosystems tables.""" - op.drop_index(op.f('ix_projects_ecosystem_name'), table_name='projects') + op.drop_index(op.f("ix_projects_ecosystem_name"), table_name="projects") op.create_table( - 'backends', - sa.Column('name', sa.VARCHAR(length=200), autoincrement=False, nullable=False), - sa.PrimaryKeyConstraint('name', name=u'backends_pkey'), - postgresql_ignore_search_path=False + "backends", + sa.Column("name", sa.VARCHAR(length=200), autoincrement=False, nullable=False), + sa.PrimaryKeyConstraint("name", name=u"backends_pkey"), + postgresql_ignore_search_path=False, ) # We have to populate the backends table before we can add the ecosystems # table with its foreign key constraint. @@ -42,44 +43,50 @@ def downgrade(): op.execute("INSERT INTO backends (name) VALUES ('{}');".format(backend.name)) op.create_table( - 'ecosystems', - sa.Column('name', sa.VARCHAR(length=200), autoincrement=False, nullable=False), + "ecosystems", + sa.Column("name", sa.VARCHAR(length=200), autoincrement=False, nullable=False), sa.Column( - 'default_backend_name', + "default_backend_name", sa.VARCHAR(length=200), autoincrement=False, - nullable=True + nullable=True, ), sa.ForeignKeyConstraint( - ['default_backend_name'], - [u'backends.name'], - name=u'ecosystems_default_backend_name_fkey', - onupdate=u'CASCADE', - ondelete=u'CASCADE' + ["default_backend_name"], + [u"backends.name"], + name=u"ecosystems_default_backend_name_fkey", + onupdate=u"CASCADE", + ondelete=u"CASCADE", + ), + sa.PrimaryKeyConstraint("name", name=u"ecosystems_pkey"), + sa.UniqueConstraint( + "default_backend_name", name=u"ecosystems_default_backend_name_key" ), - sa.PrimaryKeyConstraint('name', name=u'ecosystems_pkey'), - sa.UniqueConstraint('default_backend_name', name=u'ecosystems_default_backend_name_key') ) for ecosystem in plugins.ECOSYSTEM_PLUGINS.get_plugins(): - op.execute(""" + op.execute( + """ INSERT INTO ecosystems (name, default_backend_name) VALUES ('{name}', '{default}');""".format( - name=ecosystem.name, default=ecosystem.default_backend)) + name=ecosystem.name, default=ecosystem.default_backend + ) + ) op.create_foreign_key( - u'FK_ECOSYSTEM_FOR_PROJECT', - 'projects', - 'ecosystems', - ['ecosystem_name'], - ['name'], - onupdate=u'CASCADE', - ondelete=u'SET NULL' + u"FK_ECOSYSTEM_FOR_PROJECT", + "projects", + "ecosystems", + ["ecosystem_name"], + ["name"], + onupdate=u"CASCADE", + ondelete=u"SET NULL", ) op.create_foreign_key( - u'projects_backend_fkey', - 'projects', 'backends', - ['backend'], - ['name'], - onupdate=u'CASCADE', - ondelete=u'CASCADE' + u"projects_backend_fkey", + "projects", + "backends", + ["backend"], + ["name"], + onupdate=u"CASCADE", + ondelete=u"CASCADE", ) diff --git a/anitya/db/migrations/versions/c8735fa14a0a_add_cascade_delete.py b/anitya/db/migrations/versions/c8735fa14a0a_add_cascade_delete.py index 52273516d..b93afedce 100644 --- a/anitya/db/migrations/versions/c8735fa14a0a_add_cascade_delete.py +++ b/anitya/db/migrations/versions/c8735fa14a0a_add_cascade_delete.py @@ -9,16 +9,13 @@ # revision identifiers, used by Alembic. -revision = 'c8735fa14a0a' -down_revision = '34b9bb5fa388' +revision = "c8735fa14a0a" +down_revision = "34b9bb5fa388" def upgrade(): - ''' Rename column `distro` in packages table. ''' - op.alter_column( - 'packages', - 'distro', - new_column_name='distro_name') + """ Rename column `distro` in packages table. """ + op.alter_column("packages", "distro", new_column_name="distro_name") def downgrade(): diff --git a/anitya/db/migrations/versions/feeaa70ead67_social_authentication_table.py b/anitya/db/migrations/versions/feeaa70ead67_social_authentication_table.py index 7450f446b..2b0a6a505 100644 --- a/anitya/db/migrations/versions/feeaa70ead67_social_authentication_table.py +++ b/anitya/db/migrations/versions/feeaa70ead67_social_authentication_table.py @@ -32,8 +32,8 @@ # revision identifiers, used by Alembic. -revision = 'feeaa70ead67' -down_revision = 'a52d2fe99d4f' +revision = "feeaa70ead67" +down_revision = "a52d2fe99d4f" class GUID(TypeDecorator): @@ -42,6 +42,7 @@ class GUID(TypeDecorator): If PostgreSQL is being used, use its native UUID type, otherwise use a CHAR(32) type. """ + impl = CHAR def load_dialect_impl(self, dialect): @@ -55,7 +56,7 @@ def load_dialect_impl(self, dialect): sqlalchemy.types.TypeEngine: Either a PostgreSQL UUID or a CHAR(32) on other dialects. """ - if dialect.name == 'postgresql': + if dialect.name == "postgresql": return dialect.type_descriptor(UUID()) else: return dialect.type_descriptor(CHAR(32)) @@ -76,7 +77,7 @@ def process_bind_param(self, value, dialect): """ if value is None: return value - elif dialect.name == 'postgresql': + elif dialect.name == "postgresql": return str(value) else: if not isinstance(value, uuid.UUID): @@ -105,72 +106,82 @@ def process_result_value(self, value, dialect): def upgrade(): """Create the tables necessary for the python-social-auth library.""" op.create_table( - 'social_auth_association', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('server_url', sa.String(length=255), nullable=True), - sa.Column('handle', sa.String(length=255), nullable=True), - sa.Column('secret', sa.String(length=255), nullable=True), - sa.Column('issued', sa.Integer(), nullable=True), - sa.Column('lifetime', sa.Integer(), nullable=True), - sa.Column('assoc_type', sa.String(length=64), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('server_url', 'handle') + "social_auth_association", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("server_url", sa.String(length=255), nullable=True), + sa.Column("handle", sa.String(length=255), nullable=True), + sa.Column("secret", sa.String(length=255), nullable=True), + sa.Column("issued", sa.Integer(), nullable=True), + sa.Column("lifetime", sa.Integer(), nullable=True), + sa.Column("assoc_type", sa.String(length=64), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("server_url", "handle"), ) op.create_table( - 'social_auth_code', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('email', sa.String(length=200), nullable=True), - sa.Column('code', sa.String(length=32), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('code', 'email') + "social_auth_code", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("email", sa.String(length=200), nullable=True), + sa.Column("code", sa.String(length=32), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("code", "email"), + ) + op.create_index( + op.f("ix_social_auth_code_code"), "social_auth_code", ["code"], unique=False ) - op.create_index(op.f('ix_social_auth_code_code'), 'social_auth_code', ['code'], unique=False) op.create_table( - 'social_auth_nonce', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('server_url', sa.String(length=255), nullable=True), - sa.Column('timestamp', sa.Integer(), nullable=True), - sa.Column('salt', sa.String(length=40), nullable=True), - sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('server_url', 'timestamp', 'salt') + "social_auth_nonce", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("server_url", sa.String(length=255), nullable=True), + sa.Column("timestamp", sa.Integer(), nullable=True), + sa.Column("salt", sa.String(length=40), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("server_url", "timestamp", "salt"), ) op.create_table( - 'social_auth_partial', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('token', sa.String(length=32), nullable=True), - sa.Column('data', storage.JSONType(), nullable=True), - sa.Column('next_step', sa.Integer(), nullable=True), - sa.Column('backend', sa.String(length=32), nullable=True), - sa.PrimaryKeyConstraint('id') + "social_auth_partial", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("token", sa.String(length=32), nullable=True), + sa.Column("data", storage.JSONType(), nullable=True), + sa.Column("next_step", sa.Integer(), nullable=True), + sa.Column("backend", sa.String(length=32), nullable=True), + sa.PrimaryKeyConstraint("id"), ) op.create_index( - op.f('ix_social_auth_partial_token'), 'social_auth_partial', ['token'], unique=False) + op.f("ix_social_auth_partial_token"), + "social_auth_partial", + ["token"], + unique=False, + ) op.create_table( - 'social_auth_usersocialauth', - sa.Column('id', sa.Integer(), nullable=False), - sa.Column('provider', sa.String(length=32), nullable=True), - sa.Column('extra_data', storage.JSONType(), nullable=True), - sa.Column('uid', sa.String(length=255), nullable=True), - sa.Column('user_id', GUID(), nullable=False), - sa.ForeignKeyConstraint(['user_id'], [u'users.id'], ), - sa.PrimaryKeyConstraint('id') + "social_auth_usersocialauth", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("provider", sa.String(length=32), nullable=True), + sa.Column("extra_data", storage.JSONType(), nullable=True), + sa.Column("uid", sa.String(length=255), nullable=True), + sa.Column("user_id", GUID(), nullable=False), + sa.ForeignKeyConstraint(["user_id"], [u"users.id"]), + sa.PrimaryKeyConstraint("id"), ) op.create_index( - op.f('ix_social_auth_usersocialauth_user_id'), - 'social_auth_usersocialauth', - ['user_id'], - unique=False + op.f("ix_social_auth_usersocialauth_user_id"), + "social_auth_usersocialauth", + ["user_id"], + unique=False, ) def downgrade(): """Drop the tables necessary for the python-social-auth library.""" op.drop_index( - op.f('ix_social_auth_usersocialauth_user_id'), table_name='social_auth_usersocialauth') - op.drop_table('social_auth_usersocialauth') - op.drop_index(op.f('ix_social_auth_partial_token'), table_name='social_auth_partial') - op.drop_table('social_auth_partial') - op.drop_table('social_auth_nonce') - op.drop_index(op.f('ix_social_auth_code_code'), table_name='social_auth_code') - op.drop_table('social_auth_code') - op.drop_table('social_auth_association') + op.f("ix_social_auth_usersocialauth_user_id"), + table_name="social_auth_usersocialauth", + ) + op.drop_table("social_auth_usersocialauth") + op.drop_index( + op.f("ix_social_auth_partial_token"), table_name="social_auth_partial" + ) + op.drop_table("social_auth_partial") + op.drop_table("social_auth_nonce") + op.drop_index(op.f("ix_social_auth_code_code"), table_name="social_auth_code") + op.drop_table("social_auth_code") + op.drop_table("social_auth_association") diff --git a/anitya/db/models.py b/anitya/db/models.py index 91b3b5e9f..695e2cf0e 100644 --- a/anitya/db/models.py +++ b/anitya/db/models.py @@ -24,6 +24,7 @@ except ImportError: # pragma: no cover # Fall back to random with os.urandom import random + random = random.SystemRandom() random_choice = random.choice import datetime @@ -52,8 +53,8 @@ def _paginate_query(query, page): - ''' Paginate a given query to returned the specified page (if any). - ''' + """ Paginate a given query to returned the specified page (if any). + """ if page: try: page = int(page) @@ -69,12 +70,12 @@ def _paginate_query(query, page): class Distro(Base): - __tablename__ = 'distros' + __tablename__ = "distros" name = sa.Column(sa.String(200), primary_key=True) def __init__(self, name): - ''' Constructor. ''' + """ Constructor. """ self.name = name def __json__(self): @@ -82,9 +83,7 @@ def __json__(self): @classmethod def by_name(cls, session, name): - query = session.query( - cls - ).filter( + query = session.query(cls).filter( sa.func.lower(cls.name) == sa.func.lower(name) ) @@ -105,20 +104,17 @@ def all(cls, session, page=None, count=False): @classmethod def search(cls, session, pattern, page=None, count=False): - ''' Search the distribuutions by their name ''' + """ Search the distribuutions by their name """ - if '*' in pattern: - pattern = pattern.replace('*', '%') + if "*" in pattern: + pattern = pattern.replace("*", "%") - query = session.query( - cls - ).filter( - sa.or_( - sa.func.lower(cls.name).like(sa.func.lower(pattern)), - ) - ).order_by( - cls.name - ).distinct() + query = ( + session.query(cls) + .filter(sa.or_(sa.func.lower(cls.name).like(sa.func.lower(pattern)))) + .order_by(cls.name) + .distinct() + ) query = _paginate_query(query, page) @@ -131,55 +127,45 @@ def search(cls, session, pattern, page=None, count=False): def get_or_create(cls, session, name): distro = cls.by_name(session, name) if not distro: - distro = cls( - name=name - ) + distro = cls(name=name) session.add(distro) session.flush() return distro class Packages(Base): - __tablename__ = 'packages' + __tablename__ = "packages" id = sa.Column(sa.Integer, primary_key=True) distro_name = sa.Column( sa.String(200), - sa.ForeignKey( - "distros.name", - ondelete="cascade", - onupdate="cascade")) + sa.ForeignKey("distros.name", ondelete="cascade", onupdate="cascade"), + ) project_id = sa.Column( - sa.Integer, - sa.ForeignKey( - "projects.id", - ondelete="cascade", - onupdate="cascade") + sa.Integer, sa.ForeignKey("projects.id", ondelete="cascade", onupdate="cascade") ) package_name = sa.Column(sa.String(200)) - __table_args__ = ( - sa.UniqueConstraint('distro_name', 'package_name'), - ) + __table_args__ = (sa.UniqueConstraint("distro_name", "package_name"),) project = sa.orm.relationship( - 'Project', backref=sa.orm.backref('package', cascade='all, delete-orphan') + "Project", backref=sa.orm.backref("package", cascade="all, delete-orphan") ) distro = sa.orm.relationship( - 'Distro', backref=sa.orm.backref('package', cascade='all, delete-orphan') + "Distro", backref=sa.orm.backref("package", cascade="all, delete-orphan") ) def __repr__(self): - return '' % ( - self.project_id, self.distro_name, self.package_name) + return "" % ( + self.project_id, + self.distro_name, + self.package_name, + ) def __json__(self): - return dict( - package_name=self.package_name, - distro=self.distro_name, - ) + return dict(package_name=self.package_name, distro=self.distro_name) @classmethod def by_id(cls, session, pkg_id): @@ -187,25 +173,20 @@ def by_id(cls, session, pkg_id): @classmethod def get(cls, session, project_id, distro_name, package_name): - query = session.query( - cls - ).filter( - cls.project_id == project_id - ).filter( - sa.func.lower(cls.distro_name) == sa.func.lower(distro_name) - ).filter( - cls.package_name == package_name + query = ( + session.query(cls) + .filter(cls.project_id == project_id) + .filter(sa.func.lower(cls.distro_name) == sa.func.lower(distro_name)) + .filter(cls.package_name == package_name) ) return query.first() @classmethod def by_package_name_distro(cls, session, package_name, distro_name): - query = session.query( - cls - ).filter( - cls.package_name == package_name - ).filter( - sa.func.lower(cls.distro_name) == sa.func.lower(distro_name) + query = ( + session.query(cls) + .filter(cls.package_name == package_name) + .filter(sa.func.lower(cls.distro_name) == sa.func.lower(distro_name)) ) return query.first() @@ -244,13 +225,14 @@ class Project(Base): If this is null, a default will be used. See the :mod:`anitya.lib.versions` documentation for more information. """ - __tablename__ = 'projects' + + __tablename__ = "projects" id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.String(200), nullable=False, index=True) homepage = sa.Column(sa.String(200), nullable=False) - backend = sa.Column(sa.String(200), default='custom') + backend = sa.Column(sa.String(200), default="custom") ecosystem_name = sa.Column(sa.String(200), nullable=False, index=True) version_url = sa.Column(sa.String(200), nullable=True) regex = sa.Column(sa.String(200), nullable=True) @@ -262,24 +244,28 @@ class Project(Base): logs = sa.Column(sa.Text) check_successful = sa.Column(sa.Boolean, default=None, index=True) - last_check = sa.Column(sa.TIMESTAMP(timezone=True), - default=lambda: arrow.utcnow().datetime, index=True) - next_check = sa.Column(sa.TIMESTAMP(timezone=True), - default=lambda: arrow.utcnow().datetime, index=True) + last_check = sa.Column( + sa.TIMESTAMP(timezone=True), default=lambda: arrow.utcnow().datetime, index=True + ) + next_check = sa.Column( + sa.TIMESTAMP(timezone=True), default=lambda: arrow.utcnow().datetime, index=True + ) - updated_on = sa.Column(sa.DateTime, server_default=sa.func.now(), - onupdate=sa.func.current_timestamp()) + updated_on = sa.Column( + sa.DateTime, server_default=sa.func.now(), onupdate=sa.func.current_timestamp() + ) created_on = sa.Column(sa.DateTime, default=datetime.datetime.utcnow) - packages = sa.orm.relationship('Packages', cascade='all, delete-orphan') + packages = sa.orm.relationship("Packages", cascade="all, delete-orphan") __table_args__ = ( - sa.UniqueConstraint('name', 'homepage'), - sa.UniqueConstraint('name', 'ecosystem_name', - name="UNIQ_PROJECT_NAME_PER_ECOSYSTEM"), + sa.UniqueConstraint("name", "homepage"), + sa.UniqueConstraint( + "name", "ecosystem_name", name="UNIQ_PROJECT_NAME_PER_ECOSYSTEM" + ), ) - @validates('backend') + @validates("backend") def validate_backend(self, key, value): if value not in BACKEND_PLUGINS.get_plugin_names(): raise ValueError('Backend "{}" is not supported.'.format(value)) @@ -287,11 +273,11 @@ def validate_backend(self, key, value): @property def versions(self): - ''' Return list of all versions stored, sorted from newest to oldest. + """ Return list of all versions stored, sorted from newest to oldest. Returns: :obj:`list` of :obj:`str`: List of versions - ''' + """ sorted_versions = self.get_sorted_version_objects() return [str(v) for v in sorted_versions] @@ -307,22 +293,25 @@ def create_version_objects(self, versions): `self.version_class`. """ version_class = self.get_version_class() - versions = sorted([ - version_class( - version=version, prefix=self.version_prefix, - created_on=datetime.datetime.utcnow() - ) - for version in versions - ]) + versions = sorted( + [ + version_class( + version=version, + prefix=self.version_prefix, + created_on=datetime.datetime.utcnow(), + ) + for version in versions + ] + ) return versions def get_version_url(self): - ''' Returns full version url, which is used by backend. + """ Returns full version url, which is used by backend. Returns: str: Version url or empty string if backend is not specified - ''' + """ if not self.backend: return "" @@ -330,16 +319,17 @@ def get_version_url(self): return backend.get_version_url(self) def get_sorted_version_objects(self): - ''' Return list of all version objects stored, sorted from newest to oldest. + """ Return list of all version objects stored, sorted from newest to oldest. Returns: :obj:`list` of :obj:`anitya.db.models.ProjectVersion`: List of version objects - ''' + """ version_class = self.get_version_class() versions = [ version_class( - version=v_obj.version, prefix=self.version_prefix, - created_on=v_obj.created_on + version=v_obj.version, + prefix=self.version_prefix, + created_on=v_obj.created_on, ) for v_obj in self.versions_obj ] @@ -379,7 +369,7 @@ def get_version_class(self): return VERSION_PLUGINS.get_plugin(version_scheme) def __repr__(self): - return '' % (self.name, self.homepage) + return "" % (self.name, self.homepage) def __json__(self, detailed=False): output = dict( @@ -391,17 +381,21 @@ def __json__(self, detailed=False): version_url=self.version_url, version=self.latest_version, versions=self.versions, - created_on=time.mktime(self.created_on.timetuple()) if self.created_on else None, - updated_on=time.mktime(self.updated_on.timetuple()) if self.updated_on else None, + created_on=time.mktime(self.created_on.timetuple()) + if self.created_on + else None, + updated_on=time.mktime(self.updated_on.timetuple()) + if self.updated_on + else None, ecosystem=self.ecosystem_name, ) if detailed: - output['packages'] = [pkg.__json__() for pkg in self.packages] + output["packages"] = [pkg.__json__() for pkg in self.packages] return output @classmethod - def get_or_create(cls, session, name, homepage, backend='custom'): + def get_or_create(cls, session, name, homepage, backend="custom"): project = cls.by_name_and_homepage(session, name, homepage) if not project: project = cls(name=name, homepage=homepage, backend=backend) @@ -425,12 +419,8 @@ def by_homepage(cls, session, homepage): @classmethod def by_name_and_homepage(cls, session, name, homepage): - query = session.query( - cls - ).filter( - cls.name == name - ).filter( - cls.homepage == homepage + query = ( + session.query(cls).filter(cls.name == name).filter(cls.homepage == homepage) ) return query.first() @@ -445,11 +435,7 @@ def by_name_and_ecosystem(cls, session, name, ecosystem): @classmethod def all(cls, session, page=None, count=False): - query = session.query( - Project - ).order_by( - sa.func.lower(Project.name) - ) + query = session.query(Project).order_by(sa.func.lower(Project.name)) query = _paginate_query(query, page) @@ -460,14 +446,11 @@ def all(cls, session, page=None, count=False): @classmethod def by_distro(cls, session, distro, page=None, count=False): - query = session.query( - Project - ).filter( - Project.id == Packages.project_id - ).filter( - sa.func.lower(Packages.distro) == sa.func.lower(distro) - ).order_by( - sa.func.lower(Project.name) + query = ( + session.query(Project) + .filter(Project.id == Packages.project_id) + .filter(sa.func.lower(Packages.distro) == sa.func.lower(distro)) + .order_by(sa.func.lower(Project.name)) ) query = _paginate_query(query, page) @@ -479,9 +462,9 @@ def by_distro(cls, session, distro, page=None, count=False): @classmethod def updated( - cls, session, status='updated', name=None, log=None, - page=None, count=False): - ''' Method used to retrieve projects according to their logs and + cls, session, status="updated", name=None, log=None, page=None, count=False + ): + """ Method used to retrieve projects according to their logs and how they performed at the last cron job. :kwarg status: used to filter the projects based on how they @@ -494,62 +477,51 @@ def updated( :kwarg count: A boolean used to return either the list of entries matching the criterias or just the COUNT of entries - ''' + """ - query = session.query( - Project - ).order_by( - sa.func.lower(Project.name) - ) + query = session.query(Project).order_by(sa.func.lower(Project.name)) - if status == 'updated': + if status == "updated": query = query.filter( - Project.logs.isnot(None), - Project.logs == 'Version retrieved correctly', + Project.logs.isnot(None), Project.logs == "Version retrieved correctly" ) - elif status == 'failed': + elif status == "failed": query = query.filter( Project.logs.isnot(None), - Project.logs != 'Version retrieved correctly', - ~Project.logs.ilike('Something strange occured%'), + Project.logs != "Version retrieved correctly", + ~Project.logs.ilike("Something strange occured%"), ) - elif status == 'odd': + elif status == "odd": query = query.filter( Project.logs.isnot(None), - Project.logs != 'Version retrieved correctly', - Project.logs.ilike('Something strange occured%'), + Project.logs != "Version retrieved correctly", + Project.logs.ilike("Something strange occured%"), ) - elif status == 'new': - query = query.filter( - Project.logs.is_(None), - ) - elif status == 'never_updated': + elif status == "new": + query = query.filter(Project.logs.is_(None)) + elif status == "never_updated": query = query.filter( Project.logs.isnot(None), - Project.logs != 'Version retrieved correctly', + Project.logs != "Version retrieved correctly", Project.latest_version.is_(None), ) if name: - if '*' in name: - name = name.replace('*', '%') + if "*" in name: + name = name.replace("*", "%") else: - name = '%' + name + '%' + name = "%" + name + "%" - query = query.filter( - Project.name.ilike(name), - ) + query = query.filter(Project.name.ilike(name)) if log: - if '*' in log: - log = log.replace('*', '%') + if "*" in log: + log = log.replace("*", "%") else: - log = '%' + log + '%' + log = "%" + log + "%" - query = query.filter( - Project.logs.ilike(log), - ) + query = query.filter(Project.logs.ilike(log)) query = _paginate_query(query, page) @@ -560,53 +532,33 @@ def updated( @classmethod def search(cls, session, pattern, distro=None, page=None, count=False): - ''' Search the projects by their name or package name ''' + """ Search the projects by their name or package name """ - query1 = session.query( - cls - ) + query1 = session.query(cls) if pattern: - pattern = pattern.replace('_', r'\_') - if '*' in pattern: - pattern = pattern.replace('*', '%') - if '%' in pattern: - query1 = query1.filter( - Project.name.ilike(pattern) - ) + pattern = pattern.replace("_", r"\_") + if "*" in pattern: + pattern = pattern.replace("*", "%") + if "%" in pattern: + query1 = query1.filter(Project.name.ilike(pattern)) else: - query1 = query1.filter( - Project.name == pattern - ) + query1 = query1.filter(Project.name == pattern) - query2 = session.query( - cls - ).filter( - Project.id == Packages.project_id - ) + query2 = session.query(cls).filter(Project.id == Packages.project_id) if pattern: - if '%' in pattern: - query2 = query2.filter( - Packages.package_name.ilike(pattern) - ) + if "%" in pattern: + query2 = query2.filter(Packages.package_name.ilike(pattern)) else: - query2 = query2.filter( - Packages.package_name == pattern - ) + query2 = query2.filter(Packages.package_name == pattern) if distro is not None: - query1 = query1.filter( - Project.id == Packages.project_id - ).filter( + query1 = query1.filter(Project.id == Packages.project_id).filter( sa.func.lower(Packages.distro) == sa.func.lower(distro) ) - query = query1.distinct().union( - query2.distinct() - ).order_by( - cls.name - ) + query = query1.distinct().union(query2.distinct()).order_by(cls.name) query = _paginate_query(query, page) @@ -617,51 +569,44 @@ def search(cls, session, pattern, distro=None, page=None, count=False): class ProjectVersion(Base): - __tablename__ = 'projects_versions' + __tablename__ = "projects_versions" project_id = sa.Column( sa.Integer, - sa.ForeignKey( - "projects.id", - ondelete="cascade", - onupdate="cascade"), + sa.ForeignKey("projects.id", ondelete="cascade", onupdate="cascade"), primary_key=True, ) version = sa.Column(sa.String(50), primary_key=True) created_on = sa.Column(sa.DateTime, default=datetime.datetime.utcnow) project = sa.orm.relationship( - 'Project', backref=sa.orm.backref('versions_obj', cascade='all, delete-orphan') + "Project", backref=sa.orm.backref("versions_obj", cascade="all, delete-orphan") ) class ProjectFlag(Base): - __tablename__ = 'projects_flags' + __tablename__ = "projects_flags" id = sa.Column(sa.Integer, primary_key=True) project_id = sa.Column( - sa.Integer, - sa.ForeignKey( - "projects.id", - ondelete="cascade", - onupdate="cascade") + sa.Integer, sa.ForeignKey("projects.id", ondelete="cascade", onupdate="cascade") ) reason = sa.Column(sa.Text, nullable=False) user = sa.Column(sa.String(200), index=True, nullable=False) - state = sa.Column(sa.String(50), default='open', nullable=False) + state = sa.Column(sa.String(50), default="open", nullable=False) created_on = sa.Column(sa.DateTime, default=datetime.datetime.utcnow) - updated_on = sa.Column(sa.DateTime, server_default=sa.func.now(), - onupdate=sa.func.current_timestamp()) + updated_on = sa.Column( + sa.DateTime, server_default=sa.func.now(), onupdate=sa.func.current_timestamp() + ) project = sa.orm.relationship( - 'Project', backref=sa.orm.backref('flags', cascade='all, delete-orphan') + "Project", backref=sa.orm.backref("flags", cascade="all, delete-orphan") ) def __repr__(self): - return '' % (self.project.name, self.user, - self.state) + return "" % (self.project.name, self.user, self.state) def __json__(self, detailed=False): output = dict( @@ -673,21 +618,28 @@ def __json__(self, detailed=False): updated_on=time.mktime(self.updated_on.timetuple()), ) if detailed: - output['reason'] = self.reason + output["reason"] = self.reason return output @classmethod def all(cls, session, page=None, count=False): - query = session.query( - ProjectFlag - ).order_by(ProjectFlag.created_on) + query = session.query(ProjectFlag).order_by(ProjectFlag.created_on) return query.all() @classmethod - def search(cls, session, project_name=None, from_date=None, user=None, - state=None, limit=None, offset=None, count=False): + def search( + cls, + session, + project_name=None, + from_date=None, + user=None, + state=None, + limit=None, + offset=None, + count=False, + ): """ Return the list of the last Flag entries present in the database. :arg cls: the class object @@ -702,14 +654,10 @@ def search(cls, session, project_name=None, from_date=None, user=None, if true, returns the data if false (default). """ - query = session.query( - cls - ) + query = session.query(cls) if project_name: - query = query.filter( - cls.project_id == Project.id - ) .filter( + query = query.filter(cls.project_id == Project.id).filter( Project.name == project_name ) @@ -736,29 +684,23 @@ def search(cls, session, project_name=None, from_date=None, user=None, @classmethod def get(cls, session, flag_id): - query = session.query( - cls - ).filter( - cls.id == flag_id) + query = session.query(cls).filter(cls.id == flag_id) return query.first() class Run(Base): - __tablename__ = 'runs' + __tablename__ = "runs" status = sa.Column(sa.String(20), primary_key=True) created_on = sa.Column( - sa.DateTime, default=datetime.datetime.utcnow, primary_key=True) + sa.DateTime, default=datetime.datetime.utcnow, primary_key=True + ) @classmethod def last_entry(cls, session): - ''' Return the last log about the cron run. ''' + """ Return the last log about the cron run. """ - query = session.query( - cls - ).order_by( - cls.created_on.desc() - ) + query = session.query(cls).order_by(cls.created_on.desc()) return query.first() @@ -768,6 +710,7 @@ class GUID(TypeDecorator): If PostgreSQL is being used, use its native UUID type, otherwise use a CHAR(32) type. """ + impl = CHAR def load_dialect_impl(self, dialect): @@ -781,7 +724,7 @@ def load_dialect_impl(self, dialect): sqlalchemy.types.TypeEngine: Either a PostgreSQL UUID or a CHAR(32) on other dialects. """ - if dialect.name == 'postgresql': + if dialect.name == "postgresql": return dialect.type_descriptor(UUID()) else: return dialect.type_descriptor(CHAR(32)) @@ -802,7 +745,7 @@ def process_bind_param(self, value, dialect): """ if value is None: return value - elif dialect.name == 'postgresql': + elif dialect.name == "postgresql": return str(value) else: if not isinstance(value, uuid.UUID): @@ -846,7 +789,8 @@ class User(Base): social_auth (sqlalchemy.orm.dynamic.AppenderQuery): The list of :class:`social_flask_sqlalchemy.models.UserSocialAuth` entries for this user. """ - __tablename__ = 'users' + + __tablename__ = "users" id = sa.Column(GUID, primary_key=True, default=uuid.uuid4) # SMTP says 256 is the maximum length of a path: @@ -866,7 +810,7 @@ def is_admin(self): bool: True if the user is an administrator. """ if not self.admin: - if six.text_type(self.id) in anitya_config.get('ANITYA_WEB_ADMINS', []): + if six.text_type(self.id) in anitya_config.get("ANITYA_WEB_ADMINS", []): self.admin = True return self.admin @@ -954,7 +898,7 @@ def _api_token_generator(charset=string.ascii_letters + string.digits, length=40 Returns: str: The API token as a unicode string. """ - return u''.join(random_choice(charset) for __ in range(length)) + return u"".join(random_choice(charset) for __ in range(length)) class ApiToken(Base): @@ -969,14 +913,14 @@ class ApiToken(Base): user (User): The user this API token is associated with. """ - __tablename__ = 'tokens' + __tablename__ = "tokens" token = sa.Column(sa.String(40), default=_api_token_generator, primary_key=True) created = sa.Column(sa.DateTime, default=datetime.datetime.utcnow, nullable=False) - user_id = sa.Column(GUID, sa.ForeignKey('users.id'), nullable=False) + user_id = sa.Column(GUID, sa.ForeignKey("users.id"), nullable=False) user = sa.orm.relationship( - 'User', - lazy='joined', - backref=sa.orm.backref('api_tokens', cascade='all, delete-orphan'), + "User", + lazy="joined", + backref=sa.orm.backref("api_tokens", cascade="all, delete-orphan"), ) description = sa.Column(sa.Text, nullable=True) diff --git a/anitya/forms.py b/anitya/forms.py index 1ebfdcf5b..1da3a4085 100644 --- a/anitya/forms.py +++ b/anitya/forms.py @@ -16,33 +16,29 @@ class TokenForm(FlaskForm): description (StringField): The human-readable API token description, useful for users to describe the token's purpose. """ - description = StringField('Token description', [validators.optional()]) + + description = StringField("Token description", [validators.optional()]) class ProjectForm(FlaskForm): - name = StringField('Project name', [validators.DataRequired()]) - homepage = StringField( - 'Homepage', [validators.DataRequired(), validators.URL()]) + name = StringField("Project name", [validators.DataRequired()]) + homepage = StringField("Homepage", [validators.DataRequired(), validators.URL()]) backend = SelectField( - 'Backend', - [validators.DataRequired()], - choices=[(item, item) for item in []] + "Backend", [validators.DataRequired()], choices=[(item, item) for item in []] ) - version_url = StringField('Version URL', [validators.optional()]) - version_prefix = StringField('Version prefix', [validators.optional()]) + version_url = StringField("Version URL", [validators.optional()]) + version_prefix = StringField("Version prefix", [validators.optional()]) version_scheme = SelectField( - 'Version scheme', - [validators.Required()], - choices=[(item, item) for item in []] + "Version scheme", [validators.Required()], choices=[(item, item) for item in []] ) - regex = StringField('Regex', [validators.optional()]) - insecure = BooleanField( - 'Use insecure connection', [validators.optional()]) + regex = StringField("Regex", [validators.optional()]) + insecure = BooleanField("Use insecure connection", [validators.optional()]) - distro = StringField('Distro (optional)', [validators.optional()]) - package_name = StringField('Package (optional)', [validators.optional()]) + distro = StringField("Distro (optional)", [validators.optional()]) + package_name = StringField("Package (optional)", [validators.optional()]) check_release = BooleanField( - 'Check latest release on submit', [validators.optional()]) + "Check latest release on submit", [validators.optional()] + ) def __init__(self, *args, **kwargs): """ Calls the default constructor with the normal argument but @@ -50,44 +46,41 @@ def __init__(self, *args, **kwargs): drop-down list. """ super(ProjectForm, self).__init__(*args, **kwargs) - if 'backends' in kwargs: + if "backends" in kwargs: self.backend.choices = [ - (backend, backend) for backend in sorted(kwargs['backends']) + (backend, backend) for backend in sorted(kwargs["backends"]) ] - if 'version_schemes' in kwargs: + if "version_schemes" in kwargs: self.version_scheme.choices = [ (version_scheme, version_scheme) - for version_scheme in sorted(kwargs['version_schemes']) + for version_scheme in sorted(kwargs["version_schemes"]) ] class FlagProjectForm(FlaskForm): - reason = TextAreaField('Reason for flagging', [validators.DataRequired()]) + reason = TextAreaField("Reason for flagging", [validators.DataRequired()]) class MappingForm(FlaskForm): - distro = SelectField( - 'Distribution', - [validators.DataRequired()], - choices=[]) - package_name = StringField('Package name', [validators.DataRequired()]) + distro = SelectField("Distribution", [validators.DataRequired()], choices=[]) + package_name = StringField("Package name", [validators.DataRequired()]) def __init__(self, *args, **kwargs): """ Calls the default constructor and fill in additional information. """ super(MappingForm, self).__init__(*args, **kwargs) - if 'package' in kwargs: - package = kwargs['package'] + if "package" in kwargs: + package = kwargs["package"] self.distro.data = package.distro self.package_name.data = package.package_name self.version_url.data = package.version_url self.regex.data = package.regex - if 'distros' in kwargs: + if "distros" in kwargs: self.distro.choices = [ (distro, distro) - for distro in sorted(kwargs['distros'], key=lambda s: s.lower()) + for distro in sorted(kwargs["distros"], key=lambda s: s.lower()) ] @@ -96,4 +89,4 @@ class ConfirmationForm(FlaskForm): class DistroForm(FlaskForm): - name = StringField('Distribution name', [validators.DataRequired()]) + name = StringField("Distribution name", [validators.DataRequired()]) diff --git a/anitya/lib/backends/__init__.py b/anitya/lib/backends/__init__.py index de79242aa..e9b39a520 100644 --- a/anitya/lib/backends/__init__.py +++ b/anitya/lib/backends/__init__.py @@ -23,6 +23,7 @@ import re import socket from datetime import timedelta + # sre_constants contains re exceptions import sre_constants import urllib.request as urllib @@ -36,14 +37,14 @@ from anitya.lib.versions import RpmVersion import six -REGEX = anitya_config['DEFAULT_REGEX'] +REGEX = anitya_config["DEFAULT_REGEX"] # Default headers for requests REQUEST_HEADERS = { - 'User-Agent': 'Anitya %s at upstream-monitoring.org' % - pkg_resources.get_distribution('anitya').version, - 'From': anitya_config.get('ADMIN_EMAIL'), - } + "User-Agent": "Anitya %s at upstream-monitoring.org" + % pkg_resources.get_distribution("anitya").version, + "From": anitya_config.get("ADMIN_EMAIL"), +} _log = logging.getLogger(__name__) @@ -54,7 +55,7 @@ class BaseBackend(object): - ''' + """ The base class that all the different backends should extend. Attributes: @@ -73,7 +74,7 @@ class BaseBackend(object): is used. check_interval (`datetime.timedelta`): Interval which is used for periodic checking for new versions. This could be overriden by backend plugin. - ''' + """ name = None examples = None @@ -84,7 +85,7 @@ class BaseBackend(object): @classmethod def expand_subdirs(self, url, glob_char="*"): - ''' Expand dirs containing ``glob_char`` in the given URL with the latest + """ Expand dirs containing ``glob_char`` in the given URL with the latest Example URL: ``https://www.example.com/foo/*/`` The globbing char can be bundled with other characters enclosed within @@ -93,7 +94,7 @@ def expand_subdirs(self, url, glob_char="*"): Code originally from Till Maas as part of `cnucnu `_ - ''' + """ glob_pattern = "/([^/]*%s[^/]*)/" % re.escape(glob_char) glob_match = re.search(glob_pattern, url) if not glob_match: @@ -101,13 +102,13 @@ def expand_subdirs(self, url, glob_char="*"): glob_str = glob_match.group(1) # url until first slash before glob_match - url_prefix = url[0:glob_match.start() + 1] + url_prefix = url[0 : glob_match.start() + 1] # everything after the slash after glob_match - url_suffix = url[glob_match.end():] + url_suffix = url[glob_match.end() :] html_regex = re.compile(r'\bhref\s*=\s*["\']([^"\'/]+)/["\']', re.I) - text_regex = re.compile(r'^d.+\s(\S+)\s*$', re.I | re.M) + text_regex = re.compile(r"^d.+\s(\S+)\s*$", re.I | re.M) if url_prefix != "": resp = self.call_url(url_prefix) @@ -123,8 +124,7 @@ def expand_subdirs(self, url, glob_char="*"): regex = url.startswith("ftp://") and text_regex or html_regex for match in regex.finditer(dir_listing): subdir = match.group(1) - if subdir not in (".", "..") \ - and fnmatch.fnmatch(subdir, glob_str): + if subdir not in (".", "..") and fnmatch.fnmatch(subdir, glob_str): subdirs.append(subdir) if not subdirs: return url @@ -137,7 +137,7 @@ def expand_subdirs(self, url, glob_char="*"): @classmethod def get_version(self, project): # pragma: no cover - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. Attributes: @@ -152,12 +152,12 @@ def get_version(self, project): # pragma: no cover :obj:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ pass @classmethod def get_version_url(cls, project): # pragma: no cover - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -166,12 +166,12 @@ def get_version_url(cls, project): # pragma: no cover Returns: str: url used for version checking - ''' + """ pass @classmethod def get_versions(self, project): # pragma: no cover - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -187,12 +187,12 @@ def get_versions(self, project): # pragma: no cover :obj:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ pass @classmethod def check_feed(self): - ''' Method called to retrieve the latest uploads to a given backend, + """ Method called to retrieve the latest uploads to a given backend, via, for example, RSS or an API. Not all backends may support this. It can be used to look for updates @@ -209,12 +209,12 @@ def check_feed(self): NotImplementedError: If backend does not support batch updates. - ''' + """ raise NotImplementedError() @classmethod def get_ordered_versions(self, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, ordered from the oldest to the newest. Attributes: @@ -229,14 +229,14 @@ def get_ordered_versions(self, project): :obj:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ vlist = self.get_versions(project) sorted_versions = project.create_version_objects(vlist) return [v.version for v in sorted_versions] @classmethod def call_url(self, url, insecure=False): - ''' Dedicated method to query a URL. + """ Dedicated method to query a URL. It is important to use this method as it allows to query them with a defined user-agent header thus informing the projects we are @@ -251,28 +251,29 @@ def call_url(self, url, insecure=False): In case of FTP url it returns binary encoded string otherwise :obj:`requests.Response` object. - ''' + """ headers = REQUEST_HEADERS.copy() - if '*' in url: + if "*" in url: url = self.expand_subdirs(url) - if url.startswith('ftp://') or url.startswith('ftps://'): + if url.startswith("ftp://") or url.startswith("ftps://"): socket.setdefaulttimeout(30) req = urllib.Request(url) - req.add_header('User-Agent', headers['User-Agent']) - req.add_header('From', headers['From']) + req.add_header("User-Agent", headers["User-Agent"]) + req.add_header("From", headers["From"]) try: # Ignore this bandit issue, the url is checked above resp = urllib.urlopen(req) # nosec content = resp.read().decode() except URLError as e: raise AnityaPluginException( - 'Could not call "%s" with error: %s' % ( - url, e.reason)) + 'Could not call "%s" with error: %s' % (url, e.reason) + ) except UnicodeDecodeError: raise AnityaPluginException( - 'FTP response cannot be decoded with UTF-8: %s' % url) + "FTP response cannot be decoded with UTF-8: %s" % url + ) return content @@ -290,28 +291,27 @@ def call_url(self, url, insecure=False): # accident. This can be removed in requests-3.0. if insecure: with requests.Session() as r_session: - resp = r_session.get( - url, headers=headers, timeout=60, verify=False) + resp = r_session.get(url, headers=headers, timeout=60, verify=False) else: - resp = http_session.get( - url, headers=headers, timeout=60, verify=True) + resp = http_session.get(url, headers=headers, timeout=60, verify=True) return resp def get_versions_by_regex(url, regex, project, insecure=False): - ''' For the provided url, return all the version retrieved via the + """ For the provided url, return all the version retrieved via the specified regular expression. - ''' + """ try: req = BaseBackend.call_url(url, insecure=insecure) except Exception as err: - _log.debug('%s ERROR: %s' % (project.name, str(err))) + _log.debug("%s ERROR: %s" % (project.name, str(err))) raise AnityaPluginException( - 'Could not call : "%s" of "%s", with error: %s' % ( - url, project.name, str(err))) + 'Could not call : "%s" of "%s", with error: %s' + % (url, project.name, str(err)) + ) if not isinstance(req, six.string_types): req = req.text @@ -320,16 +320,15 @@ def get_versions_by_regex(url, regex, project, insecure=False): def get_versions_by_regex_for_text(text, url, regex, project): - ''' For the provided text, return all the version retrieved via the + """ For the provided text, return all the version retrieved via the specified regular expression. - ''' + """ try: upstream_versions = list(set(re.findall(regex, text))) except sre_constants.error: # pragma: no cover - raise AnityaPluginException( - "%s: invalid regular expression" % project.name) + raise AnityaPluginException("%s: invalid regular expression" % project.name) for index, version in enumerate(upstream_versions): @@ -341,12 +340,13 @@ def get_versions_by_regex_for_text(text, url, regex, project): if " " in version: raise AnityaPluginException( - "%s: invalid upstream version:>%s< - %s - %s " % ( - project.name, version, url, regex)) + "%s: invalid upstream version:>%s< - %s - %s " + % (project.name, version, url, regex) + ) if len(upstream_versions) == 0: raise AnityaPluginException( "%(name)s: no upstream version found. - %(url)s - " - "%(regex)s" % { - 'name': project.name, 'url': url, 'regex': regex}) + "%(regex)s" % {"name": project.name, "url": url, "regex": regex} + ) return upstream_versions diff --git a/anitya/lib/backends/bitbucket.py b/anitya/lib/backends/bitbucket.py index 4a5d2539c..fa95e34f2 100644 --- a/anitya/lib/backends/bitbucket.py +++ b/anitya/lib/backends/bitbucket.py @@ -16,21 +16,21 @@ class BitBucketBackend(BaseBackend): - ''' The custom class for projects hosted on bitbucket.org + """ The custom class for projects hosted on bitbucket.org This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'BitBucket' + name = "BitBucket" examples = [ - 'https://bitbucket.org/zzzeek/sqlalchemy', - 'https://bitbucket.org/cherrypy/cherrypy', + "https://bitbucket.org/zzzeek/sqlalchemy", + "https://bitbucket.org/cherrypy/cherrypy", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -41,12 +41,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -55,28 +55,25 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url_template = 'https://bitbucket.org/%(version_url)s/' \ - 'downloads?tab=tags' - url = '' + """ + url_template = "https://bitbucket.org/%(version_url)s/" "downloads?tab=tags" + url = "" if project.version_url: - url = project.version_url.replace( - 'https://bitbucket.org/', '') - elif project.homepage.startswith('https://bitbucket.org'): - url = project.homepage.replace( - 'https://bitbucket.org/', '') + url = project.version_url.replace("https://bitbucket.org/", "") + elif project.homepage.startswith("https://bitbucket.org"): + url = project.homepage.replace("https://bitbucket.org/", "") - if url.endswith('/'): + if url.endswith("/"): url = url[:-1] if url: - url = url_template % {'version_url': url} + url = url_template % {"version_url": url} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -88,10 +85,11 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) if not url: raise AnityaPluginException( - 'Project %s was incorrectly set-up' % project.name) + "Project %s was incorrectly set-up" % project.name + ) return get_versions_by_regex(url, REGEX, project) diff --git a/anitya/lib/backends/cpan.py b/anitya/lib/backends/cpan.py index 68ab686d9..2e9b3d415 100644 --- a/anitya/lib/backends/cpan.py +++ b/anitya/lib/backends/cpan.py @@ -20,21 +20,21 @@ class CpanBackend(BaseBackend): - ''' The custom class for projects hosted on CPAN. + """ The custom class for projects hosted on CPAN. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'CPAN (perl)' + name = "CPAN (perl)" examples = [ - 'https://metacpan.org/release/Net-Whois-Raw/', - 'https://metacpan.org/release/SOAP/', + "https://metacpan.org/release/Net-Whois-Raw/", + "https://metacpan.org/release/SOAP/", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -45,12 +45,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -59,15 +59,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://metacpan.org/release/%(name)s/' % { - 'name': project.name} + """ + url = "https://metacpan.org/release/%(name)s/" % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -79,37 +78,37 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = REGEX % {'name': project.name} + regex = REGEX % {"name": project.name} return get_versions_by_regex(url, regex, project) @classmethod def check_feed(cls): - ''' Return a generator over the latest uploads to CPAN + """ Return a generator over the latest uploads to CPAN by querying an RSS feed. - ''' + """ - url = 'https://metacpan.org/feed/recent' + url = "https://metacpan.org/feed/recent" try: response = cls.call_url(url) except Exception: # pragma: no cover - raise AnityaPluginException('Could not contact %s' % url) + raise AnityaPluginException("Could not contact %s" % url) try: root = ET.fromstring(response.text) except ET.ParseError: - raise AnityaPluginException('No XML returned by %s' % url) + raise AnityaPluginException("No XML returned by %s" % url) - for item in root.iter(tag='{http://purl.org/rss/1.0/}item'): - title = item.find('{http://purl.org/rss/1.0/}title') + for item in root.iter(tag="{http://purl.org/rss/1.0/}item"): + title = item.find("{http://purl.org/rss/1.0/}title") try: - name, version = title.text.rsplit('-', 1) + name, version = title.text.rsplit("-", 1) except ValueError: - _log.info('Unable to parse CPAN package %s into a name and version') - homepage = 'https://metacpan.org/release/%s/' % name + _log.info("Unable to parse CPAN package %s into a name and version") + homepage = "https://metacpan.org/release/%s/" % name yield name, homepage, cls.name, version diff --git a/anitya/lib/backends/cran.py b/anitya/lib/backends/cran.py index 9156c39f6..1c082700d 100644 --- a/anitya/lib/backends/cran.py +++ b/anitya/lib/backends/cran.py @@ -47,10 +47,10 @@ class CranBackend(BaseBackend): """The custom class for projects hosted on CRAN.""" - name = 'CRAN (R)' + name = "CRAN (R)" examples = [ - 'https://cran.r-project.org/web/packages/tidyverse/', - 'https://cran.r-project.org/web/packages/devtools/', + "https://cran.r-project.org/web/packages/tidyverse/", + "https://cran.r-project.org/web/packages/devtools/", ] @classmethod @@ -69,32 +69,33 @@ def get_version(cls, project): format. """ - url = 'https://crandb.r-pkg.org/{name}'.format(name=project.name) + url = "https://crandb.r-pkg.org/{name}".format(name=project.name) try: response = cls.call_url(url) except requests.RequestException as e: # pragma: no cover - raise AnityaPluginException('Could not contact {}: {}'.format(url, str(e))) + raise AnityaPluginException("Could not contact {}: {}".format(url, str(e))) if response.status_code != 200: raise AnityaPluginException( - 'Failed to download from {}: {} {}'.format(url, - response.status_code, - response.reason)) + "Failed to download from {}: {} {}".format( + url, response.status_code, response.reason + ) + ) try: data = response.json() except json.JSONDecodeError: # pragma: no cover - raise AnityaPluginException('No JSON returned by {}'.format(url)) + raise AnityaPluginException("No JSON returned by {}".format(url)) - if 'error' in data or 'Version' not in data: # pragma: no cover - raise AnityaPluginException('No versions found at {}'.format(url)) + if "error" in data or "Version" not in data: # pragma: no cover + raise AnityaPluginException("No versions found at {}".format(url)) - return data['Version'] + return data["Version"] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -103,8 +104,8 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://crandb.r-pkg.org/{name}/all'.format(name=project.name) + """ + url = "https://crandb.r-pkg.org/{name}/all".format(name=project.name) return url @@ -129,23 +130,24 @@ def get_versions(cls, project): try: response = cls.call_url(url) except requests.RequestException as e: # pragma: no cover - raise AnityaPluginException('Could not contact {}: {}'.format(url, str(e))) + raise AnityaPluginException("Could not contact {}: {}".format(url, str(e))) if response.status_code != 200: raise AnityaPluginException( - 'Failed to download from {}: {} {}'.format(url, - response.status_code, - response.reason)) + "Failed to download from {}: {} {}".format( + url, response.status_code, response.reason + ) + ) try: data = response.json() except json.JSONDecodeError: # pragma: no cover - raise AnityaPluginException('No JSON returned by {}'.format(url)) + raise AnityaPluginException("No JSON returned by {}".format(url)) - if 'error' in data or 'versions' not in data: # pragma: no cover - raise AnityaPluginException('No versions found at {}'.format(url)) + if "error" in data or "versions" not in data: # pragma: no cover + raise AnityaPluginException("No versions found at {}".format(url)) - return list(data['versions'].keys()) + return list(data["versions"].keys()) @classmethod def check_feed(cls): @@ -165,27 +167,30 @@ def check_feed(cls): format. """ - url = 'https://crandb.r-pkg.org/-/pkgreleases?descending=true&limit=50' + url = "https://crandb.r-pkg.org/-/pkgreleases?descending=true&limit=50" try: response = cls.call_url(url) except requests.RequestException as e: # pragma: no cover - raise AnityaPluginException('Could not contact {}: {}'.format(url, str(e))) + raise AnityaPluginException("Could not contact {}: {}".format(url, str(e))) if response.status_code != 200: # pragma: no cover raise AnityaPluginException( - 'Failed to download from {}: {} {}'.format(url, - response.status_code, - response.reason)) + "Failed to download from {}: {} {}".format( + url, response.status_code, response.reason + ) + ) try: data = response.json() except json.JSONDecodeError: # pragma: no cover - raise AnityaPluginException('No JSON returned by {}'.format(url)) + raise AnityaPluginException("No JSON returned by {}".format(url)) for item in data: - name = item['name'] - package = item['package'] - homepage = package.get('URL', 'https://cran.r-project.org/web/packages/' + name) - version = package['Version'] + name = item["name"] + package = item["package"] + homepage = package.get( + "URL", "https://cran.r-project.org/web/packages/" + name + ) + version = package["Version"] yield name, homepage, cls.name, version diff --git a/anitya/lib/backends/crates.py b/anitya/lib/backends/crates.py index 64783ba30..577c754ca 100644 --- a/anitya/lib/backends/crates.py +++ b/anitya/lib/backends/crates.py @@ -109,11 +109,8 @@ class CratesBackend(BaseBackend): """The crates class for projects hosted on crates.io.""" - name = 'crates.io' - examples = [ - 'https://crates.io/crates/clap', - 'https://crates.io/crates/serde', - ] + name = "crates.io" + examples = ["https://crates.io/crates/clap", "https://crates.io/crates/serde"] @classmethod def _get_versions(cls, project): @@ -153,12 +150,13 @@ def _get_versions(cls, project): req.raise_for_status() data = req.json() except requests.RequestException as e: - raise AnityaPluginException('Could not contact {url}: ' - '{reason!r}'.format(url=url, reason=e)) + raise AnityaPluginException( + "Could not contact {url}: " "{reason!r}".format(url=url, reason=e) + ) except ValueError as e: - raise AnityaPluginException('Failed to decode JSON: {!r}'.format(e)) + raise AnityaPluginException("Failed to decode JSON: {!r}".format(e)) - return data['versions'] + return data["versions"] @classmethod def get_version(cls, project): @@ -176,11 +174,11 @@ def get_version(cls, project): AnityaPluginException: If the URL was unreachable or the response was in an unexpected format. """ - return cls._get_versions(project)[0]['num'] + return cls._get_versions(project)[0]["num"] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -189,8 +187,8 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://crates.io/api/v1/crates/{}/versions'.format(project.name) + """ + url = "https://crates.io/api/v1/crates/{}/versions".format(project.name) return url @@ -210,7 +208,7 @@ def get_versions(cls, project): AnityaPluginException: If the URL was unreachable or the response was in an unexpected format. """ - return [v['num'] for v in cls._get_versions(project)] + return [v["num"] for v in cls._get_versions(project)] @classmethod def get_ordered_versions(cls, project): diff --git a/anitya/lib/backends/custom.py b/anitya/lib/backends/custom.py index 025ac9a35..f30becb73 100644 --- a/anitya/lib/backends/custom.py +++ b/anitya/lib/backends/custom.py @@ -11,31 +11,31 @@ from anitya.lib.backends import BaseBackend, get_versions_by_regex, REGEX -REGEX_ALIASES = { - 'DEFAULT': REGEX, -} +REGEX_ALIASES = {"DEFAULT": REGEX} class CustomBackend(BaseBackend): - ''' The custom class for project having a special hosting. + """ The custom class for project having a special hosting. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'custom' + name = "custom" examples = [ - 'https://subsurface-divelog.org/downloads/', - 'https://www.geany.org/Download/Releases', + "https://subsurface-divelog.org/downloads/", + "https://www.geany.org/Download/Releases", ] - more_info = 'More information in the '\ - 'user-guide.html#regular-expressions' - default_regex = REGEX % {'name': '{project name}'} + more_info = ( + "More information in the " + "user-guide.html#regular-expressions" + ) + default_regex = REGEX % {"name": "{project name}"} @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -46,12 +46,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -60,14 +60,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' + """ url = project.version_url return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -79,15 +79,14 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = REGEX_ALIASES['DEFAULT'] + regex = REGEX_ALIASES["DEFAULT"] if project.regex: regex = REGEX_ALIASES.get(project.regex, project.regex) - if '%(name)' in regex: - regex = regex % {'name': project.name.replace('+', r'\+')} + if "%(name)" in regex: + regex = regex % {"name": project.name.replace("+", r"\+")} - return get_versions_by_regex( - url, regex, project, insecure=project.insecure) + return get_versions_by_regex(url, regex, project, insecure=project.insecure) diff --git a/anitya/lib/backends/debian.py b/anitya/lib/backends/debian.py index 143a696e8..3895d6d2d 100644 --- a/anitya/lib/backends/debian.py +++ b/anitya/lib/backends/debian.py @@ -15,27 +15,27 @@ # _.orig.. So, for example, # reprepro_4.13.1.orig.tar.gz. DEBIAN_REGEX = ( - r'(?i)%(name)s(?:[-_]?(?:minsrc|src|source))?[-_]([^-/_\s]+?)(?:[-_]' - r'(?:minsrc|src|source|asc))?\.(?:orig\.)?(?:tar|t[bglx]z|tbz2|zip)' + r"(?i)%(name)s(?:[-_]?(?:minsrc|src|source))?[-_]([^-/_\s]+?)(?:[-_]" + r"(?:minsrc|src|source|asc))?\.(?:orig\.)?(?:tar|t[bglx]z|tbz2|zip)" ) class DebianBackend(BaseBackend): - ''' The custom class for projects hosted on ftp.debian.org. + """ The custom class for projects hosted on ftp.debian.org. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Debian project' + name = "Debian project" examples = [ - 'http://ftp.debian.org/debian/pool/main/q/qpdf/', - 'http://ftp.debian.org/debian/pool/main/g/guake/', + "http://ftp.debian.org/debian/pool/main/q/qpdf/", + "http://ftp.debian.org/debian/pool/main/g/guake/", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -46,12 +46,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -60,22 +60,21 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url_template = 'http://ftp.debian.org/debian/pool/main/' \ - '%(short)s/%(name)s/' + """ + url_template = "http://ftp.debian.org/debian/pool/main/" "%(short)s/%(name)s/" - if project.name.startswith('lib'): + if project.name.startswith("lib"): short = project.name[:4] else: short = project.name[0] - url = url_template % {'short': short, 'name': project.name} + url = url_template % {"short": short, "name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -87,8 +86,8 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = DEBIAN_REGEX % {'name': project.name} + regex = DEBIAN_REGEX % {"name": project.name} return get_versions_by_regex(url, regex, project) diff --git a/anitya/lib/backends/drupal6.py b/anitya/lib/backends/drupal6.py index 072c5ef8e..d4595bcf5 100644 --- a/anitya/lib/backends/drupal6.py +++ b/anitya/lib/backends/drupal6.py @@ -12,28 +12,30 @@ from anitya.lib.exceptions import AnityaPluginException -REGEX = r'6\.x-([^<]+)' +REGEX = r"6\.x-([^<]+)" class Drupal6Backend(BaseBackend): - ''' The custom class for projects hosted on ftp.debian.org. + """ The custom class for projects hosted on ftp.debian.org. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Drupal6' + name = "Drupal6" examples = [ - 'https://www.drupal.org/project/pathauto', - 'https://www.drupal.org/project/wysiwyg', + "https://www.drupal.org/project/pathauto", + "https://www.drupal.org/project/wysiwyg", ] - more_info = 'If the project exists for Drupal 6 and 7 and is '\ - 'monitored for both, you can prefix the name with `Drupal6:`, '\ - 'for example: `Drupal6: cck`.' + more_info = ( + "If the project exists for Drupal 6 and 7 and is " + "monitored for both, you can prefix the name with `Drupal6:`, " + "for example: `Drupal6: cck`." + ) @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -44,12 +46,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -58,23 +60,22 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' + """ name = project.name - if name.lower().strip().startswith('drupal6:'): - name = name[len('drupal6:'):].strip() - if '-' in project.name: + if name.lower().strip().startswith("drupal6:"): + name = name[len("drupal6:") :].strip() + if "-" in project.name: name = project.name.replace("-", "_") - url_template = 'https://updates.drupal.org/release-history/' \ - '%(name)s/6.x' + url_template = "https://updates.drupal.org/release-history/" "%(name)s/6.x" - url = url_template % {'name': name} + url = url_template % {"name": name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -86,12 +87,12 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) name = project.name - if '-' in project.name: + if "-" in project.name: name = project.name.replace("-", "_") - regex = REGEX % {'name': name} + regex = REGEX % {"name": name} versions = None try: diff --git a/anitya/lib/backends/drupal7.py b/anitya/lib/backends/drupal7.py index a2a5da390..74b4c19b7 100644 --- a/anitya/lib/backends/drupal7.py +++ b/anitya/lib/backends/drupal7.py @@ -12,28 +12,30 @@ from anitya.lib.exceptions import AnityaPluginException -REGEX = r'7\.x-([^<]+)' +REGEX = r"7\.x-([^<]+)" class Drupal7Backend(BaseBackend): - ''' The custom class for projects hosted on ftp.debian.org. + """ The custom class for projects hosted on ftp.debian.org. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Drupal7' + name = "Drupal7" examples = [ - 'https://www.drupal.org/project/pathauto', - 'https://www.drupal.org/project/wysiwyg', + "https://www.drupal.org/project/pathauto", + "https://www.drupal.org/project/wysiwyg", ] - more_info = 'If the project exists for Drupal 6 and 7 and is '\ - 'monitored for both, you can prefix the name with `Drupal7:`, '\ - 'for example: `Drupal7: cck`.' + more_info = ( + "If the project exists for Drupal 6 and 7 and is " + "monitored for both, you can prefix the name with `Drupal7:`, " + "for example: `Drupal7: cck`." + ) @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -44,12 +46,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -58,23 +60,22 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' + """ name = project.name - if name.lower().strip().startswith('drupal7:'): - name = name[len('drupal7:'):].strip() - if '-' in project.name: + if name.lower().strip().startswith("drupal7:"): + name = name[len("drupal7:") :].strip() + if "-" in project.name: name = project.name.replace("-", "_") - url_template = 'https://updates.drupal.org/release-history/' \ - '%(name)s/7.x' + url_template = "https://updates.drupal.org/release-history/" "%(name)s/7.x" - url = url_template % {'name': name} + url = url_template % {"name": name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -86,12 +87,12 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) name = project.name - if '-' in project.name: + if "-" in project.name: name = project.name.replace("-", "_") - regex = REGEX % {'name': name} + regex = REGEX % {"name": name} versions = None try: diff --git a/anitya/lib/backends/folder.py b/anitya/lib/backends/folder.py index 9044ccba0..8c2dffb98 100644 --- a/anitya/lib/backends/folder.py +++ b/anitya/lib/backends/folder.py @@ -8,8 +8,7 @@ """ -from anitya.lib.backends import ( - BaseBackend, get_versions_by_regex_for_text, REGEX) +from anitya.lib.backends import BaseBackend, get_versions_by_regex_for_text, REGEX from anitya.lib.exceptions import AnityaPluginException import six @@ -17,21 +16,21 @@ class FolderBackend(BaseBackend): - ''' The custom class for project having a special hosting. + """ The custom class for project having a special hosting. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'folder' + name = "folder" examples = [ - 'https://ftp.gnu.org/pub/gnu/gnash/', - 'https://subsurface-divelog.org/downloads/', + "https://ftp.gnu.org/pub/gnu/gnash/", + "https://subsurface-divelog.org/downloads/", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -42,12 +41,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -56,12 +55,12 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' + """ return project.version_url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -73,26 +72,25 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) try: req = cls.call_url(url, insecure=project.insecure) except Exception as err: raise AnityaPluginException( - 'Could not call : "%s" of "%s", with error: %s' % ( - url, project.name, str(err))) + 'Could not call : "%s" of "%s", with error: %s' + % (url, project.name, str(err)) + ) versions = None if not isinstance(req, six.string_types): req = req.text try: - regex = REGEX % {'name': project.name.replace('+', r'\+')} - versions = get_versions_by_regex_for_text( - req, url, regex, project) + regex = REGEX % {"name": project.name.replace("+", r"\+")} + versions = get_versions_by_regex_for_text(req, url, regex, project) except AnityaPluginException: - versions = get_versions_by_regex_for_text( - req, url, DEFAULT_REGEX, project) + versions = get_versions_by_regex_for_text(req, url, DEFAULT_REGEX, project) return versions diff --git a/anitya/lib/backends/freshmeat.py b/anitya/lib/backends/freshmeat.py index 81bc4c644..2136c42e2 100644 --- a/anitya/lib/backends/freshmeat.py +++ b/anitya/lib/backends/freshmeat.py @@ -15,21 +15,21 @@ class FreshmeatBackend(BaseBackend): - ''' The custom class for projects hosted on freshmeat.net. + """ The custom class for projects hosted on freshmeat.net. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Freshmeat' + name = "Freshmeat" examples = [ - 'http://freecode.com/projects/atmail', - 'http://freecode.com/projects/awstats', + "http://freecode.com/projects/atmail", + "http://freecode.com/projects/awstats", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -40,12 +40,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -54,16 +54,16 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url_template = 'http://freshmeat.net/projects/%(name)s' + """ + url_template = "http://freshmeat.net/projects/%(name)s" - url = url_template % {'name': project.name} + url = url_template % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -75,7 +75,7 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) return get_versions_by_regex(url, REGEX, project) diff --git a/anitya/lib/backends/github.py b/anitya/lib/backends/github.py index 7f07779d6..69f33d8c1 100644 --- a/anitya/lib/backends/github.py +++ b/anitya/lib/backends/github.py @@ -14,7 +14,7 @@ from anitya.config import config import logging -API_URL = 'https://api.github.com/graphql' +API_URL = "https://api.github.com/graphql" """ Rate limit threshold (percent) @@ -26,22 +26,22 @@ class GithubBackend(BaseBackend): - ''' The custom class for projects hosted on github.com. + """ The custom class for projects hosted on github.com. This backend is using GitHub API v4 to query releases for projects hosted on github.com See: https://developer.github.com/v4/ - ''' + """ - name = 'GitHub' + name = "GitHub" examples = [ - 'https://github.com/fedora-infra/fedocal', - 'https://github.com/fedora-infra/pkgdb2', + "https://github.com/fedora-infra/fedocal", + "https://github.com/fedora-infra/pkgdb2", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. Args: @@ -56,12 +56,12 @@ def get_version(cls, project): :obj:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -70,14 +70,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = '' + """ + url = "" if project.version_url: url = project.version_url - elif project.homepage.startswith('https://github.com'): - url = project.homepage.replace('https://github.com/', '') + elif project.homepage.startswith("https://github.com"): + url = project.homepage.replace("https://github.com/", "") - if url.endswith('/'): + if url.endswith("/"): url = url[:-1] if url: @@ -87,7 +87,7 @@ def get_version_url(cls, project): @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -103,58 +103,65 @@ def get_versions(cls, project): :obj:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ owner = None repo = None url = cls.get_version_url(project) if url: - url = url.replace('https://github.com/', '') - url = url.replace('/tags', '') + url = url.replace("https://github.com/", "") + url = url.replace("/tags", "") else: raise AnityaPluginException( - 'Project %s was incorrectly set-up' % project.name) + "Project %s was incorrectly set-up" % project.name + ) try: - (owner, repo) = url.split('/') + (owner, repo) = url.split("/") except ValueError: raise AnityaPluginException( """Project {} was incorrectly set-up. - Can\'t parse owner and repo.""".format(project.name)) + Can\'t parse owner and repo.""".format( + project.name + ) + ) query = prepare_query(owner, repo) try: headers = REQUEST_HEADERS.copy() - token = config['GITHUB_ACCESS_TOKEN'] + token = config["GITHUB_ACCESS_TOKEN"] if token: - headers['Authorization'] = 'bearer %s' % token + headers["Authorization"] = "bearer %s" % token resp = http_session.post( - API_URL, json={'query': query}, headers=headers, timeout=60, verify=True) + API_URL, json={"query": query}, headers=headers, timeout=60, verify=True + ) except Exception as err: - _log.debug('%s ERROR: %s' % (project.name, str(err))) + _log.debug("%s ERROR: %s" % (project.name, str(err))) raise AnityaPluginException( - 'Could not call : "%s" of "%s", with error: %s' % ( - API_URL, project.name, str(err))) + 'Could not call : "%s" of "%s", with error: %s' + % (API_URL, project.name, str(err)) + ) if resp.ok: json = resp.json() else: raise AnityaPluginException( - '%s: Server responded with status "%s": "%s"' % ( - project.name, resp.status_code, resp.reason)) + '%s: Server responded with status "%s": "%s"' + % (project.name, resp.status_code, resp.reason) + ) versions = parse_json(json, project) if len(versions) == 0: raise AnityaPluginException( - '%s: No upstream version found.' % ( - project.name)) + "%s: No upstream version found." % (project.name) + ) return versions def parse_json(json, project): - ''' Function for parsing json response + """ Function for parsing json response Args: json (dict): Json dictionary to parse. @@ -172,45 +179,46 @@ def parse_json(json, project): :obj:`anitya.lib.exceptions.RateLimitException` exception when rate limit threshold is reached. - ''' + """ # We need to check limit first, # because exceeding the limit will also return error try: - limit = json['data']['rateLimit']['limit'] - remaining = json['data']['rateLimit']['remaining'] - reset_time = json['data']['rateLimit']['resetAt'] - _log.debug('Github API ratelimit remains %s, will reset at %s UTC' % ( - remaining, reset_time)) - - if (remaining/limit) <= RATE_LIMIT_THRESHOLD: + limit = json["data"]["rateLimit"]["limit"] + remaining = json["data"]["rateLimit"]["remaining"] + reset_time = json["data"]["rateLimit"]["resetAt"] + _log.debug( + "Github API ratelimit remains %s, will reset at %s UTC" + % (remaining, reset_time) + ) + + if (remaining / limit) <= RATE_LIMIT_THRESHOLD: raise RateLimitException(reset_time) except KeyError: - _log.info('Github API ratelimit key is missing. Checking for errors.') + _log.info("Github API ratelimit key is missing. Checking for errors.") - if 'errors' in json: - error_str = '' - for error in json['errors']: - error_str += '"%s": "%s"\n' % ( - error['type'], error['message']) + if "errors" in json: + error_str = "" + for error in json["errors"]: + error_str += '"%s": "%s"\n' % (error["type"], error["message"]) raise AnityaPluginException( - '%s: Server responded with following errors\n%s' % ( - project.name, error_str)) + "%s: Server responded with following errors\n%s" % (project.name, error_str) + ) - total_count = json['data']['repository']['refs']['totalCount'] + total_count = json["data"]["repository"]["refs"]["totalCount"] - _log.debug('Received %s tags for %s' % (total_count, project.name)) + _log.debug("Received %s tags for %s" % (total_count, project.name)) versions = [] - for edge in json['data']['repository']['refs']['edges']: - version = edge['node']['name'] + for edge in json["data"]["repository"]["refs"]["edges"]: + version = edge["node"]["name"] versions.append(version) return versions -def prepare_query(owner, repo, after=''): - ''' Function for preparing GraphQL query for specified repository +def prepare_query(owner, repo, after=""): + """ Function for preparing GraphQL query for specified repository Args: owner (str): Owner of the repository. @@ -221,15 +229,15 @@ def prepare_query(owner, repo, after=''): Returns: str: GraphQL query. - ''' + """ - after_str = '' + after_str = "" # Fill cursor if we have the id if after: after_str = ', after: "%s"' % after - query = ''' + query = """ { repository(owner: "%s", name: "%s") { refs (refPrefix: "refs/tags/", last:50, @@ -251,6 +259,10 @@ def prepare_query(owner, repo, after=''): remaining resetAt } -}''' % (owner, repo, after_str) +}""" % ( + owner, + repo, + after_str, + ) return query diff --git a/anitya/lib/backends/gitlab.py b/anitya/lib/backends/gitlab.py index 01f552c3c..95e3909f1 100644 --- a/anitya/lib/backends/gitlab.py +++ b/anitya/lib/backends/gitlab.py @@ -33,20 +33,20 @@ class GitlabBackend(BaseBackend): - ''' The custom class for projects hosted on gitlab. + """ The custom class for projects hosted on gitlab. This backend allows to specify a version_url and owner, name of the repository. - ''' + """ - name = 'GitLab' + name = "GitLab" examples = [ - 'https://gitlab.gnome.org/GNOME/gnome-video-arcade', - 'https://gitlab.com/xonotic/xonotic', + "https://gitlab.gnome.org/GNOME/gnome-video-arcade", + "https://gitlab.com/xonotic/xonotic", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -57,12 +57,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -71,25 +71,29 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' + """ tokens = [] - url = '' - url_template = '%(hostname)s/api/v4/projects/%(owner)s%%2F%(repo)s/repository/tags' + url = "" + url_template = ( + "%(hostname)s/api/v4/projects/%(owner)s%%2F%(repo)s/repository/tags" + ) if project.version_url: - tokens = project.version_url.split('/') + tokens = project.version_url.split("/") elif project.homepage: - tokens = project.homepage.split('/') + tokens = project.homepage.split("/") if len(tokens) == 5: - url = url_template % {'hostname': tokens[0] + '//' + tokens[2], - 'owner': tokens[3], - 'repo': tokens[4]} + url = url_template % { + "hostname": tokens[0] + "//" + tokens[2], + "owner": tokens[3], + "repo": tokens[4], + } return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -101,11 +105,12 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) if not url: raise AnityaPluginException( - 'Project %s was incorrectly set-up' % project.name) + "Project %s was incorrectly set-up" % project.name + ) resp = cls.call_url(url) @@ -113,10 +118,11 @@ def get_versions(cls, project): json = resp.json() else: raise AnityaPluginException( - '%s: Server responded with status "%s": "%s"' % ( - project.name, resp.status_code, resp.reason)) + '%s: Server responded with status "%s": "%s"' + % (project.name, resp.status_code, resp.reason) + ) - _log.debug('Received %d tags for %s' % (len(json), project.name)) + _log.debug("Received %d tags for %s" % (len(json), project.name)) tags = [] for tag in json: @@ -124,7 +130,7 @@ def get_versions(cls, project): if len(tags) == 0: raise AnityaPluginException( - '%s: No upstream version found.' % ( - project.name)) + "%s: No upstream version found." % (project.name) + ) return tags diff --git a/anitya/lib/backends/gnome.py b/anitya/lib/backends/gnome.py index 66dfaa6ef..a05a89b54 100644 --- a/anitya/lib/backends/gnome.py +++ b/anitya/lib/backends/gnome.py @@ -20,23 +20,26 @@ def use_gnome_cache_json(project): - ''' Try retrieving the specified project's versions using the cache.json + """ Try retrieving the specified project's versions using the cache.json file if there is one. - ''' + """ output = [] url = GnomeBackend.get_version_url(project) + "cache.json" req = BaseBackend.call_url(url) data = req.json() for item in data: - if isinstance(item, dict) and project.name in item \ - and isinstance(item[project.name], list): + if ( + isinstance(item, dict) + and project.name in item + and isinstance(item[project.name], list) + ): output = item[project.name] return output def use_gnome_regex(project): - ''' Try retrieving the specified project's versions a regular expression. - ''' + """ Try retrieving the specified project's versions a regular expression. + """ output = [] url = GnomeBackend.get_version_url(project) output = get_versions_by_regex(url, REGEX, project) @@ -44,21 +47,21 @@ def use_gnome_regex(project): class GnomeBackend(BaseBackend): - ''' The custom class for project hosted by the GNOME project. + """ The custom class for project hosted by the GNOME project. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'GNOME' + name = "GNOME" examples = [ - 'https://download.gnome.org/sources/control-center/', - 'https://download.gnome.org/sources/evolution-caldav/', + "https://download.gnome.org/sources/control-center/", + "https://download.gnome.org/sources/evolution-caldav/", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -69,12 +72,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -83,15 +86,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://download.gnome.org/sources/%(name)s/' % { - 'name': project.name} + """ + url = "https://download.gnome.org/sources/%(name)s/" % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -103,7 +105,7 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ output = [] try: diff --git a/anitya/lib/backends/gnu.py b/anitya/lib/backends/gnu.py index 2a92c6862..29b234a1e 100644 --- a/anitya/lib/backends/gnu.py +++ b/anitya/lib/backends/gnu.py @@ -8,8 +8,7 @@ """ -from anitya.lib.backends import ( - BaseBackend, REGEX, get_versions_by_regex_for_text) +from anitya.lib.backends import BaseBackend, REGEX, get_versions_by_regex_for_text from anitya.lib.exceptions import AnityaPluginException @@ -17,20 +16,18 @@ class GnuBackend(BaseBackend): - ''' The custom class for project hosted on gnu.org. + """ The custom class for project hosted on gnu.org. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'GNU project' - examples = [ - 'https://ftp.gnu.org/pub/gnu/gnash/', - ] + name = "GNU project" + examples = ["https://ftp.gnu.org/pub/gnu/gnash/"] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -41,12 +38,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -55,14 +52,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://ftp.gnu.org/gnu/%(name)s/' % {'name': project.name} + """ + url = "https://ftp.gnu.org/gnu/%(name)s/" % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -74,22 +71,23 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) try: req = cls.call_url(url) except Exception: # pragma: no cover raise AnityaPluginException( - 'Could not call : "%s" of "%s"' % (url, project.name)) + 'Could not call : "%s" of "%s"' % (url, project.name) + ) versions = None try: - regex = REGEX % {'name': project.name} - versions = get_versions_by_regex_for_text( - req.text, url, regex, project) + regex = REGEX % {"name": project.name} + versions = get_versions_by_regex_for_text(req.text, url, regex, project) except AnityaPluginException: versions = get_versions_by_regex_for_text( - req.text, url, DEFAULT_REGEX, project) + req.text, url, DEFAULT_REGEX, project + ) return versions diff --git a/anitya/lib/backends/google.py b/anitya/lib/backends/google.py index de6732f50..f1acdf369 100644 --- a/anitya/lib/backends/google.py +++ b/anitya/lib/backends/google.py @@ -13,21 +13,21 @@ class GoogleBackend(BaseBackend): - ''' The custom class for projects hosted on Google code. + """ The custom class for projects hosted on Google code. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Google code' + name = "Google code" examples = [ - 'https://code.google.com/p/abcde/', - 'https://code.google.com/p/arduino/', + "https://code.google.com/p/abcde/", + "https://code.google.com/p/arduino/", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -38,12 +38,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -52,15 +52,17 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://code.google.com/p/%(name)s/downloads/list' \ - '?sort=releasedate' % {'name': project.name.lower()} + """ + url = ( + "https://code.google.com/p/%(name)s/downloads/list" + "?sort=releasedate" % {"name": project.name.lower()} + ) return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -72,9 +74,9 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = REGEX % {'name': project.name} + regex = REGEX % {"name": project.name} return get_versions_by_regex(url, regex, project) diff --git a/anitya/lib/backends/hackage.py b/anitya/lib/backends/hackage.py index 19577ed29..f6ab0e6ca 100644 --- a/anitya/lib/backends/hackage.py +++ b/anitya/lib/backends/hackage.py @@ -13,21 +13,21 @@ class HackageBackend(BaseBackend): - ''' The custom class for projects hosted on hackage. + """ The custom class for projects hosted on hackage. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Hackage' + name = "Hackage" examples = [ - 'https://hackage.haskell.org/package/Hs2lib', - 'https://hackage.haskell.org/package/Biobase', + "https://hackage.haskell.org/package/Hs2lib", + "https://hackage.haskell.org/package/Biobase", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -38,12 +38,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -52,15 +52,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://hackage.haskell.org/package/%(name)s' % { - 'name': project.name} + """ + url = "https://hackage.haskell.org/package/%(name)s" % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -72,10 +71,10 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = REGEX % {'name': project.name} + regex = REGEX % {"name": project.name} return get_versions_by_regex(url, regex, project) diff --git a/anitya/lib/backends/launchpad.py b/anitya/lib/backends/launchpad.py index eeb5e4fc0..938400a82 100644 --- a/anitya/lib/backends/launchpad.py +++ b/anitya/lib/backends/launchpad.py @@ -13,21 +13,18 @@ class LaunchpadBackend(BaseBackend): - ''' The custom class for projects hosted on launchpad.net. + """ The custom class for projects hosted on launchpad.net. This backend allows to specify a version_url and a regex that will be used to retrieve the version information. - ''' + """ - name = 'Launchpad' - examples = [ - 'https://launchpad.net/terminator/', - 'https://launchpad.net/exaile', - ] + name = "Launchpad" + examples = ["https://launchpad.net/terminator/", "https://launchpad.net/exaile"] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -38,12 +35,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -52,15 +49,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://launchpad.net/%(name)s/+download' % { - 'name': project.name} + """ + url = "https://launchpad.net/%(name)s/+download" % {"name": project.name} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -72,9 +68,9 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) - regex = REGEX % {'name': project.name} + regex = REGEX % {"name": project.name} return get_versions_by_regex(url, regex, project) diff --git a/anitya/lib/backends/maven.py b/anitya/lib/backends/maven.py index f86aaa42c..818c3d9bf 100644 --- a/anitya/lib/backends/maven.py +++ b/anitya/lib/backends/maven.py @@ -14,24 +14,24 @@ from anitya.lib.exceptions import AnityaPluginException -VERSION_REGEX = re.compile(r'\]+\>(\d[^]+\>(\d[^/' + "https://packagist.org/packages/phpunit/php-code-coverage", + "https://packagist.org/packages/phpunit/php-timer", + "https://packagist.org/packages//", ] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -40,12 +40,12 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ return cls.get_ordered_versions(project)[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -54,21 +54,18 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = '' - url_template = 'https://packagist.org/packages/%(user)s/%(name)s.json' + """ + url = "" + url_template = "https://packagist.org/packages/%(user)s/%(name)s.json" if project.version_url: - url = url_template % { - 'name': project.name, - 'user': project.version_url, - } + url = url_template % {"name": project.name, "user": project.version_url} return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -80,27 +77,26 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) if not url: - raise AnityaPluginException('Project {} is not correctly set-up.'.format( - project.name - )) + raise AnityaPluginException( + "Project {} is not correctly set-up.".format(project.name) + ) try: req = cls.call_url(url) except Exception: # pragma: no cover - raise AnityaPluginException('Could not contact %s' % url) + raise AnityaPluginException("Could not contact %s" % url) try: data = req.json() except Exception: # pragma: no cover - raise AnityaPluginException('No JSON returned by %s' % url) + raise AnityaPluginException("No JSON returned by %s" % url) - if 'package' in data and 'versions' in data['package']: - return sorted(data['package']['versions'].keys()) - elif 'status' in data and data['status'] == 'error' \ - and 'message' in data: - raise AnityaPluginException(data['message']) + if "package" in data and "versions" in data["package"]: + return sorted(data["package"]["versions"].keys()) + elif "status" in data and data["status"] == "error" and "message" in data: + raise AnityaPluginException(data["message"]) else: - raise AnityaPluginException('Invalid JSON returned by %s' % url) + raise AnityaPluginException("Invalid JSON returned by %s" % url) diff --git a/anitya/lib/backends/pagure.py b/anitya/lib/backends/pagure.py index ea955e992..96bfa80a4 100644 --- a/anitya/lib/backends/pagure.py +++ b/anitya/lib/backends/pagure.py @@ -15,17 +15,14 @@ class PagureBackend(BaseBackend): - ''' The pagure class for project hosted on pagure.io. ''' + """ The pagure class for project hosted on pagure.io. """ - name = 'pagure' - examples = [ - 'https://pagure.io/pagure', - 'https://pagure.io/flask-multistatic', - ] + name = "pagure" + examples = ["https://pagure.io/pagure", "https://pagure.io/flask-multistatic"] @classmethod def get_version(cls, project): - ''' Method called to retrieve the latest version of the projects + """ Method called to retrieve the latest version of the projects provided, project that relies on the backend of this plugin. :arg Project project: a :class:`anitya.db.models.Project` object whose backend @@ -36,14 +33,14 @@ def get_version(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the version cannot be retrieved correctly - ''' + """ versions = cls.get_ordered_versions(project) if versions: return versions[-1] @classmethod def get_version_url(cls, project): - ''' Method called to retrieve the url used to check for new version + """ Method called to retrieve the url used to check for new version of the project provided, project that relies on the backend of this plugin. Attributes: @@ -52,14 +49,14 @@ def get_version_url(cls, project): Returns: str: url used for version checking - ''' - url = 'https://pagure.io/api/0/%s/git/tags' % project.name + """ + url = "https://pagure.io/api/0/%s/git/tags" % project.name return url @classmethod def get_versions(cls, project): - ''' Method called to retrieve all the versions (that can be found) + """ Method called to retrieve all the versions (that can be found) of the projects provided, project that relies on the backend of this plugin. @@ -71,18 +68,16 @@ def get_versions(cls, project): :class:`anitya.lib.exceptions.AnityaPluginException` exception when the versions cannot be retrieved correctly - ''' + """ url = cls.get_version_url(project) try: req = cls.call_url(url) except Exception as err: # pragma: no cover - raise AnityaPluginException( - 'Could not contact %s: %s' % (url, str(err)) - ) + raise AnityaPluginException("Could not contact %s: %s" % (url, str(err))) try: data = req.json() except Exception: # pragma: no cover - raise AnityaPluginException('No JSON returned by %s' % url) + raise AnityaPluginException("No JSON returned by %s" % url) - return data.get('tags', []) + return data.get("tags", []) diff --git a/anitya/lib/backends/pear.py b/anitya/lib/backends/pear.py index 8635cc2d5..e21f04ff5 100644 --- a/anitya/lib/backends/pear.py +++ b/anitya/lib/backends/pear.py @@ -16,37 +16,37 @@ def _get_versions(url): - ''' Retrieve the versions for the provided url. ''' + """ Retrieve the versions for the provided url. """ try: req = PearBackend.call_url(url) except Exception: # pragma: no cover - raise AnityaPluginException('Could not contact %s' % url) + raise AnityaPluginException("Could not contact %s" % url) data = req.text versions = [] - for line in data.split('\n'): - if '' in line and '' in line: - version = line.split('v>', 2)[1].split('" in line and "" in line: + version = line.split("v>", 2)[1].split("' in line and '' in line: - version = line.split('v>', 2)[1].split('" in line and "" in line: + version = line.split("v>", 2)[1].split("([\d.]*)' % project.name + ) return get_versions_by_regex(url, regex, project) diff --git a/anitya/lib/ecosystems/__init__.py b/anitya/lib/ecosystems/__init__.py index b8d5ce894..e84e1c33d 100644 --- a/anitya/lib/ecosystems/__init__.py +++ b/anitya/lib/ecosystems/__init__.py @@ -13,7 +13,7 @@ class BaseEcosystem(object): - ''' + """ The base class that all the different ecosystems should extend. Attributes: @@ -26,7 +26,7 @@ class BaseEcosystem(object): use. aliases (list): A list of alternate names for this ecosystem. These should be lowercase. - ''' + """ name = None default_backend = None diff --git a/anitya/lib/ecosystems/crates.py b/anitya/lib/ecosystems/crates.py index 216e50788..ca6b6b6ca 100644 --- a/anitya/lib/ecosystems/crates.py +++ b/anitya/lib/ecosystems/crates.py @@ -24,8 +24,8 @@ class CratesEcosystem(BaseEcosystem): - ''' The crates.io ecosystem class. ''' + """ The crates.io ecosystem class. """ - name = 'crates.io' - default_backend = 'crates.io' - aliases = ['Cargo'] + name = "crates.io" + default_backend = "crates.io" + aliases = ["Cargo"] diff --git a/anitya/lib/ecosystems/maven.py b/anitya/lib/ecosystems/maven.py index 21dc561aa..e5f8d4393 100644 --- a/anitya/lib/ecosystems/maven.py +++ b/anitya/lib/ecosystems/maven.py @@ -11,7 +11,7 @@ class MavenEcosystem(BaseEcosystem): - ''' The Maven ecosystem class''' + """ The Maven ecosystem class""" name = "maven" default_backend = "Maven Central" diff --git a/anitya/lib/ecosystems/npm.py b/anitya/lib/ecosystems/npm.py index 5211d8e42..db7ab3b26 100644 --- a/anitya/lib/ecosystems/npm.py +++ b/anitya/lib/ecosystems/npm.py @@ -11,7 +11,7 @@ class NpmEcosystem(BaseEcosystem): - ''' The npm ecosystem class''' + """ The npm ecosystem class""" name = "npm" default_backend = "npmjs" diff --git a/anitya/lib/ecosystems/pypi.py b/anitya/lib/ecosystems/pypi.py index 08a45669a..cb7c8f8c3 100644 --- a/anitya/lib/ecosystems/pypi.py +++ b/anitya/lib/ecosystems/pypi.py @@ -11,7 +11,7 @@ class PypiEcosystem(BaseEcosystem): - ''' The PyPI ecosystem class''' + """ The PyPI ecosystem class""" name = "pypi" default_backend = "PyPI" diff --git a/anitya/lib/ecosystems/rubygems.py b/anitya/lib/ecosystems/rubygems.py index d98a1b201..ab0f0d4bc 100644 --- a/anitya/lib/ecosystems/rubygems.py +++ b/anitya/lib/ecosystems/rubygems.py @@ -11,7 +11,7 @@ class RubygemsEcosystem(BaseEcosystem): - ''' The rubygems ecosystem class''' + """ The rubygems ecosystem class""" name = "rubygems" default_backend = "Rubygems" diff --git a/anitya/lib/exceptions.py b/anitya/lib/exceptions.py index be4f3d239..498a87a57 100644 --- a/anitya/lib/exceptions.py +++ b/anitya/lib/exceptions.py @@ -26,14 +26,16 @@ class AnityaException(Exception): - ''' Generic class covering all the exceptions generated by anitya. ''' + """ Generic class covering all the exceptions generated by anitya. """ + pass class AnityaPluginException(AnityaException): - ''' Generic exception class that can be used by the plugin to indicate + """ Generic exception class that can be used by the plugin to indicate an error. - ''' + """ + pass @@ -44,23 +46,30 @@ class ProjectExists(AnityaException): This is only raised when a project is part of an ecosystem, since projects outside of an ecosystem have no uniqueness constraints. """ + def __init__(self, requested_project): self.requested_project = requested_project def to_dict(self): - return { - u'requested_project': self.requested_project.__json__(), - } + return {u"requested_project": self.requested_project.__json__()} def __str__(self): - return 'Unable to create project since it already exists.' + return "Unable to create project since it already exists." class AnityaInvalidMappingException(AnityaException): - ''' Specific exception class for invalid mapping. ''' - - def __init__(self, pkgname, distro, found_pkgname, - found_distro, project_id, project_name, link=None): + """ Specific exception class for invalid mapping. """ + + def __init__( + self, + pkgname, + distro, + found_pkgname, + found_distro, + project_id, + project_name, + link=None, + ): self.pkgname = pkgname self.distro = distro self.found_pkgname = found_pkgname @@ -71,10 +80,11 @@ def __init__(self, pkgname, distro, found_pkgname, @property def message(self): - return 'Could not edit the mapping of {pkgname} on ' \ - '{distro}, there is already a package {found_pkgname} on ' \ - '{found_distro} as part of the project ' \ - '{project_name}.'.format( + return ( + "Could not edit the mapping of {pkgname} on " + "{distro}, there is already a package {found_pkgname} on " + '{found_distro} as part of the project ' + "{project_name}.".format( pkgname=self.pkgname, distro=self.distro, found_pkgname=self.found_pkgname, @@ -83,6 +93,7 @@ def message(self): project_name=self.project_name, link=self.link, ) + ) class InvalidVersion(AnityaException): @@ -100,7 +111,9 @@ def __init__(self, version, exception=None): def __str__(self): if self.exception: - return 'Invalid version "{v}": {e}'.format(v=self.version, e=str(self.exception)) + return 'Invalid version "{v}": {e}'.format( + v=self.version, e=str(self.exception) + ) else: return 'Invalid version "{v}"'.format(v=self.version) @@ -123,4 +136,6 @@ def __init__(self, reset_time): self.reset_time = arrow.get(reset_time) def __str__(self): - return 'Rate limit was reached. Will be reset in "{0}".'.format(str(self.reset_time)) + return 'Rate limit was reached. Will be reset in "{0}".'.format( + str(self.reset_time) + ) diff --git a/anitya/lib/plugins.py b/anitya/lib/plugins.py index 6aa7d23d3..0f086cdd2 100644 --- a/anitya/lib/plugins.py +++ b/anitya/lib/plugins.py @@ -31,31 +31,32 @@ class _PluginManager(object): """Manage a particular set of Anitya plugins""" + def __init__(self, namespace, base_class): self._namespace = namespace self._base_class = base_class def get_plugins(self): - ''' Return the list of plugins.''' + """ Return the list of plugins.""" return load(self._namespace, subclasses=self._base_class) def get_plugin_names(self): - ''' Return the list of plugin names. ''' + """ Return the list of plugin names. """ plugins = self.get_plugins() output = [plugin.name for plugin in plugins] return output def get_plugin(self, plugin_name): - ''' Return the plugin corresponding to the given plugin name. ''' + """ Return the plugin corresponding to the given plugin name. """ plugins = self.get_plugins() for plugin in plugins: if plugin.name.lower() == plugin_name.lower(): return plugin -BACKEND_PLUGINS = _PluginManager('anitya.lib.backends', BaseBackend) -ECOSYSTEM_PLUGINS = _PluginManager('anitya.lib.ecosystems', BaseEcosystem) -VERSION_PLUGINS = _PluginManager('anitya.lib.versions', Version) +BACKEND_PLUGINS = _PluginManager("anitya.lib.backends", BaseBackend) +ECOSYSTEM_PLUGINS = _PluginManager("anitya.lib.ecosystems", BaseEcosystem) +VERSION_PLUGINS = _PluginManager("anitya.lib.versions", Version) def _load_backend_plugins(session): @@ -77,8 +78,8 @@ def _load_version_plugins(session): def load_all_plugins(session): - ''' Load all the plugins and insert them in the database if they are - not already present. ''' + """ Load all the plugins and insert them in the database if they are + not already present. """ plugins = {} plugins["backends"] = _load_backend_plugins(session) plugins["ecosystems"] = _load_ecosystem_plugins(session) @@ -93,9 +94,9 @@ def load_all_plugins(session): def load_plugins(session, family="backends"): - ''' Calls load_all_plugins, but only retuns plugins specified by family argument + """ Calls load_all_plugins, but only retuns plugins specified by family argument Args: family (str): family of the plugins, that should be returned - ''' + """ return load_all_plugins(session)[family] diff --git a/anitya/lib/utilities.py b/anitya/lib/utilities.py index bd83846ff..c1c17be75 100644 --- a/anitya/lib/utilities.py +++ b/anitya/lib/utilities.py @@ -39,18 +39,19 @@ def fedmsg_publish(*args, **kwargs): # pragma: no cover - ''' Try to publish a message on the fedmsg bus. ''' + """ Try to publish a message on the fedmsg bus. """ if config.config["LEGACY_MESSAGING"]: # We catch Exception if we want :-p # pylint: disable=W0703 # Ignore message about fedmsg import # pylint: disable=F0401 - kwargs['modname'] = 'anitya' - kwargs['cert_prefix'] = 'anitya' - kwargs['name'] = 'relay_inbound' - kwargs['active'] = True + kwargs["modname"] = "anitya" + kwargs["cert_prefix"] = "anitya" + kwargs["name"] = "relay_inbound" + kwargs["active"] = True try: import fedmsg + fedmsg.publish(*args, **kwargs) except Exception as err: _log.error(str(err)) @@ -58,7 +59,10 @@ def fedmsg_publish(*args, **kwargs): # pragma: no cover try: message_class = message.get_class("anitya." + kwargs["topic"]) api.publish(message_class(body=kwargs["msg"])) - except (fm_exceptions.ConnectionException, fm_exceptions.PublishException) as err: + except ( + fm_exceptions.ConnectionException, + fm_exceptions.PublishException, + ) as err: # For now, continue just logging the error. Once the messaging has # been untangled into SQLAlchemy events, it should probably result # in an exception and the client should try again later. @@ -66,19 +70,20 @@ def fedmsg_publish(*args, **kwargs): # pragma: no cover def check_project_release(project, session, test=False): - ''' Check if the provided project has a new release available or not. + """ Check if the provided project has a new release available or not. :arg package: a Package object has defined in anitya.db.modelss.Project - ''' + """ backend = plugins.get_plugin(project.backend) if not backend: raise exceptions.AnityaException( - 'No backend was found for "%s"' % project.backend) + 'No backend was found for "%s"' % project.backend + ) publish = False versions_prefix = [] - max_version = '' + max_version = "" # don't change actual data during test run if not test: @@ -91,7 +96,7 @@ def check_project_release(project, session, test=False): _log.exception("AnityaError catched:") if not test: project.logs = str(err) - project.next_check = err.reset_time.to('utc').datetime + project.next_check = err.reset_time.to("utc").datetime project.check_successful = False session.add(project) session.commit() @@ -113,25 +118,26 @@ def check_project_release(project, session, test=False): # There is always at least one version retrieved, # otherwise this backend raises exception - project.logs = 'Version retrieved correctly' + project.logs = "Version retrieved correctly" project.check_successful = True p_versions = project.get_sorted_version_objects() - old_version = project.latest_version or '' + old_version = project.latest_version or "" version_column_len = models.ProjectVersion.version.property.columns[0].type.length for version in versions: if version not in p_versions: if len(version.version) < version_column_len: project.versions_obj.append( models.ProjectVersion( - project_id=project.id, - version=version.version + project_id=project.id, version=version.version ) ) else: - _log.info("Version '{}' was skipped. Reason: too long.".format( - version.version - )) + _log.info( + "Version '{}' was skipped. Reason: too long.".format( + version.version + ) + ) sorted_versions = project.get_sorted_version_objects() if sorted_versions: @@ -140,7 +146,7 @@ def check_project_release(project, session, test=False): project.latest_version = max_version publish = True else: - project.logs = 'No new version found' + project.logs = "No new version found" if publish: log( @@ -154,8 +160,8 @@ def check_project_release(project, session, test=False): packages=[pkg.__json__() for pkg in project.packages], versions=project.versions, ecosystem=project.ecosystem_name, - agent='anitya', - odd_change=False + agent="anitya", + odd_change=False, ), ) @@ -168,10 +174,14 @@ def _construct_substitutions(msg): subs = {} for key1 in msg: if isinstance(msg[key1], dict): - subs.update(dict([ - ('.'.join([key1, key2]), val2) - for key2, val2 in _construct_substitutions(msg[key1]).items() - ])) + subs.update( + dict( + [ + (".".join([key1, key2]), val2) + for key2, val2 in _construct_substitutions(msg[key1]).items() + ] + ) + ) subs[key1] = msg[key1] @@ -185,40 +195,37 @@ def log(session, project=None, distro=None, topic=None, message=None): """ # A big lookup of fedmsg topics to log template strings. templates = { - 'distro.add': '%(agent)s added the distro named: %(distro)s', - 'distro.edit': '%(agent)s edited distro name from: %(old)s to: ' - '%(new)s', - 'distro.remove': '%(agent)s deleted the distro named: %(distro)s', - 'project.add': '%(agent)s added project: %(project)s', - 'project.add.tried': '%(agent)s tried to add an already existing ' - 'project: %(project)s', - 'project.edit': '%(agent)s edited the project: %(project)s fields: ' - '%(changes)s', - 'project.flag': '%(agent)s flagged the project: %(project)s with ' - 'reason: %(reason)s', - 'project.flag.set': '%(agent)s set flag %(flag)s to %(state)s', - 'project.remove': '%(agent)s removed the project: %(project)s', - 'project.map.new': '%(agent)s mapped the name of %(project)s in ' - '%(distro)s as %(new)s', - 'project.map.update': '%(agent)s updated the name of %(project)s in ' - '%(distro)s from: %(prev)s to: %(new)s', - 'project.map.remove': '%(agent)s removed the mapping of %(project)s ' - 'in %(distro)s', - 'project.version.remove': '%(agent)s removed the version %(version)s ' - 'of %(project)s', - 'project.version.update': 'new version: %(upstream_version)s found' - ' for project %(project.name)s ' - 'in ecosystem %(ecosystem)s ' - '(project id: %(project.id)s).', + "distro.add": "%(agent)s added the distro named: %(distro)s", + "distro.edit": "%(agent)s edited distro name from: %(old)s to: " "%(new)s", + "distro.remove": "%(agent)s deleted the distro named: %(distro)s", + "project.add": "%(agent)s added project: %(project)s", + "project.add.tried": "%(agent)s tried to add an already existing " + "project: %(project)s", + "project.edit": "%(agent)s edited the project: %(project)s fields: " + "%(changes)s", + "project.flag": "%(agent)s flagged the project: %(project)s with " + "reason: %(reason)s", + "project.flag.set": "%(agent)s set flag %(flag)s to %(state)s", + "project.remove": "%(agent)s removed the project: %(project)s", + "project.map.new": "%(agent)s mapped the name of %(project)s in " + "%(distro)s as %(new)s", + "project.map.update": "%(agent)s updated the name of %(project)s in " + "%(distro)s from: %(prev)s to: %(new)s", + "project.map.remove": "%(agent)s removed the mapping of %(project)s " + "in %(distro)s", + "project.version.remove": "%(agent)s removed the version %(version)s " + "of %(project)s", + "project.version.update": "new version: %(upstream_version)s found" + " for project %(project.name)s " + "in ecosystem %(ecosystem)s " + "(project id: %(project.id)s).", } substitutions = _construct_substitutions(message) final_msg = templates[topic] % substitutions - fedmsg_publish(topic=topic, msg=dict( - project=project, - distro=distro, - message=message, - )) + fedmsg_publish( + topic=topic, msg=dict(project=project, distro=distro, message=message) + ) return final_msg @@ -248,16 +255,19 @@ def init(db_url, alembic_ini=None, debug=False, create=False): # pragma: no cov # Source: https://docs.sqlalchemy.org/en/latest/dialects/sqlite.html # see section 'sqlite-foreign-keys' - if db_url.startswith('sqlite:'): + if db_url.startswith("sqlite:"): + def _fk_pragma_on_connect(dbapi_con, con_record): dbapi_con.execute("PRAGMA foreign_keys=ON") - sa.event.listen(engine, 'connect', _fk_pragma_on_connect) + + sa.event.listen(engine, "connect", _fk_pragma_on_connect) if alembic_ini is not None: # pragma: no cover # then, load the Alembic configuration and generate the # version table, "stamping" it with the most recent rev: from alembic.config import Config from alembic import command + alembic_cfg = Config(alembic_ini) command.stamp(alembic_cfg, "head") @@ -270,9 +280,18 @@ def _fk_pragma_on_connect(dbapi_con, con_record): def create_project( - session, name, homepage, user_id, backend='custom', - version_scheme='RPM', version_url=None, version_prefix=None, - regex=None, check_release=False, insecure=False): + session, + name, + homepage, + user_id, + backend="custom", + version_scheme="RPM", + version_url=None, + version_prefix=None, + regex=None, + check_release=False, + insecure=False, +): """ Create the project in the database. """ @@ -284,7 +303,7 @@ def create_project( version_url=version_url, regex=regex, version_prefix=version_prefix, - insecure=insecure + insecure=insecure, ) session.add(project) @@ -297,17 +316,13 @@ def create_project( except SQLAlchemyError as err: _log.exception(err) session.rollback() - raise exceptions.AnityaException( - 'Could not add this project, already exists?') + raise exceptions.AnityaException("Could not add this project, already exists?") log( session, project=project.__json__(), - topic='project.add', - message=dict( - agent=user_id, - project=project.name, - ) + topic="project.add", + message=dict(agent=user_id, project=project.name), ) session.commit() if check_release is True: @@ -316,8 +331,19 @@ def create_project( def edit_project( - session, project, name, homepage, backend, version_scheme, version_url, - version_prefix, regex, insecure, user_id, check_release=False): + session, + project, + name, + homepage, + backend, + version_scheme, + version_url, + version_prefix, + regex, + insecure, + user_id, + check_release=False, +): """ Edit a project in the database. """ @@ -325,53 +351,51 @@ def edit_project( if name != project.name: old = project.name project.name = name.strip() if name else None - changes['name'] = {'old': old, 'new': project.name} + changes["name"] = {"old": old, "new": project.name} if homepage != project.homepage: old = project.homepage project.homepage = homepage.strip() if homepage else None - changes['homepage'] = {'old': old, 'new': project.homepage} + changes["homepage"] = {"old": old, "new": project.homepage} if backend != project.backend: old = project.backend project.backend = backend - changes['backend'] = {'old': old, 'new': project.backend} + changes["backend"] = {"old": old, "new": project.backend} if version_scheme != project.version_scheme: old = project.version_scheme project.version_scheme = version_scheme - changes['version_scheme'] = {'old': old, 'new': project.version_scheme} + changes["version_scheme"] = {"old": old, "new": project.version_scheme} if version_url != project.version_url: old = project.version_url project.version_url = version_url.strip() if version_url else None if old != project.version_url: - changes['version_url'] = {'old': old, 'new': project.version_url} + changes["version_url"] = {"old": old, "new": project.version_url} if version_prefix != project.version_prefix: old = project.version_prefix - project.version_prefix = version_prefix.strip() \ - if version_prefix else None + project.version_prefix = version_prefix.strip() if version_prefix else None if old != project.version_prefix: - changes['version_prefix'] = { - 'old': old, 'new': project.version_prefix} + changes["version_prefix"] = {"old": old, "new": project.version_prefix} if regex != project.regex: old = project.regex project.regex = regex.strip() if regex else None if old != project.regex: - changes['regex'] = {'old': old, 'new': project.regex} + changes["regex"] = {"old": old, "new": project.regex} if insecure != project.insecure: old = project.insecure project.insecure = insecure - changes['insecure'] = {'old': old, 'new': project.insecure} + changes["insecure"] = {"old": old, "new": project.insecure} try: if changes: log( session, project=project.__json__(), - topic='project.edit', + topic="project.edit", message=dict( agent=user_id, project=project.name, fields=list(changes.keys()), # be backward compat changes=changes, - ) + ), ) session.add(project) session.commit() @@ -381,15 +405,22 @@ def edit_project( _log.exception(err) session.rollback() raise exceptions.AnityaException( - 'Could not edit this project. Is there already a project ' - 'with these name and homepage?') + "Could not edit this project. Is there already a project " + "with these name and homepage?" + ) return changes def map_project( - session, project, package_name, distribution, user_id, - old_package_name=None, old_distro_name=None): + session, + project, + package_name, + distribution, + user_id, + old_package_name=None, + old_distro_name=None, +): """ Map a project to a distribution. @@ -416,17 +447,16 @@ def map_project( except SQLAlchemyError: session.rollback() raise exceptions.AnityaException( - 'Could not add the distribution %s to the database, ' - 'please inform an admin.' % distribution, 'errors') + "Could not add the distribution %s to the database, " + "please inform an admin." % distribution, + "errors", + ) log( session, distro=distro_obj.__json__(), - topic='distro.add', - message=dict( - agent=user_id, - distro=distro_obj.name, - ) + topic="distro.add", + message=dict(agent=user_id, distro=distro_obj.name), ) session.add(distro_obj) try: @@ -435,48 +465,55 @@ def map_project( # We cannot test this situation session.rollback() raise exceptions.AnityaException( - 'Could not add the distribution %s to the database, ' - 'please inform an admin.' % distribution, 'errors') + "Could not add the distribution %s to the database, " + "please inform an admin." % distribution, + "errors", + ) pkgname = old_package_name or package_name distro = old_distro_name or distribution - pkg = models.Packages.get( - session, project.id, distro, pkgname) + pkg = models.Packages.get(session, project.id, distro, pkgname) # See if the new mapping would clash with an existing mapping try: other_pkg = models.Packages.query.filter_by( - distro_name=distribution, package_name=package_name).one() + distro_name=distribution, package_name=package_name + ).one() except NoResultFound: other_pkg = None # Only raise exception if the package is already associated # to project if other_pkg and other_pkg.project: raise exceptions.AnityaInvalidMappingException( - pkgname, distro, package_name, distribution, - other_pkg.project.id, other_pkg.project.name) + pkgname, + distro, + package_name, + distribution, + other_pkg.project.id, + other_pkg.project.name, + ) edited = None if not pkg: - topic = 'project.map.new' + topic = "project.map.new" if not other_pkg: pkg = models.Packages( distro_name=distro_obj.name, project_id=project.id, - package_name=package_name + package_name=package_name, ) else: other_pkg.project = project pkg = other_pkg else: - topic = 'project.map.update' + topic = "project.map.update" edited = [] if pkg.distro_name != distro_obj.name: pkg.distro_name = distro_obj.name - edited.append('distribution') + edited.append("distribution") if pkg.package_name != package_name: pkg.package_name = package_name - edited.append('package_name') + edited.append("package_name") session.add(pkg) try: @@ -485,18 +522,16 @@ def map_project( _log.exception(err) session.rollback() raise exceptions.AnityaException( - 'Could not add the mapping of %s to %s, please inform an ' - 'admin.' % (package_name, distribution)) + "Could not add the mapping of %s to %s, please inform an " + "admin." % (package_name, distribution) + ) message = dict( - agent=user_id, - project=project.name, - distro=distro_obj.name, - new=package_name, + agent=user_id, project=project.name, distro=distro_obj.name, new=package_name ) if edited: - message['prev'] = old_package_name or package_name - message['edited'] = edited + message["prev"] = old_package_name or package_name + message["edited"] = edited log( session, @@ -514,10 +549,7 @@ def flag_project(session, project, reason, user_email, user_id): """ - flag = models.ProjectFlag( - user=user_email, - project=project, - reason=reason) + flag = models.ProjectFlag(user=user_email, project=project, reason=reason) session.add(flag) @@ -526,19 +558,18 @@ def flag_project(session, project, reason, user_email, user_id): except SQLAlchemyError as err: _log.exception(err) session.rollback() - raise exceptions.AnityaException( - 'Could not flag this project.') + raise exceptions.AnityaException("Could not flag this project.") log( session, project=project.__json__(), - topic='project.flag', + topic="project.flag", message=dict( agent=user_id, project=project.name, reason=reason, packages=[pkg.__json__() for pkg in project.packages], - ) + ), ) session.commit() return flag @@ -552,8 +583,7 @@ def set_flag_state(session, flag, state, user_id): # Don't toggle the state or send a new fedmsg if the flag's # state wouldn't actually be changed. if flag.state == state: - raise exceptions.AnityaException( - 'Flag state unchanged.') + raise exceptions.AnityaException("Flag state unchanged.") flag.state = state session.add(flag) @@ -563,17 +593,12 @@ def set_flag_state(session, flag, state, user_id): except SQLAlchemyError as err: _log.exception(err) session.rollback() - raise exceptions.AnityaException( - 'Could not set the state of this flag.') + raise exceptions.AnityaException("Could not set the state of this flag.") log( session, - topic='project.flag.set', - message=dict( - agent=user_id, - flag=flag.id, - state=state, - ) + topic="project.flag.set", + message=dict(agent=user_id, flag=flag.id, state=state), ) session.commit() return flag diff --git a/anitya/lib/versions/__init__.py b/anitya/lib/versions/__init__.py index d8df03b00..d5742f036 100644 --- a/anitya/lib/versions/__init__.py +++ b/anitya/lib/versions/__init__.py @@ -46,4 +46,4 @@ #: The default version scheme to use when the project itself, its ecosystem, #: and its backend all have no version scheme set. -GLOBAL_DEFAULT = 'RPM' +GLOBAL_DEFAULT = "RPM" diff --git a/anitya/lib/versions/base.py b/anitya/lib/versions/base.py index abe2f494a..13de2b13e 100644 --- a/anitya/lib/versions/base.py +++ b/anitya/lib/versions/base.py @@ -28,14 +28,14 @@ #: A regular expression to determine if the version string contains a 'v' prefix. -v_prefix = re.compile(r'v\d.*') +v_prefix = re.compile(r"v\d.*") @functools.total_ordering class Version(object): """The base class for versions.""" - name = 'Generic Version' + name = "Generic Version" def __init__(self, version=None, prefix=None, created_on=None): self.version = version @@ -71,7 +71,7 @@ def parse(self): # If there's a prefix set on the project, strip it if it's present version = self.version if self.prefix and self.version.startswith(self.prefix): - version = self.version[len(self.prefix):] + version = self.version[len(self.prefix) :] # Many projects prefix their tags with 'v', so strip it if it's present if v_prefix.match(version): diff --git a/anitya/lib/versions/rpm.py b/anitya/lib/versions/rpm.py index 54f12f549..d9b06b395 100644 --- a/anitya/lib/versions/rpm.py +++ b/anitya/lib/versions/rpm.py @@ -45,6 +45,7 @@ # considered greater (newer). import warnings + warnings.warn("Failed to import 'rpm', emulating RPM label comparisons") try: @@ -53,7 +54,7 @@ from itertools import izip_longest as zip_longest _subfield_pattern = re.compile( - r'(?P[^a-zA-Z0-9]*)((?P[a-zA-Z]+)|(?P[0-9]+))' + r"(?P[^a-zA-Z0-9]*)((?P[a-zA-Z]+)|(?P[0-9]+))" ) def _iter_rpm_subfields(field): @@ -63,11 +64,11 @@ def _iter_rpm_subfields(field): Numeric subfields are yielded as (1, int_value) """ for subfield in _subfield_pattern.finditer(field): - text = subfield.group('text') + text = subfield.group("text") if text is not None: yield (0, text) else: - yield (1, int(subfield.group('num'))) + yield (1, int(subfield.group("num"))) def _compare_rpm_field(lhs, rhs): # Short circuit for exact matches (including both being None) @@ -112,10 +113,11 @@ class RpmVersion(Version): back to a pure Python implementation if they are not installed. """ - name = u'RPM' + name = "RPM" _rc_upstream_regex = re.compile( - r"(.*?)\.?(-?(rc|pre|beta|alpha|dev)([0-9]*))", re.I) + r"(.*?)\.?(-?(rc|pre|beta|alpha|dev)([0-9]*))", re.I + ) @classmethod def split_rc(cls, version): @@ -145,7 +147,7 @@ def prerelease(self): This recognizes versions containing "rc", "pre", "beta", "alpha", and "dev" as being pre-release versions. """ - return self.split_rc(self.parse())[1] != '' + return self.split_rc(self.parse())[1] != "" def __eq__(self, other): """ diff --git a/anitya/lib/xml2dict.py b/anitya/lib/xml2dict.py index a14ad0ea7..825ab26d8 100644 --- a/anitya/lib/xml2dict.py +++ b/anitya/lib/xml2dict.py @@ -25,6 +25,7 @@ class object_dict(dict): >>> a.test, a.test2.name, a.test2.value (1, 'test2', 2) """ + def __init__(self, initd=None): if initd is None: initd = {} @@ -33,8 +34,8 @@ def __init__(self, initd=None): def __getattr__(self, item): d = self.__getitem__(item) # if value is the only key in object, you can omit it - if isinstance(d, dict) and 'value' in d and len(d) == 1: - return d['value'] + if isinstance(d, dict) and "value" in d and len(d) == 1: + return d["value"] else: return d @@ -43,19 +44,17 @@ def __setattr__(self, item, value): class XML2Dict(object): - def _parse_node(self, node): node_tree = object_dict() # Save attrs and text, hope there will not be a child with same name if node.text: node_tree.value = node.text for (k, v) in node.attrib.items(): - k, v = self._namespace_split(k, object_dict({'value': v})) + k, v = self._namespace_split(k, object_dict({"value": v})) node_tree[k] = v # Save childrens for child in list(node): - tag, tree = self._namespace_split( - child.tag, self._parse_node(child)) + tag, tree = self._namespace_split(child.tag, self._parse_node(child)) # the first time, so store it in dict if tag not in node_tree: node_tree[tag] = tree @@ -82,14 +81,13 @@ def _namespace_split(self, tag, value): def parse(self, file): """parse a xml file to a dict""" - f = open(file, 'rb') + f = open(file, "rb") return self.fromstring(f.read()) def fromstring(self, s): """parse a string""" if isinstance(s, six.text_type): - s = s.encode('utf-8') + s = s.encode("utf-8") t = ET.fromstring(s) - root_tag, root_tree = self._namespace_split( - t.tag, self._parse_node(t)) + root_tag, root_tree = self._namespace_split(t.tag, self._parse_node(t)) return object_dict({root_tag: root_tree}) diff --git a/anitya/librariesio_consumer.py b/anitya/librariesio_consumer.py index a4d1020c3..9bb91eecd 100644 --- a/anitya/librariesio_consumer.py +++ b/anitya/librariesio_consumer.py @@ -101,23 +101,22 @@ class LibrariesioConsumer(FedmsgConsumer): config_key (str): A string that must be set to `True` in the fedmsg configuration to enable this consumer. """ - topic = [ - 'sse2fedmsg.librariesio', - ] - config_key = 'anitya.libraryio.enabled' + topic = ["sse2fedmsg.librariesio"] + + config_key = "anitya.libraryio.enabled" def __init__(self, hub): # If we're in development mode, add the dev versions of the topics so # local playback with fedmsg-dg-replay works as expected. - prefix, env = hub.config['topic_prefix'], hub.config['environment'] - self.topic = ['.'.join([prefix, env, topic]) for topic in self.topic] - _log.info('Subscribing to the following fedmsg topics: %r', self.topic) + prefix, env = hub.config["topic_prefix"], hub.config["environment"] + self.topic = [".".join([prefix, env, topic]) for topic in self.topic] + _log.info("Subscribing to the following fedmsg topics: %r", self.topic) initialize(config.config) super(LibrariesioConsumer, self).__init__(hub) - hub.config['topic_prefix'] = "org.release-monitoring" + hub.config["topic_prefix"] = "org.release-monitoring" def consume(self, message): """ @@ -139,55 +138,85 @@ def consume(self, message): Args: message (dict): The fedmsg to process. """ - librariesio_msg = message['body']['msg']['data'] - name = librariesio_msg['name'] - platform = librariesio_msg['platform'].lower() - version = librariesio_msg['version'] - homepage = librariesio_msg['package_manager_url'] + librariesio_msg = message["body"]["msg"]["data"] + name = librariesio_msg["name"] + platform = librariesio_msg["platform"].lower() + version = librariesio_msg["version"] + homepage = librariesio_msg["package_manager_url"] for ecosystem in plugins.ECOSYSTEM_PLUGINS.get_plugins(): if platform == ecosystem.name or platform in ecosystem.aliases: break else: - _log.debug('Dropped librariesio update to %s for %s (%s) since it is on the ' - 'unsupported %s platform', version, name, homepage, platform) + _log.debug( + "Dropped librariesio update to %s for %s (%s) since it is on the " + "unsupported %s platform", + version, + name, + homepage, + platform, + ) return session = Session() project = models.Project.by_name_and_ecosystem(session, name, ecosystem.name) - if project is None and platform in config.config['LIBRARIESIO_PLATFORM_WHITELIST']: + if ( + project is None + and platform in config.config["LIBRARIESIO_PLATFORM_WHITELIST"] + ): try: project = utilities.create_project( session, name, homepage, - 'anitya', + "anitya", backend=ecosystem.default_backend, check_release=True, ) - _log.info('Discovered new project at version %s via libraries.io: %r', - version, project) + _log.info( + "Discovered new project at version %s via libraries.io: %r", + version, + project, + ) except exceptions.AnityaException as e: - _log.error('A new project was discovered via libraries.io, %r, ' - 'but we failed with "%s"', project, str(e)) + _log.error( + "A new project was discovered via libraries.io, %r, " + 'but we failed with "%s"', + project, + str(e), + ) elif project is None: - _log.info('Discovered new project, %s, on the %s platform, but anitya is ' - 'configured to not create the project', name, platform) + _log.info( + "Discovered new project, %s, on the %s platform, but anitya is " + "configured to not create the project", + name, + platform, + ) else: - _log.info('libraries.io has found an update (version %s) for project %r', - version, project) + _log.info( + "libraries.io has found an update (version %s) for project %r", + version, + project, + ) # This will fetch the version, emit fedmsgs, add log entries, and # commit the transaction. try: utilities.check_project_release(project, session) except exceptions.AnityaPluginException as e: - _log.warning('libraries.io found an update for %r, but we failed with %s', - project, str(e)) + _log.warning( + "libraries.io found an update for %r, but we failed with %s", + project, + str(e), + ) # Refresh the project object that was committed by either # ``create_project`` or ``check_project_release`` above project = models.Project.by_name_and_ecosystem(session, name, ecosystem.name) if project and project.latest_version != version: - _log.info('libraries.io found %r had a latest version of %s, but Anitya found %s', - project, version, project.latest_version) + _log.info( + "libraries.io found %r had a latest version of %s, but Anitya found %s", + project, + version, + project.latest_version, + ) Session.remove() diff --git a/anitya/mail_logging.py b/anitya/mail_logging.py index 599892729..f5a64cc42 100644 --- a/anitya/mail_logging.py +++ b/anitya/mail_logging.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" Mail handler for logging. -''' +""" import logging import logging.handlers @@ -73,7 +73,7 @@ def filter(self, record): record.host = current_hostname record.proc = current_process - record.pid = '-' + record.pid = "-" if not isinstance(current_process, str): record.pid = current_process.pid # Be compatible with python-psutil 1.0 and 2.0, 3.0 @@ -89,10 +89,10 @@ def filter(self, record): record.callstack = self.format_callstack() - record.url = '-' - record.args = '-' - record.form = '-' - record.username = '-' + record.url = "-" + record.args = "-" + record.form = "-" + record.username = "-" try: record.url = flask.request.url except RuntimeError: @@ -103,13 +103,12 @@ def filter(self, record): pass try: record.form = dict(flask.request.form) - if 'csrf_token' in record.form: - record.form['csrf_token'] = 'Was present, is cleaned up' + if "csrf_token" in record.form: + record.form["csrf_token"] = "Was present, is cleaned up" except RuntimeError: pass try: - record.username = "%s -- %s" % ( - flask.g.user.id, flask.g.user.email) + record.username = "%s -- %s" % (flask.g.user.id, flask.g.user.email) except Exception: pass @@ -120,9 +119,9 @@ def format_callstack(): """ Format the callstack to find out the stack trace. """ ind = 0 for ind, frame in enumerate(f[0] for f in inspect.stack()): - if '__name__' not in frame.f_globals: + if "__name__" not in frame.f_globals: continue - modname = frame.f_globals['__name__'].split('.')[0] + modname = frame.f_globals["__name__"].split(".")[0] if modname != "logging": break @@ -186,10 +185,8 @@ def get_mail_handler(smtp_server, mail_admin): """ Set up the handler sending emails for big exception """ mail_handler = logging.handlers.SMTPHandler( - smtp_server, - 'nobody@fedoraproject.org', - mail_admin, - 'Anitya (server) error') + smtp_server, "nobody@fedoraproject.org", mail_admin, "Anitya (server) error" + ) mail_handler.setFormatter(logging.Formatter(MSG_FORMAT)) mail_handler.setLevel(logging.ERROR) mail_handler.addFilter(ContextInjector()) diff --git a/anitya/sar.py b/anitya/sar.py index b1350add8..4234d2ddc 100644 --- a/anitya/sar.py +++ b/anitya/sar.py @@ -38,26 +38,26 @@ from anitya.config import config from anitya import db -_log = logging.getLogger('anitya') +_log = logging.getLogger("anitya") def main(): - ''' + """ Retrieve database entry for user. - ''' + """ db.initialize(config) _log.setLevel(logging.DEBUG) - sar_username = os.getenv('SAR_USERNAME') - sar_email = os.getenv('SAR_EMAIL') + sar_username = os.getenv("SAR_USERNAME") + sar_email = os.getenv("SAR_EMAIL") users = [] if sar_email: - _log.debug('Find users by e-mail {}'.format(sar_email)) + _log.debug("Find users by e-mail {}".format(sar_email)) users = users + db.User.query.filter_by(email=sar_email).all() if sar_username: - _log.debug('Find users by username {}'.format(sar_username)) + _log.debug("Find users by username {}".format(sar_username)) users = users + db.User.query.filter_by(username=sar_username).all() users_list = [] @@ -67,7 +67,7 @@ def main(): json.dump(users_list, sys.stdout) -if __name__ == '__main__': - _log.info('SAR script start') +if __name__ == "__main__": + _log.info("SAR script start") main() - _log.info('SAR script end') + _log.info("SAR script end") diff --git a/anitya/tests/__init__.py b/anitya/tests/__init__.py index d83e36e7f..b35851016 100644 --- a/anitya/tests/__init__.py +++ b/anitya/tests/__init__.py @@ -18,6 +18,6 @@ # License and may only be used or replicated with the express permission # of Red Hat, Inc. # -''' +""" Anitya tests. -''' +""" diff --git a/anitya/tests/base.py b/anitya/tests/base.py index 37f131848..1b5bbc509 100644 --- a/anitya/tests/base.py +++ b/anitya/tests/base.py @@ -57,13 +57,15 @@ def login_user(app, user): user (models.User): The user to log in. Note that this user must be committed to the database as it needs a ``user.id`` value. """ + def handler(sender, **kwargs): flask_login.login_user(user) + with request_started.connected_to(handler, app): yield -def _configure_db(db_uri='sqlite://'): +def _configure_db(db_uri="sqlite://"): """Creates and configures a database engine for the tests to use. Args: @@ -73,7 +75,7 @@ def _configure_db(db_uri='sqlite://'): global engine engine = create_engine(db_uri) - if db_uri.startswith('sqlite://'): + if db_uri.startswith("sqlite://"): # Necessary to get nested transactions working with SQLite. See: # https://docs.sqlalchemy.org/en/latest/dialects/sqlite.html\ # #serializable-isolation-savepoints-transactional-ddl @@ -87,9 +89,9 @@ def connect_event(dbapi_connection, connection_record): @event.listens_for(engine, "begin") def begin_event(conn): """Emit our own 'BEGIN' instead of letting pysqlite do it.""" - conn.execute('BEGIN') + conn.execute("BEGIN") - @event.listens_for(Session, 'after_transaction_end') + @event.listens_for(Session, "after_transaction_end") def restart_savepoint(session, transaction): """Allow tests to call rollback on the session.""" if transaction.nested and not transaction._parent.nested: @@ -106,12 +108,13 @@ def setUp(self): This simply starts recording a VCR on start-up and stops on tearDown. """ self.config = config.config.copy() - self.config['TESTING'] = True + self.config["TESTING"] = True self.flask_app = app.create(self.config) cwd = os.path.dirname(os.path.realpath(__file__)) my_vcr = vcr.VCR( - cassette_library_dir=os.path.join(cwd, 'request-data/'), record_mode='once') + cassette_library_dir=os.path.join(cwd, "request-data/"), record_mode="once" + ) self.vcr = my_vcr.use_cassette(self.id()) self.vcr.__enter__() self.addCleanup(self.vcr.__exit__, None, None, None) @@ -161,14 +164,10 @@ def tearDown(self): def create_distro(session): """ Create some basic distro for testing. """ - distro = models.Distro( - name='Fedora', - ) + distro = models.Distro(name="Fedora") session.add(distro) - distro = models.Distro( - name='Debian', - ) + distro = models.Distro(name="Debian") session.add(distro) session.commit() @@ -177,28 +176,26 @@ def create_distro(session): def create_project(session): """ Create some basic projects to work with. """ project = models.Project( - name='geany', - homepage='https://www.geany.org/', - version_scheme='RPM', - backend='custom', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', + name="geany", + homepage="https://www.geany.org/", + version_scheme="RPM", + backend="custom", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", ) session.add(project) project = models.Project( - name='subsurface', - homepage='https://subsurface-divelog.org/', - backend='custom', - version_url='https://subsurface-divelog.org/downloads/', - regex='DEFAULT', + name="subsurface", + homepage="https://subsurface-divelog.org/", + backend="custom", + version_url="https://subsurface-divelog.org/downloads/", + regex="DEFAULT", ) session.add(project) project = models.Project( - name='R2spec', - homepage='https://fedorahosted.org/r2spec/', - backend='custom', + name="R2spec", homepage="https://fedorahosted.org/r2spec/", backend="custom" ) session.add(project) session.commit() @@ -210,30 +207,30 @@ def create_ecosystem_projects(session): Each project name is used in two different ecosystems """ project = models.Project( - name='pypi_and_npm', - homepage='https://example.com/not-a-real-pypi-project', - backend='PyPI', + name="pypi_and_npm", + homepage="https://example.com/not-a-real-pypi-project", + backend="PyPI", ) session.add(project) project = models.Project( - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", ) session.add(project) project = models.Project( - name='rubygems_and_maven', - homepage='https://example.com/not-a-real-rubygems-project', - backend='Rubygems', + name="rubygems_and_maven", + homepage="https://example.com/not-a-real-rubygems-project", + backend="Rubygems", ) session.add(project) project = models.Project( - name='rubygems_and_maven', - homepage='https://example.com/not-a-real-maven-project', - backend='Maven Central', + name="rubygems_and_maven", + homepage="https://example.com/not-a-real-maven-project", + backend="Maven Central", ) session.add(project) session.commit() @@ -241,17 +238,11 @@ def create_ecosystem_projects(session): def create_package(session): """ Create some basic packages to work with. """ - package = models.Packages( - project_id=1, - distro_name='Fedora', - package_name='geany', - ) + package = models.Packages(project_id=1, distro_name="Fedora", package_name="geany") session.add(package) package = models.Packages( - project_id=2, - distro_name='Fedora', - package_name='subsurface', + project_id=2, distro_name="Fedora", package_name="subsurface" ) session.add(package) @@ -261,17 +252,15 @@ def create_package(session): def create_flagged_project(session): """ Create and flag a project. Returns the ProjectFlag. """ project = models.Project( - name='geany', - homepage='https://www.geany.org/', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', + name="geany", + homepage="https://www.geany.org/", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", ) session.add(project) flag = models.ProjectFlag( - project=project, - reason="this is a duplicate.", - user="dgay@redhat.com", + project=project, reason="this is a duplicate.", user="dgay@redhat.com" ) session.add(flag) @@ -279,5 +268,5 @@ def create_flagged_project(session): return flag -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/anitya/tests/db/test_events.py b/anitya/tests/db/test_events.py index e235ecf29..2290b6b2d 100644 --- a/anitya/tests/db/test_events.py +++ b/anitya/tests/db/test_events.py @@ -25,43 +25,40 @@ class SetEcosystemTests(DatabaseTestCase): - def test_set_manually(self): """Assert the ecosystem can be set manually.""" project = models.Project( - name='requests', - homepage='https://pypi.org/requests', - ecosystem_name='crates.io', - backend='PyPI', + name="requests", + homepage="https://pypi.org/requests", + ecosystem_name="crates.io", + backend="PyPI", ) Session.add(project) Session.commit() project = models.Project.query.all()[0] - self.assertEqual('crates.io', project.ecosystem_name) + self.assertEqual("crates.io", project.ecosystem_name) def test_set_automatically(self): """Assert the ecosystem gets set automatically based on the backend.""" project = models.Project( - name='requests', - homepage='https://pypi.org/requests', - backend='PyPI', + name="requests", homepage="https://pypi.org/requests", backend="PyPI" ) Session.add(project) Session.commit() project = models.Project.query.all()[0] - self.assertEqual('pypi', project.ecosystem_name) + self.assertEqual("pypi", project.ecosystem_name) def test_invalid(self): """Assert invalid ecosystems raise an exception.""" project = models.Project( - name='requests', - homepage='https://pypi.org/requests', - backend='PyPI', - ecosystem_name='invalid_ecosystem', + name="requests", + homepage="https://pypi.org/requests", + backend="PyPI", + ecosystem_name="invalid_ecosystem", ) Session.add(project) diff --git a/anitya/tests/db/test_meta.py b/anitya/tests/db/test_meta.py index 77ce5f079..e6e8c1127 100644 --- a/anitya/tests/db/test_meta.py +++ b/anitya/tests/db/test_meta.py @@ -26,27 +26,26 @@ class InitalizeTests(unittest.TestCase): - - @mock.patch('anitya.db.meta.create_engine') - @mock.patch('anitya.db.meta.Session') + @mock.patch("anitya.db.meta.create_engine") + @mock.patch("anitya.db.meta.Session") def test_initialize(self, mock_session, mock_create_engine): - config = {'DB_URL': 'postgresql://postgres:pass@localhost/mydb'} + config = {"DB_URL": "postgresql://postgres:pass@localhost/mydb"} engine = meta.initialize(config) - mock_create_engine.assert_called_once_with(config['DB_URL'], echo=False) + mock_create_engine.assert_called_once_with(config["DB_URL"], echo=False) self.assertEqual(engine, mock_create_engine.return_value) mock_session.configure.assert_called_once_with(bind=engine) - @mock.patch('anitya.db.meta.create_engine') - @mock.patch('anitya.db.meta.event.listen') - @mock.patch('anitya.db.meta.Session') + @mock.patch("anitya.db.meta.create_engine") + @mock.patch("anitya.db.meta.event.listen") + @mock.patch("anitya.db.meta.Session") def test_initalize_sqlite(self, mock_session, mock_listen, mock_create_engine): - config = {'DB_URL': 'sqlite://', 'SQL_DEBUG': True} + config = {"DB_URL": "sqlite://", "SQL_DEBUG": True} engine = meta.initialize(config) - mock_create_engine.assert_called_once_with(config['DB_URL'], echo=True) + mock_create_engine.assert_called_once_with(config["DB_URL"], echo=True) mock_session.configure.assert_called_once_with(bind=engine) self.assertEqual(1, mock_listen.call_count) self.assertEqual(engine, mock_listen.call_args_list[0][0][0]) - self.assertEqual('connect', mock_listen.call_args_list[0][0][1]) + self.assertEqual("connect", mock_listen.call_args_list[0][0][1]) class BaseQueryPaginateTests(DatabaseTestCase): @@ -64,9 +63,9 @@ def test_defaults(self): self.assertEqual(3, page.total_items) self.assertEqual(25, page.items_per_page) # Default ordering is just by id - self.assertEqual(page.items[0].name, 'geany') - self.assertEqual(page.items[1].name, 'subsurface') - self.assertEqual(page.items[2].name, 'R2spec') + self.assertEqual(page.items[0].name, "geany") + self.assertEqual(page.items[1].name, "subsurface") + self.assertEqual(page.items[2].name, "R2spec") def test_multiple_pages(self): """Assert multiple pages work with pagination.""" @@ -76,13 +75,13 @@ def test_multiple_pages(self): self.assertEqual(1, page.page) self.assertEqual(3, page.total_items) self.assertEqual(2, page.items_per_page) - self.assertEqual(page.items[0].name, 'geany') - self.assertEqual(page.items[1].name, 'subsurface') + self.assertEqual(page.items[0].name, "geany") + self.assertEqual(page.items[1].name, "subsurface") self.assertEqual(2, page2.page) self.assertEqual(3, page2.total_items) self.assertEqual(2, page2.items_per_page) - self.assertEqual(page2.items[0].name, 'R2spec') + self.assertEqual(page2.items[0].name, "R2spec") def test_no_results(self): """Assert an empty page is returned when page * items_per_page > total_items.""" @@ -110,30 +109,32 @@ def test_order_by(self): self.assertEqual(1, page.page) self.assertEqual(3, page.total_items) self.assertEqual(25, page.items_per_page) - self.assertEqual(page.items[0].name, 'R2spec') - self.assertEqual(page.items[1].name, 'geany') - self.assertEqual(page.items[2].name, 'subsurface') + self.assertEqual(page.items[0].name, "R2spec") + self.assertEqual(page.items[1].name, "geany") + self.assertEqual(page.items[2].name, "subsurface") def test_as_dict(self): expected_dict = { - u'items_per_page': 1, - u'page': 1, - u'total_items': 3, - u'items': [{ - 'id': 3, - 'backend': u'custom', - 'name': u'R2spec', - 'homepage': u'https://fedorahosted.org/r2spec/', - 'ecosystem': u'https://fedorahosted.org/r2spec/', - 'regex': None, - 'version': None, - 'version_url': None, - 'versions': [], - }], + u"items_per_page": 1, + u"page": 1, + u"total_items": 3, + u"items": [ + { + "id": 3, + "backend": u"custom", + "name": u"R2spec", + "homepage": u"https://fedorahosted.org/r2spec/", + "ecosystem": u"https://fedorahosted.org/r2spec/", + "regex": None, + "version": None, + "version_url": None, + "versions": [], + } + ], } create_project(self.session) page = self.query.paginate(order_by=models.Project.name, items_per_page=1) actual_dict = page.as_dict() - actual_dict['items'][0].pop('updated_on') - actual_dict['items'][0].pop('created_on') + actual_dict["items"][0].pop("updated_on") + actual_dict["items"][0].pop("created_on") self.assertEqual(expected_dict, actual_dict) diff --git a/anitya/tests/db/test_models.py b/anitya/tests/db/test_models.py index c6b42d960..5aeadc669 100644 --- a/anitya/tests/db/test_models.py +++ b/anitya/tests/db/test_models.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests of the models. -''' +""" from uuid import uuid4, UUID import unittest @@ -38,9 +38,12 @@ from anitya.db import models from anitya.lib import versions from anitya.tests.base import ( - DatabaseTestCase, create_distro, - create_project, create_package, - create_flagged_project) + DatabaseTestCase, + create_distro, + create_project, + create_package, + create_flagged_project, +) from anitya.lib import utilities @@ -53,99 +56,100 @@ def test_init_project(self): self.assertEqual(3, models.Project.all(self.session, count=True)) projects = models.Project.all(self.session) - self.assertEqual(projects[0].name, 'geany') - self.assertEqual(projects[1].name, 'R2spec') - self.assertEqual(projects[2].name, 'subsurface') + self.assertEqual(projects[0].name, "geany") + self.assertEqual(projects[1].name, "R2spec") + self.assertEqual(projects[2].name, "subsurface") def test_validate_backend(self): project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', + name="test", homepage="https://example.com", backend="custom" ) self.session.add(project) self.session.commit() self.assertEqual(1, self.session.query(models.Project).count()) - self.assertEqual('custom', self.session.query(models.Project).one().backend) + self.assertEqual("custom", self.session.query(models.Project).one().backend) def test_validate_backend_bad(self): self.assertRaises( ValueError, models.Project, - name='test', - homepage='https://example.com', - backend='Nope', + name="test", + homepage="https://example.com", + backend="Nope", ) def test_default_ecosystem_is_homepage(self): project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', + name="test", + homepage="https://example.com", + backend="custom", ecosystem_name=None, ) self.session.add(project) self.session.commit() self.assertEqual(1, self.session.query(models.Project).count()) self.assertEqual( - 'https://example.com', - self.session.query(models.Project).one().ecosystem_name) + "https://example.com", + self.session.query(models.Project).one().ecosystem_name, + ) def test_validate_ecosystem_good(self): project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", ) self.session.add(project) self.session.commit() self.assertEqual(1, self.session.query(models.Project).count()) - self.assertEqual('pypi', self.session.query(models.Project).one().ecosystem_name) + self.assertEqual( + "pypi", self.session.query(models.Project).one().ecosystem_name + ) def test_ecosystem_in_json(self): """Assert the ecosystem is included in the dict returned from ``__json__``""" project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", ) - self.assertEqual('pypi', project.__json__()['ecosystem']) + self.assertEqual("pypi", project.__json__()["ecosystem"]) def test_create_version_objects_RPM(self): """ Assert that the correct version objects list is returned (RPM version scheme). """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - version_scheme='RPM', - version_prefix='test-' + name="test", + homepage="https://example.com", + backend="custom", + version_scheme="RPM", + version_prefix="test-", ) self.session.add(project) self.session.commit() - versions_list = ['test-0.1.0', 'test-0.2.0', 'test-0.3.0'] + versions_list = ["test-0.1.0", "test-0.2.0", "test-0.3.0"] versions = project.create_version_objects(versions_list) self.assertEqual(len(versions), 3) - self.assertEqual(str(versions[0]), '0.1.0') - self.assertEqual(str(versions[1]), '0.2.0') - self.assertEqual(str(versions[2]), '0.3.0') + self.assertEqual(str(versions[0]), "0.1.0") + self.assertEqual(str(versions[1]), "0.2.0") + self.assertEqual(str(versions[2]), "0.3.0") def test_create_version_objects_empty(self): """ Assert that the `create_version_objects` method returns nothing on empty list. """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - version_scheme='RPM', - version_prefix='test-' + name="test", + homepage="https://example.com", + backend="custom", + version_scheme="RPM", + version_prefix="test-", ) self.session.add(project) self.session.commit() @@ -159,20 +163,18 @@ def test_create_version_objects_empty(self): def test_get_version_url_no_backend(self): """ Assert that empty string is returned when backend is not specified. """ project = models.Project( - name='test', - homepage='https://example.com', - ecosystem_name='pypi', + name="test", homepage="https://example.com", ecosystem_name="pypi" ) - self.assertEqual('', project.get_version_url()) + self.assertEqual("", project.get_version_url()) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - version_url='https://example.com/releases', - ecosystem_name='pypi' + name="test", + homepage="https://example.com", + backend="custom", + version_url="https://example.com/releases", + ecosystem_name="pypi", ) self.assertEqual(project.version_url, project.get_version_url()) @@ -181,20 +183,14 @@ def get_sorted_version_objects(self): :data:`Project.get_sorted_version_objects`. """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', - version_scheme='RPM' - ) - version_first = models.ProjectVersion( - project_id=project.id, - version='1.0', - ) - version_second = models.ProjectVersion( - project_id=project.id, - version='0.8', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", + version_scheme="RPM", ) + version_first = models.ProjectVersion(project_id=project.id, version="1.0") + version_second = models.ProjectVersion(project_id=project.id, version="0.8") self.session.add(project) self.session.add(version_first) self.session.add(version_second) @@ -208,22 +204,22 @@ def get_sorted_version_objects(self): def test_get_version_class(self): project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', - version_scheme='RPM', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", + version_scheme="RPM", ) version_class = project.get_version_class() self.assertEqual(version_class, versions.RpmVersion) def test_get_version_class_missing(self): project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', - version_scheme='Invalid', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", + version_scheme="Invalid", ) version_class = project.get_version_class() self.assertEqual(version_class, None) @@ -238,7 +234,7 @@ def test_project_all(self): projects = models.Project.all(self.session, page=2) self.assertEqual(len(projects), 0) - projects = models.Project.all(self.session, page='asd') + projects = models.Project.all(self.session, page="asd") self.assertEqual(len(projects), 3) def test_project_search(self): @@ -246,13 +242,13 @@ def test_project_search(self): create_project(self.session) create_package(self.session) - projects = models.Project.search(self.session, '*', count=True) + projects = models.Project.search(self.session, "*", count=True) self.assertEqual(projects, 3) - projects = models.Project.search(self.session, '*', page=2) + projects = models.Project.search(self.session, "*", page=2) self.assertEqual(len(projects), 0) - projects = models.Project.search(self.session, '*', page='asd') + projects = models.Project.search(self.session, "*", page="asd") self.assertEqual(len(projects), 3) def test_project_search_no_pattern(self): @@ -262,7 +258,7 @@ def test_project_search_no_pattern(self): """ create_project(self.session) - projects = models.Project.search(self.session, '') + projects = models.Project.search(self.session, "") self.assertEqual(len(projects), 3) def test_project_search_by_distro(self): @@ -273,19 +269,17 @@ def test_project_search_by_distro(self): create_project(self.session) create_package(self.session) - projects = models.Project.search(self.session, '*', distro='Fedora') + projects = models.Project.search(self.session, "*", distro="Fedora") self.assertEqual(len(projects), 2) def test_project_get_or_create(self): """ Test the Project.get_or_create function. """ project = models.Project.get_or_create( - self.session, - name='test', - homepage='https://test.org', - backend='custom') - self.assertEqual(project.name, 'test') - self.assertEqual(project.homepage, 'https://test.org') - self.assertEqual(project.backend, 'custom') + self.session, name="test", homepage="https://test.org", backend="custom" + ) + self.assertEqual(project.name, "test") + self.assertEqual(project.homepage, "https://test.org") + self.assertEqual(project.backend, "custom") def test_project_get_or_create_exception(self): """ @@ -296,26 +290,24 @@ def test_project_get_or_create_exception(self): ValueError, models.Project.get_or_create, self.session, - name='test_project', - homepage='https://project.test.org', - backend='foobar' + name="test_project", + homepage="https://project.test.org", + backend="foobar", ) def test_project_delete_cascade(self): """ Assert deletion of mapped packages when project is deleted """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', - version_scheme='Invalid', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", + version_scheme="Invalid", ) self.session.add(project) package = models.Packages( - project_id=1, - distro_name='Fedora', - package_name='test', + project_id=1, distro_name="Fedora", package_name="test" ) self.session.add(package) self.session.commit() @@ -351,14 +343,13 @@ def test_project_get_or_create_get(self): is provided. """ create_project(self.session) - pre_projects = models.Project.search(self.session, '*', count=True) + pre_projects = models.Project.search(self.session, "*", count=True) project = models.Project.get_or_create( - self.session, - name='geany', - homepage='https://www.geany.org/') - post_projects = models.Project.search(self.session, '*', count=True) - self.assertEqual(project.name, 'geany') - self.assertEqual(project.homepage, 'https://www.geany.org/') + self.session, name="geany", homepage="https://www.geany.org/" + ) + post_projects = models.Project.search(self.session, "*", count=True) + self.assertEqual(project.name, "geany") + self.assertEqual(project.homepage, "https://www.geany.org/") self.assertEqual(pre_projects, post_projects) def test_project_updated_new(self): @@ -368,7 +359,7 @@ def test_project_updated_new(self): """ create_project(self.session) - projects = models.Project.updated(self.session, status='new') + projects = models.Project.updated(self.session, status="new") self.assertEqual(len(projects), 3) self.assertEqual(projects[0].logs, None) @@ -383,7 +374,7 @@ def test_project_updated_newer_updated(self): project.latest_version = None self.session.commit() - projects = models.Project.updated(self.session, status='never_updated') + projects = models.Project.updated(self.session, status="never_updated") self.assertEqual(len(projects), 3) self.assertEqual(projects[0].logs, "something") @@ -397,7 +388,7 @@ def test_project_updated_failed(self): project.logs = "No upstream version found" self.session.commit() - projects = models.Project.updated(self.session, status='failed') + projects = models.Project.updated(self.session, status="failed") self.assertEqual(len(projects), 3) self.assertEqual(projects[0].logs, "No upstream version found") @@ -407,11 +398,13 @@ def test_project_updated_odd(self): set to 'odd'. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Something strange occured" self.session.commit() - projects = models.Project.updated(self.session, status='odd') + projects = models.Project.updated(self.session, status="odd") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].logs, "Something strange occured") @@ -421,11 +414,13 @@ def test_project_updated_updated(self): set to 'updated'. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() - projects = models.Project.updated(self.session, status='updated') + projects = models.Project.updated(self.session, status="updated") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].logs, "Version retrieved correctly") @@ -434,7 +429,7 @@ def test_project_updated_incorrect_status(self): Assert that all projects are returned when incorrect status is used. """ create_project(self.session) - projects = models.Project.updated(self.session, status='incorrect') + projects = models.Project.updated(self.session, status="incorrect") self.assertEqual(len(projects), 3) def test_project_updated_name_pattern(self): @@ -442,11 +437,13 @@ def test_project_updated_name_pattern(self): Assert that correct project is returned when pattern as name is used. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() - projects = models.Project.updated(self.session, name='gean*') + projects = models.Project.updated(self.session, name="gean*") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].name, "geany") @@ -455,11 +452,13 @@ def test_project_updated_name(self): Assert that correct project is returned when exact name is used. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() - projects = models.Project.updated(self.session, name='geany') + projects = models.Project.updated(self.session, name="geany") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].name, "geany") @@ -468,11 +467,13 @@ def test_project_updated_log_pattern(self): Assert that correct project is returned when log pattern is used. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() - projects = models.Project.updated(self.session, log='*retrieved*') + projects = models.Project.updated(self.session, log="*retrieved*") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].name, "geany") @@ -481,11 +482,13 @@ def test_project_updated_log(self): Assert that log argument is automatically changed to pattern. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() - projects = models.Project.updated(self.session, log='retrieved') + projects = models.Project.updated(self.session, log="retrieved") self.assertEqual(len(projects), 1) self.assertEqual(projects[0].name, "geany") @@ -494,7 +497,9 @@ def test_project_updated_count(self): Assert that correct count is returned. """ create_project(self.session) - for project in self.session.query(models.Project).filter(models.Project.id == 1): + for project in self.session.query(models.Project).filter( + models.Project.id == 1 + ): project.logs = "Version retrieved correctly" self.session.commit() projects = models.Project.updated(self.session, count=True) @@ -510,29 +515,25 @@ def test_init_distro(self): self.assertEqual(2, models.Distro.all(self.session, count=True)) distros = models.Distro.all(self.session) - self.assertEqual(distros[0].name, 'Debian') - self.assertEqual(distros[1].name, 'Fedora') + self.assertEqual(distros[0].name, "Debian") + self.assertEqual(distros[1].name, "Fedora") def test_distro_delete_cascade(self): """ Assert deletion of mapped packages when project is deleted """ project = models.Project( - name='test', - homepage='https://example.com', - backend='custom', - ecosystem_name='pypi', - version_scheme='Invalid', + name="test", + homepage="https://example.com", + backend="custom", + ecosystem_name="pypi", + version_scheme="Invalid", ) self.session.add(project) - distro = models.Distro( - name='Fedora', - ) + distro = models.Distro(name="Fedora") self.session.add(distro) package = models.Packages( - project_id=1, - distro_name='Fedora', - package_name='test', + project_id=1, distro_name="Fedora", package_name="test" ) self.session.add(package) self.session.commit() @@ -555,7 +556,7 @@ def test_distro_search_count(self): """ Assert that `Distro.search` returns correct count. """ create_distro(self.session) - logs = models.Distro.search(self.session, '*', count=True) + logs = models.Distro.search(self.session, "*", count=True) self.assertEqual(logs, 2) def test_distro_search_pattern(self): @@ -565,9 +566,9 @@ def test_distro_search_pattern(self): """ create_distro(self.session) - logs = models.Distro.search(self.session, 'Fed*') + logs = models.Distro.search(self.session, "Fed*") self.assertEqual(len(logs), 1) - self.assertEqual(logs[0].name, 'Fedora') + self.assertEqual(logs[0].name, "Fedora") def test_distro_search_page(self): """ @@ -575,9 +576,9 @@ def test_distro_search_page(self): """ create_distro(self.session) - logs = models.Distro.search(self.session, 'Fed*', page=1) + logs = models.Distro.search(self.session, "Fed*", page=1) self.assertEqual(len(logs), 1) - self.assertEqual(logs[0].name, 'Fedora') + self.assertEqual(logs[0].name, "Fedora") def test_distro_search_incorrect_page(self): """ @@ -586,9 +587,9 @@ def test_distro_search_incorrect_page(self): """ create_distro(self.session) - logs = models.Distro.search(self.session, 'Fed*', page='as') + logs = models.Distro.search(self.session, "Fed*", page="as") self.assertEqual(len(logs), 1) - self.assertEqual(logs[0].name, 'Fedora') + self.assertEqual(logs[0].name, "Fedora") class PackageTestCase(DatabaseTestCase): @@ -601,8 +602,8 @@ def test_packages_by_id(self): create_package(self.session) pkg = models.Packages.by_id(self.session, 1) - self.assertEqual(pkg.package_name, 'geany') - self.assertEqual(pkg.distro_name, 'Fedora') + self.assertEqual(pkg.package_name, "geany") + self.assertEqual(pkg.distro_name, "Fedora") def test_packages__repr__(self): """ Test the Packages.__repr__ function. """ @@ -611,7 +612,7 @@ def test_packages__repr__(self): create_package(self.session) pkg = models.Packages.by_id(self.session, 1) - self.assertEqual(str(pkg), '') + self.assertEqual(str(pkg), "") class ProjectFlagTestCase(DatabaseTestCase): @@ -621,23 +622,23 @@ def test_project_flag__repr__(self): """ Test the ProjectFlag.__repr__ function. """ flag = create_flagged_project(self.session) - self.assertEqual(repr(flag), '') + self.assertEqual(repr(flag), "") def test_project_flag__json__(self): """ Test the ProjectFlag.__json__ function. """ flag = create_flagged_project(self.session) data = { - 'created_on': time.mktime(flag.created_on.timetuple()), - 'user': u'dgay@redhat.com', - 'state': u'open', - 'project': u'geany', - 'updated_on': time.mktime(flag.updated_on.timetuple()), - 'id': 1 + "created_on": time.mktime(flag.created_on.timetuple()), + "user": u"dgay@redhat.com", + "state": u"open", + "project": u"geany", + "updated_on": time.mktime(flag.updated_on.timetuple()), + "id": 1, } self.assertEqual(flag.__json__(), data) - data['reason'] = u'this is a duplicate.' + data["reason"] = u"this is a duplicate." self.assertEqual(flag.__json__(detailed=True), data) def test_project_flag_all(self): @@ -718,7 +719,7 @@ def test_project_flag_search_by_state(self): self.session.add(flag_add) self.session.commit() - flags = models.ProjectFlag.search(self.session, state='open') + flags = models.ProjectFlag.search(self.session, state="open") self.assertEqual(len(flags), 1) def test_project_flag_search_offset(self): @@ -822,7 +823,7 @@ def test_process_bind_param_uuid_other(self): result = guid.process_bind_param(uuid, dialect) self.assertEqual(32, len(result)) - self.assertEqual(str(uuid).replace('-', ''), result) + self.assertEqual(str(uuid).replace("-", ""), result) def test_process_bind_param_str_other(self): """Assert UUIDs with other dialects are hex-encoded strings of length 32.""" @@ -833,7 +834,7 @@ def test_process_bind_param_str_other(self): result = guid.process_bind_param(str(uuid), dialect) self.assertEqual(32, len(result)) - self.assertEqual(str(uuid).replace('-', ''), result) + self.assertEqual(str(uuid).replace("-", ""), result) def test_process_bind_param_none(self): """Assert UUIDs with other dialects are hex-encoded strings of length 32.""" @@ -865,24 +866,17 @@ def test_process_result_short_string(self): guid = models.GUID() uuid = uuid4() - result = guid.process_result_value(str(uuid).replace('-', ''), sqlite.dialect()) + result = guid.process_result_value(str(uuid).replace("-", ""), sqlite.dialect()) self.assertTrue(isinstance(result, UUID)) self.assertEqual(uuid, result) class UserTests(DatabaseTestCase): - def test_user_id(self): """Assert Users have a UUID id assigned to them.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -892,14 +886,8 @@ def test_user_id(self): def test_user_get_id(self): """Assert Users implements the Flask-Login API for getting user IDs.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -909,62 +897,38 @@ def test_user_get_id(self): def test_user_email_unique(self): """Assert User emails have a uniqueness constraint on them.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() - user = models.User(email='user@fedoraproject.org', username='user2') - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user2") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.assertRaises(IntegrityError, self.session.commit) def test_username_unique(self): """Assert User usernames have a uniqueness constraint on them.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() - user = models.User(email='user2@fedoraproject.org', username='user') - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user2@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.assertRaises(IntegrityError, self.session.commit) def test_default_active(self): """Assert User usernames have a uniqueness constraint on them.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -975,14 +939,8 @@ def test_default_active(self): def test_not_anonymous(self): """Assert User implements the Flask-Login API for authenticated users.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -993,14 +951,8 @@ def test_not_anonymous(self): def test_default_admin(self): """Assert default value for admin flag.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -1011,21 +963,15 @@ def test_default_admin(self): def test_is_admin_configured(self): """Assert default value for admin flag.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - admin=False, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user", admin=False) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() mock_dict = mock.patch.dict( - 'anitya.config.config', {'ANITYA_WEB_ADMINS': [six.text_type(user.id)]}) + "anitya.config.config", {"ANITYA_WEB_ADMINS": [six.text_type(user.id)]} + ) with mock_dict: self.assertFalse(user.admin) @@ -1034,16 +980,11 @@ def test_is_admin_configured(self): def test_to_dict(self): """ Assert the correct dictionary is returned. """ - user = models.User( - email='user@fedoraproject.org', - username='user', - ) + user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user, - provider='FAS', + user_id=user.id, user=user, provider="FAS" ) - user_social_auth.set_extra_data({'wookie': 'too hairy'}) + user_social_auth.set_extra_data({"wookie": "too hairy"}) self.session.add(user_social_auth) self.session.add(user) self.session.commit() @@ -1053,11 +994,13 @@ def test_to_dict(self): "email": user.email, "username": user.username, "active": user.active, - "social_auth": [{ - "provider": user_social_auth.provider, - "extra_data": user_social_auth.extra_data, - "uid": user_social_auth.uid, - }], + "social_auth": [ + { + "provider": user_social_auth.provider, + "extra_data": user_social_auth.extra_data, + "uid": user_social_auth.uid, + } + ], } json = user.to_dict() @@ -1065,17 +1008,10 @@ def test_to_dict(self): class ApiTokenTests(DatabaseTestCase): - def test_token_default(self): """Assert creating an ApiToken generates a random token.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -1088,14 +1024,8 @@ def test_token_default(self): def test_user_relationship(self): """Assert users have a reference to their tokens.""" - user = models.User( - email='user@fedoraproject.org', - username='user', - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user") + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) @@ -1107,5 +1037,5 @@ def test_user_relationship(self): self.assertEqual(user.api_tokens, [token]) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/anitya/tests/lib/backends/test_bitbucket.py b/anitya/tests/lib/backends/test_bitbucket.py index d76093ac8..a1d3ff2e1 100644 --- a/anitya/tests/lib/backends/test_bitbucket.py +++ b/anitya/tests/lib/backends/test_bitbucket.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the bitbucket backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'BitBucket' +BACKEND = "BitBucket" class BitBucketBackendtests(DatabaseTestCase): @@ -47,26 +47,26 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='sqlalchemy', - homepage='https://bitbucket.org/zzzeek/sqlalchemy', - version_url='zzzeek/sqlalchemy', + name="sqlalchemy", + homepage="https://bitbucket.org/zzzeek/sqlalchemy", + version_url="zzzeek/sqlalchemy", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foobar', - homepage='https://bitbucket.org/foo/bar', - version_url='foobar/bar', + name="foobar", + homepage="https://bitbucket.org/foo/bar", + version_url="foobar/bar", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='cherrypy', - homepage='https://bitbucket.org/cherrypy/cherrypy', + name="cherrypy", + homepage="https://bitbucket.org/cherrypy/cherrypy", backend=BACKEND, ) self.session.add(project) @@ -76,21 +76,19 @@ def test_get_version(self): """ Test the get_version function of the BitBucket backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = 'rel_1_1_3' + exp = "rel_1_1_3" obs = backend.BitBucketBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.BitBucketBackend.get_version, - project + AnityaPluginException, backend.BitBucketBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = 'v5.2.0' + exp = "v5.2.0" obs = backend.BitBucketBackend.get_version(project) self.assertEqual(obs, exp) @@ -100,11 +98,11 @@ def test_get_version_url_only_homepage(self): homepage is specified. """ project = models.Project( - name='cherrypy', - homepage='https://bitbucket.org/cherrypy/cherrypy', + name="cherrypy", + homepage="https://bitbucket.org/cherrypy/cherrypy", backend=BACKEND, ) - exp = 'https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags' + exp = "https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags" obs = backend.BitBucketBackend.get_version_url(project) @@ -116,12 +114,12 @@ def test_get_version_url_project_version_url(self): version_url is specified. """ project = models.Project( - name='cherrypy', - homepage='https://example.org', - version_url='https://bitbucket.org/cherrypy/cherrypy', + name="cherrypy", + homepage="https://example.org", + version_url="https://bitbucket.org/cherrypy/cherrypy", backend=BACKEND, ) - exp = 'https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags' + exp = "https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags" obs = backend.BitBucketBackend.get_version_url(project) @@ -133,11 +131,11 @@ def test_get_version_url_slash_homepage(self): homepage ends with /. """ project = models.Project( - name='cherrypy', - homepage='https://bitbucket.org/cherrypy/cherrypy/', + name="cherrypy", + homepage="https://bitbucket.org/cherrypy/cherrypy/", backend=BACKEND, ) - exp = 'https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags' + exp = "https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags" obs = backend.BitBucketBackend.get_version_url(project) @@ -149,12 +147,12 @@ def test_get_version_url_slash_version_url(self): version_url ends with /. """ project = models.Project( - name='cherrypy', - homepage='https://example.org', - version_url='https://bitbucket.org/cherrypy/cherrypy/', + name="cherrypy", + homepage="https://example.org", + version_url="https://bitbucket.org/cherrypy/cherrypy/", backend=BACKEND, ) - exp = 'https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags' + exp = "https://bitbucket.org/cherrypy/cherrypy/downloads?tab=tags" obs = backend.BitBucketBackend.get_version_url(project) @@ -166,11 +164,9 @@ def test_get_version_wrong_homepage(self): homepage is provided. """ project = models.Project( - name='cherrypy', - homepage='https://wrong.org', - backend=BACKEND, + name="cherrypy", homepage="https://wrong.org", backend=BACKEND ) - exp = '' + exp = "" obs = backend.BitBucketBackend.get_version_url(project) @@ -181,42 +177,149 @@ def test_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - 'rel_0_1_0', 'rel_0_1_1', 'rel_0_1_2', 'rel_0_1_3', - 'rel_0_1_4', 'rel_0_1_5', 'rel_0_1_6', 'rel_0_1_7', - 'rel_0_2_0', 'rel_0_2_1', 'rel_0_2_2', 'rel_0_2_3', - 'rel_0_2_4', 'rel_0_2_5', 'rel_0_2_6', 'rel_0_2_7', - 'rel_0_2_8', 'rel_0_3_0', 'rel_0_3_1', 'rel_0_3_2', - 'rel_0_3_3', 'rel_0_3_4', 'rel_0_3_5', 'rel_0_3_6', - 'rel_0_3_7', 'rel_0_3_8', 'rel_0_3_9', 'rel_0_3_10', - 'rel_0_3_11', 'rel_0_4beta1', 'rel_0_4beta2', 'rel_0_4beta3', - 'rel_0_4beta4', 'rel_0_4beta6', 'rel_0_4_0', 'rel_0_4_1', - 'rel_0_4_2', 'rel_0_4_2a', 'rel_0_4_2b', 'rel_0_4_2p3', - 'rel_0_4_3', 'rel_0_4_4', 'rel_0_4_5', 'rel_0_4_6', - 'rel_0_4_7', 'rel_0_4_7p1', 'rel_0_4_8', 'rel_0_5beta1', - 'rel_0_5beta2', 'rel_0_5beta3', 'rel_0_5rc1', 'rel_0_5rc2', - 'rel_0_5rc3', 'rel_0_5rc4', 'rel_0_5_0', 'rel_0_5_1', - 'rel_0_5_2', 'rel_0_5_3', 'rel_0_5_4', 'rel_0_5_4p1', - 'rel_0_5_4p2', 'rel_0_5_5', 'rel_0_5_6', 'rel_0_5_7', - 'rel_0_5_8', 'rel_0_6beta1', 'rel_0_6beta2', 'rel_0_6beta3', - 'rel_0_6_0', 'rel_0_6_1', 'rel_0_6_2', 'rel_0_6_3', - 'rel_0_6_4', 'rel_0_6_5', 'rel_0_6_6', 'rel_0_6_7', 'rel_0_6_8', - 'rel_0_6_9', 'rel_0_7b1', 'rel_0_7b2', 'rel_0_7b3', - 'rel_0_7b4', 'rel_0_7_0', 'rel_0_7_1', 'rel_0_7_2', - 'rel_0_7_3', 'rel_0_7_4', 'rel_0_7_5', 'rel_0_7_6', - 'rel_0_7_7', 'rel_0_7_8', 'rel_0_7_9', 'rel_0_7_10', - 'rel_0_8_0', 'rel_0_8_0b1', 'rel_0_8_0b2', 'rel_0_8_1', - 'rel_0_8_2', 'rel_0_8_3', 'rel_0_8_4', 'rel_0_8_5', - 'rel_0_8_6', 'rel_0_8_7', 'rel_0_9_0', 'rel_0_9_0b1', - 'rel_0_9_1', 'rel_0_9_2', 'rel_0_9_3', 'rel_0_9_4', - 'rel_0_9_5', 'rel_0_9_6', 'rel_0_9_7', 'rel_0_9_8', - 'rel_0_9_9', 'rel_0_9_10', 'rel_1_0_0', 'rel_1_0_0b1', - 'rel_1_0_0b2', 'rel_1_0_0_b3', 'rel_1_0_0b4', 'rel_1_0_0b5', - 'rel_1_0_1', 'rel_1_0_2', 'rel_1_0_3', 'rel_1_0_4', - 'rel_1_0_5', 'rel_1_0_6', 'rel_1_0_7', 'rel_1_0_8', - 'rel_1_0_9', 'rel_1_0_10', 'rel_1_0_11', 'rel_1_0_12', - 'rel_1_0_13', 'rel_1_0_14', 'rel_1_0_15', 'rel_1_1_0', - 'rel_1_1_0b1', 'rel_1_1_0b2', 'rel_1_1_0b3', 'rel_1_1_1', - 'rel_1_1_2', 'rel_1_1_3' + "rel_0_1_0", + "rel_0_1_1", + "rel_0_1_2", + "rel_0_1_3", + "rel_0_1_4", + "rel_0_1_5", + "rel_0_1_6", + "rel_0_1_7", + "rel_0_2_0", + "rel_0_2_1", + "rel_0_2_2", + "rel_0_2_3", + "rel_0_2_4", + "rel_0_2_5", + "rel_0_2_6", + "rel_0_2_7", + "rel_0_2_8", + "rel_0_3_0", + "rel_0_3_1", + "rel_0_3_2", + "rel_0_3_3", + "rel_0_3_4", + "rel_0_3_5", + "rel_0_3_6", + "rel_0_3_7", + "rel_0_3_8", + "rel_0_3_9", + "rel_0_3_10", + "rel_0_3_11", + "rel_0_4beta1", + "rel_0_4beta2", + "rel_0_4beta3", + "rel_0_4beta4", + "rel_0_4beta6", + "rel_0_4_0", + "rel_0_4_1", + "rel_0_4_2", + "rel_0_4_2a", + "rel_0_4_2b", + "rel_0_4_2p3", + "rel_0_4_3", + "rel_0_4_4", + "rel_0_4_5", + "rel_0_4_6", + "rel_0_4_7", + "rel_0_4_7p1", + "rel_0_4_8", + "rel_0_5beta1", + "rel_0_5beta2", + "rel_0_5beta3", + "rel_0_5rc1", + "rel_0_5rc2", + "rel_0_5rc3", + "rel_0_5rc4", + "rel_0_5_0", + "rel_0_5_1", + "rel_0_5_2", + "rel_0_5_3", + "rel_0_5_4", + "rel_0_5_4p1", + "rel_0_5_4p2", + "rel_0_5_5", + "rel_0_5_6", + "rel_0_5_7", + "rel_0_5_8", + "rel_0_6beta1", + "rel_0_6beta2", + "rel_0_6beta3", + "rel_0_6_0", + "rel_0_6_1", + "rel_0_6_2", + "rel_0_6_3", + "rel_0_6_4", + "rel_0_6_5", + "rel_0_6_6", + "rel_0_6_7", + "rel_0_6_8", + "rel_0_6_9", + "rel_0_7b1", + "rel_0_7b2", + "rel_0_7b3", + "rel_0_7b4", + "rel_0_7_0", + "rel_0_7_1", + "rel_0_7_2", + "rel_0_7_3", + "rel_0_7_4", + "rel_0_7_5", + "rel_0_7_6", + "rel_0_7_7", + "rel_0_7_8", + "rel_0_7_9", + "rel_0_7_10", + "rel_0_8_0", + "rel_0_8_0b1", + "rel_0_8_0b2", + "rel_0_8_1", + "rel_0_8_2", + "rel_0_8_3", + "rel_0_8_4", + "rel_0_8_5", + "rel_0_8_6", + "rel_0_8_7", + "rel_0_9_0", + "rel_0_9_0b1", + "rel_0_9_1", + "rel_0_9_2", + "rel_0_9_3", + "rel_0_9_4", + "rel_0_9_5", + "rel_0_9_6", + "rel_0_9_7", + "rel_0_9_8", + "rel_0_9_9", + "rel_0_9_10", + "rel_1_0_0", + "rel_1_0_0b1", + "rel_1_0_0b2", + "rel_1_0_0_b3", + "rel_1_0_0b4", + "rel_1_0_0b5", + "rel_1_0_1", + "rel_1_0_2", + "rel_1_0_3", + "rel_1_0_4", + "rel_1_0_5", + "rel_1_0_6", + "rel_1_0_7", + "rel_1_0_8", + "rel_1_0_9", + "rel_1_0_10", + "rel_1_0_11", + "rel_1_0_12", + "rel_1_0_13", + "rel_1_0_14", + "rel_1_0_15", + "rel_1_1_0", + "rel_1_1_0b1", + "rel_1_1_0b2", + "rel_1_1_0b3", + "rel_1_1_1", + "rel_1_1_2", + "rel_1_1_3", ] obs = backend.BitBucketBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -224,33 +327,67 @@ def test_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.BitBucketBackend.get_versions, - project + AnityaPluginException, backend.BitBucketBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - 'cherrypy-2.0.0-beta', 'cherrypy-2.0.0', 'cherrypy-2.1.0-alpha', - 'cherrypy-2.1.0-rc1', 'cherrypy-2.1.0-rc2', 'cherrypy-2.1.1', - 'cherrypy-2.2.0beta', 'cherrypy-2.2.0rc1', 'cherrypy-2.2.0', - 'cherrypy-2.2.1', 'cherrypy-2.3.0', 'cherrypy-3.0.0beta', - 'cherrypy-3.0.0beta2', 'cherrypy-3.0.0RC1', 'cherrypy-3.0.0', - 'cherrypy-3.0.1', 'cherrypy-3.0.2', 'cherrypy-3.0.3', - 'cherrypy-3.0.4', 'cherrypy-3.1.0beta', 'cherrypy-3.1.0beta2', - 'cherrypy-3.1.0beta3', 'cherrypy-3.1.0', 'cherrypy-3.1.1', - 'cherrypy-3.1.2', 'cherrypy-3.2.0beta', 'cherrypy-3.2.0rc1', - 'cherrypy-3.2.0', 'cherrypy-3.2.1', 'cherrypy-3.2.2rc1', - 'cherrypy-3.2.2', 'rdelon-experimental', 'trunk', '3.2.3', - '3.2.4', '3.2.5', '3.2.6', '3.3.0', '3.4.0', '3.5.0', - '3.6.0', '3.7.0', '3.8.0', '3.8.1', '3.8.2', '4.0.0', '5.0.0', - '5.0.1', '5.1.0', 'v5.2.0' + "cherrypy-2.0.0-beta", + "cherrypy-2.0.0", + "cherrypy-2.1.0-alpha", + "cherrypy-2.1.0-rc1", + "cherrypy-2.1.0-rc2", + "cherrypy-2.1.1", + "cherrypy-2.2.0beta", + "cherrypy-2.2.0rc1", + "cherrypy-2.2.0", + "cherrypy-2.2.1", + "cherrypy-2.3.0", + "cherrypy-3.0.0beta", + "cherrypy-3.0.0beta2", + "cherrypy-3.0.0RC1", + "cherrypy-3.0.0", + "cherrypy-3.0.1", + "cherrypy-3.0.2", + "cherrypy-3.0.3", + "cherrypy-3.0.4", + "cherrypy-3.1.0beta", + "cherrypy-3.1.0beta2", + "cherrypy-3.1.0beta3", + "cherrypy-3.1.0", + "cherrypy-3.1.1", + "cherrypy-3.1.2", + "cherrypy-3.2.0beta", + "cherrypy-3.2.0rc1", + "cherrypy-3.2.0", + "cherrypy-3.2.1", + "cherrypy-3.2.2rc1", + "cherrypy-3.2.2", + "rdelon-experimental", + "trunk", + "3.2.3", + "3.2.4", + "3.2.5", + "3.2.6", + "3.3.0", + "3.4.0", + "3.5.0", + "3.6.0", + "3.7.0", + "3.8.0", + "3.8.1", + "3.8.2", + "4.0.0", + "5.0.0", + "5.0.1", + "5.1.0", + "v5.2.0", ] obs = backend.BitBucketBackend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(BitBucketBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_cpan.py b/anitya/tests/lib/backends/test_cpan.py index 960a45e11..75382037a 100644 --- a/anitya/tests/lib/backends/test_cpan.py +++ b/anitya/tests/lib/backends/test_cpan.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'CPAN (perl)' +BACKEND = "CPAN (perl)" class CpanBackendtests(DatabaseTestCase): @@ -47,17 +47,13 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='SOAP', - homepage='http://search.cpan.org/dist/SOAP/', - backend=BACKEND, + name="SOAP", homepage="http://search.cpan.org/dist/SOAP/", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='http://search.cpan.org/dist/foo/', - backend=BACKEND, + name="foo", homepage="http://search.cpan.org/dist/foo/", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -66,26 +62,22 @@ def test_cpan_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.28' + exp = "0.28" obs = backend.CpanBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.CpanBackend.get_version, - project + AnityaPluginException, backend.CpanBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://metacpan.org/release/test/' + exp = "https://metacpan.org/release/test/" obs = backend.CpanBackend.get_version_url(project) @@ -95,16 +87,14 @@ def test_cpan_get_versions(self): """ Test the get_versions function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['0.28'] + exp = ["0.28"] obs = backend.CpanBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.CpanBackend.get_version, - project + AnityaPluginException, backend.CpanBackend.get_version, project ) def test_cpan_check_feed(self): @@ -112,15 +102,27 @@ def test_cpan_check_feed(self): generator = backend.CpanBackend.check_feed() items = list(generator) - self.assertEqual(items[0], ( - 'URI-Fast', 'https://metacpan.org/release/URI-Fast/', - 'CPAN (perl)', '0.38_06')) - self.assertEqual(items[1], ( - 'Model-Envoy', 'https://metacpan.org/release/Model-Envoy/', - 'CPAN (perl)', '0.2.4')) + self.assertEqual( + items[0], + ( + "URI-Fast", + "https://metacpan.org/release/URI-Fast/", + "CPAN (perl)", + "0.38_06", + ), + ) + self.assertEqual( + items[1], + ( + "Model-Envoy", + "https://metacpan.org/release/Model-Envoy/", + "CPAN (perl)", + "0.2.4", + ), + ) # etc... -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(CpanBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_cran.py b/anitya/tests/lib/backends/test_cran.py index 327834101..6dadf3f77 100644 --- a/anitya/tests/lib/backends/test_cran.py +++ b/anitya/tests/lib/backends/test_cran.py @@ -14,9 +14,9 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # -''' +""" anitya tests for the CRAN backend. -''' +""" import anitya.lib.backends.cran as backend from anitya.db import models @@ -24,7 +24,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'CRAN (R)' +BACKEND = "CRAN (R)" class CranBackendTests(DatabaseTestCase): @@ -39,40 +39,36 @@ def setUp(self): def test_get_version_missing_project(self): """Assert an AnityaPluginException is raised for projects that result in 404.""" project = models.Project( - name='non-existent-name-that-cannot-exist', - homepage='https://cran.r-project.org/web/packages/non-existent-name-that-cannot-exist/', + name="non-existent-name-that-cannot-exist", + homepage="https://cran.r-project.org/web/packages/non-existent-name-that-cannot-exist/", backend=BACKEND, ) self.session.add(project) self.session.commit() self.assertRaises( - AnityaPluginException, - backend.CranBackend.get_version, - project + AnityaPluginException, backend.CranBackend.get_version, project ) def test_get_version(self): """Test the get_version function of the CRAN backend.""" project = models.Project( - name='whisker', - homepage='https://github.com/edwindj/whisker', + name="whisker", + homepage="https://github.com/edwindj/whisker", backend=BACKEND, ) self.session.add(project) self.session.commit() obs = backend.CranBackend.get_version(project) - self.assertEqual(obs, '0.3-2') + self.assertEqual(obs, "0.3-2") def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://crandb.r-pkg.org/test/all' + exp = "https://crandb.r-pkg.org/test/all" obs = backend.CranBackend.get_version_url(project) @@ -81,43 +77,46 @@ def test_get_version_url(self): def test_get_versions_missing_project(self): """Assert an AnityaPluginException is raised for projects that result in 404.""" project = models.Project( - name='non-existent-name-that-cannot-exist', - homepage='https://cran.r-project.org/web/packages/non-existent-name-that-cannot-exist/', + name="non-existent-name-that-cannot-exist", + homepage="https://cran.r-project.org/web/packages/non-existent-name-that-cannot-exist/", backend=BACKEND, ) self.session.add(project) self.session.commit() self.assertRaises( - AnityaPluginException, - backend.CranBackend.get_versions, - project + AnityaPluginException, backend.CranBackend.get_versions, project ) def test_get_versions(self): """ Test the get_versions function of the CRAN backend. """ project = models.Project( - name='whisker', - homepage='https://github.com/edwindj/whisker', + name="whisker", + homepage="https://github.com/edwindj/whisker", backend=BACKEND, ) self.session.add(project) self.session.commit() obs = backend.CranBackend.get_ordered_versions(project) - self.assertEqual(obs, ['0.1', '0.3-2']) + self.assertEqual(obs, ["0.1", "0.3-2"]) def test_check_feed(self): """ Test the check_feed method of the CRAN backend. """ generator = backend.CranBackend.check_feed() items = list(generator) - self.assertEqual(items[0], ( - 'xtractomatic', - 'https://github.com/rmendels/xtractomatic', - 'CRAN (R)', '3.4.2')) - self.assertEqual(items[1], ( - 'FedData', - 'https://github.com/ropensci/FedData', - 'CRAN (R)', '2.5.2')) + self.assertEqual( + items[0], + ( + "xtractomatic", + "https://github.com/rmendels/xtractomatic", + "CRAN (R)", + "3.4.2", + ), + ) + self.assertEqual( + items[1], + ("FedData", "https://github.com/ropensci/FedData", "CRAN (R)", "2.5.2"), + ) # etc... diff --git a/anitya/tests/lib/backends/test_crates.py b/anitya/tests/lib/backends/test_crates.py index 9c904af4c..0bd4d023e 100644 --- a/anitya/tests/lib/backends/test_crates.py +++ b/anitya/tests/lib/backends/test_crates.py @@ -43,14 +43,12 @@ def setUp(self): def create_project(self): """Create some basic projects to work with.""" project1 = models.Project( - name='itoa', - homepage='https://crates.io/crates/itoa', - backend='crates.io', + name="itoa", homepage="https://crates.io/crates/itoa", backend="crates.io" ) project2 = models.Project( - name='pleasedontmakethisprojectitllbreakmytests', - homepage='https://crates.io/crates/somenonsensehomepage', - backend='crates.io', + name="pleasedontmakethisprojectitllbreakmytests", + homepage="https://crates.io/crates/somenonsensehomepage", + backend="crates.io", ) self.session.add(project1) self.session.add(project2) @@ -59,25 +57,21 @@ def create_project(self): def test_get_version(self): """Test the get_version function of the crates backend.""" project = models.Project.by_id(self.session, 1) - self.assertEqual('0.2.1', crates.CratesBackend.get_version(project)) + self.assertEqual("0.2.1", crates.CratesBackend.get_version(project)) def test_get_version_missing(self): """Assert an exception is raised if a project doesn't exist and get_version is called""" project = models.Project.get(self.session, 2) self.assertRaises( - AnityaPluginException, - crates.CratesBackend.get_version, - project + AnityaPluginException, crates.CratesBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend='crates.io', + name="test", homepage="http://example.org", backend="crates.io" ) - exp = 'https://crates.io/api/v1/crates/test/versions' + exp = "https://crates.io/api/v1/crates/test/versions" obs = crates.CratesBackend.get_version_url(project) @@ -85,25 +79,27 @@ def test_get_version_url(self): def test_get_versions(self): """Test the get_versions function of the crates backend.""" - expected_versions = ['0.2.1', '0.2.0', '0.1.1', '0.1.0'] + expected_versions = ["0.2.1", "0.2.0", "0.1.1", "0.1.0"] project = models.Project.by_id(self.session, 1) self.assertEqual(expected_versions, crates.CratesBackend.get_versions(project)) def test_get_ordered_versions(self): """Test the get_ordered_versions function of the crates backend. """ - expected_versions = ['0.2.1', '0.2.0', '0.1.1', '0.1.0'] + expected_versions = ["0.2.1", "0.2.0", "0.1.1", "0.1.0"] project = models.Project.by_id(self.session, 1) - self.assertEqual(expected_versions, crates.CratesBackend.get_ordered_versions(project)) + self.assertEqual( + expected_versions, crates.CratesBackend.get_ordered_versions(project) + ) - @mock.patch('anitya.lib.backends.crates.CratesBackend.call_url') + @mock.patch("anitya.lib.backends.crates.CratesBackend.call_url") def test__get_versions_no_json(self, mock_call_url): """Assert we handle getting non-JSON responses gracefully""" mock_call_url.return_value.json.side_effect = ValueError project = models.Project.by_id(self.session, 1) with self.assertRaises(AnityaPluginException) as context_manager: crates.CratesBackend._get_versions(project) - self.assertIn('Failed to decode JSON', str(context_manager.exception)) + self.assertIn("Failed to decode JSON", str(context_manager.exception)) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/anitya/tests/lib/backends/test_custom.py b/anitya/tests/lib/backends/test_custom.py index 024502cf6..c92ff601b 100644 --- a/anitya/tests/lib/backends/test_custom.py +++ b/anitya/tests/lib/backends/test_custom.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -30,7 +30,7 @@ from anitya.lib.exceptions import AnityaPluginException from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'custom' +BACKEND = "custom" class CustomBackendtests(DatabaseTestCase): @@ -46,29 +46,29 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='geany', - homepage='https://www.geany.org/', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', + name="geany", + homepage="https://www.geany.org/", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://pypi.python.org/pypi/repo_manager_fake', - regex='DEFAULT', + name="fake", + homepage="https://pypi.python.org/pypi/repo_manager_fake", + regex="DEFAULT", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='subsurface', - homepage='https://subsurface-divelog.org/', - version_url='https://subsurface-divelog.org/downloads/', - regex='DEFAULT', + name="subsurface", + homepage="https://subsurface-divelog.org/", + version_url="https://subsurface-divelog.org/downloads/", + regex="DEFAULT", backend=BACKEND, ) self.session.add(project) @@ -78,30 +78,28 @@ def test_custom_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '1.33' + exp = "1.33" obs = backend.CustomBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.CustomBackend.get_version, - project + AnityaPluginException, backend.CustomBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '4.7.7' + exp = "4.7.7" obs = backend.CustomBackend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) exp = project.version_url @@ -114,31 +112,54 @@ def test_custom_get_versions(self): """ Test the get_versions function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['1.33'] + exp = ["1.33"] obs = backend.CustomBackend.get_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.CustomBackend.get_version, - project + AnityaPluginException, backend.CustomBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'3.1.1', u'4.0', u'4.0.1', u'4.0.2', u'4.0.3', - u'4.1', u'4.2', u'4.3', u'4.4.0', u'4.4.1', u'4.4.2', - u'4.5.0', u'4.5.1', u'4.5.2', u'4.5.3', u'4.5.4', u'4.5.5', u'4.5.6', - u'4.6.0', u'4.6.1', u'4.6.2', u'4.6.3', u'4.6.4', - u'4.7.1', u'4.7.2', u'4.7.3', u'4.7.4', u'4.7.5', u'4.7.6', u'4.7.7', + u"3.1.1", + u"4.0", + u"4.0.1", + u"4.0.2", + u"4.0.3", + u"4.1", + u"4.2", + u"4.3", + u"4.4.0", + u"4.4.1", + u"4.4.2", + u"4.5.0", + u"4.5.1", + u"4.5.2", + u"4.5.3", + u"4.5.4", + u"4.5.5", + u"4.5.6", + u"4.6.0", + u"4.6.1", + u"4.6.2", + u"4.6.3", + u"4.6.4", + u"4.7.1", + u"4.7.2", + u"4.7.3", + u"4.7.4", + u"4.7.5", + u"4.7.6", + u"4.7.7", ] obs = backend.CustomBackend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(CustomBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_debian.py b/anitya/tests/lib/backends/test_debian.py index eaf02c7c9..8e8f3c2b8 100644 --- a/anitya/tests/lib/backends/test_debian.py +++ b/anitya/tests/lib/backends/test_debian.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the debian backend. -''' +""" import unittest @@ -32,7 +32,7 @@ from anitya.db import models -BACKEND = 'Debian project' +BACKEND = "Debian project" class DebianBackendtests(DatabaseTestCase): @@ -48,25 +48,23 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='guake', - homepage='http://ftp.debian.org/debian/pool/main/g/guake/', + name="guake", + homepage="http://ftp.debian.org/debian/pool/main/g/guake/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://pecl.php.net/package/foo', - backend=BACKEND, + name="foo", homepage="https://pecl.php.net/package/foo", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='libgnupg-interface-perl', - homepage='http://ftp.debian.org/debian/pool/main/' - 'libg/libgnupg-interface-perl/', + name="libgnupg-interface-perl", + homepage="http://ftp.debian.org/debian/pool/main/" + "libg/libgnupg-interface-perl/", backend=BACKEND, ) self.session.add(project) @@ -76,33 +74,31 @@ def test_get_version(self): """ Test the get_version function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.7.2' + exp = "0.7.2" obs = backend.DebianBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.DebianBackend.get_version, - project + AnityaPluginException, backend.DebianBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '0.52' + exp = "0.52" obs = backend.DebianBackend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'http://ftp.debian.org/debian/pool/main/t/test/' + exp = "http://ftp.debian.org/debian/pool/main/t/test/" obs = backend.DebianBackend.get_version_url(project) @@ -113,12 +109,12 @@ def test_get_version_url_lib_prefix(self): Assert that correct url is returned when name contains lib prefix. """ project = models.Project( - name='libtest', - homepage='http://example.org', - version_url='http://example.org/releases', + name="libtest", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'http://ftp.debian.org/debian/pool/main/libt/libtest/' + exp = "http://ftp.debian.org/debian/pool/main/libt/libtest/" obs = backend.DebianBackend.get_version_url(project) @@ -128,11 +124,7 @@ def test_get_versions(self): """ Test the get_versions function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = [ - u'0.4.2', u'0.4.3', u'0.4.4', - u'0.5.0', - u'0.7.0', u'0.7.2', - ] + exp = [u"0.4.2", u"0.4.3", u"0.4.4", u"0.5.0", u"0.7.0", u"0.7.2"] obs = backend.DebianBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -143,16 +135,14 @@ def test_get_versions_http_404(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.DebianBackend.get_version, - project + AnityaPluginException, backend.DebianBackend.get_version, project ) def test_get_versions_no_z_release(self): """Assert the Debian backend handles versions in the format X.Y""" pid = 3 project = models.Project.get(self.session, pid) - exp = [u'0.45', u'0.50', u'0.52'] + exp = [u"0.45", u"0.50", u"0.52"] obs = backend.DebianBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -166,11 +156,11 @@ def test_debian_regex_with_orig(self): """ versions = get_versions_by_regex_for_text( tarball_names, - 'https://example.com', - backend.DEBIAN_REGEX % {'name': 'libgnupg-interface-perl'}, - models.Project.get(self.session, 3) + "https://example.com", + backend.DEBIAN_REGEX % {"name": "libgnupg-interface-perl"}, + models.Project.get(self.session, 3), ) - self.assertEqual(sorted(['0.45', '0.46']), sorted(versions)) + self.assertEqual(sorted(["0.45", "0.46"]), sorted(versions)) def test_debian_regex_without_orig(self): """Assert Debian tarballs without the ".orig" string work""" @@ -182,13 +172,13 @@ def test_debian_regex_without_orig(self): """ versions = get_versions_by_regex_for_text( tarball_names, - 'https://example.com', - backend.DEBIAN_REGEX % {'name': 'libgnupg-interface-perl'}, - models.Project.get(self.session, 3) + "https://example.com", + backend.DEBIAN_REGEX % {"name": "libgnupg-interface-perl"}, + models.Project.get(self.session, 3), ) - self.assertEqual(sorted(['0.45', '0.46']), sorted(versions)) + self.assertEqual(sorted(["0.45", "0.46"]), sorted(versions)) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(DebianBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_drupal6.py b/anitya/tests/lib/backends/test_drupal6.py index ce1492e43..bf4de254d 100644 --- a/anitya/tests/lib/backends/test_drupal6.py +++ b/anitya/tests/lib/backends/test_drupal6.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Drupal6' +BACKEND = "Drupal6" class Drupal6Backendtests(DatabaseTestCase): @@ -47,24 +47,22 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='wysiwyg', - homepage='https://www.drupal.org/project/wysiwyg', + name="wysiwyg", + homepage="https://www.drupal.org/project/wysiwyg", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://pecl.php.net/package/foo', - backend=BACKEND, + name="foo", homepage="https://pecl.php.net/package/foo", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='admin_menu', - homepage='https://www.drupal.org/project/admin_menu', + name="admin_menu", + homepage="https://www.drupal.org/project/admin_menu", backend=BACKEND, ) self.session.add(project) @@ -74,33 +72,31 @@ def test_get_version(self): """ Test the get_version function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '2.4' + exp = "2.4" obs = backend.Drupal6Backend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.Drupal6Backend.get_version, - project + AnityaPluginException, backend.Drupal6Backend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '3.0-alpha4' + exp = "3.0-alpha4" obs = backend.Drupal6Backend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/test/6.x' + exp = "https://updates.drupal.org/release-history/test/6.x" obs = backend.Drupal6Backend.get_version_url(project) @@ -111,12 +107,12 @@ def test_get_version_url_drupal6_prefix(self): Assert that correct url is returned when project name has 'drupal6:' prefix. """ project = models.Project( - name='drupal6:test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="drupal6:test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/test/6.x' + exp = "https://updates.drupal.org/release-history/test/6.x" obs = backend.Drupal6Backend.get_version_url(project) @@ -127,12 +123,12 @@ def test_get_version_url_contains_dash(self): Assert that correct url is returned when project name contains '-'. """ project = models.Project( - name='te-st', - homepage='http://example.org', - version_url='http://example.org/releases', + name="te-st", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/te_st/6.x' + exp = "https://updates.drupal.org/release-history/te_st/6.x" obs = backend.Drupal6Backend.get_version_url(project) @@ -142,27 +138,41 @@ def test_get_versions(self): """ Test the get_versions function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['2.x-dev', '2.0-alpha1', '2.0', '2.1', '2.2', '2.3', '2.4'] + exp = ["2.x-dev", "2.0-alpha1", "2.0", "2.1", "2.2", "2.3", "2.4"] obs = backend.Drupal6Backend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.Drupal6Backend.get_version, - project + AnityaPluginException, backend.Drupal6Backend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = ['1.x-dev', '1.0-beta', '1.0', '1.1', '1.2', '1.3', '1.4', - '1.5', '1.6', '1.7', '1.8', '1.9', '3.x-dev', '3.0-alpha1', - '3.0-alpha2', '3.0-alpha3', '3.0-alpha4'] + exp = [ + "1.x-dev", + "1.0-beta", + "1.0", + "1.1", + "1.2", + "1.3", + "1.4", + "1.5", + "1.6", + "1.7", + "1.8", + "1.9", + "3.x-dev", + "3.0-alpha1", + "3.0-alpha2", + "3.0-alpha3", + "3.0-alpha4", + ] obs = backend.Drupal6Backend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Drupal6Backendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_drupal7.py b/anitya/tests/lib/backends/test_drupal7.py index 4cf1dc43d..a5d9d5501 100644 --- a/anitya/tests/lib/backends/test_drupal7.py +++ b/anitya/tests/lib/backends/test_drupal7.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Drupal7' +BACKEND = "Drupal7" class Drupal7Backendtests(DatabaseTestCase): @@ -47,24 +47,22 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='wysiwyg', - homepage='https://www.drupal.org/project/wysiwyg', + name="wysiwyg", + homepage="https://www.drupal.org/project/wysiwyg", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://pecl.php.net/package/foo', - backend=BACKEND, + name="foo", homepage="https://pecl.php.net/package/foo", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='admin_menu', - homepage='https://www.drupal.org/project/admin_menu', + name="admin_menu", + homepage="https://www.drupal.org/project/admin_menu", backend=BACKEND, ) self.session.add(project) @@ -74,33 +72,31 @@ def test_get_version(self): """ Test the get_version function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '2.2' + exp = "2.2" obs = backend.Drupal7Backend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.Drupal7Backend.get_version, - project + AnityaPluginException, backend.Drupal7Backend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '3.0-rc5' + exp = "3.0-rc5" obs = backend.Drupal7Backend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/test/7.x' + exp = "https://updates.drupal.org/release-history/test/7.x" obs = backend.Drupal7Backend.get_version_url(project) @@ -111,12 +107,12 @@ def test_get_version_url_drupal7_prefix(self): Assert that correct url is returned when project name has 'drupal7:' prefix. """ project = models.Project( - name='drupal7:test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="drupal7:test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/test/7.x' + exp = "https://updates.drupal.org/release-history/test/7.x" obs = backend.Drupal7Backend.get_version_url(project) @@ -127,12 +123,12 @@ def test_get_version_url_contains_dash(self): Assert that correct url is returned when project name contains '-'. """ project = models.Project( - name='te-st', - homepage='http://example.org', - version_url='http://example.org/releases', + name="te-st", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) - exp = 'https://updates.drupal.org/release-history/te_st/7.x' + exp = "https://updates.drupal.org/release-history/te_st/7.x" obs = backend.Drupal7Backend.get_version_url(project) @@ -142,25 +138,23 @@ def test_get_versions(self): """ Test the get_versions function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['2.x-dev', '2.0', '2.1', '2.2'] + exp = ["2.x-dev", "2.0", "2.1", "2.2"] obs = backend.Drupal7Backend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.Drupal7Backend.get_version, - project + AnityaPluginException, backend.Drupal7Backend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = ['3.x-dev', '3.0-rc1', '3.0-rc2', '3.0-rc3', '3.0-rc4', '3.0-rc5'] + exp = ["3.x-dev", "3.0-rc1", "3.0-rc2", "3.0-rc3", "3.0-rc4", "3.0-rc5"] obs = backend.Drupal7Backend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Drupal7Backendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_folder.py b/anitya/tests/lib/backends/test_folder.py index 2f9f3c6d7..8c5a33993 100644 --- a/anitya/tests/lib/backends/test_folder.py +++ b/anitya/tests/lib/backends/test_folder.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the folder backend. -''' +""" import unittest @@ -33,7 +33,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro # NOQA -BACKEND = 'folder' +BACKEND = "folder" class FolderBackendtests(DatabaseTestCase): @@ -49,17 +49,17 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='gnash', - homepage='https://www.gnu.org/software/gnash/', - version_url='https://ftp.gnu.org/pub/gnu/gnash/', + name="gnash", + homepage="https://www.gnu.org/software/gnash/", + version_url="https://ftp.gnu.org/pub/gnu/gnash/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://pypi.python.org/pypi/repo_manager_fake', + name="fake", + homepage="https://pypi.python.org/pypi/repo_manager_fake", backend=BACKEND, insecure=True, ) @@ -67,9 +67,9 @@ def create_project(self): self.session.commit() project = models.Project( - name='subsurface', - homepage='https://subsurface-divelog.org/', - version_url='https://subsurface-divelog.org/downloads/', + name="subsurface", + homepage="https://subsurface-divelog.org/", + version_url="https://subsurface-divelog.org/downloads/", backend=BACKEND, ) self.session.add(project) @@ -79,30 +79,28 @@ def test_folder_get_version(self): """ Test the get_version function of the folder backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.8.10' + exp = "0.8.10" obs = backend.FolderBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FolderBackend.get_version, - project + AnityaPluginException, backend.FolderBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '4.7.7' + exp = "4.7.7" obs = backend.FolderBackend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='http://example.org/releases', + name="test", + homepage="http://example.org", + version_url="http://example.org/releases", backend=BACKEND, ) exp = project.version_url @@ -116,12 +114,10 @@ def test_folder_get_versions_insecure(self): pid = 2 project = models.Project.get(self.session, pid) - with mock.patch('anitya.lib.backends.BaseBackend.call_url') as m_call: + with mock.patch("anitya.lib.backends.BaseBackend.call_url") as m_call: m_call.side_effect = backend.BaseBackend.call_url self.assertRaises( - AnityaPluginException, - backend.FolderBackend.get_versions, - project + AnityaPluginException, backend.FolderBackend.get_versions, project ) m_call.assert_called_with(project.version_url, insecure=True) @@ -130,9 +126,19 @@ def test_folder_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'0.7.1', u'0.7.2', u'0.8.0', u'0.8.1', u'0.8.2', u'0.8.3', - u'0.8.4', u'0.8.5', u'0.8.6', u'0.8.7', u'0.8.8', u'0.8.9', - u'0.8.10' + u"0.7.1", + u"0.7.2", + u"0.8.0", + u"0.8.1", + u"0.8.2", + u"0.8.3", + u"0.8.4", + u"0.8.5", + u"0.8.6", + u"0.8.7", + u"0.8.8", + u"0.8.9", + u"0.8.10", ] obs = backend.FolderBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -140,24 +146,47 @@ def test_folder_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FolderBackend.get_version, - project + AnityaPluginException, backend.FolderBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'3.1.1', u'4.0', u'4.0.1', u'4.0.2', u'4.0.3', u'4.1', u'4.2', - u'4.3', u'4.4.0', u'4.4.1', u'4.4.2', - u'4.5.0', u'4.5.1', u'4.5.2', u'4.5.3', u'4.5.4', u'4.5.5', u'4.5.6', - u'4.6.0', u'4.6.1', u'4.6.2', u'4.6.3', u'4.6.4', - u'4.7.1', u'4.7.2', u'4.7.3', u'4.7.4', u'4.7.5', u'4.7.6', u'4.7.7', + u"3.1.1", + u"4.0", + u"4.0.1", + u"4.0.2", + u"4.0.3", + u"4.1", + u"4.2", + u"4.3", + u"4.4.0", + u"4.4.1", + u"4.4.2", + u"4.5.0", + u"4.5.1", + u"4.5.2", + u"4.5.3", + u"4.5.4", + u"4.5.5", + u"4.5.6", + u"4.6.0", + u"4.6.1", + u"4.6.2", + u"4.6.3", + u"4.6.4", + u"4.7.1", + u"4.7.2", + u"4.7.3", + u"4.7.4", + u"4.7.5", + u"4.7.6", + u"4.7.7", ] obs = backend.FolderBackend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(FolderBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_freshmeat.py b/anitya/tests/lib/backends/test_freshmeat.py index cdec2bd0e..d5ba58340 100644 --- a/anitya/tests/lib/backends/test_freshmeat.py +++ b/anitya/tests/lib/backends/test_freshmeat.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Freshmeat' +BACKEND = "Freshmeat" class FreshmeatBackendtests(DatabaseTestCase): @@ -47,24 +47,22 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='atmail', - homepage='http://freecode.com/projects/atmail', + name="atmail", + homepage="http://freecode.com/projects/atmail", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='http://freecode.com/projects/foo', - backend=BACKEND, + name="foo", homepage="http://freecode.com/projects/foo", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='awstats', - homepage='http://freecode.com/projects/awstats', + name="awstats", + homepage="http://freecode.com/projects/awstats", backend=BACKEND, ) self.session.add(project) @@ -74,34 +72,28 @@ def test_get_version(self): """ Test the get_version function of the freshmeat backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '7' + exp = "7" obs = backend.FreshmeatBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FreshmeatBackend.get_version, - project + AnityaPluginException, backend.FreshmeatBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FreshmeatBackend.get_version, - project + AnityaPluginException, backend.FreshmeatBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'http://freshmeat.net/projects/test' + exp = "http://freshmeat.net/projects/test" obs = backend.FreshmeatBackend.get_version_url(project) @@ -111,27 +103,23 @@ def test_get_versions(self): """ Test the get_versions function of the debian backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['6.3.5', '6.5.0', '6.6.0', '6.30.3', '7'] + exp = ["6.3.5", "6.5.0", "6.6.0", "6.30.3", "7"] obs = backend.FreshmeatBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FreshmeatBackend.get_versions, - project + AnityaPluginException, backend.FreshmeatBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.FreshmeatBackend.get_versions, - project + AnityaPluginException, backend.FreshmeatBackend.get_versions, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(FreshmeatBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_github.py b/anitya/tests/lib/backends/test_github.py index be08e7ed4..7c2fc6616 100644 --- a/anitya/tests/lib/backends/test_github.py +++ b/anitya/tests/lib/backends/test_github.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the github backend. -''' +""" import unittest @@ -32,7 +32,7 @@ from anitya.lib.exceptions import AnityaPluginException, RateLimitException from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'GitHub' +BACKEND = "GitHub" class GithubBackendtests(DatabaseTestCase): @@ -48,70 +48,64 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='fedocal', - homepage='https://github.com/fedora-infra/fedocal', - version_url='fedora-infra/fedocal', + name="fedocal", + homepage="https://github.com/fedora-infra/fedocal", + version_url="fedora-infra/fedocal", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='foobar', - homepage='https://github.com/foo/bar', - version_url='foobar/bar', + name="foobar", + homepage="https://github.com/foo/bar", + version_url="foobar/bar", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='pkgdb2', - homepage='https://github.com/fedora-infra/pkgdb2/', + name="pkgdb2", + homepage="https://github.com/fedora-infra/pkgdb2/", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='foobar', - homepage='https://github.com/foo', - backend=BACKEND, + name="foobar", homepage="https://github.com/foo", backend=BACKEND ) self.session.add(project) project = models.Project( - name='foobar', - homepage='http://github.com/foo/bar', - backend=BACKEND, + name="foobar", homepage="http://github.com/foo/bar", backend=BACKEND ) self.session.add(project) project = models.Project( - name='fpdc', - homepage='https://github.com/fedora-infra/fpdc', + name="fpdc", + homepage="https://github.com/fedora-infra/fpdc", backend=BACKEND, ) self.session.add(project) self.session.commit() - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "foobar"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "foobar"}) def test_get_version(self): """ Test the get_version function of the github backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.16' + exp = "0.16" obs = backend.GithubBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_version, - project + AnityaPluginException, backend.GithubBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '2.7.1' + exp = "2.7.1" obs = backend.GithubBackend.get_version(project) self.assertEqual(obs, exp) @@ -120,12 +114,12 @@ def test_get_version_url_project_version_url(self): Assert that correct url is returned when project version url is specified. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='test/test', + name="test", + homepage="http://example.org", + version_url="test/test", backend=BACKEND, ) - exp = 'https://github.com/test/test/tags' + exp = "https://github.com/test/test/tags" obs = backend.GithubBackend.get_version_url(project) @@ -137,11 +131,9 @@ def test_get_version_url_project_homepage_only(self): project homepage is specified. """ project = models.Project( - name='test', - homepage='https://github.com/test/test', - backend=BACKEND, + name="test", homepage="https://github.com/test/test", backend=BACKEND ) - exp = 'https://github.com/test/test/tags' + exp = "https://github.com/test/test/tags" obs = backend.GithubBackend.get_version_url(project) @@ -153,11 +145,9 @@ def test_get_version_url_project_wrong_homepage(self): project homepage is wrong. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = '' + exp = "" obs = backend.GithubBackend.get_version_url(project) @@ -169,11 +159,9 @@ def test_get_version_url_homepage_slash(self): project homepage ends with '/'. """ project = models.Project( - name='test', - homepage='https://github.com/test/test/', - backend=BACKEND, + name="test", homepage="https://github.com/test/test/", backend=BACKEND ) - exp = 'https://github.com/test/test/tags' + exp = "https://github.com/test/test/tags" obs = backend.GithubBackend.get_version_url(project) @@ -185,33 +173,61 @@ def test_get_version_url_version_url_slash(self): version url ends with '/'. """ project = models.Project( - name='test', - homepage='https://example.com', - version_url='test/test/', + name="test", + homepage="https://example.com", + version_url="test/test/", backend=BACKEND, ) - exp = 'https://github.com/test/test/tags' + exp = "https://github.com/test/test/tags" obs = backend.GithubBackend.get_version_url(project) self.assertEqual(obs, exp) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "foobar"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "foobar"}) def test_get_versions(self): """ Test the get_versions function of the github backend. """ pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'v.0.4.6', u'v0.1.0', u'v0.1.1', u'v0.1.2', - u'v0.2.0', u'v0.3.0', u'v0.3.1', u'v0.4.0', - u'v0.4.1', u'v0.4.2', u'v0.4.3', u'v0.4.5', - u'v0.4.7', u'v0.5.0', u'v0.5.1', u'v0.6.0', - u'v0.6.1', u'v0.6.2', u'v0.6.3', u'v0.7', - u'v0.7.1', u'v0.8', u'v0.9', u'v0.9.1', - u'v0.9.2', u'v0.9.3', u'0.10', u'0.11', - u'0.11.1', u'0.12', u'0.13', u'0.13.1', - u'0.13.2', u'0.13.3', u'0.14', u'0.15', - u'0.15.1', u'0.16' + u"v.0.4.6", + u"v0.1.0", + u"v0.1.1", + u"v0.1.2", + u"v0.2.0", + u"v0.3.0", + u"v0.3.1", + u"v0.4.0", + u"v0.4.1", + u"v0.4.2", + u"v0.4.3", + u"v0.4.5", + u"v0.4.7", + u"v0.5.0", + u"v0.5.1", + u"v0.6.0", + u"v0.6.1", + u"v0.6.2", + u"v0.6.3", + u"v0.7", + u"v0.7.1", + u"v0.8", + u"v0.9", + u"v0.9.1", + u"v0.9.2", + u"v0.9.3", + u"0.10", + u"0.11", + u"0.11.1", + u"0.12", + u"0.13", + u"0.13.1", + u"0.13.2", + u"0.13.3", + u"0.14", + u"0.15", + u"0.15.1", + u"0.16", ] obs = backend.GithubBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -219,26 +235,62 @@ def test_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'1.21', u'1.22', u'1.22.1', u'1.22.2', - u'1.23', u'1.23.99', u'1.23.991', u'1.23.992', - u'1.23.993', u'1.23.994', u'1.23.995', u'1.24', - u'1.24.1', u'1.24.2', u'1.24.3', u'1.25', - u'1.25.1', u'1.26', u'1.27', u'1.28', - u'1.28.1', u'1.28.2', u'1.29', u'1.30', - u'1.30.1', u'1.31', u'1.32', u'1.32.1', - u'1.32.2', u'1.33.0', u'1.33.1', u'1.33.2', - u'1.33.3', u'2.0', u'2.0.1', u'2.0.2', u'2.0.3', - u'2.1', u'2.2', u'2.3', u'2.4', u'2.4.1', u'2.4.2', - u'2.4.3', u'2.5', u'2.6', u'2.6.1', - u'2.6.2', u'2.7', u'2.7.1' + u"1.21", + u"1.22", + u"1.22.1", + u"1.22.2", + u"1.23", + u"1.23.99", + u"1.23.991", + u"1.23.992", + u"1.23.993", + u"1.23.994", + u"1.23.995", + u"1.24", + u"1.24.1", + u"1.24.2", + u"1.24.3", + u"1.25", + u"1.25.1", + u"1.26", + u"1.27", + u"1.28", + u"1.28.1", + u"1.28.2", + u"1.29", + u"1.30", + u"1.30.1", + u"1.31", + u"1.32", + u"1.32.1", + u"1.32.2", + u"1.33.0", + u"1.33.1", + u"1.33.2", + u"1.33.3", + u"2.0", + u"2.0.1", + u"2.0.2", + u"2.0.3", + u"2.1", + u"2.2", + u"2.3", + u"2.4", + u"2.4.1", + u"2.4.2", + u"2.4.3", + u"2.5", + u"2.6", + u"2.6.1", + u"2.6.2", + u"2.7", + u"2.7.1", ] obs = backend.GithubBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -246,20 +298,16 @@ def test_get_versions(self): pid = 4 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) pid = 5 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': None}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": None}) def test_get_versions_no_token(self): """ Test the get_versions function of the github backend without specified token. @@ -267,12 +315,10 @@ def test_get_versions_no_token(self): pid = 1 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "Not_found"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "Not_found"}) def test_get_versions_unauthorized(self): """ Test the get_versions function of the github backend with invalid token. @@ -280,13 +326,11 @@ def test_get_versions_unauthorized(self): pid = 1 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "Not_found"}) - @mock.patch('anitya.lib.backends.github.API_URL', "foobar") + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "Not_found"}) + @mock.patch("anitya.lib.backends.github.API_URL", "foobar") def test_get_versions_invalid_url(self): """ Test the get_versions function of the github backend with invalid URL. @@ -294,12 +338,10 @@ def test_get_versions_invalid_url(self): pid = 1 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "foobar"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "foobar"}) def test_get_versions_no_version_retrieved(self): """ Test the get_versions function of the github backend with project which doesn't have any tag. @@ -307,34 +349,33 @@ def test_get_versions_no_version_retrieved(self): pid = 6 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GithubBackend.get_versions, - project + AnityaPluginException, backend.GithubBackend.get_versions, project ) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "foobar"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "foobar"}) def test_plexus_utils(self): """ Regression test for issue #286 """ project = models.Project( - version_url='codehaus-plexus/plexus-archiver', - version_prefix='plexus-archiver-', + version_url="codehaus-plexus/plexus-archiver", + version_prefix="plexus-archiver-", backend=BACKEND, ) version = backend.GithubBackend().get_version(project) - self.assertEqual(u'plexus-archiver-3.6.0', version) + self.assertEqual(u"plexus-archiver-3.6.0", version) class JsonTests(unittest.TestCase): """ Unit tests for json related functions """ + def __init__(self, *args, **kwargs): super(JsonTests, self).__init__(*args, **kwargs) self.maxDiff = None def test_prepare_query_after(self): """ Assert query creation with cursor """ - exp = ''' + exp = """ { repository(owner: "foo", name: "bar") { refs (refPrefix: "refs/tags/", last:50, @@ -356,14 +397,14 @@ def test_prepare_query_after(self): remaining resetAt } -}''' +}""" obs = backend.prepare_query("foo", "bar", "abc") self.assertMultiLineEqual(exp, obs) def test_prepare_query(self): """ Assert query creation """ - exp = ''' + exp = """ { repository(owner: "foo", name: "bar") { refs (refPrefix: "refs/tags/", last:50, @@ -385,7 +426,7 @@ def test_prepare_query(self): remaining resetAt } -}''' +}""" obs = backend.prepare_query("foo", "bar") self.assertEqual(exp, obs) @@ -393,71 +434,37 @@ def test_prepare_query(self): def test_parse_json(self): """ Assert parsing json""" project = models.Project( - name='foobar', - homepage='https://foobar.com', - version_url='foo/bar', + name="foobar", + homepage="https://foobar.com", + version_url="foo/bar", backend=BACKEND, ) - json = { - "errors": [ - { - "type": "FOO", - "message": "BAR" - } - ] - } + json = {"errors": [{"type": "FOO", "message": "BAR"}]} - self.assertRaises( - AnityaPluginException, - backend.parse_json, - json, - project - ) + self.assertRaises(AnityaPluginException, backend.parse_json, json, project) # Limit reached json = { "data": { - "repository": { - "refs": { - "totalCount": 0 - } - }, + "repository": {"refs": {"totalCount": 0}}, "rateLimit": { "limit": 5000, "remaining": 0, - "resetAt": "2008-09-03T20:56:35.450686" - } + "resetAt": "2008-09-03T20:56:35.450686", + }, } } - self.assertRaises( - RateLimitException, - backend.parse_json, - json, - project - ) + self.assertRaises(RateLimitException, backend.parse_json, json, project) json = { "data": { "repository": { - "refs": { - "totalCount": 1, - "edges": [ - { - "node": { - "name": "1.0" - } - } - ] - } + "refs": {"totalCount": 1, "edges": [{"node": {"name": "1.0"}}]} }, - "rateLimit": { - "limit": 5000, - "remaining": 5000, - "resetAt": "dummy" - } + "rateLimit": {"limit": 5000, "remaining": 5000, "resetAt": "dummy"}, } } - exp = [u'1.0'] + exp = [u"1.0"] obs = backend.parse_json(json, project) self.assertEqual(exp, obs) @@ -467,33 +474,24 @@ def test_parse_json_threshold_reach(self): rate limit threshold is reached. """ project = models.Project( - name='foobar', - homepage='https://foobar.com', - version_url='foo/bar', + name="foobar", + homepage="https://foobar.com", + version_url="foo/bar", backend=BACKEND, ) json = { "data": { - "repository": { - "refs": { - "totalCount": 0 - } - }, + "repository": {"refs": {"totalCount": 0}}, "rateLimit": { "limit": 5000, "remaining": 500, - "resetAt": "2008-09-03T20:56:35.450686" - } + "resetAt": "2008-09-03T20:56:35.450686", + }, } } - self.assertRaises( - RateLimitException, - backend.parse_json, - json, - project - ) + self.assertRaises(RateLimitException, backend.parse_json, json, project) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(GithubBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_gitlab.py b/anitya/tests/lib/backends/test_gitlab.py index 13bf0a5a0..aa0dd70c8 100644 --- a/anitya/tests/lib/backends/test_gitlab.py +++ b/anitya/tests/lib/backends/test_gitlab.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" Anitya tests for the GitLab backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'GitLab' +BACKEND = "GitLab" class GitlabBackendtests(DatabaseTestCase): @@ -47,31 +47,31 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='gnome-video-arcade', - homepage='https://gitlab.gnome.org/GNOME/gnome-video-arcade', - version_url='https://gitlab.gnome.org/GNOME/gnome-video-arcade', + name="gnome-video-arcade", + homepage="https://gitlab.gnome.org/GNOME/gnome-video-arcade", + version_url="https://gitlab.gnome.org/GNOME/gnome-video-arcade", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='foobar', - homepage='https://gitlab.com/foo/bar', - version_url='https://gitlab.com/foo/bar', + name="foobar", + homepage="https://gitlab.com/foo/bar", + version_url="https://gitlab.com/foo/bar", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='xonotic', - homepage='https://gitlab.com/xonotic/xonotic', + name="xonotic", + homepage="https://gitlab.com/xonotic/xonotic", backend=BACKEND, ) self.session.add(project) project = models.Project( - name='project_1', - homepage='https://gitlab.com/Shukat/project_1', + name="project_1", + homepage="https://gitlab.com/Shukat/project_1", backend=BACKEND, ) self.session.add(project) @@ -81,21 +81,19 @@ def test_get_version(self): """ Test the get_version function of the gitlab backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.8.8' + exp = "0.8.8" obs = backend.GitlabBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GitlabBackend.get_version, - project + AnityaPluginException, backend.GitlabBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = 'xonotic-v0.8.2' + exp = "xonotic-v0.8.2" obs = backend.GitlabBackend.get_version(project) self.assertEqual(obs, exp) @@ -105,12 +103,12 @@ def test_get_version_url_project_version_url(self): project version url is specified. """ project = models.Project( - name='test', - homepage='http://example.org', - version_url='https://gitlab.com/test/test', + name="test", + homepage="http://example.org", + version_url="https://gitlab.com/test/test", backend=BACKEND, ) - exp = 'https://gitlab.com/api/v4/projects/test%2Ftest/repository/tags' + exp = "https://gitlab.com/api/v4/projects/test%2Ftest/repository/tags" obs = backend.GitlabBackend.get_version_url(project) @@ -122,11 +120,9 @@ def test_get_version_url_project_homepage_only(self): project homepage is specified. """ project = models.Project( - name='test', - homepage='https://gitlab.com/test/test', - backend=BACKEND, + name="test", homepage="https://gitlab.com/test/test", backend=BACKEND ) - exp = 'https://gitlab.com/api/v4/projects/test%2Ftest/repository/tags' + exp = "https://gitlab.com/api/v4/projects/test%2Ftest/repository/tags" obs = backend.GitlabBackend.get_version_url(project) @@ -138,11 +134,9 @@ def test_get_version_url_project_wrong_homepage(self): project homepage is wrong. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = '' + exp = "" obs = backend.GitlabBackend.get_version_url(project) @@ -153,11 +147,26 @@ def test_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'0.6.1', u'0.6.1.1', u'0.6.2', u'0.6.3', - u'0.6.4', u'0.6.5', u'0.6.6', u'0.6.7', - u'0.6.8', u'0.7.0', u'0.7.1', u'0.8.0', - u'0.8.1', u'0.8.2', u'0.8.3', u'0.8.4', - u'0.8.5', u'0.8.6', u'0.8.7', u'0.8.8' + u"0.6.1", + u"0.6.1.1", + u"0.6.2", + u"0.6.3", + u"0.6.4", + u"0.6.5", + u"0.6.6", + u"0.6.7", + u"0.6.8", + u"0.7.0", + u"0.7.1", + u"0.8.0", + u"0.8.1", + u"0.8.2", + u"0.8.3", + u"0.8.4", + u"0.8.5", + u"0.8.6", + u"0.8.7", + u"0.8.8", ] obs = backend.GitlabBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -165,31 +174,26 @@ def test_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GitlabBackend.get_versions, - project + AnityaPluginException, backend.GitlabBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'xonotic-v0.1.0preview', u'xonotic-v0.5.0', - u'xonotic-v0.6.0', u'xonotic-v0.7.0', - u'xonotic-v0.8.0', u'xonotic-v0.8.1', - u'xonotic-v0.8.2' + u"xonotic-v0.1.0preview", + u"xonotic-v0.5.0", + u"xonotic-v0.6.0", + u"xonotic-v0.7.0", + u"xonotic-v0.8.0", + u"xonotic-v0.8.1", + u"xonotic-v0.8.2", ] obs = backend.GitlabBackend.get_ordered_versions(project) self.assertEqual(obs, exp) - project = models.Project( - name='foobar', - homepage='', - backend=BACKEND, - ) + project = models.Project(name="foobar", homepage="", backend=BACKEND) self.assertRaises( - AnityaPluginException, - backend.GitlabBackend.get_versions, - project + AnityaPluginException, backend.GitlabBackend.get_versions, project ) def test_get_versions_no_version_retrieved(self): @@ -199,12 +203,10 @@ def test_get_versions_no_version_retrieved(self): pid = 4 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GitlabBackend.get_versions, - project + AnityaPluginException, backend.GitlabBackend.get_versions, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(GitlabBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_gnome.py b/anitya/tests/lib/backends/test_gnome.py index 1c533b14e..f2ff7882b 100644 --- a/anitya/tests/lib/backends/test_gnome.py +++ b/anitya/tests/lib/backends/test_gnome.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'GNOME' +BACKEND = "GNOME" class GnomeBackendtests(DatabaseTestCase): @@ -47,24 +47,24 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='evolution-data-server', - homepage='https://git.gnome.org/browse/evolution-data-server/', + name="evolution-data-server", + homepage="https://git.gnome.org/browse/evolution-data-server/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://pypi.python.org/pypi/repo_manager_fake', + name="fake", + homepage="https://pypi.python.org/pypi/repo_manager_fake", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='gnome-control-center', - homepage='https://git.gnome.org/browse/gnome-control-center/', + name="gnome-control-center", + homepage="https://git.gnome.org/browse/gnome-control-center/", backend=BACKEND, ) self.session.add(project) @@ -74,32 +74,28 @@ def test_custom_get_version(self): """ Test the get_version function of the gnome backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '3.17.2' + exp = "3.17.2" obs = backend.GnomeBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnomeBackend.get_version, - project + AnityaPluginException, backend.GnomeBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '3.16.2' + exp = "3.16.2" obs = backend.GnomeBackend.get_version(project) self.assertEqual(obs, exp) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://download.gnome.org/sources/test/' + exp = "https://download.gnome.org/sources/test/" obs = backend.GnomeBackend.get_version_url(project) @@ -110,61 +106,319 @@ def test_custom_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'0.0.3', u'0.0.4', u'0.0.5', u'0.0.6', u'0.0.7', u'0.0.90', - u'0.0.91', u'0.0.92', u'0.0.93', u'0.0.94', u'0.0.94.1', u'0.0.95', - u'0.0.96', u'0.0.97', u'0.0.98', u'0.0.99', u'1.0.0', u'1.0.1', - u'1.0.2', u'1.0.3', u'1.0.4', u'1.1.0', u'1.1.1', u'1.1.2', - u'1.1.3', u'1.1.4', u'1.1.4.1', u'1.1.4.2', u'1.1.5', u'1.1.6', - u'1.2.0', u'1.2.1', u'1.2.2', u'1.2.3', u'1.3.1', u'1.3.2', - u'1.3.3', u'1.3.3.1', u'1.3.4', u'1.3.5', u'1.3.6', u'1.3.6.1', - u'1.3.7', u'1.3.8', u'1.4.0', u'1.4.1', u'1.4.1.1', u'1.4.2', - u'1.4.2.1', u'1.5.1', u'1.5.2', u'1.5.3', u'1.5.4', u'1.5.5', - u'1.5.90', u'1.5.91', u'1.5.92', u'1.6.0', u'1.6.1', u'1.6.2', - u'1.6.3', u'1.7.1', u'1.7.2', u'1.7.3', u'1.7.4', u'1.7.90', - u'1.7.90.1', u'1.7.91', u'1.7.92', u'1.8.0', u'1.8.1', u'1.8.2', - u'1.8.3', u'1.9.1', u'1.9.2', u'1.9.3', u'1.9.4', u'1.9.5', - u'1.9.6', u'1.9.6.1', u'1.9.91', u'1.9.92', u'1.10.0', u'1.10.1', - u'1.10.2', u'1.10.3', u'1.10.3.1', u'1.11.1', u'1.11.2', u'1.11.3', - u'1.11.4', u'1.11.5', u'1.11.6', u'1.11.6.1', u'1.11.90', - u'1.11.91', u'1.11.92', u'1.12.0', u'1.12.1', u'1.12.2', u'1.12.3', - u'2.21.1', u'2.21.2', u'2.21.3', u'2.21.4', u'2.21.5', u'2.21.5.1', - u'2.21.90', u'2.21.91', u'2.21.92', u'2.22.0', u'2.22.1', - u'2.22.1.1', u'2.22.2', u'2.22.3', u'2.23.1', u'2.23.2', u'2.23.3', - u'2.23.4', u'2.23.5', u'2.23.6', u'2.23.90', u'2.23.90.1', - u'2.23.91', u'2.23.92', u'2.24.0', u'2.24.1', u'2.24.1.1', - u'2.24.2', u'2.24.3', u'2.24.4', u'2.24.4.1', u'2.24.5', u'2.25.1', - u'2.25.2', u'2.25.3', u'2.25.4', u'2.25.5', u'2.25.90', u'2.25.91', - u'2.25.92', u'2.26.0', u'2.26.1', u'2.26.1.1', u'2.26.2', - u'2.26.3', u'2.27.1', u'2.27.2', u'2.27.3', u'2.27.4', u'2.27.5', - u'2.27.90', u'2.27.91', u'2.27.92', u'2.28.0', u'2.28.1', - u'2.28.2', u'2.28.3', u'2.28.3.1', u'2.29.1', u'2.29.2', u'2.29.3', - u'2.29.4', u'2.29.5', u'2.29.6', u'2.29.90', u'2.29.91', - u'2.29.92', u'2.30.0', u'2.30.1', u'2.30.2', u'2.30.2.1', - u'2.30.3', u'2.31.1', u'2.31.2', u'2.31.3', u'2.31.3.1', u'2.31.4', - u'2.31.5', u'2.31.6', u'2.31.90', u'2.31.91', u'2.31.92', - u'2.31.92.1', u'2.32.0', u'2.32.1', u'2.32.2', u'2.32.3', - u'2.91.0', u'2.91.1', u'2.91.1.1', u'2.91.2', u'2.91.3', u'2.91.4', - u'2.91.4.1', u'2.91.5', u'2.91.6', u'2.91.90', u'2.91.91', - u'2.91.92', u'3.0.0', u'3.0.1', u'3.0.2', u'3.0.2.1', u'3.0.3', - u'3.0.3.1', u'3.1.1', u'3.1.2', u'3.1.3', u'3.1.4', u'3.1.5', - u'3.1.90', u'3.1.91', u'3.1.92', u'3.2.0', u'3.2.1', u'3.2.2', - u'3.2.3', u'3.3.1', u'3.3.1.1', u'3.3.2', u'3.3.3', u'3.3.4', - u'3.3.5', u'3.3.90', u'3.3.91', u'3.3.92', u'3.4.0', u'3.4.1', - u'3.4.2', u'3.4.3', u'3.4.4', u'3.5.1', u'3.5.2', u'3.5.3', - u'3.5.3.1', u'3.5.4', u'3.5.5', u'3.5.90', u'3.5.91', u'3.5.92', - u'3.6.0', u'3.6.1', u'3.6.2', u'3.6.3', u'3.6.4', u'3.7.1', - u'3.7.2', u'3.7.2.1', u'3.7.3', u'3.7.4', u'3.7.5', u'3.7.90', - u'3.7.91', u'3.7.92', u'3.8.0', u'3.8.1', u'3.8.2', u'3.8.3', - u'3.8.4', u'3.8.5', u'3.9.1', u'3.9.2', u'3.9.3', u'3.9.4', - u'3.9.5', u'3.9.90', u'3.9.91', u'3.9.92', u'3.10.0', u'3.10.1', - u'3.10.2', u'3.10.3', u'3.10.4', u'3.11.1', u'3.11.2', u'3.11.3', - u'3.11.4', u'3.11.5', u'3.11.90', u'3.11.91', u'3.11.92', - u'3.12.0', u'3.12.1', u'3.12.2', u'3.12.3', u'3.12.4', u'3.12.5', - u'3.12.6', u'3.12.7', u'3.12.7.1', u'3.12.8', u'3.12.9', - u'3.12.10', u'3.12.11', u'3.13.1', u'3.13.2', u'3.13.3', u'3.13.4', - u'3.13.5', u'3.13.6', u'3.13.7', u'3.13.8', u'3.13.9', - u'3.13.10', u'3.13.90', u'3.15.91', u'3.15.92', u'3.16.0', - u'3.16.1', u'3.16.2', u'3.17.1', u'3.17.2', + u"0.0.3", + u"0.0.4", + u"0.0.5", + u"0.0.6", + u"0.0.7", + u"0.0.90", + u"0.0.91", + u"0.0.92", + u"0.0.93", + u"0.0.94", + u"0.0.94.1", + u"0.0.95", + u"0.0.96", + u"0.0.97", + u"0.0.98", + u"0.0.99", + u"1.0.0", + u"1.0.1", + u"1.0.2", + u"1.0.3", + u"1.0.4", + u"1.1.0", + u"1.1.1", + u"1.1.2", + u"1.1.3", + u"1.1.4", + u"1.1.4.1", + u"1.1.4.2", + u"1.1.5", + u"1.1.6", + u"1.2.0", + u"1.2.1", + u"1.2.2", + u"1.2.3", + u"1.3.1", + u"1.3.2", + u"1.3.3", + u"1.3.3.1", + u"1.3.4", + u"1.3.5", + u"1.3.6", + u"1.3.6.1", + u"1.3.7", + u"1.3.8", + u"1.4.0", + u"1.4.1", + u"1.4.1.1", + u"1.4.2", + u"1.4.2.1", + u"1.5.1", + u"1.5.2", + u"1.5.3", + u"1.5.4", + u"1.5.5", + u"1.5.90", + u"1.5.91", + u"1.5.92", + u"1.6.0", + u"1.6.1", + u"1.6.2", + u"1.6.3", + u"1.7.1", + u"1.7.2", + u"1.7.3", + u"1.7.4", + u"1.7.90", + u"1.7.90.1", + u"1.7.91", + u"1.7.92", + u"1.8.0", + u"1.8.1", + u"1.8.2", + u"1.8.3", + u"1.9.1", + u"1.9.2", + u"1.9.3", + u"1.9.4", + u"1.9.5", + u"1.9.6", + u"1.9.6.1", + u"1.9.91", + u"1.9.92", + u"1.10.0", + u"1.10.1", + u"1.10.2", + u"1.10.3", + u"1.10.3.1", + u"1.11.1", + u"1.11.2", + u"1.11.3", + u"1.11.4", + u"1.11.5", + u"1.11.6", + u"1.11.6.1", + u"1.11.90", + u"1.11.91", + u"1.11.92", + u"1.12.0", + u"1.12.1", + u"1.12.2", + u"1.12.3", + u"2.21.1", + u"2.21.2", + u"2.21.3", + u"2.21.4", + u"2.21.5", + u"2.21.5.1", + u"2.21.90", + u"2.21.91", + u"2.21.92", + u"2.22.0", + u"2.22.1", + u"2.22.1.1", + u"2.22.2", + u"2.22.3", + u"2.23.1", + u"2.23.2", + u"2.23.3", + u"2.23.4", + u"2.23.5", + u"2.23.6", + u"2.23.90", + u"2.23.90.1", + u"2.23.91", + u"2.23.92", + u"2.24.0", + u"2.24.1", + u"2.24.1.1", + u"2.24.2", + u"2.24.3", + u"2.24.4", + u"2.24.4.1", + u"2.24.5", + u"2.25.1", + u"2.25.2", + u"2.25.3", + u"2.25.4", + u"2.25.5", + u"2.25.90", + u"2.25.91", + u"2.25.92", + u"2.26.0", + u"2.26.1", + u"2.26.1.1", + u"2.26.2", + u"2.26.3", + u"2.27.1", + u"2.27.2", + u"2.27.3", + u"2.27.4", + u"2.27.5", + u"2.27.90", + u"2.27.91", + u"2.27.92", + u"2.28.0", + u"2.28.1", + u"2.28.2", + u"2.28.3", + u"2.28.3.1", + u"2.29.1", + u"2.29.2", + u"2.29.3", + u"2.29.4", + u"2.29.5", + u"2.29.6", + u"2.29.90", + u"2.29.91", + u"2.29.92", + u"2.30.0", + u"2.30.1", + u"2.30.2", + u"2.30.2.1", + u"2.30.3", + u"2.31.1", + u"2.31.2", + u"2.31.3", + u"2.31.3.1", + u"2.31.4", + u"2.31.5", + u"2.31.6", + u"2.31.90", + u"2.31.91", + u"2.31.92", + u"2.31.92.1", + u"2.32.0", + u"2.32.1", + u"2.32.2", + u"2.32.3", + u"2.91.0", + u"2.91.1", + u"2.91.1.1", + u"2.91.2", + u"2.91.3", + u"2.91.4", + u"2.91.4.1", + u"2.91.5", + u"2.91.6", + u"2.91.90", + u"2.91.91", + u"2.91.92", + u"3.0.0", + u"3.0.1", + u"3.0.2", + u"3.0.2.1", + u"3.0.3", + u"3.0.3.1", + u"3.1.1", + u"3.1.2", + u"3.1.3", + u"3.1.4", + u"3.1.5", + u"3.1.90", + u"3.1.91", + u"3.1.92", + u"3.2.0", + u"3.2.1", + u"3.2.2", + u"3.2.3", + u"3.3.1", + u"3.3.1.1", + u"3.3.2", + u"3.3.3", + u"3.3.4", + u"3.3.5", + u"3.3.90", + u"3.3.91", + u"3.3.92", + u"3.4.0", + u"3.4.1", + u"3.4.2", + u"3.4.3", + u"3.4.4", + u"3.5.1", + u"3.5.2", + u"3.5.3", + u"3.5.3.1", + u"3.5.4", + u"3.5.5", + u"3.5.90", + u"3.5.91", + u"3.5.92", + u"3.6.0", + u"3.6.1", + u"3.6.2", + u"3.6.3", + u"3.6.4", + u"3.7.1", + u"3.7.2", + u"3.7.2.1", + u"3.7.3", + u"3.7.4", + u"3.7.5", + u"3.7.90", + u"3.7.91", + u"3.7.92", + u"3.8.0", + u"3.8.1", + u"3.8.2", + u"3.8.3", + u"3.8.4", + u"3.8.5", + u"3.9.1", + u"3.9.2", + u"3.9.3", + u"3.9.4", + u"3.9.5", + u"3.9.90", + u"3.9.91", + u"3.9.92", + u"3.10.0", + u"3.10.1", + u"3.10.2", + u"3.10.3", + u"3.10.4", + u"3.11.1", + u"3.11.2", + u"3.11.3", + u"3.11.4", + u"3.11.5", + u"3.11.90", + u"3.11.91", + u"3.11.92", + u"3.12.0", + u"3.12.1", + u"3.12.2", + u"3.12.3", + u"3.12.4", + u"3.12.5", + u"3.12.6", + u"3.12.7", + u"3.12.7.1", + u"3.12.8", + u"3.12.9", + u"3.12.10", + u"3.12.11", + u"3.13.1", + u"3.13.2", + u"3.13.3", + u"3.13.4", + u"3.13.5", + u"3.13.6", + u"3.13.7", + u"3.13.8", + u"3.13.9", + u"3.13.10", + u"3.13.90", + u"3.15.91", + u"3.15.92", + u"3.16.0", + u"3.16.1", + u"3.16.2", + u"3.17.1", + u"3.17.2", ] obs = backend.GnomeBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -172,53 +426,194 @@ def test_custom_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnomeBackend.get_versions, - project + AnityaPluginException, backend.GnomeBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'2.19.1', u'2.19.3', u'2.19.4', u'2.19.5', u'2.19.6', u'2.19.90', - u'2.19.91', u'2.19.92', u'2.20.0', u'2.20.0.1', u'2.20.1', - u'2.20.3', u'2.21.1', u'2.21.2', u'2.21.4', u'2.21.5', u'2.21.90', - u'2.21.92', u'2.22.0', u'2.22.1', u'2.22.2', u'2.22.2.1', - u'2.23.1', u'2.23.2', u'2.23.3', u'2.23.4', u'2.23.5', u'2.23.6', - u'2.23.90', u'2.24.0', u'2.24.0.1', u'2.25.1', u'2.25.2', - u'2.25.3', u'2.25.90', u'2.25.92', u'2.26.0', u'2.27.3', u'2.27.4', - u'2.27.4.1', u'2.27.5', u'2.27.90', u'2.27.91', u'2.28.0', - u'2.28.1', u'2.29.4', u'2.29.6', u'2.29.90', u'2.29.91', - u'2.29.92', u'2.30.0', u'2.30.1', u'2.31.1', u'2.31.2', u'2.31.3', - u'2.31.4', u'2.31.4.1', u'2.31.4.2', u'2.31.5', u'2.31.6', - u'2.31.90', u'2.31.91', u'2.31.92', u'2.31.92.1', u'2.32.0', - u'2.32.1', u'2.90.1', u'2.91.0', u'2.91.2', u'2.91.3', u'2.91.3.1', - u'2.91.4', u'2.91.5', u'2.91.6', u'2.91.90', u'2.91.91', - u'2.91.92', u'2.91.93', u'3.0.0', u'3.0.0.1', u'3.0.1', u'3.0.1.1', - u'3.0.2', u'3.1.3', u'3.1.4', u'3.1.5', u'3.1.90', u'3.1.91', - u'3.1.92', u'3.2.0', u'3.2.1', u'3.2.2', u'3.2.3', u'3.3.2', - u'3.3.3', u'3.3.4', u'3.3.4.1', u'3.3.5', u'3.3.90', u'3.3.91', - u'3.3.92', u'3.4.0', u'3.4.1', u'3.4.2', u'3.4.3', u'3.4.3.1', - u'3.5.2', u'3.5.3', u'3.5.4', u'3.5.5', u'3.5.6', u'3.5.90', - u'3.5.91', u'3.5.92', u'3.6.0', u'3.6.1', u'3.6.2', u'3.6.3', - u'3.7.1', u'3.7.3', u'3.7.4', u'3.7.5', u'3.7.5.1', u'3.7.90', - u'3.7.91', u'3.7.92', u'3.8.0', u'3.8.1', u'3.8.1.5', u'3.8.2', - u'3.8.3', u'3.8.4', u'3.8.4.1', u'3.8.5', u'3.8.6', u'3.9.2', - u'3.9.2.1', u'3.9.3', u'3.9.5', u'3.9.90', u'3.9.90.1', u'3.9.91', - u'3.9.92', u'3.10.0', u'3.10.1', u'3.10.2', u'3.10.3', u'3.10.4', - u'3.11.1', u'3.11.2', u'3.11.3', u'3.11.5', - u'3.11.90', u'3.11.91', u'3.11.92', - u'3.12.0', u'3.12.1', - u'3.13.1', u'3.13.2', u'3.13.3', u'3.13.4', - u'3.13.90', u'3.13.91', u'3.13.92', - u'3.14.0', u'3.14.1', u'3.14.2', u'3.14.3', u'3.14.4', u'3.14.5', - u'3.15.4', u'3.15.90', u'3.15.91', u'3.15.92', - u'3.16.0', u'3.16.1', u'3.16.2', + u"2.19.1", + u"2.19.3", + u"2.19.4", + u"2.19.5", + u"2.19.6", + u"2.19.90", + u"2.19.91", + u"2.19.92", + u"2.20.0", + u"2.20.0.1", + u"2.20.1", + u"2.20.3", + u"2.21.1", + u"2.21.2", + u"2.21.4", + u"2.21.5", + u"2.21.90", + u"2.21.92", + u"2.22.0", + u"2.22.1", + u"2.22.2", + u"2.22.2.1", + u"2.23.1", + u"2.23.2", + u"2.23.3", + u"2.23.4", + u"2.23.5", + u"2.23.6", + u"2.23.90", + u"2.24.0", + u"2.24.0.1", + u"2.25.1", + u"2.25.2", + u"2.25.3", + u"2.25.90", + u"2.25.92", + u"2.26.0", + u"2.27.3", + u"2.27.4", + u"2.27.4.1", + u"2.27.5", + u"2.27.90", + u"2.27.91", + u"2.28.0", + u"2.28.1", + u"2.29.4", + u"2.29.6", + u"2.29.90", + u"2.29.91", + u"2.29.92", + u"2.30.0", + u"2.30.1", + u"2.31.1", + u"2.31.2", + u"2.31.3", + u"2.31.4", + u"2.31.4.1", + u"2.31.4.2", + u"2.31.5", + u"2.31.6", + u"2.31.90", + u"2.31.91", + u"2.31.92", + u"2.31.92.1", + u"2.32.0", + u"2.32.1", + u"2.90.1", + u"2.91.0", + u"2.91.2", + u"2.91.3", + u"2.91.3.1", + u"2.91.4", + u"2.91.5", + u"2.91.6", + u"2.91.90", + u"2.91.91", + u"2.91.92", + u"2.91.93", + u"3.0.0", + u"3.0.0.1", + u"3.0.1", + u"3.0.1.1", + u"3.0.2", + u"3.1.3", + u"3.1.4", + u"3.1.5", + u"3.1.90", + u"3.1.91", + u"3.1.92", + u"3.2.0", + u"3.2.1", + u"3.2.2", + u"3.2.3", + u"3.3.2", + u"3.3.3", + u"3.3.4", + u"3.3.4.1", + u"3.3.5", + u"3.3.90", + u"3.3.91", + u"3.3.92", + u"3.4.0", + u"3.4.1", + u"3.4.2", + u"3.4.3", + u"3.4.3.1", + u"3.5.2", + u"3.5.3", + u"3.5.4", + u"3.5.5", + u"3.5.6", + u"3.5.90", + u"3.5.91", + u"3.5.92", + u"3.6.0", + u"3.6.1", + u"3.6.2", + u"3.6.3", + u"3.7.1", + u"3.7.3", + u"3.7.4", + u"3.7.5", + u"3.7.5.1", + u"3.7.90", + u"3.7.91", + u"3.7.92", + u"3.8.0", + u"3.8.1", + u"3.8.1.5", + u"3.8.2", + u"3.8.3", + u"3.8.4", + u"3.8.4.1", + u"3.8.5", + u"3.8.6", + u"3.9.2", + u"3.9.2.1", + u"3.9.3", + u"3.9.5", + u"3.9.90", + u"3.9.90.1", + u"3.9.91", + u"3.9.92", + u"3.10.0", + u"3.10.1", + u"3.10.2", + u"3.10.3", + u"3.10.4", + u"3.11.1", + u"3.11.2", + u"3.11.3", + u"3.11.5", + u"3.11.90", + u"3.11.91", + u"3.11.92", + u"3.12.0", + u"3.12.1", + u"3.13.1", + u"3.13.2", + u"3.13.3", + u"3.13.4", + u"3.13.90", + u"3.13.91", + u"3.13.92", + u"3.14.0", + u"3.14.1", + u"3.14.2", + u"3.14.3", + u"3.14.4", + u"3.14.5", + u"3.15.4", + u"3.15.90", + u"3.15.91", + u"3.15.92", + u"3.16.0", + u"3.16.1", + u"3.16.2", ] obs = backend.GnomeBackend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(GnomeBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_gnu.py b/anitya/tests/lib/backends/test_gnu.py index 98345ff8c..cf03a9660 100644 --- a/anitya/tests/lib/backends/test_gnu.py +++ b/anitya/tests/lib/backends/test_gnu.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'GNU project' +BACKEND = "GNU project" class GnuBackendtests(DatabaseTestCase): @@ -47,26 +47,26 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='gnash', - homepage='https://www.gnu.org/software/gnash/', - version_url='https://ftp.gnu.org/pub/gnu/gnash/', + name="gnash", + homepage="https://www.gnu.org/software/gnash/", + version_url="https://ftp.gnu.org/pub/gnu/gnash/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://pypi.python.org/pypi/repo_manager_fake', + name="fake", + homepage="https://pypi.python.org/pypi/repo_manager_fake", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='subsurface', - homepage='https://subsurface-divelog.org/', - version_url='https://subsurface-divelog.org/downloads/', + name="subsurface", + homepage="https://subsurface-divelog.org/", + version_url="https://subsurface-divelog.org/downloads/", backend=BACKEND, ) self.session.add(project) @@ -76,34 +76,28 @@ def test_custom_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.8.10' + exp = "0.8.10" obs = backend.GnuBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnuBackend.get_version, - project + AnityaPluginException, backend.GnuBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnuBackend.get_version, - project + AnityaPluginException, backend.GnuBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://ftp.gnu.org/gnu/test/' + exp = "https://ftp.gnu.org/gnu/test/" obs = backend.GnuBackend.get_version_url(project) @@ -114,8 +108,19 @@ def test_custom_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - '0.7.1', '0.7.2', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4', - '0.8.5', '0.8.6', '0.8.7', '0.8.8', '0.8.9', '0.8.10' + "0.7.1", + "0.7.2", + "0.8.0", + "0.8.1", + "0.8.2", + "0.8.3", + "0.8.4", + "0.8.5", + "0.8.6", + "0.8.7", + "0.8.8", + "0.8.9", + "0.8.10", ] obs = backend.GnuBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -123,20 +128,16 @@ def test_custom_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnuBackend.get_version, - project + AnityaPluginException, backend.GnuBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GnuBackend.get_version, - project + AnityaPluginException, backend.GnuBackend.get_version, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(GnuBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_google.py b/anitya/tests/lib/backends/test_google.py index 10c5777f0..23690bbf6 100644 --- a/anitya/tests/lib/backends/test_google.py +++ b/anitya/tests/lib/backends/test_google.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Google code' +BACKEND = "Google code" class GoogleBackendtests(DatabaseTestCase): @@ -47,17 +47,15 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='arduino', - homepage='https://code.google.com/p/arduino/', + name="arduino", + homepage="https://code.google.com/p/arduino/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://code.google.com/p/foo', - backend=BACKEND, + name="foo", homepage="https://code.google.com/p/foo", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -65,11 +63,9 @@ def create_project(self): def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://code.google.com/p/test/downloads/list?sort=releasedate' + exp = "https://code.google.com/p/test/downloads/list?sort=releasedate" obs = backend.GoogleBackend.get_version_url(project) @@ -79,16 +75,14 @@ def test_cpan_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0023' + exp = "0023" obs = backend.GoogleBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GoogleBackend.get_version, - project + AnityaPluginException, backend.GoogleBackend.get_version, project ) def test_cpan_get_versions(self): @@ -96,20 +90,30 @@ def test_cpan_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - '1.0', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '0017', - '0018', '0019', '0020', '0021', '0022', '0023'] + "1.0", + "1.0.1", + "1.0.2", + "1.0.3", + "1.0.4", + "1.0.5", + "0017", + "0018", + "0019", + "0020", + "0021", + "0022", + "0023", + ] obs = backend.GoogleBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.GoogleBackend.get_version, - project + AnityaPluginException, backend.GoogleBackend.get_version, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(GoogleBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_hackage.py b/anitya/tests/lib/backends/test_hackage.py index 72df9499e..fb1b0935c 100644 --- a/anitya/tests/lib/backends/test_hackage.py +++ b/anitya/tests/lib/backends/test_hackage.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Hackage' +BACKEND = "Hackage" class HackageBackendtests(DatabaseTestCase): @@ -47,16 +47,16 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='Biobase', - homepage='https://hackage.haskell.org/package/Biobase', + name="Biobase", + homepage="https://hackage.haskell.org/package/Biobase", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='non-existent-package-that-does-not-exist', - homepage='https://hackage.haskell.org/package/non-existent-package-that-does-not-exist', + name="non-existent-package-that-does-not-exist", + homepage="https://hackage.haskell.org/package/non-existent-package-that-does-not-exist", backend=BACKEND, ) self.session.add(project) @@ -66,26 +66,22 @@ def test_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.3.1.1' + exp = "0.3.1.1" obs = backend.HackageBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.HackageBackend.get_version, - project + AnityaPluginException, backend.HackageBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://hackage.haskell.org/package/test' + exp = "https://hackage.haskell.org/package/test" obs = backend.HackageBackend.get_version_url(project) @@ -95,19 +91,17 @@ def test_get_versions(self): """ Test the get_versions function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['0.3.1.1'] + exp = ["0.3.1.1"] obs = backend.HackageBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.HackageBackend.get_version, - project + AnityaPluginException, backend.HackageBackend.get_version, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(HackageBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_init.py b/anitya/tests/lib/backends/test_init.py index 37c0746a0..02b14f864 100644 --- a/anitya/tests/lib/backends/test_init.py +++ b/anitya/tests/lib/backends/test_init.py @@ -38,42 +38,44 @@ class BaseBackendTests(AnityaTestCase): - def setUp(self): super(BaseBackendTests, self).setUp() self.backend = backends.BaseBackend() self.headers = { - 'User-Agent': 'Anitya {0} at upstream-monitoring.org'.format( - anitya.app.__version__), - 'From': config.get('ADMIN_EMAIL'), + "User-Agent": "Anitya {0} at upstream-monitoring.org".format( + anitya.app.__version__ + ), + "From": config.get("ADMIN_EMAIL"), } - @mock.patch('anitya.lib.backends.http_session') + @mock.patch("anitya.lib.backends.http_session") def test_call_http_url(self, mock_http_session): """Assert HTTP urls are handled by requests""" - url = 'https://www.example.com/' + url = "https://www.example.com/" self.backend.call_url(url) mock_http_session.get.assert_called_once_with( - url, headers=self.headers, timeout=60, verify=True) + url, headers=self.headers, timeout=60, verify=True + ) - @mock.patch('anitya.lib.backends.requests.Session') + @mock.patch("anitya.lib.backends.requests.Session") def test_call_insecure_http_url(self, mock_session): """Assert HTTP urls are handled by requests""" - url = 'https://www.example.com/' + url = "https://www.example.com/" self.backend.call_url(url, insecure=True) insecure_session = mock_session.return_value.__enter__.return_value insecure_session.get.assert_called_once_with( - url, headers=self.headers, timeout=60, verify=False) + url, headers=self.headers, timeout=60, verify=False + ) - @mock.patch('urllib.request.urlopen') + @mock.patch("urllib.request.urlopen") def test_call_ftp_url(self, mock_urllib): """Assert FTP urls are handled by requests""" url = "ftp://ftp.heanet.ie/debian/" req_exp = urllib.Request(url) - req_exp.add_header('User-Agent', self.headers['User-Agent']) - req_exp.add_header('From', self.headers['From']) + req_exp.add_header("User-Agent", self.headers["User-Agent"]) + req_exp.add_header("From", self.headers["From"]) self.backend.call_url(url) mock_urllib.assert_called_once_with(mock.ANY) @@ -84,19 +86,19 @@ def test_call_ftp_url(self, mock_urllib): self.assertEqual(req_exp.get_full_url(), req.get_full_url()) self.assertEqual(req_exp.header_items(), req.header_items()) - @mock.patch('urllib.request.urlopen') + @mock.patch("urllib.request.urlopen") def test_call_ftp_url_decode(self, mock_urlopen): """Assert decoding is working""" url = "ftp://ftp.heanet.ie/debian/" - exp_resp = 'drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n' + exp_resp = "drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n" mc = mock.Mock() - mc.read.return_value = b'drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n' + mc.read.return_value = b"drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n" mock_urlopen.return_value = mc resp = self.backend.call_url(url) self.assertEqual(resp, exp_resp) - @mock.patch('urllib.request.urlopen') + @mock.patch("urllib.request.urlopen") def test_call_ftp_url_decode_not_utf(self, mock_urlopen): """Assert decoding is working""" url = "ftp://ftp.heanet.ie/debian/" @@ -104,23 +106,15 @@ def test_call_ftp_url_decode_not_utf(self, mock_urlopen): mc.read.return_value = b"\x80\x81" mock_urlopen.return_value = mc - self.assertRaises( - AnityaPluginException, - self.backend.call_url, - url - ) + self.assertRaises(AnityaPluginException, self.backend.call_url, url) - @mock.patch('urllib.request.urlopen') + @mock.patch("urllib.request.urlopen") def test_call_ftp_url_Exceptions(self, mock_urllib): """Assert FTP urls are handled by requests""" - mock_urllib.side_effect = URLError(mock.Mock('not_found')) + mock_urllib.side_effect = URLError(mock.Mock("not_found")) url = "ftp://example.com" - self.assertRaises( - AnityaPluginException, - self.backend.call_url, - url - ) + self.assertRaises(AnityaPluginException, self.backend.call_url, url) def test_expand_subdirs(self): """Assert expanding subdirs""" @@ -129,8 +123,10 @@ def test_expand_subdirs(self): self.assertEqual(exp, url) - @mock.patch('anitya.lib.backends.BaseBackend.call_url', - return_value='drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n') + @mock.patch( + "anitya.lib.backends.BaseBackend.call_url", + return_value="drwxr-xr-x 9 ftp ftp 4096 Aug 23 09:02 debian\r\n", + ) def test_expand_subdirs_ftp(self, mock_call_url): """Assert expanding subdirs""" exp = "ftp://ftp.heanet.ie/debian/" @@ -151,11 +147,12 @@ def test_get_versions_by_regex_for_text(self): some other release: 0.0.2 The best release: 1.0.0 """ - regex = r'\d\.\d\.\d' - mock_project = mock.Mock(version_prefix='') + regex = r"\d\.\d\.\d" + mock_project = mock.Mock(version_prefix="") versions = backends.get_versions_by_regex_for_text( - text, 'url', regex, mock_project) - self.assertEqual(sorted(['0.0.1', '0.0.2', '1.0.0']), sorted(versions)) + text, "url", regex, mock_project + ) + self.assertEqual(sorted(["0.0.1", "0.0.2", "1.0.0"]), sorted(versions)) def test_get_versions_by_regex_for_text_tuples(self): """Assert regex that result in tuples are joined into a string""" @@ -164,28 +161,29 @@ def test_get_versions_by_regex_for_text_tuples(self): some other release: 0.0.2 The best release: 1.0.0 """ - regex = r'(\d)\.(\d)\.(\d)' - mock_project = mock.Mock(version_prefix='') + regex = r"(\d)\.(\d)\.(\d)" + mock_project = mock.Mock(version_prefix="") versions = backends.get_versions_by_regex_for_text( - text, 'url', regex, mock_project) - self.assertEqual(sorted(['0.0.1', '0.0.2', '1.0.0']), sorted(versions)) + text, "url", regex, mock_project + ) + self.assertEqual(sorted(["0.0.1", "0.0.2", "1.0.0"]), sorted(versions)) # Demonstrate that the regex does result in an iterable - self.assertEqual(3, len(re.findall(regex, '0.0.1')[0])) + self.assertEqual(3, len(re.findall(regex, "0.0.1")[0])) def test_get_versions_by_regex_for_text_no_versions(self): """Assert an exception is raised if no matches are found""" text = "This text doesn't have a release!" - regex = r'(\d)\.(\d)\.(\d)' - mock_project = mock.Mock(version_prefix='') + regex = r"(\d)\.(\d)\.(\d)" + mock_project = mock.Mock(version_prefix="") self.assertRaises( AnityaPluginException, backends.get_versions_by_regex_for_text, text, - 'url', + "url", regex, - mock_project + mock_project, ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/anitya/tests/lib/backends/test_launchpad.py b/anitya/tests/lib/backends/test_launchpad.py index f79244825..8a76b649d 100644 --- a/anitya/tests/lib/backends/test_launchpad.py +++ b/anitya/tests/lib/backends/test_launchpad.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Launchpad' +BACKEND = "Launchpad" class LaunchpadBackendtests(DatabaseTestCase): @@ -47,17 +47,13 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='exaile', - homepage='https://launchpad.net/exaile', - backend=BACKEND, + name="exaile", homepage="https://launchpad.net/exaile", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://launchpad.net/foo', - backend=BACKEND, + name="foo", homepage="https://launchpad.net/foo", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -66,26 +62,22 @@ def test_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '3.4.0' + exp = "3.4.0" obs = backend.LaunchpadBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.LaunchpadBackend.get_version, - project + AnityaPluginException, backend.LaunchpadBackend.get_version, project ) def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='http://example.org', - backend=BACKEND, + name="test", homepage="http://example.org", backend=BACKEND ) - exp = 'https://launchpad.net/test/+download' + exp = "https://launchpad.net/test/+download" obs = backend.LaunchpadBackend.get_version_url(project) @@ -95,19 +87,17 @@ def test_get_versions(self): """ Test the get_versions function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['3.3.0', '3.3.1', '3.3.2', '3.4.0'] + exp = ["3.3.0", "3.3.1", "3.3.2", "3.4.0"] obs = backend.LaunchpadBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.LaunchpadBackend.get_version, - project + AnityaPluginException, backend.LaunchpadBackend.get_version, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(LaunchpadBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_maven.py b/anitya/tests/lib/backends/test_maven.py index e1c3cc545..c03b3adeb 100644 --- a/anitya/tests/lib/backends/test_maven.py +++ b/anitya/tests/lib/backends/test_maven.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the Maven backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Maven Central' +BACKEND = "Maven Central" class MavenBackendTest(DatabaseTestCase): @@ -45,59 +45,52 @@ def setUp(self): def assert_plexus_version(self, **kwargs): project = models.Project(backend=BACKEND, **kwargs) - exp = '1.3.8' + exp = "1.3.8" obs = MavenBackend.get_version(project) self.assertEqual(obs, exp) def assert_invalid(self, **kwargs): project = models.Project(backend=BACKEND, **kwargs) - self.assertRaises( - AnityaPluginException, - MavenBackend.get_version, - project - ) + self.assertRaises(AnityaPluginException, MavenBackend.get_version, project) def test_maven_nonexistent(self): - self.assert_invalid( - name='foo', - homepage='https://example.com', - ) + self.assert_invalid(name="foo", homepage="https://example.com") def test_maven_coordinates_in_version_url(self): self.assert_plexus_version( - name='plexus-maven-plugin', - version_url='org.codehaus.plexus:plexus-maven-plugin', - homepage='https://plexus.codehaus.org/', + name="plexus-maven-plugin", + version_url="org.codehaus.plexus:plexus-maven-plugin", + homepage="https://plexus.codehaus.org/", ) def test_maven_coordinates_in_name(self): self.assert_plexus_version( - name='org.codehaus.plexus:plexus-maven-plugin', - homepage='https://plexus.codehaus.org/', + name="org.codehaus.plexus:plexus-maven-plugin", + homepage="https://plexus.codehaus.org/", ) def test_maven_bad_coordinates(self): self.assert_invalid( - name='plexus-maven-plugin', - homepage='https://plexus.codehaus.org/', - version_url='plexus-maven-plugin', + name="plexus-maven-plugin", + homepage="https://plexus.codehaus.org/", + version_url="plexus-maven-plugin", ) def test_maven_get_version_by_url(self): self.assert_plexus_version( - name='plexus-maven-plugin', - homepage='https://repo1.maven.org/maven2/' - 'org/codehaus/plexus/plexus-maven-plugin/', + name="plexus-maven-plugin", + homepage="https://repo1.maven.org/maven2/" + "org/codehaus/plexus/plexus-maven-plugin/", ) def test_dots_in_artifact_id(self): project = models.Project( backend=BACKEND, - name='felix-gogo-shell', - homepage='https://www.apache.org/dist/felix/', - version_url='org.apache.felix:org.apache.felix.gogo.shell', + name="felix-gogo-shell", + homepage="https://www.apache.org/dist/felix/", + version_url="org.apache.felix:org.apache.felix.gogo.shell", ) - exp = '1.0.0' + exp = "1.0.0" obs = MavenBackend.get_version(project) self.assertEqual(obs, exp) @@ -106,8 +99,8 @@ def test_get_version_url_homepage(self): Assert that correct url is returned when project homepage is specified. """ project = models.Project( - name='test', - homepage='https://repo1.maven.org/maven2/test/test', + name="test", + homepage="https://repo1.maven.org/maven2/test/test", backend=BACKEND, ) exp = project.homepage @@ -122,12 +115,12 @@ def test_get_version_url_project_version_url(self): is specified. """ project = models.Project( - name='test', - homepage='https://example.org', - version_url='test:test', + name="test", + homepage="https://example.org", + version_url="test:test", backend=BACKEND, ) - exp = 'https://repo1.maven.org/maven2/test/test/' + exp = "https://repo1.maven.org/maven2/test/test/" obs = MavenBackend.get_version_url(project) @@ -139,12 +132,12 @@ def test_get_version_url_contains_dot(self): contains '.'. """ project = models.Project( - name='test', - homepage='https://example.org', - version_url='test.test:test', + name="test", + homepage="https://example.org", + version_url="test.test:test", backend=BACKEND, ) - exp = 'https://repo1.maven.org/maven2/test/test/test/' + exp = "https://repo1.maven.org/maven2/test/test/test/" obs = MavenBackend.get_version_url(project) @@ -155,11 +148,9 @@ def test_get_version_url_wrong_homepage(self): Assert that empty url is returned when wrong homepage is specified. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = '' + exp = "" obs = MavenBackend.get_version_url(project) @@ -168,17 +159,31 @@ def test_get_version_url_wrong_homepage(self): def test_maven_get_versions(self): project = models.Project( backend=BACKEND, - name='plexus-maven-plugin', - version_url='org.codehaus.plexus:plexus-maven-plugin', - homepage='https://plexus.codehaus.org/', + name="plexus-maven-plugin", + version_url="org.codehaus.plexus:plexus-maven-plugin", + homepage="https://plexus.codehaus.org/", ) - exp = ['1.1-alpha-7', '1.1', '1.1.1', '1.1.2', '1.1.3', '1.2', '1.3', - '1.3.1', '1.3.2', '1.3.3', '1.3.4', '1.3.5', '1.3.6', '1.3.7', - '1.3.8'] + exp = [ + "1.1-alpha-7", + "1.1", + "1.1.1", + "1.1.2", + "1.1.3", + "1.2", + "1.3", + "1.3.1", + "1.3.2", + "1.3.3", + "1.3.4", + "1.3.5", + "1.3.6", + "1.3.7", + "1.3.8", + ] obs = MavenBackend.get_ordered_versions(project) self.assertEqual(obs, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(MavenBackendTest) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_npmjs.py b/anitya/tests/lib/backends/test_npmjs.py index ecdc12baf..0ef8e7158 100644 --- a/anitya/tests/lib/backends/test_npmjs.py +++ b/anitya/tests/lib/backends/test_npmjs.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'npmjs' +BACKEND = "npmjs" class NpmjsBackendtests(DatabaseTestCase): @@ -47,24 +47,24 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='request', - homepage='https://www.npmjs.org/package/request', + name="request", + homepage="https://www.npmjs.org/package/request", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='non-existent-package-that-does-not-exist', - homepage='https://www.npmjs.org/package/non-existent-package-that-does-not-exist', + name="non-existent-package-that-does-not-exist", + homepage="https://www.npmjs.org/package/non-existent-package-that-does-not-exist", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='colors', - homepage='https://www.npmjs.org/package/colors', + name="colors", + homepage="https://www.npmjs.org/package/colors", backend=BACKEND, ) self.session.add(project) @@ -74,21 +74,19 @@ def test_get_version(self): """ Test the get_version function of the npmjs backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '2.83.0' + exp = "2.83.0" obs = backend.NpmjsBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.NpmjsBackend.get_version, - project + AnityaPluginException, backend.NpmjsBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '1.2.0' + exp = "1.2.0" obs = backend.NpmjsBackend.get_version(project) self.assertEqual(obs, exp) @@ -97,11 +95,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://registry.npmjs.org/test' + exp = "https://registry.npmjs.org/test" obs = backend.NpmjsBackend.get_version_url(project) @@ -112,32 +108,126 @@ def test_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'0.8.3', u'0.9.0', u'0.9.1', u'0.9.5', u'0.10.0', - u'1.0.0', u'1.1.0', u'1.1.1', u'1.2.0', - u'1.9.0', u'1.9.1', u'1.9.2', u'1.9.3', u'1.9.5', u'1.9.7', - u'1.9.8', u'1.9.9', - u'2.0.0', u'2.0.1', u'2.0.2', u'2.0.3', u'2.0.4', u'2.0.5', - u'2.1.0', u'2.1.1', - u'2.2.0', u'2.2.5', u'2.2.6', u'2.2.9', - u'2.9.0', u'2.9.1', u'2.9.2', u'2.9.3', - u'2.9.100', u'2.9.150', u'2.9.151', u'2.9.152', u'2.9.153', - u'2.9.200', u'2.9.201', u'2.9.202', u'2.9.203', - u'2.10.0', - u'2.11.0', u'2.11.1', u'2.11.2', u'2.11.3', u'2.11.4', - u'2.12.0', - u'2.14.0', - u'2.16.0', u'2.16.2', u'2.16.4', u'2.16.6', - u'2.18.0', u'2.19.0', u'2.20.0', u'2.21.0', u'2.22.0', u'2.23.0', - u'2.24.0', u'2.25.0', u'2.26.0', u'2.27.0', u'2.28.0', u'2.29.0', - u'2.30.0', u'2.31.0', u'2.32.0', u'2.33.0', u'2.34.0', u'2.35.0', - u'2.36.0', u'2.37.0', u'2.38.0', u'2.39.0', u'2.40.0', u'2.41.0', - u'2.42.0', u'2.43.0', u'2.44.0', u'2.45.0', u'2.46.0', u'2.47.0', - u'2.48.0', u'2.49.0', u'2.50.0', u'2.51.0', u'2.52.0', u'2.53.0', - u'2.54.0', u'2.55.0', u'2.56.0', u'2.57.0', u'2.58.0', u'2.59.0', - u'2.60.0', u'2.61.0', u'2.62.0', u'2.63.0', u'2.64.0', u'2.65.0', - u'2.66.0', u'2.67.0', u'2.68.0', u'2.69.0', u'2.70.0', u'2.71.0', - u'2.72.0', u'2.73.0', u'2.74.0', u'2.75.0', u'2.76.0', u'2.77.0', - u'2.78.0', u'2.79.0', u'2.80.0', u'2.81.0', u'2.82.0', u'2.83.0', + u"0.8.3", + u"0.9.0", + u"0.9.1", + u"0.9.5", + u"0.10.0", + u"1.0.0", + u"1.1.0", + u"1.1.1", + u"1.2.0", + u"1.9.0", + u"1.9.1", + u"1.9.2", + u"1.9.3", + u"1.9.5", + u"1.9.7", + u"1.9.8", + u"1.9.9", + u"2.0.0", + u"2.0.1", + u"2.0.2", + u"2.0.3", + u"2.0.4", + u"2.0.5", + u"2.1.0", + u"2.1.1", + u"2.2.0", + u"2.2.5", + u"2.2.6", + u"2.2.9", + u"2.9.0", + u"2.9.1", + u"2.9.2", + u"2.9.3", + u"2.9.100", + u"2.9.150", + u"2.9.151", + u"2.9.152", + u"2.9.153", + u"2.9.200", + u"2.9.201", + u"2.9.202", + u"2.9.203", + u"2.10.0", + u"2.11.0", + u"2.11.1", + u"2.11.2", + u"2.11.3", + u"2.11.4", + u"2.12.0", + u"2.14.0", + u"2.16.0", + u"2.16.2", + u"2.16.4", + u"2.16.6", + u"2.18.0", + u"2.19.0", + u"2.20.0", + u"2.21.0", + u"2.22.0", + u"2.23.0", + u"2.24.0", + u"2.25.0", + u"2.26.0", + u"2.27.0", + u"2.28.0", + u"2.29.0", + u"2.30.0", + u"2.31.0", + u"2.32.0", + u"2.33.0", + u"2.34.0", + u"2.35.0", + u"2.36.0", + u"2.37.0", + u"2.38.0", + u"2.39.0", + u"2.40.0", + u"2.41.0", + u"2.42.0", + u"2.43.0", + u"2.44.0", + u"2.45.0", + u"2.46.0", + u"2.47.0", + u"2.48.0", + u"2.49.0", + u"2.50.0", + u"2.51.0", + u"2.52.0", + u"2.53.0", + u"2.54.0", + u"2.55.0", + u"2.56.0", + u"2.57.0", + u"2.58.0", + u"2.59.0", + u"2.60.0", + u"2.61.0", + u"2.62.0", + u"2.63.0", + u"2.64.0", + u"2.65.0", + u"2.66.0", + u"2.67.0", + u"2.68.0", + u"2.69.0", + u"2.70.0", + u"2.71.0", + u"2.72.0", + u"2.73.0", + u"2.74.0", + u"2.75.0", + u"2.76.0", + u"2.77.0", + u"2.78.0", + u"2.79.0", + u"2.80.0", + u"2.81.0", + u"2.82.0", + u"2.83.0", ] obs = backend.NpmjsBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -145,19 +235,28 @@ def test_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.NpmjsBackend.get_versions, - project + AnityaPluginException, backend.NpmjsBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) exp = [ - u'0.3.0', u'0.5.0', u'0.5.1', - u'0.6.0', u'0.6.0-1', u'0.6.1', u'0.6.2', - u'1.0.0', u'1.0.1', u'1.0.2', u'1.0.3', - u'1.1.0', u'1.1.1', u'1.1.2', - u'1.2.0-rc0', u'1.2.0', + u"0.3.0", + u"0.5.0", + u"0.5.1", + u"0.6.0", + u"0.6.0-1", + u"0.6.1", + u"0.6.2", + u"1.0.0", + u"1.0.1", + u"1.0.2", + u"1.0.3", + u"1.1.0", + u"1.1.1", + u"1.1.2", + u"1.2.0-rc0", + u"1.2.0", ] obs = backend.NpmjsBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -167,15 +266,36 @@ def test_npmjs_check_feed(self): generator = backend.NpmjsBackend.check_feed() items = sorted(generator) - self.assertEqual(items[0], ( - '2d-density', 'https://github.com/nilestanner/2d-density#readme', 'npmjs', '1.0.0')) - self.assertEqual(items[1], ( - '2d-density', 'https://github.com/nilestanner/2d-density#readme', 'npmjs', '1.0.1')) - self.assertEqual(items[2], ( - 'angular-stackblitz', 'https://npmjs.org/package/angular-stackblitz', 'npmjs', '0.0.0')) + self.assertEqual( + items[0], + ( + "2d-density", + "https://github.com/nilestanner/2d-density#readme", + "npmjs", + "1.0.0", + ), + ) + self.assertEqual( + items[1], + ( + "2d-density", + "https://github.com/nilestanner/2d-density#readme", + "npmjs", + "1.0.1", + ), + ) + self.assertEqual( + items[2], + ( + "angular-stackblitz", + "https://npmjs.org/package/angular-stackblitz", + "npmjs", + "0.0.0", + ), + ) # etc... -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(NpmjsBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_packagist.py b/anitya/tests/lib/backends/test_packagist.py index 4fcfdda0d..ac83ea74a 100644 --- a/anitya/tests/lib/backends/test_packagist.py +++ b/anitya/tests/lib/backends/test_packagist.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the packagist backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Packagist' +BACKEND = "Packagist" class PackagistBackendtests(DatabaseTestCase): @@ -47,27 +47,27 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='php-code-coverage', - homepage='https://packagist.org/packages/phpunit/php-code-coverage', - version_url='phpunit', + name="php-code-coverage", + homepage="https://packagist.org/packages/phpunit/php-code-coverage", + version_url="phpunit", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://packagist.org/packages/fake/php-fake', - version_url='fake', + name="fake", + homepage="https://packagist.org/packages/fake/php-fake", + version_url="fake", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='php-timer', - homepage='https://packagist.org/packages/phpunit/php-timer', - version_url='phpunit', + name="php-timer", + homepage="https://packagist.org/packages/phpunit/php-timer", + version_url="phpunit", backend=BACKEND, ) self.session.add(project) @@ -77,21 +77,19 @@ def test_packagist_get_version(self): """ Test the get_version function of the packagist backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '2.0.17' + exp = "2.0.17" obs = backend.PackagistBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PackagistBackend.get_version, - project + AnityaPluginException, backend.PackagistBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = '1.0.5' + exp = "1.0.5" obs = backend.PackagistBackend.get_version(project) self.assertEqual(obs, exp) @@ -100,12 +98,12 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - version_url='test', + name="test", + homepage="https://example.org", + version_url="test", backend=BACKEND, ) - exp = 'https://packagist.org/packages/test/test.json' + exp = "https://packagist.org/packages/test/test.json" obs = backend.PackagistBackend.get_version_url(project) @@ -117,11 +115,9 @@ def test_get_version_url_missing_version_url(self): version url is missing. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = '' + exp = "" obs = backend.PackagistBackend.get_version_url(project) @@ -132,16 +128,45 @@ def test_packagist_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'1.2.0', u'1.2.1', u'1.2.10', u'1.2.11', u'1.2.12', u'1.2.13', - u'1.2.14', u'1.2.15', u'1.2.16', u'1.2.17', u'1.2.18', u'1.2.2', - u'1.2.3', u'1.2.6', u'1.2.7', u'1.2.8', u'1.2.9', u'1.2.x-dev', - u'2.0.0', u'2.0.1', u'2.0.10', u'2.0.11', u'2.0.12', u'2.0.13', - u'2.0.14', u'2.0.15', u'2.0.16', u'2.0.17', - u'2.0.2', u'2.0.3', u'2.0.4', u'2.0.5', - u'2.0.6', u'2.0.7', u'2.0.8', u'2.0.9', - u'2.0.x-dev', - u'dev-feature/path-coverage', - u'dev-master', + u"1.2.0", + u"1.2.1", + u"1.2.10", + u"1.2.11", + u"1.2.12", + u"1.2.13", + u"1.2.14", + u"1.2.15", + u"1.2.16", + u"1.2.17", + u"1.2.18", + u"1.2.2", + u"1.2.3", + u"1.2.6", + u"1.2.7", + u"1.2.8", + u"1.2.9", + u"1.2.x-dev", + u"2.0.0", + u"2.0.1", + u"2.0.10", + u"2.0.11", + u"2.0.12", + u"2.0.13", + u"2.0.14", + u"2.0.15", + u"2.0.16", + u"2.0.17", + u"2.0.2", + u"2.0.3", + u"2.0.4", + u"2.0.5", + u"2.0.6", + u"2.0.7", + u"2.0.8", + u"2.0.9", + u"2.0.x-dev", + u"dev-feature/path-coverage", + u"dev-master", ] obs = backend.PackagistBackend.get_versions(project) self.assertListEqual(obs, exp) @@ -149,14 +174,12 @@ def test_packagist_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PackagistBackend.get_versions, - project + AnityaPluginException, backend.PackagistBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) - exp = ['dev-master', '1.0.3', '1.0.4', '1.0.5'] + exp = ["dev-master", "1.0.3", "1.0.4", "1.0.5"] obs = backend.PackagistBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -165,18 +188,14 @@ def test_packagist_get_versions_missing_version_url(self): Assert that exception is raised when project version url is missing. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) self.assertRaises( - AnityaPluginException, - backend.PackagistBackend.get_versions, - project + AnityaPluginException, backend.PackagistBackend.get_versions, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(PackagistBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_pagure.py b/anitya/tests/lib/backends/test_pagure.py index 4e4a62818..fa3d99dee 100644 --- a/anitya/tests/lib/backends/test_pagure.py +++ b/anitya/tests/lib/backends/test_pagure.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the pagure backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'pagure' +BACKEND = "pagure" class PagureBackendtests(DatabaseTestCase): @@ -47,17 +47,13 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='pagure', - homepage='https://pagure.io/pagure', - backend=BACKEND, + name="pagure", homepage="https://pagure.io/pagure", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='fake', - homepage='https://pagure.io/fake', - backend=BACKEND, + name="fake", homepage="https://pagure.io/fake", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -66,16 +62,14 @@ def test_pagure_get_version(self): """ Test the get_version function of the pagure backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.1.16' + exp = "0.1.16" obs = backend.PagureBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PagureBackend.get_version, - project + AnityaPluginException, backend.PagureBackend.get_version, project ) def test_get_version_url(self): @@ -83,11 +77,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pagure.io/api/0/test/git/tags' + exp = "https://pagure.io/api/0/test/git/tags" obs = backend.PagureBackend.get_version_url(project) @@ -98,21 +90,34 @@ def test_pagure_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - '0.1', '0.1.1', '0.1.10', '0.1.11', '0.1.12', '0.1.13', '0.1.14', - '0.1.15', '0.1.16', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', - '0.1.7', '0.1.8', '0.1.9'] + "0.1", + "0.1.1", + "0.1.10", + "0.1.11", + "0.1.12", + "0.1.13", + "0.1.14", + "0.1.15", + "0.1.16", + "0.1.2", + "0.1.3", + "0.1.4", + "0.1.5", + "0.1.6", + "0.1.7", + "0.1.8", + "0.1.9", + ] obs = backend.PagureBackend.get_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PagureBackend.get_versions, - project + AnityaPluginException, backend.PagureBackend.get_versions, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(PagureBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_pear.py b/anitya/tests/lib/backends/test_pear.py index 44cf59475..0a596ec7c 100644 --- a/anitya/tests/lib/backends/test_pear.py +++ b/anitya/tests/lib/backends/test_pear.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'PEAR' +BACKEND = "PEAR" class PearBackendtests(DatabaseTestCase): @@ -47,17 +47,15 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='PHP-UML', - homepage='https://pear.php.net/package/PHP_UML', + name="PHP-UML", + homepage="https://pear.php.net/package/PHP_UML", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://pear.php.net/package/foo', - backend=BACKEND, + name="foo", homepage="https://pear.php.net/package/foo", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -66,16 +64,14 @@ def test_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '1.6.2' + exp = "1.6.2" obs = backend.PearBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PearBackend.get_version, - project + AnityaPluginException, backend.PearBackend.get_version, project ) def test_get_version_url(self): @@ -83,11 +79,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pear.php.net/rest/r/test/allreleases.xml' + exp = "https://pear.php.net/rest/r/test/allreleases.xml" obs = backend.PearBackend.get_version_url(project) @@ -98,11 +92,9 @@ def test_get_version_url_dash(self): Assert that correct url is returned when project name contains '-'. """ project = models.Project( - name='te-st', - homepage='https://example.org', - backend=BACKEND, + name="te-st", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pear.php.net/rest/r/te_st/allreleases.xml' + exp = "https://pear.php.net/rest/r/te_st/allreleases.xml" obs = backend.PearBackend.get_version_url(project) @@ -113,18 +105,31 @@ def test_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - '0.4.2', '0.4.4', '0.5.0', '0.5.1', '0.5.2', '0.5.3', '1.0.0', - '1.0.1', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', '1.5.5', - '1.6.0', '1.6.1', '1.6.2'] + "0.4.2", + "0.4.4", + "0.5.0", + "0.5.1", + "0.5.2", + "0.5.3", + "1.0.0", + "1.0.1", + "1.5.0", + "1.5.1", + "1.5.2", + "1.5.3", + "1.5.4", + "1.5.5", + "1.6.0", + "1.6.1", + "1.6.2", + ] obs = backend.PearBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PearBackend.get_version, - project + AnityaPluginException, backend.PearBackend.get_version, project ) def test_pear_check_feed(self): @@ -132,15 +137,22 @@ def test_pear_check_feed(self): generator = backend.PearBackend.check_feed() items = list(generator) - self.assertEqual(items[0], ( - 'File_Therion', 'https://pear.php.net/package/File_Therion', - 'PEAR', '0.1.0')) - self.assertEqual(items[1], ( - 'Net_URL2', 'https://pear.php.net/package/Net_URL2', - 'PEAR', '2.1.2')) + self.assertEqual( + items[0], + ( + "File_Therion", + "https://pear.php.net/package/File_Therion", + "PEAR", + "0.1.0", + ), + ) + self.assertEqual( + items[1], + ("Net_URL2", "https://pear.php.net/package/Net_URL2", "PEAR", "2.1.2"), + ) # etc... -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(PearBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_pecl.py b/anitya/tests/lib/backends/test_pecl.py index 4af5f1bd8..ef38302d3 100644 --- a/anitya/tests/lib/backends/test_pecl.py +++ b/anitya/tests/lib/backends/test_pecl.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'PECL' +BACKEND = "PECL" class PeclBackendtests(DatabaseTestCase): @@ -47,17 +47,15 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='inotify', - homepage='https://pecl.php.net/package/inotify', + name="inotify", + homepage="https://pecl.php.net/package/inotify", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foo', - homepage='https://pecl.php.net/package/foo', - backend=BACKEND, + name="foo", homepage="https://pecl.php.net/package/foo", backend=BACKEND ) self.session.add(project) self.session.commit() @@ -66,16 +64,14 @@ def test_get_version(self): """ Test the get_version function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '0.1.6' + exp = "0.1.6" obs = backend.PeclBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PeclBackend.get_version, - project + AnityaPluginException, backend.PeclBackend.get_version, project ) def test_get_version_url(self): @@ -83,11 +79,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pecl.php.net/rest/r/test/allreleases.xml' + exp = "https://pecl.php.net/rest/r/test/allreleases.xml" obs = backend.PeclBackend.get_version_url(project) @@ -98,11 +92,9 @@ def test_get_version_url_dash(self): Assert that correct url is returned when project name contains '-'. """ project = models.Project( - name='te-st', - homepage='https://example.org', - backend=BACKEND, + name="te-st", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pecl.php.net/rest/r/te_st/allreleases.xml' + exp = "https://pecl.php.net/rest/r/te_st/allreleases.xml" obs = backend.PeclBackend.get_version_url(project) @@ -112,16 +104,14 @@ def test_get_versions(self): """ Test the get_versions function of the custom backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6'] + exp = ["0.1.2", "0.1.3", "0.1.4", "0.1.5", "0.1.6"] obs = backend.PeclBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.PeclBackend.get_version, - project + AnityaPluginException, backend.PeclBackend.get_version, project ) def test_pecl_check_feed(self): @@ -129,14 +119,16 @@ def test_pecl_check_feed(self): generator = backend.PeclBackend.check_feed() items = list(generator) - self.assertEqual(items[0], ( - 'rrd', 'https://pecl.php.net/package/rrd', 'PECL', '2.0.1')) - self.assertEqual(items[1], ( - 'libsodium', 'https://pecl.php.net/package/libsodium', - 'PECL', '1.0.6')) + self.assertEqual( + items[0], ("rrd", "https://pecl.php.net/package/rrd", "PECL", "2.0.1") + ) + self.assertEqual( + items[1], + ("libsodium", "https://pecl.php.net/package/libsodium", "PECL", "1.0.6"), + ) # etc... -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(PeclBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_pypi.py b/anitya/tests/lib/backends/test_pypi.py index 98fcb39a3..92e21dfe3 100644 --- a/anitya/tests/lib/backends/test_pypi.py +++ b/anitya/tests/lib/backends/test_pypi.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the pypi backend. -''' +""" import anitya.lib.backends.pypi as backend from anitya.db import models @@ -29,7 +29,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'PyPI' +BACKEND = "PyPI" class PypiBackendtests(DatabaseTestCase): @@ -44,42 +44,36 @@ def setUp(self): def test_get_version_missing_project(self): """Assert an AnityaPluginException is raised for projects that result in 404.""" project = models.Project( - name='repo_manager_fake', - homepage='https://pypi.org/project/repo_manager_fake/', + name="repo_manager_fake", + homepage="https://pypi.org/project/repo_manager_fake/", backend=BACKEND, ) self.session.add(project) self.session.commit() self.assertRaises( - AnityaPluginException, - backend.PypiBackend.get_version, - project + AnityaPluginException, backend.PypiBackend.get_version, project ) def test_pypi_get_version(self): """ Test the get_version function of the pypi backend. """ project = models.Project( - name='chai', - homepage='https://pypi.org/project/chai/', - backend=BACKEND, + name="chai", homepage="https://pypi.org/project/chai/", backend=BACKEND ) self.session.add(project) self.session.commit() obs = backend.PypiBackend.get_version(project) - self.assertEqual(obs, '1.1.2') + self.assertEqual(obs, "1.1.2") def test_get_version_url(self): """ Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://pypi.org/pypi/test/json' + exp = "https://pypi.org/pypi/test/json" obs = backend.PypiBackend.get_version_url(project) @@ -88,13 +82,13 @@ def test_get_version_url(self): def test_pypi_get_versions(self): """ Test the get_versions function of the pypi backend. """ project = models.Project( - name='repo_manager', - homepage='https://pypi.org/project/repo_manager/', + name="repo_manager", + homepage="https://pypi.org/project/repo_manager/", backend=BACKEND, ) self.session.add(project) self.session.commit() - exp = ['0.1.0'] + exp = ["0.1.0"] obs = backend.PypiBackend.get_versions(project) self.assertEqual(obs, exp) @@ -105,13 +99,15 @@ def test_pypi_check_feed(self): items = list(generator) self.assertEqual( - items[0], ('simplemdx', 'https://pypi.org/project/simplemdx/', 'PyPI', '0.1.2')) + items[0], + ("simplemdx", "https://pypi.org/project/simplemdx/", "PyPI", "0.1.2"), + ) self.assertEqual( items[1], ( - 'tapioca-trustwave-appscanner', - 'https://pypi.org/project/tapioca-trustwave-appscanner/', - 'PyPI', - '0.3' - ) + "tapioca-trustwave-appscanner", + "https://pypi.org/project/tapioca-trustwave-appscanner/", + "PyPI", + "0.3", + ), ) diff --git a/anitya/tests/lib/backends/test_rubygems.py b/anitya/tests/lib/backends/test_rubygems.py index 2250c9573..0257da426 100644 --- a/anitya/tests/lib/backends/test_rubygems.py +++ b/anitya/tests/lib/backends/test_rubygems.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Rubygems' +BACKEND = "Rubygems" class RubygemsBackendtests(DatabaseTestCase): @@ -47,16 +47,14 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='bio', - homepage='https://rubygems.org/gems/bio', - backend=BACKEND, + name="bio", homepage="https://rubygems.org/gems/bio", backend=BACKEND ) self.session.add(project) self.session.commit() project = models.Project( - name='biofoobar', - homepage='https://rubygems.org/gems/biofoobar', + name="biofoobar", + homepage="https://rubygems.org/gems/biofoobar", backend=BACKEND, ) self.session.add(project) @@ -66,16 +64,14 @@ def test_get_version(self): """ Test the get_version function of the rubygems backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '1.5.1' + exp = "1.5.1" obs = backend.RubygemsBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.RubygemsBackend.get_version, - project + AnityaPluginException, backend.RubygemsBackend.get_version, project ) def test_get_version_url(self): @@ -83,11 +79,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://rubygems.org/api/v1/versions/test/latest.json' + exp = "https://rubygems.org/api/v1/versions/test/latest.json" obs = backend.RubygemsBackend.get_version_url(project) @@ -97,16 +91,14 @@ def test_get_versions(self): """ Test the get_versions function of the rubygems backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['1.5.1'] + exp = ["1.5.1"] obs = backend.RubygemsBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.RubygemsBackend.get_version, - project + AnityaPluginException, backend.RubygemsBackend.get_version, project ) def test_rubygems_check_feed(self): @@ -114,15 +106,22 @@ def test_rubygems_check_feed(self): generator = backend.RubygemsBackend.check_feed() items = list(generator) - self.assertEqual(items[0], ( - 'mathrix-rails', 'https://rubygems.org/gems/mathrix-rails', - 'Rubygems', '1.0.0')) - self.assertEqual(items[1], ( - 'zipcoder', 'https://rubygems.org/gems/zipcoder', - 'Rubygems', '0.2.0')) + self.assertEqual( + items[0], + ( + "mathrix-rails", + "https://rubygems.org/gems/mathrix-rails", + "Rubygems", + "1.0.0", + ), + ) + self.assertEqual( + items[1], + ("zipcoder", "https://rubygems.org/gems/zipcoder", "Rubygems", "0.2.0"), + ) # etc... -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(RubygemsBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_sourceforge.py b/anitya/tests/lib/backends/test_sourceforge.py index f690b0f39..6d761ea69 100644 --- a/anitya/tests/lib/backends/test_sourceforge.py +++ b/anitya/tests/lib/backends/test_sourceforge.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Sourceforge' +BACKEND = "Sourceforge" class SourceforgeBackendtests(DatabaseTestCase): @@ -47,24 +47,24 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='filezilla', - homepage='https://sourceforge.net/projects/filezilla/', + name="filezilla", + homepage="https://sourceforge.net/projects/filezilla/", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foobar', - homepage='https://sourceforge.net/projects/foobar', + name="foobar", + homepage="https://sourceforge.net/projects/foobar", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='file-folder-ren', - homepage='https://sourceforge.net/projects/file-folder-ren/', + name="file-folder-ren", + homepage="https://sourceforge.net/projects/file-folder-ren/", backend=BACKEND, ) self.session.add(project) @@ -74,24 +74,20 @@ def test_get_version(self): """ Test the get_version function of the sourceforge backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '3.31.0' + exp = "3.31.0" obs = backend.SourceforgeBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.SourceforgeBackend.get_version, - project + AnityaPluginException, backend.SourceforgeBackend.get_version, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.SourceforgeBackend.get_version, - project + AnityaPluginException, backend.SourceforgeBackend.get_version, project ) def test_get_version_url(self): @@ -99,12 +95,12 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - version_url='test_name', + name="test", + homepage="https://example.org", + version_url="test_name", backend=BACKEND, ) - exp = 'https://sourceforge.net/projects/test_name/rss?limit=200' + exp = "https://sourceforge.net/projects/test_name/rss?limit=200" obs = backend.SourceforgeBackend.get_version_url(project) @@ -116,11 +112,9 @@ def test_get_version_url_missing_version_url(self): is missing. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://sourceforge.net/projects/test/rss?limit=200' + exp = "https://sourceforge.net/projects/test/rss?limit=200" obs = backend.SourceforgeBackend.get_version_url(project) @@ -132,12 +126,12 @@ def test_get_version_url_version_url_plus(self): contains '+'. """ project = models.Project( - name='test', - homepage='https://example.org', - version_url='test+name', + name="test", + homepage="https://example.org", + version_url="test+name", backend=BACKEND, ) - exp = r'https://sourceforge.net/projects/test\+name/rss?limit=200' + exp = r"https://sourceforge.net/projects/test\+name/rss?limit=200" obs = backend.SourceforgeBackend.get_version_url(project) @@ -149,11 +143,9 @@ def test_get_version_url_project_name_plus(self): contains '+'. """ project = models.Project( - name='test+', - homepage='https://example.org', - backend=BACKEND, + name="test+", homepage="https://example.org", backend=BACKEND ) - exp = r'https://sourceforge.net/projects/test\+/rss?limit=200' + exp = r"https://sourceforge.net/projects/test\+/rss?limit=200" obs = backend.SourceforgeBackend.get_version_url(project) @@ -164,10 +156,19 @@ def test_get_versions(self): pid = 1 project = models.Project.get(self.session, pid) exp = [ - u'3.25.0', u'3.25.1', u'3.25.2', - u'3.26.0', u'3.26.1', u'3.26.2', - u'3.27.0', u'3.27.0.1', u'3.27.1', - u'3.28.0', u'3.29.0', u'3.30.0', u'3.31.0', + u"3.25.0", + u"3.25.1", + u"3.25.2", + u"3.26.0", + u"3.26.1", + u"3.26.2", + u"3.27.0", + u"3.27.0.1", + u"3.27.1", + u"3.28.0", + u"3.29.0", + u"3.30.0", + u"3.31.0", ] obs = backend.SourceforgeBackend.get_ordered_versions(project) self.assertEqual(obs, exp) @@ -175,21 +176,16 @@ def test_get_versions(self): pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.SourceforgeBackend.get_versions, - project + AnityaPluginException, backend.SourceforgeBackend.get_versions, project ) pid = 3 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.SourceforgeBackend.get_versions, - project + AnityaPluginException, backend.SourceforgeBackend.get_versions, project ) -if __name__ == '__main__': - SUITE = unittest.TestLoader().loadTestsFromTestCase( - SourceforgeBackendtests) +if __name__ == "__main__": + SUITE = unittest.TestLoader().loadTestsFromTestCase(SourceforgeBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/backends/test_stackage.py b/anitya/tests/lib/backends/test_stackage.py index bfc7b35b7..8374e3a8b 100644 --- a/anitya/tests/lib/backends/test_stackage.py +++ b/anitya/tests/lib/backends/test_stackage.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the custom backend. -''' +""" import unittest @@ -31,7 +31,7 @@ from anitya.tests.base import DatabaseTestCase, create_distro -BACKEND = 'Stackage' +BACKEND = "Stackage" class HackageBackendtests(DatabaseTestCase): @@ -47,16 +47,16 @@ def setUp(self): def create_project(self): """ Create some basic projects to work with. """ project = models.Project( - name='cpphs', - homepage='https://www.stackage.org/package/cpphs', + name="cpphs", + homepage="https://www.stackage.org/package/cpphs", backend=BACKEND, ) self.session.add(project) self.session.commit() project = models.Project( - name='foobar', - homepage='https://www.stackage.org/package/foobar', + name="foobar", + homepage="https://www.stackage.org/package/foobar", backend=BACKEND, ) self.session.add(project) @@ -66,16 +66,14 @@ def test_get_version(self): """ Test the get_version function of the Stackage backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = '1.20.1' + exp = "1.20.1" obs = backend.StackageBackend.get_version(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.StackageBackend.get_version, - project + AnityaPluginException, backend.StackageBackend.get_version, project ) def test_get_version_url(self): @@ -83,11 +81,9 @@ def test_get_version_url(self): Assert that correct url is returned. """ project = models.Project( - name='test', - homepage='https://example.org', - backend=BACKEND, + name="test", homepage="https://example.org", backend=BACKEND ) - exp = 'https://www.stackage.org/package/test' + exp = "https://www.stackage.org/package/test" obs = backend.StackageBackend.get_version_url(project) @@ -97,19 +93,17 @@ def test_get_versions(self): """ Test the get_versions function of the Stackage backend. """ pid = 1 project = models.Project.get(self.session, pid) - exp = ['1.20.1'] + exp = ["1.20.1"] obs = backend.StackageBackend.get_ordered_versions(project) self.assertEqual(obs, exp) pid = 2 project = models.Project.get(self.session, pid) self.assertRaises( - AnityaPluginException, - backend.StackageBackend.get_version, - project + AnityaPluginException, backend.StackageBackend.get_version, project ) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(HackageBackendtests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/test_exceptions.py b/anitya/tests/lib/test_exceptions.py index 942484238..31de8b3d5 100644 --- a/anitya/tests/lib/test_exceptions.py +++ b/anitya/tests/lib/test_exceptions.py @@ -37,10 +37,11 @@ def test_message(self): project_id = 1 project_name = "Cthulhu" link = "link" - exp = 'Could not edit the mapping of {pkgname} on ' \ - '{distro}, there is already a package {found_pkgname} on ' \ - '{found_distro} as part of the project ' \ - '{project_name}.'.format( + exp = ( + "Could not edit the mapping of {pkgname} on " + "{distro}, there is already a package {found_pkgname} on " + '{found_distro} as part of the project ' + "{project_name}.".format( pkgname=pkgname, distro=distro, found_pkgname=found_pkgname, @@ -49,15 +50,17 @@ def test_message(self): project_name=project_name, link=None, ) + ) e = exceptions.AnityaInvalidMappingException( - pkgname, distro, found_pkgname, found_distro, - project_id, project_name) + pkgname, distro, found_pkgname, found_distro, project_id, project_name + ) self.assertEqual(exp, e.message) - exp = 'Could not edit the mapping of {pkgname} on ' \ - '{distro}, there is already a package {found_pkgname} on ' \ - '{found_distro} as part of the project ' \ - '{project_name}.'.format( + exp = ( + "Could not edit the mapping of {pkgname} on " + "{distro}, there is already a package {found_pkgname} on " + '{found_distro} as part of the project ' + "{project_name}.".format( pkgname=pkgname, distro=distro, found_pkgname=found_pkgname, @@ -66,9 +69,10 @@ def test_message(self): project_name=project_name, link=link, ) + ) e = exceptions.AnityaInvalidMappingException( - pkgname, distro, found_pkgname, found_distro, - project_id, project_name, link) + pkgname, distro, found_pkgname, found_distro, project_id, project_name, link + ) self.assertEqual(exp, e.message) @@ -77,12 +81,12 @@ class InvalidVersionTests(unittest.TestCase): def test_str(self): """Assert the __str__ method provides a human-readable value.""" - e = exceptions.InvalidVersion('notaversion') + e = exceptions.InvalidVersion("notaversion") self.assertEqual('Invalid version "notaversion"', str(e)) def test_str_with_wrapped_exception(self): """Assert the __str__ method provides a human-readable value including the exception.""" - e = exceptions.InvalidVersion('notaversion', IOError('womp womp')) + e = exceptions.InvalidVersion("notaversion", IOError("womp womp")) self.assertEqual('Invalid version "notaversion": womp womp', str(e)) diff --git a/anitya/tests/lib/test_plugins.py b/anitya/tests/lib/test_plugins.py index 0833b1ccb..9478e9ede 100644 --- a/anitya/tests/lib/test_plugins.py +++ b/anitya/tests/lib/test_plugins.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests of the plugins. -''' +""" import unittest @@ -30,12 +30,33 @@ from anitya.tests.base import DatabaseTestCase EXPECTED_BACKENDS = [ - 'BitBucket', 'CPAN (perl)', 'CRAN (R)', 'crates.io', 'Debian project', - 'Drupal6', 'Drupal7', 'Freshmeat', - 'GNOME', 'GNU project', 'GitHub', 'GitLab', 'Google code', 'Hackage', - 'Launchpad', 'Maven Central', 'PEAR', 'PECL', 'Packagist', 'PyPI', - 'Rubygems', 'Sourceforge', 'Stackage', 'custom', 'folder', 'npmjs', - 'pagure', + "BitBucket", + "CPAN (perl)", + "CRAN (R)", + "crates.io", + "Debian project", + "Drupal6", + "Drupal7", + "Freshmeat", + "GNOME", + "GNU project", + "GitHub", + "GitLab", + "Google code", + "Hackage", + "Launchpad", + "Maven Central", + "PEAR", + "PECL", + "Packagist", + "PyPI", + "Rubygems", + "Sourceforge", + "Stackage", + "custom", + "folder", + "npmjs", + "pagure", ] EXPECTED_ECOSYSTEMS = { @@ -46,9 +67,7 @@ "crates.io": "crates.io", } -EXPECTED_VERSIONS = [ - 'RPM' -] +EXPECTED_VERSIONS = ["RPM"] class VersionPluginsTests(unittest.TestCase): @@ -76,8 +95,9 @@ def test_load_all_plugins(self): self.assertEqual(sorted(backend_names), sorted(EXPECTED_BACKENDS)) ecosystem_plugins = all_plugins["ecosystems"] - ecosystems = dict((plugin.name, plugin.default_backend) - for plugin in ecosystem_plugins) + ecosystems = dict( + (plugin.name, plugin.default_backend) for plugin in ecosystem_plugins + ) self.assertEqual(ecosystems, EXPECTED_ECOSYSTEMS) def test_load_plugins(self): @@ -95,11 +115,10 @@ def test_plugins_get_plugin_names(self): def test_plugins_get_plugin(self): """ Test the plugins.get_plugin function. """ - plugin = plugins.get_plugin('PyPI') - self.assertEqual( - str(plugin), "") + plugin = plugins.get_plugin("PyPI") + self.assertEqual(str(plugin), "") -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Pluginstests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/lib/test_utilities.py b/anitya/tests/lib/test_utilities.py index 792b63577..ab215f422 100644 --- a/anitya/tests/lib/test_utilities.py +++ b/anitya/tests/lib/test_utilities.py @@ -28,8 +28,10 @@ from anitya.lib import utilities, exceptions, plugins from anitya.lib.exceptions import AnityaException, ProjectExists from anitya.tests.base import ( - DatabaseTestCase, create_distro, - create_project, create_flagged_project + DatabaseTestCase, + create_distro, + create_project, + create_flagged_project, ) @@ -43,47 +45,48 @@ def test_create_project(self): utilities.create_project( self.session, - name='geany', - homepage='https://www.geany.org/', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', - user_id='noreply@fedoraproject.org', + name="geany", + homepage="https://www.geany.org/", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", + user_id="noreply@fedoraproject.org", ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 1) - self.assertEqual(project_objs[0].name, 'geany') - self.assertEqual(project_objs[0].homepage, 'https://www.geany.org/') + self.assertEqual(project_objs[0].name, "geany") + self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") self.assertRaises( ProjectExists, utilities.create_project, self.session, - name='geany', - homepage='https://www.geany.org/', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', - user_id='noreply@fedoraproject.org', + name="geany", + homepage="https://www.geany.org/", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", + user_id="noreply@fedoraproject.org", ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 1) - self.assertEqual(project_objs[0].name, 'geany') - self.assertEqual(project_objs[0].homepage, 'https://www.geany.org/') + self.assertEqual(project_objs[0].name, "geany") + self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") def test_create_project_general_error(self): """Assert general SQLAlchemy exceptions result in AnityaException.""" with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): self.assertRaises( AnityaException, utilities.create_project, self.session, - name='geany', - homepage='https://www.geany.org/', - version_url='https://www.geany.org/Download/Releases', - regex='DEFAULT', - user_id='noreply@fedoraproject.org', + name="geany", + homepage="https://www.geany.org/", + version_url="https://www.geany.org/Download/Releases", + regex="DEFAULT", + user_id="noreply@fedoraproject.org", ) @@ -97,29 +100,30 @@ def test_edit_project(self): project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) - self.assertEqual(project_objs[0].name, 'geany') - self.assertEqual(project_objs[0].homepage, 'https://www.geany.org/') - self.assertEqual(project_objs[1].name, 'R2spec') - self.assertEqual(project_objs[2].name, 'subsurface') + self.assertEqual(project_objs[0].name, "geany") + self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") + self.assertEqual(project_objs[1].name, "R2spec") + self.assertEqual(project_objs[2].name, "subsurface") utilities.edit_project( self.session, project=project_objs[0], name=project_objs[0].name, - homepage='https://www.geany.org', - backend='PyPI', - version_scheme='RPM', + homepage="https://www.geany.org", + backend="PyPI", + version_scheme="RPM", version_url=None, version_prefix=None, regex=None, insecure=False, - user_id='noreply@fedoraproject.org') + user_id="noreply@fedoraproject.org", + ) project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) - self.assertEqual(project_objs[0].name, 'geany') - self.assertEqual(project_objs[0].homepage, 'https://www.geany.org') - self.assertEqual(project_objs[0].backend, 'PyPI') + self.assertEqual(project_objs[0].name, "geany") + self.assertEqual(project_objs[0].homepage, "https://www.geany.org") + self.assertEqual(project_objs[0].backend, "PyPI") def test_edit_project_creating_duplicate(self): """ @@ -130,25 +134,25 @@ def test_edit_project_creating_duplicate(self): project_objs = models.Project.all(self.session) self.assertEqual(len(project_objs), 3) - self.assertEqual(project_objs[0].name, 'geany') - self.assertEqual(project_objs[0].homepage, 'https://www.geany.org/') - self.assertEqual(project_objs[1].name, 'R2spec') - self.assertEqual(project_objs[2].name, 'subsurface') + self.assertEqual(project_objs[0].name, "geany") + self.assertEqual(project_objs[0].homepage, "https://www.geany.org/") + self.assertEqual(project_objs[1].name, "R2spec") + self.assertEqual(project_objs[2].name, "subsurface") self.assertRaises( AnityaException, utilities.edit_project, self.session, project=project_objs[2], - name='geany', - homepage='https://www.geany.org/', + name="geany", + homepage="https://www.geany.org/", backend=project_objs[2].backend, version_scheme=project_objs[2].version_scheme, version_url=project_objs[2].version_url, version_prefix=None, regex=project_objs[2].regex, insecure=False, - user_id='noreply@fedoraproject.org', + user_id="noreply@fedoraproject.org", ) def test_edit_project_insecure(self): @@ -163,15 +167,15 @@ def test_edit_project_insecure(self): utilities.edit_project( self.session, project=project_objs[0], - name='geany', - homepage='https://www.geany.org/', + name="geany", + homepage="https://www.geany.org/", backend=project_objs[0].backend, - version_scheme='RPM', + version_scheme="RPM", version_url=project_objs[0].version_url, version_prefix=None, regex=project_objs[0].regex, insecure=True, - user_id='noreply@fedoraproject.org', + user_id="noreply@fedoraproject.org", ) project_objs = models.Project.all(self.session) @@ -181,48 +185,43 @@ def test_edit_project_insecure(self): class CheckProjectReleaseTests(DatabaseTestCase): """Tests for the :func:`anitya.lib.utilities.check_project_release` function.""" - @mock.patch('anitya.db.models.Project') + @mock.patch("anitya.db.models.Project") def test_check_project_release_no_backend(self, mock_project): """ Test the check_project_release function for Project. """ m_project = mock_project.return_value - m_project.backend.return_value = 'dummy' + m_project.backend.return_value = "dummy" self.assertRaises( - AnityaException, - utilities.check_project_release, - m_project, - self.session + AnityaException, utilities.check_project_release, m_project, self.session ) @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0', '0.9.9', '0.9.8']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["1.0.0", "0.9.9", "0.9.8"], + ) def test_check_project_release_backend(self, mock_method): """ Test the check_project_release function for Project. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org' + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) - versions = utilities.check_project_release( - project, - self.session, - test=True - ) - self.assertEqual(versions, ['0.9.8', '0.9.9', '1.0.0']) + versions = utilities.check_project_release(project, self.session, test=True) + self.assertEqual(versions, ["0.9.8", "0.9.9", "1.0.0"]) @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - mock.Mock(side_effect=exceptions.AnityaPluginException(""))) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + mock.Mock(side_effect=exceptions.AnityaPluginException("")), + ) def test_check_project_release_plugin_exception(self): """ Test the check_project_release function for Project. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org' + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) self.assertRaises( exceptions.AnityaPluginException, @@ -232,122 +231,106 @@ def test_check_project_release_plugin_exception(self): ) @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", return_value=["1.0.0"] + ) def test_check_project_release_no_new_version(self, mock_method): """ Test the check_project_release function for Project. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org', - ) - project.latest_version = '1.0.0' - version = models.ProjectVersion( - version='1.0.0', - project_id=project.id + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) + project.latest_version = "1.0.0" + version = models.ProjectVersion(version="1.0.0", project_id=project.id) self.session.add(version) self.session.commit() - utilities.check_project_release( - project, - self.session - ) + utilities.check_project_release(project, self.session) - self.assertEqual(project.latest_version, '1.0.0') - self.assertEqual( - project.logs, - 'No new version found' - ) + self.assertEqual(project.latest_version, "1.0.0") + self.assertEqual(project.logs, "No new version found") @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0', '0.9.9', '0.9.8']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["1.0.0", "0.9.9", "0.9.8"], + ) def test_check_project_release_new_version(self, mock_method): """ Test the check_project_release function for Project. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org', - version_scheme='RPM', - ) - utilities.check_project_release( - project, - self.session + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", + version_scheme="RPM", ) + utilities.check_project_release(project, self.session) versions = project.get_sorted_version_objects() self.assertEqual(len(versions), 3) - self.assertEqual(versions[0].version, '1.0.0') + self.assertEqual(versions[0].version, "1.0.0") @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['v1.0.0', 'v0.9.9', 'v0.9.8']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["v1.0.0", "v0.9.9", "v0.9.8"], + ) def test_check_project_release_prefix_remove(self, mock_method): """ Test the check_project_release function for Project. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org', - version_scheme='RPM', - ) - utilities.check_project_release( - project, - self.session + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", + version_scheme="RPM", ) + utilities.check_project_release(project, self.session) versions = project.get_sorted_version_objects() self.assertEqual(len(versions), 3) - self.assertEqual(versions[0].version, 'v1.0.0') - self.assertEqual(project.latest_version, '1.0.0') + self.assertEqual(versions[0].version, "v1.0.0") + self.assertEqual(project.latest_version, "1.0.0") @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0', '0.9.9', '0.9.8']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["1.0.0", "0.9.9", "0.9.8"], + ) def test_check_project_check_times(self, mock_method): """ Test if check times are set. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org' + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) last_check_orig = project.last_check - utilities.check_project_release( - project, - self.session + utilities.check_project_release(project, self.session) + next_check = ( + plugins.get_plugin(project.backend).check_interval + project.last_check ) - next_check = plugins.get_plugin(project.backend).check_interval + project.last_check self.assertTrue(last_check_orig < project.last_check) self.assertEqual(next_check, project.next_check) @mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0', '0.9.9', '0.9.8']) + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["1.0.0", "0.9.9", "0.9.8"], + ) def test_check_project_check_times_test(self, mock_method): """ Test if check times aren't set in test mode. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org' + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) last_check_orig = project.last_check next_check_orig = project.next_check - utilities.check_project_release( - project, - self.session, - test=True - ) + utilities.check_project_release(project, self.session, test=True) self.assertEqual(last_check_orig, project.last_check) self.assertEqual(next_check_orig, project.next_check) @@ -355,17 +338,18 @@ def test_check_project_check_times_exception(self): """ Test if check times are set if `exceptions.RateLimitException` is raised. """ project = utilities.create_project( self.session, - name='pypi_and_npm', - homepage='https://example.com/not-a-real-npmjs-project', - backend='npmjs', - user_id='noreply@fedoraproject.org' + name="pypi_and_npm", + homepage="https://example.com/not-a-real-npmjs-project", + backend="npmjs", + user_id="noreply@fedoraproject.org", ) last_check_orig = project.last_check next_check = arrow.get("2008-09-03T20:56:35.450686").naive with mock.patch( - 'anitya.lib.backends.npmjs.NpmjsBackend.get_versions', - return_value=['1.0.0']) as mock_object: + "anitya.lib.backends.npmjs.NpmjsBackend.get_versions", + return_value=["1.0.0"], + ) as mock_object: mock_object.side_effect = exceptions.RateLimitException( "2008-09-03T20:56:35.450686" ) @@ -378,34 +362,33 @@ def test_check_project_check_times_exception(self): self.assertTrue(last_check_orig < project.last_check) self.assertEqual(next_check, project.next_check) - @mock.patch.dict('anitya.config.config', {'GITHUB_ACCESS_TOKEN': "foobar"}) + @mock.patch.dict("anitya.config.config", {"GITHUB_ACCESS_TOKEN": "foobar"}) def test_check_project_version_too_long(self): """ Regression test for https://github.com/release-monitoring/anitya/issues/674 Crash when version is too long """ project = models.Project( - name='daiquiri', - homepage='https://github.com/jd/daiquiri', - backend='GitHub', - version_scheme='RPM', - version_url='jd/daiquiri', + name="daiquiri", + homepage="https://github.com/jd/daiquiri", + backend="GitHub", + version_scheme="RPM", + version_url="jd/daiquiri", ) self.session.add(project) self.session.commit() - utilities.check_project_release( - project, - self.session - ) + utilities.check_project_release(project, self.session) versions = project.versions self.assertEqual(len(versions), 18) self.assertFalse( - 'remove-circular-dependency-ad4f7bc7-2ab4-43b8-afac-36ff0e2ee796' in versions + "remove-circular-dependency-ad4f7bc7-2ab4-43b8-afac-36ff0e2ee796" + in versions ) self.assertFalse( - 'remove-circular-dependency-7bbe4a64-3514-4f6e-9c03-9dc8bcf4def7' in versions + "remove-circular-dependency-7bbe4a64-3514-4f6e-9c03-9dc8bcf4def7" + in versions ) @@ -418,69 +401,69 @@ def test_map_project(self): create_project(self.session) project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 0) # Map `geany` project to CentOS utilities.map_project( self.session, project=project_obj, - package_name='geany', - distribution='CentOS', - user_id='noreply@fedoraproject.org', + package_name="geany", + distribution="CentOS", + user_id="noreply@fedoraproject.org", old_package_name=None, ) self.session.commit() project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 1) - self.assertEqual(project_obj.packages[0].package_name, 'geany') - self.assertEqual(project_obj.packages[0].distro_name, 'CentOS') + self.assertEqual(project_obj.packages[0].package_name, "geany") + self.assertEqual(project_obj.packages[0].distro_name, "CentOS") # Map `geany` project to CentOS, exactly the same way utilities.map_project( self.session, project=project_obj, - package_name='geany2', - distribution='CentOS', - user_id='noreply@fedoraproject.org', + package_name="geany2", + distribution="CentOS", + user_id="noreply@fedoraproject.org", old_package_name=None, ) self.session.commit() project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 2) - self.assertEqual(project_obj.packages[0].package_name, 'geany') - self.assertEqual(project_obj.packages[0].distro_name, 'CentOS') - self.assertEqual(project_obj.packages[1].package_name, 'geany2') - self.assertEqual(project_obj.packages[1].distro_name, 'CentOS') + self.assertEqual(project_obj.packages[0].package_name, "geany") + self.assertEqual(project_obj.packages[0].distro_name, "CentOS") + self.assertEqual(project_obj.packages[1].package_name, "geany2") + self.assertEqual(project_obj.packages[1].distro_name, "CentOS") # Edit the mapping of the `geany` project to Fedora utilities.map_project( self.session, project=project_obj, - package_name='geany3', - distribution='Fedora', - user_id='noreply@fedoraproject.org', - old_package_name='geany', - old_distro_name='CentOS', + package_name="geany3", + distribution="Fedora", + user_id="noreply@fedoraproject.org", + old_package_name="geany", + old_distro_name="CentOS", ) self.session.commit() project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 2) pkgs = sorted(project_obj.packages, key=lambda x: x.package_name) - self.assertEqual(pkgs[0].package_name, 'geany2') - self.assertEqual(pkgs[0].distro_name, 'CentOS') - self.assertEqual(pkgs[1].package_name, 'geany3') - self.assertEqual(pkgs[1].distro_name, 'Fedora') + self.assertEqual(pkgs[0].package_name, "geany2") + self.assertEqual(pkgs[0].distro_name, "CentOS") + self.assertEqual(pkgs[1].package_name, "geany3") + self.assertEqual(pkgs[1].distro_name, "Fedora") # Edit the mapping of the `geany` project to Fedora project_obj = models.Project.get(self.session, 2) - self.assertEqual(project_obj.name, 'subsurface') + self.assertEqual(project_obj.name, "subsurface") self.assertEqual(len(project_obj.packages), 0) self.assertRaises( @@ -488,9 +471,9 @@ def test_map_project(self): utilities.map_project, self.session, project=project_obj, - package_name='geany2', - distribution='CentOS', - user_id='noreply@fedoraproject.org', + package_name="geany2", + distribution="CentOS", + user_id="noreply@fedoraproject.org", ) def test_map_project_no_project_for_package(self): @@ -499,56 +482,55 @@ def test_map_project_no_project_for_package(self): create_project(self.session) pkg = models.Packages( - distro_name='Fedora', - project_id=None, - package_name='geany' + distro_name="Fedora", project_id=None, package_name="geany" ) self.session.add(pkg) self.session.commit() distro_objs = self.session.query(models.Distro).all() project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 0) - self.assertEqual(distro_objs[0].name, 'Fedora') + self.assertEqual(distro_objs[0].name, "Fedora") utilities.map_project( self.session, project=project_obj, - package_name='geany', - distribution='Fedora', - user_id='noreply@fedoraproject.org', + package_name="geany", + distribution="Fedora", + user_id="noreply@fedoraproject.org", old_package_name=None, ) self.session.commit() project_obj = models.Project.get(self.session, 1) packages = self.session.query(models.Packages).all() - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 1) self.assertEqual(len(packages), 1) - self.assertEqual(project_obj.packages[0].package_name, 'geany') - self.assertEqual(project_obj.packages[0].distro_name, 'Fedora') + self.assertEqual(project_obj.packages[0].package_name, "geany") + self.assertEqual(project_obj.packages[0].distro_name, "Fedora") def test_map_project_session_error_no_distro(self): """ Test SQLAlchemy session error """ create_project(self.session) project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 0) with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): # Without existing Distro object self.assertRaises( exceptions.AnityaException, utilities.map_project, self.session, project=project_obj, - package_name='geany', - distribution='Fedora', - user_id='noreply@fedoraproject.org', + package_name="geany", + distribution="Fedora", + user_id="noreply@fedoraproject.org", old_package_name=None, ) @@ -558,20 +540,21 @@ def test_map_project_session_error(self): create_distro(self.session) project_obj = models.Project.get(self.session, 1) - self.assertEqual(project_obj.name, 'geany') + self.assertEqual(project_obj.name, "geany") self.assertEqual(len(project_obj.packages), 0) with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): # With Distro object self.assertRaises( exceptions.AnityaException, utilities.map_project, self.session, project=project_obj, - package_name='geany', - distribution='Fedora', - user_id='noreply@fedoraproject.org', + package_name="geany", + distribution="Fedora", + user_id="noreply@fedoraproject.org", old_package_name=None, ) @@ -589,14 +572,14 @@ def test_flag_project(self): utilities.flag_project( self.session, project=project_obj, - reason='reason', - user_email='noreply@fedoraproject.org', - user_id='noreply@fedoraproject.org', + reason="reason", + user_email="noreply@fedoraproject.org", + user_id="noreply@fedoraproject.org", ) project_obj = models.Project.get(self.session, 1) self.assertEqual(len(project_obj.flags), 1) - self.assertEqual(project_obj.flags[0].reason, 'reason') + self.assertEqual(project_obj.flags[0].reason, "reason") def test_flag_project_session_error(self): """ Test SQLAlchemy session error """ @@ -605,15 +588,16 @@ def test_flag_project_session_error(self): project_obj = models.Project.get(self.session, 1) with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): self.assertRaises( exceptions.AnityaException, utilities.flag_project, self.session, project=project_obj, - reason='reason', - user_email='noreply@fedoraproject.org', - user_id='noreply@fedoraproject.org', + reason="reason", + user_email="noreply@fedoraproject.org", + user_id="noreply@fedoraproject.org", ) @@ -625,15 +609,12 @@ def test_set_flag_state(self): flag = create_flagged_project(self.session) utilities.set_flag_state( - self.session, - flag=flag, - state='closed', - user_id='noreply@fedoraproject.org', + self.session, flag=flag, state="closed", user_id="noreply@fedoraproject.org" ) project_obj = models.Project.get(self.session, 1) self.assertEqual(len(project_obj.flags), 1) - self.assertEqual(project_obj.flags[0].state, 'closed') + self.assertEqual(project_obj.flags[0].state, "closed") def test_set_flag_state_no_change(self): """ Test set state """ @@ -644,8 +625,8 @@ def test_set_flag_state_no_change(self): utilities.set_flag_state, self.session, flag=flag, - state='open', - user_id='noreply@fedoraproject.org', + state="open", + user_id="noreply@fedoraproject.org", ) def test_set_flag_project_session_error(self): @@ -653,432 +634,334 @@ def test_set_flag_project_session_error(self): flag = create_flagged_project(self.session) with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): self.assertRaises( exceptions.AnityaException, utilities.set_flag_state, self.session, flag=flag, - state='closed', - user_id='noreply@fedoraproject.org', + state="closed", + user_id="noreply@fedoraproject.org", ) class LogTests(DatabaseTestCase): """ Tests for `anitya.lib.utilities.log` function. """ - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_distro_add(self, mock_method): """ Assert that 'distro.add' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya added the distro named: Fedora" - message = { - 'agent': 'anitya', - 'distro': 'Fedora' - } + message = {"agent": "anitya", "distro": "Fedora"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='distro.add', message=message + self.session, + project=project, + distro=distro, + topic="distro.add", + message=message, ) mock_method.assert_called_with( - topic='distro.add', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="distro.add", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_distro_edit(self, mock_method): """ Assert that 'distro.edit' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya edited distro name from: Dummy to: Fedora" - message = { - 'agent': 'anitya', - 'old': 'Dummy', - 'new': 'Fedora' - } + message = {"agent": "anitya", "old": "Dummy", "new": "Fedora"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='distro.edit', message=message + self.session, + project=project, + distro=distro, + topic="distro.edit", + message=message, ) mock_method.assert_called_with( - topic='distro.edit', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="distro.edit", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_distro_remove(self, mock_method): """ Assert that 'distro.remove' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya deleted the distro named: Fedora" - message = { - 'agent': 'anitya', - 'distro': 'Fedora' - } + message = {"agent": "anitya", "distro": "Fedora"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='distro.remove', message=message + self.session, + project=project, + distro=distro, + topic="distro.remove", + message=message, ) mock_method.assert_called_with( - topic='distro.remove', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="distro.remove", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_add(self, mock_method): """ Assert that 'project.add' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya added project: test" - message = { - 'agent': 'anitya', - 'project': 'test' - } + message = {"agent": "anitya", "project": "test"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.add', message=message + self.session, + project=project, + distro=distro, + topic="project.add", + message=message, ) mock_method.assert_called_with( - topic='project.add', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.add", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_add_tried(self, mock_method): """ Assert that 'project.add.tried' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya tried to add an already existing project: test" - message = { - 'agent': 'anitya', - 'project': 'test' - } + message = {"agent": "anitya", "project": "test"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.add.tried', message=message + self.session, + project=project, + distro=distro, + topic="project.add.tried", + message=message, ) mock_method.assert_called_with( - topic='project.add.tried', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.add.tried", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_edit(self, mock_method): """ Assert that 'project.edit' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") message = { - 'agent': 'anitya', - 'project': 'test', - 'changes': { - 'name': { - 'old': 'dummy', - 'new': 'test' - } - } + "agent": "anitya", + "project": "test", + "changes": {"name": {"old": "dummy", "new": "test"}}, } - exp = "anitya edited the project: test fields: " \ - "{}".format(message['changes']) + exp = "anitya edited the project: test fields: " "{}".format(message["changes"]) final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.edit', message=message + self.session, + project=project, + distro=distro, + topic="project.edit", + message=message, ) mock_method.assert_called_with( - topic='project.edit', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.edit", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_flag(self, mock_method): """ Assert that 'project.flag' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya flagged the project: test with reason: reason" - message = { - 'agent': 'anitya', - 'project': 'test', - 'reason': 'reason' - } + message = {"agent": "anitya", "project": "test", "reason": "reason"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.flag', message=message + self.session, + project=project, + distro=distro, + topic="project.flag", + message=message, ) mock_method.assert_called_with( - topic='project.flag', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.flag", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_flag_set(self, mock_method): """ Assert that 'project.flag.set' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya set flag test to open" - message = { - 'agent': 'anitya', - 'flag': 'test', - 'state': 'open' - } + message = {"agent": "anitya", "flag": "test", "state": "open"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.flag.set', message=message + self.session, + project=project, + distro=distro, + topic="project.flag.set", + message=message, ) mock_method.assert_called_with( - topic='project.flag.set', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.flag.set", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_remove(self, mock_method): """ Assert that 'project.remove' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya removed the project: test" - message = { - 'agent': 'anitya', - 'project': 'test', - } + message = {"agent": "anitya", "project": "test"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.remove', message=message + self.session, + project=project, + distro=distro, + topic="project.remove", + message=message, ) mock_method.assert_called_with( - topic='project.remove', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.remove", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_map_new(self, mock_method): """ Assert that 'project.map.new' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya mapped the name of test in Fedora as test_package" message = { - 'agent': 'anitya', - 'project': 'test', - 'distro': 'Fedora', - 'new': 'test_package' + "agent": "anitya", + "project": "test", + "distro": "Fedora", + "new": "test_package", } final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.map.new', message=message + self.session, + project=project, + distro=distro, + topic="project.map.new", + message=message, ) mock_method.assert_called_with( - topic='project.map.new', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.map.new", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_map_update(self, mock_method): """ Assert that 'project.map.update' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) - exp = "anitya updated the name of test in Fedora from: test_old" \ - " to: test_new" + project = models.Project(name="test") + distro = models.Distro(name="Fedora") + exp = "anitya updated the name of test in Fedora from: test_old" " to: test_new" message = { - 'agent': 'anitya', - 'project': 'test', - 'distro': 'Fedora', - 'prev': 'test_old', - 'new': 'test_new' + "agent": "anitya", + "project": "test", + "distro": "Fedora", + "prev": "test_old", + "new": "test_new", } final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.map.update', message=message + self.session, + project=project, + distro=distro, + topic="project.map.update", + message=message, ) mock_method.assert_called_with( - topic='project.map.update', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.map.update", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_map_remove(self, mock_method): """ Assert that 'project.map.remove' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya removed the mapping of test in Fedora" - message = { - 'agent': 'anitya', - 'project': 'test', - 'distro': 'Fedora', - } + message = {"agent": "anitya", "project": "test", "distro": "Fedora"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.map.remove', message=message + self.session, + project=project, + distro=distro, + topic="project.map.remove", + message=message, ) mock_method.assert_called_with( - topic='project.map.remove', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.map.remove", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_version_remove(self, mock_method): """ Assert that 'project.version.remove' topic is handled correctly. """ - project = models.Project( - name='test' - ) - distro = models.Distro( - name='Fedora' - ) + project = models.Project(name="test") + distro = models.Distro(name="Fedora") exp = "anitya removed the version 1.0.0 of test" - message = { - 'agent': 'anitya', - 'project': 'test', - 'version': '1.0.0', - } + message = {"agent": "anitya", "project": "test", "version": "1.0.0"} final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.version.remove', message=message + self.session, + project=project, + distro=distro, + topic="project.version.remove", + message=message, ) mock_method.assert_called_with( - topic='project.version.remove', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.version.remove", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_log_project_version_update(self, mock_method): """ Assert that 'project.version.update' topic is handled correctly. """ - project = models.Project( - name='test' + project = models.Project(name="test") + distro = models.Distro(name="Fedora") + exp = ( + "new version: 1.0.0 found for project test " + "in ecosystem pypi (project id: 1)." ) - distro = models.Distro( - name='Fedora' - ) - exp = "new version: 1.0.0 found for project test " \ - "in ecosystem pypi (project id: 1)." message = { - 'agent': 'anitya', - 'upstream_version': '1.0.0', - 'ecosystem': 'pypi', - 'project': { - 'name': 'test', - 'id': '1' - } + "agent": "anitya", + "upstream_version": "1.0.0", + "ecosystem": "pypi", + "project": {"name": "test", "id": "1"}, } final_msg = utilities.log( - self.session, project=project, distro=distro, - topic='project.version.update', message=message + self.session, + project=project, + distro=distro, + topic="project.version.update", + message=message, ) mock_method.assert_called_with( - topic='project.version.update', msg=dict( - project=project, - distro=distro, - message=message - ) + topic="project.version.update", + msg=dict(project=project, distro=distro, message=message), ) self.assertEqual(final_msg, exp) diff --git a/anitya/tests/lib/versions/test_base.py b/anitya/tests/lib/versions/test_base.py index 71a751584..ac629e899 100644 --- a/anitya/tests/lib/versions/test_base.py +++ b/anitya/tests/lib/versions/test_base.py @@ -37,147 +37,153 @@ def test_identity_string(self): *must* write a migration to change the type column on existing versions. """ - self.assertEqual('Generic Version', base.Version.name) + self.assertEqual("Generic Version", base.Version.name) def test_str(self): """Assert __str__ calls parse""" - version = base.Version(version='v1.0.0') - self.assertEqual('1.0.0', str(version)) + version = base.Version(version="v1.0.0") + self.assertEqual("1.0.0", str(version)) def test_str_parse_error(self): """Assert __str__ calls parse""" - version = base.Version(version='v1.0.0') - version.parse = mock.Mock(side_effect=exceptions.InvalidVersion('boop')) - self.assertEqual('v1.0.0', str(version)) + version = base.Version(version="v1.0.0") + version.parse = mock.Mock(side_effect=exceptions.InvalidVersion("boop")) + self.assertEqual("v1.0.0", str(version)) def test_parse_no_v(self): """Assert parsing a version sans leading 'v' works.""" - version = base.Version(version='1.0.0') - self.assertEqual('1.0.0', version.parse()) + version = base.Version(version="1.0.0") + self.assertEqual("1.0.0", version.parse()) def test_parse_leading_v(self): """Assert parsing a version with a leading 'v' works.""" - version = base.Version(version='v1.0.0') - self.assertEqual('1.0.0', version.parse()) + version = base.Version(version="v1.0.0") + self.assertEqual("1.0.0", version.parse()) def test_parse_odd_version(self): """Assert parsing an odd version works.""" - version = base.Version(version='release_1_0_0') - self.assertEqual('release_1_0_0', version.parse()) + version = base.Version(version="release_1_0_0") + self.assertEqual("release_1_0_0", version.parse()) def test_parse_v_not_alone(self): """Assert leading 'v' isn't stripped if it's not followed by a number.""" - version = base.Version(version='version1.0.0') - self.assertEqual('version1.0.0', version.parse()) + version = base.Version(version="version1.0.0") + self.assertEqual("version1.0.0", version.parse()) def test_parse_with_prefix_no_v(self): - version = base.Version(version='release1.0.0', prefix='release') - self.assertEqual('1.0.0', version.parse()) + version = base.Version(version="release1.0.0", prefix="release") + self.assertEqual("1.0.0", version.parse()) def test_parse_with_prefix_with_v(self): - version = base.Version(version='release-v1.0.0', prefix='release-') - self.assertEqual('1.0.0', version.parse()) + version = base.Version(version="release-v1.0.0", prefix="release-") + self.assertEqual("1.0.0", version.parse()) def test_prerelease(self): """Assert prerelease is defined and returns False""" - version = base.Version(version='v1.0.0') + version = base.Version(version="v1.0.0") self.assertFalse(version.prerelease()) def test_postrelease(self): """Assert postrelease is defined and returns False""" - version = base.Version(version='v1.0.0') + version = base.Version(version="v1.0.0") self.assertFalse(version.postrelease()) def test_newer_single_version(self): """Assert newer is functional with a single instance of Version.""" - version = base.Version(version='v1.0.0') - newer_version = base.Version(version='v2.0.0') + version = base.Version(version="v1.0.0") + newer_version = base.Version(version="v2.0.0") self.assertFalse(version.newer(newer_version)) self.assertTrue(newer_version.newer(version)) def test_newer_multiple_versions(self): """Assert newer is functional with multiple instances of Version.""" - version = base.Version(version='v1.0.0') - version2 = base.Version(version='v1.1.0') - newer_version = base.Version(version='v2.0.0') + version = base.Version(version="v1.0.0") + version2 = base.Version(version="v1.1.0") + newer_version = base.Version(version="v2.0.0") self.assertFalse(version.newer(newer_version)) self.assertTrue(newer_version.newer([version, version2])) def test_newer_with_strings(self): """Assert newer handles string arguments.""" - version = base.Version(version='v1.0.0') - self.assertFalse(version.newer('v2.0.0')) + version = base.Version(version="v1.0.0") + self.assertFalse(version.newer("v2.0.0")) def test_lt(self): """Assert Version supports < comparison.""" - old_version = base.Version(version='v1.0.0') - new_version = base.Version(version='v1.1.0') + old_version = base.Version(version="v1.0.0") + new_version = base.Version(version="v1.1.0") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_one_unparsable(self): """Assert unparsable versions sort lower than parsable ones.""" - unparsable_version = base.Version(version='blarg') - unparsable_version.parse = mock.Mock(side_effect=exceptions.InvalidVersion('blarg')) - new_version = base.Version(version='v1.0.0') + unparsable_version = base.Version(version="blarg") + unparsable_version.parse = mock.Mock( + side_effect=exceptions.InvalidVersion("blarg") + ) + new_version = base.Version(version="v1.0.0") self.assertTrue(unparsable_version < new_version) self.assertFalse(new_version < unparsable_version) def test_lt_both_unparsable(self): """Assert unparsable versions resort to string sorting.""" - alphabetically_lower = base.Version(version='arg') - alphabetically_lower.parse = mock.Mock(side_effect=exceptions.InvalidVersion('arg')) - alphabetically_higher = base.Version(version='blarg') - alphabetically_higher.parse = mock.Mock(side_effect=exceptions.InvalidVersion('blarg')) + alphabetically_lower = base.Version(version="arg") + alphabetically_lower.parse = mock.Mock( + side_effect=exceptions.InvalidVersion("arg") + ) + alphabetically_higher = base.Version(version="blarg") + alphabetically_higher.parse = mock.Mock( + side_effect=exceptions.InvalidVersion("blarg") + ) self.assertTrue(alphabetically_lower < alphabetically_higher) def test_le(self): """Assert Version supports <= comparison.""" - old_version = base.Version(version='v1.0.0') - equally_old_version = base.Version(version='v1.0.0') - new_version = base.Version(version='v1.1.0') + old_version = base.Version(version="v1.0.0") + equally_old_version = base.Version(version="v1.0.0") + new_version = base.Version(version="v1.1.0") self.assertTrue(old_version <= new_version) self.assertTrue(old_version <= equally_old_version) self.assertFalse(new_version <= old_version) def test_gt(self): """Assert Version supports > comparison.""" - old_version = base.Version(version='v1.0.0') - new_version = base.Version(version='v1.1.0') + old_version = base.Version(version="v1.0.0") + new_version = base.Version(version="v1.1.0") self.assertTrue(new_version > old_version) self.assertFalse(old_version > new_version) def test_ge(self): """Assert Version supports >= comparison.""" - old_version = base.Version(version='v1.0.0') - equally_new_version = base.Version(version='v1.1.0') - new_version = base.Version(version='v1.1.0') + old_version = base.Version(version="v1.0.0") + equally_new_version = base.Version(version="v1.1.0") + new_version = base.Version(version="v1.1.0") self.assertFalse(old_version >= new_version) self.assertTrue(new_version >= equally_new_version) self.assertTrue(new_version >= old_version) def test_eq(self): """Assert Version supports == comparison.""" - v1 = base.Version(version='v1.0.0') - v2 = base.Version(version='v1.0.0') + v1 = base.Version(version="v1.0.0") + v2 = base.Version(version="v1.0.0") self.assertTrue(v1 == v2) def test_eq_one_with_v(self): """Assert Versions where one just has a v prefix are still equal""" - v1 = base.Version(version='1.0.0') - v2 = base.Version(version='v1.0.0') + v1 = base.Version(version="1.0.0") + v2 = base.Version(version="v1.0.0") self.assertTrue(v1 == v2) def test_eq_one_with_prefix(self): """Assert Versions where one just has a v prefix are still equal""" - v1 = base.Version(version='1.0.0') - v2 = base.Version(version='prefix1.0.0', prefix='prefix') + v1 = base.Version(version="1.0.0") + v2 = base.Version(version="prefix1.0.0", prefix="prefix") self.assertTrue(v1 == v2) def test_eq_both_unparsable(self): """Assert unparsable versions that are the same string are equal.""" - v1 = base.Version(version='arg') - v2 = base.Version(version='arg') - v1.parse = mock.Mock(side_effect=exceptions.InvalidVersion('arg')) - v2.parse = mock.Mock(side_effect=exceptions.InvalidVersion('arg')) + v1 = base.Version(version="arg") + v2 = base.Version(version="arg") + v1.parse = mock.Mock(side_effect=exceptions.InvalidVersion("arg")) + v2.parse = mock.Mock(side_effect=exceptions.InvalidVersion("arg")) self.assertEqual(v1, v2) diff --git a/anitya/tests/lib/versions/test_rpm.py b/anitya/tests/lib/versions/test_rpm.py index d6ecfc63c..2403a5f17 100644 --- a/anitya/tests/lib/versions/test_rpm.py +++ b/anitya/tests/lib/versions/test_rpm.py @@ -38,207 +38,207 @@ def test_identity_string(self): *must* write a migration to change the type column on existing projects. """ - self.assertEqual('RPM', rpm.RpmVersion.name) + self.assertEqual("RPM", rpm.RpmVersion.name) def test_split_rc_prerelease_tag(self): - result = rpm.RpmVersion.split_rc('1.8.23-alpha1') - self.assertEqual(('1.8.23', 'alpha', '1'), result) + result = rpm.RpmVersion.split_rc("1.8.23-alpha1") + self.assertEqual(("1.8.23", "alpha", "1"), result) def test_split_rc_no_prerelease_tag(self): - result = rpm.RpmVersion.split_rc('1.8.23') - self.assertEqual(('1.8.23', '', ''), result) + result = rpm.RpmVersion.split_rc("1.8.23") + self.assertEqual(("1.8.23", "", ""), result) def test_str(self): """Assert __str__ calls parse""" - version = rpm.RpmVersion(version='v1.0.0') - self.assertEqual('1.0.0', str(version)) + version = rpm.RpmVersion(version="v1.0.0") + self.assertEqual("1.0.0", str(version)) def test_str_parse_error(self): """Assert __str__ calls parse""" - version = rpm.RpmVersion(version='v1.0.0') - version.parse = mock.Mock(side_effect=exceptions.InvalidVersion('boop')) - self.assertEqual('v1.0.0', str(version)) + version = rpm.RpmVersion(version="v1.0.0") + version.parse = mock.Mock(side_effect=exceptions.InvalidVersion("boop")) + self.assertEqual("v1.0.0", str(version)) def test_parse_no_v(self): """Assert parsing a version sans leading 'v' works.""" - version = rpm.RpmVersion(version='1.0.0') - self.assertEqual('1.0.0', version.parse()) + version = rpm.RpmVersion(version="1.0.0") + self.assertEqual("1.0.0", version.parse()) def test_parse_leading_v(self): """Assert parsing a version with a leading 'v' works.""" - version = rpm.RpmVersion(version='v1.0.0') - self.assertEqual('1.0.0', version.parse()) + version = rpm.RpmVersion(version="v1.0.0") + self.assertEqual("1.0.0", version.parse()) def test_parse_odd_version(self): """Assert parsing an odd version works.""" - version = rpm.RpmVersion(version='release_1_0_0') - self.assertEqual('release_1_0_0', version.parse()) + version = rpm.RpmVersion(version="release_1_0_0") + self.assertEqual("release_1_0_0", version.parse()) def test_parse_v_not_alone(self): """Assert leading 'v' isn't stripped if it's not followed by a number.""" - version = rpm.RpmVersion(version='version1.0.0') - self.assertEqual('version1.0.0', version.parse()) + version = rpm.RpmVersion(version="version1.0.0") + self.assertEqual("version1.0.0", version.parse()) def test_prerelease_false(self): """Assert prerelease is defined and returns False with non-prerelease versions.""" - version = rpm.RpmVersion(version='v1.0.0') + version = rpm.RpmVersion(version="v1.0.0") self.assertFalse(version.prerelease()) def test_prerelease_prerelease_no_number(self): """Assert pre-releases without a number are still valid pre-releases.""" - for suffix in ('rc', 'alpha', 'beta', 'dev', 'pre'): - version = rpm.RpmVersion(version='v1.0.0' + suffix) + for suffix in ("rc", "alpha", "beta", "dev", "pre"): + version = rpm.RpmVersion(version="v1.0.0" + suffix) self.assertTrue(version.prerelease()) def test_prerelease_with_number(self): """Assert versions with RC are prerelease versions.""" - for suffix in ('rc1', 'alpha2', 'beta10', 'dev3', 'pre999'): - version = rpm.RpmVersion(version='v1.0.0' + suffix) + for suffix in ("rc1", "alpha2", "beta10", "dev3", "pre999"): + version = rpm.RpmVersion(version="v1.0.0" + suffix) self.assertTrue(version.prerelease()) def test_prerelease_nonsense(self): """Assert versions with junk following the version aren't prerelease versions.""" - version = rpm.RpmVersion(version='v1.0.0junk1') + version = rpm.RpmVersion(version="v1.0.0junk1") self.assertFalse(version.prerelease()) def test_postrelease_false(self): """Assert postrelease is defined and returns False for non-postreleases.""" - version = rpm.RpmVersion(version='v1.0.0') + version = rpm.RpmVersion(version="v1.0.0") self.assertFalse(version.postrelease()) def test_postrelease(self): """Assert postrelease is currently unsupported.""" - version = rpm.RpmVersion(version='v1.0.0post1') + version = rpm.RpmVersion(version="v1.0.0post1") self.assertFalse(version.postrelease()) def test_newer(self): """Assert newer is functional.""" - version = rpm.RpmVersion(version='v1.0.0') - newer_version = rpm.RpmVersion(version='v2.0.0') + version = rpm.RpmVersion(version="v1.0.0") + newer_version = rpm.RpmVersion(version="v2.0.0") self.assertFalse(version.newer(newer_version)) self.assertTrue(newer_version.newer(version)) def test_newer_with_strings(self): """Assert newer handles string arguments,""" - version = rpm.RpmVersion(version='v1.0.0') - self.assertFalse(version.newer('v2.0.0')) + version = rpm.RpmVersion(version="v1.0.0") + self.assertFalse(version.newer("v2.0.0")) def test_newer_numerical(self): """Assert newer is functional.""" - version = rpm.RpmVersion(version='v1.1.0') - newer_version = rpm.RpmVersion(version='v1.11.0') + version = rpm.RpmVersion(version="v1.1.0") + newer_version = rpm.RpmVersion(version="v1.11.0") self.assertFalse(version.newer(newer_version)) self.assertTrue(newer_version.newer(version)) def test_lt(self): """Assert RpmVersion supports < comparison.""" - old_version = rpm.RpmVersion(version='v1.0.0') - new_version = rpm.RpmVersion(version='v1.1.0') + old_version = rpm.RpmVersion(version="v1.0.0") + new_version = rpm.RpmVersion(version="v1.1.0") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_one_release_field(self): """Assert versions with release fields are greater than those that don't have them.""" - old_version = rpm.RpmVersion(version='v1.0.0') - new_version = rpm.RpmVersion(version='v1.0.0-1.fc26') + old_version = rpm.RpmVersion(version="v1.0.0") + new_version = rpm.RpmVersion(version="v1.0.0-1.fc26") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_two_release_fields(self): """Assert release fields are compared.""" - old_version = rpm.RpmVersion(version='v1.0.0-1.fc26') - new_version = rpm.RpmVersion(version='v1.0.0-11.fc26') + old_version = rpm.RpmVersion(version="v1.0.0-1.fc26") + new_version = rpm.RpmVersion(version="v1.0.0-11.fc26") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_rc_vs_pre(self): """Assert rc prereleases are greater than pre prereleases of the same version.""" - old_version = rpm.RpmVersion(version='1.0.0pre2') - new_version = rpm.RpmVersion(version='1.0.0rc1') + old_version = rpm.RpmVersion(version="1.0.0pre2") + new_version = rpm.RpmVersion(version="1.0.0rc1") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_pre_vs_beta(self): """Assert pre prereleases are greater than beta prereleases of the same version.""" - old_version = rpm.RpmVersion(version='1.0.0pre2') - new_version = rpm.RpmVersion(version='1.0.0rc1') + old_version = rpm.RpmVersion(version="1.0.0pre2") + new_version = rpm.RpmVersion(version="1.0.0rc1") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_beta_vs_alpha(self): """Assert beta prereleases are greater than alpha prereleases of the same version.""" - old_version = rpm.RpmVersion(version='1.0.0alpha2') - new_version = rpm.RpmVersion(version='1.0.0beta1') + old_version = rpm.RpmVersion(version="1.0.0alpha2") + new_version = rpm.RpmVersion(version="1.0.0beta1") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_beta_vs_newer_alpha(self): """Assert alpha prereleases of newer versions are larger than older betas.""" - old_version = rpm.RpmVersion(version='1.0.0beta1') - new_version = rpm.RpmVersion(version='1.0.1alpha2') + old_version = rpm.RpmVersion(version="1.0.0beta1") + new_version = rpm.RpmVersion(version="1.0.1alpha2") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_one_prerelease(self): """Assert prereleases are less than non-prereleases.""" - old_version = rpm.RpmVersion(version='v1.1.0rc1') - new_version = rpm.RpmVersion(version='v1.1.0') + old_version = rpm.RpmVersion(version="v1.1.0rc1") + new_version = rpm.RpmVersion(version="v1.1.0") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_both_prerelease(self): """Assert prereleases sort numerically.""" - old_version = rpm.RpmVersion(version='v1.1.0rc1') - new_version = rpm.RpmVersion(version='v1.1.0rc11') + old_version = rpm.RpmVersion(version="v1.1.0rc1") + new_version = rpm.RpmVersion(version="v1.1.0rc11") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_lt_both_prerelease_one_unversioned(self): """Assert unversioned prereleases are less than versioned ones.""" - old_version = rpm.RpmVersion(version='v1.1.0rc') - new_version = rpm.RpmVersion(version='v1.1.0rc1') + old_version = rpm.RpmVersion(version="v1.1.0rc") + new_version = rpm.RpmVersion(version="v1.1.0rc1") self.assertTrue(old_version < new_version) self.assertFalse(new_version < old_version) def test_le(self): """Assert RpmVersion supports <= comparison.""" - old_version = rpm.RpmVersion(version='v1.0.0') - equally_old_version = rpm.RpmVersion(version='v1.0.0') - new_version = rpm.RpmVersion(version='v1.1.0') + old_version = rpm.RpmVersion(version="v1.0.0") + equally_old_version = rpm.RpmVersion(version="v1.0.0") + new_version = rpm.RpmVersion(version="v1.1.0") self.assertTrue(old_version <= new_version) self.assertTrue(old_version <= equally_old_version) self.assertFalse(new_version <= old_version) def test_gt(self): """Assert RpmVersion supports > comparison.""" - old_version = rpm.RpmVersion(version='v1.0.0') - new_version = rpm.RpmVersion(version='v1.1.0') + old_version = rpm.RpmVersion(version="v1.0.0") + new_version = rpm.RpmVersion(version="v1.1.0") self.assertTrue(new_version > old_version) self.assertFalse(old_version > new_version) def test_ge(self): """Assert RpmVersion supports >= comparison.""" - old_version = rpm.RpmVersion(version='v1.0.0') - equally_new_version = rpm.RpmVersion(version='v1.1.0') - new_version = rpm.RpmVersion(version='v1.1.0') + old_version = rpm.RpmVersion(version="v1.0.0") + equally_new_version = rpm.RpmVersion(version="v1.1.0") + new_version = rpm.RpmVersion(version="v1.1.0") self.assertFalse(old_version >= new_version) self.assertTrue(new_version >= equally_new_version) self.assertTrue(new_version >= old_version) def test_eq(self): """Assert RpmVersion supports == comparison.""" - old_version = rpm.RpmVersion(version='v1.0.0') - new_version = rpm.RpmVersion(version='v1.0.0') + old_version = rpm.RpmVersion(version="v1.0.0") + new_version = rpm.RpmVersion(version="v1.0.0") self.assertTrue(new_version == old_version) def test_eq_both_unnumbered_prereleases(self): """Assert two prereleases of the same type without versions are equal.""" - old_version = rpm.RpmVersion(version='1.0.0beta') - new_version = rpm.RpmVersion(version='1.0.0beta') + old_version = rpm.RpmVersion(version="1.0.0beta") + new_version = rpm.RpmVersion(version="1.0.0beta") self.assertTrue(new_version == old_version) def test_eq_one_v_prefix(self): """Assert versions that are the same except one has a v prefix are equal.""" - old_version = rpm.RpmVersion(version='v1.0.0-1.fc26') - new_version = rpm.RpmVersion(version='1.0.0-1.fc26') + old_version = rpm.RpmVersion(version="v1.0.0-1.fc26") + new_version = rpm.RpmVersion(version="1.0.0-1.fc26") self.assertTrue(new_version == old_version) diff --git a/anitya/tests/test_alembic.py b/anitya/tests/test_alembic.py index 6ab7d14bf..f6bfb9f9c 100644 --- a/anitya/tests/test_alembic.py +++ b/anitya/tests/test_alembic.py @@ -22,8 +22,7 @@ import unittest -REPO_PATH = os.path.abspath( - os.path.join(os.path.dirname(__file__), '..', '..')) +REPO_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) class TestAlembic(unittest.TestCase): @@ -36,13 +35,13 @@ def test_alembic_history(self): and ensure it returns only one line. """ proc1 = subprocess.Popen( - ['alembic', 'history'], - cwd=REPO_PATH, stdout=subprocess.PIPE) + ["alembic", "history"], cwd=REPO_PATH, stdout=subprocess.PIPE + ) proc2 = subprocess.Popen( - ['grep', ' (head), '], - stdin=proc1.stdout, stdout=subprocess.PIPE) + ["grep", " (head), "], stdin=proc1.stdout, stdout=subprocess.PIPE + ) stdout = proc2.communicate()[0] - stdout = stdout.strip().split(b'\n') + stdout = stdout.strip().split(b"\n") self.assertEqual(len(stdout), 1) proc1.communicate() diff --git a/anitya/tests/test_app.py b/anitya/tests/test_app.py index f5dd98d60..696f3eafc 100644 --- a/anitya/tests/test_app.py +++ b/anitya/tests/test_app.py @@ -48,20 +48,20 @@ def test_default_config(self): def test_email_config(self): """Assert a SMTPHandler is added to the anitya logger when ``EMAIL_ERRORS=True``.""" config = { - 'DB_URL': 'sqlite://', - 'SOCIAL_AUTH_USER_MODEL': 'anitya.db.models.User', - 'EMAIL_ERRORS': True, - 'SMTP_SERVER': 'smtp.example.com', - 'ADMIN_EMAIL': 'admin@example.com', + "DB_URL": "sqlite://", + "SOCIAL_AUTH_USER_MODEL": "anitya.db.models.User", + "EMAIL_ERRORS": True, + "SMTP_SERVER": "smtp.example.com", + "ADMIN_EMAIL": "admin@example.com", } - anitya_logger = logging.getLogger('anitya') + anitya_logger = logging.getLogger("anitya") anitya_logger.handlers = [] app.create(config) self.assertEqual(1, len(anitya_logger.handlers)) - self.assertEqual('smtp.example.com', anitya_logger.handlers[0].mailhost) - self.assertEqual(['admin@example.com'], anitya_logger.handlers[0].toaddrs) + self.assertEqual("smtp.example.com", anitya_logger.handlers[0].mailhost) + self.assertEqual(["admin@example.com"], anitya_logger.handlers[0].toaddrs) def test_db_config(self): """Assert creating the application configures the scoped session.""" @@ -69,42 +69,43 @@ def test_db_config(self): self.assertRaises(UnboundExecutionError, Session.get_bind) Session.remove() - app.create({ - 'DB_URL': 'sqlite://', - 'SOCIAL_AUTH_USER_MODEL': 'anitya.db.models.User', - }) - self.assertEqual('sqlite://', str(Session().get_bind().url)) + app.create( + {"DB_URL": "sqlite://", "SOCIAL_AUTH_USER_MODEL": "anitya.db.models.User"} + ) + self.assertEqual("sqlite://", str(Session().get_bind().url)) class IntegrityErrorHandlerTests(base.DatabaseTestCase): - def setUp(self): super(IntegrityErrorHandlerTests, self).setUp() session = Session() - self.user = models.User(email='user@example.com', username='user') + self.user = models.User(email="user@example.com", username="user") session.add(self.user) session.commit() def test_not_email(self): """Assert an IntegrityError without the email key results in a 500 error""" - err = IntegrityError('SQL Statement', {}, None) + err = IntegrityError("SQL Statement", {}, None) msg, errno = app.integrity_error_handler(err) self.assertEqual(500, errno) - self.assertEqual('The server encountered an unexpected error', msg) + self.assertEqual("The server encountered an unexpected error", msg) def test_email(self): """Assert an HTTP 400 is generated from an email IntegrityError.""" social_auth_user = social_models.UserSocialAuth( - provider='Demo Provider', user=self.user) + provider="Demo Provider", user=self.user + ) self.session.add(social_auth_user) self.session.commit() - err = IntegrityError('SQL Statement', {'email': 'user@example.com'}, None) - expected_msg = ("Error: There's already an account associated with your email, " - "authenticate with Demo Provider.") + err = IntegrityError("SQL Statement", {"email": "user@example.com"}, None) + expected_msg = ( + "Error: There's already an account associated with your email, " + "authenticate with Demo Provider." + ) msg, errno = app.integrity_error_handler(err) @@ -114,11 +115,12 @@ def test_email(self): def test_no_social_auth(self): """Assert an HTTP 500 is generated from an social_auth IntegrityError.""" - err = IntegrityError('SQL Statement', { - 'email': 'user@example.com'}, None) - expected_msg = ("Error: There was already an existing account with missing provider. " - "So we removed it. " - "Please try to log in again.") + err = IntegrityError("SQL Statement", {"email": "user@example.com"}, None) + expected_msg = ( + "Error: There was already an existing account with missing provider. " + "So we removed it. " + "Please try to log in again." + ) msg, errno = app.integrity_error_handler(err) @@ -127,15 +129,16 @@ def test_no_social_auth(self): class AuthExceptionHandlerTests(base.DatabaseTestCase): - def setUp(self): super(AuthExceptionHandlerTests, self).setUp() def test_exception_handling(self): """Assert an AuthException results in a 400 error""" - err = AuthException('openid', 'Auth error') - exp_msg = ("Error: There was an error during authentication 'Auth error', " - "please check the provided url.") + err = AuthException("openid", "Auth error") + exp_msg = ( + "Error: There was an error during authentication 'Auth error', " + "please check the provided url." + ) msg, errno = app.auth_error_handler(err) @@ -148,13 +151,10 @@ class WhenUserLogInTests(base.DatabaseTestCase): def test_without_error(self): """Assert that nothing happens if social_auth info is available.""" - user = models.User( - email='user@example.com', - username='user' - ) + user = models.User(email="user@example.com", username="user") social_auth_user = social_models.UserSocialAuth( - provider='Demo Provider', - user=user) + provider="Demo Provider", user=user + ) self.session.add(social_auth_user) self.session.add(user) self.session.commit() @@ -164,16 +164,8 @@ def test_without_error(self): def test_social_auth_missing(self): """Assert that exception is thrown when social_auth info is missing.""" - user = models.User( - email='user@example.com', - username='user' - ) + user = models.User(email="user@example.com", username="user") self.session.add(user) self.session.commit() - self.assertRaises( - IntegrityError, - app.when_user_log_in, - app, - user - ) + self.assertRaises(IntegrityError, app.when_user_log_in, app, user) diff --git a/anitya/tests/test_authentication.py b/anitya/tests/test_authentication.py index fb4064700..940099d8d 100644 --- a/anitya/tests/test_authentication.py +++ b/anitya/tests/test_authentication.py @@ -37,13 +37,9 @@ def setUp(self): super(LoadUserFromRequestTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -56,14 +52,14 @@ def setUp(self): def test_success(self): """Assert that users can authenticate via the 'Authorization' header.""" mock_request = mock.Mock() - mock_request.headers = {'Authorization': 'token ' + self.api_token.token} + mock_request.headers = {"Authorization": "token " + self.api_token.token} user = authentication.load_user_from_request(mock_request) self.assertEqual(self.user, user) def test_no_token_in_db(self): """Assert that an invalid token results in a User of ``None``.""" mock_request = mock.Mock() - mock_request.headers = {'Authorization': 'token ' 'myinvalidtoken'} + mock_request.headers = {"Authorization": "token " "myinvalidtoken"} self.assertEqual(None, authentication.load_user_from_request(mock_request)) def test_no_header(self): @@ -74,8 +70,8 @@ def test_no_header(self): def test_unkown_auth_type(self): """Assert that unknown authentication types are rejected.""" - mock_request = mock.Mock(spec='werkzeug.wrappers.Request') - mock_request.headers = {'Authorization': 'Basic ' + self.api_token.token} + mock_request = mock.Mock(spec="werkzeug.wrappers.Request") + mock_request.headers = {"Authorization": "Basic " + self.api_token.token} self.assertEqual(None, authentication.load_user_from_request(mock_request)) @@ -86,13 +82,9 @@ def setUp(self): super(LoadUserFromSessionTests, self).setUp() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -111,7 +103,7 @@ def test_missing_user(self): def test_incorrect_type(self): """Assert ``None`` is returned when the user ID isn't a UUID.""" - loaded_user = authentication.load_user_from_session('Not a UUID') + loaded_user = authentication.load_user_from_session("Not a UUID") self.assertTrue(loaded_user is None) @@ -122,13 +114,9 @@ def setUp(self): super(RequireTokenTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -137,29 +125,29 @@ def setUp(self): session.add(self.api_token) session.commit() - @mock.patch('flask_login.current_user') + @mock.patch("flask_login.current_user") def test_unauthenticated(self, mock_current_user): """Assert decorated functions return HTTP 401 when no user is logged in.""" mock_current_user.is_authenticated = False error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - expected_response = (error_details, 401, {'WWW-Authenticate': 'Token'}) + expected_response = (error_details, 401, {"WWW-Authenticate": "Token"}) @authentication.require_token def test_func(): - return 'This should not happen!' + return "This should not happen!" self.assertEqual(expected_response, test_func()) - @mock.patch('flask_login.current_user') + @mock.patch("flask_login.current_user") def test_authenticated(self, mock_current_user): """Assert decorated functions return the function's result when a user is logged in.""" mock_current_user.is_authenticated = True @authentication.require_token def test_func(): - return 'Carry on!' + return "Carry on!" - self.assertEqual('Carry on!', test_func()) + self.assertEqual("Carry on!", test_func()) diff --git a/anitya/tests/test_config.py b/anitya/tests/test_config.py index c42f97f25..e035baeb5 100644 --- a/anitya/tests/test_config.py +++ b/anitya/tests/test_config.py @@ -90,139 +90,142 @@ class LoadTests(unittest.TestCase): maxDiff = None - @mock.patch('anitya.config.open', mock.mock_open(read_data='Ni!')) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=True) + @mock.patch("anitya.config.open", mock.mock_open(read_data="Ni!")) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=True) def test_bad_config_file(self, mock_exists, mock_log): config = anitya_config.load() self.assertEqual(anitya_config.DEFAULTS, config) - mock_exists.assert_called_once_with('/etc/anitya/anitya.toml') + mock_exists.assert_called_once_with("/etc/anitya/anitya.toml") mock_log.info.assert_called_once_with( - 'Loading Anitya configuration from /etc/anitya/anitya.toml') - error = 'Failed to parse /etc/anitya/anitya.toml: (1, 1): msg' + "Loading Anitya configuration from /etc/anitya/anitya.toml" + ) + error = "Failed to parse /etc/anitya/anitya.toml: (1, 1): msg" self.assertEqual(error, mock_log.error.call_args_list[0][0][0]) - @mock.patch('anitya.config.open', mock.mock_open(read_data=partial_config)) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=True) + @mock.patch("anitya.config.open", mock.mock_open(read_data=partial_config)) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=True) def test_partial_config_file(self, mock_exists, mock_log): config = anitya_config.load() - self.assertNotEqual('muchsecretverysafe', anitya_config.DEFAULTS['SECRET_KEY']) - self.assertEqual('muchsecretverysafe', config['SECRET_KEY']) - mock_exists.assert_called_once_with('/etc/anitya/anitya.toml') + self.assertNotEqual("muchsecretverysafe", anitya_config.DEFAULTS["SECRET_KEY"]) + self.assertEqual("muchsecretverysafe", config["SECRET_KEY"]) + mock_exists.assert_called_once_with("/etc/anitya/anitya.toml") mock_log.info.assert_called_once_with( - 'Loading Anitya configuration from /etc/anitya/anitya.toml') + "Loading Anitya configuration from /etc/anitya/anitya.toml" + ) self.assertEqual(0, mock_log.warning.call_count) - @mock.patch('anitya.config.open', mock.mock_open(read_data=full_config)) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=True) + @mock.patch("anitya.config.open", mock.mock_open(read_data=full_config)) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=True) def test_full_config_file(self, mock_exists, mock_log): expected_config = { - 'SECRET_KEY': 'very_secret', - 'PERMANENT_SESSION_LIFETIME': timedelta(seconds=3600), - 'DB_URL': 'sqlite:////var/tmp/anitya-dev.sqlite', - 'ANITYA_WEB_ADMINS': ['http://pingou.id.fedoraproject.org'], - 'ADMIN_EMAIL': 'admin@fedoraproject.org', - 'ANITYA_LOG_CONFIG': { - 'version': 1, - 'disable_existing_loggers': True, - 'formatters': { - 'simple': { - 'format': '[%(name)s %(levelname)s] %(message)s', - }, + "SECRET_KEY": "very_secret", + "PERMANENT_SESSION_LIFETIME": timedelta(seconds=3600), + "DB_URL": "sqlite:////var/tmp/anitya-dev.sqlite", + "ANITYA_WEB_ADMINS": ["http://pingou.id.fedoraproject.org"], + "ADMIN_EMAIL": "admin@fedoraproject.org", + "ANITYA_LOG_CONFIG": { + "version": 1, + "disable_existing_loggers": True, + "formatters": { + "simple": {"format": "[%(name)s %(levelname)s] %(message)s"} }, - 'handlers': { - 'console': { - 'class': 'logging.StreamHandler', - 'formatter': 'simple', - 'stream': 'ext://sys.stdout', + "handlers": { + "console": { + "class": "logging.StreamHandler", + "formatter": "simple", + "stream": "ext://sys.stdout", } }, - 'loggers': { - 'anitya': { - 'level': 'WARNING', - 'propagate': False, - 'handlers': ['console'], - }, - }, - 'root': { - 'level': 'ERROR', - 'handlers': ['console'], + "loggers": { + "anitya": { + "level": "WARNING", + "propagate": False, + "handlers": ["console"], + } }, + "root": {"level": "ERROR", "handlers": ["console"]}, }, - 'SMTP_SERVER': 'smtp.example.com', - 'EMAIL_ERRORS': False, - 'BLACKLISTED_USERS': ['http://sometroublemaker.id.fedoraproject.org'], - 'SESSION_PROTECTION': 'strong', - 'SOCIAL_AUTH_AUTHENTICATION_BACKENDS': [ - 'social_core.backends.fedora.FedoraOpenId', - 'social_core.backends.yahoo.YahooOpenId', - 'social_core.backends.open_id.OpenIdAuth', - 'social_core.backends.google_openidconnect.GoogleOpenIdConnect', - 'social_core.backends.github.GithubOAuth2', + "SMTP_SERVER": "smtp.example.com", + "EMAIL_ERRORS": False, + "BLACKLISTED_USERS": ["http://sometroublemaker.id.fedoraproject.org"], + "SESSION_PROTECTION": "strong", + "SOCIAL_AUTH_AUTHENTICATION_BACKENDS": [ + "social_core.backends.fedora.FedoraOpenId", + "social_core.backends.yahoo.YahooOpenId", + "social_core.backends.open_id.OpenIdAuth", + "social_core.backends.google_openidconnect.GoogleOpenIdConnect", + "social_core.backends.github.GithubOAuth2", ], - 'SOCIAL_AUTH_STORAGE': 'social_flask_sqlalchemy.models.FlaskStorage', - 'SOCIAL_AUTH_USER_MODEL': 'anitya.db.models.User', + "SOCIAL_AUTH_STORAGE": "social_flask_sqlalchemy.models.FlaskStorage", + "SOCIAL_AUTH_USER_MODEL": "anitya.db.models.User", # Force the application to require HTTPS on authentication redirects. - 'SOCIAL_AUTH_REDIRECT_IS_HTTPS': True, - 'SOCIAL_AUTH_LOGIN_URL': '/login/', - 'SOCIAL_AUTH_LOGIN_REDIRECT_URL': '/', - 'SOCIAL_AUTH_LOGIN_ERROR_URL': '/login-error/', - 'LIBRARIESIO_PLATFORM_WHITELIST': ['pypi', 'rubygems'], - 'DEFAULT_REGEX': 'a*b*', - 'GITHUB_ACCESS_TOKEN': 'foobar', - 'LEGACY_MESSAGING': True, + "SOCIAL_AUTH_REDIRECT_IS_HTTPS": True, + "SOCIAL_AUTH_LOGIN_URL": "/login/", + "SOCIAL_AUTH_LOGIN_REDIRECT_URL": "/", + "SOCIAL_AUTH_LOGIN_ERROR_URL": "/login-error/", + "LIBRARIESIO_PLATFORM_WHITELIST": ["pypi", "rubygems"], + "DEFAULT_REGEX": "a*b*", + "GITHUB_ACCESS_TOKEN": "foobar", + "LEGACY_MESSAGING": True, } config = anitya_config.load() self.assertEqual(sorted(expected_config.keys()), sorted(config.keys())) for key in expected_config: self.assertEqual(expected_config[key], config[key]) - mock_exists.assert_called_once_with('/etc/anitya/anitya.toml') + mock_exists.assert_called_once_with("/etc/anitya/anitya.toml") mock_log.info.assert_called_once_with( - 'Loading Anitya configuration from /etc/anitya/anitya.toml') + "Loading Anitya configuration from /etc/anitya/anitya.toml" + ) self.assertEqual(0, mock_log.warning.call_count) - @mock.patch('anitya.config.open', mock.mock_open(read_data=partial_config)) - @mock.patch.dict('anitya.config.os.environ', {'ANITYA_WEB_CONFIG': '/my/config'}) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=True) + @mock.patch("anitya.config.open", mock.mock_open(read_data=partial_config)) + @mock.patch.dict("anitya.config.os.environ", {"ANITYA_WEB_CONFIG": "/my/config"}) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=True) def test_custom_config_file(self, mock_exists, mock_log): config = anitya_config.load() - self.assertNotEqual('muchsecretverysafe', anitya_config.DEFAULTS['SECRET_KEY']) - self.assertEqual('muchsecretverysafe', config['SECRET_KEY']) - mock_exists.assert_called_once_with('/my/config') + self.assertNotEqual("muchsecretverysafe", anitya_config.DEFAULTS["SECRET_KEY"]) + self.assertEqual("muchsecretverysafe", config["SECRET_KEY"]) + mock_exists.assert_called_once_with("/my/config") mock_log.info.assert_called_once_with( - 'Loading Anitya configuration from /my/config') + "Loading Anitya configuration from /my/config" + ) self.assertEqual(0, mock_log.warning.call_count) - @mock.patch('anitya.config.open', mock.mock_open(read_data=empty_config)) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=True) + @mock.patch("anitya.config.open", mock.mock_open(read_data=empty_config)) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=True) def test_empty_config_file(self, mock_exists, mock_log): """Assert loading the config with an empty file that exists works.""" config = anitya_config.load() self.assertEqual(anitya_config.DEFAULTS, config) - mock_exists.assert_called_once_with('/etc/anitya/anitya.toml') + mock_exists.assert_called_once_with("/etc/anitya/anitya.toml") mock_log.info.assert_called_once_with( - 'Loading Anitya configuration from /etc/anitya/anitya.toml') + "Loading Anitya configuration from /etc/anitya/anitya.toml" + ) mock_log.warning.assert_called_once_with( - 'SECRET_KEY is not configured, falling back to the default. ' - 'This is NOT safe for production deployments!') + "SECRET_KEY is not configured, falling back to the default. " + "This is NOT safe for production deployments!" + ) - @mock.patch('anitya.config._log', autospec=True) - @mock.patch('anitya.config.os.path.exists', return_value=False) + @mock.patch("anitya.config._log", autospec=True) + @mock.patch("anitya.config.os.path.exists", return_value=False) def test_missing_config_file(self, mock_exists, mock_log): """Assert loading the config with a missing file works.""" config = anitya_config.load() self.assertEqual(anitya_config.DEFAULTS, config) - mock_exists.assert_called_once_with('/etc/anitya/anitya.toml') + mock_exists.assert_called_once_with("/etc/anitya/anitya.toml") mock_log.info.assert_called_once_with( - 'The Anitya configuration file, /etc/anitya/anitya.toml, does not exist.') + "The Anitya configuration file, /etc/anitya/anitya.toml, does not exist." + ) mock_log.warning.assert_called_once_with( - 'SECRET_KEY is not configured, falling back to the default. ' - 'This is NOT safe for production deployments!') + "SECRET_KEY is not configured, falling back to the default. " + "This is NOT safe for production deployments!" + ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/anitya/tests/test_distro.py b/anitya/tests/test_distro.py index 409dac3a6..b176ac5b9 100644 --- a/anitya/tests/test_distro.py +++ b/anitya/tests/test_distro.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the Distro object. -''' +""" import unittest @@ -38,24 +38,24 @@ def test_init_distro(self): self.assertEqual(2, models.Distro.all(self.session, count=True)) distros = models.Distro.all(self.session) - self.assertEqual(distros[0].name, 'Debian') - self.assertEqual(distros[1].name, 'Fedora') + self.assertEqual(distros[0].name, "Debian") + self.assertEqual(distros[1].name, "Fedora") def test_distro_by_name(self): """ Test the by_name function of Distro. """ create_distro(self.session) - distro = models.Distro.by_name(self.session, 'fedora') - self.assertEqual(distro.name, 'Fedora') + distro = models.Distro.by_name(self.session, "fedora") + self.assertEqual(distro.name, "Fedora") - distro = models.Distro.get(self.session, 'fedora') - self.assertEqual(distro.name, 'Fedora') + distro = models.Distro.get(self.session, "fedora") + self.assertEqual(distro.name, "Fedora") - distro = models.Distro.by_name(self.session, 'DEBIAN') - self.assertEqual(distro.name, 'Debian') + distro = models.Distro.by_name(self.session, "DEBIAN") + self.assertEqual(distro.name, "Debian") - distro = models.Distro.get(self.session, 'DEBIAN') - self.assertEqual(distro.name, 'Debian') + distro = models.Distro.get(self.session, "DEBIAN") + self.assertEqual(distro.name, "Debian") def test_distro_all(self): """ Test the all function of Distro. """ @@ -64,7 +64,7 @@ def test_distro_all(self): distro = models.Distro.all(self.session, page=2) self.assertEqual(distro, []) - distro = models.Distro.all(self.session, page='b') + distro = models.Distro.all(self.session, page="b") distro2 = models.Distro.all(self.session) self.assertEqual(distro, distro2) @@ -72,34 +72,34 @@ def test_distro_json(self): """ Test the __json__ function of Distro. """ create_distro(self.session) - distro = models.Distro.by_name(self.session, 'fedora') - self.assertEqual(distro.__json__(), {'name': 'Fedora'}) + distro = models.Distro.by_name(self.session, "fedora") + self.assertEqual(distro.__json__(), {"name": "Fedora"}) def test_distro_search(self): """ Test the search function of Distro. """ create_distro(self.session) - distro = models.Distro.search(self.session, 'fed') + distro = models.Distro.search(self.session, "fed") self.assertEqual(distro, []) - distro = models.Distro.search(self.session, 'fed*') + distro = models.Distro.search(self.session, "fed*") self.assertNotEqual(distro, []) - self.assertEqual(distro[0].name, 'Fedora') + self.assertEqual(distro[0].name, "Fedora") self.assertEqual(len(distro), 1) def test_distro_get_or_create(self): """ Test the get_or_create function of Distro. """ create_distro(self.session) - distro = models.Distro.get_or_create(self.session, 'fedora') - self.assertEqual(distro.name, 'Fedora') + distro = models.Distro.get_or_create(self.session, "fedora") + self.assertEqual(distro.name, "Fedora") self.assertEqual(2, models.Distro.all(self.session, count=True)) - distro = models.Distro.get_or_create(self.session, 'CentOS') - self.assertEqual(distro.name, 'CentOS') + distro = models.Distro.get_or_create(self.session, "CentOS") + self.assertEqual(distro.name, "CentOS") self.assertEqual(3, models.Distro.all(self.session, count=True)) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Distrotests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/test_flask.py b/anitya/tests/test_flask.py index 3d0f44516..9c93543a2 100644 --- a/anitya/tests/test_flask.py +++ b/anitya/tests/test_flask.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the flask application. -''' +""" from sqlalchemy.exc import SQLAlchemyError from six.moves.urllib import parse @@ -33,8 +33,14 @@ from anitya import ui from anitya.db import models, Session -from anitya.tests.base import (AnityaTestCase, DatabaseTestCase, create_distro, create_project, - login_user, create_package) +from anitya.tests.base import ( + AnityaTestCase, + DatabaseTestCase, + create_distro, + create_project, + login_user, + create_package, +) class ShutdownSessionTests(AnityaTestCase): @@ -45,23 +51,18 @@ def test_session_removed_post_request(self): session = Session() self.assertTrue(session is Session()) app = self.flask_app.test_client() - app.get('/about', follow_redirects=False) + app.get("/about", follow_redirects=False) self.assertFalse(session is Session()) class SettingsTests(DatabaseTestCase): - def setUp(self): """Set up the Flask testing environnment""" super(SettingsTests, self).setUp() self.app = self.flask_app.test_client() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -70,89 +71,109 @@ def setUp(self): def test_login_required(self): """Assert this view is protected and login is required.""" - output = self.app.get('/settings/', follow_redirects=False) + output = self.app.get("/settings/", follow_redirects=False) self.assertEqual(output.status_code, 302) - self.assertEqual('/login/', parse.urlparse(output.location).path) + self.assertEqual("/login/", parse.urlparse(output.location).path) def test_new_token(self): """Assert a user can create a new API token.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/settings/', follow_redirects=False) + output = c.get("/settings/", follow_redirects=False) self.assertEqual(output.status_code, 200) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token, 'description': 'Test token'} + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] + data = {"csrf_token": csrf_token, "description": "Test token"} - output = c.post('/settings/tokens/new', data=data, follow_redirects=True) + output = c.post( + "/settings/tokens/new", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) - self.assertTrue(b'Test token' in output.data) + self.assertTrue(b"Test token" in output.data) def test_new_token_bad_csrf(self): """Assert a valid CSRF token is required to make a token.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - data = {'csrf_token': 'no good?', 'description': 'Test token'} + data = {"csrf_token": "no good?", "description": "Test token"} - output = c.post('/settings/tokens/new', data=data, follow_redirects=True) + output = c.post( + "/settings/tokens/new", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 400) - self.assertFalse(b'Test token' in output.data) + self.assertFalse(b"Test token" in output.data) def test_delete_token(self): """Assert a user can delete an API token.""" session = Session() - token = models.ApiToken(user=self.user, description='Test token') + token = models.ApiToken(user=self.user, description="Test token") session.add(token) session.commit() with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/settings/', follow_redirects=False) + output = c.get("/settings/", follow_redirects=False) self.assertEqual(output.status_code, 200) - self.assertTrue(b'Test token' in output.data) + self.assertTrue(b"Test token" in output.data) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] + data = {"csrf_token": csrf_token} - output = c.post('/settings/tokens/delete/{}/'.format(token.token), - data=data, follow_redirects=True) + output = c.post( + "/settings/tokens/delete/{}/".format(token.token), + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 200) - self.assertFalse(b'Test token' in output.data) - self.assertEqual(0, models.ApiToken.query.filter_by(user=self.user).count()) + self.assertFalse(b"Test token" in output.data) + self.assertEqual( + 0, models.ApiToken.query.filter_by(user=self.user).count() + ) def test_delete_invalid_token(self): """Assert trying to delete an invalid token fails.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/settings/', follow_redirects=False) + output = c.get("/settings/", follow_redirects=False) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] + data = {"csrf_token": csrf_token} - output = c.post('/settings/tokens/delete/thisprobablywillnotwork/', - data=data, follow_redirects=True) + output = c.post( + "/settings/tokens/delete/thisprobablywillnotwork/", + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 404) def test_delete_token_invalid_csrf(self): """Assert trying to delete a token without a CSRF token fails.""" session = Session() - token = models.ApiToken(user=self.user, description='Test token') + token = models.ApiToken(user=self.user, description="Test token") session.add(token) session.commit() with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - data = {'csrf_token': 'not a valid token'} + data = {"csrf_token": "not a valid token"} - output = c.post('/settings/tokens/delete/{}/'.format(token.token), - data=data, follow_redirects=True) + output = c.post( + "/settings/tokens/delete/{}/".format(token.token), + data=data, + follow_redirects=True, + ) self.assertEqual(output.status_code, 400) - self.assertEqual(1, models.ApiToken.query.filter_by(user=self.user).count()) + self.assertEqual( + 1, models.ApiToken.query.filter_by(user=self.user).count() + ) class NewProjectTests(DatabaseTestCase): @@ -162,13 +183,9 @@ def setUp(self): """Set up the Flask testing environnment""" super(NewProjectTests, self).setUp() self.app = self.flask_app.test_client() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -177,45 +194,46 @@ def setUp(self): def test_protected_view(self): """Assert this view is protected and login is required.""" - output = self.app.get('/project/new', follow_redirects=False) + output = self.app.get("/project/new", follow_redirects=False) self.assertEqual(output.status_code, 302) - self.assertEqual('/login/', parse.urlparse(output.location).path) + self.assertEqual("/login/", parse.urlparse(output.location).path) def test_authenticated_access(self): """Assert authenticated users have access to the view.""" with login_user(self.flask_app, self.user): - output = self.app.get('/project/new', follow_redirects=False) + output = self.app.get("/project/new", follow_redirects=False) self.assertEqual(output.status_code, 200) def test_new_project(self): """Assert an authenticated user can create a new project""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=False) + output = c.get("/project/new", follow_redirects=False) self.assertEqual(output.status_code, 200) - self.assertTrue(b'

Add project

' in output.data) + self.assertTrue(b"

Add project

" in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'csrf_token': csrf_token, - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', + "csrf_token": csrf_token, + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", } with fml_testing.mock_sends(anitya_schema.ProjectCreated): - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project created
  • ' in output.data) - self.assertTrue( - b'

    Project: repo_manager

    ' in output.data) + b"Project created" in output.data + ) + self.assertTrue(b"

    Project: repo_manager

    " in output.data) projects = models.Project.all(self.session, count=True) self.assertEqual(projects, 1) @@ -223,20 +241,20 @@ def test_new_project_no_csrf(self): """Assert a missing CSRF token results in an HTTP 400""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=True) + output = c.get("/project/new", follow_redirects=True) self.assertEqual(output.status_code, 200) data = { - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", } - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 400) - self.assertTrue(b'

    Add project

    ' in output.data) + self.assertTrue(b"

    Add project

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) projects = models.Project.all(self.session, count=True) self.assertEqual(projects, 0) @@ -244,36 +262,36 @@ def test_new_project_duplicate(self): """Assert duplicate projects result in a HTTP 409""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=True) + output = c.get("/project/new", follow_redirects=True) self.assertEqual(output.status_code, 200) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'csrf_token': csrf_token, - 'name': 'requests', - 'homepage': 'https://pypi.python.org/pypi/requests', - 'backend': 'PyPI', - 'version_scheme': 'RPM', + "csrf_token": csrf_token, + "name": "requests", + "homepage": "https://pypi.python.org/pypi/requests", + "backend": "PyPI", + "version_scheme": "RPM", } with fml_testing.mock_sends(anitya_schema.ProjectCreated): - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) # Now try to recreate the same project we did above - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 409) self.assertFalse( b'
  • ' - b'Project created
  • ' in output.data) - self.assertFalse( - b'

    Project: repo_manager

    ' in output.data) + b"Project created" in output.data + ) + self.assertFalse(b"

    Project: repo_manager

    " in output.data) self.assertTrue( b'
  • ' - b'Unable to create project since it already exists.
  • ' - in output.data) - self.assertTrue(b'

    Add project

    ' in output.data) + b"Unable to create project since it already exists." + in output.data + ) + self.assertTrue(b"

    Add project

    " in output.data) projects = models.Project.query.count() self.assertEqual(projects, 1) @@ -281,91 +299,94 @@ def test_new_project_invalid_homepage(self): """Assert a project with an invalid homepage results in an HTTP 400.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=True) + output = c.get("/project/new", follow_redirects=True) self.assertEqual(output.status_code, 200) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'name': 'fedocal', - 'homepage': 'pypi/fedocal', - 'backend': 'PyPI', - 'version_scheme': 'RPM', - 'csrf_token': csrf_token, + "name": "fedocal", + "homepage": "pypi/fedocal", + "backend": "PyPI", + "version_scheme": "RPM", + "csrf_token": csrf_token, } - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 400) - self.assertTrue(b'

    Add project

    ' in output.data) + self.assertTrue(b"

    Add project

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) - @mock.patch('anitya.lib.utilities.check_project_release') + @mock.patch("anitya.lib.utilities.check_project_release") def test_new_project_with_check_release(self, patched): - output = self.app.get('/project/new', follow_redirects=True) + output = self.app.get("/project/new", follow_redirects=True) with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=True) + output = c.get("/project/new", follow_redirects=True) # check_release off data = { - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', - 'csrf_token': output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0], + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", + "csrf_token": output.data.split( + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0], } with fml_testing.mock_sends(anitya_schema.ProjectCreated): - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project created
  • ' in output.data) + b"Project created" in output.data + ) patched.assert_not_called() # check_release_on - data['name'] += 'xxx' - data['check_release'] = 'on' + data["name"] += "xxx" + data["check_release"] = "on" with fml_testing.mock_sends(anitya_schema.ProjectCreated): - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project created
  • ' in output.data) + b"Project created" in output.data + ) patched.assert_called_once_with(mock.ANY, mock.ANY) def test_new_project_distro_mapping(self): """Assert an authenticated user can create a new project with distro mapping""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/new', follow_redirects=False) + output = c.get("/project/new", follow_redirects=False) self.assertEqual(output.status_code, 200) - self.assertTrue(b'

    Add project

    ' in output.data) + self.assertTrue(b"

    Add project

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'csrf_token': csrf_token, - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', - 'distro': 'Fedora', - 'package_name': 'repo_manager', + "csrf_token": csrf_token, + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", + "distro": "Fedora", + "package_name": "repo_manager", } - output = c.post( - '/project/new', data=data, follow_redirects=True) + output = c.post("/project/new", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project created
  • ' in output.data) - self.assertTrue( - b'

    Project: repo_manager

    ' in output.data) + b"Project created" in output.data + ) + self.assertTrue(b"

    Project: repo_manager

    " in output.data) projects = models.Project.all(self.session) self.assertEqual(len(projects), 1) self.assertEqual(len(projects[0].package), 1) @@ -380,15 +401,11 @@ def setUp(self): """ Set up the environnment, ran before every tests. """ super(FlaskTest, self).setUp() - self.flask_app.config['TESTING'] = True + self.flask_app.config["TESTING"] = True self.app = self.flask_app.test_client() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -397,7 +414,7 @@ def setUp(self): def test_index(self): """ Test the index function. """ - output = self.app.get('/') + output = self.app.get("/") self.assertEqual(output.status_code, 200) expected = b""" @@ -421,20 +438,18 @@ def test_index(self): def test_about(self): """Assert the legacy about endpoint redirects to documentation""" - output = self.app.get('/about') + output = self.app.get("/about") self.assertEqual(output.status_code, 302) self.assertEqual( - output.headers['Location'], - 'http://localhost/static/docs/index.html' + output.headers["Location"], "http://localhost/static/docs/index.html" ) def test_fedmsg(self): """Assert the legacy fedmsg endpoint redirects to documentation""" - output = self.app.get('/fedmsg') + output = self.app.get("/fedmsg") self.assertEqual(output.status_code, 302) self.assertEqual( - output.headers['Location'], - 'http://localhost/static/docs/user-guide.html' + output.headers["Location"], "http://localhost/static/docs/user-guide.html" ) def test_project(self): @@ -442,7 +457,7 @@ def test_project(self): create_distro(self.session) create_project(self.session) - output = self.app.get('/project/1/') + output = self.app.get("/project/1/") self.assertEqual(output.status_code, 200) expected = b""" @@ -452,7 +467,7 @@ def test_project(self): self.assertTrue(expected in output.data) - output = self.app.get('/project/10/') + output = self.app.get("/project/10/") self.assertEqual(output.status_code, 404) def test_projects(self): @@ -460,7 +475,7 @@ def test_projects(self): create_distro(self.session) create_project(self.session) - output = self.app.get('/projects/') + output = self.app.get("/projects/") self.assertEqual(output.status_code, 200) expected = b""" @@ -472,7 +487,7 @@ def test_projects(self): expected = ( b'\n \n ' - b'https://fedorahosted.org/r2spec/\n ' + b"https://fedorahosted.org/r2spec/\n " ) self.assertTrue(expected in output.data) @@ -484,7 +499,7 @@ def test_projects(self): self.assertEqual(output.data.count(b'' in output.data) - self.assertTrue( - b'

    Projects of Fedora monitored

    ' in output.data) + b'class="form-inline">' in output.data + ) + self.assertTrue(b"

    Projects of Fedora monitored

    " in output.data) - output = self.app.get('/distro/Fedora/?page=ab') + output = self.app.get("/distro/Fedora/?page=ab") self.assertEqual(output.status_code, 200) self.assertTrue(expected in output.data) self.assertTrue( b'form action="/distro/Fedora/search/" role="form" ' - b'class="form-inline">' in output.data) - self.assertTrue( - b'

    Projects of Fedora monitored

    ' in output.data) + b'class="form-inline">' in output.data + ) + self.assertTrue(b"

    Projects of Fedora monitored

    " in output.data) def test_distro_projects_search(self): """ Test the distro_projects_search function. """ create_distro(self.session) create_project(self.session) - output = self.app.get('/distro/Fedora/search/gua') + output = self.app.get("/distro/Fedora/search/gua") self.assertEqual(output.status_code, 200) expected = b""" @@ -548,10 +563,9 @@ def test_distro_projects_search(self): """ self.assertTrue(expected in output.data) self.assertTrue( - b'form action="/distro/Fedora/search/" role="form">' - in output.data) - self.assertTrue( - b'

    Search projects in Fedora

    ' in output.data) + b'form action="/distro/Fedora/search/" role="form">' in output.data + ) + self.assertTrue(b"

    Search projects in Fedora

    " in output.data) def test_distro_projects_search_pattern(self): """ @@ -562,7 +576,7 @@ def test_distro_projects_search_pattern(self): create_project(self.session) create_package(self.session) - output = self.app.get('/distro/Fedora/search/g') + output = self.app.get("/distro/Fedora/search/g") self.assertEqual(output.status_code, 200) self.assertEqual(output.data.count(b'
    ' \ - b'Only one result matching with an ' \ - b'exact match, redirecting' + expected = ( + b'
  • ' + b"Only one result matching with an " + b"exact match, redirecting
  • " + ) self.assertTrue(expected in output.data) def test_projects_search(self): @@ -614,11 +629,11 @@ def test_projects_search(self): create_distro(self.session) create_project(self.session) - output = self.app.get('/projects/search/g') + output = self.app.get("/projects/search/g") self.assertEqual(output.status_code, 200) self.assertEqual(output.data.count(b'
    @@ -628,62 +643,57 @@ def test_projects_search(self): self.assertEqual(output.data.count(b'' \ - b'Only one result matching with an ' \ - b'exact match, redirecting' + expected = ( + b'
  • ' + b"Only one result matching with an " + b"exact match, redirecting
  • " + ) self.assertTrue(expected in output.data) def test_logout_redirect(self): """Assert the logout logouts user""" with login_user(self.flask_app, self.user): - output = self.app.get('/logout') + output = self.app.get("/logout") self.assertEqual(output.status_code, 302) - self.assertEqual( - output.headers['Location'], - 'http://localhost/' - ) + self.assertEqual(output.headers["Location"], "http://localhost/") def test_logout(self): """Assert the logout logouts user""" login_user(self.flask_app, self.user) - output = self.app.get('/logout', follow_redirects=True) - output = self.app.get('/project/new', follow_redirects=False) + output = self.app.get("/logout", follow_redirects=True) + output = self.app.get("/project/new", follow_redirects=False) self.assertEqual(output.status_code, 302) - self.assertEqual('/login/', parse.urlparse(output.location).path) + self.assertEqual("/login/", parse.urlparse(output.location).path) def test_projects_search_by_name(self): """ Test the project_name function. """ create_project(self.session) - output = self.app.get('/project/geany') + output = self.app.get("/project/geany") self.assertEqual(output.status_code, 301) - self.assertEqual( - output.headers['Location'], - 'http://localhost/project/geany/' - ) + self.assertEqual(output.headers["Location"], "http://localhost/project/geany/") def test_projects_search_by_name_slash(self): """ Assert that `anitya.ui.project_name` renders page with correct project. """ create_project(self.session) - output = self.app.get('/project/geany/') + output = self.app.get("/project/geany/") self.assertEqual(output.status_code, 200) - expected = b'

    Project: geany

    ' + expected = b"

    Project: geany

    " self.assertTrue(expected in output.data) def test_projects_search_by_name_incorrect_page(self): @@ -692,9 +702,9 @@ def test_projects_search_by_name_incorrect_page(self): converts incorrect page value. """ create_project(self.session) - expected = b'

    Project: geany

    ' + expected = b"

    Project: geany

    " - output = self.app.get('/project/geany/?page=ab') + output = self.app.get("/project/geany/?page=ab") self.assertEqual(output.status_code, 200) self.assertTrue(expected in output.data) @@ -705,15 +715,15 @@ def test_projects_search_by_name_pattern(self): """ create_project(self.session) project = models.Project( - name='geany_project', - homepage='https://example.com/geany_project', - backend='PyPI', - ecosystem_name='pypi', + name="geany_project", + homepage="https://example.com/geany_project", + backend="PyPI", + ecosystem_name="pypi", ) self.session.add(project) self.session.commit() - output = self.app.get('/project/geany*/') + output = self.app.get("/project/geany*/") self.assertEqual(output.status_code, 200) self.assertEqual(output.data.count(b'
    ' \ - b'status is invalid, you should use one of: ' \ - b'new, updated, failed, never_updated, odd; using default: ' \ - b'`updated`
  • ' \ - b'Returning all the projects regardless of how/if their version was ' \ - b'retrieved correctly
  • ' + output = self.app.get("/projects/updates/status") + expected = ( + b'
  • ' + b"status is invalid, you should use one of: " + b"new, updated, failed, never_updated, odd; using default: " + b'`updated`
  • ' + b"Returning all the projects regardless of how/if their version was " + b"retrieved correctly
  • " + ) self.assertEqual(output.status_code, 200) self.assertTrue(expected in output.data) class EditProjectTests(DatabaseTestCase): - def setUp(self): """Set up the Flask testing environnment""" super(EditProjectTests, self).setUp() self.app = self.flask_app.test_client() # Make a user to login with - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -792,146 +805,151 @@ def setUp(self): def test_protected_view(self): """Assert this view is protected and login is required.""" with self.flask_app.test_client() as client: - output = client.get('/project/1/edit', follow_redirects=False) + output = client.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 302) - self.assertEqual('/login/', parse.urlparse(output.location).path) + self.assertEqual("/login/", parse.urlparse(output.location).path) def test_authenticated_access(self): """Assert authenticated users have access to the view.""" with login_user(self.flask_app, self.user): - output = self.app.get('/project/1/edit', follow_redirects=False) + output = self.app.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 200) def test_non_existing_project(self): """Assert trying to edit a project that doesn't exist returns HTTP 404.""" with login_user(self.flask_app, self.user): - output = self.app.get('/project/idonotexist/edit', follow_redirects=False) + output = self.app.get("/project/idonotexist/edit", follow_redirects=False) self.assertEqual(output.status_code, 404) def test_no_csrf_token(self): """Assert trying to edit a project without a CSRF token results in no change.""" with login_user(self.flask_app, self.user): data = { - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", } - output = self.app.post('/project/1/edit', data=data) + output = self.app.post("/project/1/edit", data=data) self.assertEqual(200, output.status_code) - self.assertEqual('geany', models.Project.query.get(1).name) + self.assertEqual("geany", models.Project.query.get(1).name) def test_edit_project(self): """ Test the edit_project function. """ with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/edit', follow_redirects=False) + output = c.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 200) - self.assertTrue(b'

    Edit project

    ' in output.data) + self.assertTrue(b"

    Edit project

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', - 'csrf_token': csrf_token, + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", + "csrf_token": csrf_token, } with fml_testing.mock_sends(anitya_schema.ProjectEdited): - output = c.post( - '/project/1/edit', data=data, follow_redirects=True) + output = c.post("/project/1/edit", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project edited
  • ' in output.data) - self.assertTrue( - b'

    Project: repo_manager

    ' in output.data) + b"Project edited" in output.data + ) + self.assertTrue(b"

    Project: repo_manager

    " in output.data) def test_edit_project_no_change(self): """ Test the edit_project function. """ with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/edit', follow_redirects=False) + output = c.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 200) - self.assertTrue(b'

    Edit project

    ' in output.data) + self.assertTrue(b"

    Edit project

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'csrf_token': csrf_token, - 'name': 'geany', - 'homepage': 'https://www.geany.org/', - 'backend': 'custom', - 'version_scheme': 'RPM', + "csrf_token": csrf_token, + "name": "geany", + "homepage": "https://www.geany.org/", + "backend": "custom", + "version_scheme": "RPM", } - output = c.post( - '/project/1/edit', data=data, follow_redirects=True) + output = c.post("/project/1/edit", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project edited - No changes were made
  • ' in output.data) + b"Project edited - No changes were made" in output.data + ) def test_edit_to_duplicate_project(self): """Assert trying to edit a project to make a duplicate fails.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/edit', follow_redirects=False) + output = c.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 200) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'name': 'R2spec', - 'homepage': 'https://fedorahosted.org/r2spec/', - 'backend': 'folder', - 'version_scheme': 'RPM', - 'csrf_token': csrf_token, + "name": "R2spec", + "homepage": "https://fedorahosted.org/r2spec/", + "backend": "folder", + "version_scheme": "RPM", + "csrf_token": csrf_token, } - output = c.post( - '/project/1/edit', data=data, follow_redirects=True) + output = c.post("/project/1/edit", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Could not edit this project. Is there ' - b'already a project with these name and homepage?
  • ' - in output.data) - self.assertTrue(b'

    Project: geany

    ' in output.data) - self.assertEqual('geany', models.Project.query.get(1).name) - - @mock.patch('anitya.lib.utilities.check_project_release') + b"Could not edit this project. Is there " + b"already a project with these name and homepage?" + in output.data + ) + self.assertTrue(b"

    Project: geany

    " in output.data) + self.assertEqual("geany", models.Project.query.get(1).name) + + @mock.patch("anitya.lib.utilities.check_project_release") def test_with_check_release(self, patched): """Assert when ``check_release='on'`` it checks the project's release.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/edit', follow_redirects=False) + output = c.get("/project/1/edit", follow_redirects=False) self.assertEqual(output.status_code, 200) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'name': 'repo_manager', - 'homepage': 'https://pypi.python.org/pypi/repo_manager', - 'backend': 'PyPI', - 'version_scheme': 'RPM', - 'csrf_token': csrf_token, - 'check_release': 'on', + "name": "repo_manager", + "homepage": "https://pypi.python.org/pypi/repo_manager", + "backend": "PyPI", + "version_scheme": "RPM", + "csrf_token": csrf_token, + "check_release": "on", } with fml_testing.mock_sends(anitya_schema.ProjectEdited): - output = c.post( - '/project/1/edit', data=data, follow_redirects=True) + output = c.post("/project/1/edit", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Project edited
  • ' in output.data) + b"Project edited" in output.data + ) patched.assert_called_once_with(mock.ANY, mock.ANY) @@ -943,13 +961,9 @@ def setUp(self): create_distro(self.session) create_project(self.session) self.client = self.flask_app.test_client() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -958,30 +972,29 @@ def setUp(self): def test_protected_view(self): """Assert this view is protected and login is required.""" - output = self.client.get('/project/1/map', follow_redirects=False) + output = self.client.get("/project/1/map", follow_redirects=False) self.assertEqual(output.status_code, 302) - self.assertEqual('/login/', parse.urlparse(output.location).path) + self.assertEqual("/login/", parse.urlparse(output.location).path) def test_authenticated_access(self): """Assert authenticated users have access to the view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/1/map', follow_redirects=False) + output = self.client.get("/project/1/map", follow_redirects=False) self.assertEqual(output.status_code, 200) def test_non_existing_project(self): """Assert trying to edit a project that doesn't exist returns HTTP 404.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/idonotexist/map', follow_redirects=False) + output = self.client.get("/project/idonotexist/map", follow_redirects=False) self.assertEqual(output.status_code, 404) def test_no_csrf_token(self): """Assert trying to edit a project without a CSRF token results in no change.""" with login_user(self.flask_app, self.user): - data = { - 'package_name': 'geany', - 'distro': 'CentOS', - } - output = self.client.post('/project/1/map', data=data, follow_redirects=False) + data = {"package_name": "geany", "distro": "CentOS"} + output = self.client.post( + "/project/1/map", data=data, follow_redirects=False + ) self.assertEqual(output.status_code, 200) self.assertEqual(0, models.Packages.query.count()) @@ -989,28 +1002,31 @@ def test_map_project(self): """Assert projects can be mapped to distributions.""" with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/map') + output = c.get("/project/1/map") self.assertEqual(output.status_code, 200) - self.assertTrue(b'

    Project: geany

    ' in output.data) + self.assertTrue(b"

    Project: geany

    " in output.data) self.assertTrue( - b'' in output.data) + b'' in output.data + ) csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': 'geany', - 'distro': 'Fedora', - 'csrf_token': csrf_token, + "package_name": "geany", + "distro": "Fedora", + "csrf_token": csrf_token, } with fml_testing.mock_sends(anitya_schema.ProjectMapCreated): - output = c.post('/project/1/map', data=data, follow_redirects=True) + output = c.post("/project/1/map", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Mapping added
  • ' in output.data) - self.assertTrue(b'

    Project: geany

    ' in output.data) + b"Mapping added" in output.data + ) + self.assertTrue(b"

    Project: geany

    " in output.data) self.assertEqual(1, models.Packages.query.count()) def test_map_same_distro(self): @@ -1020,29 +1036,29 @@ def test_map_same_distro(self): """ with login_user(self.flask_app, self.user): with self.flask_app.test_client() as c: - output = c.get('/project/1/map') + output = c.get("/project/1/map") csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': 'geany', - 'distro': 'Fedora', - 'csrf_token': csrf_token, + "package_name": "geany", + "distro": "Fedora", + "csrf_token": csrf_token, } with fml_testing.mock_sends(anitya_schema.ProjectMapCreated): - output = c.post('/project/1/map', data=data, follow_redirects=True) + output = c.post("/project/1/map", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) - output = c.post('/project/1/map', data=data, follow_redirects=True) + output = c.post("/project/1/map", data=data, follow_redirects=True) self.assertEqual(output.status_code, 200) self.assertTrue( b'
  • ' - b'Could not edit the mapping of geany on ' - b'Fedora, there is already a package geany on Fedora ' + b"Could not edit the mapping of geany on " + b"Fedora, there is already a package geany on Fedora " b'as part of the project geany' - b'.
  • ' - in output.data) - self.assertTrue( - b'

    Project: geany

    ' in output.data) + b"." in output.data + ) + self.assertTrue(b"

    Project: geany

    " in output.data) class EditProjectMappingTests(DatabaseTestCase): @@ -1053,65 +1069,72 @@ def setUp(self): # Set up a mapping to edit session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) self.session.add(user_social_auth) - self.distro1 = models.Distro(name='CentOS') - self.distro2 = models.Distro(name='Fedora') + self.distro1 = models.Distro(name="CentOS") + self.distro2 = models.Distro(name="Fedora") self.project = models.Project( - name='python_project', - homepage='https://example.com/python_project', - backend='PyPI', - ecosystem_name='pypi', + name="python_project", + homepage="https://example.com/python_project", + backend="PyPI", + ecosystem_name="pypi", ) self.package = models.Packages( - package_name='python_project', distro_name=self.distro1.name, project=self.project) - session.add_all([self.user, self.distro1, self.distro2, self.project, self.package]) + package_name="python_project", + distro_name=self.distro1.name, + project=self.project, + ) + session.add_all( + [self.user, self.distro1, self.distro2, self.project, self.package] + ) session.commit() self.client = self.flask_app.test_client() def test_edit_project_mapping_package_name(self): """Assert a project's package name can be edited.""" with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/map/1') + pre_edit_output = self.client.get("/project/1/map/1") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': 'Python Project', - 'distro': self.distro1.name, - 'csrf_token': csrf_token, + "package_name": "Python Project", + "distro": self.distro1.name, + "csrf_token": csrf_token, } with fml_testing.mock_sends(anitya_schema.ProjectMapEdited): - output = self.client.post('/project/1/map/1', data=data, follow_redirects=True) + output = self.client.post( + "/project/1/map/1", data=data, follow_redirects=True + ) self.assertEqual(pre_edit_output.status_code, 200) self.assertEqual(output.status_code, 200) packages = models.Packages.query.all() self.assertEqual(1, len(packages)) - self.assertEqual('Python Project', packages[0].package_name) + self.assertEqual("Python Project", packages[0].package_name) def test_edit_project_mapping_distro(self): """Assert a project's package distro can be edited.""" with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/map/1') + pre_edit_output = self.client.get("/project/1/map/1") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': self.project.name, - 'distro': self.distro2.name, - 'csrf_token': csrf_token, + "package_name": self.project.name, + "distro": self.distro2.name, + "csrf_token": csrf_token, } with fml_testing.mock_sends(anitya_schema.ProjectMapEdited): - output = self.client.post('/project/1/map/1', data=data, follow_redirects=True) + output = self.client.post( + "/project/1/map/1", data=data, follow_redirects=True + ) self.assertEqual(pre_edit_output.status_code, 200) self.assertEqual(output.status_code, 200) @@ -1125,67 +1148,80 @@ def test_clashing_package_name(self): # Set up a package to clash with. session = Session() best_project = models.Project( - name='best_project', - homepage='https://example.com/best_project', - backend='PyPI', - ecosystem_name='pypi', + name="best_project", + homepage="https://example.com/best_project", + backend="PyPI", + ecosystem_name="pypi", ) best_package = models.Packages( - package_name='best_project', distro_name=self.distro1.name, project=best_project) + package_name="best_project", + distro_name=self.distro1.name, + project=best_project, + ) session.add_all([best_project, best_package]) session.commit() with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/map/1') + pre_edit_output = self.client.get("/project/1/map/1") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': self.project.name, - 'distro': self.distro1.name, - 'csrf_token': csrf_token, + "package_name": self.project.name, + "distro": self.distro1.name, + "csrf_token": csrf_token, } - output = self.client.post('/project/1/map/1', data=data, follow_redirects=True) + output = self.client.post( + "/project/1/map/1", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) self.assertEqual(2, models.Packages.query.count()) - self.assertEqual(1, models.Packages.query.filter_by( - package_name='best_project').count()) - self.assertEqual(1, models.Packages.query.filter_by( - package_name='python_project').count()) - self.assertTrue(b'Could not edit the mapping' in output.data) + self.assertEqual( + 1, models.Packages.query.filter_by(package_name="best_project").count() + ) + self.assertEqual( + 1, + models.Packages.query.filter_by(package_name="python_project").count(), + ) + self.assertTrue(b"Could not edit the mapping" in output.data) def test_invalid_map_id(self): """Assert trying to edit a mapping with an invalid package ID returns HTTP 404.""" with login_user(self.flask_app, self.user): - output = self.client.post('/project/1/map/42', data={}) + output = self.client.post("/project/1/map/42", data={}) self.assertEqual(output.status_code, 404) def test_invalid_project_id(self): """Assert trying to edit a mapping with an invalid project ID returns HTTP 404.""" with login_user(self.flask_app, self.user): - output = self.client.post('/project/42/map/1', data={}) + output = self.client.post("/project/42/map/1", data={}) self.assertEqual(output.status_code, 404) def test_anitya_exception(self): """Assert handling of exception.""" with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/map/1') + pre_edit_output = self.client.get("/project/1/map/1") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] data = { - 'package_name': self.project.name, - 'distro': self.distro2.name, - 'csrf_token': csrf_token, + "package_name": self.project.name, + "distro": self.distro2.name, + "csrf_token": csrf_token, } - output = self.client.post('/project/1/map/1', data=data, follow_redirects=True) + output = self.client.post( + "/project/1/map/1", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) self.assertTrue( - b'Could not add the mapping of python_project to Fedora, ' - b'please inform an admin.' - in output.data) + b"Could not add the mapping of python_project to Fedora, " + b"please inform an admin." in output.data + ) class AddDistroTests(DatabaseTestCase): @@ -1196,21 +1232,16 @@ def setUp(self): # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) session.add_all([admin_social_auth, self.admin]) @@ -1221,47 +1252,55 @@ def setUp(self): def test_no_csrf_token(self): """Assert submitting without a CSRF token, no change is made.""" with login_user(self.flask_app, self.user): - output = self.client.post('/distro/add', data={'name': 'Fedora'}) + output = self.client.post("/distro/add", data={"name": "Fedora"}) self.assertEqual(200, output.status_code) self.assertEqual(0, models.Distro.query.count()) def test_invalid_csrf_token(self): """Assert submitting with an invalid CSRF token, no change is made.""" with login_user(self.flask_app, self.user): - output = self.client.post('/distro/add', data={'csrf_token': 'abc', 'name': 'Fedora'}) + output = self.client.post( + "/distro/add", data={"csrf_token": "abc", "name": "Fedora"} + ) self.assertEqual(200, output.status_code) self.assertEqual(0, models.Distro.query.count()) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_add_distro(self, mock_method): """Assert admins can add distributions.""" with login_user(self.flask_app, self.user): - output = self.client.get('/distro/add') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'name': 'Fedora', 'csrf_token': csrf_token} + output = self.client.get("/distro/add") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"name": "Fedora", "csrf_token": csrf_token} - output = self.client.post('/distro/add', data=data, follow_redirects=True) + output = self.client.post("/distro/add", data=data, follow_redirects=True) self.assertEqual(200, output.status_code) - self.assertTrue(b'Distribution added' in output.data) + self.assertTrue(b"Distribution added" in output.data) - @mock.patch('anitya.lib.utilities.fedmsg_publish') + @mock.patch("anitya.lib.utilities.fedmsg_publish") def test_duplicate_distro(self, mock_method): """Assert trying to create a duplicate distribution results in HTTP 409.""" with login_user(self.flask_app, self.user): - output = self.client.get('/distro/add') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'name': 'Fedora', 'csrf_token': csrf_token} - - create_output = self.client.post('/distro/add', data=data, follow_redirects=True) + output = self.client.get("/distro/add") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"name": "Fedora", "csrf_token": csrf_token} + + create_output = self.client.post( + "/distro/add", data=data, follow_redirects=True + ) self.assertEqual(200, output.status_code) - dup_output = self.client.post('/distro/add', data=data, follow_redirects=True) + dup_output = self.client.post( + "/distro/add", data=data, follow_redirects=True + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'Distribution added' in create_output.data) - self.assertTrue(b'Could not add this distro' in dup_output.data) + self.assertTrue(b"Distribution added" in create_output.data) + self.assertTrue(b"Could not add this distro" in dup_output.data) class FlagProjecTests(DatabaseTestCase): @@ -1271,13 +1310,9 @@ def setUp(self): super(FlagProjecTests, self).setUp() create_project(self.session) - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) self.session.add(self.user) @@ -1288,14 +1323,14 @@ def setUp(self): def test_flag_project(self): """ Assert flaging project.""" with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/flag') + pre_edit_output = self.client.get("/project/1/flag") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = { - 'reason': 'Unfit for humanity', - 'csrf_token': csrf_token, - } - output = self.client.post('/project/1/flag', data=data, follow_redirects=True) + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] + data = {"reason": "Unfit for humanity", "csrf_token": csrf_token} + output = self.client.post( + "/project/1/flag", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) flags = self.session.query(models.ProjectFlag).all() @@ -1305,27 +1340,26 @@ def test_flag_project(self): def test_invalid_project(self): """ Assert abort with invalid project.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/99/flag') + output = self.client.get("/project/99/flag") self.assertEqual(output.status_code, 404) def test_anitya_exception(self): """Assert handling of exception.""" with mock.patch.object( - self.session, 'flush', mock.Mock(side_effect=[SQLAlchemyError(), None])): + self.session, "flush", mock.Mock(side_effect=[SQLAlchemyError(), None]) + ): with login_user(self.flask_app, self.user): - pre_edit_output = self.client.get('/project/1/flag') + pre_edit_output = self.client.get("/project/1/flag") csrf_token = pre_edit_output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = { - 'reason': 'Unfit for humanity', - 'csrf_token': csrf_token, - } - output = self.client.post('/project/1/flag', data=data, follow_redirects=True) + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] + data = {"reason": "Unfit for humanity", "csrf_token": csrf_token} + output = self.client.post( + "/project/1/flag", data=data, follow_redirects=True + ) self.assertEqual(output.status_code, 200) - self.assertTrue( - b'Could not flag this project.' - in output.data) + self.assertTrue(b"Could not flag this project." in output.data) class UiTests(DatabaseTestCase): @@ -1333,7 +1367,7 @@ class UiTests(DatabaseTestCase): def test_format_examples(self): """ Assert format examples testing. """ - output = ui.format_examples(['http://example.com']) + output = ui.format_examples(["http://example.com"]) self.assertEqual(output, "http://example.com ") diff --git a/anitya/tests/test_flask_admin.py b/anitya/tests/test_flask_admin.py index ba2d46a33..0b6dc764d 100644 --- a/anitya/tests/test_flask_admin.py +++ b/anitya/tests/test_flask_admin.py @@ -41,27 +41,23 @@ def setUp(self): # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) session.add_all([admin_social_auth, self.admin]) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -82,32 +78,28 @@ def setUp(self): # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) # Add distributions to edit - self.fedora = models.Distro(name='Fedora') - self.centos = models.Distro(name='CentOS') + self.fedora = models.Distro(name="Fedora") + self.centos = models.Distro(name="CentOS") session.add_all([admin_social_auth, self.admin, self.fedora, self.centos]) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -116,54 +108,58 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users cannot GET the edit distribution view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/distro/Fedora/edit') + output = self.client.get("/distro/Fedora/edit") self.assertEqual(401, output.status_code) def test_non_admin_post(self): """Assert non-admin users cannot POST to the edit distribution view.""" with login_user(self.flask_app, self.user): - output = self.client.post('/distro/Fedora/edit') + output = self.client.post("/distro/Fedora/edit") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can get the edit distribution view.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/Fedora/edit') + output = self.client.get("/distro/Fedora/edit") self.assertEqual(200, output.status_code) def test_admin_post(self): """Assert admin users can edit a distribution.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/Fedora/edit') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'name': 'Top', 'csrf_token': csrf_token} + output = self.client.get("/distro/Fedora/edit") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"name": "Top", "csrf_token": csrf_token} with fml_testing.mock_sends(anitya_schema.DistroEdited): - output = self.client.post('/distro/Fedora/edit', data=data, follow_redirects=True) + output = self.client.post( + "/distro/Fedora/edit", data=data, follow_redirects=True + ) self.assertEqual(200, output.status_code) - self.assertEqual(200, self.client.get('/distro/Top/edit').status_code) + self.assertEqual(200, self.client.get("/distro/Top/edit").status_code) def test_missing_distro(self): """Assert requesting a non-existing distro returns HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/LFS/edit') + output = self.client.get("/distro/LFS/edit") self.assertEqual(404, output.status_code) def test_no_csrf_token(self): """Assert submitting without a CSRF token results in no change.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/distro/Fedora/edit', data={'name': 'Top'}) + output = self.client.post("/distro/Fedora/edit", data={"name": "Top"}) self.assertEqual(200, output.status_code) - self.assertEqual(0, models.Distro.query.filter_by(name='Top').count()) + self.assertEqual(0, models.Distro.query.filter_by(name="Top").count()) def test_invalid_csrf_token(self): """Assert submitting with an invalid CSRF token results in no change.""" with login_user(self.flask_app, self.admin): output = self.client.post( - '/distro/Fedora/edit', data={'csrf_token': 'a', 'name': 'Top'}) + "/distro/Fedora/edit", data={"csrf_token": "a", "name": "Top"} + ) self.assertEqual(200, output.status_code) - self.assertEqual(0, models.Distro.query.filter_by(name='Top').count()) + self.assertEqual(0, models.Distro.query.filter_by(name="Top").count()) class DeleteDistroTests(DatabaseTestCase): @@ -174,32 +170,28 @@ def setUp(self): # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) # Add distributions to delete - self.fedora = models.Distro(name='Fedora') - self.centos = models.Distro(name='CentOS') + self.fedora = models.Distro(name="Fedora") + self.centos = models.Distro(name="CentOS") session.add_all([admin_social_auth, self.admin, self.fedora, self.centos]) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -208,53 +200,56 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users cannot GET the delete distribution view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/distro/Fedora/delete') + output = self.client.get("/distro/Fedora/delete") self.assertEqual(401, output.status_code) def test_non_admin_post(self): """Assert non-admin users cannot POST to the delete distribution view.""" with login_user(self.flask_app, self.user): - output = self.client.post('/distro/Fedora/delete') + output = self.client.post("/distro/Fedora/delete") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can get the delete distribution view.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/Fedora/delete') + output = self.client.get("/distro/Fedora/delete") self.assertEqual(200, output.status_code) def test_admin_post(self): """Assert admin users can delete a distribution.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/Fedora/delete') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + output = self.client.get("/distro/Fedora/delete") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"csrf_token": csrf_token} with fml_testing.mock_sends(anitya_schema.DistroDeleted): - output = self.client.post('/distro/Fedora/delete', data=data, follow_redirects=True) + output = self.client.post( + "/distro/Fedora/delete", data=data, follow_redirects=True + ) self.assertEqual(200, output.status_code) - self.assertEqual(404, self.client.get('/distro/Fedora/delete').status_code) + self.assertEqual(404, self.client.get("/distro/Fedora/delete").status_code) def test_missing_distro(self): """Assert requesting a non-existing distro returns HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/distro/LFS/delete') + output = self.client.get("/distro/LFS/delete") self.assertEqual(404, output.status_code) def test_no_csrf_token(self): """Assert submitting without a CSRF token results in no change.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/distro/Fedora/delete', data={}) + output = self.client.post("/distro/Fedora/delete", data={}) self.assertEqual(200, output.status_code) - self.assertEqual(1, models.Distro.query.filter_by(name='Fedora').count()) + self.assertEqual(1, models.Distro.query.filter_by(name="Fedora").count()) def test_invalid_csrf_token(self): """Assert submitting with an invalid CSRF token results in no change.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/distro/Fedora/delete', data={'csrf_token': 'a'}) + output = self.client.post("/distro/Fedora/delete", data={"csrf_token": "a"}) self.assertEqual(200, output.status_code) - self.assertEqual(1, models.Distro.query.filter_by(name='Fedora').count()) + self.assertEqual(1, models.Distro.query.filter_by(name="Fedora").count()) class DeleteProjectTests(DatabaseTestCase): @@ -263,35 +258,31 @@ class DeleteProjectTests(DatabaseTestCase): def setUp(self): super(DeleteProjectTests, self).setUp() self.project = models.Project( - name='test_project', - homepage='https://example.com/test_project', - backend='PyPI', + name="test_project", + homepage="https://example.com/test_project", + backend="PyPI", ) # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) session.add_all([admin_social_auth, self.admin, self.project]) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -300,38 +291,42 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users cannot GET the delete project view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/{0}/delete'.format(self.project.id)) + output = self.client.get("/project/{0}/delete".format(self.project.id)) self.assertEqual(401, output.status_code) def test_non_admin_post(self): """Assert non-admin users cannot POST to the delete project view.""" with login_user(self.flask_app, self.user): - output = self.client.post('/project/{0}/delete'.format(self.project.id)) + output = self.client.post("/project/{0}/delete".format(self.project.id)) self.assertEqual(401, output.status_code) def test_missing_project(self): """Assert HTTP 404 is returned if the project doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/project/42/delete') + output = self.client.post("/project/42/delete") self.assertEqual(404, output.status_code) def test_admin_get(self): """Assert admin users can get the delete project view.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/{0}/delete'.format(self.project.id)) + output = self.client.get("/project/{0}/delete".format(self.project.id)) self.assertEqual(200, output.status_code) def test_admin_post(self): """Assert admin users can delete projects.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/{0}/delete'.format(self.project.id)) - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'confirm': True, 'csrf_token': csrf_token} + output = self.client.get("/project/{0}/delete".format(self.project.id)) + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"confirm": True, "csrf_token": csrf_token} with fml_testing.mock_sends(anitya_schema.ProjectDeleted): output = self.client.post( - '/project/{0}/delete'.format(self.project.id), data=data, follow_redirects=True) + "/project/{0}/delete".format(self.project.id), + data=data, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) self.assertEqual(0, len(models.Project.query.all())) @@ -339,12 +334,15 @@ def test_admin_post(self): def test_admin_post_unconfirmed(self): """Assert admin users must confirm deleting projects.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/{0}/delete'.format(self.project.id)) - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + output = self.client.get("/project/{0}/delete".format(self.project.id)) + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"csrf_token": csrf_token} - output = self.client.post('/project/{0}/delete'.format(self.project.id), data=data) + output = self.client.post( + "/project/{0}/delete".format(self.project.id), data=data + ) self.assertEqual(302, output.status_code) self.assertEqual(1, len(models.Project.query.all())) @@ -356,38 +354,39 @@ class DeleteProjectMappingTests(DatabaseTestCase): def setUp(self): super(DeleteProjectMappingTests, self).setUp() self.project = models.Project( - name='test_project', - homepage='https://example.com/test_project', - backend='PyPI', + name="test_project", + homepage="https://example.com/test_project", + backend="PyPI", ) - self.distro = models.Distro(name='Fedora') + self.distro = models.Distro(name="Fedora") self.package = models.Packages( - distro_name=self.distro.name, project=self.project, package_name='test-project') + distro_name=self.distro.name, + project=self.project, + package_name="test-project", + ) # Add a regular user and an admin user session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) - session.add_all([admin_social_auth, self.admin, self.distro, self.project, self.package]) + session.add_all( + [admin_social_auth, self.admin, self.distro, self.project, self.package] + ) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -396,50 +395,54 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users cannot GET the delete project mapping view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/1/delete/Fedora/test-project') + output = self.client.get("/project/1/delete/Fedora/test-project") self.assertEqual(401, output.status_code) def test_non_admin_post(self): """Assert non-admin users cannot POST to the delete project mapping view.""" with login_user(self.flask_app, self.user): - output = self.client.post('/project/1/delete/Fedora/test-project') + output = self.client.post("/project/1/delete/Fedora/test-project") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can GET the delete project mapping view.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/Fedora/test-project') + output = self.client.get("/project/1/delete/Fedora/test-project") self.assertEqual(200, output.status_code) def test_missing_project(self): """Assert HTTP 404 is returned if the project doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/42/delete/Fedora/test-project') + output = self.client.get("/project/42/delete/Fedora/test-project") self.assertEqual(404, output.status_code) def test_missing_distro(self): """Assert HTTP 404 is returned if the distro doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/LFS/test-project') + output = self.client.get("/project/1/delete/LFS/test-project") self.assertEqual(404, output.status_code) def test_missing_package(self): """Assert HTTP 404 is returned if the package doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/Fedora/some-package') + output = self.client.get("/project/1/delete/Fedora/some-package") self.assertEqual(404, output.status_code) def test_admin_post(self): """Assert admin users can delete project mappings.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/Fedora/test-project') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'confirm': True, 'csrf_token': csrf_token} + output = self.client.get("/project/1/delete/Fedora/test-project") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"confirm": True, "csrf_token": csrf_token} with fml_testing.mock_sends(anitya_schema.ProjectMapDeleted): output = self.client.post( - '/project/1/delete/Fedora/test-project', data=data, follow_redirects=True) + "/project/1/delete/Fedora/test-project", + data=data, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) self.assertEqual(0, len(models.Packages.query.all())) @@ -447,13 +450,17 @@ def test_admin_post(self): def test_admin_post_unconfirmed(self): """Assert failing to confirm the action results in no change.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/Fedora/test-project') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + output = self.client.get("/project/1/delete/Fedora/test-project") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"csrf_token": csrf_token} output = self.client.post( - '/project/1/delete/Fedora/test-project', data=data, follow_redirects=True) + "/project/1/delete/Fedora/test-project", + data=data, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) self.assertEqual(1, len(models.Packages.query.all())) @@ -468,35 +475,35 @@ def setUp(self): # Add a project with a version to delete. self.project = models.Project( - name='test_project', - homepage='https://example.com/test_project', - backend='PyPI', + name="test_project", + homepage="https://example.com/test_project", + backend="PyPI", + ) + self.project_version = models.ProjectVersion( + project=self.project, version="1.0.0" ) - self.project_version = models.ProjectVersion(project=self.project, version='1.0.0') # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) - session.add_all([admin_social_auth, self.admin, self.project, self.project_version]) + session.add_all( + [admin_social_auth, self.admin, self.project, self.project_version] + ) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -505,56 +512,59 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users cannot GET the delete project version view.""" with login_user(self.flask_app, self.user): - output = self.client.get('/project/1/delete/1.0.0') + output = self.client.get("/project/1/delete/1.0.0") self.assertEqual(401, output.status_code) def test_non_admin_post(self): """Assert non-admin users cannot POST to the delete project mapping view.""" with login_user(self.flask_app, self.user): - output = self.client.post('/project/1/delete/1.0.0') + output = self.client.post("/project/1/delete/1.0.0") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can GET the delete project mapping view.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/1.0.0') + output = self.client.get("/project/1/delete/1.0.0") self.assertEqual(200, output.status_code) def test_missing_project(self): """Assert HTTP 404 is returned if the project doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/42/delete/1.0.0') + output = self.client.get("/project/42/delete/1.0.0") self.assertEqual(404, output.status_code) def test_missing_version(self): """Assert HTTP 404 is returned if the project doesn't exist.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/42/delete/9.9.9') + output = self.client.get("/project/42/delete/9.9.9") self.assertEqual(404, output.status_code) def test_admin_post(self): """Assert admin users can delete project mappings.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/1.0.0') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'confirm': True, 'csrf_token': csrf_token} + output = self.client.get("/project/1/delete/1.0.0") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"confirm": True, "csrf_token": csrf_token} with fml_testing.mock_sends(anitya_schema.ProjectVersionDeleted): output = self.client.post( - '/project/1/delete/1.0.0', data=data, follow_redirects=True) + "/project/1/delete/1.0.0", data=data, follow_redirects=True + ) self.assertEqual(200, output.status_code) self.assertEqual(0, len(models.ProjectVersion.query.all())) def test_admin_post_unconfirmed(self): """Assert failing to confirm the action results in no change.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/project/1/delete/1.0.0') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] - data = {'csrf_token': csrf_token} + output = self.client.get("/project/1/delete/1.0.0") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] + data = {"csrf_token": csrf_token} - output = self.client.post('/project/1/delete/1.0.0', data=data) + output = self.client.post("/project/1/delete/1.0.0", data=data) self.assertEqual(302, output.status_code) self.assertEqual(1, len(models.ProjectVersion.query.all())) @@ -567,38 +577,48 @@ def setUp(self): session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) self.project1 = models.Project( - name='test_project', homepage='https://example.com/test_project', backend='PyPI') + name="test_project", + homepage="https://example.com/test_project", + backend="PyPI", + ) self.project2 = models.Project( - name='project2', homepage='https://example.com/project2', backend='PyPI') + name="project2", homepage="https://example.com/project2", backend="PyPI" + ) self.flag1 = models.ProjectFlag( - reason='I wanted to flag it', user='user', project=self.project1) + reason="I wanted to flag it", user="user", project=self.project1 + ) self.flag2 = models.ProjectFlag( - reason='This project is wrong', user='user', project=self.project2) + reason="This project is wrong", user="user", project=self.project2 + ) session.add_all( - [admin_social_auth, self.admin, self.project1, self.project2, self.flag1, self.flag2]) + [ + admin_social_auth, + self.admin, + self.project1, + self.project2, + self.flag1, + self.flag2, + ] + ) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -607,50 +627,50 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users can't see flags.""" with login_user(self.flask_app, self.user): - output = self.client.get('/flags') + output = self.client.get("/flags") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can see the flags.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/flags') + output = self.client.get("/flags") self.assertEqual(200, output.status_code) - self.assertTrue(b'I wanted to flag it' in output.data) - self.assertTrue(b'This project is wrong' in output.data) + self.assertTrue(b"I wanted to flag it" in output.data) + self.assertTrue(b"This project is wrong" in output.data) def test_pages(self): """Assert admin users can see the flags.""" with login_user(self.flask_app, self.admin): - page_one = self.client.get('/flags?limit=1&page=1') + page_one = self.client.get("/flags?limit=1&page=1") self.assertEqual(200, page_one.status_code) self.assertTrue( - b'I wanted to flag it' in page_one.data or - b'This project is wrong' in page_one.data + b"I wanted to flag it" in page_one.data + or b"This project is wrong" in page_one.data ) self.assertFalse( - b'I wanted to flag it' in page_one.data and - b'This project is wrong' in page_one.data + b"I wanted to flag it" in page_one.data + and b"This project is wrong" in page_one.data ) def test_from_date(self): """Assert admin users can see the flags.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/flags?from_date=2017-07-01') + output = self.client.get("/flags?from_date=2017-07-01") self.assertEqual(200, output.status_code) - self.assertTrue(b'I wanted to flag it' in output.data) - self.assertTrue(b'This project is wrong' in output.data) + self.assertTrue(b"I wanted to flag it" in output.data) + self.assertTrue(b"This project is wrong" in output.data) def test_from_date_future(self): """Assert admin users can see the flags.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/flags?from_date=2200-07-01') + output = self.client.get("/flags?from_date=2200-07-01") self.assertEqual(200, output.status_code) - self.assertFalse(b'I wanted to flag it' in output.data) - self.assertFalse(b'This project is wrong' in output.data) + self.assertFalse(b"I wanted to flag it" in output.data) + self.assertFalse(b"This project is wrong" in output.data) class SetFlagStateTests(DatabaseTestCase): @@ -661,38 +681,48 @@ def setUp(self): session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) self.project1 = models.Project( - name='test_project', homepage='https://example.com/test_project', backend='PyPI') + name="test_project", + homepage="https://example.com/test_project", + backend="PyPI", + ) self.project2 = models.Project( - name='project2', homepage='https://example.com/project2', backend='PyPI') + name="project2", homepage="https://example.com/project2", backend="PyPI" + ) self.flag1 = models.ProjectFlag( - reason='I wanted to flag it', user='user', project=self.project1) + reason="I wanted to flag it", user="user", project=self.project1 + ) self.flag2 = models.ProjectFlag( - reason='This project is wrong', user='user', project=self.project2) + reason="This project is wrong", user="user", project=self.project2 + ) session.add_all( - [admin_social_auth, self.admin, self.project1, self.project2, self.flag1, self.flag2]) + [ + admin_social_auth, + self.admin, + self.project1, + self.project2, + self.flag1, + self.flag2, + ] + ) session.commit() mock_config = mock.patch.dict( - models.anitya_config, {'ANITYA_WEB_ADMINS': [six.text_type(self.admin.id)]}) + models.anitya_config, {"ANITYA_WEB_ADMINS": [six.text_type(self.admin.id)]} + ) mock_config.start() self.addCleanup(mock_config.stop) @@ -701,34 +731,38 @@ def setUp(self): def test_non_admin_post(self): """Assert non-admin users can't set flags.""" with login_user(self.flask_app, self.user): - output = self.client.post('/flags/1/set/closed') + output = self.client.post("/flags/1/set/closed") self.assertEqual(401, output.status_code) def test_bad_state(self): """Assert an invalid stat results in HTTP 422.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/flags/1/set/deferred') + output = self.client.post("/flags/1/set/deferred") self.assertEqual(422, output.status_code) def test_missing(self): """Assert trying to set the state of a non-existent flag results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/flags/42/set/closed') + output = self.client.post("/flags/42/set/closed") self.assertEqual(404, output.status_code) def test_set_flag(self): """Assert trying to set the state of a non-existent flag results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/flags') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/flags") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] with fml_testing.mock_sends(anitya_schema.ProjectFlagSet): output = self.client.post( - '/flags/1/set/closed', data={'csrf_token': csrf_token}, follow_redirects=True) + "/flags/1/set/closed", + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'Flag 1 set to closed' in output.data) + self.assertTrue(b"Flag 1 set to closed" in output.data) class BrowseUsersTests(DatabaseTestCase): @@ -739,25 +773,21 @@ def setUp(self): session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin', admin=True) + self.admin = models.User( + email="admin@example.com", username="admin", admin=True + ) admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) - session.add_all( - [admin_social_auth, self.admin]) + session.add_all([admin_social_auth, self.admin]) session.commit() self.client = self.flask_app.test_client() @@ -765,239 +795,229 @@ def setUp(self): def test_non_admin_get(self): """Assert non-admin users can't see users.""" with login_user(self.flask_app, self.user): - output = self.client.get('/users') + output = self.client.get("/users") self.assertEqual(401, output.status_code) def test_admin_get(self): """Assert admin users can see the users.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') + output = self.client.get("/users") self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) def test_pages(self): """Assert admin users can see the users.""" with login_user(self.flask_app, self.admin): - page_one = self.client.get('/users?limit=1&page=1') + page_one = self.client.get("/users?limit=1&page=1") self.assertEqual(200, page_one.status_code) - self.assertTrue(b'user@fedoraproject.org' in page_one.data) - self.assertFalse(b'admin@example.com' in page_one.data) + self.assertTrue(b"user@fedoraproject.org" in page_one.data) + self.assertFalse(b"admin@example.com" in page_one.data) def test_pagination_offset(self): """Assert offset is calculated when page is > 1.""" with login_user(self.flask_app, self.admin): - page = self.client.get('/users?limit=1&page=2') + page = self.client.get("/users?limit=1&page=2") self.assertEqual(200, page.status_code) - self.assertFalse(b'user@fedoraproject.org' in page.data) - self.assertTrue(b'admin@example.com' in page.data) + self.assertFalse(b"user@fedoraproject.org" in page.data) + self.assertTrue(b"admin@example.com" in page.data) def test_pagination_limit_zero(self): """Assert limit is not used when set to 0.""" with login_user(self.flask_app, self.admin): - page = self.client.get('/users?limit=0&page=1') + page = self.client.get("/users?limit=0&page=1") self.assertEqual(200, page.status_code) - self.assertTrue(b'user@fedoraproject.org' in page.data) - self.assertTrue(b'admin@example.com' in page.data) + self.assertTrue(b"user@fedoraproject.org" in page.data) + self.assertTrue(b"admin@example.com" in page.data) def test_pagination_limit_negative(self): """Assert limit is not used when set to negative value.""" with login_user(self.flask_app, self.admin): - page = self.client.get('/users?limit=-1') + page = self.client.get("/users?limit=-1") self.assertEqual(200, page.status_code) - self.assertTrue(b'user@fedoraproject.org' in page.data) - self.assertTrue(b'admin@example.com' in page.data) + self.assertTrue(b"user@fedoraproject.org" in page.data) + self.assertTrue(b"admin@example.com" in page.data) def test_pagination_invalid_page(self): """Assert pagination returns first page on invalid value.""" with login_user(self.flask_app, self.admin): - page_one = self.client.get('/users?limit=1&page=dummy') + page_one = self.client.get("/users?limit=1&page=dummy") self.assertEqual(200, page_one.status_code) - self.assertTrue(b'user@fedoraproject.org' in page_one.data) - self.assertFalse(b'admin@example.com' in page_one.data) + self.assertTrue(b"user@fedoraproject.org" in page_one.data) + self.assertFalse(b"admin@example.com" in page_one.data) def test_pagination_invalid_limit(self): """Assert pagination sets limit to default value on invalid input value.""" with login_user(self.flask_app, self.admin): - page_one = self.client.get('/users?limit=dummy&page=1') + page_one = self.client.get("/users?limit=dummy&page=1") self.assertEqual(200, page_one.status_code) - self.assertTrue(b'user@fedoraproject.org' in page_one.data) - self.assertTrue(b'admin@example.com' in page_one.data) + self.assertTrue(b"user@fedoraproject.org" in page_one.data) + self.assertTrue(b"admin@example.com" in page_one.data) def test_filter_user_id(self): """Assert filter by user_id works.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?user_id={}'.format(six.text_type(self.admin.id))) + output = self.client.get( + "/users?user_id={}".format(six.text_type(self.admin.id)) + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_user_id_wrong(self): """Assert filter by wrong user_id returns nothing.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?user_id=dummy') + output = self.client.get("/users?user_id=dummy") self.assertEqual(200, output.status_code) - self.assertFalse(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_username(self): """Assert filter by username works.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?username={}'.format(self.admin.username)) + output = self.client.get("/users?username={}".format(self.admin.username)) self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_username_wrong(self): """Assert filter by wrong username returns nothing.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?username=dummy') + output = self.client.get("/users?username=dummy") self.assertEqual(200, output.status_code) - self.assertFalse(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_email(self): """Assert filter by email works.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?email={}'.format(self.admin.email)) + output = self.client.get("/users?email={}".format(self.admin.email)) self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_email_wrong(self): """Assert filter by wrong email returns nothing.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?email=dummy') + output = self.client.get("/users?email=dummy") self.assertEqual(200, output.status_code) - self.assertFalse(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_admin_true(self): """Assert filter by admin flag works.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?admin=True') + output = self.client.get("/users?admin=True") self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) def test_filter_admin_false(self): """Assert filter by admin flag works.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?admin=False') + output = self.client.get("/users?admin=False") self.assertEqual(200, output.status_code) - self.assertFalse(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) def test_filter_admin_wrong(self): """Assert filter by wrong admin flag returns everything.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users?admin=dummy') + output = self.client.get("/users?admin=dummy") self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) def test_filter_active_true(self): """Assert filter by active flag works.""" # Add a inactive user user = models.User( - email='inactive@fedoraproject.org', - username='inactive', - active=False - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user + email="inactive@fedoraproject.org", username="inactive", active=False ) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() with login_user(self.flask_app, self.admin): - output = self.client.get('/users?active=True') + output = self.client.get("/users?active=True") self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) - self.assertFalse(b'inactive@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) + self.assertFalse(b"inactive@fedoraproject.org" in output.data) def test_filter_active_false(self): """Assert filter by active flag works.""" # Add a inactive user user = models.User( - email='inactive@fedoraproject.org', - username='inactive', - active=False - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user + email="inactive@fedoraproject.org", username="inactive", active=False ) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() with login_user(self.flask_app, self.admin): - output = self.client.get('/users?active=False') + output = self.client.get("/users?active=False") self.assertEqual(200, output.status_code) - self.assertFalse(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) - self.assertTrue(b'inactive@fedoraproject.org' in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) + self.assertTrue(b"inactive@fedoraproject.org" in output.data) def test_filter_active_wrong(self): """Assert filter by wrong active flag returns everything.""" # Add a inactive user user = models.User( - email='inactive@fedoraproject.org', - username='inactive', - active=False - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user + email="inactive@fedoraproject.org", username="inactive", active=False ) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user) self.session.add(user_social_auth) self.session.commit() with login_user(self.flask_app, self.admin): - output = self.client.get('/users?active=dummy') + output = self.client.get("/users?active=dummy") self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) - self.assertTrue(b'inactive@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) + self.assertTrue(b"inactive@fedoraproject.org" in output.data) def test_sql_exception(self): """ Assert that SQL exception is handled correctly.""" with mock.patch.object( - Query, 'filter_by', mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None])): + Query, + "filter_by", + mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None]), + ): with login_user(self.flask_app, self.admin): - output = self.client.get('/users?user_id=dummy') + output = self.client.get("/users?user_id=dummy") self.assertEqual(200, output.status_code) - self.assertTrue(b'SQLError' in output.data) - self.assertFalse(b'admin@example.com' in output.data) - self.assertFalse(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"SQLError" in output.data) + self.assertFalse(b"admin@example.com" in output.data) + self.assertFalse(b"user@fedoraproject.org" in output.data) class SetUserAdminStateTests(DatabaseTestCase): @@ -1008,24 +1028,20 @@ def setUp(self): session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin', admin=True) + self.admin = models.User( + email="admin@example.com", username="admin", admin=True + ) admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) - session.add_all( - [admin_social_auth, self.admin]) + session.add_all([admin_social_auth, self.admin]) session.commit() self.client = self.flask_app.test_client() @@ -1033,115 +1049,128 @@ def setUp(self): def test_non_admin_post(self): """Assert non-admin users can't set flags.""" with login_user(self.flask_app, self.user): - output = self.client.post('/users/{}/admin/True'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/admin/True".format(six.text_type(self.user.id)) + ) self.assertEqual(401, output.status_code) def test_bad_state(self): """Assert an invalid state results in HTTP 422.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/{}/admin/wrong'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/admin/wrong".format(six.text_type(self.user.id)) + ) self.assertEqual(422, output.status_code) def test_missing_state(self): """Assert an missing state results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/{}/admin/'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/admin/".format(six.text_type(self.user.id)) + ) self.assertEqual(404, output.status_code) def test_missing_user(self): """Assert trying to set the state of a non-existent user results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/42/admin/true') + output = self.client.post("/users/42/admin/true") self.assertEqual(404, output.status_code) def test_set_admin(self): """Assert that admin flag is set correctly.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] output = self.client.post( - '/users/{}/admin/True'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/admin/True".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'User user is now admin' in output.data) + self.assertTrue(b"User user is now admin" in output.data) self.assertTrue(self.user.admin) def test_sql_exception(self): """ Assert that SQL exception is handled correctly.""" with mock.patch.object( - self.session, 'add', mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None])): + self.session, + "add", + mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None]), + ): with login_user(self.flask_app, self.admin): - output = self.client.get('/users') + output = self.client.get("/users") csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] output = self.client.post( - '/users/{}/admin/True'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/admin/True".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'SQLError' in output.data) + self.assertTrue(b"SQLError" in output.data) self.assertFalse(self.user.admin) def test_form_not_valid(self): """ Assert that invalid form will do nothing.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] - with mock.patch('anitya.forms.ConfirmationForm') as mock_form: + with mock.patch("anitya.forms.ConfirmationForm") as mock_form: mock_form.return_value.validate_on_submit.return_value = False output = self.client.post( - '/users/{}/admin/True'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/admin/True".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) self.assertFalse(self.user.admin) def test_remove_admin(self): """Assert that admin flag is removed correctly.""" self.user.admin = True with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] self.assertTrue(self.user.admin) output = self.client.post( - '/users/{}/admin/False'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/admin/False".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'User user is not admin anymore' in output.data) + self.assertTrue(b"User user is not admin anymore" in output.data) self.assertFalse(self.user.admin) def test_remove_admin_current_user(self): """Assert that admin flag is removed correctly.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] output = self.client.post( - '/users/{}/admin/False'.format( - six.text_type(self.admin.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/admin/False".format(six.text_type(self.admin.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(401, output.status_code) self.assertFalse(self.admin.admin) @@ -1155,13 +1184,9 @@ def setUp(self): session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -1169,24 +1194,21 @@ def setUp(self): # Add inactive user self.inactive_user = models.User( - email='inactive@fedoraproject.org', - username='inactive_user', - active=False + email="inactive@fedoraproject.org", username="inactive_user", active=False ) user_social_auth = social_models.UserSocialAuth( - user_id=self.inactive_user.id, - user=self.inactive_user + user_id=self.inactive_user.id, user=self.inactive_user ) session.add(self.inactive_user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin', admin=True) + self.admin = models.User( + email="admin@example.com", username="admin", admin=True + ) admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) - session.add_all( - [admin_social_auth, self.admin]) + session.add_all([admin_social_auth, self.admin]) session.commit() self.client = self.flask_app.test_client() @@ -1194,100 +1216,111 @@ def setUp(self): def test_non_admin_post(self): """Assert non-admin users can't set flags.""" with login_user(self.flask_app, self.user): - output = self.client.post('/users/{}/active/True'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/active/True".format(six.text_type(self.user.id)) + ) self.assertEqual(401, output.status_code) def test_bad_state(self): """Assert an invalid state results in HTTP 422.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/{}/active/wrong'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/active/wrong".format(six.text_type(self.user.id)) + ) self.assertEqual(422, output.status_code) def test_missing_state(self): """Assert an missing state results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/{}/active/'.format( - six.text_type(self.user.id) - )) + output = self.client.post( + "/users/{}/active/".format(six.text_type(self.user.id)) + ) self.assertEqual(404, output.status_code) def test_missing_user(self): """Assert trying to set the state of a non-existent user results in HTTP 404.""" with login_user(self.flask_app, self.admin): - output = self.client.post('/users/42/active/true') + output = self.client.post("/users/42/active/true") self.assertEqual(404, output.status_code) def test_sql_exception(self): """ Assert that SQL exception is handled correctly.""" with mock.patch.object( - self.session, 'add', mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None])): + self.session, + "add", + mock.Mock(side_effect=[SQLAlchemyError("SQLError"), None]), + ): with login_user(self.flask_app, self.admin): - output = self.client.get('/users') + output = self.client.get("/users") csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + b'name="csrf_token" type="hidden" value="' + )[1].split(b'">')[0] output = self.client.post( - '/users/{}/active/False'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/active/False".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'SQLError' in output.data) + self.assertTrue(b"SQLError" in output.data) self.assertTrue(self.user.active) def test_form_not_valid(self): """ Assert that invalid form will do nothing.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] - with mock.patch('anitya.forms.ConfirmationForm') as mock_form: + with mock.patch("anitya.forms.ConfirmationForm") as mock_form: mock_form.return_value.validate_on_submit.return_value = False output = self.client.post( - '/users/{}/active/False'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/active/False".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'admin@example.com' in output.data) - self.assertTrue(b'user@fedoraproject.org' in output.data) + self.assertTrue(b"admin@example.com" in output.data) + self.assertTrue(b"user@fedoraproject.org" in output.data) self.assertTrue(self.user.active) def test_set_active(self): """Assert that active flag is set correctly.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] output = self.client.post( - '/users/{}/active/True'.format( - six.text_type(self.inactive_user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/active/True".format(six.text_type(self.inactive_user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'User inactive_user is no longer banned' in output.data) + self.assertTrue(b"User inactive_user is no longer banned" in output.data) self.assertTrue(self.inactive_user.active) def test_ban(self): """Assert that active flag is removed correctly.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/users') - csrf_token = output.data.split( - b'name="csrf_token" type="hidden" value="')[1].split(b'">')[0] + output = self.client.get("/users") + csrf_token = output.data.split(b'name="csrf_token" type="hidden" value="')[ + 1 + ].split(b'">')[0] output = self.client.post( - '/users/{}/active/False'.format( - six.text_type(self.user.id) - ), data={'csrf_token': csrf_token}, follow_redirects=True) + "/users/{}/active/False".format(six.text_type(self.user.id)), + data={"csrf_token": csrf_token}, + follow_redirects=True, + ) self.assertEqual(200, output.status_code) - self.assertTrue(b'User user is banned' in output.data) + self.assertTrue(b"User user is banned" in output.data) self.assertFalse(self.user.active) @@ -1298,22 +1331,17 @@ def setUp(self): super(BrowseLogsTests, self).setUp() session = Session() # Add a regular user and an admin user - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) - self.admin = models.User(email='admin@example.com', username='admin') + self.admin = models.User(email="admin@example.com", username="admin") admin_social_auth = social_models.UserSocialAuth( - user_id=self.admin.id, - user=self.admin + user_id=self.admin.id, user=self.admin ) session.add_all([admin_social_auth, self.admin]) @@ -1324,29 +1352,29 @@ def setUp(self): def test_get_logs(self): """Assert logs are shown.""" project = models.Project( - name='best_project', - homepage='https://example.com/best_project', - backend='PyPI', - ecosystem_name='pypi', + name="best_project", + homepage="https://example.com/best_project", + backend="PyPI", + ecosystem_name="pypi", check_successful=True, - logs='Everything allright', + logs="Everything allright", ) self.session.add(project) self.session.commit() with login_user(self.flask_app, self.user): - output = self.client.get('/logs') + output = self.client.get("/logs") self.assertEqual(200, output.status_code) - self.assertTrue(b'best_project' in output.data) - self.assertTrue(b'OK' in output.data) - self.assertTrue(b'Everything allright' in output.data) + self.assertTrue(b"best_project" in output.data) + self.assertTrue(b"OK" in output.data) + self.assertTrue(b"Everything allright" in output.data) def test_incorrect_page(self): """Assert exception is handled correctly.""" with login_user(self.flask_app, self.admin): - output = self.client.get('/logs?page=a') + output = self.client.get("/logs?page=a") self.assertEqual(200, output.status_code) - self.assertTrue(b'/logs?page=1' in output.data) + self.assertTrue(b"/logs?page=1" in output.data) diff --git a/anitya/tests/test_flask_api.py b/anitya/tests/test_flask_api.py index 92019f752..05bad9204 100644 --- a/anitya/tests/test_flask_api.py +++ b/anitya/tests/test_flask_api.py @@ -19,17 +19,22 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the flask API. -''' +""" import json import unittest from anitya.db import models from anitya.lib.backends import REGEX -from anitya.tests.base import (DatabaseTestCase, create_distro, create_project, - create_package, create_ecosystem_projects) +from anitya.tests.base import ( + DatabaseTestCase, + create_distro, + create_project, + create_package, + create_ecosystem_projects, +) # Py3 compatibility: UTF-8 decoding and JSON decoding may be separate steps @@ -44,28 +49,30 @@ def setUp(self): """ Set up the environnment, ran before every tests. """ super(AnityaWebAPItests, self).setUp() - self.flask_app.config['TESTING'] = True + self.flask_app.config["TESTING"] = True self.app = self.flask_app.test_client() def test_api_docs_no_slash(self): """Assert the legacy /api endpoint redirects to docs.""" - output = self.app.get('/api') + output = self.app.get("/api") self.assertEqual(302, output.status_code) self.assertEqual( - 'http://localhost/static/docs/api.html', output.headers['Location']) + "http://localhost/static/docs/api.html", output.headers["Location"] + ) def test_api_docs_with_slash(self): """Assert the legacy /api/ endpoint redirects to docs.""" - output = self.app.get('/api/') + output = self.app.get("/api/") self.assertEqual(302, output.status_code) self.assertEqual( - 'http://localhost/static/docs/api.html', output.headers['Location']) + "http://localhost/static/docs/api.html", output.headers["Location"] + ) def test_api_projects(self): """ Test the api_projects function of the API. """ create_distro(self.session) - output = self.app.get('/api/projects') + output = self.app.get("/api/projects") self.assertEqual(output.status_code, 200) data = _read_json(output) @@ -74,13 +81,13 @@ def test_api_projects(self): create_project(self.session) - output = self.app.get('/api/projects/') + output = self.app.get("/api/projects/") self.assertEqual(output.status_code, 200) data = _read_json(output) - for key in range(len(data['projects'])): - del(data['projects'][key]['created_on']) - del(data['projects'][key]['updated_on']) + for key in range(len(data["projects"])): + del (data["projects"][key]["created_on"]) + del (data["projects"][key]["updated_on"]) exp = { "projects": [ @@ -93,7 +100,7 @@ def test_api_projects(self): "regex": "DEFAULT", "version": None, "version_url": "https://www.geany.org/Download/Releases", - "versions": [] + "versions": [], }, { "id": 3, @@ -104,7 +111,7 @@ def test_api_projects(self): "regex": None, "version": None, "version_url": None, - "versions": [] + "versions": [], }, { "id": 2, @@ -115,21 +122,21 @@ def test_api_projects(self): "regex": "DEFAULT", "version": None, "version_url": "https://subsurface-divelog.org/downloads/", - "versions": [] - } + "versions": [], + }, ], - "total": 3 + "total": 3, } self.assertEqual(data, exp) - output = self.app.get('/api/projects/?pattern=ge') + output = self.app.get("/api/projects/?pattern=ge") self.assertEqual(output.status_code, 200) data = _read_json(output) - for key in range(len(data['projects'])): - del(data['projects'][key]['created_on']) - del(data['projects'][key]['updated_on']) + for key in range(len(data["projects"])): + del (data["projects"][key]["created_on"]) + del (data["projects"][key]["updated_on"]) exp = { "projects": [ @@ -143,20 +150,20 @@ def test_api_projects(self): "version": None, "version_url": "https://www.geany.org/Download/Releases", "versions": [], - }, + } ], - "total": 1 + "total": 1, } self.assertEqual(data, exp) - output = self.app.get('/api/projects/?homepage=https://www.geany.org/') + output = self.app.get("/api/projects/?homepage=https://www.geany.org/") self.assertEqual(output.status_code, 200) data = _read_json(output) - for key in range(len(data['projects'])): - del(data['projects'][key]['created_on']) - del(data['projects'][key]['updated_on']) + for key in range(len(data["projects"])): + del (data["projects"][key]["created_on"]) + del (data["projects"][key]["updated_on"]) exp = { "projects": [ @@ -170,38 +177,40 @@ def test_api_projects(self): "version": None, "version_url": "https://www.geany.org/Download/Releases", "versions": [], - }, + } ], - "total": 1 + "total": 1, } self.assertEqual(data, exp) - output = self.app.get('/api/projects/?pattern=foo&homepage=bar') + output = self.app.get("/api/projects/?pattern=foo&homepage=bar") self.assertEqual(output.status_code, 400) def test_api_packages_wiki_list(self): """ Test the api_packages_wiki_list function of the API. """ create_distro(self.session) - output = self.app.get('/api/packages/wiki/') + output = self.app.get("/api/packages/wiki/") self.assertEqual(output.status_code, 200) - self.assertEqual(output.data, b'') + self.assertEqual(output.data, b"") create_project(self.session) create_package(self.session) - output = self.app.get('/api/packages/wiki/') + output = self.app.get("/api/packages/wiki/") self.assertEqual(output.status_code, 200) - exp = b"* geany DEFAULT https://www.geany.org/Download/Releases\n"\ + exp = ( + b"* geany DEFAULT https://www.geany.org/Download/Releases\n" b"* subsurface DEFAULT https://subsurface-divelog.org/downloads/" + ) self.assertEqual(output.data, exp) def test_api_projects_names(self): """ Test the api_projects_names function of the API. """ create_distro(self.session) - output = self.app.get('/api/projects/names') + output = self.app.get("/api/projects/names") self.assertEqual(output.status_code, 200) data = _read_json(output) @@ -211,37 +220,25 @@ def test_api_projects_names(self): create_project(self.session) create_package(self.session) - output = self.app.get('/api/projects/names/') + output = self.app.get("/api/projects/names/") self.assertEqual(output.status_code, 200) data = _read_json(output) - exp = { - "projects": [ - "geany", - "R2spec", - "subsurface" - ], - "total": 3 - } + exp = {"projects": ["geany", "R2spec", "subsurface"], "total": 3} self.assertEqual(data, exp) - output = self.app.get('/api/projects/names/?pattern=ge') + output = self.app.get("/api/projects/names/?pattern=ge") self.assertEqual(output.status_code, 200) data = _read_json(output) - exp = { - "projects": [ - "geany" - ], - "total": 1 - } + exp = {"projects": ["geany"], "total": 1} self.assertEqual(data, exp) def test_api_get_version(self): """ Test the api_get_version function of the API. """ create_distro(self.session) - output = self.app.post('/api/version/get') + output = self.app.post("/api/version/get") self.assertEqual(output.status_code, 400) data = _read_json(output) @@ -251,8 +248,8 @@ def test_api_get_version(self): create_project(self.session) create_package(self.session) - data = {'id': 10} - output = self.app.post('/api/version/get', data=data) + data = {"id": 10} + output = self.app.post("/api/version/get", data=data) self.assertEqual(output.status_code, 404) data = _read_json(output) @@ -265,8 +262,8 @@ def test_api_get_version(self): self.session.add(project) self.session.commit() - data = {'id': 1} - output = self.app.post('/api/version/get', data=data) + data = {"id": 1} + output = self.app.post("/api/version/get", data=data) self.assertEqual(output.status_code, 400) data = _read_json(output) @@ -274,9 +271,9 @@ def test_api_get_version(self): "error": [ "geany: no upstream version found. " "- https://www.geany.org/Down - " - " " + REGEX % ({'name': 'geany'}) + " " + REGEX % ({"name": "geany"}) ], - "output": "notok" + "output": "notok", } self.assertEqual(data, exp) @@ -286,12 +283,12 @@ def test_api_get_version(self): self.session.add(project) self.session.commit() - data = {'id': 1} - output = self.app.post('/api/version/get', data=data) + data = {"id": 1} + output = self.app.post("/api/version/get", data=data) self.assertEqual(output.status_code, 200) data = _read_json(output) - del(data['created_on']) - del(data['updated_on']) + del (data["created_on"]) + del (data["updated_on"]) exp = { "id": 1, @@ -303,12 +300,7 @@ def test_api_get_version(self): "version": "1.33", "version_url": "https://www.geany.org/Download/Releases", "versions": ["1.33"], - "packages": [ - { - "distro": "Fedora", - "package_name": "geany" - } - ], + "packages": [{"distro": "Fedora", "package_name": "geany"}], } self.assertEqual(data, exp) @@ -316,10 +308,10 @@ def test_api_get_version(self): def test_api_get_project(self): """ Test the api_get_project function of the API. """ create_distro(self.session) - output = self.app.get('/api/project/') + output = self.app.get("/api/project/") self.assertEqual(output.status_code, 404) - output = self.app.get('/api/project/10') + output = self.app.get("/api/project/10") self.assertEqual(output.status_code, 404) data = _read_json(output) @@ -329,15 +321,15 @@ def test_api_get_project(self): create_project(self.session) create_package(self.session) - output = self.app.get('/api/project/10') + output = self.app.get("/api/project/10") self.assertEqual(output.status_code, 404) - output = self.app.get('/api/project/1') + output = self.app.get("/api/project/1") self.assertEqual(output.status_code, 200) data = _read_json(output) - del(data['created_on']) - del(data['updated_on']) + del (data["created_on"]) + del (data["updated_on"]) exp = { "id": 1, @@ -345,16 +337,11 @@ def test_api_get_project(self): "homepage": "https://www.geany.org/", "ecosystem": "https://www.geany.org/", "name": "geany", - "regex": 'DEFAULT', + "regex": "DEFAULT", "version": None, - "version_url": 'https://www.geany.org/Download/Releases', + "version_url": "https://www.geany.org/Download/Releases", "versions": [], - "packages": [ - { - "distro": "Fedora", - "package_name": "geany" - } - ], + "packages": [{"distro": "Fedora", "package_name": "geany"}], } self.assertEqual(exp, data) @@ -362,36 +349,35 @@ def test_api_get_project(self): def test_api_get_project_distro(self): """ Test the api_get_project_distro function of the API. """ create_distro(self.session) - output = self.app.get('/api/project/Fedora/geany') + output = self.app.get("/api/project/Fedora/geany") self.assertEqual(output.status_code, 404) data = _read_json(output) exp = { - "error": "No package \"geany\" found in distro \"Fedora\"", - "output": "notok" + "error": 'No package "geany" found in distro "Fedora"', + "output": "notok", } self.assertEqual(data, exp) create_project(self.session) create_package(self.session) - output = self.app.get('/api/project/Fedora/gnome-terminal/') + output = self.app.get("/api/project/Fedora/gnome-terminal/") self.assertEqual(output.status_code, 404) data = _read_json(output) exp = { - "error": "No package \"gnome-terminal\" found in distro " - "\"Fedora\"", - "output": "notok" + "error": 'No package "gnome-terminal" found in distro ' '"Fedora"', + "output": "notok", } self.assertEqual(data, exp) - output = self.app.get('/api/project/Fedora/geany/') + output = self.app.get("/api/project/Fedora/geany/") self.assertEqual(output.status_code, 200) data = _read_json(output) - del(data['created_on']) - del(data['updated_on']) + del (data["created_on"]) + del (data["updated_on"]) exp = { "id": 1, @@ -399,16 +385,11 @@ def test_api_get_project_distro(self): "homepage": "https://www.geany.org/", "ecosystem": "https://www.geany.org/", "name": "geany", - "regex": 'DEFAULT', + "regex": "DEFAULT", "version": None, - "version_url": 'https://www.geany.org/Download/Releases', + "version_url": "https://www.geany.org/Download/Releases", "versions": [], - "packages": [ - { - "distro": "Fedora", - "package_name": "geany" - } - ], + "packages": [{"distro": "Fedora", "package_name": "geany"}], } self.assertEqual(data, exp) @@ -416,34 +397,34 @@ def test_api_get_project_distro(self): def test_api_get_project_by_ecosystem(self): """ Test the api_get_project_ecosystem function of the API. """ create_distro(self.session) - output = self.app.get('/api/by_ecosystem/pypi/pypi_and_npm') + output = self.app.get("/api/by_ecosystem/pypi/pypi_and_npm") self.assertEqual(output.status_code, 404) data = _read_json(output) exp = { "error": 'No project "pypi_and_npm" found in ecosystem "pypi"', - "output": "notok" + "output": "notok", } self.assertEqual(data, exp) create_ecosystem_projects(self.session) - output = self.app.get('/api/by_ecosystem/pypi/not-a-project') + output = self.app.get("/api/by_ecosystem/pypi/not-a-project") self.assertEqual(output.status_code, 404) data = _read_json(output) exp = { "error": 'No project "not-a-project" found in ecosystem "pypi"', - "output": "notok" + "output": "notok", } self.assertEqual(data, exp) - output = self.app.get('/api/by_ecosystem/pypi/pypi_and_npm') + output = self.app.get("/api/by_ecosystem/pypi/pypi_and_npm") self.assertEqual(output.status_code, 200) data = _read_json(output) - del(data['created_on']) - del(data['updated_on']) + del (data["created_on"]) + del (data["updated_on"]) exp = { "id": 1, @@ -461,6 +442,6 @@ def test_api_get_project_by_ecosystem(self): self.assertEqual(data, exp) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(AnityaWebAPItests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/test_flask_api_v2.py b/anitya/tests/test_flask_api_v2.py index 766dbcc14..bb2bb2970 100644 --- a/anitya/tests/test_flask_api_v2.py +++ b/anitya/tests/test_flask_api_v2.py @@ -19,16 +19,16 @@ # of Red Hat, Inc. # -''' +""" Tests for the Flask-RESTful based v2 API -''' +""" from __future__ import unicode_literals import json from social_flask_sqlalchemy import models as social_models from anitya.db import Session, models -from .base import (DatabaseTestCase, create_project) +from .base import DatabaseTestCase, create_project # Py3 compatibility: UTF-8 decoding and JSON decoding may be separate steps @@ -43,85 +43,88 @@ def setUp(self): super(PackagesResourceGetTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) self.api_token = models.ApiToken(user=self.user) - fedora = models.Distro('Fedora') - debian = models.Distro('Debian') - jcline_linux = models.Distro('jcline linux') + fedora = models.Distro("Fedora") + debian = models.Distro("Debian") + jcline_linux = models.Distro("jcline linux") session.add_all([self.api_token, fedora, debian, jcline_linux]) session.commit() def test_no_packages(self): """Assert querying packages works, even if there are no packages.""" - output = self.app.get('/api/v2/packages/') + output = self.app.get("/api/v2/packages/") self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 25, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 25, "total_items": 0, "items": []} + ) def test_authenticated(self): """Assert the API works when authenticated.""" output = self.app.get( - '/api/v2/packages/', headers={'Authorization': 'Token ' + self.api_token.token}) + "/api/v2/packages/", + headers={"Authorization": "Token " + self.api_token.token}, + ) self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 25, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 25, "total_items": 0, "items": []} + ) def test_packages(self): """Assert packages are returned when they exist.""" project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) fedora_package = models.Packages( - distro_name='Fedora', project=project, package_name='python-requests') + distro_name="Fedora", project=project, package_name="python-requests" + ) debian_package = models.Packages( - distro_name='Debian', project=project, package_name='python-requests') + distro_name="Debian", project=project, package_name="python-requests" + ) jcline_package = models.Packages( - distro_name='jcline linux', project=project, package_name='requests') + distro_name="jcline linux", project=project, package_name="requests" + ) Session.add_all([project, fedora_package, debian_package, jcline_package]) Session.commit() - output = self.app.get('/api/v2/packages/') + output = self.app.get("/api/v2/packages/") self.assertEqual(output.status_code, 200) data = _read_json(output) exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 3, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 3, + "items": [ { "distribution": "Fedora", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" + "ecosystem": "pypi", }, { "distribution": "Debian", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" + "ecosystem": "pypi", }, { "distribution": "jcline linux", "name": "requests", "project": "requests", - "ecosystem": "pypi" + "ecosystem": "pypi", }, - ] + ], } self.assertEqual(data, exp) @@ -129,83 +132,86 @@ def test_packages(self): def test_filter_packages_by_name(self): """Assert filtering packages by name works.""" project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) fedora_package = models.Packages( - distro_name='Fedora', project=project, package_name='python-requests') + distro_name="Fedora", project=project, package_name="python-requests" + ) debian_package = models.Packages( - distro_name='Debian', project=project, package_name='python-requests') + distro_name="Debian", project=project, package_name="python-requests" + ) jcline_package = models.Packages( - distro_name='jcline linux', project=project, package_name='requests') + distro_name="jcline linux", project=project, package_name="requests" + ) Session.add_all([project, fedora_package, debian_package, jcline_package]) Session.commit() - output = self.app.get('/api/v2/packages/?name=python-requests') + output = self.app.get("/api/v2/packages/?name=python-requests") self.assertEqual(output.status_code, 200) data = _read_json(output) exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 2, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 2, + "items": [ { "distribution": "Fedora", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" + "ecosystem": "pypi", }, { "distribution": "Debian", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" + "ecosystem": "pypi", }, - ] + ], } self.assertEqual(data, exp) def test_list_packages_items_per_page_no_items(self): """Assert pagination works and page size is adjustable.""" - api_endpoint = '/api/v2/packages/?items_per_page=1' + api_endpoint = "/api/v2/packages/?items_per_page=1" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 1, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 1, "total_items": 0, "items": []} + ) def test_list_packages_items_per_page(self): """Assert pagination works and page size is adjustable.""" project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) fedora_package = models.Packages( - distro_name='Fedora', project=project, package_name='python-requests') + distro_name="Fedora", project=project, package_name="python-requests" + ) debian_package = models.Packages( - distro_name='Debian', project=project, package_name='python-requests') + distro_name="Debian", project=project, package_name="python-requests" + ) Session.add_all([project, fedora_package, debian_package]) Session.commit() - output = self.app.get('/api/v2/packages/?items_per_page=1') + output = self.app.get("/api/v2/packages/?items_per_page=1") self.assertEqual(output.status_code, 200) data = _read_json(output) exp = { - 'page': 1, - 'items_per_page': 1, - 'total_items': 2, - 'items': [ + "page": 1, + "items_per_page": 1, + "total_items": 2, + "items": [ { "distribution": "Fedora", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" - }, - ] + "ecosystem": "pypi", + } + ], } self.assertEqual(data, exp) @@ -213,32 +219,32 @@ def test_list_packages_items_per_page(self): def test_list_packages_items_per_page_with_page(self): """Assert retrieving other pages works.""" project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) fedora_package = models.Packages( - distro_name='Fedora', project=project, package_name='python-requests') + distro_name="Fedora", project=project, package_name="python-requests" + ) debian_package = models.Packages( - distro_name='Debian', project=project, package_name='python-requests') + distro_name="Debian", project=project, package_name="python-requests" + ) Session.add_all([project, fedora_package, debian_package]) Session.commit() - output = self.app.get('/api/v2/packages/?items_per_page=1&page=2') + output = self.app.get("/api/v2/packages/?items_per_page=1&page=2") self.assertEqual(output.status_code, 200) data = _read_json(output) exp = { - 'page': 2, - 'items_per_page': 1, - 'total_items': 2, - 'items': [ + "page": 2, + "items_per_page": 1, + "total_items": 2, + "items": [ { "distribution": "Debian", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" - }, - ] + "ecosystem": "pypi", + } + ], } self.assertEqual(data, exp) @@ -246,48 +252,48 @@ def test_list_packages_items_per_page_with_page(self): def test_filter_distribution(self): """Assert retrieving other pages works.""" project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) fedora_package = models.Packages( - distro_name='Fedora', project=project, package_name='python-requests') + distro_name="Fedora", project=project, package_name="python-requests" + ) debian_package = models.Packages( - distro_name='Debian', project=project, package_name='python-requests') + distro_name="Debian", project=project, package_name="python-requests" + ) Session.add_all([project, fedora_package, debian_package]) Session.commit() - fedora = self.app.get('/api/v2/packages/?distribution=Fedora') - debian = self.app.get('/api/v2/packages/?distribution=Debian') + fedora = self.app.get("/api/v2/packages/?distribution=Fedora") + debian = self.app.get("/api/v2/packages/?distribution=Debian") self.assertEqual(fedora.status_code, 200) self.assertEqual(debian.status_code, 200) fedora_data = _read_json(fedora) debian_data = _read_json(debian) fedora_exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 1, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 1, + "items": [ { "distribution": "Fedora", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" - }, - ] + "ecosystem": "pypi", + } + ], } debian_exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 1, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 1, + "items": [ { "distribution": "Debian", "name": "python-requests", "project": "requests", - "ecosystem": "pypi" - }, - ] + "ecosystem": "pypi", + } + ], } self.assertEqual(fedora_data, fedora_exp) @@ -295,147 +301,160 @@ def test_filter_distribution(self): def test_list_packages_items_per_page_too_big(self): """Assert unreasonably large items per page results in an error.""" - api_endpoint = '/api/v2/packages/?items_per_page=500' + api_endpoint = "/api/v2/packages/?items_per_page=500" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'items_per_page': u'Value must be less than or equal to 250.'}}) + data, + {"message": {"items_per_page": "Value must be less than or equal to 250."}}, + ) def test_list_packages_items_per_page_negative(self): """Assert a negative value for items_per_page results in an error.""" - api_endpoint = '/api/v2/packages/?items_per_page=-25' + api_endpoint = "/api/v2/packages/?items_per_page=-25" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'items_per_page': u'Value must be greater than or equal to 1.'}}) + data, + { + "message": { + "items_per_page": "Value must be greater than or equal to 1." + } + }, + ) def test_list_packages_items_per_page_non_integer(self): """Assert a non-integer for items_per_page results in an error.""" - api_endpoint = '/api/v2/packages/?items_per_page=twenty' + api_endpoint = "/api/v2/packages/?items_per_page=twenty" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( data, - {u'message': {u'items_per_page': u"invalid literal for int() with base 10: 'twenty'"}} + { + "message": { + "items_per_page": "invalid literal for int() with base 10: 'twenty'" + } + }, ) def test_list_packages_page_negative(self): """Assert a negative value for a page results in an error.""" - api_endpoint = '/api/v2/packages/?page=-25' + api_endpoint = "/api/v2/packages/?page=-25" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'page': u'Value must be greater than or equal to 1.'}}) + data, {"message": {"page": "Value must be greater than or equal to 1."}} + ) def test_list_packages_page_non_integer(self): """Assert a non-integer value for a page results in an error.""" - api_endpoint = '/api/v2/projects/?page=twenty' + api_endpoint = "/api/v2/projects/?page=twenty" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'page': u"invalid literal for int() with base 10: 'twenty'"}}) + data, + {"message": {"page": "invalid literal for int() with base 10: 'twenty'"}}, + ) class PackagesResourcePostTests(DatabaseTestCase): - def setUp(self): super(PackagesResourcePostTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) session.add(user_social_auth) self.api_token = models.ApiToken(user=self.user) self.project = models.Project( - name='requests', - homepage='https://pypi.io/project/requests', - backend='PyPI', + name="requests", homepage="https://pypi.io/project/requests", backend="PyPI" ) - self.fedora = models.Distro('Fedora') + self.fedora = models.Distro("Fedora") session.add_all([self.api_token, self.project, self.fedora]) session.commit() - self.auth = {'Authorization': 'Token ' + self.api_token.token} + self.auth = {"Authorization": "Token " + self.api_token.token} def test_unauthenticated(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - output = self.app.post('/api/v2/packages/') + output = self.app.post("/api/v2/packages/") self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_token(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - output = self.app.post('/api/v2/packages/', headers={'Authorization': 'Token eh'}) + output = self.app.post( + "/api/v2/packages/", headers={"Authorization": "Token eh"} + ) self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_auth_type(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } output = self.app.post( - '/api/v2/packages/', headers={'Authorization': 'Basic ' + self.api_token.token}) + "/api/v2/packages/", + headers={"Authorization": "Basic " + self.api_token.token}, + ) self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_no_token_type(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } output = self.app.post( - '/api/v2/packages/', headers={'Authorization': 'pleaseletmein'}) + "/api/v2/packages/", headers={"Authorization": "pleaseletmein"} + ) self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_request(self): """Assert invalid requests result in a helpful HTTP 400.""" - output = self.app.post('/api/v2/packages/', headers=self.auth) + output = self.app.post("/api/v2/packages/", headers=self.auth) self.assertEqual(output.status_code, 400) # Error details should report the missing required fields @@ -455,14 +474,16 @@ def test_valid_request(self): "distribution": "Fedora", } - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 201) data = _read_json(output) - self.assertEqual({'distribution': 'Fedora', 'name': 'python-requests'}, data) + self.assertEqual({"distribution": "Fedora", "name": "python-requests"}, data) def test_same_package_two_distros(self): """Assert packages can be created.""" - Session.add(models.Distro('Debian')) + Session.add(models.Distro("Debian")) Session.commit() request_data = { "project_ecosystem": "pypi", @@ -471,11 +492,15 @@ def test_same_package_two_distros(self): "distribution": "Fedora", } - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 201) - request_data['distribution'] = 'Debian' - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + request_data["distribution"] = "Debian" + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 201) def test_conflicting_request(self): @@ -487,13 +512,17 @@ def test_conflicting_request(self): "distribution": "Fedora", } - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 201) - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 409) # Error details should report conflicting fields. data = _read_json(output) - self.assertEqual(data, {'error': 'package already exists in distribution'}) + self.assertEqual(data, {"error": "package already exists in distribution"}) def test_missing_distro(self): """Assert a missing distribution results in HTTP 400.""" @@ -504,10 +533,14 @@ def test_missing_distro(self): "distribution": "Mythical Distribution", } - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 400) data = _read_json(output) - self.assertEqual({'error': 'Distribution "Mythical Distribution" not found'}, data) + self.assertEqual( + {"error": 'Distribution "Mythical Distribution" not found'}, data + ) def test_missing_project(self): """Assert a missing project results in HTTP 400.""" @@ -518,26 +551,24 @@ def test_missing_project(self): "distribution": "Fedora", } - output = self.app.post('/api/v2/packages/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/packages/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - {'error': 'Project "requests" in ecosystem "Missing" not found'}, data) + {"error": 'Project "requests" in ecosystem "Missing" not found'}, data + ) class ProjectsResourceGetTests(DatabaseTestCase): - def setUp(self): super(ProjectsResourceGetTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -548,38 +579,44 @@ def setUp(self): def test_no_projects(self): """Assert querying projects works, even if there are no projects.""" - output = self.app.get('/api/v2/projects/') + output = self.app.get("/api/v2/projects/") self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 25, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 25, "total_items": 0, "items": []} + ) def test_authenticated(self): """Assert the API works when authenticated.""" output = self.app.get( - '/api/v2/projects/', headers={'Authorization': 'Token ' + self.api_token.token}) + "/api/v2/projects/", + headers={"Authorization": "Token " + self.api_token.token}, + ) self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 25, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 25, "total_items": 0, "items": []} + ) def test_list_projects(self): """Assert projects are returned when they exist.""" create_project(self.session) - output = self.app.get('/api/v2/projects/') + output = self.app.get("/api/v2/projects/") self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 3, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 3, + "items": [ { "id": 3, "backend": "custom", @@ -589,7 +626,7 @@ def test_list_projects(self): "version": None, "version_url": None, "versions": [], - 'ecosystem': "https://fedorahosted.org/r2spec/", + "ecosystem": "https://fedorahosted.org/r2spec/", }, { "id": 1, @@ -612,8 +649,8 @@ def test_list_projects(self): "version_url": "https://subsurface-divelog.org/downloads/", "versions": [], "ecosystem": "https://subsurface-divelog.org/", - } - ] + }, + ], } self.assertEqual(data, exp) @@ -625,7 +662,7 @@ def test_list_projects_with_same_name(self): project1 = models.Project( name="zlib", homepage="https://hackage.haskell.org/package/zlib", - backend='GitHub', + backend="GitHub", ecosystem_name="https://hackage.haskell.org/package/zlib", ) project2 = models.Project( @@ -638,19 +675,19 @@ def test_list_projects_with_same_name(self): session.add_all([project1, project2]) session.commit() - output = self.app.get('/api/v2/projects/') + output = self.app.get("/api/v2/projects/") self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 2, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 2, + "items": [ { "id": 2, "backend": "custom", @@ -672,8 +709,8 @@ def test_list_projects_with_same_name(self): "version_url": None, "versions": [], "ecosystem": "https://hackage.haskell.org/package/zlib", - } - ] + }, + ], } self.assertEqual(data, exp) @@ -683,19 +720,20 @@ def test_filter_projects_by_ecosystem(self): create_project(self.session) output = self.app.get( - '/api/v2/projects/?ecosystem=https%3A%2F%2Fsubsurface-divelog.org%2F') + "/api/v2/projects/?ecosystem=https%3A%2F%2Fsubsurface-divelog.org%2F" + ) self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 1, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 1, + "items": [ { "id": 2, "backend": "custom", @@ -707,7 +745,7 @@ def test_filter_projects_by_ecosystem(self): "versions": [], "ecosystem": "https://subsurface-divelog.org/", } - ] + ], } self.assertEqual(data, exp) @@ -716,20 +754,19 @@ def test_filter_projects_by_name(self): """Assert projects can be filtered by name.""" create_project(self.session) - output = self.app.get( - '/api/v2/projects/?name=subsurface') + output = self.app.get("/api/v2/projects/?name=subsurface") self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 1, - 'items_per_page': 25, - 'total_items': 1, - 'items': [ + "page": 1, + "items_per_page": 25, + "total_items": 1, + "items": [ { "id": 2, "backend": "custom", @@ -741,19 +778,21 @@ def test_filter_projects_by_name(self): "versions": [], "ecosystem": "https://subsurface-divelog.org/", } - ] + ], } self.assertEqual(data, exp) def test_list_projects_items_per_page(self): """Assert pagination works and page size is adjustable.""" - api_endpoint = '/api/v2/projects/?items_per_page=1' + api_endpoint = "/api/v2/projects/?items_per_page=1" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 1, 'items_per_page': 1, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 1, "items_per_page": 1, "total_items": 0, "items": []} + ) create_project(self.session) @@ -761,15 +800,15 @@ def test_list_projects_items_per_page(self): self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 1, - 'items_per_page': 1, - 'total_items': 3, - 'items': [ + "page": 1, + "items_per_page": 1, + "total_items": 3, + "items": [ { "id": 3, "backend": "custom", @@ -780,20 +819,22 @@ def test_list_projects_items_per_page(self): "version_url": None, "versions": [], "ecosystem": "https://fedorahosted.org/r2spec/", - }, - ] + } + ], } self.assertEqual(data, exp) def test_list_projects_items_per_page_with_page(self): """Assert retrieving other pages works.""" - api_endpoint = '/api/v2/projects/?items_per_page=1&page=2' + api_endpoint = "/api/v2/projects/?items_per_page=1&page=2" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 200) data = _read_json(output) - self.assertEqual(data, {'page': 2, 'items_per_page': 1, 'total_items': 0, 'items': []}) + self.assertEqual( + data, {"page": 2, "items_per_page": 1, "total_items": 0, "items": []} + ) create_project(self.session) @@ -801,15 +842,15 @@ def test_list_projects_items_per_page_with_page(self): self.assertEqual(output.status_code, 200) data = _read_json(output) - for item in data['items']: - del item['created_on'] - del item['updated_on'] + for item in data["items"]: + del item["created_on"] + del item["updated_on"] exp = { - 'page': 2, - 'items_per_page': 1, - 'total_items': 3, - 'items': [ + "page": 2, + "items_per_page": 1, + "total_items": 3, + "items": [ { "id": 1, "backend": "custom", @@ -820,78 +861,88 @@ def test_list_projects_items_per_page_with_page(self): "version_url": "https://www.geany.org/Download/Releases", "versions": [], "ecosystem": "https://www.geany.org/", - }, - ] + } + ], } self.assertEqual(data, exp) def test_list_projects_items_per_page_too_big(self): """Assert unreasonably large items per page results in an error.""" - api_endpoint = '/api/v2/projects/?items_per_page=500' + api_endpoint = "/api/v2/projects/?items_per_page=500" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'items_per_page': u'Value must be less than or equal to 250.'}}) + data, + {"message": {"items_per_page": "Value must be less than or equal to 250."}}, + ) def test_list_projects_items_per_page_negative(self): """Assert a negative value for items_per_page results in an error.""" - api_endpoint = '/api/v2/projects/?items_per_page=-25' + api_endpoint = "/api/v2/projects/?items_per_page=-25" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'items_per_page': u'Value must be greater than or equal to 1.'}}) + data, + { + "message": { + "items_per_page": "Value must be greater than or equal to 1." + } + }, + ) def test_list_projects_items_per_page_non_integer(self): """Assert a non-integer for items_per_page results in an error.""" - api_endpoint = '/api/v2/projects/?items_per_page=twenty' + api_endpoint = "/api/v2/projects/?items_per_page=twenty" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( data, - {u'message': {u'items_per_page': u"invalid literal for int() with base 10: 'twenty'"}} + { + "message": { + "items_per_page": "invalid literal for int() with base 10: 'twenty'" + } + }, ) def test_list_projects_page_negative(self): """Assert a negative value for a page results in an error.""" - api_endpoint = '/api/v2/projects/?page=-25' + api_endpoint = "/api/v2/projects/?page=-25" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'page': u'Value must be greater than or equal to 1.'}}) + data, {"message": {"page": "Value must be greater than or equal to 1."}} + ) def test_list_projects_page_non_integer(self): """Assert a non-integer value for a page results in an error.""" - api_endpoint = '/api/v2/projects/?page=twenty' + api_endpoint = "/api/v2/projects/?page=twenty" output = self.app.get(api_endpoint) self.assertEqual(output.status_code, 400) data = _read_json(output) self.assertEqual( - data, {u'message': {u'page': u"invalid literal for int() with base 10: 'twenty'"}}) + data, + {"message": {"page": "invalid literal for int() with base 10: 'twenty'"}}, + ) class ProjectsResourcePostTests(DatabaseTestCase): - def setUp(self): super(ProjectsResourcePostTests, self).setUp() self.app = self.flask_app.test_client() session = Session() - self.user = models.User( - email='user@fedoraproject.org', - username='user', - ) + self.user = models.User(email="user@fedoraproject.org", username="user") user_social_auth = social_models.UserSocialAuth( - user_id=self.user.id, - user=self.user + user_id=self.user.id, user=self.user ) session.add(self.user) @@ -900,54 +951,58 @@ def setUp(self): session.add(self.api_token) session.commit() - self.auth = {'Authorization': 'Token ' + self.api_token.token} + self.auth = {"Authorization": "Token " + self.api_token.token} def test_unauthenticated(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - output = self.app.post('/api/v2/projects/') + output = self.app.post("/api/v2/projects/") self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_token(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } - output = self.app.post('/api/v2/projects/', headers={'Authorization': 'Token eh'}) + output = self.app.post( + "/api/v2/projects/", headers={"Authorization": "Token eh"} + ) self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_auth_type(self): """Assert unauthenticated requests result in a HTTP 401 response.""" self.maxDiff = None error_details = { - 'error': 'authentication_required', - 'error_description': 'Authentication is required to access this API.', + "error": "authentication_required", + "error_description": "Authentication is required to access this API.", } output = self.app.post( - '/api/v2/projects/', headers={'Authorization': 'Basic ' + self.api_token.token}) + "/api/v2/projects/", + headers={"Authorization": "Basic " + self.api_token.token}, + ) self.assertEqual(output.status_code, 401) self.assertEqual(error_details, _read_json(output)) - self.assertEqual('Token', output.headers['WWW-Authenticate']) + self.assertEqual("Token", output.headers["WWW-Authenticate"]) def test_invalid_request(self): """Assert invalid requests result in a helpful HTTP 400.""" - output = self.app.post('/api/v2/projects/', headers=self.auth) + output = self.app.post("/api/v2/projects/", headers=self.auth) self.assertEqual(output.status_code, 400) # Error details should report the missing required fields @@ -964,15 +1019,21 @@ def test_conflicting_request(self): "name": "requests", } - output = self.app.post('/api/v2/projects/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/projects/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 201) - output = self.app.post('/api/v2/projects/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/projects/", headers=self.auth, data=request_data + ) self.assertEqual(output.status_code, 409) # Error details should report conflicting fields. data = _read_json(output) self.assertIn("requested_project", data) self.assertEqual("PyPI", data["requested_project"]["backend"]) - self.assertEqual("http://python-requests.org", data["requested_project"]["homepage"]) + self.assertEqual( + "http://python-requests.org", data["requested_project"]["homepage"] + ) self.assertEqual("requests", data["requested_project"]["name"]) def test_valid_request(self): @@ -982,7 +1043,9 @@ def test_valid_request(self): "name": "requests", } - output = self.app.post('/api/v2/projects/', headers=self.auth, data=request_data) + output = self.app.post( + "/api/v2/projects/", headers=self.auth, data=request_data + ) data = _read_json(output) self.assertEqual(output.status_code, 201) diff --git a/anitya/tests/test_librariesio_consumer.py b/anitya/tests/test_librariesio_consumer.py index d8f734ef2..9ce70ab3a 100644 --- a/anitya/tests/test_librariesio_consumer.py +++ b/anitya/tests/test_librariesio_consumer.py @@ -33,159 +33,168 @@ from anitya.tests.base import DatabaseTestCase -@mock.patch('anitya.librariesio_consumer.initialize', mock.Mock()) +@mock.patch("anitya.librariesio_consumer.initialize", mock.Mock()) class LibrariesioConsumerTests(DatabaseTestCase): - def setUp(self): super(LibrariesioConsumerTests, self).setUp() self.supported_fedmsg = { - 'body': { - 'username': 'vagrant', - 'i': 236, - 'timestamp': 1488561045, - 'msg_id': '2017-630afdfd-4780-48ce-ba99-3a306d8de2d2', - 'topic': 'org.fedoraproject.dev.sse2fedmsg.librariesio', - 'msg': { - 'retry': 500, - 'data': { - 'name': 'ImageMetaTag', - 'project': { - 'status': None, - 'repository_url': 'https://github.com/SciTools-incubator/', - 'latest_release_published_at': '2017-03-03 16:44:46 UTC', - 'description': 'Tags images created by matplotlib with ...', - 'language': 'Python', - 'platform': 'Pypi', - 'package_manager_url': 'https://pypi.org/project/ImageMetaTag/', - 'latest_release_number': '0.6.9', - 'rank': 4, - 'stars': 1, - 'keywords': [], - 'normalized_licenses': ['BSD-3-Clause'], - 'forks': 1, - 'homepage': 'https://github.com/SciTools-incubator/image-meta-tag', - 'name': 'ImageMetaTag' + "body": { + "username": "vagrant", + "i": 236, + "timestamp": 1488561045, + "msg_id": "2017-630afdfd-4780-48ce-ba99-3a306d8de2d2", + "topic": "org.fedoraproject.dev.sse2fedmsg.librariesio", + "msg": { + "retry": 500, + "data": { + "name": "ImageMetaTag", + "project": { + "status": None, + "repository_url": "https://github.com/SciTools-incubator/", + "latest_release_published_at": "2017-03-03 16:44:46 UTC", + "description": "Tags images created by matplotlib with ...", + "language": "Python", + "platform": "Pypi", + "package_manager_url": "https://pypi.org/project/ImageMetaTag/", + "latest_release_number": "0.6.9", + "rank": 4, + "stars": 1, + "keywords": [], + "normalized_licenses": ["BSD-3-Clause"], + "forks": 1, + "homepage": "https://github.com/SciTools-incubator/image-meta-tag", + "name": "ImageMetaTag", }, - 'platform': 'Pypi', - 'published_at': '2017-03-03 16:44:46 UTC', - 'version': '0.6.9', - 'package_manager_url': 'https://pypi.org/project/ImageMetaTag/0.6.9' + "platform": "Pypi", + "published_at": "2017-03-03 16:44:46 UTC", + "version": "0.6.9", + "package_manager_url": "https://pypi.org/project/ImageMetaTag/0.6.9", }, - 'event': 'event', - 'id': None - } + "event": "event", + "id": None, + }, } } - self.mock_hub = mock.Mock(config={'environment': 'dev', 'topic_prefix': 'anitya'}) + self.mock_hub = mock.Mock( + config={"environment": "dev", "topic_prefix": "anitya"} + ) def test_dev_environment_topics(self): """Assert when the environment is set to dev, the dev topic is used.""" - mock_hub = mock.Mock(config={'environment': 'dev', 'topic_prefix': 'anitya'}) + mock_hub = mock.Mock(config={"environment": "dev", "topic_prefix": "anitya"}) consumer = LibrariesioConsumer(mock_hub) - self.assertEqual([u'anitya.dev.sse2fedmsg.librariesio'], consumer.topic) + self.assertEqual(["anitya.dev.sse2fedmsg.librariesio"], consumer.topic) def test_prod_environment_topics(self): """Assert when the environment is set to prod, only the prod topic is used.""" - mock_hub = mock.Mock(config={'environment': 'prod', 'topic_prefix': 'anitya'}) + mock_hub = mock.Mock(config={"environment": "prod", "topic_prefix": "anitya"}) consumer = LibrariesioConsumer(mock_hub) - self.assertEqual([u'anitya.prod.sse2fedmsg.librariesio'], consumer.topic) + self.assertEqual(["anitya.prod.sse2fedmsg.librariesio"], consumer.topic) def test_prefix_setup(self): """Assert that topic_prefix is changed after initialization.""" - mock_hub = mock.Mock(config={'environment': 'dev', 'topic_prefix': 'anitya'}) - self.assertEqual(mock_hub.config['topic_prefix'], 'anitya') + mock_hub = mock.Mock(config={"environment": "dev", "topic_prefix": "anitya"}) + self.assertEqual(mock_hub.config["topic_prefix"], "anitya") LibrariesioConsumer(mock_hub) - self.assertEqual(mock_hub.config['topic_prefix'], 'org.release-monitoring') + self.assertEqual(mock_hub.config["topic_prefix"], "org.release-monitoring") - @mock.patch('anitya.librariesio_consumer._log') + @mock.patch("anitya.librariesio_consumer._log") def test_no_ecosystem(self, mock_log): """Assert that messages about platforms we don't support are handled gracefully""" consumer = LibrariesioConsumer(self.mock_hub) unsupported_fedmsg = { - 'body': { - 'username': 'vagrant', - 'i': 211, - 'timestamp': 1488560762, - 'msg_id': '2017-a7dbddc2-8ce5-4291-9986-c8584ec97fdd', - 'topic': 'org.fedoraproject.dev.sse2fedmsg.librariesio', - 'msg': { - 'retry': 500, - 'data': { - 'name': 'GreatProject', - 'project': { - 'status': None, - 'repository_url': None, - 'latest_release_published_at': '2017-03-03 00:00:00 UTC', - 'description': 'A great description of the project', - 'language': None, - 'platform': 'GREAT', - 'package_manager_url': 'https://example.com/GreatProject.git', - 'latest_release_number': '1.5.0', - 'rank': 0, - 'stars': 0, - 'keywords': [], - 'normalized_licenses': ['GPL-3.0+'], - 'forks': 0, - 'homepage': 'https://example.com/GreatProject', - 'name': 'GreatProject', + "body": { + "username": "vagrant", + "i": 211, + "timestamp": 1488560762, + "msg_id": "2017-a7dbddc2-8ce5-4291-9986-c8584ec97fdd", + "topic": "org.fedoraproject.dev.sse2fedmsg.librariesio", + "msg": { + "retry": 500, + "data": { + "name": "GreatProject", + "project": { + "status": None, + "repository_url": None, + "latest_release_published_at": "2017-03-03 00:00:00 UTC", + "description": "A great description of the project", + "language": None, + "platform": "GREAT", + "package_manager_url": "https://example.com/GreatProject.git", + "latest_release_number": "1.5.0", + "rank": 0, + "stars": 0, + "keywords": [], + "normalized_licenses": ["GPL-3.0+"], + "forks": 0, + "homepage": "https://example.com/GreatProject", + "name": "GreatProject", }, - 'platform': 'GREAT', - 'published_at': '2017-03-03 00:00:00 UTC', - 'version': '1.5.0', - 'package_manager_url': 'https://example.com/GreatProject.git', + "platform": "GREAT", + "published_at": "2017-03-03 00:00:00 UTC", + "version": "1.5.0", + "package_manager_url": "https://example.com/GreatProject.git", }, - 'event': 'event', - 'id': None, - } + "event": "event", + "id": None, + }, } } self.assertEqual(0, self.session.query(Project).count()) consumer.consume(unsupported_fedmsg) self.assertEqual(0, self.session.query(Project).count()) - self.assertTrue('Dropped librariesio update' in mock_log.debug.call_args_list[0][0][0]) + self.assertTrue( + "Dropped librariesio update" in mock_log.debug.call_args_list[0][0][0] + ) def test_new_project_configured_off(self): """libraries.io events shouldn't create projects if the configuration is off.""" consumer = LibrariesioConsumer(self.mock_hub) - with mock.patch.dict(config.config, {'LIBRARIESIO_PLATFORM_WHITELIST': []}): + with mock.patch.dict(config.config, {"LIBRARIESIO_PLATFORM_WHITELIST": []}): consumer.consume(self.supported_fedmsg) self.assertEqual(0, self.session.query(Project).count()) def test_new_project_configured_on(self): """Assert that a libraries.io event about an unknown project creates that project""" consumer = LibrariesioConsumer(self.mock_hub) - with mock.patch.dict(config.config, {'LIBRARIESIO_PLATFORM_WHITELIST': ['pypi']}): + with mock.patch.dict( + config.config, {"LIBRARIESIO_PLATFORM_WHITELIST": ["pypi"]} + ): consumer.consume(self.supported_fedmsg) self.assertEqual(1, self.session.query(Project).count()) project = self.session.query(Project).first() - self.assertEqual('ImageMetaTag', project.name) - self.assertEqual('pypi', project.ecosystem_name) - self.assertEqual('0.6.9', project.latest_version) + self.assertEqual("ImageMetaTag", project.name) + self.assertEqual("pypi", project.ecosystem_name) + self.assertEqual("0.6.9", project.latest_version) - @mock.patch('anitya.librariesio_consumer._log') - @mock.patch('anitya.librariesio_consumer.utilities.create_project') + @mock.patch("anitya.librariesio_consumer._log") + @mock.patch("anitya.librariesio_consumer.utilities.create_project") def test_new_project_failure(self, mock_create, mock_log): """Assert failures to create projects are logged as errors.""" mock_create.side_effect = AnityaException("boop") consumer = LibrariesioConsumer(self.mock_hub) - with mock.patch.dict(config.config, {'LIBRARIESIO_PLATFORM_WHITELIST': ['pypi']}): + with mock.patch.dict( + config.config, {"LIBRARIESIO_PLATFORM_WHITELIST": ["pypi"]} + ): consumer.consume(self.supported_fedmsg) self.assertEqual(0, self.session.query(Project).count()) mock_log.error.assert_called_once_with( 'A new project was discovered via libraries.io, %r, but we failed with "%s"', - None, 'boop') + None, + "boop", + ) def test_existing_project(self): """Assert that a libraries.io event about an existing project updates that project""" project = Project( - name='ImageMetaTag', - homepage='https://pypi.org/project/ImageMetaTag/', - ecosystem_name='pypi', - backend='PyPI', + name="ImageMetaTag", + homepage="https://pypi.org/project/ImageMetaTag/", + ecosystem_name="pypi", + backend="PyPI", ) self.session.add(project) self.session.commit() @@ -195,20 +204,20 @@ def test_existing_project(self): consumer.consume(self.supported_fedmsg) self.assertEqual(1, self.session.query(Project).count()) project = self.session.query(Project).first() - self.assertEqual('ImageMetaTag', project.name) - self.assertEqual('pypi', project.ecosystem_name) - self.assertEqual('0.6.9', project.latest_version) + self.assertEqual("ImageMetaTag", project.name) + self.assertEqual("pypi", project.ecosystem_name) + self.assertEqual("0.6.9", project.latest_version) - @mock.patch('anitya.librariesio_consumer.utilities.check_project_release') + @mock.patch("anitya.librariesio_consumer.utilities.check_project_release") def test_existing_project_check_failure(self, mock_check): """Assert that when an existing project fails a version check nothing happens""" consumer = LibrariesioConsumer(self.mock_hub) mock_check.side_effect = AnityaPluginException() project = Project( - name='ImageMetaTag', - homepage='https://pypi.python.org/pypi/ImageMetaTag', - ecosystem_name='pypi', - backend='PyPI', + name="ImageMetaTag", + homepage="https://pypi.python.org/pypi/ImageMetaTag", + ecosystem_name="pypi", + backend="PyPI", ) self.session.add(project) self.session.commit() @@ -218,27 +227,27 @@ def test_existing_project_check_failure(self, mock_check): project = self.session.query(Project).first() self.assertIs(project.latest_version, None) - @mock.patch('anitya.librariesio_consumer._log') + @mock.patch("anitya.librariesio_consumer._log") def test_mismatched_versions(self, mock_log): """Assert when libraries.io and Anitya disagree on version, it's logged""" consumer = LibrariesioConsumer(self.mock_hub) project = Project( - name='ImageMetaTag', - homepage='https://pypi.org/project/ImageMetaTag/', - ecosystem_name='pypi', - backend='PyPI', + name="ImageMetaTag", + homepage="https://pypi.org/project/ImageMetaTag/", + ecosystem_name="pypi", + backend="PyPI", ) self.session.add(project) self.session.commit() - self.supported_fedmsg['body']['msg']['data']['version'] = '0.6.11' + self.supported_fedmsg["body"]["msg"]["data"]["version"] = "0.6.11" consumer.consume(self.supported_fedmsg) project = self.session.query(Project).first() - self.assertEqual('0.6.9', project.latest_version) + self.assertEqual("0.6.9", project.latest_version) self.assertIn( - 'libraries.io has found an update (version %s) for project %r', + "libraries.io has found an update (version %s) for project %r", mock_log.info.call_args_list[1][0], ) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/anitya/tests/test_project.py b/anitya/tests/test_project.py index 3a9811e9d..18cbbc403 100644 --- a/anitya/tests/test_project.py +++ b/anitya/tests/test_project.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for the Project object. -''' +""" import unittest @@ -38,19 +38,19 @@ def test_project_init(self): self.assertEqual(3, models.Project.all(self.session, count=True)) projects = models.Project.all(self.session) - self.assertEqual(projects[0].name, 'geany') - self.assertEqual(projects[1].name, 'R2spec') - self.assertEqual(projects[2].name, 'subsurface') + self.assertEqual(projects[0].name, "geany") + self.assertEqual(projects[1].name, "R2spec") + self.assertEqual(projects[2].name, "subsurface") def test_project_by_name(self): """ Test the by_name function of Project. """ create_project(self.session) - project = models.Project.by_name(self.session, 'geany') - self.assertEqual(project[0].name, 'geany') - self.assertEqual(project[0].homepage, 'https://www.geany.org/') + project = models.Project.by_name(self.session, "geany") + self.assertEqual(project[0].name, "geany") + self.assertEqual(project[0].homepage, "https://www.geany.org/") - project = models.Project.by_name(self.session, 'terminal') + project = models.Project.by_name(self.session, "terminal") self.assertEqual(project, []) def test_project_by_id(self): @@ -58,20 +58,20 @@ def test_project_by_id(self): create_project(self.session) project = models.Project.by_id(self.session, 1) - self.assertEqual(project.name, 'geany') - self.assertEqual(project.homepage, 'https://www.geany.org/') + self.assertEqual(project.name, "geany") + self.assertEqual(project.homepage, "https://www.geany.org/") project = models.Project.get(self.session, 1) - self.assertEqual(project.name, 'geany') - self.assertEqual(project.homepage, 'https://www.geany.org/') + self.assertEqual(project.name, "geany") + self.assertEqual(project.homepage, "https://www.geany.org/") project = models.Project.by_id(self.session, 2) - self.assertEqual(project.name, 'subsurface') - self.assertEqual(project.homepage, 'https://subsurface-divelog.org/') + self.assertEqual(project.name, "subsurface") + self.assertEqual(project.homepage, "https://subsurface-divelog.org/") project = models.Project.get(self.session, 2) - self.assertEqual(project.name, 'subsurface') - self.assertEqual(project.homepage, 'https://subsurface-divelog.org/') + self.assertEqual(project.name, "subsurface") + self.assertEqual(project.homepage, "https://subsurface-divelog.org/") project = models.Project.by_id(self.session, 10) self.assertEqual(project, None) @@ -80,19 +80,19 @@ def test_project_by_homepage(self): """ Test the by_homepage function of Project. """ create_project(self.session) - projects = models.Project.by_homepage( - self.session, 'https://www.geany.org/') + projects = models.Project.by_homepage(self.session, "https://www.geany.org/") self.assertEqual(len(projects), 1) - self.assertEqual(projects[0].name, 'geany') - self.assertEqual(projects[0].homepage, 'https://www.geany.org/') + self.assertEqual(projects[0].name, "geany") + self.assertEqual(projects[0].homepage, "https://www.geany.org/") projects = models.Project.by_homepage( - self.session, 'https://subsurface-divelog.org/') + self.session, "https://subsurface-divelog.org/" + ) self.assertEqual(len(projects), 1) - self.assertEqual(projects[0].name, 'subsurface') - self.assertEqual(projects[0].homepage, 'https://subsurface-divelog.org/') + self.assertEqual(projects[0].name, "subsurface") + self.assertEqual(projects[0].homepage, "https://subsurface-divelog.org/") - project = models.Project.by_homepage(self.session, 'terminal') + project = models.Project.by_homepage(self.session, "terminal") self.assertEqual(project, []) def test_project_all(self): @@ -100,11 +100,10 @@ def test_project_all(self): create_project(self.session) projects = models.Project.all(self.session) - self.assertEqual(projects[0].name, 'geany') - self.assertEqual(projects[0].homepage, 'https://www.geany.org/') - self.assertEqual(projects[1].name, 'R2spec') - self.assertEqual( - projects[1].homepage, 'https://fedorahosted.org/r2spec/') + self.assertEqual(projects[0].name, "geany") + self.assertEqual(projects[0].homepage, "https://www.geany.org/") + self.assertEqual(projects[1].name, "R2spec") + self.assertEqual(projects[1].homepage, "https://fedorahosted.org/r2spec/") projects = models.Project.all(self.session, page=3) self.assertEqual(projects, []) @@ -113,22 +112,22 @@ def test_project_search(self): """ Test the search function of Project. """ create_project(self.session) - projects = models.Project.search(self.session, 'gea') + projects = models.Project.search(self.session, "gea") self.assertEqual(projects, []) - projects = models.Project.search(self.session, 'gea*') - self.assertEqual(projects[0].name, 'geany') - self.assertEqual(projects[0].homepage, 'https://www.geany.org/') + projects = models.Project.search(self.session, "gea*") + self.assertEqual(projects[0].name, "geany") + self.assertEqual(projects[0].homepage, "https://www.geany.org/") def test_distro_repr(self): """ Test the __repr__ function of Project. """ create_project(self.session) - obs = '' + obs = "" project = models.Project.by_id(self.session, 1) self.assertEqual(str(project), obs) -if __name__ == '__main__': +if __name__ == "__main__": SUITE = unittest.TestLoader().loadTestsFromTestCase(Projecttests) unittest.TextTestRunner(verbosity=2).run(SUITE) diff --git a/anitya/tests/test_sar.py b/anitya/tests/test_sar.py index 7f7c1246e..3e2104fe8 100644 --- a/anitya/tests/test_sar.py +++ b/anitya/tests/test_sar.py @@ -19,9 +19,9 @@ # of Red Hat, Inc. # -''' +""" anitya tests for GDPR SAR script. -''' +""" import pytest import mock @@ -42,50 +42,34 @@ def capsys(self, capsys): """ Use capsys fixture as part of this class. """ self.capsys = capsys - @mock.patch.dict('os.environ', {'SAR_EMAIL': 'user@fedoraproject.org'}) + @mock.patch.dict("os.environ", {"SAR_EMAIL": "user@fedoraproject.org"}) def test_main_email(self): """ Assert that correct user data are dumped when providing e-mail. """ - user = models.User( - email='user@fedoraproject.org', - username='user', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user_social_auth) self.session.add(user) - user2 = models.User( - email='user2@email.org', - username='user2', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user2.id, - user=user2 - ) + user2 = models.User(email="user2@email.org", username="user2", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user2.id, user=user2) self.session.add(user_social_auth) self.session.add(user2) self.session.commit() - exp = [{ - 'id': str(user.id), - 'username': user.username, - 'email': user.email, - 'active': user.active, - 'social_auth': [{ - 'uid': None, - 'provider': None, - 'extra_data': None - }] - }] + exp = [ + { + "id": str(user.id), + "username": user.username, + "email": user.email, + "active": user.active, + "social_auth": [{"uid": None, "provider": None, "extra_data": None}], + } + ] sar.main() @@ -95,49 +79,32 @@ def test_main_email(self): self.assertEqual(exp, obs) - @mock.patch.dict('os.environ', {'SAR_USERNAME': 'user'}) + @mock.patch.dict("os.environ", {"SAR_USERNAME": "user"}) def test_main_username(self): """ Assert that correct user data are dumped when providing username. """ - user = models.User( - email='user@fedoraproject.org', - username='user', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user_social_auth) self.session.add(user) - user2 = models.User( - email='user2@email.org', - username='user2', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user2.id, - user=user2 - ) + user2 = models.User(email="user2@email.org", username="user2", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user2.id, user=user2) self.session.add(user_social_auth) self.session.add(user2) self.session.commit() - exp = [{ - 'id': str(user.id), - 'username': user.username, - 'email': user.email, - 'active': user.active, - 'social_auth': [{ - 'uid': None, - 'provider': None, - 'extra_data': None - }] + exp = [ + { + "id": str(user.id), + "username": user.username, + "email": user.email, + "active": user.active, + "social_auth": [{"uid": None, "provider": None, "extra_data": None}], } ] @@ -153,28 +120,14 @@ def test_main_no_env_set(self): """ Assert that correct user data are dumped when nothing is provided. """ - user = models.User( - email='user@fedoraproject.org', - username='user', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user.id, - user=user - ) + user = models.User(email="user@fedoraproject.org", username="user", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user.id, user=user) self.session.add(user_social_auth) self.session.add(user) - user2 = models.User( - email='user2@email.org', - username='user2', - active=True, - ) - user_social_auth = social_models.UserSocialAuth( - user_id=user2.id, - user=user2 - ) + user2 = models.User(email="user2@email.org", username="user2", active=True) + user_social_auth = social_models.UserSocialAuth(user_id=user2.id, user=user2) self.session.add(user_social_auth) self.session.add(user2) @@ -184,4 +137,4 @@ def test_main_no_env_set(self): out, err = self.capsys.readouterr() - self.assertEqual('[]', out) + self.assertEqual("[]", out) diff --git a/anitya/ui.py b/anitya/ui.py index 236de4a5b..86531dd7f 100644 --- a/anitya/ui.py +++ b/anitya/ui.py @@ -12,85 +12,80 @@ ui_blueprint = flask.Blueprint( - 'anitya_ui', __name__, static_folder='static', template_folder='templates') + "anitya_ui", __name__, static_folder="static", template_folder="templates" +) def get_extended_pattern(pattern): - ''' For a given pattern `p` return it so that it looks like `*p*` + """ For a given pattern `p` return it so that it looks like `*p*` adjusting it accordingly. - ''' + """ - if not pattern.startswith('*'): - pattern = '*' + pattern - if not pattern.endswith('*'): - pattern += '*' + if not pattern.startswith("*"): + pattern = "*" + pattern + if not pattern.endswith("*"): + pattern += "*" return pattern -@ui_blueprint.route('/') +@ui_blueprint.route("/") def index(): total = models.Project.all(Session, count=True) - return flask.render_template( - 'index.html', - current='index', - total=total, - ) + return flask.render_template("index.html", current="index", total=total) -@ui_blueprint.route('/about') +@ui_blueprint.route("/about") def about(): """A backwards-compatibility route for old documentation links""" - new_path = flask.url_for('anitya_ui.static', filename='docs/index.html') + new_path = flask.url_for("anitya_ui.static", filename="docs/index.html") return flask.redirect(new_path) -@ui_blueprint.route('/fedmsg') +@ui_blueprint.route("/fedmsg") def fedmsg(): """A backwards-compatibility route for old documentation links""" - new_path = flask.url_for('anitya_ui.static', filename='docs/user-guide.html') + new_path = flask.url_for("anitya_ui.static", filename="docs/user-guide.html") return flask.redirect(new_path) -@ui_blueprint.route('/login/', methods=('GET', 'POST')) -@ui_blueprint.route('/login', methods=('GET', 'POST')) +@ui_blueprint.route("/login/", methods=("GET", "POST")) +@ui_blueprint.route("/login", methods=("GET", "POST")) def login(): - return flask.render_template('login.html') + return flask.render_template("login.html") -@ui_blueprint.route('/logout/') -@ui_blueprint.route('/logout') +@ui_blueprint.route("/logout/") +@ui_blueprint.route("/logout") @login_required def logout(): logout_user() - return flask.redirect('/') + return flask.redirect("/") -@ui_blueprint.route('/settings/', methods=('GET', 'POST')) +@ui_blueprint.route("/settings/", methods=("GET", "POST")) @login_required def settings(): """The user's settings, currently only the API token page.""" return flask.render_template( - 'settings.html', - current='settings', - form=anitya.forms.TokenForm()) + "settings.html", current="settings", form=anitya.forms.TokenForm() + ) -@ui_blueprint.route('/settings/tokens/new', methods=('POST',)) +@ui_blueprint.route("/settings/tokens/new", methods=("POST",)) @login_required def new_token(): """Create a new API token for the current user.""" form = anitya.forms.TokenForm() if form.validate_on_submit(): - token = models.ApiToken( - user=flask.g.user, description=form.description.data) + token = models.ApiToken(user=flask.g.user, description=form.description.data) Session.add(token) Session.commit() - return flask.redirect(flask.url_for('anitya_ui.settings')) + return flask.redirect(flask.url_for("anitya_ui.settings")) else: flask.abort(400) -@ui_blueprint.route('/settings/tokens/delete//', methods=('POST',)) +@ui_blueprint.route("/settings/tokens/delete//", methods=("POST",)) @login_required def delete_token(token): """Delete the API token provided for current user.""" @@ -101,13 +96,13 @@ def delete_token(token): flask.abort(404) Session.delete(t) Session.commit() - return flask.redirect(flask.url_for('anitya_ui.settings')) + return flask.redirect(flask.url_for("anitya_ui.settings")) else: flask.abort(400) -@ui_blueprint.route('/project/') -@ui_blueprint.route('/project//') +@ui_blueprint.route("/project/") +@ui_blueprint.route("/project//") def project(project_id): project = models.Project.by_id(Session, project_id) @@ -115,28 +110,22 @@ def project(project_id): if not project: flask.abort(404) - return flask.render_template( - 'project.html', - current='project', - project=project, - ) + return flask.render_template("project.html", current="project", project=project) -@ui_blueprint.route('/project/') -@ui_blueprint.route('/project//') +@ui_blueprint.route("/project/") +@ui_blueprint.route("/project//") def project_name(project_name): - page = flask.request.args.get('page', 1) + page = flask.request.args.get("page", 1) try: page = int(page) except ValueError: page = 1 - projects = models.Project.search( - Session, pattern=project_name, page=page) - projects_count = models.Project.search( - Session, pattern=project_name, count=True) + projects = models.Project.search(Session, pattern=project_name, page=page) + projects_count = models.Project.search(Session, pattern=project_name, count=True) if projects_count == 1: return project(projects[0].id) @@ -144,20 +133,21 @@ def project_name(project_name): total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'search.html', - current='projects', + "search.html", + current="projects", pattern=project_name, projects=projects, total_page=total_page, projects_count=projects_count, - page=page) + page=page, + ) -@ui_blueprint.route('/projects') -@ui_blueprint.route('/projects/') +@ui_blueprint.route("/projects") +@ui_blueprint.route("/projects/") def projects(): - page = flask.request.args.get('page', 1) + page = flask.request.args.get("page", 1) try: page = int(page) @@ -170,50 +160,54 @@ def projects(): total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'projects.html', - current='projects', + "projects.html", + current="projects", projects=projects, total_page=total_page, projects_count=projects_count, - page=page) + page=page, + ) -@ui_blueprint.route('/projects/updates') -@ui_blueprint.route('/projects/updates/') -@ui_blueprint.route('/projects/updates/') -def projects_updated(status='updated'): +@ui_blueprint.route("/projects/updates") +@ui_blueprint.route("/projects/updates/") +@ui_blueprint.route("/projects/updates/") +def projects_updated(status="updated"): - page = flask.request.args.get('page', 1) - name = flask.request.args.get('name', None) - log = flask.request.args.get('log', None) + page = flask.request.args.get("page", 1) + name = flask.request.args.get("name", None) + log = flask.request.args.get("log", None) try: page = int(page) except ValueError: page = 1 - statuses = ['new', 'updated', 'failed', 'never_updated', 'odd'] + statuses = ["new", "updated", "failed", "never_updated", "odd"] if status not in statuses: flask.flash( - '%s is invalid, you should use one of: %s; using default: ' - '`updated`' % (status, ', '.join(statuses)), - 'errors' + "%s is invalid, you should use one of: %s; using default: " + "`updated`" % (status, ", ".join(statuses)), + "errors", ) flask.flash( - 'Returning all the projects regardless of how/if their version ' - 'was retrieved correctly') + "Returning all the projects regardless of how/if their version " + "was retrieved correctly" + ) projects = models.Project.updated( - Session, status=status, name=name, log=log, page=page) + Session, status=status, name=name, log=log, page=page + ) projects_count = models.Project.updated( - Session, status=status, name=name, log=log, count=True) + Session, status=status, name=name, log=log, count=True + ) total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'updates.html', - current='projects', + "updates.html", + current="projects", projects=projects, total_page=total_page, projects_count=projects_count, @@ -224,12 +218,12 @@ def projects_updated(status='updated'): ) -@ui_blueprint.route('/logs') +@ui_blueprint.route("/logs") @login_required def browse_logs(): - refresh = flask.request.args.get('refresh', False) - page = flask.request.args.get('page', 1) + refresh = flask.request.args.get("refresh", False) + page = flask.request.args.get("page", 1) try: page = int(page) @@ -240,8 +234,7 @@ def browse_logs(): page = 1 page_obj = models.Project.query.paginate( - page=page, - order_by=models.Project.last_check.desc() + page=page, order_by=models.Project.last_check.desc() ) projects = page_obj.items @@ -251,8 +244,8 @@ def browse_logs(): total_page = int(ceil(cnt_projects / float(page_obj.items_per_page))) return flask.render_template( - 'logs.html', - current='logs', + "logs.html", + current="logs", refresh=refresh, projects=projects, total_page=total_page, @@ -260,11 +253,11 @@ def browse_logs(): ) -@ui_blueprint.route('/distros') -@ui_blueprint.route('/distros/') +@ui_blueprint.route("/distros") +@ui_blueprint.route("/distros/") def distros(): - page = flask.request.args.get('page', 1) + page = flask.request.args.get("page", 1) try: page = int(page) @@ -277,43 +270,43 @@ def distros(): total_page = int(ceil(distros_count / float(50))) return flask.render_template( - 'distros.html', - current='distros', + "distros.html", + current="distros", distros=distros, total_page=total_page, distros_count=distros_count, - page=page) + page=page, + ) -@ui_blueprint.route('/distro/') -@ui_blueprint.route('/distro//') +@ui_blueprint.route("/distro/") +@ui_blueprint.route("/distro//") def distro(distroname): - page = flask.request.args.get('page', 1) + page = flask.request.args.get("page", 1) try: page = int(page) except ValueError: page = 1 - projects = models.Project.by_distro( - Session, distro=distroname, page=page) - projects_count = models.Project.by_distro( - Session, distro=distroname, count=True) + projects = models.Project.by_distro(Session, distro=distroname, page=page) + projects_count = models.Project.by_distro(Session, distro=distroname, count=True) total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'projects.html', - current='projects', + "projects.html", + current="projects", projects=projects, distroname=distroname, total_page=total_page, projects_count=projects_count, - page=page) + page=page, + ) -@ui_blueprint.route('/distro/add', methods=['GET', 'POST']) +@ui_blueprint.route("/distro/add", methods=["GET", "POST"]) @login_required def add_distro(): @@ -327,89 +320,80 @@ def add_distro(): utilities.log( Session, distro=distro, - topic='distro.add', - message=dict( - agent=flask.g.user.username, - distro=distro.name, - ) + topic="distro.add", + message=dict(agent=flask.g.user.username, distro=distro.name), ) try: Session.add(distro) Session.commit() - flask.flash('Distribution added') + flask.flash("Distribution added") except SQLAlchemyError: Session.rollback() - flask.flash( - 'Could not add this distro, already exists?', 'error') - return flask.redirect( - flask.url_for('anitya_ui.distros') - ) + flask.flash("Could not add this distro, already exists?", "error") + return flask.redirect(flask.url_for("anitya_ui.distros")) return flask.render_template( - 'distro_add_edit.html', - context='Add', - current='distros', - form=form) + "distro_add_edit.html", context="Add", current="distros", form=form + ) -@ui_blueprint.route('/projects/search') -@ui_blueprint.route('/projects/search/') -@ui_blueprint.route('/projects/search/') +@ui_blueprint.route("/projects/search") +@ui_blueprint.route("/projects/search/") +@ui_blueprint.route("/projects/search/") def projects_search(pattern=None): - pattern = flask.request.args.get('pattern', pattern) or '*' - page = flask.request.args.get('page', 1) - exact = flask.request.args.get('exact', 0) + pattern = flask.request.args.get("pattern", pattern) or "*" + page = flask.request.args.get("page", 1) + exact = flask.request.args.get("exact", 0) try: page = int(page) except ValueError: page = 1 - projects = models.Project.search( - Session, pattern=pattern, page=page) + projects = models.Project.search(Session, pattern=pattern, page=page) - if not str(exact).lower() in ['1', 'true']: + if not str(exact).lower() in ["1", "true"]: # Extends the search for proj in models.Project.search( - Session, - pattern=get_extended_pattern(pattern), - page=page): + Session, pattern=get_extended_pattern(pattern), page=page + ): if proj not in projects: projects.append(proj) projects_count = models.Project.search( - Session, pattern=get_extended_pattern(pattern), count=True) + Session, pattern=get_extended_pattern(pattern), count=True + ) else: - projects_count = models.Project.search( - Session, pattern=pattern, count=True) + projects_count = models.Project.search(Session, pattern=pattern, count=True) - if projects_count == 1 and projects[0].name == pattern.replace('*', ''): - flask.flash( - 'Only one result matching with an exact match, redirecting') + if projects_count == 1 and projects[0].name == pattern.replace("*", ""): + flask.flash("Only one result matching with an exact match, redirecting") return flask.redirect( - flask.url_for('anitya_ui.project', project_id=projects[0].id)) + flask.url_for("anitya_ui.project", project_id=projects[0].id) + ) total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'search.html', - current='projects', + "search.html", + current="projects", pattern=pattern, projects=projects, total_page=total_page, projects_count=projects_count, - page=page) + page=page, + ) -@ui_blueprint.route('/distro//search') -@ui_blueprint.route('/distro//search/') -@ui_blueprint.route('/distro//search/') +@ui_blueprint.route("/distro//search") +@ui_blueprint.route("/distro//search/") +@ui_blueprint.route("/distro//search/") def distro_projects_search(distroname, pattern=None): - pattern = flask.request.args.get('pattern', pattern) or '*' - page = flask.request.args.get('page', 1) - exact = flask.request.args.get('exact', 0) + pattern = flask.request.args.get("pattern", pattern) or "*" + page = flask.request.args.get("page", 1) + exact = flask.request.args.get("exact", 0) try: page = int(page) @@ -417,45 +401,48 @@ def distro_projects_search(distroname, pattern=None): page = 1 projects = models.Project.search( - Session, pattern=pattern, distro=distroname, page=page) + Session, pattern=pattern, distro=distroname, page=page + ) - if not str(exact).lower() in ['1', 'true']: + if not str(exact).lower() in ["1", "true"]: # Extends the search for proj in models.Project.search( - Session, - pattern=get_extended_pattern(pattern), - distro=distroname, - page=page): + Session, pattern=get_extended_pattern(pattern), distro=distroname, page=page + ): if proj not in projects: projects.append(proj) projects_count = models.Project.search( Session, pattern=get_extended_pattern(pattern), - distro=distroname, count=True) + distro=distroname, + count=True, + ) else: projects_count = models.Project.search( - Session, pattern=pattern, distro=distroname, count=True) + Session, pattern=pattern, distro=distroname, count=True + ) - if projects_count == 1 and projects[0].name == pattern.replace('*', ''): - flask.flash( - 'Only one result matching with an exact match, redirecting') + if projects_count == 1 and projects[0].name == pattern.replace("*", ""): + flask.flash("Only one result matching with an exact match, redirecting") return flask.redirect( - flask.url_for('anitya_ui.project', project_id=projects[0].id)) + flask.url_for("anitya_ui.project", project_id=projects[0].id) + ) total_page = int(ceil(projects_count / float(50))) return flask.render_template( - 'search.html', - current='projects', + "search.html", + current="projects", pattern=pattern, projects=projects, distroname=distroname, total_page=total_page, projects_count=projects_count, - page=page) + page=page, + ) -@ui_blueprint.route('/project/new', methods=['GET', 'POST']) +@ui_blueprint.route("/project/new", methods=["GET", "POST"]) @login_required def new_project(): """ @@ -467,22 +454,23 @@ def new_project(): """ backend_plugins = anitya_plugins.load_plugins(Session) plg_names = [plugin.name for plugin in backend_plugins] - version_plugins = anitya_plugins.load_plugins(Session, family='versions') + version_plugins = anitya_plugins.load_plugins(Session, family="versions") version_plg_names = [plugin.name for plugin in version_plugins] form = anitya.forms.ProjectForm( - backends=plg_names, version_schemes=version_plg_names) - - if flask.request.method == 'GET': - form.name.data = flask.request.args.get('name', '') - form.homepage.data = flask.request.args.get('homepage', '') - form.backend.data = flask.request.args.get('backend', '') - form.version_scheme.data = flask.request.args.get('version_scheme', '') - form.distro.data = flask.request.args.get('distro', '') - form.package_name.data = flask.request.args.get('package_name', '') + backends=plg_names, version_schemes=version_plg_names + ) + + if flask.request.method == "GET": + form.name.data = flask.request.args.get("name", "") + form.homepage.data = flask.request.args.get("homepage", "") + form.backend.data = flask.request.args.get("backend", "") + form.version_scheme.data = flask.request.args.get("version_scheme", "") + form.distro.data = flask.request.args.get("distro", "") + form.package_name.data = flask.request.args.get("package_name", "") return flask.render_template( - 'project_new.html', - context='Add', - current='Add projects', + "project_new.html", + context="Add", + current="Add projects", form=form, plugins=backend_plugins, ) @@ -514,31 +502,35 @@ def new_project(): ) Session.commit() - flask.flash('Project created') + flask.flash("Project created") except exceptions.AnityaException as err: flask.flash(str(err)) - return flask.render_template( - 'project_new.html', - context='Add', - current='Add projects', - form=form, - plugins=backend_plugins - ), 409 + return ( + flask.render_template( + "project_new.html", + context="Add", + current="Add projects", + form=form, + plugins=backend_plugins, + ), + 409, + ) - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id) - ) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id)) - return flask.render_template( - 'project_new.html', - context='Add', - current='Add projects', - form=form, - plugins=backend_plugins - ), 400 + return ( + flask.render_template( + "project_new.html", + context="Add", + current="Add projects", + form=form, + plugins=backend_plugins, + ), + 400, + ) -@ui_blueprint.route('/project//edit', methods=['GET', 'POST']) +@ui_blueprint.route("/project//edit", methods=["GET", "POST"]) @login_required def edit_project(project_id): @@ -548,13 +540,12 @@ def edit_project(project_id): backend_plugins = anitya_plugins.load_plugins(Session) plg_names = [plugin.name for plugin in backend_plugins] - version_plugins = anitya_plugins.load_plugins(Session, family='versions') + version_plugins = anitya_plugins.load_plugins(Session, family="versions") version_plg_names = [plugin.name for plugin in version_plugins] form = anitya.forms.ProjectForm( - backends=plg_names, - version_schemes=version_plg_names, - obj=project) + backends=plg_names, version_schemes=version_plg_names, obj=project + ) if form.validate_on_submit(): try: @@ -573,28 +564,26 @@ def edit_project(project_id): check_release=form.check_release.data, ) if changes: - flask.flash('Project edited') + flask.flash("Project edited") else: - flask.flash('Project edited - No changes were made') - flask.session['justedit'] = True + flask.flash("Project edited - No changes were made") + flask.session["justedit"] = True except exceptions.AnityaException as err: - flask.flash(str(err), 'errors') + flask.flash(str(err), "errors") - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project_id) - ) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project_id)) return flask.render_template( - 'project_new.html', - context='Edit', - current='projects', + "project_new.html", + context="Edit", + current="projects", form=form, project=project, plugins=backend_plugins, ) -@ui_blueprint.route('/project//flag', methods=['GET', 'POST']) +@ui_blueprint.route("/project//flag", methods=["GET", "POST"]) @login_required def flag_project(project_id): @@ -602,8 +591,7 @@ def flag_project(project_id): if not project: flask.abort(404) - form = anitya.forms.FlagProjectForm( - obj=project) + form = anitya.forms.FlagProjectForm(obj=project) if form.validate_on_submit(): try: @@ -614,24 +602,22 @@ def flag_project(project_id): user_email=flask.g.user.email, user_id=flask.g.user.username, ) - flask.flash('Project flagged for admin review') + flask.flash("Project flagged for admin review") except exceptions.AnityaException as err: - flask.flash(str(err), 'errors') + flask.flash(str(err), "errors") - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id) - ) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id)) return flask.render_template( - 'project_flag.html', - context='Flag', - current='projects', + "project_flag.html", + context="Flag", + current="projects", form=form, project=project, ) -@ui_blueprint.route('/project//map', methods=['GET', 'POST']) +@ui_blueprint.route("/project//map", methods=["GET", "POST"]) @login_required def map_project(project_id): @@ -647,10 +633,9 @@ def map_project(project_id): form = anitya.forms.MappingForm(distros=distro_names) - if flask.request.method == 'GET': - form.package_name.data = flask.request.args.get( - 'package_name', project.name) - form.distro.data = flask.request.args.get('distro', '') + if flask.request.method == "GET": + form.package_name.data = flask.request.args.get("package_name", project.name) + form.distro.data = flask.request.args.get("distro", "") if form.validate_on_submit(): try: @@ -662,26 +647,21 @@ def map_project(project_id): user_id=flask.g.user.username, ) Session.commit() - flask.flash('Mapping added') + flask.flash("Mapping added") except exceptions.AnityaInvalidMappingException as err: - err.link = flask.url_for('anitya_ui.project', project_id=err.project_id) - flask.flash(err.message, 'error') + err.link = flask.url_for("anitya_ui.project", project_id=err.project_id) + flask.flash(err.message, "error") except exceptions.AnityaException as err: - flask.flash(str(err), 'error') + flask.flash(str(err), "error") - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project.id) - ) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project.id)) return flask.render_template( - 'mapping.html', - current='projects', - project=project, - form=form, + "mapping.html", current="projects", project=project, form=form ) -@ui_blueprint.route('/project//map/', methods=['GET', 'POST']) +@ui_blueprint.route("/project//map/", methods=["GET", "POST"]) @login_required def edit_project_mapping(project_id, pkg_id): @@ -715,46 +695,37 @@ def edit_project_mapping(project_id, pkg_id): ) Session.commit() - flask.flash('Mapping edited') + flask.flash("Mapping edited") except exceptions.AnityaInvalidMappingException as err: - err.link = flask.url_for('anitya_ui.project', project_id=err.project_id) - flask.flash(err.message, 'error') + err.link = flask.url_for("anitya_ui.project", project_id=err.project_id) + flask.flash(err.message, "error") except exceptions.AnityaException as err: - flask.flash(str(err), 'error') + flask.flash(str(err), "error") - return flask.redirect( - flask.url_for('anitya_ui.project', project_id=project_id)) + return flask.redirect(flask.url_for("anitya_ui.project", project_id=project_id)) return flask.render_template( - 'mapping.html', - current='projects', - project=project, - package=package, - form=form, + "mapping.html", current="projects", project=project, package=package, form=form ) def format_examples(examples): - ''' Return the plugins examples as HTML links. ''' - output = '' + """ Return the plugins examples as HTML links. """ + output = "" if examples: for cnt, example in enumerate(examples): if cnt > 0: output += "
    " - output += "%(url)s " % ({'url': example}) + output += "%(url)s " % ({"url": example}) return output def context_class(category): - ''' Return bootstrap context class for a given category. ''' - values = { - 'message': 'default', - 'error': 'danger', - 'info': 'info', - } - return values.get(category, 'warning') + """ Return bootstrap context class for a given category. """ + values = {"message": "default", "error": "danger", "info": "info"} + return values.get(category, "warning") -ui_blueprint.add_app_template_filter(format_examples, name='format_examples') -ui_blueprint.add_app_template_filter(context_class, name='context_class') +ui_blueprint.add_app_template_filter(format_examples, name="format_examples") +ui_blueprint.add_app_template_filter(context_class, name="context_class") diff --git a/anitya_schema/anitya_schema/distro_messages.py b/anitya_schema/anitya_schema/distro_messages.py index a9d893644..29cce6213 100644 --- a/anitya_schema/anitya_schema/distro_messages.py +++ b/anitya_schema/anitya_schema/distro_messages.py @@ -56,7 +56,9 @@ def __str__(self): @property def summary(self): """Return a short summary of the message.""" - return "A new distribution, {}, was added to release-monitoring.".format(self.name) + return "A new distribution, {}, was added to release-monitoring.".format( + self.name + ) @property def name(self): diff --git a/anitya_schema/anitya_schema/project_messages.py b/anitya_schema/anitya_schema/project_messages.py index d09c9d083..988b5766f 100644 --- a/anitya_schema/anitya_schema/project_messages.py +++ b/anitya_schema/anitya_schema/project_messages.py @@ -109,7 +109,7 @@ class ProjectEdited(message.Message): }, "required": ["agent", "project"], }, - "project": project_schema + "project": project_schema, }, } @@ -151,7 +151,7 @@ class ProjectDeleted(message.Message): }, "required": ["agent", "project"], }, - "project": project_schema + "project": project_schema, }, } @@ -207,7 +207,9 @@ def __str__(self): @property def summary(self): """Return a summary of the message.""" - return "A flag was created on project {} in release-monitoring.".format(self.name) + return "A flag was created on project {} in release-monitoring.".format( + self.name + ) @property def name(self): @@ -299,7 +301,9 @@ def __str__(self): @property def summary(self): """Return a summary of the message.""" - return "A new mapping was created for project {} in release-monitoring.".format(self.name) + return "A new mapping was created for project {} in release-monitoring.".format( + self.name + ) @property def name(self): @@ -347,7 +351,8 @@ def __str__(self): def summary(self): """Return a summary of the message.""" return "A mapping for project {} was edited in release-monitoring.".format( - self.name) + self.name + ) @property def name(self): @@ -388,7 +393,8 @@ def __str__(self): def summary(self): """Return a summary of the message.""" return "A mapping for project {} was deleted in release-monitoring.".format( - self.name) + self.name + ) @property def name(self): @@ -441,7 +447,8 @@ def __str__(self): def summary(self): """Return a summary of the message.""" return "A new version '{}' was found for project {} in release-monitoring.".format( - self.version, self.name) + self.version, self.name + ) @property def name(self): @@ -487,7 +494,8 @@ def __str__(self): def summary(self): """Return a summary of the message.""" return "A version '{}' was deleted in project {} in release-monitoring.".format( - self.version, self.name) + self.version, self.name + ) @property def name(self): diff --git a/anitya_schema/anitya_schema/tests/__init__.py b/anitya_schema/anitya_schema/tests/__init__.py index 2745be6e7..eb45b0ce2 100644 --- a/anitya_schema/anitya_schema/tests/__init__.py +++ b/anitya_schema/anitya_schema/tests/__init__.py @@ -16,5 +16,4 @@ import os -FIXTURES_DIR = os.path.abspath( - os.path.join(os.path.dirname(__file__), "fixtures/")) +FIXTURES_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "fixtures/")) diff --git a/anitya_schema/anitya_schema/tests/test_distro_messages.py b/anitya_schema/anitya_schema/tests/test_distro_messages.py index 51495972d..e22bcfb96 100644 --- a/anitya_schema/anitya_schema/tests/test_distro_messages.py +++ b/anitya_schema/anitya_schema/tests/test_distro_messages.py @@ -18,11 +18,7 @@ import unittest import mock -from anitya_schema import ( - DistroCreated, - DistroEdited, - DistroDeleted -) +from anitya_schema import DistroCreated, DistroEdited, DistroDeleted class TestDistroCreated(unittest.TestCase): @@ -33,35 +29,31 @@ def setUp(self): self.message = DistroCreated() @mock.patch( - 'anitya_schema.distro_messages.DistroCreated.summary', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroCreated.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.distro_messages.DistroCreated.name', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroCreated.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A new distribution, Dummy, was added to release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "distro": { - "name": "Dummy" - } - } + self.message.body = {"distro": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestDistroEdited(unittest.TestCase): @@ -72,50 +64,42 @@ def setUp(self): self.message = DistroEdited() @mock.patch( - 'anitya_schema.distro_messages.DistroEdited.summary', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroEdited.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.distro_messages.DistroEdited.new_name', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroEdited.new_name", + new_callable=mock.PropertyMock, ) @mock.patch( - 'anitya_schema.distro_messages.DistroEdited.old_name', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroEdited.old_name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_old_name, mock_new_name): """ Assert that correct summary string is returned. """ - mock_new_name.return_value = 'New name' - mock_old_name.return_value = 'Old name' + mock_new_name.return_value = "New name" + mock_old_name.return_value = "Old name" exp = "The name of the Old name distribution changed to New name." self.assertEqual(self.message.summary, exp) def test_new_name(self): """ Assert that new_name string is returned. """ - self.message.body = { - "message": { - "new": "Dummy" - } - } + self.message.body = {"message": {"new": "Dummy"}} - self.assertEqual(self.message.new_name, 'Dummy') + self.assertEqual(self.message.new_name, "Dummy") def test_old_name(self): """ Assert that old_name string is returned. """ - self.message.body = { - "message": { - "old": "Dummy" - } - } + self.message.body = {"message": {"old": "Dummy"}} - self.assertEqual(self.message.old_name, 'Dummy') + self.assertEqual(self.message.old_name, "Dummy") class TestDistroDeleted(unittest.TestCase): @@ -126,32 +110,28 @@ def setUp(self): self.message = DistroDeleted() @mock.patch( - 'anitya_schema.distro_messages.DistroDeleted.summary', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroDeleted.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.distro_messages.DistroDeleted.name', - new_callable=mock.PropertyMock + "anitya_schema.distro_messages.DistroDeleted.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "The Dummy distribution was removed from release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "message": { - "distro": "Dummy" - } - } + self.message.body = {"message": {"distro": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") diff --git a/anitya_schema/anitya_schema/tests/test_project_messages.py b/anitya_schema/anitya_schema/tests/test_project_messages.py index 880f6c78d..11974f2a7 100644 --- a/anitya_schema/anitya_schema/tests/test_project_messages.py +++ b/anitya_schema/anitya_schema/tests/test_project_messages.py @@ -40,35 +40,31 @@ def setUp(self): self.message = ProjectCreated() @mock.patch( - 'anitya_schema.project_messages.ProjectCreated.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectCreated.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectCreated.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectCreated.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A new project, Dummy, was added to release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectEdited(unittest.TestCase): @@ -79,35 +75,31 @@ def setUp(self): self.message = ProjectEdited() @mock.patch( - 'anitya_schema.project_messages.ProjectEdited.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectEdited.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectEdited.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectEdited.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A project, Dummy, was edited in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectDeleted(unittest.TestCase): @@ -118,35 +110,31 @@ def setUp(self): self.message = ProjectDeleted() @mock.patch( - 'anitya_schema.project_messages.ProjectDeleted.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectDeleted.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectDeleted.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectDeleted.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A project, Dummy, was deleted in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectFlag(unittest.TestCase): @@ -157,35 +145,31 @@ def setUp(self): self.message = ProjectFlag() @mock.patch( - 'anitya_schema.project_messages.ProjectFlag.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectFlag.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectFlag.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectFlag.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A flag was created on project Dummy in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectFlagSet(unittest.TestCase): @@ -196,50 +180,42 @@ def setUp(self): self.message = ProjectFlagSet() @mock.patch( - 'anitya_schema.project_messages.ProjectFlagSet.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectFlagSet.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectFlagSet.flag', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectFlagSet.flag", + new_callable=mock.PropertyMock, ) @mock.patch( - 'anitya_schema.project_messages.ProjectFlagSet.state', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectFlagSet.state", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_state, mock_flag): """ Assert that correct summary string is returned. """ - mock_flag.return_value = '007' - mock_state.return_value = 'closed' + mock_flag.return_value = "007" + mock_state.return_value = "closed" exp = "A flag '007' was closed in release-monitoring." self.assertEqual(self.message.summary, exp) def test_flag(self): """ Assert that flag string is returned. """ - self.message.body = { - "message": { - "flag": "Dummy" - } - } + self.message.body = {"message": {"flag": "Dummy"}} - self.assertEqual(self.message.flag, 'Dummy') + self.assertEqual(self.message.flag, "Dummy") def test_state(self): """ Assert that state string is returned. """ - self.message.body = { - "message": { - "state": "Dummy" - } - } + self.message.body = {"message": {"state": "Dummy"}} - self.assertEqual(self.message.state, 'Dummy') + self.assertEqual(self.message.state, "Dummy") class TestProjectMapCreated(unittest.TestCase): @@ -250,35 +226,31 @@ def setUp(self): self.message = ProjectMapCreated() @mock.patch( - 'anitya_schema.project_messages.ProjectMapCreated.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapCreated.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectMapCreated.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapCreated.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A new mapping was created for project Dummy in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectMapEdited(unittest.TestCase): @@ -289,35 +261,31 @@ def setUp(self): self.message = ProjectMapEdited() @mock.patch( - 'anitya_schema.project_messages.ProjectMapEdited.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapEdited.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectMapEdited.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapEdited.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A mapping for project Dummy was edited in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectMapDeleted(unittest.TestCase): @@ -328,35 +296,31 @@ def setUp(self): self.message = ProjectMapDeleted() @mock.patch( - 'anitya_schema.project_messages.ProjectMapDeleted.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapDeleted.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectMapDeleted.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectMapDeleted.name", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_property): """ Assert that correct summary string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" exp = "A mapping for project Dummy was deleted in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") class TestProjectVersionUpdated(unittest.TestCase): @@ -367,50 +331,42 @@ def setUp(self): self.message = ProjectVersionUpdated() @mock.patch( - 'anitya_schema.project_messages.ProjectVersionUpdated.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionUpdated.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectVersionUpdated.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionUpdated.name", + new_callable=mock.PropertyMock, ) @mock.patch( - 'anitya_schema.project_messages.ProjectVersionUpdated.version', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionUpdated.version", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_version, mock_name): """ Assert that correct summary string is returned. """ - mock_name.return_value = 'Dummy' - mock_version.return_value = '1.0.0' + mock_name.return_value = "Dummy" + mock_version.return_value = "1.0.0" exp = "A new version '1.0.0' was found for project Dummy in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") def test_version(self): """ Assert that version string is returned. """ - self.message.body = { - "message": { - "upstream_version": "1.0.0" - } - } + self.message.body = {"message": {"upstream_version": "1.0.0"}} - self.assertEqual(self.message.version, '1.0.0') + self.assertEqual(self.message.version, "1.0.0") class TestProjectVersionDeleted(unittest.TestCase): @@ -421,47 +377,39 @@ def setUp(self): self.message = ProjectVersionDeleted() @mock.patch( - 'anitya_schema.project_messages.ProjectVersionDeleted.summary', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionDeleted.summary", + new_callable=mock.PropertyMock, ) def test__str__(self, mock_property): """ Assert that correct string is returned. """ - mock_property.return_value = 'Dummy' + mock_property.return_value = "Dummy" - self.assertEqual(self.message.__str__(), 'Dummy') + self.assertEqual(self.message.__str__(), "Dummy") @mock.patch( - 'anitya_schema.project_messages.ProjectVersionDeleted.name', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionDeleted.name", + new_callable=mock.PropertyMock, ) @mock.patch( - 'anitya_schema.project_messages.ProjectVersionDeleted.version', - new_callable=mock.PropertyMock + "anitya_schema.project_messages.ProjectVersionDeleted.version", + new_callable=mock.PropertyMock, ) def test_summary(self, mock_version, mock_name): """ Assert that correct summary string is returned. """ - mock_name.return_value = 'Dummy' - mock_version.return_value = '1.0.0' + mock_name.return_value = "Dummy" + mock_version.return_value = "1.0.0" exp = "A version '1.0.0' was deleted in project Dummy in release-monitoring." self.assertEqual(self.message.summary, exp) def test_name(self): """ Assert that name string is returned. """ - self.message.body = { - "project": { - "name": "Dummy" - } - } + self.message.body = {"project": {"name": "Dummy"}} - self.assertEqual(self.message.name, 'Dummy') + self.assertEqual(self.message.name, "Dummy") def test_version(self): """ Assert that version string is returned. """ - self.message.body = { - "message": { - "version": "1.0.0" - } - } + self.message.body = {"message": {"version": "1.0.0"}} - self.assertEqual(self.message.version, '1.0.0') + self.assertEqual(self.message.version, "1.0.0") diff --git a/ansible/roles/anitya-dev/tasks/main.yml b/ansible/roles/anitya-dev/tasks/main.yml index 348cb4ffc..a1455aa23 100644 --- a/ansible/roles/anitya-dev/tasks/main.yml +++ b/ansible/roles/anitya-dev/tasks/main.yml @@ -9,7 +9,8 @@ python-devel, python35, python36, - python37 + python37, + python3-black ] state: present diff --git a/createdb.py b/createdb.py index 4f7f48932..254e17a8b 100644 --- a/createdb.py +++ b/createdb.py @@ -4,8 +4,4 @@ from anitya.config import config from anitya.lib import utilities -utilities.init( - config['DB_URL'], - None, - debug=True, - create=True) +utilities.init(config["DB_URL"], None, debug=True, create=True) diff --git a/docs/conf.py b/docs/conf.py index 110e5e67e..55cd49efc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -34,44 +34,44 @@ import os import sys -sys.path.insert(0, os.path.abspath('../')) # NOQA +sys.path.insert(0, os.path.abspath("../")) # NOQA from anitya import app extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.viewcode', - 'sphinx.ext.napoleon', - 'sphinxcontrib.autohttp.flask', + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx.ext.napoleon", + "sphinxcontrib.autohttp.flask", ] autosummary_generate = True # Add any paths # that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'index' +master_doc = "index" # General information about the project. -project = 'Anitya' -copyright = '2019, Red Hat, Inc. and others' -author = 'Red Hat, Inc. and others' +project = "Anitya" +copyright = "2019, Red Hat, Inc. and others" +author = "Red Hat, Inc. and others" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -79,7 +79,7 @@ # # The short X.Y version. # The short X.Y version. -version = '.'.join(app.__version__.split('.')[:2]) +version = ".".join(app.__version__.split(".")[:2]) # The full version, including alpha/beta/rc tags. release = app.__version__ @@ -102,7 +102,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -124,7 +124,7 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -141,7 +141,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = "alabaster" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -149,10 +149,10 @@ # # html_theme_options = {} html_theme_options = { - 'logo_name': True, - 'github_user': 'release-monitoring', - 'github_repo': 'anitya', - 'page_width': '1040px', + "logo_name": True, + "github_user": "release-monitoring", + "github_repo": "anitya", + "page_width": "1040px", } # Add any paths that contain custom themes here, relative to this directory. @@ -181,7 +181,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = ["_static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied @@ -203,12 +203,12 @@ # Custom sidebar templates, maps document names to template names. # html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', # needs 'show_related': True theme option to display - 'searchbox.html', - 'donate.html', + "**": [ + "about.html", + "navigation.html", + "relations.html", # needs 'show_related': True theme option to display + "searchbox.html", + "donate.html", ] } @@ -269,34 +269,36 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'Anityadoc' +htmlhelp_basename = "Anityadoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'Anitya.tex', 'Anitya Documentation', - 'Red Hat, Inc. and others', 'manual'), + ( + master_doc, + "Anitya.tex", + "Anitya Documentation", + "Red Hat, Inc. and others", + "manual", + ) ] # The name of an image file (relative to this directory) to place at the top of @@ -336,10 +338,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'anitya', 'Anitya Documentation', - [author], 1) -] +man_pages = [(master_doc, "anitya", "Anitya Documentation", [author], 1)] # If true, show URL addresses after external links. # @@ -352,9 +351,15 @@ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'Anitya', 'Anitya Documentation', - author, 'Anitya', 'One line description of project.', - 'Miscellaneous'), + ( + master_doc, + "Anitya", + "Anitya Documentation", + author, + "Anitya", + "One line description of project.", + "Miscellaneous", + ) ] # Documents to append as an appendix to all manuals. @@ -374,7 +379,7 @@ # texinfo_no_detailmenu = False intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), - 'fedmsg': ('https://fedmsg.readthedocs.io/en/stable/', None), - 'sqlalchemy': ('https://docs.sqlalchemy.org/en/latest/', None), + "python": ("https://docs.python.org/3", None), + "fedmsg": ("https://fedmsg.readthedocs.io/en/stable/", None), + "sqlalchemy": ("https://docs.sqlalchemy.org/en/latest/", None), } diff --git a/fedmsg.d/fedmsg-config.py b/fedmsg.d/fedmsg-config.py index f4602493e..0eafb5286 100644 --- a/fedmsg.d/fedmsg-config.py +++ b/fedmsg.d/fedmsg-config.py @@ -3,14 +3,12 @@ """ config = { - 'zmq_enabled': True, - 'active': True, - 'endpoints': { - "relay_outbound": ["tcp://127.0.0.1:4011"], - }, - 'relay_inbound': "tcp://127.0.0.1:2013", - 'environment': "dev", - 'sign_messages': False, - 'validate_signatures': False, - 'anitya.libraryio.enabled': True + "zmq_enabled": True, + "active": True, + "endpoints": {"relay_outbound": ["tcp://127.0.0.1:4011"]}, + "relay_inbound": "tcp://127.0.0.1:2013", + "environment": "dev", + "sign_messages": False, + "validate_signatures": False, + "anitya.libraryio.enabled": True, } diff --git a/files/anitya_cron.py b/files/anitya_cron.py index 3809c8c14..be7ec75de 100644 --- a/files/anitya_cron.py +++ b/files/anitya_cron.py @@ -4,6 +4,7 @@ import sys import logging from threading import Lock + # We need to use multiprocessing.dummy, since we use the Pool to run # update_project. This in turn uses anitya.lib.backends.BaseBackend.call_url, # which utilizes a global requests session. Requests session is not usable @@ -21,7 +22,7 @@ import anitya import anitya.lib.exceptions -LOG = logging.getLogger('anitya') +LOG = logging.getLogger("anitya") """ This dictionary is used for backend blacklisting. @@ -57,8 +58,7 @@ def projects_by_feed(session): If a new entry is noticed and we don't have a project for it, add it. """ for name, homepage, backend, version in indexed_listings(): - project = db.Project.get_or_create( - session, name, homepage, backend) + project = db.Project.get_or_create(session, name, homepage, backend) if project.latest_version == version: LOG.debug("Project %s is already up to date." % project.name) else: @@ -84,28 +84,31 @@ def update_project(project_id): utilities.check_project_release(project, session), except anitya.lib.exceptions.RateLimitException as err: with blacklist_lock: - LOG.debug("Rate limit threshold reached. Adding {} to blacklist.".format( - project.backend - )) - blacklist_dict[project.backend] = err.reset_time.to('utc').datetime + LOG.debug( + "Rate limit threshold reached. Adding {} to blacklist.".format( + project.backend + ) + ) + blacklist_dict[project.backend] = err.reset_time.to("utc").datetime except anitya.lib.exceptions.AnityaException as err: LOG.info(err) def main(debug, feed): - ''' Retrieve all the packages and for each of them update the release + """ Retrieve all the packages and for each of them update the release version. - ''' + """ time = arrow.utcnow().datetime db.initialize(config) session = db.Session() - run = db.Run(status='started') + run = db.Run(status="started") session.add(run) session.commit() LOG.setLevel(logging.DEBUG) formatter = logging.Formatter( - '%(asctime)s - %(name)s - %(levelname)s - %(message)s') + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) if debug: # Console handler @@ -115,7 +118,7 @@ def main(debug, feed): LOG.addHandler(chand) # Save the logs in a file - fhand = logging.FileHandler('/var/tmp/anitya_cron.log') + fhand = logging.FileHandler("/var/tmp/anitya_cron.log") fhand.setLevel(logging.INFO) fhand.setFormatter(formatter) LOG.addHandler(fhand) @@ -125,23 +128,25 @@ def main(debug, feed): session.commit() else: # Get all projects, that are ready for check - projects = db.Project.query.order_by( - sa.func.lower(db.Project.name) - ).filter(db.Project.next_check < time).all() + projects = ( + db.Project.query.order_by(sa.func.lower(db.Project.name)) + .filter(db.Project.next_check < time) + .all() + ) project_ids = [project.id for project in projects] - N = config.get('CRON_POOL', 10) + N = config.get("CRON_POOL", 10) LOG.info("Launching pool (%i) to update %i projects", N, len(project_ids)) p = multiprocessing.Pool(N) p.map(update_project, project_ids) - run = db.Run(status='ended') + run = db.Run(status="ended") session.add(run) session.commit() -if __name__ == '__main__': - debug = '--debug' in sys.argv - feed = '--check-feed' in sys.argv +if __name__ == "__main__": + debug = "--debug" in sys.argv + feed = "--check-feed" in sys.argv main(debug=debug, feed=feed) diff --git a/news/PR725.dev b/news/PR725.dev new file mode 100644 index 000000000..5d52e4e3c --- /dev/null +++ b/news/PR725.dev @@ -0,0 +1 @@ +Check formatting using black diff --git a/news/get-authors.py b/news/get-authors.py index 4f6acc9ae..bec64e9ff 100644 --- a/news/get-authors.py +++ b/news/get-authors.py @@ -25,7 +25,9 @@ last_tag = check_output(["git", "describe", "--abbrev=0"], universal_newlines=True) authors = {} log_range = last_tag.strip() + "..HEAD" -output = check_output(["git", "log", log_range, "--format=%ae\t%an"], universal_newlines=True) +output = check_output( + ["git", "log", log_range, "--format=%ae\t%an"], universal_newlines=True +) for line in output.splitlines(): email, fullname = line.split("\t") email = email.split("@")[0].replace(".", "") diff --git a/request_oidc_credentials.py b/request_oidc_credentials.py index 225216389..e34eb8ccd 100755 --- a/request_oidc_credentials.py +++ b/request_oidc_credentials.py @@ -4,6 +4,7 @@ import json import os.path import webbrowser + try: # Default to Python 3 from http.server import HTTPServer, BaseHTTPRequestHandler @@ -18,14 +19,12 @@ AUTH_TIMEOUT = 300 _this_dir = os.path.dirname(__file__) SECRETS_FILE = os.path.join(_this_dir, "client_secrets.json") -CREDENTIALS_FILE = os.path.join(_this_dir, - "anitya", - "tests", - "oidc_credentials.json") +CREDENTIALS_FILE = os.path.join(_this_dir, "anitya", "tests", "oidc_credentials.json") class OAuthCallbackHandler(BaseHTTPRequestHandler): """Callback handler to log the details of received OAuth callbacks""" + def do_GET(self): self.server.oauth_callbacks.append(self.path) self.send_response(200) @@ -36,6 +35,7 @@ def do_GET(self): class OAuthCallbackServer(HTTPServer): """Local HTTP server to handle OAuth authentication callbacks""" + def __init__(self, server_address): self.oauth_callbacks = [] HTTPServer.__init__(self, server_address, OAuthCallbackHandler) @@ -43,7 +43,7 @@ def __init__(self, server_address): def receive_oauth_callback(timeout): """Blocking call to wait for a single OAuth authentication callback""" - server_address = ('', 5000) + server_address = ("", 5000) oauthd = OAuthCallbackServer(server_address) oauthd.timeout = timeout try: @@ -67,7 +67,8 @@ def main(): token_uri = client_details["token_uri"] scopes = ( # Access user email address for audit trail logging - "openid", "email", + "openid", + "email", # Submit new project monitoring requests "https://release-monitoring.org/oidc/upstream", ) @@ -82,13 +83,10 @@ def main(): if cb_state != state: msg = "Callback state {0!r} didn't match request state {1!r}" raise RuntimeError(msg.format(cb_state, state)) - client_token = oauth.fetch_token(token_uri, - code=authorization_code, - client_secret=client_secret) - oidc_credentials = { - "client_details": client_details, - "client_token": client_token - } + client_token = oauth.fetch_token( + token_uri, code=authorization_code, client_secret=client_secret + ) + oidc_credentials = {"client_details": client_details, "client_token": client_token} with open(CREDENTIALS_FILE, "w") as f: json.dump(oidc_credentials, f) print("OIDC client access details saved as " + CREDENTIALS_FILE) diff --git a/setup.py b/setup.py index 5d9966e99..b5dbef815 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ def get_project_version(): """Read the declared version of the project from the source code""" version_file = "anitya/__init__.py" with open(version_file, "rb") as f: - version_pattern = b"^__version__ = '(.+)'$" + version_pattern = b'^__version__ = "(.+)"$' match = re.search(version_pattern, f.read(), re.MULTILINE) if match is None: err_msg = "No line matching %r found in %r" @@ -20,7 +20,7 @@ def get_project_version(): return match.groups()[0].decode("utf-8") -def get_requirements(requirements_file='requirements.txt'): +def get_requirements(requirements_file="requirements.txt"): """Get the contents of a file listing the requirements. :arg requirements_file: path to a requirements file @@ -34,16 +34,16 @@ def get_requirements(requirements_file='requirements.txt'): dependencies = [] for line in lines: maybe_dep = line.strip() - if maybe_dep.startswith('#'): + if maybe_dep.startswith("#"): # Skip pure comment lines continue - if maybe_dep.startswith('git+'): + if maybe_dep.startswith("git+"): # VCS reference for dev purposes, expect a trailing comment # with the normal requirement - __, __, maybe_dep = maybe_dep.rpartition('#') + __, __, maybe_dep = maybe_dep.rpartition("#") else: # Ignore any trailing comment - maybe_dep, __, __ = maybe_dep.partition('#') + maybe_dep, __, __ = maybe_dep.partition("#") # Remove any whitespace and assume non-empty results are dependencies maybe_dep = maybe_dep.strip() if maybe_dep: @@ -52,25 +52,25 @@ def get_requirements(requirements_file='requirements.txt'): setup( - name='anitya', - description='anitya is a project to monitor upstream releases in a distro.', + name="anitya", + description="anitya is a project to monitor upstream releases in a distro.", version=get_project_version(), - author='Pierre-Yves Chibon', - author_email='pingou@pingoured.fr', - maintainer='Pierre-Yves Chibon', - maintainer_email='pingou@pingoured.fr', - license='GPLv2+', - download_url='https://fedorahosted.org/releases/a/n/anitya/', - url='https://fedorahosted.org/anitya/', + author="Pierre-Yves Chibon", + author_email="pingou@pingoured.fr", + maintainer="Pierre-Yves Chibon", + maintainer_email="pingou@pingoured.fr", + license="GPLv2+", + download_url="https://fedorahosted.org/releases/a/n/anitya/", + url="https://fedorahosted.org/anitya/", classifiers=[ "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", ], - packages=find_packages(exclude=['anitya.tests', 'anitya.tests.*']), + packages=find_packages(exclude=["anitya.tests", "anitya.tests.*"]), include_package_data=True, - scripts=['files/anitya_cron.py', 'anitya/sar.py'], + scripts=["files/anitya_cron.py", "anitya/sar.py"], install_requires=get_requirements(), - test_suite='anitya.tests', + test_suite="anitya.tests", entry_points=""" [moksha.consumer] librariesio = anitya.librariesio_consumer:LibrariesioConsumer diff --git a/tox.ini b/tox.ini index bee1e6bb7..a4459aeb1 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,lint,bandit,docs +envlist = py36,py37,lint,format,bandit,docs [testenv] passenv = TRAVIS TRAVIS_* @@ -36,6 +36,11 @@ deps = commands = python -m flake8 {posargs} +[testenv:format] +deps = black +commands = + python -m black --check {posargs:.} + [testenv:bandit] deps = bandit commands = @@ -44,4 +49,5 @@ commands = [flake8] show-source = True max-line-length = 100 +ignore = E203,W503 exclude = .git,.tox,dist,*egg,build,files