ConnectionUtil.java

1
package com.jsql.util;
2
3
import com.jsql.model.InjectionModel;
4
import com.jsql.model.bean.util.Header;
5
import com.jsql.model.bean.util.Interaction;
6
import com.jsql.model.bean.util.Request;
7
import com.jsql.model.exception.InjectionFailureException;
8
import com.jsql.model.exception.JSqlException;
9
import com.jsql.model.injection.method.AbstractMethodInjection;
10
import org.apache.commons.lang3.StringUtils;
11
import org.apache.logging.log4j.LogManager;
12
import org.apache.logging.log4j.Logger;
13
14
import java.io.IOException;
15
import java.net.Authenticator;
16
import java.net.CookieManager;
17
import java.net.PasswordAuthentication;
18
import java.net.URI;
19
import java.net.http.HttpClient;
20
import java.net.http.HttpClient.Version;
21
import java.net.http.HttpHeaders;
22
import java.net.http.HttpRequest;
23
import java.net.http.HttpRequest.BodyPublishers;
24
import java.net.http.HttpRequest.Builder;
25
import java.net.http.HttpResponse;
26
import java.net.http.HttpResponse.BodyHandlers;
27
import java.security.SecureRandom;
28
import java.time.Duration;
29
import java.util.*;
30
import java.util.AbstractMap.SimpleEntry;
31
import java.util.Map.Entry;
32
import java.util.stream.Collectors;
33
import java.util.stream.Stream;
34
35
/**
36
 * Utility class in charge of connection to web resources and management
37
 * of source page and request and response headers.
38
 */
39
public class ConnectionUtil {
40
    
41
    private static final Logger LOGGER = LogManager.getRootLogger();
42
    
43
    private String urlByUser;  // URL entered by user
44
    private String urlBase;  // URL entered by user without the query string
45
    private AbstractMethodInjection methodInjection;  // Method of injection: by query string, request or header
46
    private String typeRequest = StringUtil.GET;  // Default HTTP method. It can be changed to a custom method
47
    private final Random randomForUserAgent = new SecureRandom();
48
    private final InjectionModel injectionModel;
49
    private final CookieManager cookieManager = new CookieManager();
50
    
51
    public ConnectionUtil(InjectionModel injectionModel) {
52
        this.injectionModel = injectionModel;
53
    }
54
    
55
    public HttpClient.Builder getHttpClient() {
56
        var httpClientBuilder = HttpClient.newBuilder()
57
            .connectTimeout(Duration.ofSeconds(this.getTimeout()))
58
            .sslContext(this.injectionModel.getMediatorUtils().getCertificateUtil().getSslContext())
59
            .followRedirects(
60 1 1. getHttpClient : negated conditional → NO_COVERAGE
                this.injectionModel.getMediatorUtils().getPreferencesUtil().isFollowingRedirection()
61
                ? HttpClient.Redirect.ALWAYS
62
                : HttpClient.Redirect.NEVER
63
            );
64 1 1. getHttpClient : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isHttp2Disabled()) {
65
            httpClientBuilder.version(Version.HTTP_1_1);
66
        }
67 1 1. getHttpClient : negated conditional → NO_COVERAGE
        if (!this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotProcessingCookies()) {
68
            httpClientBuilder.cookieHandler(this.cookieManager);
69
        }
70 1 1. getHttpClient : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().getAuthenticationUtil().isAuthentEnabled()) {
71
            httpClientBuilder.authenticator(new Authenticator() {
72
                @Override
73
                protected PasswordAuthentication getPasswordAuthentication() {
74 1 1. getPasswordAuthentication : replaced return value with null for com/jsql/util/ConnectionUtil$1::getPasswordAuthentication → NO_COVERAGE
                    return new PasswordAuthentication(
75
                        ConnectionUtil.this.injectionModel.getMediatorUtils().getAuthenticationUtil().getUsernameAuthentication(),
76
                        ConnectionUtil.this.injectionModel.getMediatorUtils().getAuthenticationUtil().getPasswordAuthentication().toCharArray()
77
                    );
78
                }
79
            });
80
        }
