diff --git a/.github/workflows/13-backend-incremental-pitest.yml b/.github/workflows/13-backend-incremental-pitest.yml
index e3f02ae2..7ca5bbdb 100644
--- a/.github/workflows/13-backend-incremental-pitest.yml
+++ b/.github/workflows/13-backend-incremental-pitest.yml
@@ -54,7 +54,7 @@ jobs:
- name: Build with Maven
run: mvn -B test
- name: Pitest
- run: mvn test org.pitest:pitest-maven:mutationCoverage -DmutationThreshold=100
+ run: mvn pitest:mutationCoverage -DmutationThreshold=100
- name: Upload Pitest History to Artifacts
if: always() # always upload artifacts, even if tests fail
uses: actions/upload-artifact@v3.1.2
diff --git a/.github/workflows/14-backend-pitest.yml b/.github/workflows/14-backend-pitest.yml
index e99c7eb7..534a0eb2 100644
--- a/.github/workflows/14-backend-pitest.yml
+++ b/.github/workflows/14-backend-pitest.yml
@@ -43,7 +43,7 @@ jobs:
# main branch changes
- name: Pitest
- run: mvn test org.pitest:pitest-maven:mutationCoverage -DmutationThreshold=100
+ run: mvn pitest:mutationCoverage -DmutationThreshold=100
- name: Upload Pitest History to Artifacts
if: always() # always upload artifacts, even if tests fail
uses: actions/upload-artifact@v3.1.2
diff --git a/README.md b/README.md
index c8f647fe..f0a85bec 100644
--- a/README.md
+++ b/README.md
@@ -165,12 +165,12 @@ INTEGRATION=true HEADLESS=false mvn test-compile failsafe:integration-test
To run a particular integration test (e.g. only `HomePageWebIT.java`) use `-Dit.test=ClassName`, for example:
```
-INTEGRATION=true mvn test-compile failsafe:integration-test -Dit.test=HomePageWebIt
+INTEGRATION=true mvn test-compile failsafe:integration-test -Dit.test=HomePageWebIT
```
or to see it run live:
```
-INTEGRATION=true HEADLESS=false mvn test-compile failsafe:integration-test -Dit.test=HomePageWebIt
+INTEGRATION=true HEADLESS=false mvn test-compile failsafe:integration-test -Dit.test=HomePageWebIT
```
Integration tests are any methods labelled with `@Test` annotation, that are under the `/src/test/java` hierarchy, and have names starting with `IT` (specifically capital I, capital T).
@@ -181,5 +181,4 @@ Unless you want a particular integration test to *also* be run when you type `mv
Note that while `mvn test` is typically sufficient to run tests, we have found that if you haven't compiled the test code yet, running `mvn failsafe:integration-test` may not actually run any of the tests.
-To run a single integration test (e.g. only `HomePageWebIT.java`) use `-Dit.test=ClassName`, for example:
diff --git a/pom.xml b/pom.xml
index 97ba0156..070bfa9e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.6.3
+ 3.1.1
@@ -75,7 +75,7 @@
org.springframework.cloud
spring-cloud-gateway-mvc
- 3.0.1
+ 4.1.3
@@ -135,11 +135,12 @@
2.0.1.Final
+
org.springdoc
- springdoc-openapi-ui
- 1.7.0
-
+ springdoc-openapi-starter-webmvc-ui
+ 2.5.0
+
@@ -157,7 +158,8 @@
3.0.0-M5
-
+
@@ -198,6 +200,7 @@
**/${app.packagePath}/controllers/FrontendController.*
**/${app.packagePath}/controllers/FrontendProxyController.*
**/${app.packagePath}/services/CurrentUserServiceImpl.*
+ **/${app.packagePath}/services/GrantedAuthoritiesService.*
**/${app.packagePath}/ExampleApplication.*
**/edu/ucsb/cs156/example/services/wiremock/*
@@ -286,12 +289,16 @@
${app.package}.services.CurrentUserServiceImpl
${app.package}.ExampleApplication
${app.package}.config.SecurityConfig
+ ${app.package}.config.SpaCsrfTokenRequestHandler
+ ${app.package}.config.CsrfCookieFilter
edu.ucsb.cs156.example.services.wiremock.WiremockService
edu.ucsb.cs156.example.services.wiremock.WiremockServiceDummy
edu.ucsb.cs156.example.services.wiremock.WiremockServiceImpl
+ ${app.package}.services.GrantedAuthoritiesService
edu.ucsb.cs156.example.web.*
+ edu.ucsb.cs156.example.integration.*
HTML
@@ -377,8 +384,8 @@
frontend-maven-plugin
1.12.1
- frontend
- ${project.build.directory}
+ frontend
+ ${project.build.directory}
@@ -409,26 +416,26 @@
-
-
- maven-antrun-plugin
- 3.0.0
-
-
- generate-resources
-
-
-
-
-
-
-
-
- run
-
-
-
-
+
+
+ maven-antrun-plugin
+ 3.0.0
+
+
+ generate-resources
+
+
+
+
+
+
+
+
+ run
+
+
+
+
diff --git a/src/main/java/edu/ucsb/cs156/example/aop/LoggingAspect.java b/src/main/java/edu/ucsb/cs156/example/aop/LoggingAspect.java
index 2cdc6acf..15e1a10d 100644
--- a/src/main/java/edu/ucsb/cs156/example/aop/LoggingAspect.java
+++ b/src/main/java/edu/ucsb/cs156/example/aop/LoggingAspect.java
@@ -1,5 +1,6 @@
package edu.ucsb.cs156.example.aop;
+import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
@@ -8,8 +9,6 @@
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
-import javax.servlet.http.HttpServletRequest;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Optional;
diff --git a/src/main/java/edu/ucsb/cs156/example/config/SecurityConfig.java b/src/main/java/edu/ucsb/cs156/example/config/SecurityConfig.java
index 103397a1..bf281d53 100644
--- a/src/main/java/edu/ucsb/cs156/example/config/SecurityConfig.java
+++ b/src/main/java/edu/ucsb/cs156/example/config/SecurityConfig.java
@@ -1,88 +1,100 @@
package edu.ucsb.cs156.example.config;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-import javax.servlet.http.HttpServletRequest;
-
+import edu.ucsb.cs156.example.entities.User;
+import edu.ucsb.cs156.example.repositories.UserRepository;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
+import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
+import org.springframework.security.web.csrf.CsrfTokenRequestAttributeHandler;
+import org.springframework.security.web.csrf.CsrfTokenRequestHandler;
+import org.springframework.security.web.csrf.XorCsrfTokenRequestAttributeHandler;
+import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
-import org.springframework.security.web.util.matcher.RequestMatcher;
-
-
+import org.springframework.util.StringUtils;
+import org.springframework.web.filter.OncePerRequestFilter;
-import edu.ucsb.cs156.example.entities.User;
-import edu.ucsb.cs156.example.repositories.UserRepository;
-import lombok.extern.slf4j.Slf4j;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Supplier;
/**
- * The `SecurityConfig` class in Java configures web security with OAuth2 login, CSRF protection, and
+ * The `SecurityConfig` class in Java configures web security with OAuth2 login,
+ * CSRF protection, and
* role-based authorization based on user email addresses.
*/
@Configuration
@EnableWebSecurity
-@EnableGlobalMethodSecurity(prePostEnabled = true)
+@EnableMethodSecurity
@Slf4j
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
+public class SecurityConfig {
@Value("${app.admin.emails}")
- private final List adminEmails = new ArrayList();
+ private final List adminEmails = new ArrayList<>();
@Autowired
UserRepository userRepository;
/**
- * The `configure` method in this Java code configures various security settings for an HTTP request,
- * including authorization, exception handling, OAuth2 login, CSRF protection, and logout behavior.
+ * The `filterChain` method in this Java code configures various security
+ * settings for an HTTP request,
+ * including authorization, exception handling, OAuth2 login, CSRF protection,
+ * and logout behavior.
*
* @param http injected HttpSecurity object (injected by Spring framework)
+ * //
*/
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests(authorize -> authorize
- .anyRequest().permitAll())
- .exceptionHandling(handlingConfigurer -> handlingConfigurer
- .authenticationEntryPoint(new Http403ForbiddenEntryPoint()))
+ // https://docs.spring.io/spring-security/reference/servlet/exploits/csrf.html#csrf-integration-javascript-spa
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http
+ .exceptionHandling(handling -> handling.authenticationEntryPoint(new Http403ForbiddenEntryPoint()))
.oauth2Login(
oauth2 -> oauth2.userInfoEndpoint(userInfo -> userInfo.userAuthoritiesMapper(this.userAuthoritiesMapper())))
.csrf(csrf -> csrf
- .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
- .logout(logout -> logout
- .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
- .logoutSuccessUrl("/"));
+ .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
+ .csrfTokenRequestHandler(new SpaCsrfTokenRequestHandler()))
+ .addFilterAfter(new CsrfCookieFilter(), BasicAuthenticationFilter.class)
+ .authorizeHttpRequests(auth -> auth.anyRequest().permitAll())
+ .logout(logout -> logout.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/"));
+ return http.build();
}
/**
- * The `configure` method is used to configure web security in Java, specifically ignoring requests
+ * The `webSecurityCustomizer` method is used to configure web security in Java,
+ * specifically ignoring requests
* to the "/h2-console/**" path.
- *
- * @param web injected by Spring Framework
*/
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring().antMatchers("/h2-console/**");
+ @Bean
+ public WebSecurityCustomizer webSecurityCustomizer() {
+ return web -> web.ignoring().requestMatchers("/h2-console/**");
}
private GrantedAuthoritiesMapper userAuthoritiesMapper() {
@@ -93,12 +105,12 @@ private GrantedAuthoritiesMapper userAuthoritiesMapper() {
authorities.forEach(authority -> {
log.info("********** authority={}", authority);
mappedAuthorities.add(authority);
- if (OAuth2UserAuthority.class.isInstance(authority)) {
- OAuth2UserAuthority oauth2UserAuthority = (OAuth2UserAuthority) authority;
-
+ if (authority instanceof OAuth2UserAuthority oauth2UserAuthority) {
Map userAttributes = oauth2UserAuthority.getAttributes();
log.info("********** userAttributes={}", userAttributes);
+ mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
+
String email = (String) userAttributes.get("email");
if (getAdmin(email)) {
mappedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
@@ -116,7 +128,8 @@ private GrantedAuthoritiesMapper userAuthoritiesMapper() {
}
/**
- * This method checks if the given email belongs to an admin user either from a predefined
+ * This method checks if the given email belongs to an admin user either from a
+ * predefined
* list or by querying the user repository.
*
* @param email email address of the user
@@ -129,4 +142,54 @@ public boolean getAdmin(String email) {
Optional u = userRepository.findByEmail(email);
return u.isPresent() && u.get().getAdmin();
}
+}
+
+final class SpaCsrfTokenRequestHandler extends CsrfTokenRequestAttributeHandler {
+ private final CsrfTokenRequestHandler delegate = new XorCsrfTokenRequestAttributeHandler();
+
+ @Override
+ public void handle(HttpServletRequest request, HttpServletResponse response,
+ Supplier deferredCsrfToken) {
+ /*
+ * Always use XorCsrfTokenRequestAttributeHandler to provide BREACH protection
+ * of
+ * the CsrfToken when it is rendered in the response body.
+ */
+ this.delegate.handle(request, response, deferredCsrfToken);
+ }
+
+ @Override
+ public String resolveCsrfTokenValue(HttpServletRequest request, CsrfToken csrfToken) {
+ /*
+ * If the request contains a request header, use
+ * CsrfTokenRequestAttributeHandler
+ * to resolve the CsrfToken. This applies when a single-page application
+ * includes
+ * the header value automatically, which was obtained via a cookie containing
+ * the
+ * raw CsrfToken.
+ */
+ if (StringUtils.hasText(request.getHeader(csrfToken.getHeaderName()))) {
+ return super.resolveCsrfTokenValue(request, csrfToken);
+ }
+ /*
+ * In all other cases (e.g. if the request contains a request parameter), use
+ * XorCsrfTokenRequestAttributeHandler to resolve the CsrfToken. This applies
+ * when a server-side rendered form includes the _csrf request parameter as a
+ * hidden input.
+ */
+ return this.delegate.resolveCsrfTokenValue(request, csrfToken);
+ }
+}
+
+final class CsrfCookieFilter extends OncePerRequestFilter {
+
+ @Override
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+ throws ServletException, IOException {
+ CsrfToken csrfToken = (CsrfToken) request.getAttribute("_csrf");
+ // Render the token value to a cookie by causing the deferred token to be loaded
+ csrfToken.getToken();
+ filterChain.doFilter(request, response);
+ }
}
\ No newline at end of file
diff --git a/src/main/java/edu/ucsb/cs156/example/controllers/UserInfoController.java b/src/main/java/edu/ucsb/cs156/example/controllers/UserInfoController.java
index 5a34463e..df8bdc9c 100644
--- a/src/main/java/edu/ucsb/cs156/example/controllers/UserInfoController.java
+++ b/src/main/java/edu/ucsb/cs156/example/controllers/UserInfoController.java
@@ -1,8 +1,6 @@
package edu.ucsb.cs156.example.controllers;
-import edu.ucsb.cs156.example.entities.User;
import edu.ucsb.cs156.example.models.CurrentUser;
-import edu.ucsb.cs156.example.services.CurrentUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
diff --git a/src/main/java/edu/ucsb/cs156/example/entities/Restaurant.java b/src/main/java/edu/ucsb/cs156/example/entities/Restaurant.java
index 196778bc..373bfae3 100644
--- a/src/main/java/edu/ucsb/cs156/example/entities/Restaurant.java
+++ b/src/main/java/edu/ucsb/cs156/example/entities/Restaurant.java
@@ -1,14 +1,13 @@
package edu.ucsb.cs156.example.entities;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
/**
* This is a JPA entity that represents a restaurant.
diff --git a/src/main/java/edu/ucsb/cs156/example/entities/UCSBDate.java b/src/main/java/edu/ucsb/cs156/example/entities/UCSBDate.java
index 1769918c..9a8996f5 100644
--- a/src/main/java/edu/ucsb/cs156/example/entities/UCSBDate.java
+++ b/src/main/java/edu/ucsb/cs156/example/entities/UCSBDate.java
@@ -1,18 +1,17 @@
package edu.ucsb.cs156.example.entities;
-import java.time.LocalDateTime;
-
-import javax.persistence.Entity;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
-/**
+/**
* This is a JPA entity that represents a UCSBDate, i.e. an entry
* that comes from the UCSB API for academic calendar dates.
*/
@@ -28,6 +27,6 @@ public class UCSBDate {
private long id;
private String quarterYYYYQ;
- private String name;
+ private String name;
private LocalDateTime localDateTime;
}
\ No newline at end of file
diff --git a/src/main/java/edu/ucsb/cs156/example/entities/UCSBDiningCommons.java b/src/main/java/edu/ucsb/cs156/example/entities/UCSBDiningCommons.java
index d54ea34d..55810380 100644
--- a/src/main/java/edu/ucsb/cs156/example/entities/UCSBDiningCommons.java
+++ b/src/main/java/edu/ucsb/cs156/example/entities/UCSBDiningCommons.java
@@ -1,12 +1,11 @@
package edu.ucsb.cs156.example.entities;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
/**
* This is a JPA entity that represents a UCSBDiningCommons
diff --git a/src/main/java/edu/ucsb/cs156/example/entities/User.java b/src/main/java/edu/ucsb/cs156/example/entities/User.java
index 5819f731..61cc13e2 100644
--- a/src/main/java/edu/ucsb/cs156/example/entities/User.java
+++ b/src/main/java/edu/ucsb/cs156/example/entities/User.java
@@ -1,14 +1,14 @@
package edu.ucsb.cs156.example.entities;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
-import lombok.AccessLevel;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
+import lombok.Data;
+import lombok.NoArgsConstructor;
/**
* This is a JPA entity that represents a user.
diff --git a/src/main/resources/application-integration.properties b/src/main/resources/application-integration.properties
index b7f3b013..52d73869 100644
--- a/src/main/resources/application-integration.properties
+++ b/src/main/resources/application-integration.properties
@@ -16,7 +16,6 @@ spring.security.oauth2.client.registration.my-oauth-provider.client-name=Client
spring.security.oauth2.client.registration.my-oauth-provider.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-oauth-provider.scope=https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile
spring.security.oauth2.client.registration.my-oauth-provider.redirect-uri=http://localhost:8080/login/oauth2/code/my-oauth-provider
-spring.security.oauth2.client.registration.my-oauth-provider.client-authentication-method=basic
spring.security.oauth2.client.registration.my-oauth-provider.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://localhost:8090/oauth/authorize
diff --git a/src/main/resources/application-wiremock.properties b/src/main/resources/application-wiremock.properties
index 81ddf1e3..2cce381c 100644
--- a/src/main/resources/application-wiremock.properties
+++ b/src/main/resources/application-wiremock.properties
@@ -16,7 +16,6 @@ spring.security.oauth2.client.registration.my-oauth-provider.client-name=Client
spring.security.oauth2.client.registration.my-oauth-provider.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-oauth-provider.scope=https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile
spring.security.oauth2.client.registration.my-oauth-provider.redirect-uri=http://localhost:8080/login/oauth2/code/my-oauth-provider
-spring.security.oauth2.client.registration.my-oauth-provider.client-authentication-method=basic
spring.security.oauth2.client.registration.my-oauth-provider.authorization-grant-type=authorization_code
spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=http://localhost:8090/oauth/authorize
diff --git a/src/test/java/edu/ucsb/cs156/example/WebTestCase.java b/src/test/java/edu/ucsb/cs156/example/WebTestCase.java
index 7feee284..eb5ba557 100644
--- a/src/test/java/edu/ucsb/cs156/example/WebTestCase.java
+++ b/src/test/java/edu/ucsb/cs156/example/WebTestCase.java
@@ -1,14 +1,5 @@
package edu.ucsb.cs156.example;
-import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
-
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeAll;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.web.server.LocalServerPort;
-import org.springframework.test.context.ActiveProfiles;
-
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
import com.microsoft.playwright.Browser;
@@ -16,8 +7,15 @@
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
-
import edu.ucsb.cs156.example.services.wiremock.WiremockServiceImpl;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.web.server.LocalServerPort;
+import org.springframework.test.context.ActiveProfiles;
+
+import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
@ActiveProfiles("integration")
public abstract class WebTestCase {
diff --git a/src/test/java/edu/ucsb/cs156/example/services/CurrentUserServiceTests.java b/src/test/java/edu/ucsb/cs156/example/services/CurrentUserServiceTests.java
index effbc3ab..06539bdc 100644
--- a/src/test/java/edu/ucsb/cs156/example/services/CurrentUserServiceTests.java
+++ b/src/test/java/edu/ucsb/cs156/example/services/CurrentUserServiceTests.java
@@ -9,19 +9,20 @@
import edu.ucsb.cs156.example.ControllerTestCase;
import edu.ucsb.cs156.example.entities.User;
+import org.mockito.Answers;
class CurrentUserServiceTests extends ControllerTestCase {
@Test
void test_isLoggedIn_returns_false() {
- CurrentUserService currentUserService = mock(CurrentUserService.class);
+ CurrentUserService currentUserService = mock(CurrentUserService.class, Answers.CALLS_REAL_METHODS);
when(currentUserService.getUser()).thenReturn(null);
assertFalse(currentUserService.isLoggedIn());
}
@Test
void test_isLoggedIn_returns_true() {
- CurrentUserService currentUserService = mock(CurrentUserService.class);
+ CurrentUserService currentUserService = mock(CurrentUserService.class, Answers.CALLS_REAL_METHODS);
when(currentUserService.getUser()).thenReturn(User.builder().build());
assertTrue(currentUserService.isLoggedIn());
}
diff --git a/src/test/java/edu/ucsb/cs156/example/services/GrantedAuthoritiesServiceTests.java b/src/test/java/edu/ucsb/cs156/example/services/GrantedAuthoritiesServiceTests.java
deleted file mode 100644
index 24fd6d09..00000000
--- a/src/test/java/edu/ucsb/cs156/example/services/GrantedAuthoritiesServiceTests.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package edu.ucsb.cs156.example.services;
-
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import java.util.Collection;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.context.annotation.Import;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.test.context.support.WithMockUser;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import edu.ucsb.cs156.example.repositories.UserRepository;
-import edu.ucsb.cs156.example.testconfig.TestConfig;
-
-@ExtendWith(SpringExtension.class)
-@EnableConfigurationProperties(value = SystemInfoServiceImpl.class)
-@Import(TestConfig.class)
-@ContextConfiguration
-class GrantedAuthoritiesServiceTests {
-
- @MockBean
- UserRepository userRepository;
-
- @Autowired
- GrantedAuthoritiesService grantedAuthoritiesService;
-
- @WithMockUser(roles = { "USER" })
- @Test
- void test_getGrantedAuthorities() {
- // act
- Collection extends GrantedAuthority> grantedAuthorities = grantedAuthoritiesService.getGrantedAuthorities();
-
- // assert
-
- assertTrue(grantedAuthorities.size() > 0 );
- }
-
-}
diff --git a/src/test/java/edu/ucsb/cs156/example/testconfig/TestConfig.java b/src/test/java/edu/ucsb/cs156/example/testconfig/TestConfig.java
index c9590520..ea96a428 100644
--- a/src/test/java/edu/ucsb/cs156/example/testconfig/TestConfig.java
+++ b/src/test/java/edu/ucsb/cs156/example/testconfig/TestConfig.java
@@ -1,13 +1,16 @@
package edu.ucsb.cs156.example.testconfig;
+import edu.ucsb.cs156.example.config.SecurityConfig;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import edu.ucsb.cs156.example.services.CurrentUserService;
import edu.ucsb.cs156.example.services.GrantedAuthoritiesService;
+import org.springframework.context.annotation.Import;
@TestConfiguration
+@Import(SecurityConfig.class)
public class TestConfig {
@Bean
diff --git a/src/test/java/edu/ucsb/cs156/example/web/HomePageWebIT.java b/src/test/java/edu/ucsb/cs156/example/web/HomePageWebIT.java
index b3abe7f7..ac61eb40 100644
--- a/src/test/java/edu/ucsb/cs156/example/web/HomePageWebIT.java
+++ b/src/test/java/edu/ucsb/cs156/example/web/HomePageWebIT.java
@@ -1,15 +1,12 @@
package edu.ucsb.cs156.example.web;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
-
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
diff --git a/src/test/java/edu/ucsb/cs156/example/web/SwaggerWebIT.java b/src/test/java/edu/ucsb/cs156/example/web/SwaggerWebIT.java
index 2cfa6663..9ce7e5f8 100644
--- a/src/test/java/edu/ucsb/cs156/example/web/SwaggerWebIT.java
+++ b/src/test/java/edu/ucsb/cs156/example/web/SwaggerWebIT.java
@@ -6,7 +6,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;