Skip to content

Commit

Permalink
Increase Coverage for Github API (OWASP#319)
Browse files Browse the repository at this point in the history
* added tests for github/api/

* refined the code

* added test class and removed timestamp in label

* added comment for simulating queryset
  • Loading branch information
Naveen-Pal authored Dec 31, 2024
1 parent 389bef4 commit 875662d
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 2 deletions.
2 changes: 0 additions & 2 deletions backend/apps/github/api/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ class Meta:
"name",
"description",
"color",
"created_at",
"updated_at",
)


Expand Down
Empty file.
38 changes: 38 additions & 0 deletions backend/tests/github/api/issue_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest

from apps.github.api.issue import IssueSerializer


class TestIssueSerializer:
@pytest.mark.parametrize(
"issue_data",
[
{
"title": "Test Issue 1",
"body": "This is a test issue 1",
"state": "open",
"url": "http://example.com/issues/1",
"created_at": "2024-12-30T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
{
"title": "Test Issue 2",
"body": "This is a test issue 2",
"state": "closed",
"url": "http://example.com/issues/2",
"created_at": "2024-12-29T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
],
)
def test_issue_serializer(self, issue_data):
serializer = IssueSerializer(data=issue_data)
assert serializer.is_valid()
validated_data = serializer.validated_data
validated_data["created_at"] = (
validated_data["created_at"].isoformat().replace("+00:00", "Z")
)
validated_data["updated_at"] = (
validated_data["updated_at"].isoformat().replace("+00:00", "Z")
)
assert validated_data == issue_data
28 changes: 28 additions & 0 deletions backend/tests/github/api/label_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import pytest

from apps.github.api.label import LabelSerializer


class TestLabelSerializer:
@pytest.mark.parametrize(
"label_data",
[
{
"name": "bug",
"description": "Indicates a bug in the project",
"color": "f29513",
},
{
"name": "enhancement",
"description": "Indicates a new feature or enhancement",
"color": "a2eeef",
},
],
)
def test_label_serializer(self, label_data):
serializer = LabelSerializer(data=label_data)
assert serializer.is_valid(), serializer.errors
validated_data = serializer.validated_data
assert validated_data["name"] == label_data["name"]
assert validated_data["description"] == label_data["description"]
assert validated_data["color"] == label_data["color"]
47 changes: 47 additions & 0 deletions backend/tests/github/api/organization_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from unittest.mock import MagicMock, patch

import pytest

from apps.github.api.organization import OrganizationSerializer


class TestOrganizationSerializer:
@pytest.mark.parametrize(
"organization_data",
[
{
"name": "GitHub",
"login": "github",
"company": "GitHub, Inc.",
"location": "San Francisco, CA",
"created_at": "2024-12-30T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
{
"name": "Microsoft",
"login": "microsoft",
"company": "Microsoft Corporation",
"location": "Redmond, WA",
"created_at": "2024-12-29T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
],
)
# Ensures that test runs without actual database access by simulating behavior of a queryset.
@patch("apps.github.models.organization.Organization.objects.filter")
def test_organization_serializer(self, mock_filter, organization_data):
mock_qs = MagicMock()
# To mimic a queryset where no matching objects are found.
mock_qs.exists.return_value = False
mock_filter.return_value = mock_qs

serializer = OrganizationSerializer(data=organization_data)
assert serializer.is_valid()
validated_data = serializer.validated_data
validated_data["created_at"] = (
validated_data["created_at"].isoformat().replace("+00:00", "Z")
)
validated_data["updated_at"] = (
validated_data["updated_at"].isoformat().replace("+00:00", "Z")
)
assert validated_data == organization_data
37 changes: 37 additions & 0 deletions backend/tests/github/api/release_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import pytest

from apps.github.api.release import ReleaseSerializer


class TestReleaseSerializer:
@pytest.mark.parametrize(
"release_data",
[
{
"name": "v1.0",
"tag_name": "v1.0.0",
"description": "First stable release",
"created_at": "2024-12-30T00:00:00Z",
"published_at": "2024-12-30T00:00:00Z",
},
{
"name": "v1.1",
"tag_name": "v1.1.0",
"description": "Minor improvements and bug fixes",
"created_at": "2024-12-29T00:00:00Z",
"published_at": "2024-12-30T00:00:00Z",
},
],
)
def test_release_serializer(self, release_data):
serializer = ReleaseSerializer(data=release_data)
assert serializer.is_valid()
validated_data = serializer.validated_data

validated_data["created_at"] = (
validated_data["created_at"].isoformat().replace("+00:00", "Z")
)
validated_data["published_at"] = (
validated_data["published_at"].isoformat().replace("+00:00", "Z")
)
assert validated_data == release_data
35 changes: 35 additions & 0 deletions backend/tests/github/api/repository_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import pytest

from apps.github.api.repository import RepositorySerializer


class TestRepositorySerializer:
@pytest.mark.parametrize(
"repository_data",
[
{
"name": "Repo1",
"description": "Description for Repo1",
"created_at": "2024-12-30T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
{
"name": "Repo2",
"description": "Description for Repo2",
"created_at": "2024-12-29T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
],
)
def test_repository_serializer(self, repository_data):
serializer = RepositorySerializer(data=repository_data)
assert serializer.is_valid()
validated_data = serializer.validated_data

validated_data["created_at"] = (
validated_data["created_at"].isoformat().replace("+00:00", "Z")
)
validated_data["updated_at"] = (
validated_data["updated_at"].isoformat().replace("+00:00", "Z")
)
assert validated_data == repository_data
36 changes: 36 additions & 0 deletions backend/tests/github/api/urls_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest

from apps.github.api.issue import IssueViewSet
from apps.github.api.label import LabelViewSet
from apps.github.api.organization import OrganizationViewSet
from apps.github.api.release import ReleaseViewSet
from apps.github.api.repository import RepositoryViewSet
from apps.github.api.urls import router
from apps.github.api.user import UserViewSet


class TestRouterRegistration:
@pytest.mark.parametrize(
("url_name", "viewset_class", "expected_prefix"),
[
("issue-list", IssueViewSet, "github/issues"),
("label-list", LabelViewSet, "github/labels"),
("organization-list", OrganizationViewSet, "github/organizations"),
("release-list", ReleaseViewSet, "github/releases"),
("repository-list", RepositoryViewSet, "github/repositories"),
("user-list", UserViewSet, "github/users"),
],
)
def test_router_registration(self, url_name, expected_prefix, viewset_class):
matching_routes = [route for route in router.urls if route.name == url_name]
assert matching_routes, f"Route '{url_name}' not found in router."

for route in matching_routes:
assert (
expected_prefix in route.pattern.describe()
), f"Prefix '{expected_prefix}' not found in route '{route.name}'."

viewset = route.callback.cls
assert issubclass(
viewset, viewset_class
), f"Viewset for '{route.name}' does not match {viewset_class}."
48 changes: 48 additions & 0 deletions backend/tests/github/api/user_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from unittest.mock import MagicMock, patch

import pytest

from apps.github.api.user import UserSerializer


class TestUserSerializer:
@pytest.mark.parametrize(
"user_data",
[
{
"name": "John Doe",
"login": "johndoe",
"company": "GitHub",
"location": "San Francisco",
"created_at": "2024-12-30T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
{
"name": "Jane Smith",
"login": "janesmith",
"company": "Microsoft",
"location": "Redmond",
"created_at": "2024-12-29T00:00:00Z",
"updated_at": "2024-12-30T00:00:00Z",
},
],
)
# Ensures that test runs without actual database access by simulating behavior of a queryset.
@patch("apps.github.models.user.User.objects.filter")
def test_user_serializer(self, mock_filter, user_data):
mock_qs = MagicMock()
# To mimic a queryset where no matching objects are found.
mock_qs.exists.return_value = False
mock_filter.return_value = mock_qs

serializer = UserSerializer(data=user_data)
assert serializer.is_valid()
validated_data = serializer.validated_data

validated_data["created_at"] = (
validated_data["created_at"].isoformat().replace("+00:00", "Z")
)
validated_data["updated_at"] = (
validated_data["updated_at"].isoformat().replace("+00:00", "Z")
)
assert validated_data == user_data

0 comments on commit 875662d

Please sign in to comment.