Skip to content
Merged

Fix #57

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import pl.luczak.michal.joboffersapp.ports.input.offer.OfferSchedulerPort;
import pl.luczak.michal.joboffersapp.ports.output.OfferService;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.bean.override.mockito.MockitoSpyBean;
import pl.luczak.michal.joboffersapp.ports.input.offer.OfferSchedulerPort;

import java.time.Duration;
Expand All @@ -20,7 +21,7 @@
@SpringBootTest(properties = "job-offers.offer.scheduler.fixed-rate=PT1S")
class OfferSchedulerTest {

@SpyBean
@MockitoSpyBean
private OfferSchedulerPort offerScheduler;

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import java.util.UUID;

/**
* @param <RP> Response
* @param <RQ> Request
* @param <Response> Response
* @param <Request> Request
**/

public interface OfferControllerPort<RP, RQ> {
public interface OfferControllerPort<Response, Request> {

RP saveOffer(RQ rq);
Response saveOffer(Request rq);

RP findAllOffers();
Response findAllOffers();

RP findOfferById(UUID uniqueID);
Response findOfferById(UUID uniqueID);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package pl.luczak.michal.joboffersapp.ports.input.user;

/**
* @param <RQ> request
* @param <RP> response
* @param <Request> request
* @param <Response> response
**/
public interface UserControllerPort<RP, RQ> {
public interface UserControllerPort<Response, Request> {

RP register(RQ rq);
Response register(Request request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ void should_successfully_find_offer_by_id() {

@Test
void should_unsuccessfully_find_offer_by_id_and_throw_OfferNotFoundException() {
//then
var uuid = UUID.randomUUID();
assertThrows(
OfferNotFoundException.class,
() -> offerFacade.findOfferById(UUID.randomUUID())
() -> offerFacade.findOfferById(uuid)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Builder;
import org.springframework.context.annotation.PropertySource;

@Builder
public record OfferSaveRequest(
@NotNull(message = "{not.null}")
@NotBlank(message = "{not.blank}")
@Pattern(
regexp = "https:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)",
regexp = "https://(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)",
message = "{wrong.link.pattern}"
)
@JsonProperty("offerUrl")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
import pl.luczak.michal.joboffersapp.offer.IOfferDTOMapper;
import pl.luczak.michal.joboffersapp.offer.dto.OfferDTO;

import java.util.UUID;

@Service
class OfferSaveRequestToOfferDTOMapper implements IOfferDTOMapper<OfferSaveRequest> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import pl.luczak.michal.joboffersapp.OfferSaveRequest;
import pl.luczak.michal.joboffersapp.offer.OfferAlreadyExistsException;
import pl.luczak.michal.joboffersapp.offer.OfferNotFoundException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class OfferFetcher implements OfferFetcherPort<OfferRequestDTO> {
@Override
public List<OfferRequestDTO> fetchOffers() {
log.warn("Fetching offers from external server...");
String url = UriComponentsBuilder.fromHttpUrl(getUrlService("/offers"))
String url = UriComponentsBuilder.fromUriString(getUrlService("/offers"))
.toUriString();
ResponseEntity<List<OfferRequestDTO>> response = restTemplate.exchange(
url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ RestTemplate restTemplate(
) {
return new RestTemplateBuilder()
.errorHandler(restTemplateResponseErrorHandler)
.setConnectTimeout(
.connectTimeout(
Duration.ofMillis(restTemplateConfigProperties.connectionTimeOut())
)
.setReadTimeout(
.readTimeout(
Duration.ofMillis(restTemplateConfigProperties.readTimeOut())
)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ public List<OfferDTO> findAllOffers() {
@Override
public List<UUID> saveAllOffers(List<OfferDTO> offerDTOs) {
List<UUID> uniqueIDs = new LinkedList<>();
offerDTOs.forEach(offerDTO -> {
uniqueIDs.add(saveOffer(offerDTO));
});
offerDTOs.forEach(offerDTO -> uniqueIDs.add(saveOffer(offerDTO)));
return uniqueIDs;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
import pl.luczak.michal.joboffersapp.offer.dto.OfferDTO;
import pl.luczak.michal.joboffersapp.utils.SamplesOffersResponse;

import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class OfferDTOMapperTest implements SamplesOffersResponse {

Expand All @@ -31,7 +29,6 @@ void setUp() {

@Test
void should_map_OfferDTO_to_OfferDocument() {
// GIVEN && WHEN && THEN
assertThat(offerDTOMapper.fromOfferDTO(offerDTO))
.usingRecursiveComparison()
.ignoringFields("uniqueID")
Expand All @@ -40,7 +37,6 @@ void should_map_OfferDTO_to_OfferDocument() {

@Test
void should_map_OfferDocument_to_OfferDTO() {
// GIVEN && WHEN && THEN
assertThat(offerDTOMapper.apply(offerDocument))
.usingRecursiveComparison()
.ignoringFields("uniqueID")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;

@WebMvcTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class UserDAOAdapterTest {
private UserDAOAdapter userDAOAdapter;

@BeforeEach
public void setUp() {
void setUp() {
MockitoAnnotations.openMocks(this);
}

Expand All @@ -56,7 +56,7 @@ void should_successfully_save_user_and_returns_user_id() {
}

@Test
public void should_throw_UserIdDuplicationException() {
void should_throw_UserIdDuplicationException() {
// GIVEN
UserDTO userDTO = new UserDTO(1L, "username", "password");
UserEntity userEntity = new UserEntity();
Expand All @@ -77,7 +77,7 @@ public void should_throw_UserIdDuplicationException() {
}

@Test
public void delete_SuccessfullyDeleted_ReturnsUserId() {
void delete_SuccessfullyDeleted_ReturnsUserId() {
// GIVEN
UserDTO userDTO = new UserDTO(1L, "username", "password");
UserEntity userEntity = new UserEntity();
Expand All @@ -97,7 +97,7 @@ public void delete_SuccessfullyDeleted_ReturnsUserId() {
}

@Test
public void delete_UserNotFound_ThrowsException() {
void delete_UserNotFound_ThrowsException() {
// GIVEN
UserDTO userDTO = new UserDTO(1L, "username", "password");
UserEntity userEntity = new UserEntity();
Expand All @@ -112,7 +112,7 @@ public void delete_UserNotFound_ThrowsException() {
}

@Test
public void findByUsername_UserExists_ReturnsOptionalUserDTO() {
void findByUsername_UserExists_ReturnsOptionalUserDTO() {
// GIVEN
String username = "testuser";
UserEntity userEntity = new UserEntity();
Expand All @@ -135,7 +135,7 @@ public void findByUsername_UserExists_ReturnsOptionalUserDTO() {
}

@Test
public void findByUsername_UserNotExists_ReturnsEmptyOptional() {
void findByUsername_UserNotExists_ReturnsEmptyOptional() {
// GIVEN
String username = "nonexistentuser";
when(userRepository.findByUsername(username))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import pl.luczak.michal.joboffersapp.loginandsignup.dto.UserDTO;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class UserEntityMapperTest {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.HttpStatusEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
Expand All @@ -22,6 +21,8 @@
import org.springframework.web.filter.CorsFilter;
import pl.luczak.michal.joboffersapp.ports.output.UserService;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
class SecurityConfig {

Expand All @@ -46,40 +47,36 @@ UserDetailsService userDetailsService(
}

@Bean
SecurityFilterChain securityFilterChain(
HttpSecurity httpSecurity,
JWTAuthTokenFilter jwtAuthTokenFilter
) throws Exception {
httpSecurity.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests()
.requestMatchers(HttpMethod.GET, "/offers/**").permitAll()
.requestMatchers(HttpMethod.POST, "/token").permitAll()
.requestMatchers(HttpMethod.POST, "/register").permitAll()
.requestMatchers("/v2/api-docs").permitAll()
.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/swagger-resources/**").permitAll()
.requestMatchers("/configuration/ui").permitAll()
.requestMatchers("/configuration/security").permitAll()
.requestMatchers("/swagger-ui/**").permitAll()
.requestMatchers("/webjars/**").permitAll()
.requestMatchers("/swagger-ui.html").permitAll()
.anyRequest()
.authenticated()
.and()
.headers().frameOptions().disable()
.and()
.httpBasic().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling().authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
.and()
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity, JWTAuthTokenFilter jwtAuthTokenFilter) throws Exception {
httpSecurity
.csrf(AbstractHttpConfigurer::disable)
.cors(withDefaults())
.authorizeHttpRequests(authz -> authz
.requestMatchers(HttpMethod.GET, "/offers/**").permitAll()
.requestMatchers(HttpMethod.POST, "/token").permitAll()
.requestMatchers(HttpMethod.POST, "/register").permitAll()
.requestMatchers("/v2/api-docs").permitAll()
.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/swagger-resources/**").permitAll()
.requestMatchers("/configuration/ui").permitAll()
.requestMatchers("/configuration/security").permitAll()
.requestMatchers("/swagger-ui/**").permitAll()
.requestMatchers("/webjars/**").permitAll()
.requestMatchers("/swagger-ui.html").permitAll()
.anyRequest().authenticated()
)
.headers(headers -> headers.frameOptions(Customizer.withDefaults()).disable())
.httpBasic(withDefaults())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.exceptionHandling(exceptionHandling ->
exceptionHandling.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.addFilterBefore(jwtAuthTokenFilter, UsernamePasswordAuthenticationFilter.class);

return httpSecurity.build();
}


@Bean
CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.web.servlet.MockMvc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ void typical_scenario() throws Exception {
assertThat(firstFoundOfferDTO).isEqualTo(firstOffer);

//step 12: there are 2 new offers in external HTTP server
// GIVEN && WHEN && THEN
wireMockServer.stubFor(WireMock.get("/offers")
.willReturn(WireMock.aResponse()
.withStatus(HttpStatus.OK.value())
Expand All @@ -230,7 +229,6 @@ void typical_scenario() throws Exception {
// THEN
assertThat(offerListWith2NewOffers).hasSize(2);

//step 14: user made GET /offers and system returned OK(200) with 4 offers with ids: ${firstOfferUUID}, ${secondOfferUUID}, ${thirdOfferUUID} and ${fourthOfferUUID}
// GIVEN && WHEN
ResultActions getWithFourOffers = mockMvc.perform(get("/offers"));
String getWithFourOffersResponse = getWithFourOffers.andExpect(status().isOk())
Expand Down
Loading