| 
1 | 1 | # -*- coding: utf-8 -*-  | 
 | 2 | +# flake8: noqa  | 
2 | 3 | """  | 
3 | 4 | Simple test bank.  | 
4 | 5 | 
  | 
5 | 6 | Test the three use cases that we care about.  | 
6 | 7 | """  | 
 | 8 | +import unittest  | 
7 | 9 | import logging  | 
 | 10 | +import json  | 
8 | 11 | 
 
  | 
9 | 12 | from secure_logger.decorators import secure_logger  | 
10 |  | -from secure_logger.masked_dict import masked_dict, masked_dict2str  | 
 | 13 | +from secure_logger.masked_dict import (  | 
 | 14 | +    masked_dict,  | 
 | 15 | +    masked_dict2str,  | 
 | 16 | +    DEFAULT_REDACTION_MESSAGE,  | 
 | 17 | +)  | 
11 | 18 | 
 
  | 
12 |  | -logging.basicConfig(level=logging.DEBUG)  | 
13 | 19 | 
 
  | 
14 |  | -MY_SENSITIVE_KEYS = [  | 
15 |  | -    "client_id",  | 
16 |  | -    "client_secret",  | 
17 |  | -    "aws_access_key_id",  | 
18 |  | -    "aws_secret_access_key",  | 
19 |  | -]  | 
 | 20 | +###############################################################################  | 
 | 21 | +#                                 TEST BANK  | 
 | 22 | +###############################################################################  | 
 | 23 | +class TestMaskedDict(unittest.TestCase):  | 
 | 24 | +    test_dict = {  | 
 | 25 | +        "insensitive_key": "you-can-see-me",  | 
 | 26 | +        "aws_access_key_id": "i-am-hidden",  | 
 | 27 | +        "aws_secret_access_key": "so-am-i",  | 
 | 28 | +    }  | 
 | 29 | +    expected_dict = {  | 
 | 30 | +        "insensitive_key": "you-can-see-me",  | 
 | 31 | +        "aws_access_key_id": DEFAULT_REDACTION_MESSAGE,  | 
 | 32 | +        "aws_secret_access_key": DEFAULT_REDACTION_MESSAGE,  | 
 | 33 | +    }  | 
 | 34 | + | 
 | 35 | +    def test_masked_dict(self):  | 
 | 36 | +        md = masked_dict(self.test_dict)  | 
 | 37 | +        self.assertDictEqual(md, self.expected_dict)  | 
 | 38 | + | 
 | 39 | +    def test_masked_dict2str(self):  | 
 | 40 | +        md2s = masked_dict2str(self.test_dict)  | 
 | 41 | +        md2s_to_json = json.loads(md2s)  | 
 | 42 | +        self.assertDictEqual(md2s_to_json, self.expected_dict)  | 
 | 43 | + | 
 | 44 | + | 
 | 45 | +class TestMaskedDictCaseSensitivity(unittest.TestCase):  | 
 | 46 | +    test_dict = {  | 
 | 47 | +        "insensitive_key": "you-can-see-me",  | 
 | 48 | +        "AWs_AcCEss_KeY_iD": "i-am-very-hidden",  | 
 | 49 | +        "AWS_SECRET_ACCESS_KEY": "so-am-i",  | 
 | 50 | +    }  | 
 | 51 | +    expected_dict = {  | 
 | 52 | +        "insensitive_key": "you-can-see-me",  | 
 | 53 | +        "AWs_AcCEss_KeY_iD": DEFAULT_REDACTION_MESSAGE,  | 
 | 54 | +        "AWS_SECRET_ACCESS_KEY": DEFAULT_REDACTION_MESSAGE,  | 
 | 55 | +    }  | 
 | 56 | + | 
 | 57 | +    def test_masked_dict(self):  | 
 | 58 | +        md = masked_dict(self.test_dict)  | 
 | 59 | +        self.assertDictEqual(md, self.expected_dict)  | 
 | 60 | + | 
 | 61 | +    def test_masked_dict2str(self):  | 
 | 62 | +        md2s = masked_dict2str(self.test_dict)  | 
 | 63 | +        md2s_to_json = json.loads(md2s)  | 
 | 64 | +        self.assertDictEqual(md2s_to_json, self.expected_dict)  | 
 | 65 | + | 
20 | 66 | 
 
  | 
 | 67 | +class TestCustomParams(unittest.TestCase):  | 
 | 68 | +    visible_value = "i should be visible"  | 
 | 69 | +    custom_keys = ["foo", "bar"]  | 
 | 70 | +    custom_message = "--REDACTED--"  | 
 | 71 | +    test_dict = {"foo": "i should be hidden", "bar": "me too", "visible_key": visible_value}  | 
