Skip to content

Commit

Permalink
Merge pull request #324 from lucc/fix-323
Browse files Browse the repository at this point in the history
Fix yaml conversion of post addresses
  • Loading branch information
lucc committed Sep 13, 2023
2 parents 8035e67 + 5718d96 commit 8b93dea
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 16 deletions.
8 changes: 4 additions & 4 deletions khard/carddav_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

from . import address_book # pylint: disable=unused-import # for type checking
from . import helpers
from .helpers.typing import (convert_to_vcard, Date, ObjectType, StrList,
list_to_string, string_to_date, string_to_list)
from .helpers.typing import (Date, ObjectType, PostAddress, StrList,
convert_to_vcard, list_to_string, string_to_date, string_to_list)
from .query import AnyQuery, Query


Expand Down Expand Up @@ -770,11 +770,11 @@ def add_email(self, type: str, address: str) -> None:
label_obj.value = custom_types[0]

@property
def post_addresses(self) -> Dict[str, List[Dict[str, Union[List, str]]]]:
def post_addresses(self) -> Dict[str, List[PostAddress]]:
"""
:returns: dict of type and post address list
"""
post_adr_dict: Dict[str, List[Dict[str, Union[List, str]]]] = {}
post_adr_dict: Dict[str, List[PostAddress]] = {}
for child in self.vcard.getChildren():
if child.name == "ADR":
type = list_to_string(self._get_types_for_vcard_object(
Expand Down
28 changes: 17 additions & 11 deletions khard/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
from typing import Any, Dict, List, Optional, Sequence, Union

from ruamel.yaml.scalarstring import LiteralScalarString
from .typing import list_to_string
from .typing import list_to_string, PostAddress


YamlPostAddresses = Dict[str, Union[List[Dict[str, Any]], Dict[str, Any]]]


def pretty_print(table: List[List[str]], justify: str = "L") -> str:
Expand Down Expand Up @@ -115,10 +118,10 @@ def yaml_dicts(
return data_dict


def yaml_addresses(addresses: Optional[Dict[str, Any]],
def yaml_addresses(addresses: Optional[Dict[str, List[PostAddress]]],
address_properties: List[str],
defaults: Optional[List[str]] = None
) -> Optional[Dict[str, Any]]:
) -> Optional[YamlPostAddresses]:
"""
build a dict from an address, using a list of properties, an address has.
Expand All @@ -134,14 +137,17 @@ def yaml_addresses(addresses: Optional[Dict[str, Any]],
address_fields = {key: None for key in address_properties}
return {address_type: address_fields for address_type in defaults}

address_dict = {}
for address_type, address in addresses.items():
if isinstance(address, list):
address = address[0]
address_dict[address_type] = {
key: yaml_clean(address.get(f"{key[0].lower()}{key[1:]}"))
for key in address_properties
}
address_dict: YamlPostAddresses = {}
for address_type, addresses_ in addresses.items():
entry = [
{key: yaml_clean(address.get(f"{key[0].lower()}{key[1:]}"))
for key in address_properties}
for address in addresses_
]
if len(entry) == 1:
address_dict[address_type] = entry[0]
else:
address_dict[address_type] = entry
return address_dict


Expand Down
3 changes: 2 additions & 1 deletion khard/helpers/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from datetime import datetime
from enum import Enum
from typing import List, Union
from typing import Dict, List, Union


class ObjectType(Enum):
Expand All @@ -14,6 +14,7 @@ class ObjectType(Enum):
# some type aliases
Date = Union[str, datetime]
StrList = Union[str, List[str]]
PostAddress = Dict[str, str]


def convert_to_vcard(name: str, value: StrList, constraint: ObjectType
Expand Down
30 changes: 30 additions & 0 deletions test/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,36 @@ def test_empty_strings_produce_empty_values(self):
result = helpers.convert_to_yaml("Note", "", 0, 5, True)
self.assertListEqual(result, ["Note : "])

def test_preparing_multiple_addresses_with_same_label_for_yaml_conversion_returns_all_entries(self):
input = {'home': [{'street': 'street 1',
'city': 'city1',
'code': 'zip1',
'country': ''},
{'street': 'street 2',
'city': 'city2',
'code': 'zip2',
'country': ''}]}
expected = [{'Street': 'street 1',
'City': 'city1',
'Code': 'zip1',
'Country': None},
{'Street': 'street 2',
'City': 'city2',
'Code': 'zip2',
'Country': None}]
actual = helpers.yaml_addresses(input, ["Street", "Code", "City",
"Country"])
self.assertEqual(expected, actual["home"])

def test_preparing_single_addresse_for_yaml_conversion_returns_dict_not_list(self):
input = {'home': [{'street': 'street', 'city': 'city', 'code': 'zip',
'country': ''}]}
expected = {'Street': 'street', 'City': 'city', 'Code': 'zip',
'Country': None}
actual = helpers.yaml_addresses(input, ["Street", "Code", "City",
"Country"])
self.assertEqual(expected, actual["home"])


if __name__ == "__main__":
unittest.main()
27 changes: 27 additions & 0 deletions test/test_yaml_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ def test_yaml_quoted_special_characters(self):
yaml_dump = yaml_editable.to_yaml()
self.assertIn("'@khard'", yaml_dump)

def test_dumping_multiple_home_addresses_to_yaml(self):
yaml_editable = TestYAMLEditable()
yaml_editable._add_post_address("home", "", "", "street 1", "zip1",
"city1", "", "")
yaml_editable._add_post_address("home", "", "", "street 2", "zip2",
"city2", "", "")
yaml_dump = yaml_editable.to_yaml()
self.assertIn("zip1", yaml_dump)
self.assertIn("zip2", yaml_dump)

def test_dumping_multiple_home_phone_number_to_yaml(self):
yaml_editable = TestYAMLEditable()
yaml_editable._add_phone_number("home", "1234567890")
yaml_editable._add_phone_number("home", "0987654321")
yaml_dump = yaml_editable.to_yaml()
self.assertIn("1234567890", yaml_dump)
self.assertIn("0987654321", yaml_dump)

def test_dumping_multiple_home_email_addresses_to_yaml(self):
yaml_editable = TestYAMLEditable()
yaml_editable.add_email("home", "home1@example.org")
yaml_editable.add_email("home", "home2@example.org")
yaml_dump = yaml_editable.to_yaml()
self.assertIn("home1", yaml_dump)
self.assertIn("home2", yaml_dump)



class ExceptionHandling(unittest.TestCase):

Expand Down

0 comments on commit 8b93dea

Please sign in to comment.