Skip to content

Commit ef56169

Browse files
authored
Merge pull request #13354 from SORMAS-Foundation/13311-move-email-server-configuration-to-user-interface
13311 move email server configuration to user interface
2 parents e52db8c + 3ca94f4 commit ef56169

File tree

10 files changed

+199
-53
lines changed

10 files changed

+199
-53
lines changed

sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,6 @@ public interface ConfigFacade {
4040

4141
String getSormasStatsUrl();
4242

43-
String getEmailSenderAddress();
44-
45-
String getEmailSenderName();
46-
47-
String getSmsSenderName();
48-
49-
String getSmsAuthKey();
50-
51-
String getSmsAuthSecret();
52-
5343
String getDocumentFilesPath();
5444

5545
String getTempFilesPath();

sormas-api/src/main/java/de/symeda/sormas/api/i18n/Validations.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ public interface Validations {
216216
String requiredField = "requiredField";
217217
String sampleDateTimeAfterPathogenTestDateTime = "sampleDateTimeAfterPathogenTestDateTime";
218218
String selfReportAlreadyProcessedError = "selfReportAlreadyProcessedError";
219+
String smsAuthKeyValueValidation = "smsAuthKeyValueValidation";
220+
String smsAuthSecretValueValidation = "smsAuthSecretValueValidation";
219221
String softAddEntryToList = "softAddEntryToList";
220222
String softApproximateAgeTooHigh = "softApproximateAgeTooHigh";
221223
String sormasToSormasAcceptCaseBeforeContact = "sormasToSormasAcceptCaseBeforeContact";
@@ -271,9 +273,12 @@ public interface Validations {
271273
String systemConfigurationValueInvalidValue = "systemConfigurationValueInvalidValue";
272274
String systemConfigurationValuePatternNotMatched = "systemConfigurationValuePatternNotMatched";
273275
String systemConfigurationValueValidationNotADirectory = "systemConfigurationValueValidationNotADirectory";
276+
String systemConfigurationValueValidationNotAEmail = "systemConfigurationValueValidationNotAEmail";
274277
String systemConfigurationValueValidationNotAFile = "systemConfigurationValueValidationNotAFile";
275278
String systemConfigurationValueValidationNotAIPAddr = "systemConfigurationValueValidationNotAIPAddr";
276279
String systemConfigurationValueValidationNotANumber = "systemConfigurationValueValidationNotANumber";
280+
String systemConfigurationValueValidationNotAValidEmailsenderName = "systemConfigurationValueValidationNotAValidEmailsenderName";
281+
String systemConfigurationValueValidationNotAValidSmsSenderName = "systemConfigurationValueValidationNotAValidSmsSenderName";
277282
String systemConfigurationValueValidationNotValid = "systemConfigurationValueValidationNotValid";
278283
String taskMissingCaseLink = "taskMissingCaseLink";
279284
String taskMissingContactLink = "taskMissingContactLink";

sormas-api/src/main/resources/validations.properties

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,8 @@ systemConfigurationValueValidationNotAIPAddr = Value is not a valid IP address
323323
systemConfigurationValueValidationNotANumber = Value is not a valid number
324324
systemConfigurationValueValidationNotADirectory = Value is not a valid directory
325325
systemConfigurationValueValidationNotAFile = Value is not a valid file
326+
systemConfigurationValueValidationNotAEmail = Value is not a valid email address
327+
systemConfigurationValueValidationNotAValidEmailsenderName = Value is not a valid email sender name. Name should contain only alphabets.
328+
systemConfigurationValueValidationNotAValidSmsSenderName = Value is not a valid name. Name should contain only letters and numbers without spaces & special characters. For more info please see https://developer.vonage.com/en/messaging/sms/guides/custom-sender-id .
329+
smsAuthKeyValueValidation = SMS Auth key value is not valid
330+
smsAuthSecretValueValidation = SMS Auth secret value is not valid

sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -451,31 +451,6 @@ public boolean isAnyCaseClassificationCalculationEnabled() {
451451
return classificationCalculationProps.stream().anyMatch(p -> !CaseClassificationCalculationMode.DISABLED.name().equals(props.getProperty(p)));
452452
}
453453

454-
@Override
455-
public String getEmailSenderAddress() {
456-
return getProperty(EMAIL_SENDER_ADDRESS, "noreply@sormas.org");
457-
}
458-
459-
@Override
460-
public String getEmailSenderName() {
461-
return getProperty(EMAIL_SENDER_NAME, "SORMAS Support");
462-
}
463-
464-
@Override
465-
public String getSmsSenderName() {
466-
return getProperty(SMS_SENDER_NAME, "SORMAS");
467-
}
468-
469-
@Override
470-
public String getSmsAuthKey() {
471-
return getProperty(SMS_AUTH_KEY, "");
472-
}
473-
474-
@Override
475-
public String getSmsAuthSecret() {
476-
return getProperty(SMS_AUTH_SECRET, "");
477-
}
478-
479454
@Override
480455
public boolean isDuplicateChecksExcludePersonsOfArchivedEntries() {
481456
return getBoolean(DUPLICATE_CHECKS_EXCLUDE_PERSONS_OF_ACHIVED_ENTRIES, false);

sormas-backend/src/main/java/de/symeda/sormas/backend/common/messaging/EmailService.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,25 @@
3939
import javax.mail.internet.MimeMessage;
4040
import javax.mail.internet.MimeMultipart;
4141

42+
import de.symeda.sormas.api.systemconfiguration.SystemConfigurationValueFacade;
43+
import de.symeda.sormas.backend.systemconfiguration.SystemConfigurationValueEjb;
4244
import org.slf4j.Logger;
4345
import org.slf4j.LoggerFactory;
4446

45-
import de.symeda.sormas.backend.common.ConfigFacadeEjb.ConfigFacadeEjbLocal;
46-
4747
@Stateless(name = "EmailService")
4848
@LocalBean
4949
public class EmailService {
5050

51+
private static final String EMAIL_SENDER_ADDRESS = "EMAIL_SENDER_ADDRESS";
52+
private static final String EMAIL_SENDER_NAME = "EMAIL_SENDER_NAME";
53+
5154
private final Logger logger = LoggerFactory.getLogger(getClass());
5255

5356
@Resource(name = "mail/MailSession")
5457
private Session mailSession;
5558

5659
@EJB
57-
private ConfigFacadeEjbLocal configFacade;
60+
private SystemConfigurationValueFacade systemConfigurationValueEjb;
5861

5962
@Asynchronous
6063
public void sendEmailAsync(String recipient, String subject, String content) throws MessagingException {
@@ -91,9 +94,8 @@ public void sendEmail(String recipient, String subject, String content, Map<File
9194

9295
private void sendEmailAsync(String recipient, String subject, Object content, String contentType) throws MessagingException {
9396
MimeMessage message = new MimeMessage(mailSession);
94-
95-
String senderAddress = configFacade.getEmailSenderAddress();
96-
String senderName = configFacade.getEmailSenderName();
97+
String senderAddress = systemConfigurationValueEjb.getValue(EMAIL_SENDER_ADDRESS);
98+
String senderName = systemConfigurationValueEjb.getValue(EMAIL_SENDER_NAME);
9799

98100
try {
99101
InternetAddress fromAddress = new InternetAddress(senderAddress, senderName);

sormas-backend/src/main/java/de/symeda/sormas/backend/common/messaging/SmsService.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import javax.ejb.LocalBean;
2525
import javax.ejb.Stateless;
2626

27+
import de.symeda.sormas.api.systemconfiguration.SystemConfigurationValueFacade;
28+
import de.symeda.sormas.backend.systemconfiguration.SystemConfigurationValueEjb;
2729
import org.slf4j.Logger;
2830
import org.slf4j.LoggerFactory;
2931

@@ -46,9 +48,16 @@ public class SmsService {
4648

4749
private final Logger logger = LoggerFactory.getLogger(getClass());
4850

51+
public static final String SMS_SENDER_NAME = "SMS_SENDER_NAME";
52+
public static final String SMS_AUTH_KEY = "SMS_AUTH_KEY";
53+
public static final String SMS_AUTH_SECRET = "SMS_AUTH_SECRET";
54+
4955
@EJB
5056
private ConfigFacadeEjbLocal configFacade;
5157

58+
@EJB
59+
private SystemConfigurationValueFacade systemConfigurationValueEjb;
60+
5261
@Asynchronous
5362
public void sendSms(String phoneNumber, String content) throws IOException, NexmoClientException, InvalidPhoneNumberException {
5463

@@ -61,7 +70,7 @@ public void sendSms(String phoneNumber, String content) throws IOException, Nexm
6170
phoneNumber = phoneNumber.substring(1);
6271
}
6372

64-
NexmoClient client = NexmoClient.builder().apiKey(configFacade.getSmsAuthKey()).apiSecret(configFacade.getSmsAuthSecret()).build();
73+
NexmoClient client = NexmoClient.builder().apiKey(systemConfigurationValueEjb.getValue(SMS_AUTH_KEY)).apiSecret(systemConfigurationValueEjb.getValue(SMS_AUTH_SECRET)).build();
6574

6675
// If the phone number is invalid, e.g. because it is a landline number or malformed otherwise, throw an exception
6776
InsightClient insightClient = client.getInsightClient();

sormas-backend/src/main/java/de/symeda/sormas/backend/systemconfiguration/SystemConfigurationValueEjb.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,6 @@ public class SystemConfigurationValueEjb
7878
AbstractBaseEjb<SystemConfigurationValue, SystemConfigurationValueDto, SystemConfigurationValueIndexDto, SystemConfigurationValueReferenceDto, SystemConfigurationValueService, SystemConfigurationValueCriteria>
7979
implements SystemConfigurationValueFacade {
8080

81-
@LocalBean
82-
@Singleton
83-
@Startup
84-
@DependsOn("StartupShutdownService")
85-
public static class SystemConfigurationValueEjbLocal extends SystemConfigurationValueEjb {
86-
}
87-
8881
private static final long serialVersionUID = 1L;
8982

9083
private static final Logger LOGGER = LoggerFactory.getLogger(SystemConfigurationValueEjb.class);

sormas-backend/src/main/resources/sql/sormas_schema.sql

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14071,18 +14071,130 @@ BEGIN
1407114071
CONTINUE;
1407214072
END IF;
1407314073
END LOOP;
14074-
14075-
INSERT INTO userroles_userrights(userrole_id,sys_period,userright)
14074+
14075+
INSERT INTO userroles_userrights(userrole_id,sys_period,userright)
1407614076
SELECT userrole_id,
1407714077
sys_period,
1407814078
userright
1407914079
FROM tmp_roles_rights_inserts;
14080-
DELETE FROM userroles_userrights
14080+
DELETE FROM userroles_userrights
1408114081
WHERE userrole_id IN (SELECT DISTINCT userrole_id FROM tmp_roles_rights_inserts)
1408214082
AND userright IN ('EXTERNAL_MESSAGE_DELETE','EXTERNAL_MESSAGE_PROCESS','EXTERNAL_MESSAGE_VIEW');
1408314083

1408414084
DROP TABLE IF EXISTS tmp_roles_rights_inserts;
1408514085
END $$;
1408614086
INSERT INTO schema_version (version_number, comment) VALUES (568, 'Redesign User Rights System for Message Types #13297');
1408714087

14088+
-- 2025-05-05 Moving Email & SMS properties to the new system configuration structure #13311
14089+
DO
14090+
$$ DECLARE
14091+
email_configuration_id bigint; sms_configuration_id
14092+
bigint;
14093+
14094+
BEGIN
14095+
-- Check if the category 'EMAIL' already exists
14096+
SELECT id
14097+
INTO email_configuration_id
14098+
FROM systemconfigurationcategory
14099+
WHERE name = 'EMAIL';
14100+
14101+
SELECT id
14102+
INTO sms_configuration_id
14103+
FROM systemconfigurationcategory
14104+
WHERE name = 'SMS';
14105+
14106+
-- Insert the email category if it doesn't exist
14107+
IF
14108+
email_configuration_id IS NULL THEN
14109+
INSERT INTO systemconfigurationcategory(id, uuid, changedate, creationdate, name, caption, description) VALUES (nextval('entity_seq'), generate_base32_uuid(), now(), now(), 'EMAIL', 'Email', 'Email Configuration')
14110+
RETURNING id INTO email_configuration_id;
14111+
14112+
END IF;
14113+
-- Insert the sms category if it doesn't exist
14114+
IF
14115+
sms_configuration_id IS NULL THEN
14116+
INSERT INTO systemconfigurationcategory(id, uuid, changedate, creationdate, name, caption, description) VALUES (nextval('entity_seq'), generate_base32_uuid(), now(), now(), 'SMS', 'SMS', 'SMS Configuration')
14117+
RETURNING id INTO sms_configuration_id;
14118+
end if;
14119+
14120+
14121+
DELETE
14122+
FROM systemconfigurationvalue
14123+
WHERE category_id = email_configuration_id
14124+
AND config_key = 'EMAIL_SENDER_ADDRESS';
14125+
DELETE
14126+
FROM systemconfigurationvalue_history
14127+
WHERE category_id = email_configuration_id
14128+
AND config_key = 'EMAIL_SENDER_ADDRESS';
14129+
INSERT INTO systemconfigurationvalue(config_key, config_value, category_id, value_optional, value_pattern,
14130+
value_encrypt, data_provider, validation_message, changedate, creationdate, id,
14131+
uuid)
14132+
VALUES ('EMAIL_SENDER_ADDRESS', 'noreply@sormas.org', email_configuration_id, true,
14133+
'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', false, null,
14134+
'i18n/systemConfigurationValueValidationNotAEmail', now(), now(), nextval('entity_seq'),
14135+
generate_base32_uuid());
14136+
14137+
DELETE
14138+
FROM systemconfigurationvalue
14139+
WHERE category_id = email_configuration_id
14140+
AND config_key = 'EMAIL_SENDER_NAME';
14141+
DELETE
14142+
FROM systemconfigurationvalue_history
14143+
WHERE category_id = email_configuration_id
14144+
AND config_key = 'EMAIL_SENDER_NAME';
14145+
INSERT INTO systemconfigurationvalue(config_key, config_value, category_id, value_optional, value_pattern,
14146+
value_encrypt, data_provider, validation_message, changedate, creationdate, id,
14147+
uuid)
14148+
VALUES ('EMAIL_SENDER_NAME', 'SORMAS Support', email_configuration_id, true, '^[A-Za-z]+( [A-Za-z]+)*$', false, null,
14149+
'i18n/systemConfigurationValueValidationNotAValidEmailsenderName', now(), now(), nextval('entity_seq'),
14150+
generate_base32_uuid());
14151+
14152+
14153+
DELETE
14154+
FROM systemconfigurationvalue
14155+
WHERE category_id = sms_configuration_id
14156+
AND config_key = 'SMS_SENDER_NAME';
14157+
DELETE
14158+
FROM systemconfigurationvalue_history
14159+
WHERE category_id = sms_configuration_id
14160+
AND config_key = 'SMS_SENDER_NAME';
14161+
INSERT INTO systemconfigurationvalue(config_key, config_value, category_id, value_optional, value_pattern,
14162+
value_encrypt, data_provider, validation_message, changedate, creationdate, id,
14163+
uuid)
14164+
VALUES ('SMS_SENDER_NAME', '', sms_configuration_id, true,
14165+
'^(([1-9]{2}[0-9]{0,13})|([A-Za-z1-9]{1}[A-Za-z0-9]{0,10}))$', false, null,
14166+
'i18n/systemConfigurationValueValidationNotAValidSmsSenderName', now(), now(), nextval('entity_seq'),
14167+
generate_base32_uuid());
14168+
14169+
DELETE
14170+
FROM systemconfigurationvalue
14171+
WHERE category_id = sms_configuration_id
14172+
AND config_key = 'SMS_AUTH_KEY';
14173+
DELETE
14174+
FROM systemconfigurationvalue_history
14175+
WHERE category_id = sms_configuration_id
14176+
AND config_key = 'SMS_AUTH_KEY';
14177+
INSERT INTO systemconfigurationvalue(config_key, config_value, category_id, value_optional, value_pattern,
14178+
value_encrypt, data_provider, validation_message, changedate, creationdate, id,
14179+
uuid)
14180+
VALUES ('SMS_AUTH_KEY', '', sms_configuration_id, true, '\s*[^\s]+', false, null, 'i18n/smsAuthKeyValueValidation',
14181+
now(), now(), nextval('entity_seq'), generate_base32_uuid());
14182+
14183+
DELETE
14184+
FROM systemconfigurationvalue
14185+
WHERE category_id = sms_configuration_id
14186+
AND config_key = 'SMS_AUTH_SECRET';
14187+
DELETE
14188+
FROM systemconfigurationvalue_history
14189+
WHERE category_id = sms_configuration_id
14190+
AND config_key = 'SMS_AUTH_SECRET';
14191+
INSERT INTO systemconfigurationvalue(config_key, config_value, category_id, value_optional, value_pattern,
14192+
value_encrypt, data_provider, validation_message, changedate, creationdate, id,
14193+
uuid)
14194+
VALUES ('SMS_AUTH_SECRET', '', sms_configuration_id, true, '(?i)(secret|password|token|api[_-]?key)\s*[:=]\s*[^\s]+',
14195+
false, null, 'i18n/smsAuthSecretValueValidation', now(), now(), nextval('entity_seq'), generate_base32_uuid());
14196+
END $$
14197+
LANGUAGE plpgsql;
14198+
14199+
INSERT INTO schema_version (version_number, comment) VALUES (569, 'Moving Email & SMS properties to the new system configuration structure #13311');
1408814200
-- *** Insert new sql commands BEFORE this line. Remember to always consider _history tables. ***

sormas-backend/src/test/java/de/symeda/sormas/backend/AbstractBeanTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ public SystemConfigurationCategoryService getSystemConfigurationCategoryService(
11331133
}
11341134

11351135
public SystemConfigurationValueFacade getSystemConfigurationValueFacade() {
1136-
return getBean(SystemConfigurationValueEjb.SystemConfigurationValueEjbLocal.class);
1136+
return getBean(SystemConfigurationValueEjb.class);
11371137
}
11381138

11391139
public SystemConfigurationValueService getSystemConfigurationValueService() {

sormas-backend/src/test/java/de/symeda/sormas/backend/systemconfiguration/SystemConfigurationValueFacadeEJbTest.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import de.symeda.sormas.api.utils.DataHelper;
2626
import de.symeda.sormas.api.utils.ValidationRuntimeException;
2727
import de.symeda.sormas.backend.AbstractBeanTest;
28+
import org.junit.jupiter.params.ParameterizedTest;
29+
import org.junit.jupiter.params.provider.CsvSource;
2830

2931
class SystemConfigurationValueFacadeEJbTest extends AbstractBeanTest {
3032

@@ -223,6 +225,59 @@ void testValidateSystemConfigurationValuePipeSeparatedWordsPatternFail() {
223225
});
224226
}
225227

228+
/**
229+
* Test the validation of a system configuration value against a pattern.
230+
*/
231+
@ParameterizedTest
232+
@CsvSource({
233+
"'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$', 192.168.1.1",
234+
"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$, test@sormas.org", // Valid email
235+
"^[A-Za-z]+( [A-Za-z]+)*$, Sormas Support", // Valid email sender name
236+
"'^(([1-9]{2}[0-9]{0,13})|([A-Za-z1-9]{1}[A-Za-z0-9]{0,10}))$', 'abcXYZ123'", // Valid sms sender name as name
237+
"'^(([1-9]{2}[0-9]{0,13})|([A-Za-z1-9]{1}[A-Za-z0-9]{0,10}))$', '12345678901234'", // Valid sms sender as phone number
238+
"'\\s*[^\\s]+', 'abCD12!@efGH34#$'", // Valid Auth Key
239+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'apiKey=sormas2025orgKEY'", // Valid secret api key
240+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'Secret : s3cr3tV@lu3P@ssw0rd!'", // Valid secret key
241+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'token: sormasSecureToken12345678!'" // Valid token key
242+
})
243+
void testValidateSystemConfigurationValuePattern(String pattern, String value) {
244+
245+
final SystemConfigurationValue configValue = createSystemConfigurationValue("VALUE_PATTERN_KEY", value, pattern);
246+
final SystemConfigurationValueDto configValueDto = getSystemConfigurationValueFacade().getByUuid(configValue.getUuid());
247+
248+
// Validate against IP pattern
249+
final SystemConfigurationValueDto updatedConfigValue = getSystemConfigurationValueFacade().save(configValueDto);
250+
251+
assertThat(updatedConfigValue.getKey(), is("VALUE_PATTERN_KEY"));
252+
assertThat(updatedConfigValue.getValue(), is(value));
253+
}
254+
255+
/**
256+
* Test the validation of a system configuration value against a pattern with an invalid value.
257+
*/
258+
@ParameterizedTest
259+
@CsvSource({
260+
"'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$', 1.234343.2.3", // invalid IP
261+
"'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$', test.sormas.org", // Invalid email
262+
"'^[A-Za-z]+( [A-Za-z]+)*$', Sormas 123", // Valid email sender name
263+
"'^(([1-9]{2}[0-9]{0,13})|([A-Za-z1-9]{1}[A-Za-z0-9]{0,10}))$', 'abc XYZ123'", // Invalid sms sender name as name
264+
"'^(([1-9]{2}[0-9]{0,13})|([A-Za-z1-9]{1}[A-Za-z0-9]{0,10}))$', 'ABCdefHI055202'", // Invalid sms sender as phone number
265+
"'\\s*[^\\s]+', 'abCD12 !@efG H34#$'", // Valid Auth Key
266+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'apiKey=abcd EFGH1234ijk lMNOP'", // Invalid secret api key
267+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'Secret : s3cr3 tV@lu3P@ ssw0rd!'", // Invalid secret key
268+
"'(?i)(secret|password|token|api[_-]?key)\\s*[:=]\\s*[^\\s]+', 'token: sormasSecu reToken12 345678!'" // Invalid token key
269+
})
270+
void testValidateSystemConfigurationValuePatternFail(String pattern, String value) {
271+
272+
final SystemConfigurationValue configValue = createSystemConfigurationValue("VALUE_PATTERN_KEY", value, pattern);
273+
final SystemConfigurationValueDto configValueDto = getSystemConfigurationValueFacade().getByUuid(configValue.getUuid());
274+
275+
// Validate against pattern and expect exception
276+
assertThrows(ValidationRuntimeException.class, () -> {
277+
getSystemConfigurationValueFacade().save(configValueDto);
278+
});
279+
}
280+
226281
/**
227282
* Test the validation of an optional system configuration value.
228283
*/

0 commit comments

Comments
 (0)