81 1 1. getHttpClient : replaced return value with null for com/jsql/util/ConnectionUtil::getHttpClient → NO_COVERAGE
        return httpClientBuilder;
82
    }
83
84
    public static <T> Map<String, String> getHeadersMap(HttpResponse<T> httpResponse) {
85
        Map<String, String> sortedMap = ConnectionUtil.getHeadersMap(httpResponse.headers());
86
        String responseCodeHttp = String.valueOf(httpResponse.statusCode());
87
        sortedMap.put(":status", responseCodeHttp);
88 1 1. getHeadersMap : replaced return value with Collections.emptyMap for com/jsql/util/ConnectionUtil::getHeadersMap → NO_COVERAGE
        return sortedMap;
89
    }
90
    
91
    public static Map<String, String> getHeadersMap(HttpHeaders httpHeaders) {
92
        Map<String, String> unsortedMap = httpHeaders.map()
93
            .entrySet()
94
            .stream()
95
            .sorted(Entry.comparingByKey())
96 1 1. lambda$getHeadersMap$0 : replaced return value with null for com/jsql/util/ConnectionUtil::lambda$getHeadersMap$0 → NO_COVERAGE
            .map(entrySet -> new AbstractMap.SimpleEntry<>(
97
                entrySet.getKey(),
98
                String.join(", ", entrySet.getValue())
99
            ))
100
            .collect(Collectors.toMap(
101
                AbstractMap.SimpleEntry::getKey,
102
                AbstractMap.SimpleEntry::getValue
103
            ));
104 1 1. getHeadersMap : replaced return value with Collections.emptyMap for com/jsql/util/ConnectionUtil::getHeadersMap → NO_COVERAGE
        return new TreeMap<>(unsortedMap);
105
    }
106
107
    /**
108
     * Check that the connection to the website is working correctly.
109
     * It uses authentication defined by user, with fixed timeout, and warn
110
     * user in case of authentication detected.
111
     */
112
    public HttpResponse<String> checkConnectionResponse() throws IOException, InterruptedException, JSqlException {
113
        var queryString = this.injectionModel.getMediatorUtils().getParameterUtil().getQueryStringFromEntries();
114
        var testUrl = this.getUrlBase().replaceAll("\\?$", StringUtils.EMPTY);
115
116 1 1. checkConnectionResponse : negated conditional → NO_COVERAGE
        if (StringUtils.isNotEmpty(queryString)) {
117
            testUrl += "?"+ queryString;
118
        }
119
120
        String contentTypeRequest = "text/plain";
121
122
        var body = this.injectionModel.getMediatorUtils().getParameterUtil().getRawRequest();
123
124 1 1. checkConnectionResponse : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().getParameterUtil().isMultipartRequest()) {
125
            body = body.replaceAll("(?s)\\\\n", "\r\n");
126 1 1. checkConnectionResponse : negated conditional → NO_COVERAGE
        } else if (this.injectionModel.getMediatorUtils().getParameterUtil().isRequestSoap()) {
127
            contentTypeRequest = "text/xml";
128 1 1. checkConnectionResponse : negated conditional → NO_COVERAGE
        } else if (!this.injectionModel.getMediatorUtils().getParameterUtil().getListRequest().isEmpty()) {
129
            contentTypeRequest = "application/x-www-form-urlencoded";
130
        }
131
132
        // Test the HTTP connection
133
        Builder httpRequest = HttpRequest.newBuilder();
134
        try {
135
            httpRequest.uri(
136
                URI.create(
137
                    testUrl  // Get encoded params without fragment
138
                    .replace(InjectionModel.STAR, StringUtils.EMPTY)  // Ignore injection point during the test
139
                )
140
            );
141
        } catch (IllegalArgumentException e) {
142
            throw new JSqlException(e);
143
        }
