Commit 5019220c authored by George Papathanail's avatar George Papathanail
Browse files

change federation_controller, add tests

parent ffbdd363
Loading
Loading
Loading
Loading
Loading
(52 KiB)

File changed.

No diff preview for this file type.

+177 −62
Original line number Diff line number Diff line
<?xml version="1.0" ?>
<coverage version="7.9.1" timestamp="1751027832353" lines-valid="609" lines-covered="130" line-rate="0.2135" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
<coverage version="7.9.1" timestamp="1751628678582" lines-valid="724" lines-covered="181" line-rate="0.25" branches-covered="0" branches-valid="0" branch-rate="0" complexity="0">
	<!-- Generated by coverage.py: https://coverage.readthedocs.io/en/7.9.1 -->
	<!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
	<sources>
@@ -61,7 +61,7 @@
				</class>
			</classes>
		</package>
		<package name="controllers" line-rate="0.4514" branch-rate="0" complexity="0">
		<package name="controllers" line-rate="0.519" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="controllers/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
@@ -210,51 +210,86 @@
						<line number="69" hits="1"/>
						<line number="83" hits="1"/>
						<line number="84" hits="1"/>
						<line number="93" hits="1"/>
						<line number="94" hits="0"/>
						<line number="98" hits="1"/>
						<line number="99" hits="0"/>
						<line number="101" hits="1"/>
						<line number="92" hits="1"/>
						<line number="93" hits="0"/>
						<line number="96" hits="1"/>
						<line number="97" hits="0"/>
						<line number="99" hits="1"/>
						<line number="100" hits="1"/>
						<line number="102" hits="1"/>
						<line number="104" hits="1"/>
						<line number="105" hits="1"/>
						<line number="110" hits="0"/>
						<line number="111" hits="0"/>
						<line number="116" hits="0"/>
						<line number="103" hits="1"/>
						<line number="108" hits="0"/>
						<line number="109" hits="0"/>
						<line number="114" hits="0"/>
					</lines>
				</class>
				<class name="federation_manager_controller.py" filename="controllers/federation_manager_controller.py" complexity="0" line-rate="0" branch-rate="0">
				<class name="federation_manager_controller.py" filename="controllers/federation_manager_controller.py" complexity="0" line-rate="0.4688" branch-rate="0">
					<methods/>
					<lines>
						<line number="1" hits="0"/>
						<line number="2" hits="0"/>
						<line number="4" hits="0"/>
						<line number="5" hits="0"/>
						<line number="7" hits="0"/>
						<line number="12" hits="0"/>
						<line number="13" hits="0"/>
						<line number="14" hits="0"/>
						<line number="15" hits="0"/>
						<line number="1" hits="1"/>
						<line number="2" hits="1"/>
						<line number="5" hits="1"/>
						<line number="10" hits="1"/>
						<line number="11" hits="1"/>
						<line number="12" hits="1"/>
						<line number="13" hits="1"/>
						<line number="14" hits="1"/>
						<line number="15" hits="1"/>
						<line number="16" hits="0"/>
						<line number="17" hits="0"/>
						<line number="20" hits="0"/>
						<line number="25" hits="0"/>
						<line number="26" hits="0"/>
						<line number="27" hits="0"/>
						<line number="28" hits="0"/>
						<line number="29" hits="0"/>
						<line number="32" hits="0"/>
						<line number="37" hits="0"/>
						<line number="38" hits="0"/>
						<line number="39" hits="0"/>
						<line number="40" hits="0"/>
						<line number="41" hits="0"/>
						<line number="20" hits="1"/>
						<line number="25" hits="1"/>
						<line number="26" hits="1"/>
						<line number="27" hits="1"/>
						<line number="28" hits="1"/>
						<line number="29" hits="1"/>
						<line number="30" hits="0"/>
						<line number="31" hits="0"/>
						<line number="34" hits="1"/>
						<line number="39" hits="1"/>
						<line number="40" hits="1"/>
						<line number="41" hits="1"/>
						<line number="42" hits="1"/>
						<line number="43" hits="1"/>
						<line number="44" hits="0"/>
						<line number="49" hits="0"/>
						<line number="50" hits="0"/>
						<line number="51" hits="0"/>
						<line number="52" hits="0"/>
						<line number="53" hits="0"/>
						<line number="45" hits="0"/>
						<line number="48" hits="1"/>
						<line number="53" hits="1"/>
						<line number="54" hits="1"/>
						<line number="55" hits="1"/>
						<line number="56" hits="1"/>
						<line number="57" hits="1"/>
						<line number="58" hits="0"/>
						<line number="59" hits="0"/>
						<line number="62" hits="1"/>
						<line number="67" hits="0"/>
						<line number="68" hits="0"/>
						<line number="69" hits="0"/>
						<line number="70" hits="0"/>
						<line number="71" hits="0"/>
						<line number="72" hits="0"/>
						<line number="73" hits="0"/>
						<line number="74" hits="0"/>
						<line number="77" hits="1"/>
						<line number="82" hits="0"/>
						<line number="83" hits="0"/>
						<line number="84" hits="0"/>
						<line number="85" hits="0"/>
						<line number="86" hits="0"/>
						<line number="87" hits="0"/>
						<line number="88" hits="0"/>
						<line number="89" hits="0"/>
						<line number="90" hits="0"/>
						<line number="93" hits="1"/>
						<line number="98" hits="0"/>
						<line number="99" hits="0"/>
						<line number="100" hits="0"/>
						<line number="101" hits="0"/>
						<line number="102" hits="0"/>
						<line number="103" hits="0"/>
						<line number="104" hits="0"/>
						<line number="105" hits="0"/>
						<line number="106" hits="0"/>
					</lines>
				</class>
			</classes>
