bmc_hub/tests/test_globalconnect_internet_sync.py
Christian adc4fb5876 Implement tests for sag module, add knowledge base templates, and enhance internet connection migrations
- Added multiple test cases for the sag module to ensure proper functionality and data handling.
- Created new templates for knowledge detail and knowledge index pages to display articles and solutions.
- Introduced migrations to enhance the internet connections schema, including new columns for manual sharing and SLA subscriptions.
- Added a script to reconcile known internet connections with verified data.
- Planned the implementation of a new website content administration module for managing customer references and operational status.
2026-08-30 14:34:43 +02:00

863 lines
33 KiB
Python

import sys
from decimal import Decimal
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from app.billing.backend import supplier_invoices as supplier_module
def test_sync_globalconnect_extraction_creates_connections_and_ip_ranges(monkeypatch):
created_connections = []
created_ranges = []
ensured_ranges = []
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "100 Mbps fiberforbindelse",
"provider_reference": "NKA008214",
"circuit_id": "NKA008214",
"line_total": 2850.0,
"unit_price": 950.0,
"quantity": 3,
"end_customer_name": "Malerfirmaet Gert Jensen ApS",
"service_address": "Metalbuen 26, 2750 Ballerup",
},
{
"description": "IPv4 IP-adresser",
"provider_reference": "NKA008214",
"circuit_id": "NKA008214",
"ip_address": "152.115.84.232/29",
"line_total": 192.0,
"unit_price": 64.0,
"quantity": 3,
"end_customer_name": "Malerfirmaet Gert Jensen ApS",
"service_address": "Metalbuen 26, 2750 Ballerup",
},
]
def fake_load_lines(_):
return lines
def fake_load_customers():
return [{"id": 322, "name": "Malerfirmaet Gert Jensen ApS", "address": "Metalbuen 26", "postal_code": "2750", "city": "Ballerup"}]
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_connections" in query and "WHERE id = %s" in query:
return {"address": "Metalbuen 26, 2750 Ballerup", "allocation_model": "dedicated"}
if "FROM internet_connections_pricing" in query:
return None
if "FROM internet_connections_ip_ranges" in query:
return None
if "COUNT(*) AS total" in query and "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
if "FROM internet_connections_ip_addresses" in query and "WHERE ip_address = %s" in query:
return None
return None
def fake_execute_query(query, params=None):
if "FROM internet_connections_connections" in query:
return []
if "FROM internet_connections_ip_ranges" in query:
return []
return []
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_connections" in query:
created_connections.append(params)
return 501
if "INSERT INTO internet_connections_ip_ranges" in query:
created_ranges.append(params)
return 601
return 1
def fake_execute_update(query, params=None):
if "INSERT INTO internet_connections_ip_addresses" in query:
ensured_ranges.append(params[0])
return 1
monkeypatch.setattr(supplier_module, "_load_extraction_lines", fake_load_lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", fake_load_customers)
monkeypatch.setattr(supplier_module, "execute_query", fake_execute_query)
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
monkeypatch.setattr(supplier_module, "execute_update", fake_execute_update)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["skipped"] is False
assert result["connections_synced"] == 1
assert result["connections_synced"] == 1
assert created_connections
assert created_ranges
assert ensured_ranges
assert created_connections[0][0] == "Malerfirmaet Gert Jensen ApS"
assert created_connections[0][2] is None
assert created_connections[0][9] == 100
assert created_connections[0][10] == 100
assert created_connections[0][11] == 100
assert created_connections[0][13] == "dedicated"
assert created_connections[0][14] == "other"
assert created_ranges[0][2] == "152.115.84.232/29"
assert created_ranges[0][6] is None
def test_sync_globalconnect_infers_dsl_kbps_speed(monkeypatch):
created_connections = []
extraction = {
"extraction_id": 175,
"vendor_name": "GlobalConnect A/S",
"document_id": "3016392",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "20480/2048 Kbps ADSL forbindelse",
"provider_reference": "DSL-EB680288",
"circuit_id": "DSL-EB680288",
"line_total": 420.0,
"unit_price": 140.0,
"quantity": 3,
"end_customer_name": "Malerfirmaet Gert Jensen ApS",
"service_address": "Metalbuen 26, 2750 Ballerup",
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(
supplier_module,
"_load_active_customers_for_matching",
lambda: [{"id": 322, "name": "Malerfirmaet Gert Jensen ApS", "address": "Metalbuen 26", "postal_code": "2750", "city": "Ballerup"}],
)
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_connections" in query:
created_connections.append(params)
return 700
return 1
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: 1)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 1
assert created_connections
assert created_connections[0][9] == 20
assert created_connections[0][10] == 2
assert created_connections[0][11] == 20
def test_sync_globalconnect_marks_uncertain_connection_pending(monkeypatch):
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "1 Gbps fiberforbindelse",
"provider_reference": "NKA020902",
"circuit_id": "NKA020902",
"line_total": 5417.4,
"unit_price": 1805.8,
"quantity": 3,
"end_customer_name": None,
"service_address": None,
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
monkeypatch.setattr(supplier_module, "execute_query_single", lambda query, params=None: None)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 0
assert result["skipped_connection_lines"] == 1
assert result["verification"]["requires_manual_review"] is True
assert result["skipped_items"][0]["reason"] == "Mangler serviceadresse"
def test_upsert_globalconnect_connection_requires_service_address(monkeypatch):
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
connection_id = supplier_module._upsert_globalconnect_connection(
reference="NKA020902",
lines=[{
"description": "1 Gbps fiberforbindelse",
"provider_reference": "NKA020902",
"circuit_id": "NKA020902",
"line_total": 5417.4,
"unit_price": 1805.8,
"quantity": 3,
"end_customer_name": None,
"service_address": None,
}],
invoice_date="2026-01-01",
invoice_number="3018657",
customers=[],
)
assert connection_id is None
def test_sync_globalconnect_creates_pending_reference_shell_without_customer(monkeypatch):
created_connections = []
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "IPv4 IP-adresser",
"provider_reference": "NKA008225",
"circuit_id": "NKA008225",
"ip_address": "152.115.57.96/27",
"line_total": 768.0,
"unit_price": 256.0,
"quantity": 3,
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(supplier_module, "_resolve_internal_bmc_customer", lambda: {"id": 1662, "name": "BMC Networks"})
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_connections" in query:
created_connections.append(params)
return 800
return 1
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: 1)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 1
assert result["ip_ranges_synced"] == 1
assert result["skipped_orphan_ip_ranges"] == 0
assert created_connections
assert created_connections[0][2] is None
def test_upsert_globalconnect_connection_does_not_infer_shared_from_address_or_mpls(monkeypatch):
created_connections = []
line = {
"description": "1 Gbps fiberforbindelse MPLS VPN",
"provider_reference": "NKA020900",
"circuit_id": "NKA020900",
"line_total": 4950.0,
"unit_price": 1650.0,
"quantity": 3,
"service_address": "Rydagervej 27, 2620 Albertslund",
"end_customer_name": "",
}
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
monkeypatch.setattr(supplier_module, "_resolve_internal_bmc_customer", lambda: {"id": 1662, "name": "BMC Networks"})
monkeypatch.setattr(supplier_module, "_ensure_connection_pricing_entry", lambda **kwargs: None)
monkeypatch.setattr(supplier_module, "_append_connection_history", lambda *args, **kwargs: None)
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_connections" in query:
created_connections.append(params)
return 901
return 1
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
connection_id = supplier_module._upsert_globalconnect_connection(
reference="NKA020900",
lines=[line],
invoice_date="2026-01-01",
invoice_number="3018657",
customers=[],
)
assert connection_id == 901
assert created_connections
assert created_connections[0][2] is None
assert created_connections[0][-3] == "dedicated"
assert created_connections[0][-2] == "other"
def test_shared_classification_requires_explicit_invoice_wording():
assert supplier_module._should_assign_internal_bmc_owner(
[{"description": "Delt transit backbone"}], None, "Testvej 1"
) is True
assert supplier_module._should_assign_internal_bmc_owner(
[{"description": "MPLS VPN 1 Gbps"}], None, "Testvej 1"
) is False
def test_existing_ip_range_matches_canonical_network_not_raw_text(monkeypatch):
monkeypatch.setattr(
supplier_module,
"execute_query",
lambda query, params=None: [{
"connection_id": 44,
"cidr": "192.0.2.0/29",
"service_address": "Testvej 1, 8000 Aarhus",
"provider_reference": "NKA123456",
"connection_address": "Testvej 1, 8000 Aarhus",
"connection_reference": "NKA123456",
}],
)
result = supplier_module._resolve_existing_ip_range_connection({
"ip_address": "192.0.2.1 / 29",
"provider_reference": "NKA-123456",
"service_address": "Testvej 1, 8000 Aarhus",
})
assert result["connection_id"] == 44
assert result["conflict_reason"] is None
def test_unique_circuit_reference_matches_dash_and_dsl_eb_alias(monkeypatch):
monkeypatch.setattr(
supplier_module,
"execute_query",
lambda query, params=None: [
{"id": 11, "circuit_number": "NKA020900"},
{"id": 12, "circuit_number": "DSL-EB528263"},
],
)
assert supplier_module._find_unique_globalconnect_connection_by_reference("NKA-020900") == 11
assert supplier_module._find_unique_globalconnect_connection_by_reference("EB528263") == 12
def test_reference_match_keys_treat_eb_and_dsl_eb_as_same_circuit():
assert supplier_module._provider_reference_match_keys("EB528263") == {"EB528263", "DSLEB528263"}
assert supplier_module._provider_reference_match_keys("DSL-EB528263") == {"EB528263", "DSLEB528263"}
def test_bare_eb_ip_reference_is_not_allowed_to_create_a_pending_connection():
source = Path('app/billing/backend/supplier_invoices.py').read_text()
assert 'not simulate and not reference.startswith("EB")' in source
assert 'simulate and not reference.startswith("EB")' in source
def test_sync_globalconnect_attaches_ip_range_to_existing_connection(monkeypatch):
created_ranges = []
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "IPv4 IP-adresser",
"provider_reference": "NKA008225",
"circuit_id": "NKA008225",
"ip_address": "152.115.57.96/27",
"line_total": 768.0,
"unit_price": 256.0,
"quantity": 3,
"service_address": "Metalbuen 26, 2750 Ballerup",
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(
supplier_module,
"execute_query",
lambda query, params=None: [{"id": 16, "address": "Metalbuen 26, 2750 Ballerup"}] if "FROM internet_connections_connections" in query else [],
)
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_ranges" in query:
return None
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_insert", lambda query, params=None: 601 if "INSERT INTO internet_connections_ip_ranges" in query else 1)
def fake_execute_update(query, params=None):
return 1
monkeypatch.setattr(supplier_module, "execute_update", fake_execute_update)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 0
assert result["ip_ranges_synced"] == 1
assert result["skipped_orphan_ip_ranges"] == 0
assert result["line_audit"][0]["result"] == "linked_existing_connection"
def test_sync_globalconnect_normalizes_reference_without_dash(monkeypatch):
created_ranges = []
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "IPv4 IP-adresser",
"provider_reference": "NKA008225",
"circuit_id": "NKA008225",
"ip_address": "152.115.57.96/27",
"line_total": 768.0,
"unit_price": 256.0,
"quantity": 3,
"service_address": "Metalbuen 26, 2750 Ballerup",
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(
supplier_module,
"execute_query",
lambda query, params=None: [{"id": 32, "address": "Metalbuen 26, 2750 Ballerup"}] if "FROM internet_connections_connections" in query else [],
)
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_ranges" in query:
return None
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_ip_ranges" in query:
created_ranges.append(params)
return 3
return 1
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: 1)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["ip_ranges_synced"] == 1
assert created_ranges
assert created_ranges[0][0] == 32
def test_sync_globalconnect_merges_duplicate_connections(monkeypatch):
updates = []
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "100 Mbps fiberforbindelse",
"provider_reference": "NKA008225",
"circuit_id": "NKA008225",
"line_total": 768.0,
"unit_price": 256.0,
"quantity": 3,
"service_address": "Metalbuen 26, 2750 Ballerup",
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
def fake_execute_query(query, params=None):
if "FROM internet_connections_connections" in query:
return [{"id": 16, "customer_id": None, "address": None}, {"id": 32, "customer_id": None, "address": None}]
if "FROM internet_connections_ip_ranges" in query:
return []
return []
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_ranges" in query:
return None
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
monkeypatch.setattr(supplier_module, "execute_query", fake_execute_query)
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_insert", lambda query, params=None: 3)
monkeypatch.setattr(supplier_module, "_ensure_internet_change_case", lambda **kwargs: 99)
monkeypatch.setattr(supplier_module, "_ensure_connection_pricing_entry", lambda **kwargs: None)
def fake_execute_update(query, params=None):
updates.append((query, params))
return 1
monkeypatch.setattr(supplier_module, "execute_update", fake_execute_update)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 1
assert any(
"UPDATE internet_connections_ip_ranges" in query and params[0] == 16 and params[1] == 32
for query, params in updates
)
assert any(
"UPDATE internet_connections_connections" in query and params[1] == 32
for query, params in updates
)
def test_sync_globalconnect_skips_reference_when_address_conflicts(monkeypatch):
extraction = {
"extraction_id": 176,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "100 Mbps fiberforbindelse",
"provider_reference": "NKA008225",
"circuit_id": "NKA008225",
"line_total": 768.0,
"unit_price": 256.0,
"quantity": 3,
"service_address": "Metalbuen 26, 2750 Ballerup",
}
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(
supplier_module,
"execute_query",
lambda query, params=None: [{"id": 16, "address": "Andenvej 99, 2100 København Ø"}] if "FROM internet_connections_connections" in query else [],
)
monkeypatch.setattr(supplier_module, "execute_query_single", lambda query, params=None: None)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 0
assert result["verification"]["requires_manual_review"] is True
assert "anden adresse" in result["skipped_items"][0]["reason"].lower()
def test_sync_globalconnect_uses_circuit_address_when_ip_line_address_is_shifted(monkeypatch):
extraction = {
"extraction_id": 180,
"vendor_name": "GlobalConnect A/S",
"document_id": "3018657",
"document_date": "2026-01-01",
"llm_response_json": {"template": "dk.globalconnect"},
}
lines = [
{
"description": "1 Gbps fiberforbindelse MPLS VPN",
"provider_reference": "NKA020900",
"circuit_id": "NKA020900",
"line_total": 4950.0,
"unit_price": 1650.0,
"quantity": 3,
"service_address": "Rydagervej 27, 2620 Albertslund",
},
{
"description": "IPv4 IP-adresser",
"provider_reference": "NKA-020900",
"circuit_id": "NKA-020900",
"ip_address": "87.116.1.200/29",
"line_total": 384.0,
"unit_price": 128.0,
"quantity": 3,
"service_address": "Tobaksvejen 25, 2860 Søborg",
},
]
monkeypatch.setattr(supplier_module, "_load_extraction_lines", lambda _: lines)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [])
monkeypatch.setattr(supplier_module, "_ensure_connection_pricing_entry", lambda **kwargs: None)
monkeypatch.setattr(supplier_module, "_append_connection_history", lambda *args, **kwargs: None)
monkeypatch.setattr(supplier_module, "_ensure_internet_change_case", lambda **kwargs: None)
def fake_execute_query(query, params=None):
if "FROM internet_connections_connections" in query:
if "regexp_replace(UPPER(COALESCE(circuit_number, ''))" in query:
return []
return []
if "FROM internet_connections_ip_ranges" in query:
return []
return []
def fake_execute_query_single(query, params=None):
if "FROM customers" in query:
return None
if "FROM internet_connections_connections" in query and "WHERE id = %s" in query:
return {
"address": "Rydagervej 27, 2620 Albertslund",
"allocation_model": "dedicated",
}
if "FROM internet_connections_ip_ranges" in query:
return None
if "FROM internet_connections_ip_addresses" in query:
return {"total": 0}
return None
created_connections = []
def fake_execute_insert(query, params=None):
if "INSERT INTO internet_connections_connections" in query:
created_connections.append(params)
return 96
if "INSERT INTO internet_connections_ip_ranges" in query:
return 97
return 1
monkeypatch.setattr(supplier_module, "execute_query", fake_execute_query)
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_insert", fake_execute_insert)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: 1)
result = supplier_module._sync_globalconnect_extraction_to_internet(extraction)
assert result["connections_synced"] == 1
assert result["ip_ranges_synced"] == 1
assert result["skipped_orphan_ip_ranges"] == 0
assert created_connections
ip_entries = [entry for entry in result["line_audit"] if entry["classification"] == "ip_range"]
assert ip_entries[0]["status"] == "synced"
assert ip_entries[0]["matched_by"] == "unique_circuit_reference"
assert ip_entries[0]["service_address_corrected"] is True
assert "Rydagervej 27" in ip_entries[0]["address_warning"]
def test_upsert_globalconnect_connection_logs_changes_and_creates_case(monkeypatch):
history_calls = []
case_calls = []
updates = []
customer = {
"id": 322,
"name": "Malerfirmaet Gert Jensen ApS",
"address": "Metalbuen 26",
"postal_code": "2750",
"city": "Ballerup",
}
line = {
"description": "200 Mbps fiberforbindelse",
"provider_reference": "NKA008214",
"circuit_id": "NKA008214",
"line_total": 360.0,
"unit_price": 120.0,
"quantity": 3,
"end_customer_name": "Malerfirmaet Gert Jensen ApS",
"service_address": "Metalbuen 26, 2750 Ballerup",
}
def fake_execute_query(query, params=None):
if "FROM internet_connections_connections" in query:
return [
{
"id": 16,
"customer_id": 322,
"address": "Metalbuen 26, 2750 Ballerup",
"monthly_cost": Decimal("100.00"),
"technology": "Fiber",
"connection_type": "fiber",
"circuit_number": "NKA008214",
"speed_mbps": 100,
"download_mbps": 100,
"upload_mbps": 100,
"status": "active",
"allocation_model": "dedicated",
"value_type": "other",
"value_label": None,
}
]
return []
monkeypatch.setattr(supplier_module, "execute_query", fake_execute_query)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: updates.append((query, params)) or 1)
monkeypatch.setattr(supplier_module, "_append_connection_history", lambda *args: history_calls.append(args))
monkeypatch.setattr(supplier_module, "_ensure_internet_change_case", lambda **kwargs: case_calls.append(kwargs) or 91)
monkeypatch.setattr(supplier_module, "_ensure_connection_pricing_entry", lambda **kwargs: None)
connection_id = supplier_module._upsert_globalconnect_connection(
reference="NKA008214",
lines=[line],
invoice_date="2026-01-01",
invoice_number="3018657",
customers=[customer],
)
assert connection_id == 16
assert updates
assert history_calls
assert history_calls[0][1] == "supplier_invoice_sync_changed"
assert history_calls[0][3]["changes"]["monthly_cost"] == {"from": "100.00", "to": "120.00"}
assert history_calls[0][3]["changes"]["speed_mbps"] == {"from": "100", "to": "200"}
assert case_calls
assert case_calls[0]["connection_id"] == 16
assert case_calls[0]["changes"]["download_mbps"] == {"from": "100", "to": "200"}
def test_upsert_globalconnect_ip_range_logs_changes_and_creates_case(monkeypatch):
history_calls = []
case_calls = []
customer = {
"id": 322,
"name": "Malerfirmaet Gert Jensen ApS",
"address": "Metalbuen 26",
"postal_code": "2750",
"city": "Ballerup",
}
line = {
"description": "IPv4 IP-adresser",
"provider_reference": "NKA008214",
"circuit_id": "NKA008214",
"contract_number": "GC-NEW",
"ip_address": "152.115.84.232/29",
"line_total": 240.0,
"unit_price": 80.0,
"quantity": 3,
"end_customer_name": "Malerfirmaet Gert Jensen ApS",
"service_address": "Metalbuen 26, 2750 Ballerup",
}
def fake_execute_query_single(query, params=None):
if "FROM internet_connections_ip_ranges" in query:
return {
"id": 88,
"provider_reference": "NKA008214",
"contract_number": "GC-OLD",
"customer_id": None,
"service_address": "Gammel adresse 1, 2000 Frederiksberg",
"monthly_cost": Decimal("64.00"),
}
if "FROM internet_connections_ip_addresses" in query:
return {"total": 6}
return None
monkeypatch.setattr(supplier_module, "execute_query", lambda query, params=None: [])
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_update", lambda query, params=None: 1)
monkeypatch.setattr(supplier_module, "_append_connection_history", lambda *args: history_calls.append(args))
monkeypatch.setattr(supplier_module, "_ensure_internet_change_case", lambda **kwargs: case_calls.append(kwargs) or 92)
monkeypatch.setattr(supplier_module, "_ensure_ip_addresses_for_range", lambda range_id, cidr: 6)
monkeypatch.setattr(supplier_module, "_load_active_customers_for_matching", lambda: [customer])
range_id = supplier_module._upsert_globalconnect_ip_range(16, line, "3018657")
assert range_id == 88
assert history_calls
assert history_calls[0][1] == "supplier_invoice_ip_range_changed"
assert history_calls[0][3]["changes"]["contract_number"] == {"from": "GC-OLD", "to": "GC-NEW"}
assert history_calls[0][3]["changes"]["monthly_cost"] == {"from": "64.00", "to": "80.00"}
assert case_calls
assert case_calls[0]["reference"] == "NKA008214"
assert case_calls[0]["changes"]["service_address"]["to"] == "Metalbuen 26, 2750 Ballerup"
def test_supplier_sync_skips_ip_addresses_that_already_exist(monkeypatch):
inserted = []
def fake_execute_query_single(query, params=None):
if "COUNT(*) AS total" in query and "internet_connections_ip_addresses" in query:
return {"total": 0}
if "FROM internet_connections_ip_addresses" in query and "WHERE ip_address = %s" in query:
if params[0] == "152.115.84.233":
return {"id": 91}
return None
return None
def fake_execute_update(query, params=None):
if "INSERT INTO internet_connections_ip_addresses" in query:
inserted.append(params[1])
return 1
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_update", fake_execute_update)
created = supplier_module._ensure_ip_addresses_for_range(601, "152.115.84.232/30")
assert created == 1
assert inserted == ["152.115.84.234"]
def test_append_amount_validation_case_note_creates_system_comment(monkeypatch):
comments = []
def fake_execute_query_single(query, params=None):
if "FROM sag_kommentarer" in query:
return None
return None
def fake_execute_update(query, params=None):
if "INSERT INTO sag_kommentarer" in query:
comments.append(params)
return 1
monkeypatch.setattr(supplier_module, "execute_query_single", fake_execute_query_single)
monkeypatch.setattr(supplier_module, "execute_update", fake_execute_update)
supplier_module._append_amount_validation_case_note(
sag_id=91,
invoice_id=17,
invoice_number="3018657",
validation_details={
"line_sum": 600.0,
"subtotal": 800.0,
"difference": 200.0,
"vat_amount": 200.0,
"vat_expected": 200.0,
"vat_difference": 0.0,
},
validation_warning="Varelinjer sum (600.00) passer ikke med subtotal (800.00)",
vat_warning=None,
file_id=176,
)
assert comments
assert comments[0][0] == 91
assert "Subtotal-advarsel" in comments[0][2]
assert "Afvigelse: 200.0" in comments[0][2]