1 /* 2 * Copyright (c) 2023 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.networknt.schema; 17 18 import static org.junit.jupiter.api.Assertions.assertEquals; 19 20 import java.util.HashMap; 21 import java.util.List; 22 import java.util.Locale; 23 import java.util.Map; 24 import java.util.Set; 25 26 import org.junit.jupiter.api.Test; 27 28 import com.fasterxml.jackson.core.JsonProcessingException; 29 import com.fasterxml.jackson.databind.JsonMappingException; 30 import com.fasterxml.jackson.databind.JsonNode; 31 import com.fasterxml.jackson.databind.ObjectMapper; 32 import com.networknt.schema.SpecVersion.VersionFlag; 33 import com.networknt.schema.i18n.Locales; 34 import com.networknt.schema.serialization.JsonMapperFactory; 35 36 public class LocaleTest { getSchema(SchemaValidatorsConfig config)37 private JsonSchema getSchema(SchemaValidatorsConfig config) { 38 JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909); 39 return factory.getSchema( 40 "{ \"$schema\": \"https://json-schema.org/draft/2019-09/schema\", \"$id\": \"https://json-schema.org/draft/2019-09/schema\", \"type\": \"object\", \"properties\": { \"foo\": { \"type\": \"string\" } } } }", 41 config); 42 } 43 44 /** 45 * Tests that the validation messages are generated based on the execution 46 * context locale. 47 * 48 * @throws JsonMappingException the error 49 * @throws JsonProcessingException the error 50 */ 51 @Test executionContextLocale()52 void executionContextLocale() throws JsonMappingException, JsonProcessingException { 53 JsonNode rootNode = new ObjectMapper().readTree(" { \"foo\": 123 } "); 54 SchemaValidatorsConfig config = new SchemaValidatorsConfig(); 55 JsonSchema jsonSchema = getSchema(config); 56 57 Locale locale = Locales.findSupported("it;q=0.9,fr;q=1.0"); // fr 58 ExecutionContext executionContext = jsonSchema.createExecutionContext(); 59 assertEquals(config.getLocale(), executionContext.getExecutionConfig().getLocale()); 60 executionContext.getExecutionConfig().setLocale(locale); 61 Set<ValidationMessage> messages = jsonSchema.validate(executionContext, rootNode); 62 assertEquals(1, messages.size()); 63 assertEquals("$.foo: integer trouvé, string attendu", messages.iterator().next().getMessage()); 64 65 locale = Locales.findSupported("it;q=1.0,fr;q=0.9"); // it 66 executionContext = jsonSchema.createExecutionContext(); 67 assertEquals(config.getLocale(), executionContext.getExecutionConfig().getLocale()); 68 executionContext.getExecutionConfig().setLocale(locale); 69 messages = jsonSchema.validate(executionContext, rootNode); 70 assertEquals(1, messages.size()); 71 assertEquals("$.foo: integer trovato, string previsto", messages.iterator().next().getMessage()); 72 } 73 74 /** 75 * Issue 949. 76 * <p> 77 * Locale.ENGLISH should work despite Locale.getDefault setting. 78 * 79 * @throws JsonMappingException the exception 80 * @throws JsonProcessingException the exception 81 */ 82 @Test englishLocale()83 void englishLocale() throws JsonMappingException, JsonProcessingException { 84 Locale locale = Locale.getDefault(); 85 try { 86 Locale.setDefault(Locale.GERMAN); 87 String schema = "{\r\n" 88 + " \"$schema\": \"http://json-schema.org/draft-07/schema#\",\r\n" 89 + " \"$id\": \"https://www.example.com\",\r\n" 90 + " \"type\": \"object\"\r\n" 91 + "}"; 92 JsonSchema jsonSchema = JsonSchemaFactory.getInstance(VersionFlag.V7) 93 .getSchema(JsonMapperFactory.getInstance().readTree(schema)); 94 String input = "1"; 95 Set<ValidationMessage> messages = jsonSchema.validate(input, InputFormat.JSON); 96 assertEquals(1, messages.size()); 97 assertEquals("$: integer gefunden, object erwartet", messages.iterator().next().toString()); 98 99 SchemaValidatorsConfig config = new SchemaValidatorsConfig(); 100 config.setLocale(Locale.ENGLISH); 101 jsonSchema = JsonSchemaFactory.getInstance(VersionFlag.V7) 102 .getSchema(JsonMapperFactory.getInstance().readTree(schema), config); 103 messages = jsonSchema.validate(input, InputFormat.JSON); 104 assertEquals(1, messages.size()); 105 assertEquals("$: integer found, object expected", messages.iterator().next().toString()); 106 } finally { 107 Locale.setDefault(locale); 108 } 109 } 110 111 /** 112 * Tests that the file encoding for the locale files are okay. 113 * <p> 114 * Java 8 does not support UTF-8 encoded resource bundles. That is only 115 * supported in Java 9 and above. 116 */ 117 @Test encoding()118 void encoding() { 119 Map<String, String> expected = new HashMap<>(); 120 expected.put("ar","$: يجب أن يكون طوله 5 حرفًا على الأكثر"); 121 expected.put("cs","$: musí mít maximálně 5 znaků"); 122 expected.put("da","$: må højst være på 5 tegn"); 123 expected.put("de","$: darf höchstens 5 Zeichen lang sein"); 124 expected.put("fa","$: باید حداکثر 5 کاراکتر باشد"); 125 expected.put("fi","$: saa olla enintään 5 merkkiä pitkä"); 126 expected.put("fr","$: doit contenir au plus 5 caractères"); 127 expected.put("iw","$: חייב להיות באורך של 5 תווים לכל היותר"); 128 expected.put("he","$: חייב להיות באורך של 5 תווים לכל היותר"); 129 expected.put("hr","$: mora imati najviše 5 znakova"); 130 expected.put("hu","$: legfeljebb 5 karakter hosszúságú lehet"); 131 expected.put("it","$: deve contenere al massimo 5 caratteri"); 132 expected.put("ja","$: 長さは最大 5 文字でなければなりません"); 133 expected.put("ko","$: 길이는 최대 5자여야 합니다."); 134 expected.put("nb","$: må bestå av maksimalt 5 tegn"); 135 expected.put("nl","$: mag maximaal 5 tekens lang zijn"); 136 expected.put("pl","$: musi mieć maksymalnie 5 znaków"); 137 expected.put("pt","$: deve ter no máximo 5 caracteres"); 138 expected.put("ro","$: trebuie să aibă cel mult 5 caractere"); 139 expected.put("ru","$: длина должна быть не более 5 символов."); 140 expected.put("sk","$: musí mať maximálne 5 znakov"); 141 expected.put("sv","$: får vara högst 5 tecken lång"); 142 expected.put("th","$: ต้องมีความยาวสูงสุด 5 อักขระ"); 143 expected.put("tr","$: en fazla 5 karakter uzunluğunda olmalıdır"); 144 expected.put("uk","$: не більше ніж 5 символів"); 145 expected.put("vi","$: phải dài tối đa 5 ký tự"); 146 expected.put("zh_CN","$: 长度不得超过 5 个字符"); 147 expected.put("zh_TW","$: 長度不得超過 5 個字元"); 148 149 // In later JDK versions the numbers will be formatted 150 Map<String, String> expectedAlternate = new HashMap<>(); 151 expectedAlternate.put("ar","$: يجب أن يكون طوله ٥ حرفًا على الأكثر"); 152 expectedAlternate.put("fa","$: باید حداکثر ۵ کاراکتر باشد"); 153 154 String schemaData = "{\r\n" 155 + " \"type\": \"string\",\r\n" 156 + " \"maxLength\": 5\r\n" 157 + "}"; 158 JsonSchema schema = JsonSchemaFactory.getInstance(VersionFlag.V7).getSchema(schemaData); 159 List<Locale> locales = Locales.getSupportedLocales(); 160 for (Locale locale : locales) { 161 Set<ValidationMessage> messages = schema.validate("\"aaaaaa\"", InputFormat.JSON, executionContext -> { 162 executionContext.getExecutionConfig().setLocale(locale); 163 }); 164 String msg = messages.iterator().next().toString(); 165 String expectedMsg = expected.get(locale.toString()); 166 String expectedMsgAlternate = expectedAlternate.get(locale.toString()); 167 if (msg.equals(expectedMsg) || msg.equals(expectedMsgAlternate)) { 168 continue; 169 } 170 if ("iw".equals(locale.toString()) || "he".equals(locale.toString())) { 171 // There are changes in the iso codes across JDK versions that make this 172 // troublesome to handle 173 continue; 174 } 175 assertEquals(expectedMsg, msg); 176 // System.out.println(messages.iterator().next().toString()); 177 // System.out.println("expected.put(\"" +locale.toString() + "\",\"" + messages.iterator().next().toString() + "\");"); 178 179 // OutputUnit outputUnit = schema.validate("\"aaaaaa\"", InputFormat.JSON, OutputFormat.HIERARCHICAL, executionContext -> { 180 // executionContext.getExecutionConfig().setLocale(locale); 181 // }); 182 // System.out.println(outputUnit); 183 184 } 185 } 186 } 187