Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
API_KEY=
API_KEY=
E2E_API_KEY=
E2E_BASE_URL=https://testapi.multisafepay.com/v1/
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,24 @@ make lint
make test
```

### E2E target environment

By default, E2E tests target `https://testapi.multisafepay.com/v1/`.

Use dedicated E2E variables instead of the general SDK variables:

```bash
export E2E_API_KEY="<test_api_key>"
export E2E_BASE_URL="https://testapi.multisafepay.com/v1/" # optional
make test-e2e
```

`E2E_BASE_URL` is optional and can point to any HTTPS base URL used for E2E.
When omitted, E2E defaults to `testapi.multisafepay.com`.

The e2e suite does not use the shared `API_KEY` variable or the shared `MSP_SDK_*`
custom base URL settings.

## Support

Create an issue on this repository or email <a href="mailto:integration@multisafepay.com">
Expand Down
82 changes: 78 additions & 4 deletions tests/multisafepay/e2e/conftest.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,103 @@
"""Configuration for end-to-end tests."""

import os
from collections.abc import Callable
from typing import Optional
from urllib.parse import urlparse

import pytest
from dotenv import load_dotenv

from multisafepay.client import Client
from multisafepay.sdk import Sdk
from multisafepay.transport import HTTPTransport

E2E_API_KEY_ENV = "E2E_API_KEY"
E2E_BASE_URL_ENV = "E2E_BASE_URL"

# Load .env file from the project root
load_dotenv()


def _get_e2e_api_key() -> str:
return os.getenv(E2E_API_KEY_ENV, "").strip()


def _get_e2e_base_url() -> str:
base_url = os.getenv(E2E_BASE_URL_ENV, "").strip()
return base_url or Client.TEST_URL


def _validate_e2e_base_url(base_url: str) -> str:
parsed = urlparse(base_url)
if parsed.scheme != "https" or not parsed.netloc:
msg = f"{E2E_BASE_URL_ENV} must be a valid https URL"
raise pytest.UsageError(msg)

parsed = urlparse(base_url)
path = parsed.path.rstrip("/")
normalized_path = "/" if not path else f"{path}/"
return f"{parsed.scheme}://{parsed.netloc}{normalized_path}"


@pytest.fixture(scope="session")
def e2e_api_key() -> str:
"""Return the dedicated API key used by E2E tests."""
api_key = _get_e2e_api_key()
if not api_key:
pytest.skip(f"E2E tests require {E2E_API_KEY_ENV} (not set)")

return api_key


@pytest.fixture(scope="session")
def e2e_base_url() -> str:
"""Return the dedicated base URL used by E2E tests."""
return _validate_e2e_base_url(_get_e2e_base_url())


@pytest.fixture(scope="session")
def e2e_sdk_factory(
e2e_api_key: str,
e2e_base_url: str,
) -> Callable[..., Sdk]:
"""Create SDK instances for E2E tests with a shared configuration."""

def create_sdk(*, transport: Optional[HTTPTransport] = None) -> Sdk:
sdk = Sdk(
api_key=e2e_api_key,
is_production=False,
transport=transport,
)
sdk.get_client().url = e2e_base_url

return sdk

return create_sdk


@pytest.fixture(scope="session")
def e2e_sdk(e2e_sdk_factory: Callable[..., Sdk]) -> Sdk:
"""Return the default SDK instance used by E2E tests."""
return e2e_sdk_factory()


def pytest_collection_modifyitems(
config: pytest.Config, # noqa: ARG001
items: list[pytest.Item],
) -> None:
"""
Skip all e2e tests when API_KEY is missing.
Skip all e2e tests when E2E_API_KEY is missing.

These tests perform real API calls. In most local/CI environments the secret
isn't present, so we prefer a clean skip over hard errors during fixture setup.
"""
api_key = os.getenv("API_KEY")
if api_key and api_key.strip():
if _get_e2e_api_key():
return

skip = pytest.mark.skip(reason="E2E tests require API_KEY (not set)")
skip = pytest.mark.skip(
reason=f"E2E tests require {E2E_API_KEY_ENV} (not set)",
)
for item in items:
# This hook runs for the whole session (all collected tests), even when
# this conftest is only loaded due to e2e tests being present/deselected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv

