|
13 | 13 | from aws_lambda_decorators.decorators import extract, extract_from_event, extract_from_context, handle_exceptions, \ |
14 | 14 | log, response_body_as_json, extract_from_ssm, validate, handle_all_exceptions, cors |
15 | 15 | from aws_lambda_decorators.validators import Mandatory, RegexValidator, SchemaValidator, Minimum, Maximum, MaxLength, \ |
16 | | - MinLength, Type, EnumValidator, NonEmpty |
| 16 | + MinLength, Type, EnumValidator, NonEmpty, DateValidator |
17 | 17 |
|
18 | 18 | TEST_JWT = "eyJraWQiOiJEQlwvK0lGMVptekNWOGNmRE1XVUxBRlBwQnVObW5CU2NcL2RoZ3pnTVhcL2NzPSIsImFsZyI6IlJTMjU2In0." \ |
19 | 19 | "eyJzdWIiOiJhYWRkMWUwZS01ODA3LTQ3NjMtYjFlOC01ODIzYmY2MzFiYjYiLCJhdWQiOiIycjdtMW1mdWFiODg3ZmZvdG9iNWFjcX" \ |
@@ -1546,58 +1546,6 @@ def handler(event, context, **kwargs): # noqa |
1546 | 1546 | self.assertEqual(HTTPStatus.OK, response["statusCode"]) |
1547 | 1547 | self.assertEqual(expected_body, response["body"]) |
1548 | 1548 |
|
1549 | | - |
1550 | | -class IsolatedDecoderTests(unittest.TestCase): |
1551 | | - # Tests have been named so they run in a specific order |
1552 | | - |
1553 | | - ID_PATTERN = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" |
1554 | | - |
1555 | | - PARAMETERS = [ |
1556 | | - Parameter(path="pathParameters/test_id", validators=[Mandatory, RegexValidator(ID_PATTERN)]), |
1557 | | - Parameter(path="body[json]/name", validators=[MaxLength(255)]) |
1558 | | - ] |
1559 | | - |
1560 | | - def test_01_extract_from_event_400(self): |
1561 | | - event = { |
1562 | | - "pathParameters": {} |
1563 | | - } |
1564 | | - |
1565 | | - @extract_from_event(parameters=self.PARAMETERS, group_errors=True, allow_none_defaults=False) |
1566 | | - def handler(event, context, **kwargs): # noqa |
1567 | | - return kwargs |
1568 | | - |
1569 | | - response = handler(event, None) |
1570 | | - self.assertEqual(HTTPStatus.BAD_REQUEST, response["statusCode"]) |
1571 | | - |
1572 | | - def test_02_extract_from_event_200(self): |
1573 | | - test_id = str(uuid4()) |
1574 | | - |
1575 | | - event = { |
1576 | | - "pathParameters": { |
1577 | | - "test_id": test_id |
1578 | | - }, |
1579 | | - "body": json.dumps({ |
1580 | | - "name": "Gird" |
1581 | | - }) |
1582 | | - } |
1583 | | - |
1584 | | - @extract_from_event(parameters=self.PARAMETERS, group_errors=True, allow_none_defaults=False) |
1585 | | - def handler(event, context, **kwargs): # noqa |
1586 | | - return { |
1587 | | - "statusCode": HTTPStatus.OK, |
1588 | | - "body": json.dumps(kwargs) |
1589 | | - } |
1590 | | - |
1591 | | - expected_body = json.dumps({ |
1592 | | - "test_id": test_id, |
1593 | | - "name": "Gird" |
1594 | | - }) |
1595 | | - |
1596 | | - response = handler(event, None) |
1597 | | - |
1598 | | - self.assertEqual(HTTPStatus.OK, response["statusCode"]) |
1599 | | - self.assertEqual(expected_body, response["body"]) |
1600 | | - |
1601 | 1549 | def test_extract_non_empty_parameter(self): |
1602 | 1550 | event = { |
1603 | 1551 | "value": 20 |
@@ -1665,3 +1613,120 @@ def handler(event, a=None): # noqa: pylint - unused-argument |
1665 | 1613 | "Error validating parameters. Errors: %s", |
1666 | 1614 | [{"a": ["The value was empty"]}] |
1667 | 1615 | ) |
| 1616 | + |
| 1617 | + def test_extract_date_parameter(self): |
| 1618 | + event = { |
| 1619 | + "a": "2001-01-01 00:00:00" |
| 1620 | + } |
| 1621 | + |
| 1622 | + @extract([Parameter("/a", "event", validators=[DateValidator("%Y-%m-%d %H:%M:%S")])]) |
| 1623 | + def handler(event, a=None): # noqa: pylint - unused-argument |
| 1624 | + return a |
| 1625 | + |
| 1626 | + response = handler(event) |
| 1627 | + self.assertEqual("2001-01-01 00:00:00", response) |
| 1628 | + |
| 1629 | + @patch("aws_lambda_decorators.decorators.LOGGER") |
| 1630 | + def test_extract_date_parameter_fails_on_invalid_date(self, mock_logger): |
| 1631 | + event = { |
| 1632 | + "a": "2001-01-01 35:00:00" |
| 1633 | + } |
| 1634 | + |
| 1635 | + @extract([Parameter("/a", "event", validators=[DateValidator("%Y-%m-%d %H:%M:%S")])]) |
| 1636 | + def handler(event, a=None): # noqa: pylint - unused-argument |
| 1637 | + return {} |
| 1638 | + |
| 1639 | + response = handler(event, None) |
| 1640 | + |
| 1641 | + self.assertEqual(400, response["statusCode"]) |
| 1642 | + self.assertEqual("{\"message\": [{\"a\": [\"'2001-01-01 35:00:00' is not a '%Y-%m-%d %H:%M:%S' date\"]}]}", |
| 1643 | + response["body"]) |
| 1644 | + |
| 1645 | + mock_logger.error.assert_called_once_with( |
| 1646 | + "Error validating parameters. Errors: %s", |
| 1647 | + [{"a": ["'2001-01-01 35:00:00' is not a '%Y-%m-%d %H:%M:%S' date"]}] |
| 1648 | + ) |
| 1649 | + |
| 1650 | + @patch("aws_lambda_decorators.decorators.LOGGER") |
| 1651 | + def test_extract_date_parameter_fails_with_custom_error(self, mock_logger): |
| 1652 | + event = { |
| 1653 | + "a": "2001-01-01 35:00:00" |
| 1654 | + } |
| 1655 | + |
| 1656 | + @extract([Parameter("/a", "event", validators=[DateValidator("%Y-%m-%d %H:%M:%S", "Not a valid date!")])]) |
| 1657 | + def handler(event, a=None): # noqa: pylint - unused-argument |
| 1658 | + return {} |
| 1659 | + |
| 1660 | + response = handler(event, None) |
| 1661 | + |
| 1662 | + self.assertEqual(400, response["statusCode"]) |
| 1663 | + self.assertEqual("{\"message\": [{\"a\": [\"Not a valid date!\"]}]}", response["body"]) |
| 1664 | + |
| 1665 | + mock_logger.error.assert_called_once_with( |
| 1666 | + "Error validating parameters. Errors: %s", |
| 1667 | + [{"a": ["Not a valid date!"]}] |
| 1668 | + ) |
| 1669 | + |
| 1670 | + def test_extract_date_parameter_valid_on_empty(self): |
| 1671 | + event = { |
| 1672 | + "a": None |
| 1673 | + } |
| 1674 | + |
| 1675 | + @extract([Parameter("/a", "event", validators=[DateValidator("%Y-%m-%d %H:%M:%S")])]) |
| 1676 | + def handler(event, a=None): # noqa: pylint - unused-argument |
| 1677 | + return a |
| 1678 | + |
| 1679 | + response = handler(event) |
| 1680 | + self.assertEqual(None, response) |
| 1681 | + |
| 1682 | + |
| 1683 | +class IsolatedDecoderTests(unittest.TestCase): |
| 1684 | + # Tests have been named so they run in a specific order |
| 1685 | + |
| 1686 | + ID_PATTERN = "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" |
| 1687 | + |
| 1688 | + PARAMETERS = [ |
| 1689 | + Parameter(path="pathParameters/test_id", validators=[Mandatory, RegexValidator(ID_PATTERN)]), |
| 1690 | + Parameter(path="body[json]/name", validators=[MaxLength(255)]) |
| 1691 | + ] |
| 1692 | + |
| 1693 | + def test_01_extract_from_event_400(self): |
| 1694 | + event = { |
| 1695 | + "pathParameters": {} |
| 1696 | + } |
| 1697 | + |
| 1698 | + @extract_from_event(parameters=self.PARAMETERS, group_errors=True, allow_none_defaults=False) |
| 1699 | + def handler(event, context, **kwargs): # noqa |
| 1700 | + return kwargs |
| 1701 | + |
| 1702 | + response = handler(event, None) |
| 1703 | + self.assertEqual(HTTPStatus.BAD_REQUEST, response["statusCode"]) |
| 1704 | + |
| 1705 | + def test_02_extract_from_event_200(self): |
| 1706 | + test_id = str(uuid4()) |
| 1707 | + |
| 1708 | + event = { |
| 1709 | + "pathParameters": { |
| 1710 | + "test_id": test_id |
| 1711 | + }, |
| 1712 | + "body": json.dumps({ |
| 1713 | + "name": "Gird" |
| 1714 | + }) |
| 1715 | + } |
| 1716 | + |
| 1717 | + @extract_from_event(parameters=self.PARAMETERS, group_errors=True, allow_none_defaults=False) |
| 1718 | + def handler(event, context, **kwargs): # noqa |
| 1719 | + return { |
| 1720 | + "statusCode": HTTPStatus.OK, |
| 1721 | + "body": json.dumps(kwargs) |
| 1722 | + } |
| 1723 | + |
| 1724 | + expected_body = json.dumps({ |
| 1725 | + "test_id": test_id, |
| 1726 | + "name": "Gird" |
| 1727 | + }) |
| 1728 | + |
| 1729 | + response = handler(event, None) |
| 1730 | + |
| 1731 | + self.assertEqual(HTTPStatus.OK, response["statusCode"]) |
| 1732 | + self.assertEqual(expected_body, response["body"]) |
0 commit comments