Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions yoti_python_sandbox/doc_scan/check/sandbox_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@


class SandboxCheck(YotiSerializable):
def __init__(self, result):
def __init__(self, result, handled_check_limit=None):
"""
:param result: the result
:type result: SandboxCheckResult
:param handled_check_limit: optional limit on how many times this check response is used
:type handled_check_limit: int or None
"""
self.__result = result
self.__handled_check_limit = handled_check_limit

@property
def result(self):
Expand All @@ -20,8 +23,22 @@ def result(self):
"""
return self.__result

@property
def handled_check_limit(self):
"""
The number of times this configured check response is used before the sandbox
advances to the next configured response. When None, the backend treats it as
no limit.

:rtype: int or None
"""
return self.__handled_check_limit

def to_json(self):
return {"result": self.result}
json = {"result": self.result}
if self.__handled_check_limit is not None:
json["handled_check_limit"] = self.__handled_check_limit
return json


class SandboxCheckBuilder(object):
Expand All @@ -30,6 +47,7 @@ class SandboxCheckBuilder(object):
def __init__(self):
self.__recommendation = None
self.__breakdown = []
self.__handled_check_limit = None

def with_recommendation(self, recommendation):
self.__recommendation = recommendation
Expand All @@ -43,6 +61,19 @@ def with_breakdowns(self, breakdowns):
self.__breakdown = breakdowns
return self

def with_handled_check_limit(self, handled_check_limit):
"""
Sets the number of times this configured check response is used before the sandbox
advances to the next configured response.

