Skip to content

Commit 9f94677

Browse files
committed
fix: EmptyJsonFuzzer and EmptyBodyFuzzer should expect 2XX or 4XX depending on required fields being defined in the contract
1 parent ee20bfb commit 9f94677

File tree

5 files changed

+59
-10
lines changed

5 files changed

+59
-10
lines changed

src/main/java/com/endava/cats/fuzzer/http/BaseHttpWithPayloadSimpleFuzzer.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import com.endava.cats.fuzzer.executor.SimpleExecutor;
55
import com.endava.cats.fuzzer.executor.SimpleExecutorContext;
66
import com.endava.cats.http.HttpMethod;
7+
import com.endava.cats.http.ResponseCodeFamily;
78
import com.endava.cats.http.ResponseCodeFamilyPredefined;
8-
import com.endava.cats.util.JsonUtils;
99
import com.endava.cats.model.FuzzingData;
1010
import com.endava.cats.util.ConsoleUtils;
11+
import com.endava.cats.util.JsonUtils;
1112
import io.github.ludovicianul.prettylogger.PrettyLogger;
1213
import io.github.ludovicianul.prettylogger.PrettyLoggerFactory;
1314

@@ -35,7 +36,7 @@ public void fuzz(FuzzingData data) {
3536

3637
simpleExecutor.execute(
3738
SimpleExecutorContext.builder()
38-
.expectedResponseCode(ResponseCodeFamilyPredefined.FOURXX)
39+
.expectedResponseCode(this.getExpectedResponseCode(data))
3940
.fuzzingData(data)
4041
.logger(logger)
4142
.replaceRefData(false)
@@ -47,6 +48,16 @@ public void fuzz(FuzzingData data) {
4748
);
4849
}
4950

51+
/**
52+
* By default, expect a 4XX response. This can be overridden by subclasses to expect other response codes.
53+
*
54+
* @param data the data to fuzz
55+
* @return the expected response code family for the fuzzing operation
56+
*/
57+
protected ResponseCodeFamily getExpectedResponseCode(FuzzingData data) {
58+
return ResponseCodeFamilyPredefined.FOURXX;
59+
}
60+
5061
@Override
5162
public String toString() {
5263
return ConsoleUtils.sanitizeFuzzerName(this.getClass().getSimpleName());

src/main/java/com/endava/cats/fuzzer/http/EmptyBodyFuzzer.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.endava.cats.annotations.HttpFuzzer;
44
import com.endava.cats.fuzzer.executor.SimpleExecutor;
5+
import com.endava.cats.http.ResponseCodeFamily;
6+
import com.endava.cats.http.ResponseCodeFamilyPredefined;
57
import com.endava.cats.model.FuzzingData;
68
import jakarta.inject.Inject;
79
import jakarta.inject.Singleton;
@@ -33,6 +35,14 @@ protected String getPayload(FuzzingData data) {
3335
return "";
3436
}
3537

38+
@Override
39+
protected ResponseCodeFamily getExpectedResponseCode(FuzzingData data) {
40+
if (data.getAllRequiredFields().isEmpty()) {
41+
return ResponseCodeFamilyPredefined.TWOXX;
42+
}
43+
return super.getExpectedResponseCode(data);
44+
}
45+
3646
@Override
3747
public String description() {
3848
return "send a request with a empty string body";

src/main/java/com/endava/cats/fuzzer/http/EmptyJsonBodyFuzzer.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.endava.cats.annotations.HttpFuzzer;
44
import com.endava.cats.fuzzer.executor.SimpleExecutor;
5+
import com.endava.cats.http.ResponseCodeFamily;
6+
import com.endava.cats.http.ResponseCodeFamilyPredefined;
57
import com.endava.cats.model.FuzzingData;
68
import jakarta.inject.Inject;
79
import jakarta.inject.Singleton;
@@ -33,8 +35,21 @@ protected String getPayload(FuzzingData data) {
3335
return "{}";
3436
}
3537

38+
@Override
39+
protected ResponseCodeFamily getExpectedResponseCode(FuzzingData data) {
40+
if (doesNotHaveRequiredFieldsInRoot(data)) {
41+
return ResponseCodeFamilyPredefined.TWOXX;
42+
}
43+
return super.getExpectedResponseCode(data);
44+
}
45+
3646
@Override
3747
public String description() {
3848
return "send a request with a empty json body";
3949
}
50+
51+
52+
private boolean doesNotHaveRequiredFieldsInRoot(FuzzingData data) {
53+
return data.getAllRequiredFields().stream().allMatch(field -> field.contains("#"));
54+
}
4055
}

src/test/java/com/endava/cats/fuzzer/http/EmptyBodyFuzzerTest.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.assertj.core.api.Assertions;
1515
import org.junit.jupiter.api.BeforeEach;
1616
import org.junit.jupiter.api.Test;
17+
import org.junit.jupiter.params.ParameterizedTest;
18+
import org.junit.jupiter.params.provider.CsvSource;
1719
import org.mockito.Mockito;
1820
import org.springframework.test.util.ReflectionTestUtils;
1921

@@ -42,17 +44,22 @@ void shouldNotRunForEmptyPayload() {
4244
Mockito.verifyNoInteractions(testCaseListener);
4345
}
4446

45-
@Test
46-
void givenAHttpMethodWithPayload_whenApplyingTheMalformedJsonFuzzer_thenTheResultsAreCorrectlyReported() {
47-
FuzzingData data = FuzzingData.builder().method(HttpMethod.POST).reqSchema(new StringSchema()).requestContentTypes(List.of("application/json")).responseCodes(Set.of("400")).build();
47+
@ParameterizedTest
48+
@CsvSource({"FOURXX,true", "TWOXX,false"})
49+
void givenAHttpMethodWithPayload_whenApplyingTheMalformedJsonFuzzer_thenTheResultsAreCorrectlyReported(ResponseCodeFamilyPredefined responseCodeFamily, boolean required) {
50+
FuzzingData data = FuzzingData.builder().method(HttpMethod.POST).reqSchema(new StringSchema())
51+
.requestContentTypes(List.of("application/json"))
52+
.allRequiredFields(required ? List.of("required") : List.of())
53+
.responseCodes(Set.of("400")).build();
4854
ReflectionTestUtils.setField(data, "processedPayload", "{\"id\": 1}");
4955

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

5461
emptyBodyFuzzer.fuzz(data);
55-
Mockito.verify(testCaseListener, Mockito.times(1)).reportResult(Mockito.any(), Mockito.eq(data), Mockito.eq(catsResponse), Mockito.eq(ResponseCodeFamilyPredefined.FOURXX), Mockito.anyBoolean(), Mockito.eq(true));
62+
Mockito.verify(testCaseListener, Mockito.times(1)).reportResult(Mockito.any(), Mockito.eq(data), Mockito.eq(catsResponse), Mockito.eq(responseCodeFamily), Mockito.anyBoolean(), Mockito.eq(true));
5663
}
5764

5865
@Test

src/test/java/com/endava/cats/fuzzer/http/EmptyJsonBodyFuzzerTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import org.assertj.core.api.Assertions;
1515
import org.junit.jupiter.api.BeforeEach;
1616
import org.junit.jupiter.api.Test;
17+
import org.junit.jupiter.params.ParameterizedTest;
18+
import org.junit.jupiter.params.provider.CsvSource;
1719
import org.mockito.Mockito;
1820
import org.springframework.test.util.ReflectionTestUtils;
1921

@@ -42,17 +44,21 @@ void shouldNotRunForEmptyPayload() {
4244
Mockito.verifyNoInteractions(testCaseListener);
4345
}
4446

45-
@Test
46-
void givenAHttpMethodWithPayload_whenApplyingTheMalformedJsonFuzzer_thenTheResultsAreCorrectlyReported() {
47-
FuzzingData data = FuzzingData.builder().method(HttpMethod.POST).reqSchema(new StringSchema()).requestContentTypes(List.of("application/json")).responseCodes(Set.of("400")).build();
47+
@ParameterizedTest
48+
@CsvSource({"FOURXX,true", "TWOXX,false"})
49+
void givenAHttpMethodWithPayload_whenApplyingTheMalformedJsonFuzzer_thenTheResultsAreCorrectlyReported(ResponseCodeFamilyPredefined responseCodeFamily, boolean required) {
50+
FuzzingData data = FuzzingData.builder().method(HttpMethod.POST).reqSchema(new StringSchema())
51+
.requestContentTypes(List.of("application/json"))
52+
.allRequiredFields(required ? List.of("field") : List.of())
53+
.responseCodes(Set.of("400")).build();
4854
ReflectionTestUtils.setField(data, "processedPayload", "{\"id\": 1}");
4955

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

5460
emptyJsonBodyFuzzer.fuzz(data);
55-
Mockito.verify(testCaseListener, Mockito.times(1)).reportResult(Mockito.any(), Mockito.eq(data), Mockito.eq(catsResponse), Mockito.eq(ResponseCodeFamilyPredefined.FOURXX), Mockito.anyBoolean(), Mockito.eq(true));
61+
Mockito.verify(testCaseListener, Mockito.times(1)).reportResult(Mockito.any(), Mockito.eq(data), Mockito.eq(catsResponse), Mockito.eq(responseCodeFamily), Mockito.anyBoolean(), Mockito.eq(true));
5662
}
5763

5864
@Test

0 commit comments

Comments
 (0)