1+ using System ;
2+ using System . Collections . Generic ;
3+ using Microsoft . Azure . Cosmos ;
4+ using Microsoft . VisualStudio . TestTools . UnitTesting ;
5+
6+ namespace Microsoft . Azure . Cosmos . Tests
7+ {
8+ /// <summary>
9+ /// Tests for the fix to handle long numeric strings in patch operation paths
10+ /// </summary>
11+ [ TestClass ]
12+ public class PatchOperationLongNumericPathTests
13+ {
14+ [ TestMethod ]
15+ public void TestLongNumericStringInPath_EscapedCorrectly ( )
16+ {
17+ // Test the exact scenario from the issue
18+ var longNumericString = "12345678901234567890" ; // 20 characters - should be escaped
19+ var processedPath = PatchPathHelper . ProcessPath ( $ "/strings/{ longNumericString } ") ;
20+
21+ Assert . AreEqual ( $ "/strings/[\" { longNumericString } \" ]", processedPath ) ;
22+ }
23+
24+ [ TestMethod ]
25+ public void TestVeryLongNumericStringInPath_EscapedCorrectly ( )
26+ {
27+ // Test with an even longer numeric string
28+ var veryLongNumericString = "123456789012345678901234567890" ; // 30 characters
29+ var processedPath = PatchPathHelper . ProcessPath ( $ "/strings/{ veryLongNumericString } ") ;
30+
31+ Assert . AreEqual ( $ "/strings/[\" { veryLongNumericString } \" ]", processedPath ) ;
32+ }
33+
34+ [ TestMethod ]
35+ public void TestShortNumericStringInPath_NotEscaped ( )
36+ {
37+ // Test with a short numeric string (should not be escaped)
38+ var shortNumericString = "123456789" ; // 9 characters
39+ var processedPath = PatchPathHelper . ProcessPath ( $ "/strings/{ shortNumericString } ") ;
40+
41+ Assert . AreEqual ( $ "/strings/{ shortNumericString } ", processedPath ) ;
42+ }
43+
44+ [ TestMethod ]
45+ public void TestBoundaryNumericStringInPath_NotEscaped ( )
46+ {
47+ // Test with a numeric string at the boundary (19 characters - should not be escaped)
48+ var boundaryNumericString = "1234567890123456789" ; // 19 characters
49+ var processedPath = PatchPathHelper . ProcessPath ( $ "/strings/{ boundaryNumericString } ") ;
50+
51+ Assert . AreEqual ( $ "/strings/{ boundaryNumericString } ", processedPath ) ;
52+ }
53+
54+ [ TestMethod ]
55+ public void TestMixedAlphaNumericStringInPath_NotEscaped ( )
56+ {
57+ // Test with mixed alphanumeric string (should not be escaped regardless of length)
58+ var mixedString = "abc123456789012345678901234567890def" ;
59+ var processedPath = PatchPathHelper . ProcessPath ( $ "/strings/{ mixedString } ") ;
60+
61+ Assert . AreEqual ( $ "/strings/{ mixedString } ", processedPath ) ;
62+ }
63+
64+ [ TestMethod ]
65+ public void TestMultipleSegmentsWithLongNumeric_OnlyLongNumericEscaped ( )
66+ {
67+ // Test with multiple segments where only the long numeric one should be escaped
68+ var path = "/strings/12345678901234567890/nested/123456789" ;
69+ var processedPath = PatchPathHelper . ProcessPath ( path ) ;
70+
71+ Assert . AreEqual ( "/strings/[\" 12345678901234567890\" ]/nested/123456789" , processedPath ) ;
72+ }
73+
74+ [ TestMethod ]
75+ public void TestMultipleLongNumericSegments_AllEscaped ( )
76+ {
77+ // Test with multiple long numeric segments
78+ var path = "/data/12345678901234567890/items/987654321098765432109876543210" ;
79+ var processedPath = PatchPathHelper . ProcessPath ( path ) ;
80+
81+ Assert . AreEqual ( "/data/[\" 12345678901234567890\" ]/items/[\" 987654321098765432109876543210\" ]" , processedPath ) ;
82+ }
83+
84+ [ TestMethod ]
85+ public void TestPatchOperationsWithLongNumericPaths_CreatedSuccessfully ( )
86+ {
87+ // Test that patch operations can be created with long numeric paths
88+ var longNumericString = "12345678901234567890" ;
89+
90+ var addOperation = PatchOperation . Add ( $ "/strings/{ longNumericString } ", "test_value" ) ;
91+ var replaceOperation = PatchOperation . Replace ( $ "/data/{ longNumericString } ", "new_value" ) ;
92+ var removeOperation = PatchOperation . Remove ( $ "/items/{ longNumericString } ") ;
93+
94+ Assert . AreEqual ( $ "/strings/{ longNumericString } ", addOperation . Path ) ;
95+ Assert . AreEqual ( $ "/data/{ longNumericString } ", replaceOperation . Path ) ;
96+ Assert . AreEqual ( $ "/items/{ longNumericString } ", removeOperation . Path ) ;
97+ }
98+
99+ [ TestMethod ]
100+ public void TestEdgeCases_HandledCorrectly ( )
101+ {
102+ // Test edge cases
103+ Assert . AreEqual ( "" , PatchPathHelper . ProcessPath ( "" ) ) ;
104+ Assert . AreEqual ( "/" , PatchPathHelper . ProcessPath ( "/" ) ) ;
105+ Assert . AreEqual ( null , PatchPathHelper . ProcessPath ( null ) ) ;
106+ Assert . AreEqual ( "/[\" 12345678901234567890\" ]" , PatchPathHelper . ProcessPath ( "/12345678901234567890" ) ) ;
107+ }
108+
109+ [ TestMethod ]
110+ public void TestMoveOperationWithLongNumericPaths_BothPathsEscaped ( )
111+ {
112+ // Test that move operations escape both 'from' and 'path' when they contain long numeric strings
113+ var longNumericString1 = "12345678901234567890" ;
114+ var longNumericString2 = "98765432109876543210" ;
115+
116+ var moveOperation = PatchOperation . Move ( $ "/source/{ longNumericString1 } ", $ "/target/{ longNumericString2 } ") ;
117+
118+ Assert . AreEqual ( $ "/target/{ longNumericString2 } ", moveOperation . Path ) ;
119+ Assert . AreEqual ( $ "/source/{ longNumericString1 } ", moveOperation . From ) ;
120+
121+ // Test that the helper processes both paths correctly
122+ var processedPath = PatchPathHelper . ProcessPath ( moveOperation . Path ) ;
123+ var processedFrom = PatchPathHelper . ProcessPath ( moveOperation . From ) ;
124+
125+ Assert . AreEqual ( $ "/target/[\" { longNumericString2 } \" ]", processedPath ) ;
126+ Assert . AreEqual ( $ "/source/[\" { longNumericString1 } \" ]", processedFrom ) ;
127+ }
128+ }
129+ }
0 commit comments