Skip to content

Commit

Permalink
Add checkFalse and checkTrue for assertions to replace checkBoolean
Browse files Browse the repository at this point in the history
  • Loading branch information
en-milie committed Nov 14, 2023
1 parent 0dcedc8 commit 8a10759
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 11 deletions.
20 changes: 18 additions & 2 deletions src/main/java/com/endava/cats/fuzzer/special/CustomFuzzerUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@
import java.util.stream.Collectors;

import static com.endava.cats.json.JsonUtils.NOT_SET;
import static com.endava.cats.util.CatsDSLWords.*;
import static com.endava.cats.util.CatsDSLWords.CATS_HEADERS;
import static com.endava.cats.util.CatsDSLWords.CHECKS;
import static com.endava.cats.util.CatsDSLWords.DESCRIPTION;
import static com.endava.cats.util.CatsDSLWords.EXPECTED_RESPONSE_CODE;
import static com.endava.cats.util.CatsDSLWords.HTTP_METHOD;
import static com.endava.cats.util.CatsDSLWords.ONE_OF_SELECTION;
import static com.endava.cats.util.CatsDSLWords.OUTPUT;
import static com.endava.cats.util.CatsDSLWords.RESERVED_WORDS;
import static com.endava.cats.util.CatsDSLWords.VERIFY;

