1
+ <?php
2
+
3
+ declare (strict_types=1 );
4
+
5
+ namespace HashSensitiveTests ;
6
+
7
+ use GlobyApp \HashSensitive \HashSensitiveProcessor ;
8
+ use TypeError ;
9
+
10
+ it ('redacts nested objects ' , function (): void {
11
+ $ nested = new \stdClass ();
12
+ $ nested ->value = 'foobar ' ;
13
+ $ nested ->nested = ['value ' => 'bazqux ' ];
14
+
15
+ $ input = ['test ' => ['nested ' => $ nested ]];
16
+ $ sensitive_keys = ['test ' => ['nested ' => ['value ' , 'nested ' => ['value ' ]]]];
17
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
18
+
19
+ $ record = $ this ->getRecord (context: $ input );
20
+
21
+ expect ($ processor ($ record )->context )->toBe (['test ' => ['nested ' => $ nested ]])
22
+ ->and ($ nested ->value )->toBe ('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 ' )
23
+ ->and ($ nested ->nested ['value ' ])->toBe ('972c5e1203896784a7cf9dd60acd443a1065e19ad5f92e59a9180c185f065c04 ' );
24
+ });
25
+
26
+ it ('works without sensitive key subobjects ' , function (): void {
27
+ $ nested = new \stdClass ();
28
+ $ nested ->foobar = "test " ;
29
+
30
+ $ obj = new \stdClass ();
31
+ $ obj ->test = $ nested ;
32
+
33
+ $ input = ['obj ' => $ obj ];
34
+ $ sensitive_keys = ['test ' ];
35
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
36
+
37
+ $ record = $ this ->getRecord (context: $ input );
38
+ expect ($ processor ($ record )->context )->toBe (['obj ' => $ obj ])
39
+ ->and ($ obj ->test )->toBe ('914dba76d2c953789b8ec73425b85bea1c8298815dd0afc1e4fc6c2d8be69648 ' );
40
+ });
41
+
42
+ it ('keeps non redacted nested objects intact ' , function (): void {
43
+ $ nested = new \stdClass ();
44
+ $ nested ->value = 'bazqux ' ;
45
+ $ nested ->no_hash = 'foobar ' ;
46
+
47
+ $ value = new \stdClass ();
48
+ $ value ->value = 'foobar ' ;
49
+ $ value ->nested = $ nested ;
50
+
51
+ $ input = ['test ' => ['nested ' => $ value ]];
52
+ $ sensitive_keys = ['test ' => ['nested ' => ['value ' , 'nested ' => ['value ' ]]]];
53
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
54
+
55
+ $ record = $ this ->getRecord (context: $ input );
56
+
57
+ expect ($ processor ($ record )->context )->toBe (['test ' => ['nested ' => $ value ]])
58
+ ->and ($ value ->value )->toBe ('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 ' )
59
+ ->and ($ value ->nested )->toBe ($ nested )
60
+ ->and ($ nested ->value )->toBe ('972c5e1203896784a7cf9dd60acd443a1065e19ad5f92e59a9180c185f065c04 ' )
61
+ ->and ($ nested ->no_hash )->toBe ('foobar ' );
62
+ });
63
+
64
+ it ('doesn \'t break on null values in input object ' , function (): void {
65
+ $ nested = new \stdClass ();
66
+ $ nested ->value = null ;
67
+ $ nested ->no_hash = null ;
68
+
69
+ $ value = new \stdClass ();
70
+ $ value ->value = 'foobar ' ;
71
+ $ value ->nested = $ nested ;
72
+
73
+ $ input = ['test ' => ['nested ' => $ value ]];
74
+ $ sensitive_keys = ['test ' => ['nested ' => ['value ' , 'nested ' => ['value ' ]]]];
75
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
76
+
77
+ $ record = $ this ->getRecord (context: $ input );
78
+
79
+ expect ($ processor ($ record )->context )->toBe (['test ' => ['nested ' => $ value ]])
80
+ ->and ($ value ->value )->toBe ('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 ' )
81
+ ->and ($ value ->nested )->toBe ($ nested )
82
+ ->and ($ nested ->value )->toBeNull ()
83
+ ->and ($ nested ->no_hash )->toBeNull ();
84
+ });
85
+
86
+ it ('doesn \'t break on null values in sensitive keys (object) ' , function (): void {
87
+ $ nested = new \stdClass ();
88
+ $ nested ->value = 'foobar ' ;
89
+ $ nested ->nested = ['value ' => 'bazqux ' , 'no_hash ' => 'foobar ' ];
90
+
91
+ $ input = ['test ' => ['nested ' => $ nested ]];
92
+ $ sensitive_keys = ['test ' => ['nested ' => [null , 'nested ' => [null ], null ], null ], null ];
93
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
94
+
95
+ $ record = $ this ->getRecord (context: $ input );
96
+
97
+ expect ($ processor ($ record )->context )->toBe (['test ' => ['nested ' => $ nested ]])
98
+ ->and ($ nested ->nested ['no_hash ' ])->toBe ('foobar ' );
99
+ });
100
+
101
+ it ('redacts inside nested objects ' , function (): void {
102
+ $ nested = new \stdClass ();
103
+ $ nested ->value = 'foobar ' ;
104
+ $ nested ->nested = ['value ' => 'bazqux ' ];
105
+
106
+ $ input = ['test ' => ['nested ' => $ nested ]];
107
+ $ sensitive_keys = ['nested ' => ['value ' ]];
108
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
109
+
110
+ $ record = $ this ->getRecord (context: $ input );
111
+
112
+ expect ($ processor ($ record )->context )->toBe (['test ' => ['nested ' => $ nested ]])
113
+ ->and ($ nested ->value )->toBe ('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 ' )
114
+ ->and ($ nested ->nested ['value ' ])->toBe ('972c5e1203896784a7cf9dd60acd443a1065e19ad5f92e59a9180c185f065c04 ' );
115
+ });
116
+
117
+ it ('it hashes all instances with exclusiveSubtree false in nested objects ' , function (): void {
118
+ $ nested = new \stdClass ();
119
+ $ nested ->to_hash = 'test_value ' ;
120
+ $ nested ->test = 'test ' ;
121
+
122
+ $ value = new \stdClass ();
123
+ $ value ->test_key = 'test_value ' ;
124
+ $ value ->test_subkey = $ nested ;
125
+
126
+ $ input = ['nested ' => $ value ];
127
+ $ sensitive_keys = ['test ' , 'test_subkey ' => ['to_hash ' ]];
128
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys , exclusiveSubtree: false );
129
+
130
+ $ record = $ this ->getRecord (context: $ input );
131
+ expect ($ processor ($ record )->context )->toBe (['nested ' => $ value ])
132
+ ->and ($ value ->test_key )->toBe ('test_value ' )
133
+ ->and ($ value ->test_subkey )->toBe ($ nested )
134
+ ->and ($ nested ->to_hash )->toBe ('4f7f6a4ae46676d9751fdccdf15ae1e6a200ed0de5653e06390148928c642006 ' )
135
+ ->and ($ nested ->test )->toBe ('9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08 ' );
136
+ });
137
+
138
+ it ('ensures exclusiveSubtree is turned on by default for objects ' , function (): void {
139
+ $ nested = new \stdClass ();
140
+ $ nested ->to_hash = 'test_value ' ;
141
+ $ nested ->test = 'test ' ;
142
+
143
+ $ value = new \stdClass ();
144
+ $ value ->test_key = 'test_value ' ;
145
+ $ value ->test_subkey = $ nested ;
146
+
147
+ $ input = ['nested ' => $ value ];
148
+ $ sensitive_keys = ['test ' , 'test_subkey ' => ['to_hash ' ]];
149
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
150
+
151
+ $ record = $ this ->getRecord (context: $ input );
152
+ expect ($ processor ($ record )->context )->toBe (['nested ' => $ value ])
153
+ ->and ($ value ->test_key )->toBe ('test_value ' )
154
+ ->and ($ value ->test_subkey )->toBe ($ nested )
155
+ ->and ($ nested ->to_hash )->toBe ('4f7f6a4ae46676d9751fdccdf15ae1e6a200ed0de5653e06390148928c642006 ' )
156
+ ->and ($ nested ->test )->toBe ('test ' );
157
+ });
158
+
159
+ it ('preserves empty values in objects ' , function (): void {
160
+ $ nested = new \stdClass ();
161
+ $ nested ->test = 'foobar ' ;
162
+ $ nested ->optionalKey = '' ;
163
+
164
+ $ input = ['nested ' => $ nested ];
165
+ $ sensitive_keys = ['test ' , 'optionalKey ' ];
166
+ $ processor = new HashSensitiveProcessor ($ sensitive_keys );
167
+
168
+ $ record = $ this ->getRecord (context: $ input );
169
+ expect ($ processor ($ record )->context )->toBe (['nested ' => $ nested ])
170
+ ->and ($ nested ->test )->toBe ('c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2 ' )
171
+ ->and ($ nested ->optionalKey )->toBeNull ();
172
+ });
0 commit comments