commit fbce8e7582a6ab27fe73c8690491cf159f09bc82
Author: Hrabikv <hrabikv@students.zcu.cz>
Date:   Sun Apr 30 15:23:59 2023 +0200

    #10519 vytvoření kotraktů pro login, registraci a častečně logout

diff --git a/pom.xml b/pom.xml
index bd30b95..ca0c002 100644
--- a/pom.xml
+++ b/pom.xml
@@ -140,6 +140,13 @@
 			<scope>test</scope>
 		</dependency>
 
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-inline</artifactId>
+			<version>3.4.6</version>
+			<scope>test</scope>
+		</dependency>
+
 		<!-- json library with minimal overhead -->
 		<dependency>
 			<groupId>com.googlecode.json-simple</groupId>
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
index 02281e0..bac00c9 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
@@ -46,6 +46,8 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
 
     private String AUTH_URL_REFRESH = "http://localhost:8081/refresh";
 
+    @Autowired
+    private RequestBuilder requestBuilder;
     /**
      *
      */
@@ -57,7 +59,7 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
 
     public ResponseEntity<String> authenticate(String token) {
 
-        return RequestBuilder.sendRequestResponse(AUTH_URL_AUTH, token);
+        return requestBuilder.sendRequestResponse(AUTH_URL_AUTH, token);
     }
 
     public ResponseEntity<String> loginUser(User user) {
@@ -71,7 +73,7 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
 
         requestBody.put("name", userName);
 
-        return RequestBuilder.sendRequestResponse(AUTH_URL_LOGIN, requestBody);
+        return requestBuilder.sendRequestResponse(AUTH_URL_LOGIN, requestBody);
     }
 
     public ResponseEntity<String> logoutUser(User user) {
@@ -88,12 +90,12 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
         requestBody.put("name", userName);
         requestBody.put("token", token);
 
-        return RequestBuilder.sendRequestResponse(AUTH_URL_LOGOUT, requestBody);
+        return requestBuilder.sendRequestResponse(AUTH_URL_LOGOUT, requestBody);
     }
 
     @Override
     public ResponseEntity<String> refreshToken(String token) {
-        return RequestBuilder.sendRequestResponse(AUTH_URL_REFRESH, token, true);
+        return requestBuilder.sendRequestResponse(AUTH_URL_REFRESH, token, true);
     }
 
     @Override
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
index 661918c..a39571e 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
@@ -3,6 +3,7 @@ package cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.httpErrorHandler.CustomErrorHandler;
 import org.json.simple.JSONObject;
 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
 import org.springframework.web.client.HttpClientErrorException;
 import org.springframework.web.client.HttpServerErrorException;
 import org.springframework.web.client.HttpStatusCodeException;
@@ -17,12 +18,11 @@ import org.springframework.http.*;
 
 import javax.servlet.http.HttpServletRequest;
 
