-
-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add missing permission checks in runs/get_case_runs.html #750
Conversation
Codecov Report
@@ Coverage Diff @@
## master #750 +/- ##
==========================================
- Coverage 73.42% 66.97% -6.45%
==========================================
Files 111 114 +3
Lines 4753 5893 +1140
Branches 607 782 +175
==========================================
+ Hits 3490 3947 +457
- Misses 1041 1706 +665
- Partials 222 240 +18
Continue to review full report at Codecov.
|
Pull Request Test Coverage Report for Build 2407
💛 - Coveralls |
Pull Request Test Coverage Report for Build 3165
💛 - Coveralls |
3ab16c5
to
2f94d5c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix MissingPermissionsChecker visit_module booliean condition
- fix the typo in the commit log
- explain why you do this, not only what you have done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix the commit log for the linter so I can cherry-pick it. The rest will need a lot more work before it is ready.
tcms/testruns/tests/test_views.py
Outdated
username=self.tester.username, | ||
password='password') | ||
|
||
def getNewResponse(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't need a function that has only 2 lines. Repeating them, specially in tests is just fine. It saves you from having to go back and see what this function does.
tcms/testruns/tests/test_views.py
Outdated
self.getNewResponse() | ||
|
||
for html_string in self.menu_html: | ||
self.assertContains(self.response, html_string, html=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not very nice. These should be separate test methods so that when something fails we know what failed. Otherwise when this method fails we have to spend the time to debug the entire menu and its permissions to figure out which exactly part failed.
While at it the menu_html list should become separate variables for each part of the menu.
tcms/testruns/tests/test_views.py
Outdated
self.getNewResponse() | ||
|
||
for html_string in self.menu_html: | ||
self.assertNotContains(self.response, html_string, html=True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, separate test methods so we know what and when fails!
<li><a href="#" class="addBlue9 js-show-commentdialog">{% trans "Add" %}</a></li> | ||
</ul> | ||
</div> | ||
{% if perms.testruns.change_testcaserun %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testruns.change_testcaserun
means to edit the TestCaseRun
object, that is to be able to edit the recorded status of a test execution which we don't do.
Only the 'Update' and 'Assignee' actions in this menu are controlled by this permission so it is wrong to surround the entire sub-menu with it.
{% if perms.testruns.delete_testcaserun %} | ||
<li><a href="#" title="Remove selected cases form this test run" data-param="{{ test_run.run_id }}" class="removeBlue9 js-del-case">{% trans "Remove" %}</a></li> | ||
{% endif %} | ||
<li><a href="#" title="Update the IDLE case runs to newest case text" href="javascript:void(0)" data-param="{% url 'testruns-update_case_run_text' test_run.pk %}" class="updateBlue9 js-update-case">{% trans "Update" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this one should be controlled via testruns.change_testcaserun
. Also the view handling this request is missing the permissions required decorator so you will have to create tests for it and add the missing decorator before continuing with the HTML template (better use a separate pull request)
<li><a href="#" title="Remove selected cases form this test run" data-param="{{ test_run.run_id }}" class="removeBlue9 js-del-case">{% trans "Remove" %}</a></li> | ||
{% endif %} | ||
<li><a href="#" title="Update the IDLE case runs to newest case text" href="javascript:void(0)" data-param="{% url 'testruns-update_case_run_text' test_run.pk %}" class="updateBlue9 js-update-case">{% trans "Update" %}</a></li> | ||
<li><a href="#" title="Assignee this case(s) to other people" class="assigneeBlue9 js-change-assignee">{% trans "Assignee" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is also controlled by testruns.change_testcaserun
so group it with the previous one. This time the backend portion has the permission decorator applied.
</ul> | ||
</div> | ||
<div class="btnBlueCaserun"> | ||
<span>{% trans "Status" %}</span> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testruns.change_testcaserun
<span>{% trans "Bugs" %}</span> | ||
<ul> | ||
{% if perms.testcases.add_bug %} | ||
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The backend ajax function doesn't use any permissions and should be removed in favor of existing JSON-RPC
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> | ||
{% endif %} | ||
{% if perms.testcases.delete_bug %} | ||
<li><a href="javascript:void(0);" class="removeBlue9 js-remove-bugs">{% trans "Remove" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here, refactor to JSON-RPC first.
<div class="btnBlueCaserun"> | ||
<span>{% trans "Comment" %}</span> | ||
<ul> | ||
<li><a href="#" class="addBlue9 js-show-commentdialog">{% trans "Add" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing here. No permissions used on the backend, must be refactored first to use JSON-RPC (TestCaseRun.add_comment). On the backend no permissions are enforced when adding comments and there are 2 duplicate helpers that do this.
eb66c05
to
698316a
Compare
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> | ||
<li><a href="javascript:void(0);" class="removeBlue9 js-remove-bugs">{% trans "Remove" %}</a></li> | ||
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> | ||
<li><a href="javascript:void(0);" class="removeBlue9 js-remove-bugs">{% trans "Remove" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not change spaces if you are not changing anything else. It makes the PR harder to read/review and doesn't bring anything useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not resolved, revert white-space changes if nothing else changed.
class TestCaserunEditMenus(BaseCaseRun): | ||
@classmethod | ||
def setUpTestData(cls): | ||
super().setUpTestData() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Method that only calls super()
is useless. It doesn't do anything on its own and directly delegates to the parent class as if it didn't exist.
tcms/testruns/tests/test_views.py
Outdated
def setUpTestData(cls): | ||
super().setUpTestData() | ||
|
||
def setUp(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setUp
is executed before every test method, while setUpTestData
is executed only once. Given that your testing data doesn't change between the various test methods you probably want this executed only once.
tcms/testruns/tests/test_views.py
Outdated
|
||
self.client.login( # nosec:B106:hardcoded_password_funcarg | ||
username=self.tester.username, | ||
password='password') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this is already done in one of the parent classes. Why do we need it?
tcms/testruns/tests/test_views.py
Outdated
self.unauthorized.save() | ||
|
||
for perm_string in self.menu_perms: | ||
remove_perm_from_user(self.unauthorized, perm_string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be best to have permissions assigned inside the test method and only assign/remove permissions for which we are testing. Nothing else! This will mean the tests are in their most strict form and will catch possible errors in the future where we mess up permissions.
323f58c
to
1e9c3b3
Compare
1e9c3b3
to
0318481
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is getting there, but there is still work to be done which will be very hard in such a big PR. You will have to start splitting this into smaller pieces so we can make progress on it:
- For the Cases menu, there are permission label checks inside the template from before. However Rename model TestCaseRun to TestExecution #848 renames them. Do the following: Checkout PR 848 into a separate branch (
git fetch upstream pull/848/head:pr848
) and create a new branch on top of it. Cherry-pick only the tests commit and apply modifications to it:
- update the permission label names
- remove other test scenarios for the other menus
- Rename test class to reference only the Cases menu
- Rename test methods to not include the
_get_
part
Then submit a new PR which we can review first!
-
For the Status menu permission labels seem to be OK, tests need some changes. This is independent of 1). Also the tests must be in their own class to avoid making the test class too big.
-
Bugs menu: you have extra white-space (tabs vs. space) in the template without any other changes. No permission labels in the template, no tests.
-
Comments menu: extra white space, missing permission label checks in template, no tests (there is the
add_comment_html
variable but it is unused.
So we're looking at 4 separate pull requests.
tcms/testruns/tests/test_views.py
Outdated
response = self.client.get(self.url) | ||
self.assertEqual(HTTPStatus.OK, response.status_code) | ||
|
||
for tcrs in TestCaseRunStatus.objects.all(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have to iterate over the html menu options, not the status objects in the database.
def test_get_change_assignee_without_permissions(self): | ||
remove_perm_from_user(self.tester, 'testruns.change_testcaserun') | ||
response = self.client.get(self.url) | ||
self.assertEqual(HTTPStatus.OK, response.status_code) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not needed b/c assertContains will check if the status is OK
self.assertEqual(HTTPStatus.OK, response.status_code) | ||
self.assertNotContains(response, self.update_case_run_text_html, html=True) | ||
|
||
def test_get_change_assignee_without_permissions(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All test names must end without the extra s
.
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> | ||
<li><a href="javascript:void(0);" class="removeBlue9 js-remove-bugs">{% trans "Remove" %}</a></li> | ||
<li><a href="javascript:void(0);" class="addBlue9 js-add-bugs">{% trans "Add" %}</a></li> | ||
<li><a href="javascript:void(0);" class="removeBlue9 js-remove-bugs">{% trans "Remove" %}</a></li> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not resolved, revert white-space changes if nothing else changed.
0318481
to
bcaffc6
Compare
bcaffc6
to
a816615
Compare
Fixes #716