Skip to content

Commit

Permalink
merge: #9193
Browse files Browse the repository at this point in the history
9193: [Backport stable/8.0] Check for message names being null during validation r=pihme a=github-actions[bot]

# Description
Backport of #9164 to `stable/8.0`.

relates to #9083

Co-authored-by: pihme <pihme@users.noreply.github.com>
  • Loading branch information
zeebe-bors-camunda[bot] and pihme committed Apr 21, 2022
2 parents ad802a9 + 5f81d81 commit 85bd4b3
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 67 deletions.
6 changes: 6 additions & 0 deletions engine/pom.xml
Expand Up @@ -129,6 +129,12 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
Expand Down
Expand Up @@ -57,6 +57,10 @@ private void validateMessageName(
return;
}
final String nameExpression = message.getName();
if (nameExpression == null) {
// no need to add an error, this case was already handled by MessageValidator
return;
}
final Expression parseResult = expressionLanguage.parseExpression(nameExpression);

final EvaluationResult evaluationResult =
Expand Down
Expand Up @@ -7,6 +7,8 @@
*/
package io.camunda.zeebe.engine.processing.deployment.model.validation;

import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
Expand All @@ -15,90 +17,108 @@
import io.camunda.zeebe.el.Expression;
import io.camunda.zeebe.el.ExpressionLanguage;
import io.camunda.zeebe.el.ResultType;
import io.camunda.zeebe.el.impl.FeelExpressionLanguage;
import io.camunda.zeebe.model.bpmn.Bpmn;
import io.camunda.zeebe.model.bpmn.BpmnModelInstance;
import io.camunda.zeebe.model.bpmn.instance.StartEvent;
import io.camunda.zeebe.util.sched.clock.ActorClock;
import org.camunda.bpm.model.xml.validation.ValidationResultCollector;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;

@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
public class ProcessMessageStartEventMessageNameValidatorTest {

private static final String TEST_EXPRESSION = "expression";

private static final BpmnModelInstance MODEL =
Bpmn.createProcess().startEvent().message(TEST_EXPRESSION).endEvent().done();

private static final StartEvent START_EVENT =
MODEL.getModelElementsByType(StartEvent.class).iterator().next();

@Mock ExpressionLanguage mockExpressionLanguage;

@Mock Expression mockExpression;

@Mock EvaluationResult mockResult;

@Mock ValidationResultCollector mockResultCollector;

ProcessMessageStartEventMessageNameValidator sutValidator;

@Before
public void setUp() {
when(mockExpressionLanguage.parseExpression(TEST_EXPRESSION)).thenReturn(mockExpression);

when(mockExpressionLanguage.evaluateExpression(Mockito.eq(mockExpression), Mockito.any()))
.thenReturn(mockResult);

sutValidator = new ProcessMessageStartEventMessageNameValidator(mockExpressionLanguage);
}

@Test
public void shouldLetValidMessageNameExpressionsPass() {
@Test // regression test for #9083
void shouldNotThrowNPEIfMessageNameIsNull() {
// given
when(mockResult.isFailure()).thenReturn(false);
when(mockResult.getType()).thenReturn(ResultType.STRING);
final var model = Bpmn.createProcess().startEvent().message((String) null).endEvent().done();

// when
sutValidator.validate(START_EVENT, mockResultCollector);
final var startEvent = model.getModelElementsByType(StartEvent.class).iterator().next();

// then
verifyNoInteractions(mockResultCollector);
}

@Test
public void shoulAddErrorIfEvaluationFailed() {
// given
when(mockResult.isFailure()).thenReturn(true);
when(mockResult.getFailureMessage()).thenReturn("Test failure message");
final var sutValidator =
new ProcessMessageStartEventMessageNameValidator(
new FeelExpressionLanguage(ActorClock.current()));

// when
sutValidator.validate(START_EVENT, mockResultCollector);

// then
verify(mockResultCollector)
.addError(
0,
"Expected constant expression but found 'expression', which could not be evaluated without context: Test failure message");
assertThatNoException()
.isThrownBy(() -> sutValidator.validate(startEvent, mockResultCollector));
}

@Test
public void shoulAddErrorIfEvaluationDoesNotReturnString() {
// given
when(mockResult.isFailure()).thenReturn(false);
when(mockResult.getType()).thenReturn(ResultType.NUMBER);

// when
sutValidator.validate(START_EVENT, mockResultCollector);

// then
verify(mockResultCollector)
.addError(
0,
"Expected constant expression of type String for message name 'expression', but was NUMBER");
@Nested
final class WithMockedExpressionLanguage {

private static final String TEST_EXPRESSION = "expression";
private static final BpmnModelInstance MODEL =
Bpmn.createProcess().startEvent().message(TEST_EXPRESSION).endEvent().done();
private static final StartEvent START_EVENT =
MODEL.getModelElementsByType(StartEvent.class).iterator().next();
@Mock ExpressionLanguage mockExpressionLanguage;
@Mock Expression mockExpression;
@Mock EvaluationResult mockResult;

ProcessMessageStartEventMessageNameValidator sutValidator;

@BeforeEach
void setUp() {
when(mockExpressionLanguage.parseExpression(TEST_EXPRESSION)).thenReturn(mockExpression);

when(mockExpressionLanguage.evaluateExpression(eq(mockExpression), Mockito.any()))
.thenReturn(mockResult);

sutValidator = new ProcessMessageStartEventMessageNameValidator(mockExpressionLanguage);
}

@Test
void shouldLetValidMessageNameExpressionsPass() {
// given
when(mockResult.isFailure()).thenReturn(false);
when(mockResult.getType()).thenReturn(ResultType.STRING);

// when
sutValidator.validate(START_EVENT, mockResultCollector);

// then
verifyNoInteractions(mockResultCollector);
}

@Test
void shouldAddErrorIfEvaluationFailed() {
// given
when(mockResult.isFailure()).thenReturn(true);
when(mockResult.getFailureMessage()).thenReturn("Test failure message");

// when
sutValidator.validate(START_EVENT, mockResultCollector);

// then
verify(mockResultCollector)
.addError(
0,
"Expected constant expression but found 'expression', which could not be evaluated without context: Test failure message");
}

@Test
void shouldAddErrorIfEvaluationDoesNotReturnString() {
// given
when(mockResult.isFailure()).thenReturn(false);
when(mockResult.getType()).thenReturn(ResultType.NUMBER);

// when
sutValidator.validate(START_EVENT, mockResultCollector);

// then
verify(mockResultCollector)
.addError(
0,
"Expected constant expression of type String for message name 'expression', but was NUMBER");
}
}
}

0 comments on commit 85bd4b3

Please sign in to comment.