Skip to content
Snippets Groups Projects
Commit 054c17e6 authored by DAVID Axel's avatar DAVID Axel
Browse files

test: :white_check_mark: Implements tests for new features and refactor

parent 30d5fd4d
No related branches found
No related tags found
No related merge requests found
Pipeline #15236 passed
Showing
with 488 additions and 61 deletions
......@@ -20,8 +20,7 @@ from collections.abc import Generator
import pytest
import pytest_asyncio
from blacksheep import Application
from blacksheep import Request
from blacksheep import Application, Request
from blacksheep.testing import TestClient
from vigenere_api.api import application
......
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import pytest
from blacksheep.server.controllers import APIController
from vigenere_api.api.helpers.controller import _camel_to_kebab, Controller
from vigenere_api.api.helpers.errors import NameTypeError
class CamelCaseToKebabCaseSuite:
@staticmethod
def test_camelcase() -> None:
converted = _camel_to_kebab("Camel")
assert converted == "camel"
converted = _camel_to_kebab("CamelCase")
assert converted == "camel-case"
@staticmethod
def test_kebab() -> None:
converted = _camel_to_kebab("camel-case")
assert converted == "camel-case"
@staticmethod
def test_snake_case() -> None:
converted = _camel_to_kebab("tedede_test")
assert converted == "tedede_test"
@staticmethod
@pytest.mark.raises(excpetion=NameTypeError)
def test_bad_type_name() -> None:
_ignored = _camel_to_kebab(b"tedede")
class ControllerSuite:
@staticmethod
def test_instantiate() -> None:
controller = Controller()
assert controller is not None
assert isinstance(controller, Controller)
assert isinstance(controller, APIController)
@staticmethod
def test_class_name() -> None:
assert Controller.__name__ == "Controller"
assert Controller.class_name() == ""
@staticmethod
def test_inheritance_with_basic_name() -> None:
class Test(Controller):
pass
test = Test()
assert isinstance(test, Controller)
assert isinstance(test, APIController)
assert test.class_name() == "test"
@staticmethod
def test_inheritance_with_controller_name() -> None:
class TestController(Controller):
pass
test = TestController()
assert isinstance(test, Controller)
assert isinstance(test, APIController)
assert test.class_name() == "test"
@staticmethod
def test_inheritance_with_complex_controller_name() -> None:
class ComplexTestController(Controller):
pass
test = ComplexTestController()
assert isinstance(test, Controller)
assert isinstance(test, APIController)
assert test.class_name() == "complex-test"
......@@ -14,54 +14,38 @@
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import pytest
from openapidocs.common import Format
from openapidocs.v3 import Contact
from openapidocs.v3 import ExternalDocs
from openapidocs.v3 import Info
from openapidocs.v3 import License
from openapidocs.v3 import Tag
from openapidocs.v3 import ExternalDocs, Tag
from vigenere_api.api import application
from vigenere_api.api.utils import VigenereAPIOpenAPIHandler
from vigenere_api.api.helpers import VigenereAPIOpenAPIHandler
from vigenere_api.api.helpers.errors import VersionTypeError
from vigenere_api.version import Version
def basic_test() -> None:
docs = VigenereAPIOpenAPIHandler(
info=Info(
title="Vigenere-API",
version="1.0.0",
description="""
An API to use cipher, decipher and decrypt method with the Vigenere algorithm.
The Caesar algorithm is provided for the cipher method and decipher method.
docs = VigenereAPIOpenAPIHandler(Version(major=1, minor=0, patch=0))
It's a JSON-RPC API.
Powered by BlackSheep framework: https://www.neoteroi.dev/blacksheep/
""",
contact=Contact(name="Axel DAVID", email="axel.david@etu.univ-amu.fr"),
license=License(name="GPL-3.0", url="TEST/LICENSE.md"),
),
ui_path="/api/v1",
preferred_format=Format.YAML,
)
assert docs.version == Version(major=1, minor=0, patch=0)
info = docs.info
assert info.title == "Vigenere-API"
assert info.version == "1.0.0"
assert info.description == (
"\n"
" An API to use cipher, decipher and decrypt method with the "
"Vigenere algorithm.\n"
" The Caesar algorithm is provided for the cipher method and "
"decipher method.\n"
"\n"
" It's a JSON-RPC API.\n"
" Powered by BlackSheep framework: "
"https://www.neoteroi.dev/blacksheep/\n"
" "
assert (
info.description
== """
An API to use cipher, decipher and decrypt method with the Vigenere algorithm.
The Caesar algorithm is provided for the cipher method and decipher method.
It's a JSON-RPC API.
Powered by BlackSheep framework: https://www.neoteroi.dev/blacksheep/
"""
)
assert info.contact.name == "Axel DAVID"
assert info.contact.email == "axel.david@etu.univ-amu.fr"
assert info.license.name == "GPL-3.0"
assert info.license.url == "TEST/LICENSE.md"
assert info.license.url == "http://localhost:8080/LICENSE.md"
assert docs.ui_providers[0].ui_path == "/api/v1"
......@@ -88,3 +72,8 @@ def basic_test() -> None:
),
),
]
@pytest.mark.raises(exception=VersionTypeError)
def test_bad_type_version() -> None:
_ignored = VigenereAPIOpenAPIHandler(b"toto")
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
from inspect import signature
import pytest
from blacksheep import Route
from vigenere_api.api.helpers.errors import (
ExcludedPathsTypeError,
ExcludedPathTypeError,
PathTypeError,
)
from vigenere_api.api.helpers.open_api_route_filter import get_route_filter
def test_get_filter() -> None:
excluded = []
filter = get_route_filter(excluded)
assert callable(filter)
s = signature(filter)
assert s.return_annotation == bool
parameters_type = list(s.parameters.values())
assert len(parameters_type) == 2
assert parameters_type[0].annotation == str
assert parameters_type[1].annotation == Route
@pytest.mark.raises(exception=ExcludedPathsTypeError)
def test_bad_type_excluded() -> None:
excluded = 10
_ignored = get_route_filter(excluded)
@pytest.mark.raises(exception=ExcludedPathTypeError)
def test_bad_type_path_in_excluded() -> None:
excluded = [b"test"]
_ignored = get_route_filter(excluded)
@pytest.mark.raises(exception=PathTypeError)
def test_filter_bad_type_path() -> None:
route_filter = get_route_filter(["/api"])
_ignored = route_filter(b"/http", Route("http", {}))
def test_filter_bad_type_route() -> None:
route_filter = get_route_filter(["/api"])
assert route_filter("/http", {})
def test_filter_route_excluded() -> None:
route_filter = get_route_filter(["/api"])
assert not route_filter("/api", Route("http", {}))
def test_filter_route_not_excluded() -> None:
route_filter = get_route_filter(["/api"])
assert route_filter("/http", Route("http", {}))
......@@ -31,3 +31,16 @@ async def test_get_index(test_client: TestClient) -> None:
first_header = response.headers.values[0]
assert first_header[0] == b"Location"
assert first_header[1] == b"/api/v1"
@pytest.mark.asyncio()
async def test_bad_path(test_client: TestClient) -> None:
response = await test_client.get("/zzzzzzzzzz")
assert response is not None
assert response.status == 200
assert response.content is not None
assert response.reason.upper() == "OK"
assert await response.text() == "OOPS! Nothing was found here!"
......@@ -16,15 +16,19 @@
from http import HTTPStatus
from blacksheep.server.openapi.common import ContentInfo
from blacksheep.server.openapi.common import RequestBodyInfo
from blacksheep.server.openapi.common import ResponseExample
from blacksheep.server.openapi.common import ResponseInfo
from blacksheep.server.openapi.common import (
ContentInfo,
RequestBodyInfo,
ResponseExample,
ResponseInfo,
)
from vigenere_api.api.v1.controllers.docs.caesar import CAESAR_DATA1
from vigenere_api.api.v1.controllers.docs.caesar import CAESAR_DATA2
from vigenere_api.api.v1.controllers.docs.caesar import CaesarControllerDocs
from vigenere_api.api.v1.controllers.docs.caesar import CaesarOperation
from vigenere_api.api.v1.controllers.caesar.docs import (
CAESAR_DATA1,
CAESAR_DATA2,
CaesarControllerDocs,
CaesarOperation,
)
from vigenere_api.models import CaesarData
......
......@@ -25,10 +25,6 @@ async def test_get_api_docs(test_client: TestClient) -> None:
assert response.status == 200
assert response.content is not None
assert (
response.content.body
== b'<!DOCTYPE html>\n<html>\n<head>\n <title>Vigenere-API</title>\n <link rel="icon" href="/favicon.png"/>\n <link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3.30.0/swagger-ui.css">\n</head>\n<body>\n <div id="swagger-ui"></div>\n <script src="https://cdn.jsdelivr.net/npm/swagger-ui-dist@3.30.0/swagger-ui-bundle.js"></script>\n <script>\n const ui = SwaggerUIBundle({\n url: \'/openapi.yaml\',\n oauth2RedirectUrl: window.location.origin + \'/docs/oauth2-redirect\',\n dom_id: \'#swagger-ui\',\n presets: [\n SwaggerUIBundle.presets.apis,\n SwaggerUIBundle.SwaggerUIStandalonePreset\n ],\n layout: "BaseLayout",\n deepLinking: true,\n showExtensions: true,\n showCommonExtensions: true\n })\n </script>\n</body>\n</html>\n'
)
assert response.reason.upper() == "OK"
......@@ -40,8 +36,4 @@ async def test_get_api_redocs(test_client: TestClient) -> None:
assert response.status == 200
assert response.content is not None
assert (
response.content.body
== b'<!DOCTYPE html>\n<html>\n <head>\n <title>Vigenere-API</title>\n <meta charset="utf-8"/>\n <meta name="viewport" content="width=device-width, initial-scale=1">\n <link rel="icon" href="/favicon.png"/>\n <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">\n <style>\n body {\n margin: 0;\n padding: 0;\n }\n </style>\n </head>\n <body>\n <redoc spec-url="/openapi.yaml"></redoc>\n <script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>\n </body>\n</html>\n'
)
assert response.reason.upper() == "OK"
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import pytest
from vigenere_api.helpers import VigenereAPITypeError
@pytest.mark.raises(
exception=VigenereAPITypeError, message="The text is 'str'. Please give a bytes."
)
def test_throws_VigenereAPITypeError() -> None:
raise VigenereAPITypeError("test", "text", "a bytes")
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
from vigenere_api.helpers import Model
def test_instantiate() -> None:
obj = Model()
assert obj is not None
class InheritanceSuite:
@staticmethod
def test_basic() -> None:
class Test(Model):
pass
obj = Test()
assert obj is not None
assert obj == Model()
@staticmethod
def test_with_new_field() -> None:
class Test(Model):
test: str
obj = Test(test="TEST")
assert obj is not None
assert obj.test == "TEST"
......@@ -34,3 +34,20 @@ def test_get_index(server: str) -> None:
assert response.next is not None
assert response.next.path_url == "/api/v1"
@pytest.mark.integration_test()
def test_bad_path(server: str) -> None:
response = requests.get(
url=f"{server}/zzzzzzzzzz",
timeout=1,
allow_redirects=False,
)
assert response is not None
assert response.status == 200
assert response.content is not None
assert response.reason.upper() == "OK"
assert response.text == "OOPS! Nothing was found here!"
......@@ -20,8 +20,7 @@ import pytest
from pydantic import ValidationError
from vigenere_api.models.caesar import CaesarData
from vigenere_api.models.errors import AlgorithmKeyTypeError
from vigenere_api.models.errors import AlgorithmTextTypeError
from vigenere_api.models.errors import AlgorithmKeyTypeError, AlgorithmTextTypeError
class CtorSuite:
......
......@@ -18,13 +18,15 @@
import pytest
from vigenere_api.models.helper import move_char
from vigenere_api.models.helper.errors import HelperBadCharValueError
from vigenere_api.models.helper.errors import HelperBadFirstLetterValueError
from vigenere_api.models.helper.errors import HelperBadLengthCharValueError
from vigenere_api.models.helper.errors import HelperCharTypeError
from vigenere_api.models.helper.errors import HelperFirstLetterTypeError
from vigenere_api.models.helper.errors import HelperKeyTypeError
from vigenere_api.models.helpers import move_char
from vigenere_api.models.helpers.errors import (
HelperBadCharValueError,
HelperBadFirstLetterValueError,
HelperBadLengthCharValueError,
HelperCharTypeError,
HelperFirstLetterTypeError,
HelperKeyTypeError,
)
def test_move_lower_letter() -> None:
......
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Vigenere-API +
# Copyright (C) 2023 Axel DAVID +
# +
# This program is free software: you can redistribute it and/or modify it under +
# the terms of the GNU General Public License as published by the Free Software +
# Foundation, either version 3 of the License, or (at your option) any later version. +
# +
# This program is distributed in the hope that it will be useful, but WITHOUT ANY +
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +
# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +
# +
# You should have received a copy of the GNU General Public License along with +
# this program. If not, see <https://www.gnu.org/licenses/>. +
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
import pytest
from pydantic import ValidationError
from vigenere_api.version import get_version, Version
class CtorSuite:
@staticmethod
def test_ctor() -> None:
v = Version(major=1, minor=0, patch=0)
assert v.major == 1
assert v.minor == 0
assert v.patch == 0
class MissingFieldsSuite:
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="major")
def test_without_major() -> None:
_ignored = Version(minor=0, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="minor")
def test_without_minor() -> None:
_ignored = Version(major=0, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="patch")
def test_without_patch() -> None:
_ignored = Version(minor=0, major=0)
@staticmethod
def test_with_only_patch() -> None:
with pytest.raises(ValidationError) as error:
_ignored = Version(patch=0)
error_msg = str(error)
assert "minor" in error_msg
assert "major" in error_msg
@staticmethod
def test_with_only_minor() -> None:
with pytest.raises(ValidationError) as error:
_ignored = Version(minor=0)
error_msg = str(error)
assert "patch" in error_msg
assert "major" in error_msg
@staticmethod
def test_with_only_manor() -> None:
with pytest.raises(ValidationError) as error:
_ignored = Version(major=0)
error_msg = str(error)
assert "minor" in error_msg
assert "patch" in error_msg
@staticmethod
def test_with_nothing() -> None:
with pytest.raises(ValidationError) as error:
_ignored = Version()
error = error.value.args[0]
assert "major" in error[0]._loc
assert "minor" in error[1]._loc
assert "patch" in error[2]._loc
class BadTypeSuite:
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="major")
def test_major() -> None:
_ignored = Version(major=1.0, minor=0, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="minor")
def test_minor() -> None:
_ignored = Version(major=1, minor=0.0, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="patch")
def test_patch() -> None:
_ignored = Version(major=1, minor=0, patch=0.0)
class BadValueSuite:
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="major")
def test_major() -> None:
_ignored = Version(major=-10, minor=0, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="minor")
def test_minor() -> None:
_ignored = Version(major=1, minor=-8, patch=0)
@staticmethod
@pytest.mark.raises(exception=ValidationError, message="patch")
def test_patch() -> None:
_ignored = Version(major=1, minor=0, patch=-9)
class OperationSuite:
@staticmethod
def test_str() -> None:
v = Version(major=1, minor=0, patch=0)
assert str(v) == "1.0.0"
def test_get_version() -> None:
v = get_version()
assert isinstance(v, Version)
assert v == Version(major=1, minor=0, patch=0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment