@@ -120,4 +120,174 @@ void validateOptionalPositiveInteger_withInvalidValue_shouldThrow() {
120120
121121 assertEquals ("testParam must be positive, got: 0" , exception .getMessage ());
122122 }
123+
124+ @ Test
125+ void validateOperationName_withNull_shouldPass () {
126+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (null ));
127+ }
128+
129+ @ Test
130+ void validateOperationName_withValidName_shouldPass () {
131+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("test" ));
132+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("my-operation" ));
133+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation_123" ));
134+ }
135+
136+ @ Test
137+ void validateOperationName_withEmptyString_shouldThrow () {
138+ var exception =
139+ assertThrows (IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("" ));
140+
141+ assertEquals ("Operation name cannot be empty" , exception .getMessage ());
142+ }
143+
144+ @ Test
145+ void validateOperationName_withMaxLength_shouldPass () {
146+ var name = "a" .repeat (ParameterValidator .MAX_OPERATION_NAME_LENGTH );
147+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (name ));
148+ }
149+
150+ @ Test
151+ void validateOperationName_exceedingMaxLength_shouldThrow () {
152+ var name = "a" .repeat (ParameterValidator .MAX_OPERATION_NAME_LENGTH + 1 );
153+ var exception =
154+ assertThrows (IllegalArgumentException .class , () -> ParameterValidator .validateOperationName (name ));
155+
156+ assertEquals (
157+ "Operation name must be less than " + ParameterValidator .MAX_OPERATION_NAME_LENGTH
158+ + " characters, got: " + name ,
159+ exception .getMessage ());
160+ }
161+
162+ @ Test
163+ void validateOperationName_withCustomMaxLength_withNull_shouldPass () {
164+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (null , 100 ));
165+ }
166+
167+ @ Test
168+ void validateOperationName_withCustomMaxLength_withValidName_shouldPass () {
169+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("test" , 100 ));
170+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("a" .repeat (100 ), 100 ));
171+ }
172+
173+ @ Test
174+ void validateOperationName_withCustomMaxLength_withEmptyString_shouldThrow () {
175+ var exception =
176+ assertThrows (IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("" , 100 ));
177+
178+ assertEquals ("Operation name cannot be empty" , exception .getMessage ());
179+ }
180+
181+ @ Test
182+ void validateOperationName_withCustomMaxLength_exceedingLimit_shouldThrow () {
183+ var customMaxLength = 50 ;
184+ var name = "a" .repeat (customMaxLength + 1 );
185+ var exception = assertThrows (
186+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName (name , customMaxLength ));
187+
188+ assertEquals (
189+ "Operation name must be less than " + customMaxLength + " characters, got: " + name ,
190+ exception .getMessage ());
191+ }
192+
193+ @ Test
194+ void validateOperationName_withCustomMaxLength_atExactLimit_shouldPass () {
195+ var customMaxLength = 50 ;
196+ var name = "a" .repeat (customMaxLength );
197+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (name , customMaxLength ));
198+ }
199+
200+ @ Test
201+ void validateOperationName_withSpecialCharacters_shouldPass () {
202+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation-name" ));
203+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation_name" ));
204+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation.name" ));
205+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation:name" ));
206+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation/name" ));
207+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation@name" ));
208+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation#name" ));
209+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation$name" ));
210+ }
211+
212+ @ Test
213+ void validateOperationName_withUnicodeCharacters_shouldThrow () {
214+ var exception1 =
215+ assertThrows (IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("操作名称" ));
216+ assertEquals ("Operation name must contain only printable ASCII characters, got: 操作名称" , exception1 .getMessage ());
217+
218+ var exception2 = assertThrows (
219+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("opération" ));
220+ assertEquals (
221+ "Operation name must contain only printable ASCII characters, got: opération" , exception2 .getMessage ());
222+
223+ var exception3 = assertThrows (
224+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("операция" ));
225+ assertEquals (
226+ "Operation name must contain only printable ASCII characters, got: операция" , exception3 .getMessage ());
227+ }
228+
229+ @ Test
230+ void validateOperationName_withWhitespace_shouldPass () {
231+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation name" ));
232+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (" operation" ));
233+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("operation " ));
234+ }
235+
236+ @ Test
237+ void validateOperationName_withControlCharacters_shouldThrow () {
238+ var exception1 = assertThrows (
239+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("operation\n name" ));
240+ assertEquals (
241+ "Operation name must contain only printable ASCII characters, got: operation\n name" ,
242+ exception1 .getMessage ());
243+
244+ var exception2 = assertThrows (
245+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("operation\t name" ));
246+ assertEquals (
247+ "Operation name must contain only printable ASCII characters, got: operation\t name" ,
248+ exception2 .getMessage ());
249+
250+ var exception3 = assertThrows (
251+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("operation\r name" ));
252+ assertEquals (
253+ "Operation name must contain only printable ASCII characters, got: operation\r name" ,
254+ exception3 .getMessage ());
255+ }
256+
257+ @ Test
258+ void validateOperationName_withNonPrintableASCII_shouldThrow () {
259+ // Test character below printable range (0x1F)
260+ var exception1 = assertThrows (
261+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("test\u001F name" ));
262+ assertEquals (
263+ "Operation name must contain only printable ASCII characters, got: test\u001F name" ,
264+ exception1 .getMessage ());
265+
266+ // Test character above printable range (0x7F - DEL)
267+ var exception2 = assertThrows (
268+ IllegalArgumentException .class , () -> ParameterValidator .validateOperationName ("test\u007F name" ));
269+ assertEquals (
270+ "Operation name must contain only printable ASCII characters, got: test\u007F name" ,
271+ exception2 .getMessage ());
272+ }
273+
274+ @ Test
275+ void validateOperationName_withPrintableASCIIBoundaries_shouldPass () {
276+ // Test lower boundary (0x20 - space)
277+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (" " ));
278+
279+ // Test upper boundary (0x7E - tilde)
280+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("~" ));
281+
282+ // Test all printable ASCII characters
283+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName (
284+ "!\" #$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\ ]^_`abcdefghijklmnopqrstuvwxyz{|}~" ));
285+ }
286+
287+ @ Test
288+ void validateOperationName_withSingleCharacter_shouldPass () {
289+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("a" ));
290+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("1" ));
291+ assertDoesNotThrow (() -> ParameterValidator .validateOperationName ("-" ));
292+ }
123293}
0 commit comments