144
        httpRequest.setHeader(HeaderUtil.CONTENT_TYPE_REQUEST, contentTypeRequest)
145
            .timeout(Duration.ofSeconds(this.getTimeout()));
146
        
147 1 1. checkConnectionResponse : removed call to com/jsql/util/CsrfUtil::addHeaderToken → NO_COVERAGE
        this.injectionModel.getMediatorUtils().getCsrfUtil().addHeaderToken(httpRequest);
148 1 1. checkConnectionResponse : removed call to com/jsql/util/DigestUtil::addHeaderToken → NO_COVERAGE
        this.injectionModel.getMediatorUtils().getDigestUtil().addHeaderToken(httpRequest);
149
150
        httpRequest.method(this.typeRequest, BodyPublishers.ofString(body));
151
152
        // Add headers if exists (Authorization:Basic, etc.)
153
        for (SimpleEntry<String, String> header: this.injectionModel.getMediatorUtils().getParameterUtil().getListHeader()) {
154 1 1. checkConnectionResponse : removed call to com/jsql/util/HeaderUtil::sanitizeHeaders → NO_COVERAGE
            HeaderUtil.sanitizeHeaders(httpRequest, header);
155
        }
156
157 1 1. checkConnectionResponse : replaced return value with null for com/jsql/util/ConnectionUtil::checkConnectionResponse → NO_COVERAGE
        return this.injectionModel.getMediatorUtils().getHeaderUtil().checkResponseHeader(httpRequest, body);
158
    }
159
160
    public void testConnection() throws IOException, InterruptedException, JSqlException {
161
        // Check connection is working: define Cookie management, check HTTP status, parse <form> parameters, process CSRF
162
        LOGGER.log(LogLevelUtil.CONSOLE_DEFAULT, () -> I18nUtil.valueByKey("LOG_CONNECTION_TEST"));
163
        this.getCookieManager().getCookieStore().removeAll();
164
        HttpResponse<String> httpResponse = this.checkConnectionResponse();
165
166
        if (
167 2 1. testConnection : negated conditional → NO_COVERAGE
2. testConnection : negated conditional → NO_COVERAGE
            (httpResponse.statusCode() == 401 || httpResponse.statusCode() == 403)
168 1 1. testConnection : negated conditional → NO_COVERAGE
            && !this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotProcessingCookies()
169
            && (
170 1 1. testConnection : negated conditional → NO_COVERAGE
                this.injectionModel.getMediatorUtils().getCsrfUtil().isCsrf()
171 1 1. testConnection : negated conditional → NO_COVERAGE
                || this.injectionModel.getMediatorUtils().getDigestUtil().isDigest()
172
            )
173
        ) {
174 1 1. testConnection : negated conditional → NO_COVERAGE
            if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isProcessingCsrf()) {
175
                LOGGER.log(LogLevelUtil.CONSOLE_INFORM, () -> "Testing CSRF handshake from previous connection...");
176 1 1. testConnection : negated conditional → NO_COVERAGE
            } else if (StringUtils.isNotEmpty(this.injectionModel.getMediatorUtils().getDigestUtil().getTokenDigest())) {
177
                LOGGER.log(LogLevelUtil.CONSOLE_INFORM, () -> "Testing Digest handshake from previous connection...");
178
            }
179
            httpResponse = this.checkConnectionResponse();
180
        }
181
182 3 1. testConnection : changed conditional boundary → NO_COVERAGE
2. testConnection : negated conditional → NO_COVERAGE
3. testConnection : negated conditional → NO_COVERAGE
        if (httpResponse.statusCode() >= 400 && !this.injectionModel.getMediatorUtils().getPreferencesUtil().isNotTestingConnection()) {
183
            throw new InjectionFailureException(String.format("Connection failed: problem when calling %s", httpResponse.uri().toURL()));
184
        }
