test: Add initial integration tests

ref: #947 #152 closes #774
This commit is contained in:
2025-08-12 13:15:15 +09:30
parent bc9d6b74fd
commit 089480620e
3 changed files with 194 additions and 0 deletions

View File

@ -46,6 +46,17 @@ jobs:
WORKFLOW_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
integration-test:
name: 'Integration Test'
uses: nofusscomputing/action_python/.github/workflows/python-integration.yaml@development
needs:
- docker
with:
PYTHON_VERSION: '3.11'
secrets:
WORKFLOW_TOKEN: ${{ secrets.WORKFLOW_TOKEN }}
gitlab-mirror:
if: ${{ github.repository == 'nofusscomputing/centurion_erp' }}
runs-on: ubuntu-latest

View File

@ -0,0 +1,182 @@
import pytest
import re
import requests
from django.urls import get_resolver, URLPattern, URLResolver
def list_urls(urlpatterns, parent_pattern=''):
urls = []
for entry in urlpatterns:
if isinstance(entry, URLPattern):
urls.append(parent_pattern + str(entry.pattern))
elif isinstance(entry, URLResolver):
urls.extend(list_urls(entry.url_patterns, parent_pattern + str(entry.pattern)))
filtered = [
re.sub(r"\^([a-z\-]+)\$$", r"\1", u).rstrip('/') for u in urls if (
re.sub(r"\^([a-z\-]+)\$$", r"\1", u).startswith('api/')
and '(' not in re.sub(r"\^([a-z\-]+)\$$", r"\1", u).rstrip('/')
and '<' not in re.sub(r"\^([a-z\-]+)\$$", r"\1", u).rstrip('/')
and '$' not in re.sub(r"\^([a-z\-]+)\$$", r"\1", u).rstrip('/')
)
]
return filtered
no_auth_urls = [
'api/v2/auth/login',
'api/v2/docs',
'api/v2/schema',
]
urls_list_view_auth_required_excluded = [
'api/v2/auth/logout',
]
urls_list_view_auth_required_authenticated_excluded = [
'api/v2/itam/inventory',
'api/v2/auth/logout',
]
@pytest.mark.integration
@pytest.mark.regression
class URLChecksPyTest:
@pytest.fixture(scope="class")
def auto_login_client(self):
session = requests.Session()
login_page_url = "http://127.0.0.1:8003/api/v2/auth/login"
login_post_url = "http://127.0.0.1:8003/api/v2/auth/login"
resp = session.get(login_page_url)
resp.raise_for_status()
# Extract CSRF token from cookies (Django sets csrftoken cookie)
csrf_token = session.cookies.get("csrftoken")
if not csrf_token:
raise RuntimeError("CSRF token cookie not found")
login_data = {
"username": "admin",
"password": "admin",
"csrfmiddlewaretoken": csrf_token,
}
headers = {
"Referer": login_page_url,
"X-CSRFToken": csrf_token, # Include CSRF token header
}
resp = session.post(login_post_url, data=login_data, headers=headers, allow_redirects=True)
resp.raise_for_status()
class Client:
def __init__(self, session):
self._session = session
self._unauth_session = requests.Session()
resp = self._unauth_session.get(login_page_url)
resp.raise_for_status()
self._headers = csrf_token = {
"Referer": login_page_url,
"X-CSRFToken": self._unauth_session.cookies.get("csrftoken"),
}
def request(self, method, url, auth = False, **kwargs):
if auth:
session = self._session
else:
session = self._unauth_session
return session.request(method, url, headers=self._headers, **kwargs)
@property
def cookies(self):
return self._session.cookies
return Client(session)
list_view_urls = list_urls(urlpatterns = get_resolver().url_patterns)
@pytest.mark.parametrize(
argnames = "url_path",
argvalues = [
url for url in list_view_urls if( url in no_auth_urls )
],
ids = [
re.sub(r'[^\w_\-.:]', '_', url) for url in list_view_urls if( url in no_auth_urls )
],
)
def test_urls_no_auth_required(self, url_path, auto_login_client):
url = f"http://127.0.0.1:8003/{url_path}"
response = auto_login_client.request("GET", url)
assert response.status_code == 200
@pytest.mark.permissions
@pytest.mark.parametrize(
argnames = "url_path",
argvalues = [
url for url in list_view_urls if(
url not in no_auth_urls
and url not in urls_list_view_auth_required_excluded
)
],
ids = [
re.sub(r'[^\w_\-.:]', '_', url) for url in list_view_urls if(
url not in no_auth_urls
and url not in urls_list_view_auth_required_excluded
)
],
)
def test_urls_list_view_auth_required(self, url_path, auto_login_client):
url = f"http://127.0.0.1:8003/{url_path}"
response = auto_login_client.request("GET", url)
assert response.status_code == 401
@pytest.mark.permissions
@pytest.mark.parametrize(
argnames = "url_path",
argvalues = [
url for url in list_view_urls if(
url not in no_auth_urls
and url not in urls_list_view_auth_required_authenticated_excluded
)
],
ids = [
re.sub(r'[^\w_\-.:]', '_', url) for url in list_view_urls if(
url not in no_auth_urls
and url not in urls_list_view_auth_required_authenticated_excluded
)
],
)
def test_urls_list_view_auth_required_authenticated(self, url_path, auto_login_client):
url = f"http://127.0.0.1:8003/{url_path}"
response = auto_login_client.request(method = "GET", url = url, auth = True)
assert response.status_code == 200

View File

@ -1100,6 +1100,7 @@ markers = [
"audit_models: Selects Audit models.",
"centurion_models: Selects Centurion models",
"functional: Selects all Functional tests.",
"integration: Selects all Integration tests.",
"meta_models: Selects Meta models",
"mixin: Selects all mixin test cases.",
"mixin_centurion: Selects all centurion mixin test cases.",