commit f80fcfd749cb5863d4a0ee87361859b3c2eb7701
Author: Hrabikv <hrabikv@students.zcu.cz>
Date:   Sat Apr 22 20:18:34 2023 +0200

    #10258 vytvoření prof of concept kontraktových testů s použitím groovy scriptů

diff --git a/pom.xml b/pom.xml
index f655bcf..a938038 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,6 +24,7 @@
 		<com.fasterxml.jackson.core.version>2.13.3</com.fasterxml.jackson.core.version>
 		<org.junit.jupiter.version>5.4.0</org.junit.jupiter.version>
 		<org.apache.maven.plugins.version>3.0.0-M7</org.apache.maven.plugins.version>
+		<spring-cloud-contract.version>3.0.3</spring-cloud-contract.version>
 	</properties>
 
 	<dependencies>
@@ -45,10 +46,10 @@
 			<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
 
-<!--		<dependency>-->
-<!--			<groupId>org.springframework.boot</groupId>-->
-<!--			<artifactId>spring-boot-starter-security</artifactId>-->
-<!--		</dependency>-->
+		<dependency>
+			<groupId>org.springframework.security</groupId>
+			<artifactId>spring-security-web</artifactId>
+		</dependency>
 
 		<dependency>
 			<groupId>mysql</groupId>
@@ -98,7 +99,7 @@
 			<version>${com.fasterxml.jackson.core.version}</version>
 		</dependency>
 
-	<!-- Security library -->
+		<!-- Security library -->
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-security</artifactId>
@@ -108,6 +109,7 @@
 			<groupId>org.apache.httpcomponents</groupId>
 			<artifactId>httpclient</artifactId>
 		</dependency>
+
 		<!-- Junit libraries for unit tests-->
 		<dependency>
 			<groupId>org.junit.jupiter</groupId>
@@ -129,6 +131,7 @@
 			<artifactId>json-simple</artifactId>
 			<version>1.1.1</version>
 		</dependency>
+
 		<!-- UI TESTING -->
 		<dependency>
 			<groupId>org.seleniumhq.selenium</groupId>
@@ -160,6 +163,14 @@
 			<scope>test</scope>
 		</dependency>
 
+		<!-- Contract testing -->
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-contract-verifier</artifactId>
+			<version>2.1.1.RELEASE</version>
+			<scope>test</scope>
+		</dependency>
+
     </dependencies>
 
 	<build>
@@ -185,6 +196,19 @@
 				<version>${org.apache.maven.plugins.version}</version>
 			</plugin>
 
+			<plugin>
+				<groupId>org.springframework.cloud</groupId>
+				<artifactId>spring-cloud-contract-maven-plugin</artifactId>
+				<version>${spring-cloud-contract.version}</version>
+				<extensions>true</extensions>
+				<configuration>
+					<testFramework>JUNIT5</testFramework>
+					<baseClassForTests>
+						cz.zcu.fav.kiv.antipatterndetectionapp.v2.controller.BaseTest
+					</baseClassForTests>
+				</configuration>
+			</plugin>
+
 		</plugins>
 	</build>
 
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
index bc46ca6..e07bc31 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
@@ -2,7 +2,10 @@ package cz.zcu.fav.kiv.antipatterndetectionapp.v2.security;
 
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.AuthProvider;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.OAuthService;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.OAuthServiceImpl;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.UserServiceImpl;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -14,12 +17,12 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.core.userdetails.UserDetailsService;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.access.channel.ChannelProcessingFilter;
+import org.springframework.security.web.FilterChainProxy;
 import org.springframework.web.client.RestTemplate;
 import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.CorsConfigurationSource;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
 
 import java.util.Arrays;
 
@@ -27,8 +30,13 @@ import java.util.Arrays;
 @EnableWebSecurity(debug = true)
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
-    @Autowired
-    private UserDetailsService userService;
+    @Bean
+    public FilterChainProxy filterChainProxy() {
+        return new FilterChainProxy();
+    }
+
+//    @Autowired
+    private final UserDetailsService userService = new OAuthServiceImpl();
 
     @Autowired
     private JwtAuthenticationFilter jwtAuthenticationFilter;
@@ -66,7 +74,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         return super.authenticationManagerBean();
     }
 