@@ -463,29 +498,27 @@
				</class>
			</classes>
		</package>
		<package name="services" line-rate="0.08871" branch-rate="0" complexity="0">
		<package name="services" line-rate="0.1311" branch-rate="0" complexity="0">
			<classes>
				<class name="__init__.py" filename="services/__init__.py" complexity="0" line-rate="1" branch-rate="0">
					<methods/>
					<lines/>
				</class>
				<class name="federation_services.py" filename="services/federation_services.py" complexity="0" line-rate="0" branch-rate="0">
				<class name="federation_services.py" filename="services/federation_services.py" complexity="0" line-rate="0.1214" branch-rate="0">
					<methods/>
					<lines>
						<line number="1" hits="0"/>
						<line number="2" hits="0"/>
						<line number="3" hits="0"/>
						<line number="4" hits="0"/>
						<line number="6" hits="0"/>
						<line number="7" hits="0"/>
						<line number="8" hits="0"/>
						<line number="10" hits="0"/>
						<line number="11" hits="0"/>
						<line number="16" hits="0"/>
						<line number="17" hits="0"/>
						<line number="18" hits="0"/>
						<line number="19" hits="0"/>
						<line number="20" hits="0"/>
						<line number="1" hits="1"/>
						<line number="2" hits="1"/>
						<line number="3" hits="1"/>
						<line number="4" hits="1"/>
						<line number="5" hits="1"/>
						<line number="6" hits="1"/>
						<line number="10" hits="1"/>
						<line number="11" hits="1"/>
						<line number="12" hits="0"/>
						<line number="14" hits="1"/>
						<line number="15" hits="0"/>
						<line number="20" hits="1"/>
						<line number="21" hits="0"/>
						<line number="22" hits="0"/>
						<line number="23" hits="0"/>
@@ -499,11 +532,11 @@
						<line number="31" hits="0"/>
						<line number="32" hits="0"/>
						<line number="33" hits="0"/>
						<line number="34" hits="0"/>
						<line number="35" hits="0"/>
						<line number="36" hits="0"/>
						<line number="37" hits="0"/>
						<line number="38" hits="0"/>
						<line number="39" hits="0"/>
						<line number="39" hits="1"/>
						<line number="40" hits="0"/>
						<line number="41" hits="0"/>
						<line number="42" hits="0"/>
@@ -517,11 +550,11 @@
						<line number="50" hits="0"/>
						<line number="51" hits="0"/>
						<line number="52" hits="0"/>
						<line number="53" hits="0"/>
						<line number="54" hits="0"/>
						<line number="55" hits="0"/>
						<line number="56" hits="0"/>
						<line number="57" hits="0"/>
						<line number="58" hits="0"/>
						<line number="58" hits="1"/>
						<line number="59" hits="0"/>
						<line number="60" hits="0"/>
						<line number="61" hits="0"/>
@@ -536,11 +569,11 @@
						<line number="70" hits="0"/>
						<line number="71" hits="0"/>
						<line number="72" hits="0"/>
						<line number="73" hits="0"/>
						<line number="74" hits="0"/>
						<line number="75" hits="0"/>
						<line number="76" hits="0"/>
						<line number="77" hits="0"/>
						<line number="78" hits="0"/>
						<line number="78" hits="1"/>
						<line number="79" hits="0"/>
						<line number="80" hits="0"/>
						<line number="81" hits="0"/>