+@Component
 public class RequestBuilder {
     private static Logger logger = Logger.getLogger(RequestBuilder.class.getName());
 
-
-
-    public static ResponseEntity<String> sendRequestResponse(String url, Map<String, Object> body) {
+    public ResponseEntity<String> sendRequestResponse(String url, Map<String, Object> body) {
         RestTemplate restTemplate = new RestTemplate();
         restTemplate.setErrorHandler(new CustomErrorHandler());
         restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
@@ -35,7 +35,7 @@ public class RequestBuilder {
         return restTemplate.postForEntity(url, entity, String.class);
     }
 
-    public static ResponseEntity<String> sendRequestResponse(String url, String token) {
+    public ResponseEntity<String> sendRequestResponse(String url, String token) {
         RestTemplate restTemplate = new RestTemplate();
         //custom error handler to handle http response
         restTemplate.setErrorHandler(new CustomErrorHandler());
@@ -52,7 +52,7 @@ public class RequestBuilder {
 
     }
 
-    public static ResponseEntity<String> sendRequestResponse(String url, String token, boolean get) {
+    public ResponseEntity<String> sendRequestResponse(String url, String token, boolean get) {
         RestTemplate restTemplate = new RestTemplate();
         restTemplate.setErrorHandler(new CustomErrorHandler());
         restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
@@ -68,7 +68,7 @@ public class RequestBuilder {
     }
 
 
-    public static ResponseEntity<String> sendRequestResponse(String url, Map<String, Object> body, String token) {
+    public ResponseEntity<String> sendRequestResponse(String url, Map<String, Object> body, String token) {
         RestTemplate restTemplate = new RestTemplate();
         restTemplate.setErrorHandler(new CustomErrorHandler());
         restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
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
index 7a1a7e3..5ebed08 100644
--- 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
@@ -2,14 +2,20 @@ package cz.zcu.fav.kiv.antipatterndetectionapp.v2.controller;
 
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.User;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.repository.UserRepository;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.JSONBuilder;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.RequestBuilder;
 import io.restassured.module.mockmvc.RestAssuredMockMvc;
 import org.junit.jupiter.api.BeforeEach;
 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.http.ResponseEntity;
 import org.springframework.web.context.WebApplicationContext;
 
-import static org.mockito.ArgumentMatchers.any;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.when;
 
 @SpringBootTest()
@@ -21,13 +27,47 @@ public abstract class BaseTest {
     @MockBean
     private UserRepository userRepository;
 
+    @MockBean
+    private RequestBuilder requestBuilder;
+
     @BeforeEach
     public void init() {
-        User user = new User("foo", "foo@foo.foo", "foo");
+        User user = new User("foo", "foo@foo.foo", "76D3BC41C9F588F7FCD0D5BF4718F8F84B1C41B20882703100B9EB9413807C01");
+        User userWrongPassword = new User("foo", "foo@foo.foo", "foo");
+        ResponseEntity<String> loginResponse = ResponseEntity.ok("token");
 
-        when(userRepository.findByName("non-existing")).thenReturn(null);
-        when(userRepository.findByName("foo")).thenReturn(user);
+
+        /* Registration of user */
+        when(userRepository.findByName("new_user")).thenReturn(null);
+        when(userRepository.findByName("existing")).thenReturn(user);
         when(userRepository.save(any(User.class))).thenReturn(user);
+
+        /* Login of user */
+        when(userRepository.findByName("existing")).thenReturn(user);
+        when(requestBuilder.sendRequestResponse(eq("http://localhost:8081/login"), anyMap())).thenReturn(loginResponse);
+        when(userRepository.findByName("non_existing")).thenReturn(null);
+        when(userRepository.findByName("foo")).thenReturn(userWrongPassword);
+
+        /* Filter mock */
+        Map<String,Object> filterJson = new HashMap<>();
+        filterJson.put("message", "User authorized");
+        String filterBody = JSONBuilder.buildJSON(filterJson);
+        ResponseEntity<String> oauth = ResponseEntity.ok(filterBody);
+        when(requestBuilder.sendRequestResponse(anyString(), eq("token"))).thenReturn(oauth);
+
+        Map<String,Object> filterJson2 = new HashMap<>();
+        filterJson2.put("message", "User unauthorized");
+        String filterBody2 = JSONBuilder.buildJSON(filterJson2);
+        ResponseEntity<String> oauth2 = ResponseEntity.status(500).body(filterBody2);
+        when(requestBuilder.sendRequestResponse(anyString(), eq("wrong"))).thenReturn(oauth2);
+
+        /* Logout of user */
+        Map<String,Object> logoutJson = new HashMap<>();
+        logoutJson.put("message", "User logged out");
+        String logoutBody = JSONBuilder.buildJSON(logoutJson);
+        ResponseEntity<String> logoutResponse = ResponseEntity.ok(logoutBody);
+        when(requestBuilder.sendRequestResponse(eq("http://localhost:8081/logout"), anyMap())).thenReturn(logoutResponse);
+
         RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
     }
 
diff --git a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImplTest.java b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImplTest.java
index 63c66df..0eac8c2 100644
--- a/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImplTest.java
+++ b/src/test/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImplTest.java
@@ -1,100 +1,110 @@
-//package cz.zcu.fav.kiv.antipatterndetectionapp.v2.service;
-//
-//import cz.zcu.fav.kiv.antipatterndetectionapp.v2.dials.UserModelStatusCodes;
-//import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.User;
-//import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.JSONBuilder;
-//import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.RequestBuilder;
-//import org.junit.Test;
-//import org.junit.runner.RunWith;
-//import org.mockito.MockedStatic;
-//import org.mockito.Mockito;
-//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.http.HttpStatus;
-//import org.springframework.http.ResponseEntity;
-//import org.springframework.test.context.junit4.SpringRunner;
-//import java.util.HashMap;
-//import java.util.Map;
-//
-//import static org.junit.jupiter.api.Assertions.assertEquals;
-//import static org.mockito.ArgumentMatchers.*;
-//import static org.mockito.Mockito.mock;
-//import static org.mockito.Mockito.when;
-//
-//@RunWith(SpringRunner.class)
-//@SpringBootTest
-//public class OAuthServiceImplTest {
-//
-//    @Autowired
-//    private OAuthService oAuthService;
-//
-//    /**
-//     * Mocked User
-//     */
-//    private final User mockUser = new User("foo", "foo@foo.cz", "foo");
-//    private final String sampleToken = "eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyMGU4NmJiMC1lMDU4LTQwYTMtYjQyZC02ZTBjOWIyMmQ5MWQiL" +
-//            "CJzdWIiOiJmb28iLCJpYXQiOjE2ODE0MTY2ODAsImV4cCI6MTY4MTQxNjk4MH0.YJTwPEI4njQqYRuLGilf_oVl0gGD5BWFmdolk1O" +
-//            "vYWIgTcoIAFwh6bwqrW7XM6Hlj-ItYj9EmihYIqN5gfJVtg";
-//    // valid user logged in - http response with code 200 and token in body is expected
-//    @Test
-//    public void loginValidUser(){
-//        ResponseEntity<String> response = ResponseEntity.ok().body(sampleToken);
-//        try(MockedStatic<RequestBuilder> requestBuilderMockedStatic = Mockito.mockStatic(RequestBuilder.class)){
-//               requestBuilderMockedStatic.when(() -> RequestBuilder.sendRequestResponse(anyString(), anyMap())).thenReturn(response);
-//            ResponseEntity<String> response1 = oAuthService.loginUser(mockUser);
-//
-//            assertEquals(response, response1);
-//        }
-//    }
-//
-//    // return 200 response if valid user is trying to authenticate
-//    @Test
-//    public void authenticateValidUser(){
-//        ResponseEntity<String> expectedResponse = ResponseEntity.ok().body(mockUser.getName());
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.service;
+
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.model.User;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.JSONBuilder;
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.utils.RequestBuilder;
+import org.junit.jupiter.api.Test;
+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.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.when;
+
+@SpringBootTest
+public class OAuthServiceImplTest {
+
+    @Autowired
+    private OAuthService oAuthService;
+
+    @MockBean
+    private RequestBuilder requestBuilder;
+
+    /**
+     * Mocked User
+     */
+    private final User mockUser = new User("foo", "foo@foo.cz", "foo");
+    private final String sampleToken = "eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyMGU4NmJiMC1lMDU4LTQwYTMtYjQyZC02ZTBjOWIyMmQ5MWQiL" +
+            "CJzdWIiOiJmb28iLCJpYXQiOjE2ODE0MTY2ODAsImV4cCI6MTY4MTQxNjk4MH0.YJTwPEI4njQqYRuLGilf_oVl0gGD5BWFmdolk1O" +
+            "vYWIgTcoIAFwh6bwqrW7XM6Hlj-ItYj9EmihYIqN5gfJVtg";
+    // valid user logged in - http response with code 200 and token in body is expected
+    @Test
+    public void loginValidUser() {
+        ResponseEntity<String> response = ResponseEntity.ok().body(sampleToken);
+
+        when(requestBuilder.sendRequestResponse(anyString(), anyMap())).thenReturn(response);
+        ResponseEntity<String> response1 = oAuthService.loginUser(mockUser);
+        assertEquals(response, response1);
+
+    }
+
+    // return 200 response if valid user is trying to authenticate
+    @Test
+    public void authenticateValidUser() {
+        ResponseEntity<String> expectedResponse = ResponseEntity.ok().body(mockUser.getName());
+
+        when(requestBuilder.sendRequestResponse(anyString(), anyString())).thenReturn(expectedResponse);
+        ResponseEntity<String> response1 = oAuthService.authenticate(sampleToken);
+        assertEquals(expectedResponse, response1);
+
 //        try(MockedStatic<RequestBuilder> requestBuilderMockedStatic = Mockito.mockStatic(RequestBuilder.class)){
 //            requestBuilderMockedStatic.when(() -> RequestBuilder.sendRequestResponse(anyString(), anyString())).thenReturn(expectedResponse);
 //            ResponseEntity<String> response = oAuthService.authenticate(sampleToken);
 //            assertEquals(expectedResponse, response);
 //        }
-//
-//    }
-//
-//    // return 401 if unauthorized user is trying to authenticate
-//    @Test
-//    public void authenticateInvalidUser(){
-//        ResponseEntity<String> expectedResponse = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(mockUser.getName());
+
+    }
+
+    // return 401 if unauthorized user is trying to authenticate
+    @Test
+    public void authenticateInvalidUser() {
+        ResponseEntity<String> expectedResponse = ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(mockUser.getName());
+
+        when(requestBuilder.sendRequestResponse(anyString(), anyString())).thenReturn(expectedResponse);
+        ResponseEntity<String> response1 = oAuthService.authenticate(sampleToken);
+        assertEquals(expectedResponse, response1);
+
 //        try(MockedStatic<RequestBuilder> requestBuilderMockedStatic = Mockito.mockStatic(RequestBuilder.class)){
 //            requestBuilderMockedStatic.when(() -> RequestBuilder.sendRequestResponse(anyString(), anyString())).thenReturn(expectedResponse);
 //            ResponseEntity<String> response = oAuthService.authenticate(sampleToken);
 //            assertEquals(expectedResponse, response);
 //        }
-//
-//    }
-//    @Test
-//    public void logoutUser(){
-//        Map<String,Object> json = new HashMap<>();
-//        json.put("message","ok");
-//        //have to set token to the user - in this scenario we assume user is logged in
-//        mockUser.setToken(sampleToken);
-//        String jsonString = JSONBuilder.buildJSON(json);
-//        ResponseEntity<String> expectedResponse = ResponseEntity.status(HttpStatus.OK).body(jsonString);
+
+    }
+    @Test
+    public void logoutUser() {
+        Map<String,Object> json = new HashMap<>();
+        json.put("message","ok");
+        //have to set token to the user - in this scenario we assume user is logged in
+        mockUser.setToken(sampleToken);
+        String jsonString = JSONBuilder.buildJSON(json);
+        ResponseEntity<String> expectedResponse = ResponseEntity.status(HttpStatus.OK).body(jsonString);
+
+        when(requestBuilder.sendRequestResponse(anyString(), anyMap())).thenReturn(expectedResponse);
+        ResponseEntity<String> response1 = oAuthService.logoutUser(mockUser);
+        assertEquals(expectedResponse, response1);
+
 //        try(MockedStatic<RequestBuilder> requestBuilderMockedStatic = Mockito.mockStatic(RequestBuilder.class)){
 //            requestBuilderMockedStatic.when(() -> RequestBuilder.sendRequestResponse(anyString(), anyMap())).thenReturn(expectedResponse);
 //            ResponseEntity<String> response = oAuthService.logoutUser(mockUser);
 //            assertEquals(expectedResponse, response);
 //        }
-//
-//
-//    }
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//
-//}
+
+
+    }
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/src/test/resources/contracts/loginUser_200.groovy b/src/test/resources/contracts/loginUser_200.groovy
new file mode 100644
index 0000000..8039b2b
--- /dev/null
+++ b/src/test/resources/contracts/loginUser_200.groovy
@@ -0,0 +1,25 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "Login of registered user."
+    request {
+        method POST()
+        url("/v2/user/login")
+        headers {
+            contentType applicationJson()
+        }
+        body(
+                "name": "existing",
+                "password": "foo"
+        )
+    }
+    response {
+        body(
+                "message": "User logged in successfully",
+                "jwtToken": "token"
+        )
+        status 200
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/contracts/loginUser_401_1.groovy b/src/test/resources/contracts/loginUser_401_1.groovy
new file mode 100644
index 0000000..9554b4b
--- /dev/null
+++ b/src/test/resources/contracts/loginUser_401_1.groovy
@@ -0,0 +1,24 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "Login of unregistered user."
+    request {
+        method POST()
+        url("/v2/user/login")
+        headers {
+            contentType applicationJson()
+        }
+        body(
+                "name": "non_existing",
+                "password": "foo"
+        )
+    }
+    response {
+        body(
+                "message" : "User login failed"
+        )
+        status 401
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/contracts/loginUser_401_2.groovy b/src/test/resources/contracts/loginUser_401_2.groovy
new file mode 100644
index 0000000..a913c73
--- /dev/null
+++ b/src/test/resources/contracts/loginUser_401_2.groovy
@@ -0,0 +1,24 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "Login of registered user with wrong password."
+    request {
+        method POST()
+        url("/v2/user/login")
+        headers {
+            contentType applicationJson()
+        }
+        body(
+                "name": "foo",
+                "password": "wrong"
+        )
+    }
+    response {
+        body(
+                "message" : "User login failed"
+        )
+        status 401
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/contracts/logoutUser_200.groovy b/src/test/resources/contracts/logoutUser_200.groovy
new file mode 100644
index 0000000..327de7f
--- /dev/null
+++ b/src/test/resources/contracts/logoutUser_200.groovy
@@ -0,0 +1,24 @@
+package contracts
+
+import org.springframework.cloud.contract.spec.Contract
+
+Contract.make {
+    description "Logout of logged in user."
+    request {
+        method POST()
+        url("/v2/user/logout")
+        headers {
+            header("Authorization": "Bearer token")
+            contentType applicationJson()
+        }
+        body(
+                "name": "existing"
+        )
+    }
+    response {
+        body(
+                "message": "User logged out"
+        )
+        status 200
+    }
+}
\ No newline at end of file
diff --git a/src/test/resources/contracts/registerNewUser_201.groovy b/src/test/resources/contracts/registerNewUser_201.groovy
index c5026e2..5e7c494 100644
--- a/src/test/resources/contracts/registerNewUser_201.groovy
+++ b/src/test/resources/contracts/registerNewUser_201.groovy
@@ -11,7 +11,7 @@ Contract.make {
             contentType applicationJson()
         }
         body(
-                "name": "non-existing",
+                "name": "new_user",
                 "password": "foo",
                 "email": "foo@foo.foo"
         )
diff --git a/src/test/resources/contracts/registerNewUser_400.groovy b/src/test/resources/contracts/registerNewUser_400.groovy
index 058027d..e05d84a 100644
--- a/src/test/resources/contracts/registerNewUser_400.groovy
+++ b/src/test/resources/contracts/registerNewUser_400.groovy
@@ -11,7 +11,7 @@ Contract.make {
             contentType applicationJson()
         }
         body(
-                "name": "foo",
+                "name": "existing",
                 "password": "foo",
                 "email": "foo@foo.foo"
         )
