From f047becb2f43e5b83353eb1296c2422c4492134e Mon Sep 17 00:00:00 2001 From: Caio Date: Tue, 2 Oct 2018 15:27:23 -0300 Subject: [PATCH 1/2] Making some JUnit tests --- demo/.gitignore | 3 + demo/.idea/workspace.xml | 641 +++++++++++++----- demo/pom.xml | 6 + .../easynotes/model/ApplicationUser.java | 2 - .../example/easynotes/model/AuditModel.java | 1 + .../com/example/easynotes/model/Note.java | 4 +- .../easynotes/security/WebSecurity.java | 24 +- .../src/main/resources/application.properties | 2 +- .../easynotes/EasyNotesApplicationTests.java | 16 - .../example/easynotes/NoteControllerTest.java | 184 +++++ .../example/easynotes/UserControllerTest.java | 104 +++ demo/target/classes/application.properties | 2 +- 12 files changed, 796 insertions(+), 193 deletions(-) delete mode 100644 demo/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java create mode 100644 demo/src/test/java/com/example/easynotes/NoteControllerTest.java create mode 100644 demo/src/test/java/com/example/easynotes/UserControllerTest.java diff --git a/demo/.gitignore b/demo/.gitignore index bd6fd30..94c6ff0 100644 --- a/demo/.gitignore +++ b/demo/.gitignore @@ -1,2 +1,5 @@ .idea/ .gradle/ +gradle/ +.DS_STORE +target/ \ No newline at end of file diff --git a/demo/.idea/workspace.xml b/demo/.idea/workspace.xml index 57e2b60..694c1c6 100644 --- a/demo/.idea/workspace.xml +++ b/demo/.idea/workspace.xml @@ -49,17 +49,6 @@ - - - - - - - - - - - - - @@ -354,7 +458,7 @@ - + @@ -362,6 +466,11 @@ + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -396,18 +600,54 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + @@ -415,10 +655,11 @@ + - - + + @@ -448,6 +689,36 @@ + + + + + file://$PROJECT_DIR$/src/test/java/com/example/easynotes/UserControllerTest.java + 49 + + + + file://$PROJECT_DIR$/src/test/java/com/example/easynotes/UserControllerTest.java + 47 + + + + file://$PROJECT_DIR$/src/test/java/com/example/easynotes/UserControllerTest.java + 74 + + + + file://$PROJECT_DIR$/src/test/java/com/example/easynotes/UserControllerTest.java + 73 + + + + + @@ -463,95 +734,122 @@ - + - + + + + - + - - + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + - - + + - - - + - - + + - + + - - + + + + - + + - - - - - + + - + - - + + - + + + + - - + + - - - - + - - + + @@ -560,75 +858,87 @@ - - + + - + - - + + - + - - + + + + + - + - - + + - + - - + + + + + + + + + - + - - + + + + - + - - + + - + - - + + @@ -637,58 +947,55 @@ - - + + - + - - - - - + + - + - - + + - + - - - - - + + - + - - + + - + - - + + + + + diff --git a/demo/pom.xml b/demo/pom.xml index b390cfe..f193dc9 100644 --- a/demo/pom.xml +++ b/demo/pom.xml @@ -72,6 +72,12 @@ modelmapper 2.3.0 + + org.springframework.security + spring-security-test + 4.0.0.RELEASE + test + diff --git a/demo/src/main/java/com/example/easynotes/model/ApplicationUser.java b/demo/src/main/java/com/example/easynotes/model/ApplicationUser.java index e71e609..a44cd7b 100644 --- a/demo/src/main/java/com/example/easynotes/model/ApplicationUser.java +++ b/demo/src/main/java/com/example/easynotes/model/ApplicationUser.java @@ -10,11 +10,9 @@ public class ApplicationUser extends AuditModel { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @NotNull @Column(unique = true) private String username; - @NotNull private String password; public ApplicationUser() { } diff --git a/demo/src/main/java/com/example/easynotes/model/AuditModel.java b/demo/src/main/java/com/example/easynotes/model/AuditModel.java index a48dde9..5ebfa5f 100644 --- a/demo/src/main/java/com/example/easynotes/model/AuditModel.java +++ b/demo/src/main/java/com/example/easynotes/model/AuditModel.java @@ -14,6 +14,7 @@ @EntityListeners(AuditingEntityListener.class) @JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true) public class AuditModel implements Serializable { + @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_at", nullable = false, updatable = false) @CreatedDate diff --git a/demo/src/main/java/com/example/easynotes/model/Note.java b/demo/src/main/java/com/example/easynotes/model/Note.java index 58d035e..ce7284c 100644 --- a/demo/src/main/java/com/example/easynotes/model/Note.java +++ b/demo/src/main/java/com/example/easynotes/model/Note.java @@ -11,11 +11,9 @@ public class Note extends AuditModel { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long noteId; - @NotNull @Lob private String title; - @NotNull @Lob private String content; @@ -40,7 +38,7 @@ public void setUser(ApplicationUser user) { this.user = user; } - protected Note() { } + public Note() { } public String getTitle() { return title; diff --git a/demo/src/main/java/com/example/easynotes/security/WebSecurity.java b/demo/src/main/java/com/example/easynotes/security/WebSecurity.java index 4e68982..a5a8e7f 100644 --- a/demo/src/main/java/com/example/easynotes/security/WebSecurity.java +++ b/demo/src/main/java/com/example/easynotes/security/WebSecurity.java @@ -26,17 +26,35 @@ public WebSecurity(UserDetailsServiceImpl userDetailsService, BCryptPasswordEnco } protected void configure(HttpSecurity httpSecurity) throws Exception{ - httpSecurity.cors().and().csrf().disable().authorizeRequests().antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll().anyRequest().authenticated().and().addFilter(new JWTAuthenticationFilter(authenticationManager())).addFilter(new JWTAuthorizationFilter(authenticationManager())).sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + httpSecurity + .cors() + .and() + .csrf() + .disable() + .authorizeRequests() + .antMatchers(HttpMethod.POST, SIGN_UP_URL) + .permitAll() + .anyRequest() + .authenticated() + .and() + .addFilter(new JWTAuthenticationFilter(authenticationManager())) + .addFilter(new JWTAuthorizationFilter(authenticationManager())) + .sessionManagement() + .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{ - authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder); + authenticationManagerBuilder + .userDetailsService(userDetailsService) + .passwordEncoder(bCryptPasswordEncoder); } @Bean CorsConfigurationSource corsConfigurationSource(){ final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); - source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues()); + source + .registerCorsConfiguration("/**", new CorsConfiguration() + .applyPermitDefaultValues()); return source; } } diff --git a/demo/src/main/resources/application.properties b/demo/src/main/resources/application.properties index c236fd8..523e585 100644 --- a/demo/src/main/resources/application.properties +++ b/demo/src/main/resources/application.properties @@ -11,7 +11,7 @@ debug=true spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect #Hibernate ddl auto (creat, creat-drop, validate, update) -spring.jpa.hibernate.ddl-auto = create-drop +spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy spring.jpa.show-sql=true \ No newline at end of file diff --git a/demo/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java b/demo/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java deleted file mode 100644 index 4bf539c..0000000 --- a/demo/src/test/java/com/example/easynotes/EasyNotesApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.example.easynotes; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@SpringBootTest -public class EasyNotesApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/demo/src/test/java/com/example/easynotes/NoteControllerTest.java b/demo/src/test/java/com/example/easynotes/NoteControllerTest.java new file mode 100644 index 0000000..d8e68c0 --- /dev/null +++ b/demo/src/test/java/com/example/easynotes/NoteControllerTest.java @@ -0,0 +1,184 @@ +package com.example.easynotes; + +import com.example.easynotes.controller.NoteController; +import com.example.easynotes.dto.DtoManager; +import com.example.easynotes.dto.NotesDto; +import com.example.easynotes.model.ApplicationUser; +import com.example.easynotes.model.Note; +import com.example.easynotes.service.UserDetailsServiceImpl; +import com.example.easynotes.service.UserService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.text.ParseException; +import java.util.List; +import static java.util.Collections.singletonList; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.core.Is.is; +import static org.mockito.BDDMockito.given; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringRunner.class) +@SpringBootTest( + classes = EasyNotesApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ContextConfiguration +@AutoConfigureMockMvc +public class NoteControllerTest { + + @Autowired + private MockMvc mvc; + + @MockBean + private NoteController noteController; + + @MockBean + private UserService userService; + + private DtoManager dtoManager = new DtoManager(); + + @InjectMocks + private UserDetailsServiceImpl userDetailsService = new UserDetailsServiceImpl(userService); + + @Test + public void getNotesByUserId() throws ParseException, Exception { + ApplicationUser user = createUser(); + + UserDetails userDetails = userDetailsService.loadUserByUsername("caio"); + + Authentication authToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authToken); + + Note note = createNote(user); + + NotesDto notesDto = dtoManager.convertToDto(note); + List allNotes = singletonList(notesDto); + + given(noteController.getAllNotesByUserId(user.getId())) + .willReturn(allNotes); + + mvc.perform(get("/1/notes") + .with(user("root").password("mysql")) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$", hasSize(1))) + .andExpect(jsonPath("$[0].title", is(note.getTitle()))); + } + + @Test + public void getNoteByUserAndNoteId() throws Exception, ParseException { + ApplicationUser user = createUser(); + + UserDetails userDetails = userDetailsService.loadUserByUsername("caio"); + + Authentication authToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authToken); + + Note note = createNote(user); + + NotesDto notesDto = dtoManager.convertToDto(note); + + given(noteController.getNoteByUserIdAndNoteId(user.getId(), note.getNoteId())) + .willReturn(notesDto); + + mvc.perform(get("/1/notes/1") + .with(user("blaze") + .password("Q1w2e3r4")) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("title", is(note.getTitle()))); + } + + + //Put + @Test + public void updateNote() throws ParseException, Exception { + ApplicationUser user = createUser(); + + UserDetails userDetails = userDetailsService.loadUserByUsername("caio"); + + Authentication authToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authToken); + + Note note = createNote(user); + + Note noteToUpdate = new Note(); + note.setTitle("test 2"); + note.setContent("testingg"); + note.setUser(user); + + NotesDto notesDto = dtoManager.convertToDto(note); + + NotesDto noteUpdatedDto = dtoManager.convertToDto(noteToUpdate); + + given(noteController.updateNote(note.getNoteId(), noteUpdatedDto)) + .willReturn(notesDto); + + mvc.perform(put("/notes/1") + .with(user("blaze") + .password("Q1w2e3r4")) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("title", is(noteUpdatedDto.getTitle()))); + } + + + //Delete + @Test + public void removeNoteByNoteId() throws ParseException, Exception { + ApplicationUser user = createUser(); + + UserDetails userDetails = userDetailsService.loadUserByUsername("caio"); + + Authentication authToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authToken); + + Note note = createNote(user); + + NotesDto notesDto = dtoManager.convertToDto(note); + + mvc.perform(delete("/notes/1") + .with(user("blaze") + .password("Q1w2e3r4")) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + public ApplicationUser createUser(){ + ApplicationUser user = new ApplicationUser(); + user.setUsername("caio"); + user.setPassword("test"); + return user; + } + + public Note createNote(ApplicationUser user){ + Note note = new Note(); + note.setTitle("test 1"); + note.setContent("testing"); + note.setUser(user); + return note; + } + +} diff --git a/demo/src/test/java/com/example/easynotes/UserControllerTest.java b/demo/src/test/java/com/example/easynotes/UserControllerTest.java new file mode 100644 index 0000000..129def8 --- /dev/null +++ b/demo/src/test/java/com/example/easynotes/UserControllerTest.java @@ -0,0 +1,104 @@ +package com.example.easynotes; + +import com.example.easynotes.controller.UserController; +import com.example.easynotes.dto.ApplicationUserDto; +import com.example.easynotes.dto.DtoManager; +import com.example.easynotes.model.ApplicationUser; + +import com.example.easynotes.service.UserDetailsServiceImpl; +import com.example.easynotes.service.UserService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + +import java.text.ParseException; +import static org.hamcrest.core.Is.is; +import static org.mockito.BDDMockito.given; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@RunWith(SpringRunner.class) +@SpringBootTest( + classes = EasyNotesApplication.class, + webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +@ContextConfiguration +@AutoConfigureMockMvc +public class UserControllerTest { + + @Autowired + private MockMvc mvc; + + @MockBean + private UserController userController; + + DtoManager dtoManager = new DtoManager(); + + @MockBean + private UserService userService; + + @InjectMocks + private UserDetailsServiceImpl userDetailsService = new UserDetailsServiceImpl(userService); + + //delete + @Test + public void deleteUser() throws Exception { + ApplicationUser user = createUser(); + + UserDetails userDetails = userDetailsService.loadUserByUsername("caio"); + + Authentication authToken = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities()); + + SecurityContextHolder.getContext().setAuthentication(authToken); + + mvc.perform(delete("/users/"+user.getId()) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()); + } + + + //put + @Test + public void updateUser() throws ParseException, Exception { + ApplicationUser user = createUser(); + + ApplicationUser userRequest = new ApplicationUser(); + userRequest.setPassword("caioo"); + userRequest.setUsername("testt"); + + ApplicationUserDto userRequestDto = dtoManager.convertToDto(userRequest); + + given(userController.updateUser(user.getId(), userRequest)) + .willReturn(userRequestDto); + + mvc.perform(put("/users/"+ user.getId()) + .with(user("blaze").password("Q1w2e3r4")) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("username", is(userRequestDto.getUsername()))); + } + + + public ApplicationUser createUser(){ + ApplicationUser user = new ApplicationUser(); + user.setUsername("caio"); + user.setPassword("test"); + return user; + } + +} diff --git a/demo/target/classes/application.properties b/demo/target/classes/application.properties index c236fd8..523e585 100644 --- a/demo/target/classes/application.properties +++ b/demo/target/classes/application.properties @@ -11,7 +11,7 @@ debug=true spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect #Hibernate ddl auto (creat, creat-drop, validate, update) -spring.jpa.hibernate.ddl-auto = create-drop +spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.naming.implicit-strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy spring.jpa.show-sql=true \ No newline at end of file From 8a028e1c4c9da1b8b9078e8daf37047d5116e5f6 Mon Sep 17 00:00:00 2001 From: Caio Date: Thu, 4 Oct 2018 13:27:17 -0300 Subject: [PATCH 2/2] Adding UserService and N ote Service tests --- demo/.idea/workspace.xml | 507 +++++++++++------- .../easynotes/controller/NoteController.java | 4 +- .../easynotes/dto/ApplicationUserDto.java | 2 +- .../com/example/easynotes/dto/DtoManager.java | 22 +- .../com/example/easynotes/dto/NotesDto.java | 25 +- .../easynotes/model/ApplicationUser.java | 38 +- .../example/easynotes/model/AuditModel.java | 43 -- .../com/example/easynotes/model/Note.java | 38 +- .../easynotes/service/NoteService.java | 24 +- .../easynotes/service/UserService.java | 13 +- .../src/main/resources/application.properties | 4 +- .../controller}/NoteControllerTest.java | 18 +- .../controller}/UserControllerTest.java | 7 +- .../tests/service/NoteServiceTest.java | 132 +++++ .../tests/service/UserServiceTest.java | 87 +++ demo/target/classes/application.properties | 4 +- 16 files changed, 697 insertions(+), 271 deletions(-) delete mode 100644 demo/src/main/java/com/example/easynotes/model/AuditModel.java rename demo/src/test/java/com/example/easynotes/{ => tests/controller}/NoteControllerTest.java (91%) rename demo/src/test/java/com/example/easynotes/{ => tests/controller}/UserControllerTest.java (96%) create mode 100644 demo/src/test/java/com/example/easynotes/tests/service/NoteServiceTest.java create mode 100644 demo/src/test/java/com/example/easynotes/tests/service/UserServiceTest.java diff --git a/demo/.idea/workspace.xml b/demo/.idea/workspace.xml index 694c1c6..4b8a910 100644 --- a/demo/.idea/workspace.xml +++ b/demo/.idea/workspace.xml @@ -240,6 +240,8 @@ getUser + TypeMap + convertFrom $PROJECT_DIR$/src/main/java/com/example/easynotes/dto @@ -267,29 +269,33 @@ @@ -326,8 +332,6 @@ - - @@ -379,6 +383,15 @@ + + + + + + + + + @@ -441,12 +454,32 @@ - + + + + + + + + + + + + + + + + + + +