298 lines
11 KiB
Python
298 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Tests for account CRUD operations and pick-web filtering.
|
|
"""
|
|
import json
|
|
import os
|
|
import pytest
|
|
|
|
|
|
class TestAccountAddWeb:
|
|
"""account add-web creates records correctly without requiring phone numbers."""
|
|
|
|
def test_add_web_email_login_id(self, clean_db):
|
|
"""Email login_id should be accepted (no 11-digit phone restriction)."""
|
|
from service.account_service import cmd_account_add_web
|
|
|
|
cmd_account_add_web(
|
|
platform_input="maersk",
|
|
login_id="demo@maersk.com",
|
|
login_id_type="email",
|
|
label="Maersk sim test",
|
|
tenant_id="tenant-demo",
|
|
environment="simulator",
|
|
role="booking",
|
|
provider_code=None,
|
|
url=None,
|
|
extra_json_str=None,
|
|
profile_dir_override=None,
|
|
)
|
|
# Should succeed with JSON output
|
|
from db.accounts_repo import find_accounts
|
|
accs = find_accounts(platform_key="maersk")
|
|
assert len(accs) == 1
|
|
assert accs[0]["login_id"] == "demo@maersk.com"
|
|
assert accs[0]["login_id_type"] == "email"
|
|
assert accs[0]["environment"] == "simulator"
|
|
assert accs[0]["role"] == "booking"
|
|
assert accs[0]["tenant_id"] == "tenant-demo"
|
|
assert accs[0]["status"] == "active"
|
|
assert accs[0]["platform_key"] == "maersk"
|
|
|
|
def test_add_web_no_login_id(self, clean_db):
|
|
"""login_id can be None (e.g. for browser_profile-only accounts)."""
|
|
from service.account_service import cmd_account_add_web
|
|
|
|
cmd_account_add_web(
|
|
platform_input="deepseek",
|
|
login_id=None,
|
|
login_id_type="unknown",
|
|
label="DeepSeek prod",
|
|
tenant_id=None,
|
|
environment="production",
|
|
role="api",
|
|
provider_code=None,
|
|
url=None,
|
|
extra_json_str=None,
|
|
profile_dir_override=None,
|
|
)
|
|
from db.accounts_repo import find_accounts
|
|
accs = find_accounts(platform_key="deepseek")
|
|
assert len(accs) == 1
|
|
assert accs[0]["login_id"] == ""
|
|
|
|
def test_add_web_profile_dir_created(self, clean_db, fake_env):
|
|
"""profile_dir should be auto-created under fake_env data root."""
|
|
from service.account_service import cmd_account_add_web
|
|
|
|
cmd_account_add_web(
|
|
platform_input="maersk",
|
|
login_id="test@example.com",
|
|
login_id_type="email",
|
|
label="Profile dir test",
|
|
tenant_id="tenant-test",
|
|
environment="production",
|
|
role="booking",
|
|
provider_code=None,
|
|
url=None,
|
|
extra_json_str=None,
|
|
profile_dir_override=None,
|
|
)
|
|
from db.accounts_repo import find_accounts
|
|
accs = find_accounts(platform_key="maersk")
|
|
assert len(accs) == 1
|
|
profile_dir = accs[0]["profile_dir"]
|
|
assert profile_dir, "profile_dir should be non-empty"
|
|
assert os.path.isdir(profile_dir), f"profile_dir should be created: {profile_dir}"
|
|
# The path should be under the fake data root
|
|
assert profile_dir.startswith(fake_env["data_root"]), \
|
|
f"profile_dir should be under fake data root: {profile_dir}"
|
|
|
|
def test_add_web_extra_json(self, clean_db):
|
|
"""extra_json field is stored and retrieved correctly."""
|
|
from service.account_service import cmd_account_add_web
|
|
|
|
extra = {"api_version": "v1", "timeout": 30}
|
|
cmd_account_add_web(
|
|
platform_input="cma_cgm",
|
|
login_id="cma@test.com",
|
|
login_id_type="email",
|
|
label="CMA CGM test",
|
|
tenant_id="tenant-cma",
|
|
environment="production",
|
|
role="documentation",
|
|
provider_code=None,
|
|
url=None,
|
|
extra_json_str=json.dumps(extra),
|
|
profile_dir_override=None,
|
|
)
|
|
from db.accounts_repo import find_accounts
|
|
accs = find_accounts(platform_key="cma_cgm")
|
|
assert len(accs) == 1
|
|
raw_ex = accs[0].get("extra_json")
|
|
extra_parsed = raw_ex if isinstance(raw_ex, dict) else json.loads(raw_ex or "{}")
|
|
assert extra_parsed["api_version"] == "v1"
|
|
assert extra_parsed["timeout"] == 30
|
|
|
|
|
|
class TestAccountGetList:
|
|
"""account get/list operations."""
|
|
|
|
def test_get_account_found(self, clean_db):
|
|
"""account get returns JSON with correct account fields."""
|
|
from service.account_service import cmd_account_add_web, cmd_account_get
|
|
import io
|
|
import sys
|
|
|
|
# Add account first
|
|
cmd_account_add_web(
|
|
platform_input="evergreen",
|
|
login_id="ship@evergreen.com",
|
|
login_id_type="email",
|
|
label="Evergreen booking",
|
|
tenant_id="tenant-evg",
|
|
environment="production",
|
|
role="booking",
|
|
provider_code=None,
|
|
url=None,
|
|
extra_json_str=None,
|
|
profile_dir_override=None,
|
|
)
|
|
accs = find_accounts_()
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_get(accs[0]["id"])
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
output = captured.getvalue()
|
|
data = json.loads(output)
|
|
assert data["platform_key"] == "evergreen"
|
|
assert data["login_id"] == "ship@evergreen.com"
|
|
|
|
def test_get_account_not_found(self, clean_db):
|
|
"""account get for unknown id returns ERROR:ACCOUNT_NOT_FOUND."""
|
|
from service.account_service import cmd_account_get
|
|
import io
|
|
import sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_get(9999)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
output = captured.getvalue()
|
|
assert "ERROR:ACCOUNT_NOT_FOUND" in output
|
|
|
|
def test_list_platform_filter(self, clean_db):
|
|
"""account list --platform filters by platform."""
|
|
from service.account_service import cmd_account_add_web, cmd_account_list
|
|
import io
|
|
import sys
|
|
|
|
cmd_account_add_web("maersk", "a@maersk.com", "email", "m", "t1", "prod", "booking", None, None, None, None)
|
|
cmd_account_add_web("maersk", "b@maersk.com", "email", "m2", "t1", "prod", "documentation", None, None, None, None)
|
|
cmd_account_add_web("cma_cgm", "c@cma.com", "email", "c", "t2", "prod", "booking", None, None, None, None)
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_list(platform_input="maersk")
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
output = captured.getvalue()
|
|
accs = json.loads(output)
|
|
assert len(accs) == 2
|
|
assert all(a["platform_key"] == "maersk" for a in accs)
|
|
|
|
|
|
def find_accounts_():
|
|
from db.accounts_repo import find_accounts
|
|
return find_accounts(limit=200)
|
|
|
|
|
|
class TestPickWebFiltering:
|
|
"""pick-web filtering by environment / role / tenant_id."""
|
|
|
|
def _add(self, platform, login, label, tenant, env, role):
|
|
from service.account_service import cmd_account_add_web
|
|
cmd_account_add_web(
|
|
platform, login, "email", label, tenant, env, role,
|
|
None, None, None, None,
|
|
)
|
|
|
|
def test_filter_environment(self, clean_db):
|
|
"""pick-web --environment simulator selects only simulator account."""
|
|
self._add("maersk", "sim@maersk.com", "S", "t1", "simulator", "booking")
|
|
self._add("maersk", "prod@maersk.com", "P", "t1", "production", "booking")
|
|
self._add("maersk", "prod2@maersk.com", "P2", "t1", "production", "documentation")
|
|
|
|
from service.account_service import cmd_account_pick_web
|
|
import io, sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_pick_web("maersk", environment="simulator", tenant_id=None, role=None, do_lease=False)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
result = json.loads(captured.getvalue())
|
|
assert result["login_id"] == "sim@maersk.com"
|
|
assert result["environment"] == "simulator"
|
|
|
|
def test_filter_role(self, clean_db):
|
|
"""pick-web --role booking selects only booking role."""
|
|
self._add("maersk", "a@maersk.com", "A", "t1", "simulator", "booking")
|
|
self._add("maersk", "b@maersk.com", "B", "t1", "simulator", "documentation")
|
|
|
|
from service.account_service import cmd_account_pick_web
|
|
import io, sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_pick_web("maersk", environment=None, tenant_id=None, role="documentation", do_lease=False)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
result = json.loads(captured.getvalue())
|
|
assert result["role"] == "documentation"
|
|
|
|
def test_filter_tenant(self, clean_db):
|
|
"""pick-web --tenant-id filters correctly."""
|
|
self._add("cma_cgm", "a@cma.com", "A", "tenant-a", "production", "booking")
|
|
self._add("cma_cgm", "b@cma.com", "B", "tenant-b", "production", "booking")
|
|
|
|
from service.account_service import cmd_account_pick_web
|
|
import io, sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_pick_web("cma_cgm", environment=None, tenant_id="tenant-b", role=None, do_lease=False)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
result = json.loads(captured.getvalue())
|
|
assert result["tenant_id"] == "tenant-b"
|
|
|
|
def test_no_accounts_returns_error(self, clean_db):
|
|
"""pick-web when no account matches returns ERROR:NO_ACCOUNT."""
|
|
from service.account_service import cmd_account_pick_web
|
|
import io, sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_pick_web("maersk", environment="nonexistent", tenant_id=None, role=None, do_lease=False)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
output = captured.getvalue()
|
|
err = json.loads(output)
|
|
assert err["success"] is False
|
|
assert err["error"]["code"] == "ERROR:NO_ACCOUNT"
|
|
|
|
def test_platform_alias_chinese(self, clean_db):
|
|
"""pick-web resolves Chinese platform alias correctly."""
|
|
self._add("maersk", "test@test.com", "Test", "t", "production", "booking")
|
|
|
|
from service.account_service import cmd_account_pick_web
|
|
import io, sys
|
|
|
|
captured = io.StringIO()
|
|
sys.stdout = captured
|
|
try:
|
|
cmd_account_pick_web("马士基", environment=None, tenant_id=None, role=None, do_lease=False)
|
|
finally:
|
|
sys.stdout = sys.__stdout__
|
|
|
|
result = json.loads(captured.getvalue())
|
|
assert result["platform_key"] == "maersk"
|