Skip to content

Commit 7a06fe6

Browse files
authored
Merge pull request #18 from bobocode-projects/GP-55_CreateViewResolverExercise
Gp-55 create view resolver exercise
2 parents 9683916 + 42b20ad commit 7a06fe6

File tree

9 files changed

+270
-0
lines changed

9 files changed

+270
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>3-0-spring-framework</artifactId>
7+
<groupId>com.bobocode</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>3-0-2-view-resolver</artifactId>
13+
<packaging>war</packaging>
14+
15+
<properties>
16+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
17+
<maven.compiler.source>11</maven.compiler.source>
18+
<maven.compiler.target>11</maven.compiler.target>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.springframework</groupId>
24+
<artifactId>spring-webmvc</artifactId>
25+
<version>5.3.6</version>
26+
</dependency>
27+
28+
<dependency>
29+
<groupId>javax.servlet</groupId>
30+
<artifactId>javax.servlet-api</artifactId>
31+
<version>4.0.1</version>
32+
<scope>provided</scope>
33+
</dependency>
34+
35+
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
36+
<dependency>
37+
<groupId>org.springframework.boot</groupId>
38+
<artifactId>spring-boot-starter-test</artifactId>
39+
<version>2.4.5</version>
40+
<scope>test</scope>
41+
</dependency>
42+
43+
44+
</dependencies>
45+
46+
<build>
47+
<plugins>
48+
<plugin>
49+
<groupId>org.apache.maven.plugins</groupId>
50+
<artifactId>maven-war-plugin</artifactId>
51+
<version>3.3.0</version>
52+
</plugin>
53+
</plugins>
54+
</build>
55+
</project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.bobocode;
2+
3+
public class ViewResolverApp {
4+
public static void main(String[] args) {
5+
}
6+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.bobocode.config;
2+
3+
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
4+
5+
public class DispatcherServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
6+
@Override
7+
protected Class<?>[] getRootConfigClasses() {
8+
return new Class[0];
9+
}
10+
11+
@Override
12+
protected Class<?>[] getServletConfigClasses() {
13+
return new Class[]{ResolverConfig.class};
14+
}
15+
16+
@Override
17+
protected String[] getServletMappings() {
18+
return new String[]{"/"};
19+
}
20+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.bobocode.config;
2+
3+
public class ResolverConfig {
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.bobocode.controller;
2+
3+
public class HelloJspController {
4+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<html>
2+
<body>
3+
<h2>Hello World!</h2>
4+
</body>
5+
</html>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.bobocode;
2+
3+
import com.bobocode.config.ResolverConfig;
4+
import com.bobocode.controller.HelloJspController;
5+
import lombok.SneakyThrows;
6+
import org.junit.jupiter.api.*;
7+
import org.mockito.internal.configuration.ClassPathLoader;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
10+
import org.springframework.http.MediaType;
11+
import org.springframework.stereotype.Controller;
12+
import org.springframework.test.context.ContextConfiguration;
13+
import org.springframework.test.web.servlet.MockMvc;
14+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
15+
import org.springframework.validation.support.BindingAwareModelMap;
16+
import org.springframework.web.bind.annotation.GetMapping;
17+
import org.springframework.web.bind.annotation.RequestMapping;
18+
19+
import java.lang.reflect.Method;
20+
import java.util.Arrays;
21+
22+
import static org.junit.jupiter.api.Assertions.*;
23+
import static org.junit.jupiter.api.Assertions.assertTrue;
24+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
25+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
26+
27+
@WebMvcTest
28+
@ContextConfiguration(classes = ResolverConfig.class)
29+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
30+
public class HelloJspControllerTest {
31+
32+
@Autowired
33+
private MockMvc mockMvc;
34+
private final HelloJspController helloJspController = new HelloJspController();
35+
36+
@Test
37+
@Order(1)
38+
@DisplayName("Class marked as @Controller")
39+
void helloJspControllerClassMarkedAsController() {
40+
Controller controller = HelloJspController.class.getAnnotation(Controller.class);
41+
assertNotNull(controller);
42+
}
43+
44+
@Test
45+
@Order(2)
46+
@DisplayName("Class marked as @RequestMapping")
47+
void helloJspControllerClassMarkedAsRequestMapping() {
48+
RequestMapping requestMapping = HelloJspController.class.getAnnotation(RequestMapping.class);
49+
assertNotNull(requestMapping);
50+
}
51+
52+
@Test
53+
@Order(3)
54+
@DisplayName("Method that get hello page is marker with @GetMapping")
55+
void helloJspControllerHasMethodAnnotatedAsGetMapping() {
56+
boolean hasAnnotation = Arrays.stream(HelloJspController.class.getMethods())
57+
.anyMatch(method ->
58+
method.getAnnotation(GetMapping.class) != null
59+
);
60+
assertTrue(hasAnnotation);
61+
}
62+
63+
@Test
64+
@Order(4)
65+
@SneakyThrows
66+
@DisplayName("Get method returns view name \"hello\"")
67+
void helloJspControllerMethodReturnsHelloViewName() {
68+
Method method = Arrays.stream(HelloJspController.class.getMethods())
69+
.filter(m -> m.getAnnotation(GetMapping.class) != null)
70+
.findFirst()
71+
.orElseThrow();
72+
73+
var viewName = method.invoke(helloJspController);
74+
75+
assertEquals("hello", viewName);
76+
}
77+
78+
@Test
79+
@Order(5)
80+
@SneakyThrows
81+
@DisplayName("GET method is completed ✅")
82+
void getRequestShouldReturnStatusOkAndCorrectData() {
83+
mockMvc.perform(get("/"))
84+
.andExpect(status().isOk())
85+
.andExpect(view().name("hello"))
86+
.andExpect(MockMvcResultMatchers.forwardedUrl("/WEB-INF/views/hello.jsp"));
87+
}
88+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package com.bobocode;
2+
3+
import com.bobocode.config.ResolverConfig;
4+
import lombok.SneakyThrows;
5+
import org.junit.jupiter.api.*;
6+
import org.mockito.Mockito;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
9+
import org.springframework.context.annotation.ComponentScan;
10+
import org.springframework.context.annotation.Configuration;
11+
import org.springframework.test.context.ContextConfiguration;
12+
import org.springframework.test.web.servlet.MockMvc;
13+
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
14+
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
15+
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
16+
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
17+
18+
import java.lang.reflect.Method;
19+
20+
import static org.junit.jupiter.api.Assertions.*;
21+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
22+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
23+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
24+
25+
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
26+
public class ViewResolverTest {
27+
28+
private final ResolverConfig config = new ResolverConfig();
29+
private final ViewResolverRegistry resolverRegistry = Mockito.mock(ViewResolverRegistry.class);
30+
31+
@Test
32+
@Order(1)
33+
@DisplayName("Class is marked as @Configuration")
34+
void classIsMarkedAsConfiguration() {
35+
Configuration configuration = ResolverConfig.class.getAnnotation(Configuration.class);
36+
assertNotNull(configuration);
37+
}
38+
39+
@Test
40+
@Order(2)
41+
@DisplayName("Configuration Class has annotation @EnableWebMvc")
42+
void classAnnotatedWithEnableWebMvc() {
43+
EnableWebMvc enableWebMvc = ResolverConfig.class.getAnnotation(EnableWebMvc.class);
44+
assertNotNull(enableWebMvc);
45+
}
46+
47+
@Test
48+
@Order(3)
49+
@DisplayName("Configuration Class has annotation @ComponentScan")
50+
void classAnnotatedWithComponentScan() {
51+
ComponentScan componentScan = ResolverConfig.class.getAnnotation(ComponentScan.class);
52+
assertNotNull(componentScan);
53+
}
54+
55+
@Test
56+
@Order(4)
57+
@DisplayName("ComponentScan packages are indicated")
58+
void ComponentScanHasIndicatedPackages() {
59+
ComponentScan componentScan = ResolverConfig.class.getAnnotation(ComponentScan.class);
60+
assertEquals("com.bobocode", componentScan.basePackages()[0]);
61+
}
62+
63+
@Test
64+
@Order(5)
65+
@DisplayName("Config class implements WebMvcConfigurer interface")
66+
void isConfigClassImplementsWebMvcConfigurerInterface() {
67+
assertTrue(WebMvcConfigurer.class.isAssignableFrom(ResolverConfig.class));
68+
}
69+
70+
@SneakyThrows
71+
@Test
72+
@Order(6)
73+
@DisplayName("Config class overrides configureViewResolvers method")
74+
void isConfigurationClassContainsViewResolverMethod() {
75+
Method configureViewResolvers = ResolverConfig.class.getMethod("configureViewResolvers", ViewResolverRegistry.class);
76+
assertNotNull(configureViewResolvers);
77+
}
78+
79+
@Test
80+
@Order(7)
81+
@SneakyThrows
82+
@DisplayName("View resolver registry has correct prefix and suffix")
83+
void viewResolverRegistryHasCorrectPrefixAndSuffix() {
84+
config.getClass().getMethod("configureViewResolvers", ViewResolverRegistry.class).invoke(config, resolverRegistry);
85+
Mockito.verify(resolverRegistry).jsp("/WEB-INF/views/", ".jsp");
86+
}
87+
}

3-0-spring-framework/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
<module>3-0-0-hello-spring-framework</module>
1717
<module>3-0-1-hello-spring-mvc</module>
1818
<module>3-1-1-dispatcher-servlet-initializer</module>
19+
<module>3-0-2-view-resolver</module>
1920
<module>3-2-1-account-rest-api</module>
2021
</modules>
2122

0 commit comments

Comments
 (0)