Add unit tests for Djblets web API backend auth.
Review Request #8440 — Created Sept. 25, 2016 and submitted
Added unit tests for WebAPITokenAuthBackend and WebAPIBasicAuthBackend.
This patch is based on previous work by Minh Le Hoang at
https://reviews.reviewboard.org/r/7997/.
All tests pass.
Description | From | Last Updated |
---|---|---|
Your description is missing a period. |
brennie | |
Please re-write your summary in the imperitive mood. |
brennie | |
Please include in your summary: This patch is based on work by Minh Le Hong at (the URL) |
brennie | |
local variable 'user' is assigned to but never used |
reviewbot | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
local variable 'get_credentials_mock' is assigned to but never used |
reviewbot | |
local variable 'get_credentials_mock' is assigned to but never used |
reviewbot | |
Col: 53 E126 continuation line over-indented for hanging indent |
reviewbot | |
Col: 9 E265 block comment should start with '# ' |
reviewbot | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
You don't need the entire module path in here, you can just do: """Unit tests for the WebAPITokenBackend.""" For future … |
brennie | |
See previous comment about docstring formatting. |
brennie | |
""" will fit on previous line. |
brennie | |
See previous comment about docstring formatting |
brennie | |
This attribution should be in the commit message, I believe. May want to ask Christian. Best to include the URL … |
brennie | |
Needs module-level docstring. |
brennie | |
See comment re: formatting docstrings. |
brennie | |
Col: 53 E126 continuation line over-indented for hanging indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
See comment re: formatting docstrings. |
brennie | |
See comment re: formatting docstrings. |
brennie | |
See comment re: formatting docstrings. |
brennie | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
Col: 41 E126 continuation line over-indented for hanging indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
Col: 13 E128 continuation line under-indented for visual indent |
reviewbot | |
See comment re: formatting docstrings. |
brennie | |
Col: 13 E128 continuation line under-indented for visual indent |
reviewbot | |
Blank line between these. |
brennie | |
Docstring (just needs to indicate that its a dummy model for tests.) |
brennie | |
Likewise. |
brennie | |
Blank line between these. |
brennie | |
Single quotes. |
brennie | |
Single quotes. |
brennie | |
Single quotes. |
brennie | |
Single quotes. |
brennie | |
Single quotes. |
brennie | |
Single quotes. |
brennie | |
Blank line between these. |
brennie | |
Unused method. |
brennie | |
Since this is a private method for tests, lets call it _validate_credentials. Also, needs a docstring. |
brennie | |
You can reflow this to fill more of the first line. |
brennie | |
Single quotes. |
brennie | |
This should be comparing against a constant. |
brennie | |
No leading space. Missing a period. |
brennie | |
Missing a period. |
brennie | |
Missing super(...).tearDown() |
brennie | |
You should just use the constant here. |
brennie | |
Single quotes. |
brennie | |
You want to use bytes(random()). We avoid str because in Python 2 str is a binary type and not a … |
brennie | |
bytes(random()) |
brennie | |
missing super(...).setUp() |
brennie | |
Single quotes. |
brennie | |
missing super(...).tearDown() |
brennie | |
No leading or trailing spaces. Missing a period. Missing args, returns. |
brennie | |
Use either: clean_credentials = \ self.basic_auth_backend.clean_credentials_for_display( credentials) or: clean_credentials = ( self.basic_auth_backend .clean_credentials_for_display( credentials ) ) |
brennie | |
You should inherit from SpyAgency e.g. class WebAPITokenAuthBackendTests(SpyAgency, TestModelsLoaderMixin, TestCase): # ... That way, you dont need self.agency, nor do … |
brennie | |
"succeeds" |
brennie | |
Add a trailing , or move the ) onto this line. |
brennie | |
Same here. |
brennie | |
Since you're inheriting from SpyAgency, you don't need to unspy in tearDown -- it will happen automatically. |
brennie | |
Can you rename this to TestWebAPITokenModel |
brennie | |
TestTokenAuthBackend. |
brennie | |
You will want to use assertIsNone(result). When comparing against None, you always want to use is or is not. |
brennie | |
assertIsNone |
brennie | |
You aren't using middleware or requestfactory in the testcases so why not: self.request = RequestFactory().get('/') SessionMiddleware().process_request(self.request) |
brennie | |
Does the User need to exist in the database? If not we can just make User() object. |
brennie | |
"web API" missing period. |
brennie | |
Can you move this into test_get_credentials_missing_credentials? It is only used in that test. |
brennie | |
Unnecessary. |
brennie | |
Put the trailing space on the previous line, even if it means splitting the string earlier. |
brennie | |
You can move this to a single line statement -- you won't need the comma in that case. |
brennie | |
Is there any particular reason we are doing rand() here instead of just using a non-matching token |
brennie | |
Is there any particular reason we are doing rand() here instead of just using a non-matching token |
brennie | |
Missing period. web API |
brennie | |
import foo statements go above from foo import bar statements. |
brennie | |
Can you move this into test_get_credentials_malformed_credentials? It is only used in that test. |
brennie | |
Unnecessary method. If this class doesn't implement tearDown, the superclass method will be invoked instead. |
brennie | |
This sentence contains a comma splice. How about: """Fake version of validate credentials that always succeeds. This is used in … |
brennie | |
None. Only one space between sentences. |
brennie | |
"request" Missing period. |
brennie | |
"non-basic" |
brennie | |
"with" |
brennie | |
"with" |
brennie | |
Missing trailing comma. |
brennie | |
Missing trailing comma. |
brennie | |
Missing trailing comma. |
brennie | |
Missing trailing comma. |
brennie | |
Missing trailing comma. |
brennie | |
Missing trailing comma. |
brennie | |
print() is not used. |
brennie | |
Alphabetize. |
brennie | |
Alphabetize imports. |
brennie | |
Blank line between these. |
brennie | |
Can you rearrange this so that things are defined just before they're tested? result = self.api_token_auth_backend.get_credentials(self.request) self.assertIsNone(result) warning_message = logging.warning.spy.last_call.args[0] … |
david | |
Please use single quotes around HTTP_AUTHORIZATION |
david | |
username and password are only used the once, so we could bring them inline instead of creating variables: self.user = … |
david | |
Same comments about username/password. |
david | |
print() is not used. |
brennie | |
Alphabetize these. |
brennie | |
Blank line between these. |
brennie | |
can also include that function returns None in function doc string. I believe like Returns: None |
LA larmiej | |
username and password are only used once, so we can simplify: encoded_credentials = 'testuser:testpassword'.encode('base64') |
david | |
Same here. |
david | |
Same here. |
david | |
It's a little silly to define a credentials dict just to unpack it for kwargs. Let's change this to be: … |
david | |
Same here re: credentials. |
david | |
Same here re: credentials |
david | |
Same here re: credentials |
david | |
Same here re: credentials |
david | |
Same here re: credentials |
david | |
No blank line here (django and kgb are both third-party libraries from the point of view of the djblets package). |
david | |
Why is this 'invalidtoken123? This is a valid token, no? Kinda makes the test confusing when the invalidtoken is valid. |
mike_conley | |
Same as above. |
mike_conley | |
No blank line here. |
david | |
So I believe you may be testing this wrongly after reading further into it. Firstly you are setting the user … |
brennie | |
I don't think "always succeeds" is true. Because this is returning None, it means we're falling back to the base … |
mike_conley |
-
Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py
-
-
-
-
-
- Summary:
-
[WIP] Adding unit tests for djblets.webapi.auth.backends.basicAdding unit tests for djblets.webapi.auth.backends.basic
- Description:
-
~ [WIP] Adding unit tests for djblets.webapi.auth.backends.basic
~ Adding unit tests for djblets.webapi.auth.backends.basic
- Testing Done:
-
+ All tests pass
- Commit:
-
94e1bd99317a2e155227ae2f88f693acce0b5778c5b80cec4ae11baccab7db8a269f51e6dc9d71d0
-
Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
-
-
-
-
-
- Change Summary:
-
Indentation fixes
- Commit:
-
c5b80cec4ae11baccab7db8a269f51e6dc9d71d0b3a7397c0d4d5fded8a9e3cb6a9f545f9f7d7198
-
Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
You don't need the entire module path in here, you can just do:
"""Unit tests for the WebAPITokenBackend."""
For future reference, docstrings should be of the form:
"""Single line sumnary Multi-line description. """
(except for
test_
method docstrings, of course). -
-
-
-
This attribution should be in the commit message, I believe. May want to ask Christian. Best to include the URL instead of just the ID.
-
-
-
-
-
-
-
-
-
-
-
- Summary:
-
Adding unit tests for djblets.webapi.auth.backends.basicDjblets webapi backend auth tests
- Description:
-
~ Adding unit tests for djblets.webapi.auth.backends.basic
~ Added unit tests for WebAPITokenAuthBackend and WebAPIBasicAuthBackend
- Commit:
-
b3a7397c0d4d5fded8a9e3cb6a9f545f9f7d7198c14d727af92fa6ca060f5d3d30f4ce4ab4e5b534
-
Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
- Change Summary:
-
Style fixes
- Commit:
-
e9072816ca992db1cec4a93b48bba9a1e03ff01e2952cd71cbd0f837be4abe7dd0d45727df374c1d
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
-
-
-
-
-
-
You want to use
bytes(random())
.We avoid
str
because in Python 2str
is a binary type and not a text type. It has been renamed tobytes
in Python 3 and backported. The text type of Python 2 isunicode
(which was renamed tostr
in Python 3). For actual string types, usesix.text_type
which converts tounicode
in py2 andstr
in py3. For binary data (such as HTTP headers) usebytes
. (There is alsosix.binary_type
, but since we are Python 2.7 only we can usebytes
instead.) -
-
-
-
-
-
Use either:
clean_credentials = \ self.basic_auth_backend.clean_credentials_for_display( credentials)
or:
clean_credentials = ( self.basic_auth_backend .clean_credentials_for_display( credentials ) )
- Description:
-
~ Added unit tests for WebAPITokenAuthBackend and WebAPIBasicAuthBackend
~ Added unit tests for WebAPITokenAuthBackend and WebAPIBasicAuthBackend.
- Testing Done:
-
~ All tests pass
~ All tests pass.
- Commit:
-
2952cd71cbd0f837be4abe7dd0d45727df374c1d796c3d875e87b6e7b4bd5ca5bb9a785b6a8d2d10
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
-
You should inherit from
SpyAgency
e.g.class WebAPITokenAuthBackendTests(SpyAgency, TestModelsLoaderMixin, TestCase): # ...
That way, you dont need
self.agency
, nor do you need yourtearDown
method --SpyAgency.tearDown()
(which will be called after each test) will unspy on all spies! -
-
-
-
Since you're inheriting from
SpyAgency
, you don't need to unspy intearDown
-- it will happen automatically.
- Summary:
-
Djblets webapi backend auth testsAdd unit tests for Djblets webapi backend auth
- Commit:
-
796c3d875e87b6e7b4bd5ca5bb9a785b6a8d2d107bb5dd57c5c8bc054e16c91f24acd1e6c8b15ac9
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
-
-
-
-
-
-
-
-
-
-
Unnecessary method. If this class doesn't implement
tearDown
, the superclass method will be invoked instead. -
This sentence contains a comma splice. How about:
"""Fake version of validate credentials that always succeeds. This is used in lieu of the actual method for testing purposes. ... """
or similar.
-
-
-
-
-
-
-
-
-
-
-
- Summary:
-
Add unit tests for Djblets webapi backend authAdd unit tests for Djblets web API backend auth
- Commit:
-
dde3462c7a94f5f0df6380d9f1df28caae10505865e6c0ddcaa08ef2bca42ef790744319c932910e
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
Can you rearrange this so that things are defined just before they're tested?
result = self.api_token_auth_backend.get_credentials(self.request) self.assertIsNone(result) warning_message = logging.warning.spy.last_call.args[0] self.assertTrue(warning_message.startswith( ...)
-
-
username
andpassword
are only used the once, so we could bring them inline instead of creating variables:self.user = User.objects.create_user( username='testuser', password='testuser_password')
That said, I don't see anywhere that we actually care about the password being set, so we could leave that out entirely.
-
-
username
andpassword
are only used once, so we can simplify:encoded_credentials = 'testuser:testpassword'.encode('base64')
-
-
-
It's a little silly to define a
credentials
dict just to unpack it for kwargs. Let's change this to be:result = self.basic_auth_backend.login_with_credentials( request, username=username, password=password)
and kill the
credentials
definition. -
-
-
-
-
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
Thanks stensby - just a few questions. See below.
-
Why is this
'invalidtoken123
? This is a valid token, no? Kinda makes the test confusing when theinvalidtoken
is valid. -
-
I don't think "always succeeds" is true. Because this is returning None, it means we're falling back to the base authentication mechanism. At least, that's what I understand from reading https://github.com/djblets/djblets/blob/c4fa360ad80e72bab4cca142e17a90ee9dbfb68a/djblets/webapi/auth/backends/base.py#L59
-
Tool: Pyflakes Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py Tool: PEP8 Style Checker Processed Files: djblets/webapi/tests/test_basic_auth_backend.py djblets/webapi/tests/test_api_auth_backend.py
-
-
So I believe you may be testing this wrongly after reading further into it.
Firstly you are setting the user on the request AND short circuiting the
validate_credentials
method. We shouldn't have to do either of these things.Instead, you should create the user and store it as
self.user
and setself.request.user = AnonymousUser()
. That way, the realvalidate_credentials
will be called and returnNone
.
- Change Summary:
-
Changed the request user to be anonymous, added additional test case for validate_credentials where the user is invalid.
- Commit:
-
ccb73279c8210280766f31cf6e7b5ca93d66da5165425560d3dcdc8b020bbf09f75b2c0f1128cc69