185
    }
186
187
    /**
188
     * Call a URL and return the source page.
189
     * @param url to call
190
     * @return the source page of the URL
191
     */
192
    public String getSourceLineFeed(String url) {
193 1 1. getSourceLineFeed : replaced return value with "" for com/jsql/util/ConnectionUtil::getSourceLineFeed → NO_COVERAGE
        return this.getSource(url, true, false);
194
    }
195
196
    public String getSource(String url) {
197 1 1. getSource : replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE
        return this.getSource(url, false, false);
198
    }
199
200
    public String getSource(String url, boolean isConnectIssueIgnored) {  // reverse init result can be ignored
201 1 1. getSource : replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE
        return this.getSource(url, false, isConnectIssueIgnored);
202
    }
203
204
    public String getSource(String url, boolean lineFeed, boolean isConnectIssueIgnored) {
205
        Map<Header, Object> msgHeader = new EnumMap<>(Header.class);
206
        msgHeader.put(Header.URL, url);
207
        
208
        String pageSource = StringUtils.EMPTY;
209
        
210
        try {
211
            var httpRequest = HttpRequest.newBuilder()
212
                .uri(URI.create(url))
213
                .timeout(Duration.ofSeconds(this.getTimeout()))
214
                .build();
215
            
216
            HttpHeaders httpHeaders;
217 1 1. getSource : negated conditional → NO_COVERAGE
            if (lineFeed) {
218
                HttpResponse<Stream<String>> response = this.getHttpClient().build().send(httpRequest, BodyHandlers.ofLines());
219
                pageSource = response.body().collect(Collectors.joining("\n"));
220
                httpHeaders = response.headers();
221
            } else {
222
                HttpResponse<String> response = this.getHttpClient().build().send(httpRequest, BodyHandlers.ofString());
223
                pageSource = response.body();
224
                httpHeaders = response.headers();
225
            }
226
            
227
            msgHeader.put(Header.RESPONSE, ConnectionUtil.getHeadersMap(httpHeaders));
228
            msgHeader.put(Header.HEADER, ConnectionUtil.getHeadersMap(httpRequest.headers()));
229
            
230
        } catch (IOException e) {
231 1 1. getSource : negated conditional → NO_COVERAGE
            if (!isConnectIssueIgnored) {  // ignoring reverse connection timeout
232
                LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
233
            }
234
        } catch (InterruptedException e) {
235
            LOGGER.log(LogLevelUtil.IGNORE, e, e);
236 1 1. getSource : removed call to java/lang/Thread::interrupt → NO_COVERAGE
            Thread.currentThread().interrupt();
237
        } finally {
238
            msgHeader.put(Header.SOURCE, pageSource);
239
            // Inform the view about the log infos
240
            var request = new Request();
241 1 1. getSource : removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE
            request.setMessage(Interaction.MESSAGE_HEADER);
242 1 1. getSource : removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE
            request.setParameters(msgHeader);
243 1 1. getSource : removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE
            this.injectionModel.sendToViews(request);
244
        }
245
        
246 1 1. getSource : replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE
        return pageSource.trim();
247
    }
248
249
    public void setCustomUserAgent(Builder httpRequest) {
250 1 1. setCustomUserAgent : negated conditional → NO_COVERAGE
        if (this.injectionModel.getMediatorUtils().getPreferencesUtil().isUserAgentRandom()) {
251
            String agents = this.injectionModel.getMediatorUtils().getUserAgentUtil().getCustomUserAgent();
252
            List<String> listAgents = Stream.of(agents.split("[\\r\\n]+"))
253 2 1. lambda$setCustomUserAgent$4 : replaced boolean return with true for com/jsql/util/ConnectionUtil::lambda$setCustomUserAgent$4 → NO_COVERAGE
2. lambda$setCustomUserAgent$4 : negated conditional → NO_COVERAGE
                .filter(q -> !q.matches("^#.*"))
254
                .collect(Collectors.toList());
255
            String randomElement = listAgents.get(this.randomForUserAgent.nextInt(listAgents.size()));
256
            httpRequest.setHeader("User-Agent", randomElement);
257
        }
258
    }
