-
-
Couldn't load subscription status.
- Fork 248
Feature/graphql support for badges #2152
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
Merged
arkid15r
merged 17 commits into
OWASP:main
from
Piyushrathoree:feature/graphql-support-for-badges
Sep 6, 2025
Merged
Changes from 10 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
42f1e38
feat: Implement GraphQL support for badges
Piyushrathoree 0abfabf
fix: Update UserNode test to include badges field
Piyushrathoree 2d3a1c7
done with changes suggested by coderabbit with all checks passing
Piyushrathoree eb053a5
fixed some more coderabbit suggestion
Piyushrathoree 9562782
Merge branch 'main' into feature/graphql-support-for-badges
Piyushrathoree 44331be
Merge branch 'main' into pr/Piyushrathoree/2152
arkid15r 10d1341
Merge branch 'main' into pr/Piyushrathoree/2152
arkid15r 4c5210f
Update code
arkid15r d60aecd
Refactor badges field resolution in UserNode and BadgeQueries for imp…
Piyushrathoree 9c0efac
Merge branch 'main' into feature/graphql-support-for-badges
kasya 494c82d
updated the suggested changes by @arkid15r
Piyushrathoree 1f0ca1d
done with coderabbit suggestions
Piyushrathoree 2d01b8e
Remove BadgeQueries import from NestQuery class
Piyushrathoree c490e20
Remove BadgeQueries inheritance from NestQuery class
Piyushrathoree d32b708
Update badges resolver to sort by badge weight in descending order
Piyushrathoree 9301ff5
Merge branch 'main' into pr/Piyushrathoree/2152
arkid15r 1df5367
Update code
arkid15r File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| """GraphQL node for Badge model.""" | ||
|
|
||
| import strawberry | ||
| import strawberry_django | ||
|
|
||
| from apps.nest.models.badge import Badge | ||
|
|
||
|
|
||
| @strawberry_django.type( | ||
| Badge, | ||
| fields=[ | ||
| "css_class", | ||
| "description", | ||
| "id", | ||
| "name", | ||
| "weight", | ||
| ], | ||
| ) | ||
| class BadgeNode(strawberry.relay.Node): | ||
| """GraphQL node for Badge model.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,9 @@ | ||
| import strawberry | ||
|
|
||
| from apps.nest.api.internal.queries.api_key import ApiKeyQueries | ||
| from apps.nest.api.internal.queries.badge import BadgeQueries | ||
|
|
||
|
|
||
| @strawberry.type | ||
| class NestQuery(ApiKeyQueries): | ||
| class NestQuery(ApiKeyQueries, BadgeQueries): | ||
| """Nest query.""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| """GraphQL queries for Badge model.""" | ||
|
|
||
| import strawberry | ||
|
|
||
| from apps.nest.api.internal.nodes.badge import BadgeNode | ||
| from apps.nest.models.badge import Badge | ||
|
|
||
|
|
||
| @strawberry.type | ||
| class BadgeQueries: | ||
Piyushrathoree marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """GraphQL query class for badges.""" | ||
|
|
||
| @strawberry.field | ||
| def badges(self) -> list[BadgeNode]: | ||
| """Return badges.""" | ||
| return Badge.objects.order_by("weight", "name") | ||
31 changes: 31 additions & 0 deletions
31
backend/tests/apps/github/api/internal/nodes/user_badges_field_test.py
Piyushrathoree marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| """Tests for badges field on GitHub UserNode.""" | ||
|
|
||
| from unittest.mock import MagicMock | ||
|
|
||
| from apps.github.api.internal.nodes.user import UserNode | ||
|
|
||
|
|
||
| class TestUserNodeBadgesField: | ||
| """Test cases for badges field on UserNode.""" | ||
|
|
||
| def test_badges_resolution_orders_and_filters_active(self): | ||
| """Badges resolution should filter active and order by badge weight/name.""" | ||
| # Build a lightweight object with required attributes and methods | ||
| user = MagicMock() | ||
| user_badge_qs = MagicMock() | ||
| user.badges.select_related.return_value = user_badge_qs | ||
|
|
||
| # Mock chained calls: filter(...).order_by(...) -> [ub1] | ||
| ordered_qs = MagicMock() | ||
| ub1 = MagicMock() | ||
| ub1.badge = MagicMock() | ||
| user_badge_qs.filter.return_value = ordered_qs | ||
| ordered_qs.order_by.return_value = [ub1] | ||
|
|
||
| # Use the resolver through the class to keep Strawberry decorators intact | ||
| result = UserNode.badges(user) # pass instance as self | ||
|
|
||
| user.badges.select_related.assert_called_once_with("badge") | ||
| user_badge_qs.filter.assert_called_once_with(is_active=True) | ||
| ordered_qs.order_by.assert_called_once_with("badge__weight", "badge__name") | ||
| assert result == [ub1.badge] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
backend/tests/apps/nest/api/internal/queries/badge_test.py
Piyushrathoree marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| """Tests for Badge GraphQL queries and nodes.""" | ||
|
|
||
| from unittest.mock import MagicMock, patch | ||
|
|
||
| from apps.nest.api.internal.queries.badge import BadgeQueries | ||
| from apps.nest.models.badge import Badge | ||
|
|
||
|
|
||
| class TestBadgeQueries: | ||
| """Test cases for BadgeQueries class.""" | ||
|
|
||
| def test_has_strawberry_definition(self): | ||
| """BadgeQueries should be a valid Strawberry type with 'badges' field.""" | ||
| from strawberry import Schema | ||
|
|
||
| schema = Schema(query=BadgeQueries) | ||
| res = schema.execute_sync('{ __type(name:"BadgeQueries"){ fields { name } } }') | ||
| assert res.errors is None | ||
| field_names = [f["name"] for f in res.data["__type"]["fields"]] | ||
| assert "badges" in field_names | ||
|
|
||
| def test_badges_field_configuration(self): | ||
| """'badges' field should return a list of BadgeNode.""" | ||
| from strawberry import Schema | ||
|
|
||
| schema = Schema(query=BadgeQueries) | ||
| res = schema.execute_sync( | ||
| """ | ||
| { | ||
| __type(name: "BadgeQueries") { | ||
| fields { | ||
| name type { kind ofType { kind ofType { kind ofType { name } } } } | ||
| } | ||
| } | ||
| } | ||
| """ | ||
| ) | ||
| assert res.errors is None | ||
| badges_field = next(f for f in res.data["__type"]["fields"] if f["name"] == "badges") | ||
| assert badges_field["type"]["kind"] == "NON_NULL" | ||
| assert badges_field["type"]["ofType"]["kind"] == "LIST" | ||
| assert badges_field["type"]["ofType"]["ofType"]["kind"] == "NON_NULL" | ||
| assert badges_field["type"]["ofType"]["ofType"]["ofType"]["name"] == "BadgeNode" | ||
|
|
||
| @patch("apps.nest.api.internal.queries.badge.Badge.objects") | ||
| def test_badges_resolution(self, mock_manager): | ||
| """Resolver should return badges ordered by weight and name.""" | ||
| mock_badge = MagicMock(spec=Badge) | ||
| mock_manager.order_by.return_value = [mock_badge] | ||
|
|
||
| result = BadgeQueries().badges() | ||
|
|
||
| assert list(result) == [mock_badge] | ||
| mock_manager.order_by.assert_called_once_with("weight", "name") |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.