from multisafepay.api.base.response.custom_api_response import (
CustomApiResponse,
Expand All @@ -21,12 +19,9 @@


@pytest.fixture(scope="module")
def auth_manager() -> AuthManager:
def auth_manager(e2e_sdk: Sdk) -> AuthManager:
"""Fixture that provides an AuthManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_auth_manager()
return e2e_sdk.get_auth_manager()


def test_get_api_token(auth_manager: AuthManager):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@

"""Test module for e2e testing."""

import os
import time
import pytest
from typing import TYPE_CHECKING

from dotenv import load_dotenv
from multisafepay.api.paths.capture.response.capture import CancelReservation
from multisafepay.api.paths.capture.request.capture_request import (
CaptureRequest,
Expand Down Expand Up @@ -49,11 +47,9 @@


@pytest.fixture(scope="module")
def sdk() -> Sdk:
def sdk(e2e_sdk: Sdk) -> Sdk:
"""Fixture that provides an SDK instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
return Sdk(api_key, False)
return e2e_sdk


def test_capture_reservation_cancel(sdk: Sdk):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv

from multisafepay.api.base.response.custom_api_response import (
CustomApiResponse,
Expand All @@ -24,12 +22,9 @@


@pytest.fixture(scope="module")
def category_manager() -> "CategoryManager":
def category_manager(e2e_sdk: Sdk) -> "CategoryManager":
"""Fixture that provides a CategoryManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_category_manager()
return e2e_sdk.get_category_manager()


def test_get_categories(category_manager: CategoryManager):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv
from multisafepay.api.base.response.custom_api_response import (
CustomApiResponse,
)
Expand All @@ -20,12 +18,9 @@


@pytest.fixture(scope="module")
def gateway_manager() -> GatewayManager:
def gateway_manager(e2e_sdk: Sdk) -> GatewayManager:
"""Fixture that provides a GatewayManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_gateway_manager()
return e2e_sdk.get_gateway_manager()


def test_get_by_code(gateway_manager: GatewayManager):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv
from multisafepay.api.base.response.custom_api_response import (
CustomApiResponse,
)
Expand All @@ -20,12 +18,9 @@


@pytest.fixture(scope="module")
def gateway_manager() -> GatewayManager:
def gateway_manager(e2e_sdk: Sdk) -> GatewayManager:
"""Fixture that provides a GatewayManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_gateway_manager()
return e2e_sdk.get_gateway_manager()


def test_get_gateways(gateway_manager: GatewayManager):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv
from multisafepay.api.paths.issuers.response.issuer import Issuer

from multisafepay.api.base.response.custom_api_response import (
Expand All @@ -21,12 +19,9 @@


@pytest.fixture(scope="module")
def issuer_manager() -> IssuerManager:
def issuer_manager(e2e_sdk: Sdk) -> IssuerManager:
"""Fixture that provides an IssuerManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_issuer_manager()
return e2e_sdk.get_issuer_manager()


def test_get_issuers_by_gateway_code(issuer_manager: IssuerManager):
Expand Down
9 changes: 2 additions & 7 deletions tests/multisafepay/e2e/examples/me_manager/test_get_me.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

"""Test module for e2e testing."""

import os
import pytest
from dotenv import load_dotenv

from multisafepay.api.paths.me.response.me import Me

Expand All @@ -24,12 +22,9 @@


@pytest.fixture(scope="module")
def me_manager() -> "MeManager":
def me_manager(e2e_sdk: Sdk) -> "MeManager":
"""Fixture that provides a MeManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_me_manager()
return e2e_sdk.get_me_manager()


def test_get_me(me_manager: MeManager):
Expand Down
9 changes: 2 additions & 7 deletions tests/multisafepay/e2e/examples/order_manager/test_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

"""Test module for e2e testing."""

import os
import time
import pytest
from dotenv import load_dotenv
from typing import TYPE_CHECKING


Expand Down Expand Up @@ -45,12 +43,9 @@


@pytest.fixture(scope="module")
def order_manager() -> OrderManager:
def order_manager(e2e_sdk: Sdk) -> OrderManager:
"""Fixture that provides an OrderManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_order_manager()
return e2e_sdk.get_order_manager()


def test_capture(order_manager: OrderManager):
Expand Down
9 changes: 2 additions & 7 deletions tests/multisafepay/e2e/examples/order_manager/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

"""Test module for e2e testing."""

import os
import time
import pytest
from dotenv import load_dotenv

from multisafepay.value_object.weight import Weight
from multisafepay.api.shared.cart.cart_item import CartItem
Expand Down Expand Up @@ -43,12 +41,9 @@


@pytest.fixture(scope="module")
def order_manager() -> "OrderManager":
def order_manager(e2e_sdk: Sdk) -> "OrderManager":
"""Fixture that provides an OrderManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_order_manager()
return e2e_sdk.get_order_manager()


def test_create_order(order_manager: OrderManager):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@

"""Test module for e2e testing."""

import os
import time
import pytest
from dotenv import load_dotenv
from multisafepay.api.paths.orders.order_manager import OrderManager
from multisafepay.value_object.weight import Weight
from multisafepay.api.shared.cart.cart_item import CartItem
Expand Down Expand Up @@ -40,12 +38,9 @@


@pytest.fixture(scope="module")
def order_manager() -> OrderManager:
def order_manager(e2e_sdk: Sdk) -> OrderManager:
"""Fixture that provides an OrderManager instance for testing."""
load_dotenv()
api_key = os.getenv("API_KEY")
multisafepay_sdk = Sdk(api_key, False)
return multisafepay_sdk.get_order_manager()
return e2e_sdk.get_order_manager()


def test_get_order(order_manager: OrderManager):
Expand Down
Loading
Loading