Chore: Add unit tests for NoRepeatedValueJSONArrayValidator#14208
Chore: Add unit tests for NoRepeatedValueJSONArrayValidator#14208Divinesoumyadip wants to merge 3 commits intolearningequality:developfrom
Conversation
|
👋 Thanks for contributing! We will assign a reviewer within the next two weeks. In the meantime, please ensure that:
We'll be in touch! 😊 |
|
Hi @Divinesoumyadip - we generally prefer that issues are assigned before work is done, but as there is no associated issue here, we can take a look at your work. In future, it would be helpful to raise issues for these kinds of gaps you spot so we can evaluate and triage first. |
rtibblesbot
left a comment
There was a problem hiding this comment.
Thanks for adding test coverage for NoRepeatedValueJSONArrayValidator.
CI passing. No UI changes.
There are a few structural issues that need to be addressed before this can be merged:
- blocking: The file is placed at
kolibri/kolibri/core/utils/tests/— a nestedkolibri/kolibri/path that doesn't exist in the project structure. It should be atkolibri/core/utils/test/test_validators.py(see inline comment). - blocking: The new directory is missing an
__init__.pyfile, which every test directory in this project has. - blocking: Uses
unittest.TestCaseinstead ofdjango.test.TestCase, which is the project convention for Django-related code. - suggestion: Several validator behaviors are untested —
array_keyparameter, non-list input raisingValidationError, duplicate object keys raising errors. Adding these would make the suite more thorough.
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Reviewed the pull request diff checking for:
- Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
- Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
- Architecture: duplicated concerns, minimal interfaces, composition over inheritance
- Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
- Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
- Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
- Checked CI status and linked issue acceptance criteria
- For UI changes: inspected screenshots for layout, visual completeness, and consistency
| @@ -0,0 +1,22 @@ | |||
| import unittest | |||
There was a problem hiding this comment.
blocking: This file is at the wrong path. The project structure has test directories under kolibri/core/<module>/test/, not kolibri/kolibri/core/<module>/tests/.
Two issues:
- The
kolibri/kolibri/nesting is incorrect — the repo root already containskolibri/, so the path should start from there. - The project convention uses
test/(singular) nottests/— seekolibri/core/auth/test/,kolibri/core/content/test/, etc.
The correct location would be kolibri/core/utils/test/test_validators.py, with an __init__.py in the new test/ directory.
There was a problem hiding this comment.
This is not testing Django code, so no need to use the Django TestCase.
| self.assertEqual(v(data), data) | ||
|
|
||
| def test_empty_list_passes(self): | ||
| self.assertEqual(self.validator([]), []) |
There was a problem hiding this comment.
suggestion: Consider adding tests for the remaining validator behaviors:
array_keyparameter (extracts a nested array from a dict)- Non-list input raising
ValidationError("Value must be an array") - Duplicate values with
object_keyraisingValidationError - String values with duplicates (e.g.,
["a", "b", "a"])
These are all distinct code paths in the validator.
There was a problem hiding this comment.
array_key parameter (extracts a nested array from a dict)
Non-list input raising ValidationError ("Value must be an array")
Duplicate values with object_key raising ValidationError
All three of these are necessary to give test coverage of the validator, if we're going to add test coverage here, we should do the whole lot!
There was a problem hiding this comment.
Agreed — full coverage of all code paths is the right call.
|
Hi @rtibbles, thank you for taking a look and for explaining the workflow! I completely understand the process now.I will make sure to open an issue and request assignment first for any future contributions. I am currently addressing the structural and test-coverage feedback provided by the automated review (fixing the directory path to kolibri/core/utils/test/, adding the init.py, switching to django.test.TestCase, and adding the suggested edge cases). I will push the updated commit shortly! |
rtibbles
left a comment
There was a problem hiding this comment.
Code is in the correct place now, but still lacking coverage - if we're going to add coverage, we should do it completely!
| @@ -0,0 +1,22 @@ | |||
| import unittest | |||
There was a problem hiding this comment.
This is not testing Django code, so no need to use the Django TestCase.
| self.assertEqual(v(data), data) | ||
|
|
||
| def test_empty_list_passes(self): | ||
| self.assertEqual(self.validator([]), []) |
There was a problem hiding this comment.
array_key parameter (extracts a nested array from a dict)
Non-list input raising ValidationError ("Value must be an array")
Duplicate values with object_key raising ValidationError
All three of these are necessary to give test coverage of the validator, if we're going to add test coverage here, we should do the whole lot!
rtibblesbot
left a comment
There was a problem hiding this comment.
Good progress — 2 prior finding(s) resolved.
CI passing. No UI changes.
- [blocking] The misplaced file at
kolibri/kolibri/core/utils/tests/test_validators.pyis still being added by this PR — UNRESOLVED (see inline comment) - [nitpick] Missing trailing newline — see inline comment
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Compared the current PR state against findings from a prior review:
- Retrieved prior bot reviews deterministically via the GitHub API
- Classified each prior finding as RESOLVED, UNRESOLVED, PARTIALLY_ADDRESSED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
- Checked CI status and linked issue acceptance criteria
| @@ -0,0 +1,22 @@ | |||
| import unittest | |||
There was a problem hiding this comment.
blocking: This file at the incorrect kolibri/kolibri/ path is still in the PR. Now that the correct file exists at kolibri/core/utils/test/test_validators.py, this one should be deleted from the PR entirely — it creates a spurious directory (kolibri/kolibri/) that doesn't belong in the project.
|
|
||
| def test_duplicate_string_values_raises_error(self): | ||
| with self.assertRaises(ValidationError): | ||
| self.validator(["a", "b", "a"]) No newline at end of file |
There was a problem hiding this comment.
nitpick: Missing trailing newline at end of file. Most editors and linters expect a final newline.
|
Hi @rtibbles, I've pushed a final commit to address the bot's feedback. I completely removed the outdated file at the incorrect kolibri/kolibri/ path and added the missing trailing newline to the correct test file. The PR should be fully clean and ready for your review now. Thank you! |
rtibblesbot
left a comment
There was a problem hiding this comment.
Tests are well-structured and cover the key behaviors of NoRepeatedValueJSONArrayValidator.
CI passing. No UI changes.
4 prior finding(s) resolved.
@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly
How was this generated?
Compared the current PR state against findings from a prior review:
- Retrieved prior bot reviews deterministically via the GitHub API
- Classified each prior finding as RESOLVED, UNRESOLVED, PARTIALLY_ADDRESSED, or CONTESTED
- Only raised NEW findings for newly introduced code
- Reviewed the pull request diff checking for correctness, design, architecture, testing, completeness, and adherence to DRY/SRP principles
- Checked CI status and linked issue acceptance criteria
rtibbles
left a comment
There was a problem hiding this comment.
Just one more test case needed! Test the unhappy paths :)
| def test_empty_list_passes(self): | ||
| self.assertEqual(self.validator([]), []) | ||
|
|
||
| def test_array_key_parameter(self): |
There was a problem hiding this comment.
Good to have the happy path here, but I think we're missing one more test for raising a ValidationError when the "items" key is not a unique list.
Hi Team,
I noticed that NoRepeatedValueJSONArrayValidator in core/utils/validators.py lacked dedicated unit test coverage, so I’ve implemented a new test suite in kolibri/kolibri/core/utils/tests/test_validators.py to improve its robustness. The tests validate that duplicate integers and strings correctly raise a ValidationError, ensure uniqueness based on a specified object_key for dictionaries, and confirm that empty lists pass validation. All tests pass locally with pytest. I look forward to your feedback.