Skip to content

Commit

Permalink
Merge pull request #200 from getyoti/2.12.1-Release
Browse files Browse the repository at this point in the history
2.12.1 release
  • Loading branch information
echarrod authored Jun 9, 2020
2 parents d4ed035 + 5be1632 commit 03ba5ee
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 15 deletions.
6 changes: 3 additions & 3 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
asn1==2.2.0
cryptography>=2.8.0
cffi>=1.13.0
cffi>=1.14.0
future==0.18.2
itsdangerous==0.24
pbr==1.10.0
protobuf==3.11.3
pyopenssl==18.0.0
PyYAML==5.2 # PyYAML 5.3 does not support Python 3.4
pytz==2018.9
pytz==2020.1
requests>=2.20.0
urllib3>=1.24.2
urllib3>=1.24.3
deprecated==1.2.6
wheel==0.24.0
iso8601==0.1.12
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
asn1==2.2.0 # via -r requirements.in
certifi==2018.11.29 # via requests
cffi==1.13.0 # via -r requirements.in, cryptography
cffi==1.14.0 # via -r requirements.in, cryptography
chardet==3.0.4 # via requests
cryptography==2.8 # via -r requirements.in, pyopenssl
deprecated==1.2.6 # via -r requirements.in
Expand All @@ -18,11 +18,11 @@ pbr==1.10.0 # via -r requirements.in
protobuf==3.11.3 # via -r requirements.in
pycparser==2.18 # via cffi
pyopenssl==18.0.0 # via -r requirements.in
pytz==2018.9 # via -r requirements.in
pytz==2020.1 # via -r requirements.in
pyyaml==5.2 # via -r requirements.in
requests==2.21.0 # via -r requirements.in
six==1.10.0 # via cryptography, protobuf, pyopenssl
urllib3==1.24.2 # via -r requirements.in, requests
urllib3==1.24.3 # via -r requirements.in, requests
wheel==0.24.0 # via -r requirements.in
wrapt==1.11.2 # via deprecated

Expand Down
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ sonar.host.url = https://sonarcloud.io
sonar.organization = getyoti
sonar.projectKey = getyoti:python
sonar.projectName = Python SDK
sonar.projectVersion = 2.12.0
sonar.projectVersion = 2.12.1
sonar.exclusions = yoti_python_sdk/tests/**,examples/**,yoti_python_sdk/protobuf/**/*

sonar.python.pylint.reportPath = coverage.out
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import copy

import pytz


class ThirdPartyAttributeExtension(object):
THIRDPARTY_ATTRIBUTE = "THIRD_PARTY_ATTRIBUTE"

def __init__(self):
self.__extension = {}
self.__extension["type"] = self.THIRDPARTY_ATTRIBUTE
self.__extension["content"] = {"expiry_date": None, "definitions": []}
self.__extension = {
"type": self.THIRDPARTY_ATTRIBUTE,
"content": {"expiry_date": None, "definitions": []},
}

def with_expiry_date(self, expiry_date):
self.__extension["content"]["expiry_date"] = expiry_date.isoformat()
"""
:param expiry_date: Expiry date for the attribute. If no timezone info is provided, UTC will be used.
:type expiry_date: datetime
"""
if expiry_date.tzinfo is None:
expiry_date = expiry_date.replace(tzinfo=pytz.UTC)

utc_time = expiry_date.astimezone(pytz.utc)
rfc_3339_milliseconds = utc_time.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
self.__extension["content"]["expiry_date"] = rfc_3339_milliseconds + "Z"
return self

def with_definitions(self, *names):
"""
:param names: attribute definitions
:type names: str or list[str]
"""
self.__extension["content"]["definitions"].extend([{"name": s} for s in names])
return self

def build(self):
"""
Builds the object
:return: the third party attribute
:rtype: ThirdPartyAttributeExtension
"""
return copy.deepcopy(self.__extension)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
from __future__ import unicode_literals

from datetime import datetime

import pytest
import pytz

from yoti_python_sdk.dynamic_sharing_service.extension.third_party_attribute_extension import (
ThirdPartyAttributeExtension,
)
Expand All @@ -19,7 +23,7 @@ def test_should_create_extension():
)