21 | 72 | 
 
  | 
22 |  | -@secure_logger()  | 
23 |  | -def test_1(msg):  | 
24 |  | -    """Test 1: a simple module function."""  | 
25 |  | -    print("test 1: " + msg)  # noqa: T201  | 
 | 73 | +    def test_custom_keys(self):  | 
 | 74 | +        expected_result = {  | 
 | 75 | +            "foo": DEFAULT_REDACTION_MESSAGE,  | 
 | 76 | +            "bar": DEFAULT_REDACTION_MESSAGE,  | 
 | 77 | +            "visible_key": self.visible_value,  | 
 | 78 | +        }  | 
 | 79 | +        masked_test_dict = masked_dict(self.test_dict, self.custom_keys)  | 
 | 80 | +        self.assertDictEqual(masked_test_dict, expected_result)  | 
26 | 81 | 
 
  | 
 | 82 | +    def test_custom_keys_and_message(self):  | 
 | 83 | +        expected_result = {"foo": self.custom_message, "bar": self.custom_message, "visible_key": self.visible_value}  | 
 | 84 | +        masked_test_dict = masked_dict(self.test_dict, self.custom_keys, self.custom_message)  | 
 | 85 | +        self.assertDictEqual(masked_test_dict, expected_result)  | 
27 | 86 | 
 
  | 
28 |  | -class TestClass(object):  | 
29 |  | -    """Test class method logging."""  | 
30 | 87 | 
 
  | 
 | 88 | +class TestModuleDefDecorator(unittest.TestCase):  | 
31 | 89 |     @secure_logger()  | 
32 |  | -    def test_2(self, test_dict, test_list):  | 
33 |  | -        """Test class input parameter as objects."""  | 
 | 90 | +    def mock_decorated_def(self, msg):  | 
 | 91 | +        """Test 1: a simple module function."""  | 
34 | 92 |         pass  | 
35 | 93 | 
 
  | 
36 |  | -    @secure_logger(sensitive_keys=["aws_secret_access_key"], indent=10, message="-- Forbidden! --")  | 
37 |  | -    def test_4(self, test_dict, test_list):  | 
38 |  | -        """Test class input parameter as objects."""  | 
39 |  | -        pass  | 
 | 94 | +    def test_decorator_output(self):  | 
 | 95 | +        hello_world = json.dumps(["'hello world'"])  | 
 | 96 | +        hello_world = "'hello world'"  | 
40 | 97 | 
 
  | 
 | 98 | +        expected_output = (  | 
 | 99 | +            "INFO:secure_logger.decorators:secure_logger: __main__.mock_decorated_def() ['<__main__.TestModuleDefDecorator testMethod=test_decorator_output>', "  | 
 | 100 | +            + hello_world  | 
 | 101 | +        )  | 
 | 102 | +        with self.assertLogs(level=logging.DEBUG) as cm:  | 
 | 103 | +            self.mock_decorated_def("hello world")  | 
41 | 104 | 
 
  | 
42 |  | -@secure_logger()  | 
43 |  | -class Test3:  | 
44 |  | -    """Test 3: decorate a class."""  | 
 | 105 | +        self.assertEqual(cm.output[0][0:100], expected_output[0:100])  | 
45 | 106 | 
 
  | 
46 |  | -    pass  | 
47 | 107 | 
 
  | 
 | 108 | +class TestClassMethodDecorator(unittest.TestCase):  | 
 | 109 | +    class MockClass(object):  | 
 | 110 | +        """Test class method logging."""  | 
48 | 111 | 
 
  | 
49 |  | -if __name__ == "__main__":  | 
50 |  | -    # test 1  | 
51 |  | -    print("test 1 - default parameters on module function")  # noqa: T201  | 
52 |  | -    test_1("hello world")  | 
 | 112 | +        @secure_logger()  | 
 | 113 | +        def decorator_with_defaults(self, test_dict, test_list):  | 
 | 114 | +            """Test class input parameter as objects."""  | 
 | 115 | +            pass  | 
 | 116 | + | 
 | 117 | +        @secure_logger(sensitive_keys=["aws_secret_access_key"], indent=10, message="-- Forbidden! --")  | 
 | 118 | +        def decorator_with_custom_params(self, test_dict, test_list):  | 
 | 119 | +            """Test class input parameter as objects."""  | 
 | 120 | +            pass  | 
53 | 121 | 
 
  | 