:param handled_check_limit: the limit
:type handled_check_limit: int
:return: the builder
:rtype: SandboxCheckBuilder
"""
self.__handled_check_limit = handled_check_limit
return self

@property
def recommendation(self):
return self.__recommendation
Expand All @@ -51,6 +82,10 @@ def recommendation(self):
def breakdown(self):
return self.__breakdown

@property
def handled_check_limit(self):
return self.__handled_check_limit

@abstractmethod
def build(self):
raise NotImplementedError
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ class SandboxDocumentAuthenticityCheckBuilder(SandboxDocumentCheckBuilder):
def build(self):
report = SandboxCheckReport(self.recommendation, self.breakdown)
result = SandboxCheckResult(report)
return SandboxDocumentAuthenticityCheck(result, self.document_filter)
return SandboxDocumentAuthenticityCheck(
result, self.document_filter, self.handled_check_limit
)
4 changes: 2 additions & 2 deletions yoti_python_sandbox/doc_scan/check/sandbox_document_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@


class SandboxDocumentCheck(SandboxCheck):
def __init__(self, result, document_filter):
SandboxCheck.__init__(self, result)
def __init__(self, result, document_filter, handled_check_limit=None):
SandboxCheck.__init__(self, result, handled_check_limit)
self.__document_filter = document_filter

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ class SandboxDocumentFaceMatchCheckBuilder(SandboxDocumentCheckBuilder):
def build(self):
report = SandboxCheckReport(self.recommendation, self.breakdown)
result = SandboxCheckResult(report)
return SandboxDocumentFaceMatchCheck(result, self.document_filter)
return SandboxDocumentFaceMatchCheck(
result, self.document_filter, self.handled_check_limit
)
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ def with_document_fields(self, document_fields):
def build(self):
report = SandboxCheckReport(self.recommendation, self.breakdown)
result = SandboxDocumentTextDataCheckResult(report, self.__document_fields)
return SandboxDocumentTextDataCheck(result, self.document_filter)
return SandboxDocumentTextDataCheck(
result, self.document_filter, self.handled_check_limit
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@


class SandboxIdDocumentComparisonCheck(SandboxCheck):
def __init__(self, result, secondary_document_filter):
SandboxCheck.__init__(self, result)
def __init__(self, result, secondary_document_filter, handled_check_limit=None):
SandboxCheck.__init__(self, result, handled_check_limit)
self.__secondary_document_filter = secondary_document_filter

@staticmethod
Expand Down Expand Up @@ -37,5 +37,5 @@ def build(self):
report = SandboxCheckReport(self.recommendation, self.breakdown)
result = SandboxCheckResult(report)
return SandboxIdDocumentComparisonCheck(
result, self.__secondary_document_filter
result, self.__secondary_document_filter, self.handled_check_limit
)
4 changes: 2 additions & 2 deletions yoti_python_sandbox/doc_scan/check/sandbox_liveness_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@


class SandboxLivenessCheck(SandboxCheck):
def __init__(self, result, liveness_type):
SandboxCheck.__init__(self, result)
def __init__(self, result, liveness_type, handled_check_limit=None):
SandboxCheck.__init__(self, result, handled_check_limit)
self.__liveness_type = liveness_type

@property
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,6 @@ def build(self):
result = SandboxSupplementaryDocumentTextDataCheckResult(
report, self.__document_fields
)
return SandboxSupplementaryDocumentTextDataCheck(result, self.document_filter)
return SandboxSupplementaryDocumentTextDataCheck(
result, self.document_filter, self.handled_check_limit
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@


class SandboxZoomLivenessCheck(SandboxLivenessCheck):
def __init__(self, result):
SandboxLivenessCheck.__init__(self, result, constants.ZOOM)
def __init__(self, result, handled_check_limit=None):
SandboxLivenessCheck.__init__(self, result, constants.ZOOM, handled_check_limit)


class SandboxZoomLivenessCheckBuilder(SandboxCheckBuilder):
def build(self):
report = SandboxCheckReport(self.recommendation, self.breakdown)
result = SandboxCheckResult(report)
return SandboxZoomLivenessCheck(result)
return SandboxZoomLivenessCheck(result, self.handled_check_limit)
144 changes: 144 additions & 0 deletions yoti_python_sandbox/tests/doc_scan/check/test_handled_check_limit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"""
Tests for handled_check_limit on all IDV sandbox check-report types.
"""
import pytest

from yoti_python_sandbox.doc_scan.check import (
SandboxDocumentAuthenticityCheckBuilder,
SandboxDocumentFaceMatchCheckBuilder,
SandboxDocumentTextDataCheckBuilder,
SandboxIdDocumentComparisonCheckBuilder,
SandboxSupplementaryDocumentTextDataCheckBuilder,
SandboxZoomLivenessCheckBuilder,
)


HANDLED_CHECK_LIMIT = 3

ALL_BUILDER_CLASSES = [
SandboxDocumentAuthenticityCheckBuilder,
SandboxDocumentFaceMatchCheckBuilder,
SandboxDocumentTextDataCheckBuilder,
SandboxIdDocumentComparisonCheckBuilder,
SandboxSupplementaryDocumentTextDataCheckBuilder,
SandboxZoomLivenessCheckBuilder,
]


@pytest.mark.parametrize("builder_class", ALL_BUILDER_CLASSES)
def test_handled_check_limit_is_included_in_json_when_set(builder_class):
check = builder_class().with_handled_check_limit(HANDLED_CHECK_LIMIT).build()

json = check.to_json()

assert json.get("handled_check_limit") == HANDLED_CHECK_LIMIT

Comment on lines +28 to +35

@pytest.mark.parametrize("builder_class", ALL_BUILDER_CLASSES)
def test_handled_check_limit_is_omitted_from_json_when_not_set(builder_class):
check = builder_class().build()

json = check.to_json()

assert "handled_check_limit" not in json


@pytest.mark.parametrize("builder_class", ALL_BUILDER_CLASSES)
def test_handled_check_limit_property_returns_set_value(builder_class):
check = builder_class().with_handled_check_limit(HANDLED_CHECK_LIMIT).build()

assert check.handled_check_limit == HANDLED_CHECK_LIMIT


@pytest.mark.parametrize("builder_class", ALL_BUILDER_CLASSES)
def test_handled_check_limit_property_returns_none_when_not_set(builder_class):
check = builder_class().build()

assert check.handled_check_limit is None


def test_document_authenticity_check_handled_check_limit_end_to_end():
check = (
SandboxDocumentAuthenticityCheckBuilder()
.with_handled_check_limit(5)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 5
assert check.handled_check_limit == 5


def test_zoom_liveness_check_handled_check_limit_end_to_end():
check = (
SandboxZoomLivenessCheckBuilder()
.with_handled_check_limit(2)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 2
assert check.handled_check_limit == 2
assert check.liveness_type == "ZOOM"


def test_id_document_comparison_check_handled_check_limit_end_to_end():
check = (
SandboxIdDocumentComparisonCheckBuilder()
.with_handled_check_limit(1)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 1


def test_document_face_match_check_handled_check_limit_end_to_end():
check = (
SandboxDocumentFaceMatchCheckBuilder()
.with_handled_check_limit(10)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 10


def test_document_text_data_check_handled_check_limit_end_to_end():
check = (
SandboxDocumentTextDataCheckBuilder()
.with_handled_check_limit(7)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 7


def test_supplementary_document_text_data_check_handled_check_limit_end_to_end():
check = (
SandboxSupplementaryDocumentTextDataCheckBuilder()
.with_handled_check_limit(4)
.build()
)

json = check.to_json()

assert json.get("handled_check_limit") == 4


def test_existing_builder_calls_remain_backward_compatible():
"""Ensure existing callers that do not set handled_check_limit still work."""
check = (
SandboxDocumentAuthenticityCheckBuilder()
.build()
)

assert check.handled_check_limit is None
json = check.to_json()
assert "handled_check_limit" not in json
Loading