Skip to content

Commit b226060

Browse files
committed
fixes and tests
Signed-off-by: Mark Herwege <mark.herwege@telenet.be>
1 parent e24fb1f commit b226060

11 files changed

Lines changed: 317 additions & 77 deletions

File tree

bundles/org.openhab.core.io.rest.sitemap/src/test/java/org/openhab/core/io/rest/sitemap/internal/SitemapResourceTest.java

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public class SitemapResourceTest extends JavaTest {
9090
private static final String VALUE_COLOR_ITEM_NAME = "valueColorItemName";
9191
private static final String ICON_COLOR_ITEM_NAME = "iconColorItemName";
9292
private static final String ICON_ITEM_NAME = "iconItemName";
93+
private static final String CONFIRM_CMD_ITEM_NAME = "confirmCmdItemName";
9394
private static final String WIDGET1_LABEL = "widget 1";
9495
private static final String WIDGET3_LABEL = "widget 3";
9596
private static final String GROUP_LABEL = "frame";
@@ -114,6 +115,7 @@ public class SitemapResourceTest extends JavaTest {
114115
private @NonNullByDefault({}) GenericItem valueColorItem;
115116
private @NonNullByDefault({}) GenericItem iconColorItem;
116117
private @NonNullByDefault({}) GenericItem iconItem;
118+
private @NonNullByDefault({}) GenericItem confirmCmdItem;
117119

118120
private @Mock @NonNullByDefault({}) HttpHeaders headersMock;
119121
private @Mock @NonNullByDefault({}) Sitemap defaultSitemapMock;
@@ -150,6 +152,7 @@ public void setup() throws Exception {
150152
valueColorItem = new TestItem(VALUE_COLOR_ITEM_NAME);
151153
iconColorItem = new TestItem(ICON_COLOR_ITEM_NAME);
152154
iconItem = new TestItem(ICON_ITEM_NAME);
155+
confirmCmdItem = new TestItem(CONFIRM_CMD_ITEM_NAME);
153156

154157
when(localeServiceMock.getLocale(null)).thenReturn(Locale.US);
155158

@@ -406,6 +409,22 @@ public void whenLongPollingShouldObserveItemsFromIconConditions() {
406409
assertThat(pageDTO.timeout, is(false));
407410
}
408411

412+
@Test
413+
public void whenLongPollingShouldObserveItemsFromConfirmCmdConditions() {
414+
ItemEvent itemEvent = mock(ItemEvent.class);
415+
when(itemEvent.getItemName()).thenReturn(confirmCmdItem.getName());
416+
executeWithDelay(() -> sitemapResource.receive(itemEvent));
417+
418+
// non-null is sufficient here.
419+
when(headersMock.getRequestHeader(HTTP_HEADER_X_ATMOSPHERE_TRANSPORT)).thenReturn(List.of());
420+
421+
Response response = sitemapResource.getPageData(headersMock, null, SITEMAP_NAME, SITEMAP_NAME, null, false);
422+
423+
PageDTO pageDTO = (PageDTO) response.getEntity();
424+
// assert that the item state change did trigger the blocking method to return
425+
assertThat(pageDTO.timeout, is(false));
426+
}
427+
409428
private static void executeWithDelay(Runnable executionWithDelay) {
410429
new Thread(() -> {
411430
try {
@@ -515,6 +534,7 @@ private void configureCommonUIRegistryMockMethods() throws ItemNotFoundException
515534
when(itemUIRegistryMock.getItem(VALUE_COLOR_ITEM_NAME)).thenReturn(valueColorItem);
516535
when(itemUIRegistryMock.getItem(ICON_COLOR_ITEM_NAME)).thenReturn(iconColorItem);
517536
when(itemUIRegistryMock.getItem(ICON_ITEM_NAME)).thenReturn(iconItem);
537+
when(itemUIRegistryMock.getItem(CONFIRM_CMD_ITEM_NAME)).thenReturn(confirmCmdItem);
518538
}
519539

520540
private void configureWidgetStatesPage1(State state1, State state2) {
@@ -560,73 +580,84 @@ private List<Widget> initSitemapWidgets() {
560580
// add icon rules to the mock widget:
561581
Class<Rule> classToMock = Rule.class;
562582
Rule iconRule = mock(classToMock);
563-
Condition conditon0 = mock(Condition.class);
564-
when(conditon0.getItem()).thenReturn(ICON_ITEM_NAME);
583+
Condition condition0 = mock(Condition.class);
584+
when(condition0.getItem()).thenReturn(ICON_ITEM_NAME);
565585
List<Condition> conditions0 = new ArrayList<>();
566-
conditions0.add(conditon0);
586+
conditions0.add(condition0);
567587
when(iconRule.getConditions()).thenReturn(conditions0);
568588
List<Rule> iconRulesW1 = new ArrayList<>();
569589
iconRulesW1.add(iconRule);
570590

571591
// add visibility rules to the mock widget:
572592
Rule visibilityRule = mock(Rule.class);
573-
Condition conditon = mock(Condition.class);
574-
when(conditon.getItem()).thenReturn(VISIBILITY_RULE_ITEM_NAME);
593+
Condition condition = mock(Condition.class);
594+
when(condition.getItem()).thenReturn(VISIBILITY_RULE_ITEM_NAME);
575595
List<Condition> conditions = new ArrayList<>();
576-
conditions.add(conditon);
596+
conditions.add(condition);
577597
when(visibilityRule.getConditions()).thenReturn(conditions);
578598
List<Rule> visibilityRulesW1 = new ArrayList<>(1);
579599
visibilityRulesW1.add(visibilityRule);
580600

581601
// add label color conditions to the item:
582602
Rule labelColor = mock(Rule.class);
583-
Condition conditon1 = mock(Condition.class);
584-
when(conditon1.getItem()).thenReturn(LABEL_COLOR_ITEM_NAME);
603+
Condition condition1 = mock(Condition.class);
604+
when(condition1.getItem()).thenReturn(LABEL_COLOR_ITEM_NAME);
585605
List<Condition> conditions1 = new ArrayList<>();
586-
conditions1.add(conditon1);
606+
conditions1.add(condition1);
587607
when(labelColor.getConditions()).thenReturn(conditions1);
588608
List<Rule> labelColorsW1 = new ArrayList<>();
589609
labelColorsW1.add(labelColor);
590610

591611
// add value color conditions to the item:
592612
Rule valueColor = mock(Rule.class);
593-
Condition conditon2 = mock(Condition.class);
594-
when(conditon2.getItem()).thenReturn(VALUE_COLOR_ITEM_NAME);
613+
Condition condition2 = mock(Condition.class);
614+
when(condition2.getItem()).thenReturn(VALUE_COLOR_ITEM_NAME);
595615
List<Condition> conditions2 = new ArrayList<>();
596-
conditions2.add(conditon2);
616+
conditions2.add(condition2);
597617
when(valueColor.getConditions()).thenReturn(conditions2);
598618
List<Rule> valueColorsW1 = new ArrayList<>();
599619
valueColorsW1.add(valueColor);
600620

601621
// add icon color conditions to the item:
602622
Rule iconColor = mock(Rule.class);
603-
Condition conditon3 = mock(Condition.class);
604-
when(conditon3.getItem()).thenReturn(ICON_COLOR_ITEM_NAME);
623+
Condition condition3 = mock(Condition.class);
624+
when(condition3.getItem()).thenReturn(ICON_COLOR_ITEM_NAME);
605625
List<Condition> conditions3 = new ArrayList<>();
606-
conditions3.add(conditon3);
626+
conditions3.add(condition3);
607627
when(iconColor.getConditions()).thenReturn(conditions3);
608628
List<Rule> iconColorsW1 = new ArrayList<>();
609629
iconColorsW1.add(iconColor);
610630

631+
// add confirm command conditions to the item:
632+
Rule confirmCmd = mock(Rule.class);
633+
Condition conditon4 = mock(Condition.class);
634+
when(conditon4.getItem()).thenReturn(CONFIRM_CMD_ITEM_NAME);
635+
List<Condition> conditions4 = new ArrayList<>();
636+
conditions4.add(conditon4);
637+
when(confirmCmd.getConditions()).thenReturn(conditions4);
638+
List<Rule> confirmCmdRulesW1 = new ArrayList<>();
639+
confirmCmdRulesW1.add(confirmCmd);
640+
611641
String sliderType = "Slider";
612642

613-
Widget w1 = mockWidget(iconRulesW1, visibilityRulesW1, labelColorsW1, valueColorsW1, iconColorsW1, sliderType,
614-
WIDGET1_LABEL, null, false);
643+
Widget w1 = mockWidget(iconRulesW1, visibilityRulesW1, labelColorsW1, valueColorsW1, iconColorsW1,
644+
confirmCmdRulesW1, sliderType, WIDGET1_LABEL, null, false);
615645

616646
List<Rule> iconRules = new ArrayList<>();
617647
List<Rule> visibilityRules = new ArrayList<>();
618648
List<Rule> labelColors = new ArrayList<>();
619649
List<Rule> valueColors = new ArrayList<>();
620650
List<Rule> iconColors = new ArrayList<>();
651+
List<Rule> confirmCmdRules = new ArrayList<>();
621652

622653
String switchType = "Switch";
623654

624-
Widget w2 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, switchType, null,
625-
WIDGET2_ICON, false);
655+
Widget w2 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, confirmCmdRules,
656+
switchType, null, WIDGET2_ICON, false);
626657
mock(Widget.class);
627658

628-
Widget w3 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, switchType,
629-
WIDGET3_LABEL, WIDGET3_ICON, true);
659+
Widget w3 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, confirmCmdRules,
660+
switchType, WIDGET3_LABEL, WIDGET3_ICON, true);
630661

631662
List<Widget> widgets = new ArrayList<>(3);
632663
widgets.add(w1);
@@ -645,17 +676,18 @@ private List<Widget> initSitemapWidgetsWithSubpages() {
645676
List<Rule> labelColors = new ArrayList<>();
646677
List<Rule> valueColors = new ArrayList<>();
647678
List<Rule> iconColors = new ArrayList<>();
679+
List<Rule> confirmCmdRules = new ArrayList<>();
648680

649-
Widget group1 = mockGroup(iconRules, visibilityRules, labelColors, valueColors, iconColors, groupType,
650-
GROUP_LABEL, GROUP_ICON, true, baseWidgets);
681+
Widget group1 = mockGroup(iconRules, visibilityRules, labelColors, valueColors, iconColors, confirmCmdRules,
682+
groupType, GROUP_LABEL, GROUP_ICON, true, baseWidgets);
651683

652684
String switchType = "Switch";
653685

654-
Widget w4 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, switchType,
655-
WIDGET4_LABEL, WIDGET4_ICON, true);
686+
Widget w4 = mockWidget(iconRules, visibilityRules, labelColors, valueColors, iconColors, confirmCmdRules,
687+
switchType, WIDGET4_LABEL, WIDGET4_ICON, true);
656688

657-
Widget group2 = mockGroup(iconRules, visibilityRules, labelColors, valueColors, iconColors, groupType,
658-
GROUP_LABEL, GROUP_ICON, true, new ArrayList<>(List.of(w4)));
689+
Widget group2 = mockGroup(iconRules, visibilityRules, labelColors, valueColors, iconColors, confirmCmdRules,
690+
groupType, GROUP_LABEL, GROUP_ICON, true, new ArrayList<>(List.of(w4)));
659691

660692
List<Widget> allWidgets = new ArrayList<>();
661693
allWidgets.add(group1);
@@ -666,28 +698,28 @@ private List<Widget> initSitemapWidgetsWithSubpages() {
666698
}
667699

668700
private static Widget mockWidget(List<Rule> iconRules1, List<Rule> visibilityRules1, List<Rule> labelColors1,
669-
List<Rule> valueColors1, List<Rule> iconColors1, String widgetType, String widgetLabel, String widgetIcon,
670-
boolean widgetStaticIcon) {
701+
List<Rule> valueColors1, List<Rule> iconColors1, List<Rule> confirmCmdRules1, String widgetType,
702+
String widgetLabel, String widgetIcon, boolean widgetStaticIcon) {
671703
Widget w = mock(Widget.class);
672-
mockWidgetMethods(iconRules1, visibilityRules1, labelColors1, valueColors1, iconColors1, widgetType,
673-
widgetLabel, widgetIcon, widgetStaticIcon, w);
704+
mockWidgetMethods(iconRules1, visibilityRules1, labelColors1, valueColors1, iconColors1, confirmCmdRules1,
705+
widgetType, widgetLabel, widgetIcon, widgetStaticIcon, w);
674706
when(w.getItem()).thenReturn(ITEM_NAME);
675707
return w;
676708
}
677709

678710
private static Group mockGroup(List<Rule> iconRules1, List<Rule> visibilityRules1, List<Rule> labelColors1,
679-
List<Rule> valueColors1, List<Rule> iconColors1, String widgetType, String widgetLabel, String widgetIcon,
680-
boolean widgetStaticIcon, List<Widget> children) {
711+
List<Rule> valueColors1, List<Rule> iconColors1, List<Rule> confirmCmdRules1, String widgetType,
712+
String widgetLabel, String widgetIcon, boolean widgetStaticIcon, List<Widget> children) {
681713
Group w = mock(Group.class);
682-
mockWidgetMethods(iconRules1, visibilityRules1, labelColors1, valueColors1, iconColors1, widgetType,
683-
widgetLabel, widgetIcon, widgetStaticIcon, w);
714+
mockWidgetMethods(iconRules1, visibilityRules1, labelColors1, valueColors1, iconColors1, confirmCmdRules1,
715+
widgetType, widgetLabel, widgetIcon, widgetStaticIcon, w);
684716
when(w.getWidgets()).thenReturn(children);
685717
return w;
686718
}
687719

688720
private static void mockWidgetMethods(List<Rule> iconRules1, List<Rule> visibilityRules1, List<Rule> labelColors1,
689-
List<Rule> valueColors1, List<Rule> iconColors1, String widgetType, String widgetLabel, String widgetIcon,
690-
boolean widgetStaticIcon, Widget w) {
721+
List<Rule> valueColors1, List<Rule> iconColors1, List<Rule> confirmCmdRules1, String widgetType,
722+
String widgetLabel, String widgetIcon, boolean widgetStaticIcon, Widget w) {
691723
when(w.getWidgetType()).thenReturn(widgetType);
692724
when(w.getLabel()).thenReturn(widgetLabel);
693725
when(w.getIcon()).thenReturn(widgetIcon);
@@ -697,6 +729,7 @@ private static void mockWidgetMethods(List<Rule> iconRules1, List<Rule> visibili
697729
when(w.getLabelColor()).thenReturn(labelColors1);
698730
when(w.getValueColor()).thenReturn(valueColors1);
699731
when(w.getIconColor()).thenReturn(iconColors1);
732+
when(w.getConfirmCmdRules()).thenReturn(confirmCmdRules1);
700733
}
701734

702735
private void configureSitemapMock() {

bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/sitemaps/YamlConditionDTO.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ public YamlConditionDTO() {
3737
}
3838

3939
public boolean isValid(@NonNull List<@NonNull String> errors, @NonNull List<@NonNull String> warnings) {
40+
if (item == null && operator == null && argument == null) {
41+
return true; // empty condition may be valid when there is a rule value, condition will be ignored for rule
42+
// with unique condition
43+
}
4044
boolean ok = true;
4145
if (item != null && !ItemUtil.isValidItemName(item)) {
4246
addToList(errors,
@@ -48,7 +52,7 @@ public boolean isValid(@NonNull List<@NonNull String> errors, @NonNull List<@Non
4852
addToList(errors, "invalid value \"%s\" for \"operator\" field in condition".formatted(operator));
4953
ok = false;
5054
}
51-
if ((item != null || operator != null) && argument == null) {
55+
if (argument == null) {
5256
addToList(errors, "\"argument\" field missing while mandatory in condition");
5357
ok = false;
5458
}

bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/sitemaps/YamlSitemapDTO.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ private void addToList(@Nullable List<@NonNull String> list, String value) {
293293

294294
private @NonNull Object toRuleDto(@NonNull JsonNode ruleNode) throws SerializationException {
295295
JsonNode conditionsNode, conditionNode;
296+
if (ruleNode.isTextual()) {
297+
return ruleNode.asText();
298+
}
296299
if (!ruleNode.isObject()) {
297300
throw new SerializationException("Expected rule to be an object node");
298301
}

bundles/org.openhab.core.model.yaml/src/main/java/org/openhab/core/model/yaml/internal/sitemaps/YamlSitemapProvider.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,11 @@ private void addWidgetMappings(List<Mapping> mappings, @Nullable List<YamlMappin
338338

339339
private void addWidgetRules(List<Rule> rules, @Nullable Object rulesDTO, boolean ignoreValue) {
340340
if (rulesDTO instanceof String value) {
341-
Rule rule = sitemapFactory.createRule();
342341
if (!ignoreValue) {
342+
Rule rule = sitemapFactory.createRule();
343343
rule.setArgument(value);
344+
rules.add(rule);
344345
}
345-
rules.add(rule);
346346
} else if (rulesDTO instanceof YamlRuleWithAndConditionsDTO ruleDTO) {
347347
Rule rule = sitemapFactory.createRule();
348348
addRuleConditions(rule.getConditions(), ruleDTO.and);
@@ -385,6 +385,9 @@ private void addWidgetRules(List<Rule> rules, @Nullable Object rulesDTO, boolean
385385
private void addRuleConditions(List<Condition> conditions, @Nullable List<YamlConditionDTO> conditionsDTO) {
386386
if (conditionsDTO != null) {
387387
conditionsDTO.forEach(dto -> {
388+
if (dto.item == null && dto.operator == null && dto.argument == null) {
389+
return; // empty condition is ignored
390+
}
388391
Condition condition = sitemapFactory.createCondition();
389392
condition.setItem(dto.item);
390393
condition.setCondition(dto.operator);

0 commit comments

Comments
 (0)