"""Unit tests for crawler_core.qcwy.sign — Job51Sign.

All tests are pure function assertions: no HTTP, no network, no mocks.
"""
import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..'))

import re
import pytest
from crawler_core.qcwy.sign import Job51Sign, SIGN_KEY


class TestJob51SignInit:
    def test_default_sign_key(self):
        signer = Job51Sign()
        assert signer.sign_key == SIGN_KEY
        assert len(SIGN_KEY) == 64  # 64-char hex key

    def test_custom_sign_key(self):
        custom_key = "a" * 64
        signer = Job51Sign(sign_key=custom_key)
        assert signer.sign_key == custom_key


class TestJob51SignBuildSignPath:
    def setup_method(self):
        self.signer = Job51Sign()

    def test_returns_tuple_of_two_strings(self):
        result = self.signer.build_sign_path("open/test")
        assert isinstance(result, tuple)
        assert len(result) == 2
        assert all(isinstance(s, str) for s in result)

    def test_get_path_format(self):
        path, sign = self.signer.build_sign_path("open/test", "GET")
        assert path.startswith("/open/test?api_key=51job&timestamp="), \
            f"Path format wrong: {path}"

    def test_sign_hex_length(self):
        _, sign = self.signer.build_sign_path("open/test")
        assert len(sign) == 64, f"Sign should be 64-char hex, got {len(sign)}: {sign}"

    def test_sign_hex_format(self):
        _, sign = self.signer.build_sign_path("open/test")
        assert re.match(r'^[0-9a-f]{64}$', sign), f"Sign not hex: {sign}"

    def test_get_vs_post_different_sign(self):
        _, get_sign = self.signer.build_sign_path("open/test", "GET")
        _, post_sign = self.signer.build_sign_path("open/test", "POST", body={"k": "v"})
        assert get_sign != post_sign, "GET and POST should produce different signatures"

    def test_get_with_params_includes_params_in_path(self):
        path, _ = self.signer.build_sign_path("open/test", "GET", params={"city": "shanghai"})
        assert "city" in path and "shanghai" in path, \
            f"Params should appear in path: {path}"

    def test_sign_key_in_path(self):
        path, _ = self.signer.build_sign_path("open/jobs")
        assert "api_key=51job" in path, f"api_key=51job missing from path: {path}"


class TestJob51SignGenerateUuid:
    def test_generate_uuid_is_string(self):
        uuid = Job51Sign.generate_uuid()
        assert isinstance(uuid, str)

    def test_generate_uuid_length(self):
        uuid = Job51Sign.generate_uuid()
        # 13-char ms timestamp + 10-char random int = 23 chars
        assert len(uuid) == 23, f"Expected 23 chars, got {len(uuid)}: {uuid}"

    def test_generate_uuid_numeric(self):
        uuid = Job51Sign.generate_uuid()
        assert uuid.isdigit(), f"UUID should be all digits: {uuid}"
