sysnet-pyutils 1.7.2__tar.gz → 1.7.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/PKG-INFO +1 -1
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/pyproject.toml +1 -1
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/__init__.py +1 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/models/general.py +38 -2
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/PKG-INFO +1 -1
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/SOURCES.txt +1 -0
- sysnet_pyutils-1.7.3/tests/test_models_contact.py +333 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/LICENSE +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/README.md +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/setup.cfg +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/barcode.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/constants.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/cron_utils/__init__.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/cron_utils/validation.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/data_utils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/domino.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/geo.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/globalmodel/__init__.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/globalmodel/global_model.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/globalmodel/models.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/globalmodel/timeutils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/ident.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/log.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/models/__init__.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/ses.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/syslog/__init__.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/syslog/factory.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/tools.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils/utils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/dependency_links.txt +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/not-zip-safe +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/requires.txt +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/sysnet_pyutils.egg-info/top_level.txt +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_cron_utils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_cron_validation_edge.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_data_utils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_data_utils_edge.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_data_utils_missing_branches.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_domino.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_domino_edge.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_geo.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_global_model_recursive.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_global_model_timezone.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_ident_barcode.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_log_importerror_branch.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_log_mongo.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_models_general.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_models_general_edge.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_package_init_version.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_recursive_update.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_ses.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_ses_importerror_branch.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_syslog_factory.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_tools.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_utils.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_utils_edge.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_utils_log_base64.py +0 -0
- {sysnet_pyutils-1.7.2 → sysnet_pyutils-1.7.3}/tests/test_utils_missing_branches.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sysnet-pyutils
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.3
|
|
4
4
|
Summary: SYSNET Python Utilities - kompletní sada nástrojů pro Python aplikace
|
|
5
5
|
Author-email: Data Developer <info@sysnet.cz>
|
|
6
6
|
Maintainer-email: SYSNET Development Team <info@sysnet.cz>
|
|
@@ -3,9 +3,9 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from enum import Enum
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any, Optional, List
|
|
7
7
|
|
|
8
|
-
from pydantic import BaseModel, EmailStr, Field
|
|
8
|
+
from pydantic import BaseModel, ConfigDict, EmailStr, Field
|
|
9
9
|
from typing_extensions import Self
|
|
10
10
|
|
|
11
11
|
from sysnet_pyutils.utils import is_valid_pid, is_valid_unid, is_valid_uuid, local_now
|
|
@@ -425,3 +425,39 @@ class MailAddressType(BaseModel):
|
|
|
425
425
|
|
|
426
426
|
name: str | None = Field(default=None, description="Název adresa elektronické pošty (práce, domů)")
|
|
427
427
|
email: str | None = Field(default=None, description="Adresa elektronické pošty")
|
|
428
|
+
|
|
429
|
+
class ContactType(BaseModel):
|
|
430
|
+
"""
|
|
431
|
+
Kontaktní údaje osoby — jméno, telefony, e-maily a další kontaktní informace.
|
|
432
|
+
|
|
433
|
+
Pole ``phone_default`` / ``phoneDefault`` (alias) určuje index primárního
|
|
434
|
+
telefonního čísla v seznamu ``phone``. Alias je zachován pro kompatibilitu
|
|
435
|
+
s JSON API (camelCase). Model je nastaven s ``populate_by_name=True``, takže
|
|
436
|
+
lze použít jak Python název (``phone_default``), tak alias (``phoneDefault``).
|
|
437
|
+
|
|
438
|
+
Příklad::
|
|
439
|
+
|
|
440
|
+
c = ContactType(
|
|
441
|
+
first_name="Jan",
|
|
442
|
+
last_name="Novák",
|
|
443
|
+
phone=[PhoneNumberType(prefix="+420", number="602000001")],
|
|
444
|
+
email=[MailAddressType(email="jan@example.com")],
|
|
445
|
+
)
|
|
446
|
+
""" # noqa: E501
|
|
447
|
+
|
|
448
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
449
|
+
identifier: Optional[str] = Field(default=None, description="identifikátor uuid")
|
|
450
|
+
first_name: Optional[str] = Field(default=None, description="Křestní jméno")
|
|
451
|
+
last_name: Optional[str] = Field(default=None, description="Příjmení")
|
|
452
|
+
degree_before: Optional[List[Optional[str]]] = Field(default=None, description="Tituly před jménem")
|
|
453
|
+
degree_after: Optional[List[Optional[str]]] = Field(default=None, description="Tituly za jménem")
|
|
454
|
+
full_name: Optional[str] = Field(default=None, description="Celé jméno pro zobrazení a tisk")
|
|
455
|
+
birthdate: Optional[datetime] = Field(default=None, description="Datum narození")
|
|
456
|
+
phone: Optional[List[Optional[PhoneNumberType]]] = Field(default=None, description="Telefonní číslo")
|
|
457
|
+
phone_default: Optional[int] = Field(default=0, description="Index hlavního telefonního čísla", alias="phoneDefault")
|
|
458
|
+
email: Optional[List[Optional[MailAddressType]]] = Field(default=None, description="Elektronická pošta")
|
|
459
|
+
email_default: Optional[int] = Field(default=0, description="Index hlavní adresy elektronické pošty")
|
|
460
|
+
web: Optional[str] = Field(default=None, description="Webová stránka subjektu")
|
|
461
|
+
isds: Optional[str] = Field(default=None, description="Identifikátor datové schránky")
|
|
462
|
+
reference: Optional[str] = Field(default=None, description="identifikátor uuid")
|
|
463
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sysnet-pyutils
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.3
|
|
4
4
|
Summary: SYSNET Python Utilities - kompletní sada nástrojů pro Python aplikace
|
|
5
5
|
Author-email: Data Developer <info@sysnet.cz>
|
|
6
6
|
Maintainer-email: SYSNET Development Team <info@sysnet.cz>
|
|
@@ -41,6 +41,7 @@ tests/test_global_model_timezone.py
|
|
|
41
41
|
tests/test_ident_barcode.py
|
|
42
42
|
tests/test_log_importerror_branch.py
|
|
43
43
|
tests/test_log_mongo.py
|
|
44
|
+
tests/test_models_contact.py
|
|
44
45
|
tests/test_models_general.py
|
|
45
46
|
tests/test_models_general_edge.py
|
|
46
47
|
tests/test_package_init_version.py
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Testy pro ContactType a přidružené modely (PhoneNumberType, MailAddressType)
|
|
3
|
+
v modulu sysnet_pyutils.models.general
|
|
4
|
+
|
|
5
|
+
Pokrývá:
|
|
6
|
+
- pyutils-bcn.2: základní vytvoření a pole
|
|
7
|
+
- pyutils-bcn.3: integrace PhoneNumberType a MailAddressType
|
|
8
|
+
- pyutils-bcn.4: alias phoneDefault / phone_default
|
|
9
|
+
- pyutils-bcn.5: hraniční případy
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
from pydantic import ValidationError
|
|
16
|
+
|
|
17
|
+
from sysnet_pyutils.models.general import (
|
|
18
|
+
ContactType,
|
|
19
|
+
MailAddressType,
|
|
20
|
+
PhoneNumberType,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ---------------------------------------------------------------------------
|
|
25
|
+
# Pomocné továrny
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
def make_phone(name: str = "mobil", prefix: str = "+420", number: str = "602000001") -> PhoneNumberType:
|
|
29
|
+
return PhoneNumberType(name=name, prefix=prefix, number=number)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def make_email(name: str = "práce", email: str = "test@example.com") -> MailAddressType:
|
|
33
|
+
return MailAddressType(name=name, email=email)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
# PhoneNumberType
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
class TestPhoneNumberType:
|
|
41
|
+
"""Testy pro PhoneNumberType"""
|
|
42
|
+
|
|
43
|
+
def test_create_with_all_fields(self):
|
|
44
|
+
phone = PhoneNumberType(name="mobil", prefix="+420", number="602000001")
|
|
45
|
+
assert phone.name == "mobil"
|
|
46
|
+
assert phone.prefix == "+420"
|
|
47
|
+
assert phone.number == "602000001"
|
|
48
|
+
|
|
49
|
+
def test_create_empty(self):
|
|
50
|
+
phone = PhoneNumberType()
|
|
51
|
+
assert phone.name is None
|
|
52
|
+
assert phone.prefix is None
|
|
53
|
+
assert phone.number is None
|
|
54
|
+
|
|
55
|
+
def test_create_partial(self):
|
|
56
|
+
phone = PhoneNumberType(number="123456789")
|
|
57
|
+
assert phone.number == "123456789"
|
|
58
|
+
assert phone.name is None
|
|
59
|
+
assert phone.prefix is None
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
# ---------------------------------------------------------------------------
|
|
63
|
+
# MailAddressType
|
|
64
|
+
# ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
class TestMailAddressType:
|
|
67
|
+
"""Testy pro MailAddressType"""
|
|
68
|
+
|
|
69
|
+
def test_create_with_all_fields(self):
|
|
70
|
+
mail = MailAddressType(name="práce", email="jan@example.com")
|
|
71
|
+
assert mail.name == "práce"
|
|
72
|
+
assert mail.email == "jan@example.com"
|
|
73
|
+
|
|
74
|
+
def test_create_empty(self):
|
|
75
|
+
mail = MailAddressType()
|
|
76
|
+
assert mail.name is None
|
|
77
|
+
assert mail.email is None
|
|
78
|
+
|
|
79
|
+
def test_create_partial(self):
|
|
80
|
+
mail = MailAddressType(email="only@email.cz")
|
|
81
|
+
assert mail.email == "only@email.cz"
|
|
82
|
+
assert mail.name is None
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# ---------------------------------------------------------------------------
|
|
86
|
+
# ContactType — bcn.2: základní vytvoření a pole
|
|
87
|
+
# ---------------------------------------------------------------------------
|
|
88
|
+
|
|
89
|
+
class TestContactTypeBasic:
|
|
90
|
+
"""Testy základního vytvoření ContactType a nastavení polí (bcn.2)"""
|
|
91
|
+
|
|
92
|
+
def test_create_empty(self):
|
|
93
|
+
"""ContactType lze vytvořit bez argumentů — vše None / default"""
|
|
94
|
+
c = ContactType()
|
|
95
|
+
assert c.identifier is None
|
|
96
|
+
assert c.first_name is None
|
|
97
|
+
assert c.last_name is None
|
|
98
|
+
assert c.degree_before is None
|
|
99
|
+
assert c.degree_after is None
|
|
100
|
+
assert c.full_name is None
|
|
101
|
+
assert c.birthdate is None
|
|
102
|
+
assert c.phone is None
|
|
103
|
+
assert c.phone_default == 0
|
|
104
|
+
assert c.email is None
|
|
105
|
+
assert c.email_default == 0
|
|
106
|
+
assert c.web is None
|
|
107
|
+
assert c.isds is None
|
|
108
|
+
assert c.reference is None
|
|
109
|
+
|
|
110
|
+
def test_create_with_scalar_fields(self):
|
|
111
|
+
"""Nastavení všech skalárních polí"""
|
|
112
|
+
uuid = "550e8400-e29b-41d4-a716-446655440000"
|
|
113
|
+
c = ContactType(
|
|
114
|
+
identifier=uuid,
|
|
115
|
+
first_name="Jan",
|
|
116
|
+
last_name="Novák",
|
|
117
|
+
full_name="Ing. Jan Novák",
|
|
118
|
+
web="https://novak.cz",
|
|
119
|
+
isds="abc1234",
|
|
120
|
+
reference=uuid,
|
|
121
|
+
)
|
|
122
|
+
assert c.identifier == uuid
|
|
123
|
+
assert c.first_name == "Jan"
|
|
124
|
+
assert c.last_name == "Novák"
|
|
125
|
+
assert c.full_name == "Ing. Jan Novák"
|
|
126
|
+
assert c.web == "https://novak.cz"
|
|
127
|
+
assert c.isds == "abc1234"
|
|
128
|
+
assert c.reference == uuid
|
|
129
|
+
|
|
130
|
+
def test_create_with_birthdate(self):
|
|
131
|
+
"""Pole birthdate přijímá datetime objekt"""
|
|
132
|
+
bday = datetime(1985, 6, 15)
|
|
133
|
+
c = ContactType(birthdate=bday)
|
|
134
|
+
assert c.birthdate == bday
|
|
135
|
+
assert c.birthdate.year == 1985
|
|
136
|
+
|
|
137
|
+
def test_create_with_degree_lists(self):
|
|
138
|
+
"""Tituly před/za jménem jsou listy stringů"""
|
|
139
|
+
c = ContactType(
|
|
140
|
+
degree_before=["Ing.", "Bc."],
|
|
141
|
+
degree_after=["PhD.", "MBA"],
|
|
142
|
+
)
|
|
143
|
+
assert c.degree_before == ["Ing.", "Bc."]
|
|
144
|
+
assert c.degree_after == ["PhD.", "MBA"]
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# ---------------------------------------------------------------------------
|
|
148
|
+
# ContactType — bcn.3: integrace PhoneNumberType a MailAddressType
|
|
149
|
+
# ---------------------------------------------------------------------------
|
|
150
|
+
|
|
151
|
+
class TestContactTypePhoneEmail:
|
|
152
|
+
"""Testy integrace PhoneNumberType a MailAddressType v ContactType (bcn.3)"""
|
|
153
|
+
|
|
154
|
+
def test_single_phone(self):
|
|
155
|
+
"""ContactType s jedním telefonním číslem"""
|
|
156
|
+
c = ContactType(phone=[make_phone()])
|
|
157
|
+
assert len(c.phone) == 1
|
|
158
|
+
assert c.phone[0].number == "602000001"
|
|
159
|
+
|
|
160
|
+
def test_multiple_phones(self):
|
|
161
|
+
"""ContactType s více telefonními čísly"""
|
|
162
|
+
phones = [
|
|
163
|
+
make_phone(name="mobil", number="602000001"),
|
|
164
|
+
make_phone(name="práce", number="257000002"),
|
|
165
|
+
]
|
|
166
|
+
c = ContactType(phone=phones)
|
|
167
|
+
assert len(c.phone) == 2
|
|
168
|
+
assert c.phone[0].name == "mobil"
|
|
169
|
+
assert c.phone[1].name == "práce"
|
|
170
|
+
|
|
171
|
+
def test_single_email(self):
|
|
172
|
+
"""ContactType s jednou e-mailovou adresou"""
|
|
173
|
+
c = ContactType(email=[make_email()])
|
|
174
|
+
assert len(c.email) == 1
|
|
175
|
+
assert c.email[0].email == "test@example.com"
|
|
176
|
+
|
|
177
|
+
def test_multiple_emails(self):
|
|
178
|
+
"""ContactType s více e-mailovými adresami"""
|
|
179
|
+
emails = [
|
|
180
|
+
make_email(name="práce", email="jan@firma.cz"),
|
|
181
|
+
make_email(name="domů", email="jan@home.cz"),
|
|
182
|
+
]
|
|
183
|
+
c = ContactType(email=emails)
|
|
184
|
+
assert len(c.email) == 2
|
|
185
|
+
assert c.email[0].name == "práce"
|
|
186
|
+
assert c.email[1].name == "domů"
|
|
187
|
+
|
|
188
|
+
def test_phone_and_email_combined(self):
|
|
189
|
+
"""ContactType kombinuje phone i email"""
|
|
190
|
+
c = ContactType(
|
|
191
|
+
first_name="Eva",
|
|
192
|
+
last_name="Svobodová",
|
|
193
|
+
phone=[make_phone()],
|
|
194
|
+
email=[make_email()],
|
|
195
|
+
)
|
|
196
|
+
assert c.first_name == "Eva"
|
|
197
|
+
assert len(c.phone) == 1
|
|
198
|
+
assert len(c.email) == 1
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# ---------------------------------------------------------------------------
|
|
202
|
+
# ContactType — bcn.4: alias phoneDefault / phone_default
|
|
203
|
+
# ---------------------------------------------------------------------------
|
|
204
|
+
|
|
205
|
+
class TestContactTypeAlias:
|
|
206
|
+
"""Testy Pydantic aliasu phoneDefault vs phone_default (bcn.4)"""
|
|
207
|
+
|
|
208
|
+
def test_phone_default_python_name(self):
|
|
209
|
+
"""phone_default lze nastavit přes Python název pole"""
|
|
210
|
+
c = ContactType(phone_default=1)
|
|
211
|
+
assert c.phone_default == 1
|
|
212
|
+
|
|
213
|
+
def test_phone_default_via_alias_dict(self):
|
|
214
|
+
"""Parsování z dict s camelCase klíčem phoneDefault"""
|
|
215
|
+
data = {"phoneDefault": 2}
|
|
216
|
+
c = ContactType.model_validate(data)
|
|
217
|
+
assert c.phone_default == 2
|
|
218
|
+
|
|
219
|
+
def test_phone_default_default_value(self):
|
|
220
|
+
"""Výchozí hodnota phone_default je 0"""
|
|
221
|
+
c = ContactType()
|
|
222
|
+
assert c.phone_default == 0
|
|
223
|
+
|
|
224
|
+
def test_email_default_default_value(self):
|
|
225
|
+
"""Výchozí hodnota email_default je 0"""
|
|
226
|
+
c = ContactType()
|
|
227
|
+
assert c.email_default == 0
|
|
228
|
+
|
|
229
|
+
def test_email_default_set(self):
|
|
230
|
+
"""email_default lze nastavit"""
|
|
231
|
+
c = ContactType(email_default=3)
|
|
232
|
+
assert c.email_default == 3
|
|
233
|
+
|
|
234
|
+
def test_model_dump_snake_case(self):
|
|
235
|
+
"""model_dump() vrátí phone_default (snake_case)"""
|
|
236
|
+
c = ContactType(phone_default=1)
|
|
237
|
+
d = c.model_dump()
|
|
238
|
+
assert "phone_default" in d
|
|
239
|
+
assert d["phone_default"] == 1
|
|
240
|
+
|
|
241
|
+
def test_model_dump_by_alias(self):
|
|
242
|
+
"""model_dump(by_alias=True) vrátí phoneDefault (camelCase)"""
|
|
243
|
+
c = ContactType(phone_default=1)
|
|
244
|
+
d = c.model_dump(by_alias=True)
|
|
245
|
+
assert "phoneDefault" in d
|
|
246
|
+
assert d["phoneDefault"] == 1
|
|
247
|
+
|
|
248
|
+
def test_model_dump_by_alias_excludes_snake(self):
|
|
249
|
+
"""model_dump(by_alias=True) neobsahuje phone_default snake variantu"""
|
|
250
|
+
c = ContactType(phone_default=1)
|
|
251
|
+
d = c.model_dump(by_alias=True)
|
|
252
|
+
assert "phone_default" not in d
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
# ---------------------------------------------------------------------------
|
|
256
|
+
# ContactType — bcn.5: hraniční případy
|
|
257
|
+
# ---------------------------------------------------------------------------
|
|
258
|
+
|
|
259
|
+
class TestContactTypeEdgeCases:
|
|
260
|
+
"""Hraniční případy ContactType (bcn.5)"""
|
|
261
|
+
|
|
262
|
+
def test_all_none_fields(self):
|
|
263
|
+
"""ContactType přijme explicitní None u všech Optional polí"""
|
|
264
|
+
c = ContactType(
|
|
265
|
+
identifier=None,
|
|
266
|
+
first_name=None,
|
|
267
|
+
last_name=None,
|
|
268
|
+
degree_before=None,
|
|
269
|
+
degree_after=None,
|
|
270
|
+
full_name=None,
|
|
271
|
+
birthdate=None,
|
|
272
|
+
phone=None,
|
|
273
|
+
email=None,
|
|
274
|
+
web=None,
|
|
275
|
+
isds=None,
|
|
276
|
+
reference=None,
|
|
277
|
+
)
|
|
278
|
+
assert c.phone is None
|
|
279
|
+
assert c.email is None
|
|
280
|
+
|
|
281
|
+
def test_empty_lists_for_phone_and_email(self):
|
|
282
|
+
"""Prázdný seznam pro phone/email je validní"""
|
|
283
|
+
c = ContactType(phone=[], email=[])
|
|
284
|
+
assert c.phone == []
|
|
285
|
+
assert c.email == []
|
|
286
|
+
|
|
287
|
+
def test_degree_before_with_none_items(self):
|
|
288
|
+
"""List titulů může obsahovat None hodnoty"""
|
|
289
|
+
c = ContactType(degree_before=["Ing.", None, "Bc."])
|
|
290
|
+
assert c.degree_before == ["Ing.", None, "Bc."]
|
|
291
|
+
|
|
292
|
+
def test_phone_list_with_none_item(self):
|
|
293
|
+
"""Seznam telefonů může obsahovat None (dle type annotation)"""
|
|
294
|
+
c = ContactType(phone=[make_phone(), None])
|
|
295
|
+
assert c.phone[0].number == "602000001"
|
|
296
|
+
assert c.phone[1] is None
|
|
297
|
+
|
|
298
|
+
def test_serialization_round_trip(self):
|
|
299
|
+
"""model_dump → model_validate zachová data"""
|
|
300
|
+
original = ContactType(
|
|
301
|
+
identifier="abc-123",
|
|
302
|
+
first_name="Petr",
|
|
303
|
+
last_name="Kos",
|
|
304
|
+
phone=[make_phone()],
|
|
305
|
+
email=[make_email()],
|
|
306
|
+
phone_default=0,
|
|
307
|
+
email_default=0,
|
|
308
|
+
)
|
|
309
|
+
data = original.model_dump()
|
|
310
|
+
restored = ContactType.model_validate(data)
|
|
311
|
+
assert restored.identifier == original.identifier
|
|
312
|
+
assert restored.first_name == original.first_name
|
|
313
|
+
assert restored.phone[0].number == original.phone[0].number
|
|
314
|
+
assert restored.email[0].email == original.email[0].email
|
|
315
|
+
|
|
316
|
+
def test_json_round_trip(self):
|
|
317
|
+
"""model_dump_json → model_validate_json zachová data"""
|
|
318
|
+
original = ContactType(
|
|
319
|
+
first_name="Jana",
|
|
320
|
+
isds="xyz9876",
|
|
321
|
+
phone=[make_phone(number="777888999")],
|
|
322
|
+
)
|
|
323
|
+
json_str = original.model_dump_json()
|
|
324
|
+
restored = ContactType.model_validate_json(json_str)
|
|
325
|
+
assert restored.first_name == "Jana"
|
|
326
|
+
assert restored.isds == "xyz9876"
|
|
327
|
+
assert restored.phone[0].number == "777888999"
|
|
328
|
+
|
|
329
|
+
def test_export_from_package_init(self):
|
|
330
|
+
"""ContactType je exportován z hlavního __init__ balíčku"""
|
|
331
|
+
from sysnet_pyutils import ContactType as CT
|
|
332
|
+
assert CT is ContactType
|
|
333
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|