@@ -554,17 +587,99 @@
						<line number="89" hits="0"/>
						<line number="90" hits="0"/>
						<line number="91" hits="0"/>
						<line number="92" hits="0"/>
						<line number="93" hits="0"/>
						<line number="94" hits="0"/>
						<line number="95" hits="0"/>
						<line number="96" hits="0"/>
						<line number="97" hits="1"/>
						<line number="98" hits="0"/>
						<line number="99" hits="0"/>
						<line number="100" hits="0"/>
						<line number="101" hits="0"/>
						<line number="102" hits="0"/>
						<line number="103" hits="0"/>
						<line number="104" hits="0"/>
						<line number="105" hits="0"/>
						<line number="106" hits="0"/>
						<line number="107" hits="0"/>
						<line number="108" hits="0"/>
						<line number="109" hits="0"/>
						<line number="110" hits="0"/>
						<line number="111" hits="0"/>
						<line number="112" hits="0"/>
						<line number="113" hits="0"/>
						<line number="114" hits="0"/>
						<line number="117" hits="1"/>
						<line number="118" hits="0"/>
						<line number="119" hits="0"/>
						<line number="120" hits="0"/>
						<line number="121" hits="0"/>
						<line number="122" hits="0"/>
						<line number="123" hits="0"/>
						<line number="124" hits="0"/>
						<line number="125" hits="0"/>
						<line number="126" hits="0"/>
						<line number="127" hits="0"/>
						<line number="128" hits="0"/>
						<line number="129" hits="0"/>
						<line number="130" hits="0"/>
						<line number="131" hits="0"/>
						<line number="132" hits="0"/>
						<line number="133" hits="0"/>
						<line number="134" hits="0"/>
						<line number="136" hits="1"/>
						<line number="137" hits="0"/>
						<line number="138" hits="0"/>
						<line number="139" hits="0"/>
						<line number="140" hits="0"/>
						<line number="141" hits="0"/>
						<line number="142" hits="0"/>
						<line number="143" hits="0"/>
						<line number="144" hits="0"/>
						<line number="145" hits="0"/>
						<line number="146" hits="0"/>
						<line number="147" hits="0"/>
						<line number="148" hits="0"/>
						<line number="149" hits="0"/>
						<line number="150" hits="0"/>
						<line number="151" hits="0"/>
						<line number="152" hits="0"/>
						<line number="153" hits="0"/>
						<line number="157" hits="1"/>
						<line number="158" hits="1"/>
						<line number="159" hits="0"/>
						<line number="161" hits="1"/>
						<line number="162" hits="0"/>
						<line number="163" hits="0"/>
						<line number="165" hits="1"/>
						<line number="166" hits="0"/>
						<line number="167" hits="0"/>
						<line number="168" hits="0"/>
						<line number="170" hits="0"/>
						<line number="171" hits="0"/>
						<line number="172" hits="0"/>
						<line number="174" hits="0"/>
						<line number="175" hits="0"/>
						<line number="177" hits="0"/>
						<line number="178" hits="0"/>
						<line number="180" hits="0"/>
						<line number="181" hits="0"/>
						<line number="188" hits="0"/>
						<line number="189" hits="0"/>
						<line number="191" hits="0"/>
						<line number="192" hits="0"/>
						<line number="193" hits="0"/>
						<line number="194" hits="0"/>
						<line number="195" hits="0"/>
						<line number="196" hits="0"/>
						<line number="202" hits="0"/>
						<line number="203" hits="0"/>
						<line number="210" hits="0"/>
						<line number="213" hits="1"/>
						<line number="214" hits="0"/>
						<line number="215" hits="0"/>
						<line number="217" hits="0"/>
						<line number="218" hits="0"/>
					</lines>
				</class>
				<class name="pi_edge_services.py" filename="services/pi_edge_services.py" complexity="0" line-rate="0.1419" branch-rate="0">
+20 −8
Original line number Diff line number Diff line
from flask import request, jsonify
from edge_cloud_management_api.services.federation_services import FederationManagerClientFactory

factory = FederationManagerClientFactory()
federation_client = factory.create_federation_client()