-
     @Override
     protected void configure(HttpSecurity httpSecurity) throws Exception {
         httpSecurity
diff --git a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/BaseTest.java b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/BaseTest.java
new file mode 100644
index 0000000..1708b4a
--- /dev/null
+++ b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/BaseTest.java
@@ -0,0 +1,40 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.controller;
+
+import cz.zcu.fav.kiv.antipatterndetectionapp.AntiPatternDetectionAppApplication;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.User;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.repository.UserRepository;
+import io.restassured.module.mockmvc.RestAssuredMockMvc;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = AntiPatternDetectionAppApplication.class)
+public abstract class BaseTest {
+
+    @Autowired
+    WebApplicationContext webApplicationContext;
+
+    @MockBean
+    private UserRepository userRepository;
+
+
+
+    @Before
+    public void init() {
+        User user = new User("foo", "foo@foo.foo", "foo");
+
+        when(userRepository.findByName("non-existing")).thenReturn(null);
+        when(userRepository.findByName("foo")).thenReturn(user);
+        when(userRepository.save(any(User.class))).thenReturn(user);
+        RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
+    }
+
+}
diff --git a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserControllerTest.java b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserControllerTest.java
index 21fe899..2192038 100644
--- a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserControllerTest.java
+++ b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserControllerTest.java
@@ -3,17 +3,20 @@ package cz.zcu.fav.kiv.antipatterndetectionapp.v2.controller;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.dials.UserModelStatusCodes;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.UserService;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.JSONBuilder;
-import org.junit.jupiter.api.Test;
+import org.junit.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.runner.RunWith;
 import org.mockito.Mockito;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.mock.mockito.MockBean;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.mock.web.MockHttpServletResponse;
 import org.springframework.security.test.context.support.WithMockUser;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit4.SpringRunner;
 import org.springframework.test.web.servlet.MockMvc;
 import org.springframework.test.web.servlet.MvcResult;
 import org.springframework.test.web.servlet.RequestBuilder;
@@ -24,9 +27,11 @@ import java.util.HashMap;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 
-@ExtendWith(SpringExtension.class)
+//@ExtendWith(SpringExtension.class)
+@RunWith(SpringRunner.class)
+//@SpringBootTest
 @WebMvcTest(value = UserController.class)
-@WithMockUser
+//@WithMockUser
 public class UserControllerTest {
 
     @Autowired
diff --git a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpTest.java b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpTest.java
index 47e25ab..c617721 100644
--- a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpTest.java
+++ b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/UserServiceImpTest.java
@@ -12,6 +12,7 @@ import org.springframework.test.context.junit4.SpringRunner;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.BDDMockito.given;
 import static org.mockito.Mockito.when;
 
 /**
diff --git a/src/test/resources/contracts/registerNewUser_201.groovy b/src/test/resources/contracts/registerNewUser_201.groovy
new file mode 100644
index 0000000..c5026e2
--- /dev/null
+++ b/src/test/resources/contracts/registerNewUser_201.groovy
@@ -0,0 +1,25 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "Creates new user in the application"
+    request {
+        method POST()
+        url("/v2/user/register")
+        headers {
+            contentType applicationJson()
+        }
+        body(
+                "name": "non-existing",
+                "password": "foo",
+                "email": "foo@foo.foo"
+        )
+    }
+    response {
+        body(
+                "message" : "User successfully created"
+        )
+        status 201
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/contracts/registerNewUser_400.groovy b/src/test/resources/contracts/registerNewUser_400.groovy
new file mode 100644
index 0000000..058027d
--- /dev/null
+++ b/src/test/resources/contracts/registerNewUser_400.groovy
@@ -0,0 +1,25 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "User already exists"
+    request {
+        method POST()
+        url("/v2/user/register")
+        headers {
+            contentType applicationJson()
+        }
+        body(
+                "name": "foo",
+                "password": "foo",
+                "email": "foo@foo.foo"
+        )
+    }
+    response {
+        body(
+                "message" : "User exists"
+        )
+        status 400
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/swagger_prep/registerExistingUser.yaml b/src/test/resources/swagger_prep/registerExistingUser.yaml
new file mode 100644
index 0000000..8f3014d
--- /dev/null
+++ b/src/test/resources/swagger_prep/registerExistingUser.yaml
@@ -0,0 +1,65 @@
+openapi: 3.0.0
+info:
+    title: todo title
+    description: todo desc
+    version: 2.0.0
+
+paths:
+  /v2/user/register:
+    post:
+      summary: Registers a new user to the database
+      description: desc
+      requestBody:
+        required: true
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/User'
+            examples:
+              '201':
+                value:
+                  {
+                    name: non-existing,
+                    email: foo@foo.foo,
+                    password: foo
+                  }
+
+      responses:
+        '201':  #status code
+          description: TODO
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  type: string
+                  properties:
+                    message:
+                      type: string
+              examples:
+                '201':
+                  value:
+                    {
+                      message: User successfully created
+                    }
+
+components:
+  schemas:
+
+    User:
+      title: User
+      type: object
+      properties:
+        name:
+          type: string
+          description: User name
+        email:
+          type: string
+          description: User email
+        password:
+          type: string
+          description: User password
+      required:
+        - name
+        - email
+        - password
\ No newline at end of file