assert extension["type"] == ThirdPartyAttributeExtension.THIRDPARTY_ATTRIBUTE
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458000"
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458Z"
assert extension["content"]["definitions"][0]["name"] == DEFINITION


Expand All @@ -38,7 +42,7 @@ def test_with_definition_should_add_to_list():
)

assert extension["type"] == ThirdPartyAttributeExtension.THIRDPARTY_ATTRIBUTE
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458000"
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458Z"

assert extension["content"]["definitions"][0]["name"] == DEFINITION1
assert extension["content"]["definitions"][1]["name"] == DEFINITION2
Expand All @@ -58,7 +62,82 @@ def test_with_definition_should_add_multiple():
)

assert extension["type"] == ThirdPartyAttributeExtension.THIRDPARTY_ATTRIBUTE
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458000"
assert extension["content"]["expiry_date"] == "2019-10-30T12:10:09.458Z"

assert extension["content"]["definitions"][0]["name"] == DEFINITION1
assert extension["content"]["definitions"][1]["name"] == DEFINITION2


@pytest.mark.parametrize(
"expiry_date, expected_value",
[
(
datetime(2051, 1, 13, 19, 50, 53, 1, tzinfo=pytz.utc),
"2051-01-13T19:50:53.000Z",
),
(
datetime(2026, 2, 2, 22, 4, 5, 123, tzinfo=pytz.utc),
"2026-02-02T22:04:05.000Z",
),
(
datetime(2051, 4, 13, 19, 50, 53, 999, tzinfo=pytz.utc),
"2051-04-13T19:50:53.000Z",
),
(
datetime(2026, 1, 31, 22, 4, 5, 1232, tzinfo=pytz.utc),
"2026-01-31T22:04:05.001Z",
),
(
datetime(2026, 1, 31, 22, 4, 5, 17777, tzinfo=pytz.utc),
"2026-01-31T22:04:05.017Z",
),
(
datetime(2019, 10, 30, 12, 10, 9, int(458e3), tzinfo=pytz.utc),
"2019-10-30T12:10:09.458Z",
),
(
datetime(2026, 1, 2, 22, 4, 5, 123456, tzinfo=pytz.utc),
"2026-01-02T22:04:05.123Z",
),
],
)
def test_should_format_utc_expiry_dates_correctly(expiry_date, expected_value):
DEFINITION = "some_value"

extension = (
ThirdPartyAttributeExtension()
.with_expiry_date(expiry_date)
.with_definitions(DEFINITION)
.build()
)

assert extension["content"]["expiry_date"] == expected_value


@pytest.mark.parametrize(
"expiry_date, tz_name",
[
(datetime(2030, 6, 6, 8, 0, 0, 0), "US/Eastern",),
(datetime(2030, 6, 6, 15, 0, 0, 0), "Europe/Moscow",),
(datetime(2030, 6, 6, 7, 0, 0, 0), "America/Jamaica",),
(datetime(2030, 6, 6, 23, 0, 0, 0), "Etc/GMT-11"),
(datetime(2030, 6, 6, 7, 0, 0, 0), "Etc/GMT+5"),
# In order to conform with the POSIX style, those zones beginning
# with "Etc/GMT" have their sign reversed from what most people expect. In this style, zones west of GMT have
# a positive sign and those east have a negative sign.
],
)
def test_should_format_localized_expiry_dates(expiry_date, tz_name):
DEFINITION = "some_value"

tz = pytz.timezone(tz_name)
localized_expiry_date = tz.localize(expiry_date)

extension = (
ThirdPartyAttributeExtension()
.with_expiry_date(localized_expiry_date)
.with_definitions(DEFINITION)
.build()
)

assert extension["content"]["expiry_date"] == "2030-06-06T12:00:00.000Z"
2 changes: 1 addition & 1 deletion yoti_python_sdk/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# -*- coding: utf-8 -*-
__version__ = "2.12.0"
__version__ = "2.12.1"

0 comments on commit 03ba5ee

Please sign in to comment.