@ApplicationScoped
public class CustomFuzzerUtil {
Expand Down Expand Up @@ -209,10 +217,18 @@ private Map<String, String> matchVariablesWithTheResponse(CatsResponse response,
//we make sure that "checkBoolean" is not marked as NOT_SET and set to TRUE so that is matched against the computed expression
return result.entrySet()
.stream()
.map(entry -> entry.getKey().equalsIgnoreCase(CHECK) ? new AbstractMap.SimpleEntry<>(entry.getKey(), TRUE) : entry)
.map(CustomFuzzerUtil::remapCheckBoolean)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

private static Map.Entry<String, String> remapCheckBoolean(Map.Entry<String, String> entry) {
return CHECKS.entrySet()
.stream()
.filter(checkEntry -> entry.getKey().startsWith(checkEntry.getKey()))
.map(checkEntry -> new AbstractMap.SimpleEntry<>(entry.getKey(), checkEntry.getValue()))
.findFirst()
.orElseGet(() -> new AbstractMap.SimpleEntry<>(entry.getKey(), entry.getValue()));
}

public String getTestScenario(String testName, Map<String, Object> currentPathValues) {
String description = WordUtils.nullOrValueOf(currentPathValues.get(DESCRIPTION));
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/endava/cats/io/ServiceCaller.java
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ private String getContentType(HttpMethod method, String defaultContentType) {
}

private void addIfNotPresent(String headerName, String headerValue, ServiceData data, List<KeyValuePair<String, Object>> headers) {
boolean notAccept = data.getHeaders().stream().noneMatch(catsHeader -> catsHeader.getName().equalsIgnoreCase(headerName));
if (notAccept) {
boolean exists = data.getHeaders().stream().noneMatch(catsHeader -> catsHeader.getName().equalsIgnoreCase(headerName));
if (exists) {
headers.add(new KeyValuePair<>(headerName, headerValue));
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/com/endava/cats/util/CatsDSLWords.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.endava.cats.util;

import java.util.List;
import java.util.Map;

public abstract class CatsDSLWords {
/**
Expand All @@ -17,10 +18,12 @@ public abstract class CatsDSLWords {
*/
public static final String CHECK = "checkBoolean";

/**
* Self-explanatory.
*/
public static final String TRUE = "true";
public static final String CHECK_TRUE = "checkTrue";

public static final String CHECK_FALSE = "checkFalse";

public static final Map<String, String> CHECKS = Map.of(CHECK, "true", CHECK_TRUE, "true", CHECK_FALSE, "false");

/**
* Reserved word used in CATS DSL files to specify the http method to be run.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/com/endava/cats/args/FilterArgumentsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void shouldIncludeAllFuzzers() {
List<String> fuzzers = filterArguments.getFirstPhaseFuzzersForPath();

Assertions.assertThat(fuzzers).contains("LeadingControlCharsInHeadersFuzzer", "LeadingWhitespacesInHeadersFuzzer", "LeadingMultiCodePointEmojisInFieldsTrimValidateFuzzer"
, "RemoveFieldsFuzzer", "CheckSecurityHeadersFuzzer").hasSize(118);
, "RemoveFieldsFuzzer", "CheckSecurityHeadersFuzzer").hasSize(124);
}

@Test
Expand Down Expand Up @@ -159,7 +159,7 @@ void shouldReturnGetAndDeleteWhenNotHttpMethodSupplied() {

@Test
void shouldReturnAllRegisteredFuzzers() {
Assertions.assertThat(filterArguments.getAllRegisteredFuzzers()).hasSize(122);
Assertions.assertThat(filterArguments.getAllRegisteredFuzzers()).hasSize(128);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,76 @@
package com.endava.cats.fuzzer.http;

import com.endava.cats.fuzzer.executor.SimpleExecutor;
import com.endava.cats.http.HttpMethod;
import com.endava.cats.http.ResponseCodeFamily;
import com.endava.cats.io.ServiceCaller;
import com.endava.cats.model.CatsResponse;
import com.endava.cats.model.FuzzingData;
import com.endava.cats.report.TestCaseExporter;
import com.endava.cats.report.TestCaseListener;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectSpy;
import io.swagger.v3.oas.models.media.StringSchema;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.test.util.ReflectionTestUtils;

import java.util.List;

@QuarkusTest
class EmptyJsonArrayBodyTest {
class EmptyJsonArrayBodyFuzzerTest {
private ServiceCaller serviceCaller;
@InjectSpy
private TestCaseListener testCaseListener;
private EmptyJsonArrayBodyFuzzer emptyJsonArrayBodyFuzzer;

@BeforeEach
void setup() {
serviceCaller = Mockito.mock(ServiceCaller.class);
SimpleExecutor simpleExecutor = new SimpleExecutor(testCaseListener, serviceCaller);
emptyJsonArrayBodyFuzzer = new EmptyJsonArrayBodyFuzzer(simpleExecutor);
ReflectionTestUtils.setField(testCaseListener, "testCaseExporter", Mockito.mock(TestCaseExporter.class));
}

@Test
void shouldNotRunForEmptyPayload() {
emptyJsonArrayBodyFuzzer.fuzz(Mockito.mock(FuzzingData.class));

Mockito.verifyNoInteractions(testCaseListener);
}

@Test
void givenAHttpMethodWithPayload_whenApplyingTheMalformedJsonFuzzer_thenTheResultsAreCorrectlyReported() {
FuzzingData data = FuzzingData.builder().method(HttpMethod.POST).reqSchema(new StringSchema()).requestContentTypes(List.of("application/json")).build();
ReflectionTestUtils.setField(data, "processedPayload", "{\"id\": 1}");

CatsResponse catsResponse = CatsResponse.builder().body("{}").responseCode(400).build();
Mockito.when(serviceCaller.call(Mockito.any())).thenReturn(catsResponse);
Mockito.doNothing().when(testCaseListener).reportResult(Mockito.any(), Mockito.eq(data), Mockito.any(), Mockito.any(), Mockito.anyBoolean());

emptyJsonArrayBodyFuzzer.fuzz(data);
Mockito.verify(testCaseListener, Mockito.times(1)).reportResult(Mockito.any(), Mockito.eq(data), Mockito.eq(catsResponse), Mockito.eq(ResponseCodeFamily.FOURXX), Mockito.anyBoolean());
}

@Test
void shouldHaveToString() {
Assertions.assertThat(emptyJsonArrayBodyFuzzer).hasToString(emptyJsonArrayBodyFuzzer.getClass().getSimpleName());
}

@Test
void shouldHaveDescription() {
Assertions.assertThat(emptyJsonArrayBodyFuzzer.description()).isNotBlank();
}

@Test
void shouldSkipForNonHttpBodyMethods() {
Assertions.assertThat(emptyJsonArrayBodyFuzzer.skipForHttpMethods()).contains(HttpMethod.GET, HttpMethod.DELETE);
}

@Test
void shouldHaveNullPayload() {
Assertions.assertThat(emptyJsonArrayBodyFuzzer.getPayload(null)).isEqualTo("[]");
}
}
3 changes: 3 additions & 0 deletions src/test/resources/functionalFuzzer-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
id: 25
$#length(): 3
checkBoolean: T(java.time.LocalDate).now().isAfter(T(java.time.LocalDate).parse(expiry.toString()))
checkTrue: T(java.time.LocalDate).now().isAfter(T(java.time.LocalDate).parse(expiry.toString()))
checkFalse: T(java.time.LocalDate).now().isBefore(T(java.time.LocalDate).parse(expiry.toString()))
checkTrue_2: T(java.time.LocalDate).now().isAfter(T(java.time.LocalDate).parse(expiry.toString()))
test_2:
description: Second Test Case
pet: ${resp}
Expand Down

0 comments on commit 8a10759

Please sign in to comment.