259
    
260
    
261
    // Builder
262
263
    public ConnectionUtil withMethodInjection(AbstractMethodInjection methodInjection) {
264
        this.methodInjection = methodInjection;
265 1 1. withMethodInjection : replaced return value with null for com/jsql/util/ConnectionUtil::withMethodInjection → NO_COVERAGE
        return this;
266
    }
267
    
268
    public ConnectionUtil withTypeRequest(String typeRequest) {
269
        this.typeRequest = typeRequest;
270 1 1. withTypeRequest : replaced return value with null for com/jsql/util/ConnectionUtil::withTypeRequest → NO_COVERAGE
        return this;
271
    }
272
    
273
    
274
    // Getters and setters
275
    
276
    public String getUrlByUser() {
277 1 1. getUrlByUser : replaced return value with "" for com/jsql/util/ConnectionUtil::getUrlByUser → NO_COVERAGE
        return this.urlByUser;
278
    }
279
280
    public void setUrlByUser(String urlByUser) {
281
        this.urlByUser = urlByUser;
282
    }
283
    
284
    public String getUrlBase() {
285 1 1. getUrlBase : replaced return value with "" for com/jsql/util/ConnectionUtil::getUrlBase → SURVIVED
        return this.urlBase;
286
    }
287
288
    public void setUrlBase(String urlBase) {
289
        this.urlBase = urlBase;
290
    }
291
    
292
    public AbstractMethodInjection getMethodInjection() {
293 1 1. getMethodInjection : replaced return value with null for com/jsql/util/ConnectionUtil::getMethodInjection → KILLED
        return this.methodInjection;
294
    }
295
296
    public void setMethodInjection(AbstractMethodInjection methodInjection) {
297
        this.methodInjection = methodInjection;
298
    }
299
    
300
    public String getTypeRequest() {
301 1 1. getTypeRequest : replaced return value with "" for com/jsql/util/ConnectionUtil::getTypeRequest → NO_COVERAGE
        return this.typeRequest;
302
    }
303
304
    public void setTypeRequest(String typeRequest) {
305
        this.typeRequest = typeRequest;
306
    }
307
308
    /**
309
     * Default timeout used by the jcifs fix. It's the default value used usually by the JVM.
310
     */
311
    public Integer getTimeout() {
312 1 1. getTimeout : replaced Integer return value with 0 for com/jsql/util/ConnectionUtil::getTimeout → NO_COVERAGE
        return this.injectionModel.getMediatorUtils().getPreferencesUtil().countConnectionTimeout();
313
    }
314
315
    public CookieManager getCookieManager() {
316 1 1. getCookieManager : replaced return value with null for com/jsql/util/ConnectionUtil::getCookieManager → NO_COVERAGE
        return this.cookieManager;
317
    }
318
}

Mutations

60

1.1
Location : getHttpClient
Killed by : none
negated conditional → NO_COVERAGE

64

1.1
Location : getHttpClient
Killed by : none
negated conditional → NO_COVERAGE

67

1.1
Location : getHttpClient
Killed by : none
negated conditional → NO_COVERAGE

70

1.1
Location : getHttpClient
Killed by : none
negated conditional → NO_COVERAGE

74

1.1
Location : getPasswordAuthentication
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil$1::getPasswordAuthentication → NO_COVERAGE

81

1.1
Location : getHttpClient
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::getHttpClient → NO_COVERAGE

88

1.1
Location : getHeadersMap
Killed by : none
replaced return value with Collections.emptyMap for com/jsql/util/ConnectionUtil::getHeadersMap → NO_COVERAGE

96

1.1
Location : lambda$getHeadersMap$0
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::lambda$getHeadersMap$0 → NO_COVERAGE

