Skip to content

Commit

Permalink
Merge pull request #30 from ARYAN-NIKNEZHAD/tests/settings
Browse files Browse the repository at this point in the history
🚨  Enhance Tests for Iranian Cities Settings Configuration
  • Loading branch information
sepehr-akbarzadeh authored Aug 12, 2024
2 parents b534ec8 + 0f037d6 commit d591091
Show file tree
Hide file tree
Showing 4 changed files with 216 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ markers = [
"models_str_method: mark test to check __str__ methods of models",
"models_code_field: mark test to check code fields in models",
"models_code_field_unique: mark test to check code fields are unique",
"settings_admin_permission: mark test to check admin permissions",
"settings_checks: mark test to check settings configuration",
]
norecursedirs = [
"migrations",
Expand Down
Empty file added tests/settings/__init__.py
Empty file.
109 changes: 109 additions & 0 deletions tests/settings/test_admin_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
from django.contrib.admin.sites import AdminSite
from django.contrib.auth.models import User
from django.http import HttpRequest
from tests.constants import PYTHON_VERSION, PYTHON_VERSION_REASON
from iranian_cities.conf import sage_iranian_cities_settings
from typing import List, Type, Dict, Optional
from iranian_cities.mixins.dynamic_permission import IranianCitiesAdminReadOnlyEnabled, DynamicInlineAdmin
from iranian_cities.admin import (
Province, County, District, RuralDistrict,
CityInline, VillageInline, CountyInline, DistrictInline
)
import pytest
import sys


pytestmark = [
pytest.mark.django_db,
pytest.mark.settings_admin_permission,
pytest.mark.skipif(sys.version_info < PYTHON_VERSION, reason=PYTHON_VERSION_REASON)
]


class TestAdminPermission:
"""Test IranianCities Admin Permission."""
def test_iranian_cities_admin_permissions(self) -> None:
"""
Test the IranianCitiesAdminReadOnlyEnabled mixin to verify that permission
checks are correctly based on settings.
This test verifies that add, delete, and change permissions are granted
or denied based on the configuration settings.
Returns
-------
None
"""
settings_instance = IranianCitiesAdminReadOnlyEnabled()
request = HttpRequest()

# Set configuration settings
sage_iranian_cities_settings.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED = True
sage_iranian_cities_settings.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED = False
sage_iranian_cities_settings.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED = True

assert settings_instance.has_add_permission(request) is True
assert settings_instance.has_delete_permission(request) is False
assert settings_instance.has_change_permission(request) is True

def test_dynamic_inline_admin(self) -> None:
"""
Test the DynamicInlineAdmin mixin to ensure that the correct inlines
are returned based on settings.
This test checks that the appropriate inline model admins are returned
for different models when the inline settings are enabled.
Returns
-------
None
"""
settings_instance = DynamicInlineAdmin()

# Mock the models and inlines
sage_iranian_cities_settings.IRANIAN_CITIES_ADMIN_INLINE_ENABLED = True

assert settings_instance.get_dynamic_inlines(Province) == [CountyInline]
assert settings_instance.get_dynamic_inlines(County) == [DistrictInline]
assert settings_instance.get_dynamic_inlines(District) == [CityInline]
assert settings_instance.get_dynamic_inlines(RuralDistrict) == [VillageInline]
assert settings_instance.get_dynamic_inlines(object) == []

def test_get_inlines_method(self, settings) -> None:
"""
Test the `get_inlines` method in a custom admin model admin class.
This test verifies that the `get_inlines` method returns the correct
inlines based on the model provided, using the dynamic inline admin settings.
Parameters
----------
settings : pytest fixture
The Django settings fixture used to configure the test environment.
Returns
-------
None
"""

request = HttpRequest()
request.user = User.objects.create_superuser('admin', '[email protected]', 'password')

class CustomModelAdmin(DynamicInlineAdmin):
def __init__(self, model: Optional[Type], admin_site: Optional[AdminSite]) -> None:
self.model = model
self.admin_site = admin_site

model_admins: Dict[Type, List[Type]] = {
Province: [CountyInline],
County: [DistrictInline],
District: [CityInline],
RuralDistrict: [VillageInline]
}

for model, expected_inlines in model_admins.items():
model_admin = CustomModelAdmin(model=model, admin_site=AdminSite())

inlines = model_admin.get_inlines(request)

assert inlines == expected_inlines
105 changes: 105 additions & 0 deletions tests/settings/test_checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from typing import List
from iranian_cities.checks import check_iranian_cities_config
from iranian_cities.exc import IranianCitiesConfigurationError
from iranian_cities.conf import SageIranianCitiesSettings
from tests.constants import PYTHON_VERSION, PYTHON_VERSION_REASON
import pytest
import sys

pytestmark = [
pytest.mark.settings_checks,
pytest.mark.skipif(sys.version_info < PYTHON_VERSION, reason=PYTHON_VERSION_REASON)
]

class TestIranianCitiesConfig:
"""Test IranianCities configuration and settings."""
def test_check_iranian_cities_config_correct_settings(self, settings) -> None:
"""
Test the Iranian Cities configuration checker with correct settings.
This test verifies that no errors are returned when all required settings
are correctly configured.
Parameters
----------
settings : pytest.Settings
The Django settings fixture used to configure the test environment.
"""
settings.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_INLINE_ENABLED = True

errors: List[Exception] = check_iranian_cities_config({})
assert len(errors) == 0

def test_sage_iranian_cities_settings(self, settings) -> None:
"""
Test the SageIranianCitiesSettings class with correct settings.
This test verifies that the settings class reads and applies the correct
settings values.
Parameters
----------
settings : pytest.Settings
The Django settings fixture used to configure the test environment.
"""
settings.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_INLINE_ENABLED = True

settings_instance = SageIranianCitiesSettings()

assert settings_instance.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED is True
assert settings_instance.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED is True
assert settings_instance.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED is True
assert settings_instance.IRANIAN_CITIES_ADMIN_INLINE_ENABLED is True

def test_check_iranian_cities_config_invalid_type_again(self, settings) -> None:
"""
Test the Iranian Cities configuration checker with invalid type settings.
This test ensures that an IranianCitiesConfigurationError is raised when
settings are of the wrong type.
Parameters
----------
settings : pytest.Settings
The Django settings fixture used to configure the test environment.
"""
settings.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED = "true"
settings.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED = True
settings.IRANIAN_CITIES_ADMIN_INLINE_ENABLED = True

with pytest.raises(IranianCitiesConfigurationError):
SageIranianCitiesSettings()

def test_sage_iranian_cities_settings_missing_configs(self, settings) -> None:
"""
Test the SageIranianCitiesSettings class with missing configuration values.
This test verifies that an IranianCitiesConfigurationError is raised when
required settings are missing or set to None.
Parameters
----------
settings : pytest.Settings
The Django settings fixture used to configure the test environment.
"""
settings.IRANIAN_CITIES_ADMIN_ADD_READONLY_ENABLED = None
settings.IRANIAN_CITIES_ADMIN_DELETE_READONLY_ENABLED = None
settings.IRANIAN_CITIES_ADMIN_CHANGE_READONLY_ENABLED = None
settings.IRANIAN_CITIES_ADMIN_INLINE_ENABLED = None

with pytest.raises(IranianCitiesConfigurationError) as excinfo:
SageIranianCitiesSettings()

error_message: str = str(excinfo.value)

assert excinfo.value.code == "E4001"
assert excinfo.value.section_code == "CFG"

assert "must be of type boolean" in error_message

0 comments on commit d591091

Please sign in to comment.