Skip to content

Commit a254010

Browse files
committed
added tests
1 parent b2bac14 commit a254010

File tree

3 files changed

+321
-0
lines changed

3 files changed

+321
-0
lines changed

csrf/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@
2525
<groupId>com.google.guava</groupId>
2626
<artifactId>guava</artifactId>
2727
</dependency>
28+
<dependency>
29+
<groupId>org.junit.jupiter</groupId>
30+
<artifactId>junit-jupiter</artifactId>
31+
<scope>test</scope>
32+
</dependency>
33+
<dependency>
34+
<groupId>org.mockito</groupId>
35+
<artifactId>mockito-core</artifactId>
36+
<scope>test</scope>
37+
</dependency>
2838
</dependencies>
2939

3040
<build>
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright (C) 2026 Dominik Schadow, dominikschadow@gmail.com
3+
*
4+
* This file is part of the Java Security project.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package de.dominikschadow.javasecurity.csrf;
19+
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
import org.mockito.Mock;
23+
import org.mockito.MockitoAnnotations;
24+
25+
import javax.servlet.ServletException;
26+
import javax.servlet.http.HttpServletRequest;
27+
import javax.servlet.http.HttpSession;
28+
import java.security.NoSuchAlgorithmException;
29+
import java.security.NoSuchProviderException;
30+
31+
import static org.junit.jupiter.api.Assertions.*;
32+
import static org.mockito.Mockito.*;
33+
34+
/**
35+
* Tests for the CSRFTokenHandler class.
36+
*
37+
* @author Dominik Schadow
38+
*/
39+
class CSRFTokenHandlerTest {
40+
@Mock
41+
private HttpServletRequest request;
42+
43+
@Mock
44+
private HttpSession session;
45+
46+
@BeforeEach
47+
void setUp() {
48+
MockitoAnnotations.openMocks(this);
49+
}
50+
51+
@Test
52+
void getToken_withNullSession_throwsServletException() {
53+
assertThrows(ServletException.class, () -> CSRFTokenHandler.getToken(null));
54+
}
55+
56+
@Test
57+
void getToken_withValidSessionWithoutToken_generatesNewToken() throws Exception {
58+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
59+
60+
String token = CSRFTokenHandler.getToken(session);
61+
62+
assertNotNull(token);
63+
assertFalse(token.isEmpty());
64+
verify(session).setAttribute(eq(CSRFTokenHandler.CSRF_TOKEN), anyString());
65+
}
66+
67+
@Test
68+
void getToken_withValidSessionWithEmptyToken_generatesNewToken() throws Exception {
69+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("");
70+
71+
String token = CSRFTokenHandler.getToken(session);
72+
73+
assertNotNull(token);
74+
assertFalse(token.isEmpty());
75+
verify(session).setAttribute(eq(CSRFTokenHandler.CSRF_TOKEN), anyString());
76+
}
77+
78+
@Test
79+
void getToken_withValidSessionWithExistingToken_returnsExistingToken() throws Exception {
80+
String existingToken = "existingToken123";
81+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(existingToken);
82+
83+
String token = CSRFTokenHandler.getToken(session);
84+
85+
assertEquals(existingToken, token);
86+
verify(session, never()).setAttribute(anyString(), anyString());
87+
}
88+
89+
@Test
90+
void isValid_withNullSession_throwsServletException() {
91+
when(request.getSession(false)).thenReturn(null);
92+
93+
assertThrows(ServletException.class, () -> CSRFTokenHandler.isValid(request));
94+
}
95+
96+
@Test
97+
void isValid_withMatchingToken_returnsTrue() throws Exception {
98+
String csrfToken = "validToken123";
99+
when(request.getSession(false)).thenReturn(session);
100+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
101+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
102+
103+
boolean result = CSRFTokenHandler.isValid(request);
104+
105+
assertTrue(result);
106+
}
107+
108+
@Test
109+
void isValid_withNonMatchingToken_returnsFalse() throws Exception {
110+
when(request.getSession(false)).thenReturn(session);
111+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("sessionToken");
112+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("differentToken");
113+
114+
boolean result = CSRFTokenHandler.isValid(request);
115+
116+
assertFalse(result);
117+
}
118+
119+
@Test
120+
void isValid_withNullRequestToken_returnsFalse() throws Exception {
121+
when(request.getSession(false)).thenReturn(session);
122+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("sessionToken");
123+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
124+
125+
boolean result = CSRFTokenHandler.isValid(request);
126+
127+
assertFalse(result);
128+
}
129+
130+
@Test
131+
void isValid_withNullSessionToken_returnsFalse() throws Exception {
132+
when(request.getSession(false)).thenReturn(session);
133+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
134+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("requestToken");
135+
136+
boolean result = CSRFTokenHandler.isValid(request);
137+
138+
assertFalse(result);
139+
}
140+
141+
@Test
142+
void isValid_withBothTokensNull_returnsTrue() throws Exception {
143+
when(request.getSession(false)).thenReturn(session);
144+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
145+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
146+
147+
boolean result = CSRFTokenHandler.isValid(request);
148+
149+
// When session has no token, getToken() generates a new one
150+
// So the tokens won't match
151+
assertFalse(result);
152+
}
153+
154+
@Test
155+
void getToken_generatesUniqueTokens() throws Exception {
156+
HttpSession session1 = mock(HttpSession.class);
157+
HttpSession session2 = mock(HttpSession.class);
158+
when(session1.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
159+
when(session2.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
160+
161+
String token1 = CSRFTokenHandler.getToken(session1);
162+
String token2 = CSRFTokenHandler.getToken(session2);
163+
164+
assertNotNull(token1);
165+
assertNotNull(token2);
166+
// Tokens should be different (with very high probability)
167+
assertNotEquals(token1, token2);
168+
}
169+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (C) 2026 Dominik Schadow, dominikschadow@gmail.com
3+
*
4+
* This file is part of the Java Security project.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
package de.dominikschadow.javasecurity.csrf;
19+
20+
import org.junit.jupiter.api.BeforeEach;
21+
import org.junit.jupiter.api.Test;
22+
import org.mockito.Mock;
23+
import org.mockito.MockitoAnnotations;
24+
25+
import javax.servlet.ServletException;
26+
import javax.servlet.http.HttpServletRequest;
27+
import javax.servlet.http.HttpServletResponse;
28+
import javax.servlet.http.HttpSession;
29+
import java.io.PrintWriter;
30+
import java.io.StringWriter;
31+
32+
import static org.junit.jupiter.api.Assertions.*;
33+
import static org.mockito.Mockito.*;
34+
35+
/**
36+
* Tests for the OrderServlet class.
37+
*
38+
* @author Dominik Schadow
39+
*/
40+
class OrderServletTest {
41+
private OrderServlet orderServlet;
42+
43+
@Mock
44+
private HttpServletRequest request;
45+
46+
@Mock
47+
private HttpServletResponse response;
48+
49+
@Mock
50+
private HttpSession session;
51+
52+
private StringWriter stringWriter;
53+
private PrintWriter printWriter;
54+
55+
@BeforeEach
56+
void setUp() throws Exception {
57+
MockitoAnnotations.openMocks(this);
58+
orderServlet = new OrderServlet();
59+
stringWriter = new StringWriter();
60+
printWriter = new PrintWriter(stringWriter);
61+
when(response.getWriter()).thenReturn(printWriter);
62+
}
63+
64+
@Test
65+
void doPost_withValidToken_returnsOrderConfirmation() throws Exception {
66+
String csrfToken = "validToken123";
67+
68+
when(request.getSession(false)).thenReturn(session);
69+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
70+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
71+
when(request.getParameter("product")).thenReturn("TestProduct");
72+
when(request.getParameter("quantity")).thenReturn("5");
73+
74+
orderServlet.doPost(request, response);
75+
76+
printWriter.flush();
77+
String output = stringWriter.toString();
78+
79+
verify(response).setContentType("text/html");
80+
assertTrue(output.contains("Order Confirmation"));
81+
assertTrue(output.contains("Ordered 5 of product TestProduct"));
82+
}
83+
84+
@Test
85+
void doPost_withInvalidToken_returns401() throws Exception {
86+
String sessionToken = "sessionToken123";
87+
String requestToken = "differentToken456";
88+
89+
when(request.getSession(false)).thenReturn(session);
90+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(sessionToken);
91+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(requestToken);
92+
93+
orderServlet.doPost(request, response);
94+
95+
printWriter.flush();
96+
String output = stringWriter.toString();
97+
98+
verify(response).setStatus(401);
99+
assertTrue(output.contains("Invalid token"));
100+
assertTrue(output.contains("Anti CSRF token is invalid!"));
101+
}
102+
103+
@Test
104+
void doPost_withMissingToken_returns401() throws Exception {
105+
when(request.getSession(false)).thenReturn(session);
106+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn("sessionToken");
107+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(null);
108+
109+
orderServlet.doPost(request, response);
110+
111+
printWriter.flush();
112+
String output = stringWriter.toString();
113+
114+
verify(response).setStatus(401);
115+
assertTrue(output.contains("Invalid token"));
116+
}
117+
118+
@Test
119+
void doPost_withInvalidQuantity_setsQuantityToZero() throws Exception {
120+
String csrfToken = "validToken123";
121+
122+
when(request.getSession(false)).thenReturn(session);
123+
when(session.getAttribute(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
124+
when(request.getParameter(CSRFTokenHandler.CSRF_TOKEN)).thenReturn(csrfToken);
125+
when(request.getParameter("product")).thenReturn("TestProduct");
126+
when(request.getParameter("quantity")).thenReturn("invalid");
127+
128+
orderServlet.doPost(request, response);
129+
130+
printWriter.flush();
131+
String output = stringWriter.toString();
132+
133+
assertTrue(output.contains("Ordered 0 of product TestProduct"));
134+
}
135+
136+
@Test
137+
void doPost_withNoSession_throwsServletException() {
138+
when(request.getSession(false)).thenReturn(null);
139+
140+
assertThrows(ServletException.class, () -> orderServlet.doPost(request, response));
141+
}
142+
}

0 commit comments

Comments
 (0)