104

1.1
Location : getHeadersMap
Killed by : none
replaced return value with Collections.emptyMap for com/jsql/util/ConnectionUtil::getHeadersMap → NO_COVERAGE

116

1.1
Location : checkConnectionResponse
Killed by : none
negated conditional → NO_COVERAGE

124

1.1
Location : checkConnectionResponse
Killed by : none
negated conditional → NO_COVERAGE

126

1.1
Location : checkConnectionResponse
Killed by : none
negated conditional → NO_COVERAGE

128

1.1
Location : checkConnectionResponse
Killed by : none
negated conditional → NO_COVERAGE

147

1.1
Location : checkConnectionResponse
Killed by : none
removed call to com/jsql/util/CsrfUtil::addHeaderToken → NO_COVERAGE

148

1.1
Location : checkConnectionResponse
Killed by : none
removed call to com/jsql/util/DigestUtil::addHeaderToken → NO_COVERAGE

154

1.1
Location : checkConnectionResponse
Killed by : none
removed call to com/jsql/util/HeaderUtil::sanitizeHeaders → NO_COVERAGE

157

1.1
Location : checkConnectionResponse
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::checkConnectionResponse → NO_COVERAGE

167

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

168

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

170

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

171

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

174

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

176

1.1
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

182

1.1
Location : testConnection
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : testConnection
Killed by : none
negated conditional → NO_COVERAGE

193

1.1
Location : getSourceLineFeed
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getSourceLineFeed → NO_COVERAGE

197

1.1
Location : getSource
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE

201

1.1
Location : getSource
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE

217

1.1
Location : getSource
Killed by : none
negated conditional → NO_COVERAGE

231

1.1
Location : getSource
Killed by : none
negated conditional → NO_COVERAGE

236

1.1
Location : getSource
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

241

1.1
Location : getSource
Killed by : none
removed call to com/jsql/model/bean/util/Request::setMessage → NO_COVERAGE

242

1.1
Location : getSource
Killed by : none
removed call to com/jsql/model/bean/util/Request::setParameters → NO_COVERAGE

243

1.1
Location : getSource
Killed by : none
removed call to com/jsql/model/InjectionModel::sendToViews → NO_COVERAGE

246

1.1
Location : getSource
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getSource → NO_COVERAGE

250

1.1
Location : setCustomUserAgent
Killed by : none
negated conditional → NO_COVERAGE

253

1.1
Location : lambda$setCustomUserAgent$4
Killed by : none
replaced boolean return with true for com/jsql/util/ConnectionUtil::lambda$setCustomUserAgent$4 → NO_COVERAGE

2.2
Location : lambda$setCustomUserAgent$4
Killed by : none
negated conditional → NO_COVERAGE

265

1.1
Location : withMethodInjection
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::withMethodInjection → NO_COVERAGE

270

1.1
Location : withTypeRequest
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::withTypeRequest → NO_COVERAGE

277

1.1
Location : getUrlByUser
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getUrlByUser → NO_COVERAGE

285

1.1
Location : getUrlBase
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getUrlBase → SURVIVED
Covering tests

293

1.1
Location : getMethodInjection
Killed by : ParameterUtilSpock.[engine:spock]/[spec:ParameterUtilSpock]/[feature:$spock_feature_0_1]
replaced return value with null for com/jsql/util/ConnectionUtil::getMethodInjection → KILLED

301

1.1
Location : getTypeRequest
Killed by : none
replaced return value with "" for com/jsql/util/ConnectionUtil::getTypeRequest → NO_COVERAGE

312

1.1
Location : getTimeout
Killed by : none
replaced Integer return value with 0 for com/jsql/util/ConnectionUtil::getTimeout → NO_COVERAGE

316

1.1
Location : getCookieManager
Killed by : none
replaced return value with null for com/jsql/util/ConnectionUtil::getCookieManager → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.1