def create_federation():
    """
@@ -10,6 +8,8 @@ def create_federation():
    Forwards the federation creation request to Federation Manager.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        body = request.get_json()
        result = federation_client.post_partner(body)
        return jsonify(result), 200 if "error" not in result else 502
@@ -23,6 +23,8 @@ def get_federation(federationContextId):
    Forwards the GET federation info request.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        result = federation_client.get_partner(federationContextId)
        return jsonify(result), 200 if "error" not in result else 502
    except Exception as e:
@@ -35,6 +37,8 @@ def delete_federation(federationContextId):
    Forwards the DELETE federation request.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        result = federation_client.delete_partner(federationContextId)
        return jsonify(result), 200 if "error" not in result else 502
    except Exception as e:
@@ -47,32 +51,37 @@ def get_federation_context_ids():
    Forwards the request to fetch federation context IDs.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        result = federation_client.get_federation_context_ids()
        return jsonify(result), 200 if "error" not in result else 502
    except Exception as e:
        return jsonify({"error": str(e)}), 400


        
        
def onboard_application_to_partner(federationContextId):
    """
    POST /{federationContextId}/application/onboarding
    Forwards the onboarding request to the Federation Manager.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        body = request.get_json()
        result = federation_client.onboard_application(federationContextId, body)
        return jsonify(result), 202 if "error" not in result else 502
    except Exception as e:
        return jsonify({"error": str(e)}), 400


def get_onboarded_app(federationContextId, appId):
    """
    GET /{federationContextId}/application/onboarding/app/{appId}
    Retrieves onboarding info of a federated app from a partner OP.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        result = federation_client.get_onboarded_app(federationContextId, appId)
        if "error" in result:
            return jsonify(result), result.get("status_code", 502)
@@ -80,12 +89,15 @@ def get_onboarded_app(federationContextId, appId):
    except Exception as e:
        return jsonify({"error": str(e)}), 500


def delete_onboarded_app(federationContextId, appId):
    """
    DELETE /{federationContextId}/application/onboarding/app/{appId}
    Deboards the application and deletes it from the partner OP.
    """
    try:
        factory = FederationManagerClientFactory()
        federation_client = factory.create_federation_client()
        result = federation_client.delete_onboarded_app(federationContextId, appId)
        if "error" in result:
            return jsonify(result), result.get("status_code", 502)

results.txt

0 → 100644
+170 −0

File added.

Preview size limit exceeded, changes collapsed.

+81 −0
Original line number Diff line number Diff line
import pytest
from unittest.mock import patch, MagicMock
from flask import Flask
from edge_cloud_management_api.controllers import federation_manager_controller


@pytest.fixture
def test_app():
    app = Flask(__name__)
    app.config["TESTING"] = True
    with app.app_context():
        yield app


@pytest.mark.component
@patch("edge_cloud_management_api.controllers.federation_manager_controller.FederationManagerClientFactory")
def test_create_federation(mock_factory_class, test_app: Flask):
    """Test create_federation returns federation data"""
    body = {
        "origOPFederationId": "orig-123",
        "initialDate": "2024-01-01T00:00:00Z",
        "partnerStatusLink": "https://callback.example.com/status"
    }

    mock_client = MagicMock()
    mock_client.post_partner.return_value = {"federationContextId": "abc", "partnerOPFederationId": "partner-xyz"}
    mock_factory_class.return_value.create_federation_client.return_value = mock_client

    with test_app.test_request_context(json=body):
        response, status = federation_manager_controller.create_federation()

    assert status == 200
    data = response.get_json()
    assert "federationContextId" in data
    assert data["federationContextId"] == "abc"


@pytest.mark.component
@patch("edge_cloud_management_api.controllers.federation_manager_controller.FederationManagerClientFactory")
def test_get_federation(mock_factory_class, test_app: Flask):
    federation_context_id = "abc"

    mock_client = MagicMock()
    mock_client.get_partner.return_value = {"some": "data"}
    mock_factory_class.return_value.create_federation_client.return_value = mock_client

    with test_app.test_request_context():
        response, status = federation_manager_controller.get_federation(federation_context_id)

    assert status == 200
    assert response.get_json() == {"some": "data"}


@pytest.mark.component
@patch("edge_cloud_management_api.controllers.federation_manager_controller.FederationManagerClientFactory")
def test_delete_federation(mock_factory_class, test_app: Flask):
    federation_context_id = "abc"

    mock_client = MagicMock()
    mock_client.delete_partner.return_value = {"result": "Deleted"}
    mock_factory_class.return_value.create_federation_client.return_value = mock_client

    with test_app.test_request_context():
        response, status = federation_manager_controller.delete_federation(federation_context_id)

    assert status == 200
    assert response.get_json() == {"result": "Deleted"}


@pytest.mark.component
@patch("edge_cloud_management_api.controllers.federation_manager_controller.FederationManagerClientFactory")
def test_get_federation_context_ids(mock_factory_class, test_app: Flask):
    mock_client = MagicMock()
    mock_client.get_federation_context_ids.return_value = {"FederationContextId": "ctx-123"}
    mock_factory_class.return_value.create_federation_client.return_value = mock_client

    with test_app.test_request_context():
        response, status = federation_manager_controller.get_federation_context_ids()

    assert status == 200
    assert response.get_json() == {"FederationContextId": "ctx-123"}