Recipient preview for notification request; template params functions

This commit is contained in:
ViacheslavKlimov 2023-03-22 18:11:54 +02:00
parent 8705a2324e
commit cda1836986
12 changed files with 84 additions and 87 deletions

View File

@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.NotificationId;
import org.thingsboard.server.common.data.id.NotificationRequestId;
@ -38,7 +39,7 @@ import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.Notification;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.service.notification.NotificationProcessingContext;
import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestInfo;
import org.thingsboard.server.common.data.notification.NotificationRequestPreview;
@ -62,8 +63,10 @@ import org.thingsboard.server.service.security.permission.Operation;
import javax.validation.Valid;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@ -196,6 +199,7 @@ public class NotificationController extends BaseController {
@PostMapping("/notification/request/preview")
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
public NotificationRequestPreview getNotificationRequestPreview(@RequestBody @Valid NotificationRequest request,
@RequestParam(defaultValue = "20") int recipientsPreviewSize,
@AuthenticationPrincipal SecurityUser user) throws ThingsboardException {
NotificationRequestPreview preview = new NotificationRequestPreview();
@ -229,18 +233,29 @@ public class NotificationController extends BaseController {
preview.setProcessedTemplates(processedTemplates);
// generic permission
Set<User> recipientsPreview = new LinkedHashSet<>();
Map<String, Integer> recipientsCountByTarget = new HashMap<>();
List<NotificationTarget> targets = notificationTargetService.findNotificationTargetsByTenantIdAndIds(user.getTenantId(),
request.getTargets().stream().map(NotificationTargetId::new).collect(Collectors.toList()));
for (NotificationTarget target : targets) {
int recipientsCount;
if (target.getConfiguration().getType() == NotificationTargetType.PLATFORM_USERS) {
recipientsCount = notificationTargetService.countRecipientsForNotificationTargetConfig(user.getTenantId(), target.getConfiguration());
PageData<User> recipients = notificationTargetService.findRecipientsForNotificationTargetConfig(user.getTenantId(), null,
target.getConfiguration(), new PageLink(recipientsPreviewSize));
recipientsCount = (int) recipients.getTotalElements();
for (User recipient : recipients.getData()) {
if (recipientsPreview.size() < recipientsPreviewSize) {
recipientsPreview.add(recipient);
} else {
break;
}
}
} else {
recipientsCount = 1;
}
recipientsCountByTarget.put(target.getName(), recipientsCount);
}
preview.setRecipientsPreview(recipientsPreview);
preview.setRecipientsCountByTarget(recipientsCountByTarget);
preview.setTotalRecipientsCount(recipientsCountByTarget.values().stream().mapToInt(Integer::intValue).sum());

View File

@ -33,7 +33,6 @@ import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.AlreadySentException;
import org.thingsboard.server.common.data.notification.Notification;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestConfig;
import org.thingsboard.server.common.data.notification.NotificationRequestStats;

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.notification;
package org.thingsboard.server.service.notification;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
@ -25,6 +25,9 @@ import org.apache.commons.lang3.StringUtils;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationRequest;
import org.thingsboard.server.common.data.notification.NotificationRequestStats;
import org.thingsboard.server.common.data.notification.info.NotificationInfo;
import org.thingsboard.server.common.data.notification.info.RuleOriginatedNotificationInfo;
import org.thingsboard.server.common.data.notification.settings.NotificationDeliveryMethodConfig;
@ -40,6 +43,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
@SuppressWarnings("unchecked")
public class NotificationProcessingContext {
@ -58,6 +62,8 @@ public class NotificationProcessingContext {
@Getter
private final NotificationRequestStats stats;
private static final Pattern TEMPLATE_PARAM_PATTERN = Pattern.compile("\\$\\{([a-zA-Z]+)(:[a-zA-Z]+)?}");
@Builder
public NotificationProcessingContext(TenantId tenantId, NotificationRequest request, NotificationSettings settings,
NotificationTemplate template) {
@ -111,7 +117,7 @@ public class NotificationProcessingContext {
}
JsonNode link = buttonConfig.get().get("link");
if (link != null && link.isTextual()) {
link = new TextNode(processTemplate(link.asText(), templateContext).toLowerCase());
link = new TextNode(processTemplate(link.asText(), templateContext));
buttonConfig.get().set("link", link);
}
}
@ -120,19 +126,22 @@ public class NotificationProcessingContext {
}
private static String processTemplate(String template, Map<String, String> context) {
if (template == null) return null;
String result = template;
for (Map.Entry<String, String> kv : context.entrySet()) {
String value = Strings.nullToEmpty(kv.getValue());
result = result.replace("${" + kv.getKey() + '}', value);
}
return result;
}
public static String processTemplate(String template, NotificationInfo notificationInfo) {
if (notificationInfo == null) return template;
Map<String, String> templateContext = notificationInfo.getTemplateData();
return processTemplate(template, templateContext);
return TEMPLATE_PARAM_PATTERN.matcher(template).replaceAll(matchResult -> {
String key = matchResult.group(1);
String value = Strings.nullToEmpty(context.get(key));
String function = matchResult.group(2);
if (function != null) {
switch (function) {
case ":upperCase":
return value.toUpperCase();
case ":lowerCase":
return value.toLowerCase();
case ":capitalize":
return StringUtils.capitalize(value.toLowerCase());
}
}
return value;
});
}
public Map<String, String> createTemplateContext(User recipient) {

View File

@ -23,7 +23,7 @@ import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.template.EmailDeliveryMethodNotificationTemplate;
import org.thingsboard.server.service.mail.MailExecutorService;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.service.notification.NotificationProcessingContext;
@Component
@RequiredArgsConstructor

View File

@ -17,7 +17,7 @@ package org.thingsboard.server.service.notification.channels;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.service.notification.NotificationProcessingContext;
import org.thingsboard.server.common.data.notification.targets.NotificationRecipient;
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;

View File

@ -20,7 +20,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.thingsboard.rule.engine.api.slack.SlackService;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.service.notification.NotificationProcessingContext;
import org.thingsboard.server.common.data.notification.settings.SlackNotificationDeliveryMethodConfig;
import org.thingsboard.server.common.data.notification.targets.slack.SlackConversation;
import org.thingsboard.server.common.data.notification.template.SlackDeliveryMethodNotificationTemplate;

View File

@ -24,7 +24,7 @@ import org.thingsboard.rule.engine.api.SmsService;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.template.SmsDeliveryMethodNotificationTemplate;
import org.thingsboard.server.common.data.notification.NotificationProcessingContext;
import org.thingsboard.server.service.notification.NotificationProcessingContext;
import org.thingsboard.server.service.sms.SmsExecutorService;
@Component

View File

@ -132,7 +132,6 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
notificationTemplate.setName("Notification template: " + text);
notificationTemplate.setNotificationType(notificationType);
NotificationTemplateConfig config = new NotificationTemplateConfig();
config.setDefaultTextTemplate(text);
config.setDeliveryMethodsTemplates(new HashMap<>());
for (NotificationDeliveryMethod deliveryMethod : deliveryMethods) {
DeliveryMethodNotificationTemplate deliveryMethodNotificationTemplate;
@ -157,6 +156,7 @@ public abstract class AbstractNotificationApiTest extends AbstractControllerTest
throw new IllegalArgumentException("Unsupported delivery method " + deliveryMethod);
}
deliveryMethodNotificationTemplate.setEnabled(true);
deliveryMethodNotificationTemplate.setBody(text);
config.getDeliveryMethodsTemplates().put(deliveryMethod, deliveryMethodNotificationTemplate);
}
notificationTemplate.setConfiguration(config);

View File

@ -25,6 +25,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.thingsboard.rule.engine.api.NotificationCenter;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.NotificationTargetId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.notification.Notification;
import org.thingsboard.server.common.data.notification.NotificationDeliveryMethod;
import org.thingsboard.server.common.data.notification.NotificationRequest;
@ -339,6 +340,8 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
target1Config.setUsersFilter(userListFilter);
target1.setConfiguration(target1Config);
target1 = saveNotificationTarget(target1);
List<UserId> recipients = new ArrayList<>();
recipients.add(tenantAdminUserId);
createDifferentCustomer();
loginTenantAdmin();
@ -350,6 +353,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
customerUser.setCustomerId(differentCustomerId);
customerUser.setEmail("other-customer-" + i + "@thingsboard.org");
customerUser = createUser(customerUser, "12345678");
recipients.add(customerUser.getId());
}
NotificationTarget target2 = new NotificationTarget();
target2.setName("Other customer users");
@ -367,27 +371,25 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
String requestorEmail = TENANT_ADMIN_EMAIL;
NotificationTemplateConfig templateConfig = new NotificationTemplateConfig();
templateConfig.setDefaultTextTemplate("Default message for SMS and WEB: ${recipientEmail}");
templateConfig.setNotificationSubject("Default subject for EMAIL: ${recipientEmail}");
HashMap<NotificationDeliveryMethod, DeliveryMethodNotificationTemplate> templates = new HashMap<>();
templateConfig.setDeliveryMethodsTemplates(templates);
notificationTemplate.setConfiguration(templateConfig);
WebDeliveryMethodNotificationTemplate webNotificationTemplate = new WebDeliveryMethodNotificationTemplate();
webNotificationTemplate.setEnabled(true);
// using default message for web
webNotificationTemplate.setBody("Message for WEB: ${recipientEmail}");
webNotificationTemplate.setSubject("Subject for WEB: ${recipientEmail}");
templates.put(NotificationDeliveryMethod.WEB, webNotificationTemplate);
SmsDeliveryMethodNotificationTemplate smsNotificationTemplate = new SmsDeliveryMethodNotificationTemplate();
smsNotificationTemplate.setEnabled(true);
// using default message for sms
smsNotificationTemplate.setBody("Message for SMS: ${recipientEmail}");
templates.put(NotificationDeliveryMethod.SMS, smsNotificationTemplate);
EmailDeliveryMethodNotificationTemplate emailNotificationTemplate = new EmailDeliveryMethodNotificationTemplate();
emailNotificationTemplate.setEnabled(true);
emailNotificationTemplate.setSubject("Subject for EMAIL: ${recipientEmail}");
emailNotificationTemplate.setBody("Message for EMAIL: ${recipientEmail}");
// using default subject for email
templates.put(NotificationDeliveryMethod.EMAIL, emailNotificationTemplate);
SlackDeliveryMethodNotificationTemplate slackNotificationTemplate = new SlackDeliveryMethodNotificationTemplate();
@ -407,12 +409,13 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
assertThat(preview.getRecipientsCountByTarget().get(target1.getName())).isEqualTo(1);
assertThat(preview.getRecipientsCountByTarget().get(target2.getName())).isEqualTo(customerUsersCount);
assertThat(preview.getTotalRecipientsCount()).isEqualTo(1 + customerUsersCount);
assertThat(preview.getRecipientsPreview()).extracting(User::getId).containsAll(recipients);
Map<NotificationDeliveryMethod, DeliveryMethodNotificationTemplate> processedTemplates = preview.getProcessedTemplates();
assertThat(processedTemplates.get(NotificationDeliveryMethod.WEB)).asInstanceOf(type(WebDeliveryMethodNotificationTemplate.class))
.satisfies(template -> {
assertThat(template.getBody())
.startsWith("Default message for SMS and WEB")
.startsWith("Message for WEB")
.endsWith(requestorEmail);
assertThat(template.getSubject())
.startsWith("Subject for WEB")
@ -421,7 +424,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
assertThat(processedTemplates.get(NotificationDeliveryMethod.SMS)).asInstanceOf(type(SmsDeliveryMethodNotificationTemplate.class))
.satisfies(template -> {
assertThat(template.getBody())
.startsWith("Default message for SMS and WEB")
.startsWith("Message for SMS")
.endsWith(requestorEmail);
});
assertThat(processedTemplates.get(NotificationDeliveryMethod.EMAIL)).asInstanceOf(type(EmailDeliveryMethodNotificationTemplate.class))
@ -430,7 +433,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
.startsWith("Message for EMAIL")
.endsWith(requestorEmail);
assertThat(template.getSubject())
.startsWith("Default subject for EMAIL")
.startsWith("Subject for EMAIL")
.endsWith(requestorEmail);
});
assertThat(processedTemplates.get(NotificationDeliveryMethod.SLACK)).asInstanceOf(type(SlackDeliveryMethodNotificationTemplate.class))
@ -534,9 +537,9 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
notificationTemplate.setName("Slack notification template");
notificationTemplate.setNotificationType(NotificationType.GENERAL);
NotificationTemplateConfig config = new NotificationTemplateConfig();
config.setDefaultTextTemplate("To Slack :) ${recipientEmail}");
SlackDeliveryMethodNotificationTemplate slackNotificationTemplate = new SlackDeliveryMethodNotificationTemplate();
slackNotificationTemplate.setEnabled(true);
slackNotificationTemplate.setBody("To Slack :) ${recipientEmail}");
config.setDeliveryMethodsTemplates(Map.of(
NotificationDeliveryMethod.SLACK, slackNotificationTemplate
));
@ -556,7 +559,7 @@ public class NotificationApiTest extends AbstractNotificationApiTest {
NotificationRequest successfulNotificationRequest = submitNotificationRequest(List.of(notificationTarget.getId()), notificationTemplate.getId(), 0);
await().atMost(2, TimeUnit.SECONDS)
.until(() -> findNotificationRequest(successfulNotificationRequest.getId()).isSent());
verify(slackService).sendMessage(eq(tenantId), eq(slackToken), eq(conversationId), eq(config.getDefaultTextTemplate()));
verify(slackService).sendMessage(eq(tenantId), eq(slackToken), eq(conversationId), eq(slackNotificationTemplate.getBody()));
NotificationRequestStats stats = getStats(successfulNotificationRequest.getId());
assertThat(stats.getSent().get(NotificationDeliveryMethod.SLACK)).hasValue(1);

View File

@ -75,6 +75,8 @@ import org.thingsboard.server.common.data.script.ScriptLanguage;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.notification.NotificationRequestService;
import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.service.DaoSqlTest;
import org.thingsboard.server.service.telemetry.AlarmSubscriptionService;
@ -103,6 +105,10 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
private AlarmSubscriptionService alarmSubscriptionService;
@Autowired
private NotificationRequestService notificationRequestService;
@Autowired
private NotificationRuleService notificationRuleService;
@Autowired
private NotificationTemplateService notificationTemplateService;
@SpyBean
private AlarmService alarmService;
@ -110,7 +116,8 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
@Before
public void beforeEach() throws Exception {
loginTenantAdmin();
notificationRuleService.deleteNotificationRulesByTenantId(tenantId);
notificationTemplateService.deleteNotificationTemplatesByTenantId(tenantId);
}
@Test
@ -226,7 +233,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
assertThat(actualDelay).isCloseTo(expectedDelay, offset(0.5));
AlarmStatus expectedStatus = AlarmStatus.ACTIVE_UNACK;
AlarmSeverity expectedSeverity = AlarmSeverity.CRITICAL;
String expectedSeverity = AlarmSeverity.CRITICAL.toString().toLowerCase();
assertThat(notification.getSubject()).isEqualTo("Alarm type: " + alarmType + ", status: " + expectedStatus + ", " +
"severity: " + expectedSeverity + ", deviceId: " + device.getId());
@ -304,7 +311,7 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
getWsClient().waitForUpdate(true);
Notification notification = getWsClient().getLastDataUpdate().getUpdate();
assertThat(notification.getSubject()).isEqualTo("CRITICAL alarm '" + alarmType + "' is ACTIVE_UNACK");
assertThat(notification.getSubject()).isEqualTo("critical alarm '" + alarmType + "' is ACTIVE_UNACK");
assertThat(notification.getInfo()).asInstanceOf(type(AlarmNotificationInfo.class))
.extracting(AlarmNotificationInfo::getAlarmId).isEqualTo(alarm.getUuidId());
@ -323,48 +330,6 @@ public class NotificationRuleApiTest extends AbstractNotificationApiTest {
assertThat(findNotificationRequests(EntityType.ALARM).getData()).filteredOn(NotificationRequest::isScheduled).isEmpty();
}
@Test
public void testNotificationRuleProcessing_ruleEngineComponentLifecycleEvent_ruleNodeStartError() {
String subject = "Rule Node '${componentName}' in Rule Chain '${ruleChainName}' failed to start";
String text = "The error: ${error}";
NotificationTemplate template = createNotificationTemplate(NotificationType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT, subject, text, NotificationDeliveryMethod.WEB);
NotificationRule rule = new NotificationRule();
rule.setName("Rule node start-up failures in my rule chain");
rule.setTemplateId(template.getId());
rule.setTriggerType(NotificationRuleTriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT);
RuleChain ruleChain = createEmptyRuleChain("My Rule Chain");
var triggerConfig = new RuleEngineComponentLifecycleEventNotificationRuleTriggerConfig();
triggerConfig.setRuleChains(Set.of(ruleChain.getUuidId()));
triggerConfig.setRuleChainEvents(Set.of(ComponentLifecycleEvent.STARTED));
triggerConfig.setOnlyRuleChainLifecycleFailures(true);
triggerConfig.setTrackRuleNodeEvents(true);
triggerConfig.setRuleNodeEvents(Set.of(ComponentLifecycleEvent.STARTED));
triggerConfig.setOnlyRuleNodeLifecycleFailures(true);
rule.setTriggerConfig(triggerConfig);
NotificationTarget target = createNotificationTarget(tenantAdminUserId);
DefaultNotificationRuleRecipientsConfig recipientsConfig = new DefaultNotificationRuleRecipientsConfig();
recipientsConfig.setTriggerType(NotificationRuleTriggerType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT);
recipientsConfig.setTargets(List.of(target.getUuidId()));
rule.setRecipientsConfig(recipientsConfig);
rule = saveNotificationRule(rule);
getWsClient().subscribeForUnreadNotifications(10).waitForReply(true);
getWsClient().registerWaitForUpdate();
addRuleNodeWithError(ruleChain.getId(), "My generator");
getWsClient().waitForUpdate(10000, true);
Notification notification = getWsClient().getLastDataUpdate().getUpdate();
assertThat(notification.getType()).isEqualTo(NotificationType.RULE_ENGINE_COMPONENT_LIFECYCLE_EVENT);
assertThat(notification.getSubject()).isEqualTo("Rule Node 'My generator' in Rule Chain 'My Rule Chain' failed to start");
assertThat(notification.getText()).startsWith("The error: Can't compile script");
}
@Test
public void testNotificationRuleInfo() throws Exception {
NotificationDeliveryMethod[] deliveryMethods = {NotificationDeliveryMethod.WEB, NotificationDeliveryMethod.EMAIL};

View File

@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.ResultMatcher;
import org.thingsboard.server.common.data.id.IdBased;
@ -29,6 +30,8 @@ import org.thingsboard.server.common.data.notification.template.NotificationTemp
import org.thingsboard.server.common.data.notification.template.NotificationTemplateConfig;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.notification.NotificationRuleService;
import org.thingsboard.server.dao.notification.NotificationTemplateService;
import org.thingsboard.server.dao.service.DaoSqlTest;
import java.util.List;
@ -40,9 +43,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@DaoSqlTest
public class NotificationTemplateApiTest extends AbstractNotificationApiTest {
@Autowired
private NotificationTemplateService templateService;
@Autowired
private NotificationRuleService notificationRuleService;
@Before
public void beforeEach() throws Exception {
loginTenantAdmin();
notificationRuleService.deleteNotificationRulesByTenantId(tenantId);
templateService.deleteNotificationTemplatesByTenantId(tenantId);
}
@Test
@ -61,8 +71,6 @@ public class NotificationTemplateApiTest extends AbstractNotificationApiTest {
NotificationTemplateConfig config = new NotificationTemplateConfig();
notificationTemplate.setConfiguration(config);
config.setDefaultTextTemplate("Default text");
config.setNotificationSubject(null);
EmailDeliveryMethodNotificationTemplate emailTemplate = new EmailDeliveryMethodNotificationTemplate();
emailTemplate.setEnabled(true);
emailTemplate.setBody(null);
@ -74,14 +82,9 @@ public class NotificationTemplateApiTest extends AbstractNotificationApiTest {
validationError = saveAndGetError(notificationTemplate, status().isBadRequest());
assertThat(validationError)
.contains("notificationSubject must be")
.contains("subject must not be")
.contains("body must not be")
.contains("name is malformed");
config.setDefaultTextTemplate(null);
validationError = saveAndGetError(notificationTemplate, status().isBadRequest());
assertThat(validationError)
.contains("defaultTextTemplate").contains("must be specified");
}
@Test

View File

@ -16,8 +16,10 @@
package org.thingsboard.server.common.data.notification;
import lombok.Data;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.notification.template.DeliveryMethodNotificationTemplate;
import java.util.Collection;
import java.util.Map;
@Data
@ -26,5 +28,6 @@ public class NotificationRequestPreview {
private Map<NotificationDeliveryMethod, DeliveryMethodNotificationTemplate> processedTemplates;
private int totalRecipientsCount;
private Map<String, Integer> recipientsCountByTarget;
private Collection<User> recipientsPreview;
}