Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5e1d3cb
delete recomendation (sugerencia)
JulianKer Nov 25, 2025
d302954
Cambio paginado de prendas a 10
camilamarendazzo Nov 25, 2025
3b38efc
Testing user repo
FeliWeigel Nov 25, 2025
280751c
Testing user subscriptions repo
FeliWeigel Nov 26, 2025
ec93a7d
Testing user subscriptions repo
FeliWeigel Nov 26, 2025
4740641
Testing user subscriptions repo
FeliWeigel Nov 26, 2025
3fcf4d2
test/useCases/garment - refactor
JulianKer Nov 26, 2025
30f3fae
test/useCases/garments - nuevos test
JulianKer Nov 26, 2025
f377405
test/useCases/garments - todos testeados
JulianKer Nov 26, 2025
0d7190c
refactor tests subscription
AilinVara Nov 27, 2025
37a6ee2
refactor tests subscription
AilinVara Nov 27, 2025
67ee3a0
test controllers (algunos)
JulianKer Nov 27, 2025
1026050
merge pull
JulianKer Nov 27, 2025
a7c3805
Agrega todos los tests de subscription
AilinVara Nov 27, 2025
47eef17
Agrega todos los tests de brand
AilinVara Nov 27, 2025
0b098ab
Agrega todos los tests de bucketImages
AilinVara Nov 27, 2025
8967924
Agrega todos los tests de combination
AilinVara Nov 27, 2025
5ebc04d
Agrega todos los tests de combinationAttempt
AilinVara Nov 27, 2025
52802b1
Agrega todos los tests de combinationFavorite
AilinVara Nov 27, 2025
01b64ab
Agrega todos los tests de dashboard
AilinVara Nov 27, 2025
801e192
Agrega todos los tests para gmail
AilinVara Nov 27, 2025
b8b2540
Agrega todos los tests de recomendations
AilinVara Nov 27, 2025
8ff380e
Refactor de tests de tripo
AilinVara Nov 27, 2025
241b433
Agrega todos los tests de user
AilinVara Nov 27, 2025
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 @@ -12,4 +12,6 @@ public interface GarmentRecomendationRepository {
void deleteRecomendationsByGarmentCode(String garmentCode);

void createSugerenciasByGarmentCode(String garmentCode, String type, List<String> sugerencias);

void deleteRecomendationByGarmentsCode(String garmentCodePrimary, String garmentCodeSecondary, String type);
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ public UserModel(long id, String email) {
this.email = email;
}

public UserModel() {

}

/*
* public String getPassword() {
* return "";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.outfitlab.project.domain.useCases.recomendations;

import com.outfitlab.project.domain.interfaces.repositories.GarmentRecomendationRepository;

public class DeleteRecomendationByPrimaryAndSecondaryGarmentCode {

private final GarmentRecomendationRepository garmentRecomendationRepository;

public DeleteRecomendationByPrimaryAndSecondaryGarmentCode(GarmentRecomendationRepository garmentRecomendationRepository) {
this.garmentRecomendationRepository = garmentRecomendationRepository;
}

public String execute(String garmentCodePrimary, String garmentCodeSecondary, String type) {
this.garmentRecomendationRepository.deleteRecomendationByGarmentsCode(garmentCodePrimary, garmentCodeSecondary, type);
return "Sugerencia eliminada con éxito.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public PrendaOcacionRepository prendaOcacionRepository(PrendaOcacionJpaRepositor
return new PrendaOcacionRepositoryImpl(prendaOcacionJpaRepository);
}

@Bean
public DeleteRecomendationByPrimaryAndSecondaryGarmentCode deleteRecomendationByPrimaryAndSecondaryGarmentCode(GarmentRecomendationRepository recomendationRepository){
return new DeleteRecomendationByPrimaryAndSecondaryGarmentCode(recomendationRepository);
}

@Bean
public CreateSugerenciasByGarmentsCode createSugerenciasByGarmentsCode(GarmentRecomendationRepository garmentRecomendationRepository){
return new CreateSugerenciasByGarmentsCode(garmentRecomendationRepository);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ public class UserEntity implements UserDetails {

public UserEntity() {
}
public UserEntity(String email) {
this.email = email;
}

public UserEntity(String name, String lastName, String email, String satulation, String secondName, Integer years,
String password) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

public class GarmentRepositoryImpl implements GarmentRepository {

private final int PAGE_SIZE = 20;
private final int PAGE_SIZE = 10;
private final GarmentJpaRepository garmentJpaRepository;
private final BrandJpaRepository brandJpaRepository;
private final ColorJpaRepository colorJpaRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ public void createSugerenciasByGarmentCode(String garmentCode, String type, List
this.recomendationJpaRepository.saveAll(sugerenciasToCeate);
}

@Override
public void deleteRecomendationByGarmentsCode(String garmentCodePrimary, String garmentCodeSecondary, String type) {
if (type.equalsIgnoreCase("inferior"))
this.recomendationJpaRepository.deleteWhenPrimaryIsBottom(garmentCodePrimary, garmentCodeSecondary);
else
this.recomendationJpaRepository.deleteWhenPrimaryIsTop(garmentCodePrimary, garmentCodeSecondary);
}

private List<GarmentRecomendationEntity> getGarmentRecomendationEntitiesToCreate(String type, List<String> sugerencias, PrendaEntity prendaPrincipal) {
List<GarmentRecomendationEntity> sugerenciasToCeate = new ArrayList<>();

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

public class UserGarmentFavoriteRepositoryImpl implements UserGarmentFavoriteRepository {

private final int PAGE_SIZE = 20;
private final int PAGE_SIZE = 10;
private final UserGarmentFavoriteJpaRepository userGarmentFavoriteJpaRepository;
private final UserJpaRepository userJpaRepository;
private final GarmentJpaRepository garmentJpaRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import com.outfitlab.project.infrastructure.repositories.interfaces.UserJpaRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

import java.util.List;
import java.util.Optional;

import static com.outfitlab.project.domain.enums.Role.*; // ← Usar enums

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,25 @@ public interface RecomendationJpaRepository extends JpaRepository<GarmentRecomen
OR gr.bottomGarment.garmentCode = :garmentCode
""")
void deleteAllByGarmentCode(@Param("garmentCode") String garmentCode);



@Modifying
@Transactional
@Query("""
delete from GarmentRecomendationEntity gr
where gr.bottomGarment.garmentCode = :primaryCode
and gr.topGarment.garmentCode = :secondaryCode
""")
void deleteWhenPrimaryIsBottom(String primaryCode, String secondaryCode);


@Modifying
@Transactional
@Query("""
delete from GarmentRecomendationEntity gr
where gr.topGarment.garmentCode = :primaryCode
and gr.bottomGarment.garmentCode = :secondaryCode
""")
void deleteWhenPrimaryIsTop(String primaryCode, String secondaryCode);
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
package com.outfitlab.project.presentation;

import com.outfitlab.project.domain.helper.CodeFormatter;
import com.outfitlab.project.domain.useCases.garment.GetGarmentRecomendation;
import com.outfitlab.project.domain.useCases.recomendations.DeleteRecomendationByPrimaryAndSecondaryGarmentCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class RecomendationController {

private final GetGarmentRecomendation getGarmentRecomendation;
private final DeleteRecomendationByPrimaryAndSecondaryGarmentCode deleteRecomendationByPrimaryAndSecondaryGarmentCode;

public RecomendationController(GetGarmentRecomendation getGarmentRecomendation) {
public RecomendationController(GetGarmentRecomendation getGarmentRecomendation, DeleteRecomendationByPrimaryAndSecondaryGarmentCode deleteRecomendationByPrimaryAndSecondaryGarmentCode) {
this.getGarmentRecomendation = getGarmentRecomendation;
this.deleteRecomendationByPrimaryAndSecondaryGarmentCode = deleteRecomendationByPrimaryAndSecondaryGarmentCode;
}


Expand All @@ -28,4 +29,15 @@ public ResponseEntity<?> getRecomendations(@PathVariable String garmentCode) {
.body(e.getMessage());
}
}

@DeleteMapping("/garment-recomendation/delete")
public ResponseEntity<?> deleteRecomendation(@RequestParam String garmentCodePrimary, @RequestParam String garmentCodeSecondary, @RequestParam String type) {
try {
return ResponseEntity.ok(this.deleteRecomendationByPrimaryAndSecondaryGarmentCode.execute(garmentCodePrimary, garmentCodeSecondary, type));
} catch (Exception e) {
return ResponseEntity
.status(404)
.body(e.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.outfitlab.project.domain.useCases.brand;

import com.outfitlab.project.domain.exceptions.BrandsNotFoundException;
import com.outfitlab.project.domain.interfaces.repositories.BrandRepository;
import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
import com.outfitlab.project.domain.model.BrandModel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class ActivateBrandTest {

private BrandRepository brandRepository = mock(BrandRepository.class);
private UserRepository userRepository = mock(UserRepository.class);
private ActivateBrand activateBrand;

private final String BRAND_CODE = "adidas";
private final String USER_EMAIL = "adidas@corp.com";
private final String SUCCESS_MESSAGE = "Marca activada con éxito.";

@BeforeEach
void setUp() {
activateBrand = new ActivateBrand(brandRepository, userRepository);
}


@Test
public void shouldActivateUserAndReturnSuccessMessageWhenBrandExists() throws BrandsNotFoundException {
givenBrandExistsAndUserEmailIsAvailable(BRAND_CODE, USER_EMAIL);

String result = whenExecuteActivateBrand(BRAND_CODE);

thenResultIsSuccessMessage(result);
thenUserWasActivated(USER_EMAIL);
}

@Test
public void shouldThrowBrandsNotFoundExceptionWhenBrandDoesNotExist() {
givenBrandDoesNotExist(BRAND_CODE);

assertThrows(BrandsNotFoundException.class, () -> activateBrand.execute(BRAND_CODE));

thenActivationWasNeverCalled();
}


//privadosss
private void givenBrandExistsAndUserEmailIsAvailable(String brandCode, String userEmail) {
when(brandRepository.findByBrandCode(brandCode)).thenReturn(new BrandModel());
when(userRepository.getEmailUserRelatedToBrandByBrandCode(brandCode)).thenReturn(userEmail);
}

private void givenBrandDoesNotExist(String brandCode) {
when(brandRepository.findByBrandCode(brandCode)).thenReturn(null);
}

private String whenExecuteActivateBrand(String brandCode) {
return activateBrand.execute(brandCode);
}

private void thenResultIsSuccessMessage(String result) {
assertEquals(SUCCESS_MESSAGE, result, "El mensaje de retorno debe ser de activación exitosa.");
}

private void thenUserWasActivated(String userEmail) {
verify(userRepository, times(1)).getEmailUserRelatedToBrandByBrandCode(BRAND_CODE);
verify(userRepository, times(1)).activateUser(userEmail);
}

private void thenActivationWasNeverCalled() {
verify(userRepository, never()).activateUser(anyString());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.outfitlab.project.domain.useCases.brand;

import com.outfitlab.project.domain.interfaces.repositories.BrandRepository;
import com.outfitlab.project.domain.model.BrandModel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class CreateBrandTest {

private BrandRepository brandRepository = mock(BrandRepository.class);
private CreateBrand createBrand;

private final String BRAND_NAME = "Zara Shop";
private final String LOGO_URL = "http://logo.com/zara-shop.png";
private final String URL_SITE = "http://zarashop.com";
private final String EXPECTED_BRAND_CODE = "zara_shop";
private final String EXPECTED_RESPONSE = "brand-id-123";

@BeforeEach
void setUp() {
createBrand = new CreateBrand(brandRepository);
}


@Test
public void shouldCreateBrandModelWithFormattedCodeAndCallRepository() {
givenRepositoryReturnsExpectedResponse(EXPECTED_RESPONSE);

String result = whenExecuteCreateBrand(BRAND_NAME, LOGO_URL, URL_SITE);

thenRepositoryWasCalledWithCorrectBrandModel(BRAND_NAME, LOGO_URL, URL_SITE, EXPECTED_BRAND_CODE);
thenResultIsExpected(result, EXPECTED_RESPONSE);
}


//privadoss
private void givenRepositoryReturnsExpectedResponse(String response) {
when(brandRepository.createBrand(any(BrandModel.class))).thenReturn(response);
}

private String whenExecuteCreateBrand(String brandName, String logoUrl, String urlSite) {
return createBrand.execute(brandName, logoUrl, urlSite);
}

private void thenResultIsExpected(String actualResult, String expectedResponse) {
assertEquals(expectedResponse, actualResult, "El resultado debe ser la respuesta del repositorio.");
}

private void thenRepositoryWasCalledWithCorrectBrandModel(String expectedName, String expectedLogoUrl, String expectedUrlSite, String expectedCode) {
ArgumentCaptor<BrandModel> captor = ArgumentCaptor.forClass(BrandModel.class);
verify(brandRepository, times(1)).createBrand(captor.capture());

BrandModel capturedModel = captor.getValue();

assertEquals(expectedName, capturedModel.getNombre(), "El nombre de la marca debe coincidir.");
assertEquals(expectedLogoUrl, capturedModel.getLogoUrl(), "La URL del logo debe coincidir.");
assertEquals(expectedUrlSite, capturedModel.getUrlSite(), "La URL del sitio debe coincidir.");
assertEquals(expectedCode, capturedModel.getCodigoMarca(), "El código de marca debe estar formateado.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.outfitlab.project.domain.useCases.brand;

import com.outfitlab.project.domain.exceptions.BrandsNotFoundException;
import com.outfitlab.project.domain.interfaces.repositories.BrandRepository;
import com.outfitlab.project.domain.interfaces.repositories.UserRepository;
import com.outfitlab.project.domain.model.BrandModel;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

public class DesactivateBrandTest {

private BrandRepository brandRepository = mock(BrandRepository.class);
private UserRepository userRepository = mock(UserRepository.class);
private DesactivateBrand desactivateBrand;

private final String BRAND_CODE = "nike";
private final String USER_EMAIL = "nike@corp.com";
private final String SUCCESS_MESSAGE = "Marca desactivada con éxito.";

@BeforeEach
void setUp() {
desactivateBrand = new DesactivateBrand(brandRepository, userRepository);
}


@Test
public void shouldDesactivateUserAndReturnSuccessMessageWhenBrandExists() throws BrandsNotFoundException {
givenBrandExistsAndUserEmailIsAvailable(BRAND_CODE, USER_EMAIL);

String result = whenExecuteDesactivateBrand(BRAND_CODE);

thenResultIsSuccessMessage(result);
thenUserWasDesactivated(USER_EMAIL);
}

@Test
public void shouldThrowBrandsNotFoundExceptionWhenBrandDoesNotExist() {
givenBrandDoesNotExist(BRAND_CODE);

assertThrows(BrandsNotFoundException.class, () -> desactivateBrand.execute(BRAND_CODE));

thenDesactivationWasNeverCalled();
}


//privadoss
private void givenBrandExistsAndUserEmailIsAvailable(String brandCode, String userEmail) {
when(brandRepository.findByBrandCode(brandCode)).thenReturn(new BrandModel());
when(userRepository.getEmailUserRelatedToBrandByBrandCode(brandCode)).thenReturn(userEmail);
}

private void givenBrandDoesNotExist(String brandCode) {
when(brandRepository.findByBrandCode(brandCode)).thenReturn(null);
}

private String whenExecuteDesactivateBrand(String brandCode) {
return desactivateBrand.execute(brandCode);
}

private void thenResultIsSuccessMessage(String result) {
assertEquals(SUCCESS_MESSAGE, result, "El mensaje de retorno debe ser de desactivación exitosa.");
}

private void thenUserWasDesactivated(String userEmail) {
verify(userRepository, times(1)).getEmailUserRelatedToBrandByBrandCode(BRAND_CODE);
verify(userRepository, times(1)).desactivateUser(userEmail);
}

private void thenDesactivationWasNeverCalled() {
verify(userRepository, never()).desactivateUser(anyString());
}
}
Loading