hooks: if available, use sys.executable as executable for git hooks
Windows doesn't necessarily have "python2" available in $PATH, but we still want to make sure we don't end up invoking a python3. Using the absolute path seems more safe.
notifications: improve response time when number of notifications is large
NotificationsController always retrieved materialized list of all notifications in database, even to display only 10 of them. This is improved by feeding SQLAlchemy Query object directly to webhelpers.paginate.Page, avoiding eager load of all notifications.
(4.x seems like a more major upgrade - we stick to the 3 series for now.)
Note that select2-bootstrap.css *not* is upgraded. It is a separate thing (see LICENSE.md) and currently unused. (Select2 now has similar functionality built in - that should perhaps be used with Bootstrap instead.)
This creates a separate "Upgrading Kallithea" section, instead of trying (and failing) to repeat the same information for each installation page. Trying to maintain upgrade instructions for each installation method was perhaps overly ambitious. In practice, only the Linux instructions were up-to-date.
(Incidentally, this is kind of a throwback to Kallithea 0.1, which also had a separate upgrade section.)
templates: use a better class name for an enabled toggle button
"btn-success" is rather a poor choice for a class applied when the button is active, "active" is better for that. A side effect of the change is that "Enabled" is now shown in bold.
Use markup from Web Accessibility Initiative - it is default in Bootstrap examples and "comes for free" but is currently not used, complete, or tested.
Use Bootstrap classes for dropdowns. Use explicit Bootstrap-style carets instead of :after preudoclass. Use Bootstrap class for badges. Introduce Bootstrap data-toggle properties - currently unused.
cleanup: remove dead code and templates related to 'Switch To'
a33448d81f70 introduced a new 'Switch To' functionality and removed the last reference to branch_tag_switcher and thus to switch_to_list.html and the tags, bookmarks and branches pages.
We don't need these pages ... and if we do, we will implement them differently. They are mostly YUI datatables with compare links that only can compare within the same kind of revision names.
pytest migration: rename TestControllerPytest back to TestController
The name TestControllerPytest was introduced to allow a temporary situation where nose/unittest and pytest-based tests could coexist. This situation is now over, so the base test class can be renamed again.
pytest migration: move init_stack under TestControllerPytest
Avoid top-level methods if they could be placed under classes. The init_stack method is only used from TestControllerPytest so it makes sense to scope it under that class.
pytest migration: backout declassification of remove_all_notifications
In order to accomodate both nose/unittest and pytest at the same time, method remove_all_notifications has been extracted from BaseTestCase in commit 37d713674f63. Now that nose/unittest is no longer used, we can backout this change again.
pytest migration: __init__: switch to standard assert statements
Use unittest2pytest to replace unittest-style assert statements (e.g. assertEqual) with standard Python assert statements to benefit from pytest's improved reporting on assert failures.
pytest migration: functional: switch to standard assert statements
Use unittest2pytest to replace unittest-style assert statements (e.g. assertEqual) with standard Python assert statements to benefit from pytest's improved reporting on assert failures.
The conversion by unittest2pytest was correct, except for line wrapping problems.
pytest migration: api: switch to standard assert statements
Use unittest2pytest to replace unittest-style assert statements (e.g. assertEqual) with standard Python assert statements to benefit from pytest's improved reporting on assert failures.
pytest migration: models: switch to standard assert statements
Use unittest2pytest to replace unittest-style assert statements (e.g. assertEqual) with standard Python assert statements to benefit from pytest's improved reporting on assert failures.
The conversion by unittest2pytest was correct except for: - 'import pytest' is not automatically added when needed - line wrapping in string formatting caused a syntax error in the transformed code. Reported upstream at https://github.com/pytest-dev/unittest2pytest/issues/3 . - in assertRaises with a lambda, the lambda needs to be removed
pytest migration: other: switch to standard assert statements
Use unittest2pytest to replace unittest-style assert statements (e.g. assertEqual) with standard Python assert statements to benefit from pytest's improved reporting on assert failures.
The conversion by unittest2pytest was correct except for: - 'import pytest' is not automatically added when needed - line wrapping in string formatting caused a syntax error in the transformed code. Reported upstream at https://github.com/pytest-dev/unittest2pytest/issues/3 .
pytest migration: add args/kwargs to assertRaises replacement
Even though we'll soon get rid of the assertRaises replacement, the tests in kallithea/tests/other/test_validators.py expect to pass it args and kwargs so we need to adapt it first.
tests: api: fix intertest dependency on repository locking
In test classes based on unittest, tests are executed in alphabetical order. In test classes based on pytest, tests are executed in the order they are specified. This difference revealed a problem in the API tests:
- test_api_lock_repo_lock_optional_locked locks the test repository - test_api_get_locks_regular_user gets the current locks and expects it to be empty
With unittest as base class, this worked fine because the 'get_locks' group of tests are executed before the 'lock_repo' group (alphabetical order). Using a real pytest-based test class, the order is swapped and the locked repository from the first test invalidates the preconditions of the second test.
Fix this specific problem by releasing the lock from test_api_lock_repo_lock_optional_locked.
This commit does not fix other interdependencies between tests. For example, test_api_lock_repo_lock_optional_locked expects the existing lock state to be 'locked' but did not lock the repo itself; instead it expects a previous test to have locked. In practice, this is test_api_lock_repo_lock_aquire_optional_userid. A full solution would make each test fully self contained so that tests can be executed in random order. The pytest extension pytest-random can help detecting these problems.
pullrequests: reword the grumpy "Rejected" to the more neutral and factual "Not approved"
"Rejecting" could be considered rude and some reviewers were thus reluctant to use it. Rewording it might give reviewers a voice to better express their feelings.
pull requests: prevent adding DEFAULT user as reviewer
Add a helper method to resolve reviewers, with an added check to prevent the adding of the DEFAULT user as reviewer.
The __add_reviewers method, although internal, had a troubling interface where the method was responsible for resolving reviewers, but the caller was responsible for resolving mention_recipients. The method is changed to always take two sets of database User objects, leaving the resolution to the caller in both cases.
Previously, extract_mentioned_users performed a regex search, converted to a set to remove duplicates, converted that set back into a list, and sorted the list on username, ignoring case. Every single caller of the function then promptly took the carefully pruned and sorted result and put it back into a set, rendering the entire exercise pointless.
In addition, every caller also resolved the usernames to database User objects.
In this changeset, extract_mentioned_users is changed to return a set of database User objects directly. A new extract_mentioned_usernames function, which does only username extraction, is kept for the sole purpose of providing a more testable interface (no database needed).
Bonus feature: The new extract_mentioned_users will prune non-existent users, as well as the DEFAULT user. This means it is no longer possible to @mention (and send notifications to) the DEFAULT user.
This removes a broken permission check when viewing notifications (the HasRepoPermissionAny object was created, but never actually called with a repo_name argument as required). It would be non-trivial to actually implement the check, as notifications don't track their repository relationship explicitly, and even then, it's unclear why it would make sense to allow a repository admin to see notifications to other users.
It was never a vulnerability, due to a subsequent (and much stricter) ownership check, which remains but has been untangled for readability. In short, this changeset is a pure refactoring, except that specifying a non-existent notification ID will now produce error 404, not 403.
pytest-sugar enables a nice visual representation of test progress and results. Minimum version is set to 0.7.0 as it fixes a problem where skipped tests would not be shown in the test summary. The upper version 1.0.0 is arbitrarily chosen and could be increased as seen fit.