54 |  | -    # test 2  | 
55 |  | -    print("test 2 - default parameters on class method")  # noqa: T201  | 
56 | 122 |     test_dict = {  | 
57 | 123 |         "insensitive_key": "you-can-see-me",  | 
58 | 124 |         "aws_access_key_id": "i-am-hidden",  | 
59 | 125 |         "aws_secret_access_key": "so-am-i",  | 
60 | 126 |     }  | 
61 | 127 |     test_list = ["foo", "bar"]  | 
62 |  | -    o = TestClass()  | 
63 |  | -    o.test_2(test_dict=test_dict, test_list=test_list)  | 
 | 128 | +    mock_class = MockClass()  | 
64 | 129 | 
 
  | 
65 |  | -    # test 3  | 
66 |  | -    print("test 3 - default parameters on class definition")  # noqa: T201  | 
67 |  | -    test3 = Test3()  | 
 | 130 | +    def test_class_method_with_default_params(self):  | 
 | 131 | +        expected_output = "INFO:secure_logger.decorators:secure_logger: __main__.decorator_with_defaults() ['<__main__.TestClassMethodDecorator.MockClass"  | 
68 | 132 | 
 
  | 
69 |  | -    # test 4  | 
70 |  | -    print("test 4 - custom parameters")  # noqa: T201  | 
71 |  | -    o.test_4(test_dict=test_dict, test_list=test_list)  | 
 | 133 | +        with self.assertLogs(level=logging.DEBUG) as cm:  | 
 | 134 | +            self.mock_class.decorator_with_defaults(self.test_dict, self.test_list)  | 
72 | 135 | 
 
  | 
73 |  | -    # test 5  | 
74 |  | -    print("test 5 - masked_dict() w defaults")  # noqa: T201  | 
75 |  | -    print(masked_dict(test_dict))  # noqa: T201  | 
 | 136 | +        self.assertEqual(cm.output[0][0:100], expected_output[0:100])  | 
76 | 137 | 
 
  | 
77 |  | -    # test 6  | 
78 |  | -    print("test 6 - masked_dict() with custom parameters")  # noqa: T201  | 
79 |  | -    print(masked_dict(test_dict, sensitive_keys=["insensitive_key"], message=" -- TEST 6 MESSAGE -- "))  # noqa: T201  | 
80 | 138 | 
 
  | 
81 |  | -    # test 7  | 
82 |  | -    print("test 7 - masked_dict2str() w defaults")  # noqa: T201  | 
83 |  | -    print(masked_dict2str(test_dict))  # noqa: T201  | 
 | 139 | +class TestClassDecorator(unittest.TestCase):  | 
 | 140 | +    def test_class_with_default_params(self):  | 
 | 141 | +        @secure_logger()  | 
 | 142 | +        class MockDecoratedClass(object):  | 
 | 143 | +            """Test 3: decorate a class."""  | 
84 | 144 | 
 
  | 
85 |  | -    # test 8  | 
86 |  | -    print("test 8 - masked_dict2str() w custom parameters")  # noqa: T201  | 
87 |  | -    md = masked_dict2str(test_dict, sensitive_keys=["insensitive_key"], message=" -- TEST 8 MESSAGE -- ", indent=2)  | 
88 |  | -    print(md)  # noqa: T201  | 
 | 145 | +            pass  | 
89 | 146 | 
 
  | 
90 |  | -    # test 9  | 
91 |  | -    print("test 9 - masked_dict2str() upper case keys")  # noqa: T201  | 
92 |  | -    test_dict = {  | 
93 |  | -        "insensitive_key": "you-can-see-me",  | 
94 |  | -        "AWS_ACCESS_KEY_ID": "i-am-hidden",  | 
95 |  | -        "AWS_Secret_Access_Key": "so-am-i",  | 
96 |  | -    }  | 
97 |  | -    print(test_dict)  # noqa: T201  | 
98 |  | -    print(masked_dict(test_dict))  # noqa: T201  | 
99 |  | -    print(masked_dict2str(test_dict))  # noqa: T201  | 
 | 147 | +        expected_output = "INFO:secure_logger.decorators:secure_logger: __main__.MockDecoratedClass.  "  | 
 | 148 | + | 
 | 149 | +        with self.assertLogs(level=logging.DEBUG) as cm:  | 
 | 150 | +            mock_decoratorated_class = MockDecoratedClass()  | 
 | 151 | + | 
 | 152 | +        self.assertEqual(cm.output[0][0:100], expected_output[0:100])  | 
 | 153 | + | 
 | 154 | + | 
 | 155 | +if __name__ == "__main__":  | 
 | 156 | +    unittest.main()  | 
0 commit comments