diff --git a/codecov.yml b/codecov.yml index eabd4fa..88ebebe 100644 --- a/codecov.yml +++ b/codecov.yml @@ -15,10 +15,11 @@ codecov: paths: - "api-products/coverage.out" # Ruta al reporte de cobertura de API - "scraper/coverage.out" # Ruta al reporte de cobertura de Scraper + - "api-users/coverage.out" # Ruta al reporte de cobertura de API de usuarios status: project: default: - threshold: 80 # Porcentaje de cobertura requerido para pasar + threshold: 70 # Porcentaje de cobertura requerido para pasar # Configuration for coverage reporting status: diff --git a/scraper/src/service/scraper_service_impl.go b/scraper/src/service/scraper_service_impl.go index 5019eaf..0819911 100644 --- a/scraper/src/service/scraper_service_impl.go +++ b/scraper/src/service/scraper_service_impl.go @@ -18,6 +18,7 @@ type ScraperServiceImpl struct { // GetProducts implements ScraperService. func (s *ScraperServiceImpl) GetProducts() (bool, error) { const baseURL string = "cugat.cl/categoria-producto" + protocol := "https" err := s.ScraperRepository.DeleteAll() if err != nil { @@ -26,9 +27,6 @@ func (s *ScraperServiceImpl) GetProducts() (bool, error) { } logrus.Info("[ProductServiceImpl.UpdateData] Scraping data started") - - protocol := "https" - for _, categoryInfo := range scraper.Categories { products, err := s.Scraper.ScrapeData(protocol, baseURL, categoryInfo.MaxPage, categoryInfo.Category) if err != nil { diff --git a/scraper/src/service/scraper_service_impl_test.go b/scraper/src/service/scraper_service_impl_test.go new file mode 100644 index 0000000..bdbae8d --- /dev/null +++ b/scraper/src/service/scraper_service_impl_test.go @@ -0,0 +1,124 @@ +package service + +import ( + "testing" + + "github.com/dieg0code/shared/mocks" + "github.com/dieg0code/shared/models" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestScraperService_GetProducts(t *testing.T) { + t.Run("GetProducts_Success", func(t *testing.T) { + repo := new(mocks.MockScraperRepository) + scraper := new(mocks.MockScraper) + + scraperService := NewScraperServiceImpl(scraper, repo) + + // Configurar los mocks + repo.On("DeleteAll").Return(nil) + scraper.On("ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything).Return([]models.Product{ + { + Name: "Product1", + Category: "Category1", + OriginalPrice: 100, + DiscountedPrice: 80, + }, + }, nil) + repo.On("Create", mock.Anything).Return(models.Product{}, nil) + + // Llamar a la función + success, err := scraperService.GetProducts() + + // Verificar los resultados + assert.NoError(t, err, "Expected no error, but got %v", err) + assert.True(t, success, "Expected success to be true, but got %v", success) + + repo.AssertCalled(t, "DeleteAll") + scraper.AssertCalled(t, "ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything) + repo.AssertCalled(t, "Create", mock.Anything) + }) + + t.Run("GetProducts_ErrorDeletingAllProducts", func(t *testing.T) { + repo := new(mocks.MockScraperRepository) + scraper := new(mocks.MockScraper) + + scraperService := NewScraperServiceImpl(scraper, repo) + + // Configurar los mocks + repo.On("DeleteAll").Return(assert.AnError) + scraper.On("ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything).Return([]models.Product{ + { + Name: "Product1", + Category: "Category1", + OriginalPrice: 100, + DiscountedPrice: 80, + }, + }, nil) + repo.On("Create", mock.Anything).Return(models.Product{}, nil) + + // Llamar a la función + success, err := scraperService.GetProducts() + + // Verificar los resultados + assert.Error(t, err, "Expected an error, but got nil") + assert.False(t, success, "Expected success to be false, but got %v", success) + + repo.AssertCalled(t, "DeleteAll") + repo.AssertNotCalled(t, "Create", mock.Anything) + }) + + t.Run("GetProducts_ErrorScrapingData", func(t *testing.T) { + repo := new(mocks.MockScraperRepository) + scraper := new(mocks.MockScraper) + + scraperService := NewScraperServiceImpl(scraper, repo) + + // Configurar los mocks + repo.On("DeleteAll").Return(nil) + scraper.On("ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything).Return([]models.Product{}, assert.AnError) + repo.On("Create", mock.Anything).Return(models.Product{}, nil) + + // Llamar a la función + success, err := scraperService.GetProducts() + + // Verificar los resultados + assert.Error(t, err, "Expected an error, but got nil") + assert.False(t, success, "Expected success to be false, but got %v", success) + + repo.AssertCalled(t, "DeleteAll") + scraper.AssertCalled(t, "ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything) + repo.AssertNotCalled(t, "Create", mock.Anything) + }) + + t.Run("GetProducts_ErrorCreatingProduct", func(t *testing.T) { + repo := new(mocks.MockScraperRepository) + scraper := new(mocks.MockScraper) + + scraperService := NewScraperServiceImpl(scraper, repo) + + // Configurar los mocks + repo.On("DeleteAll").Return(nil) + scraper.On("ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything).Return([]models.Product{ + { + Name: "Product1", + Category: "Category1", + OriginalPrice: 100, + DiscountedPrice: 80, + }, + }, nil) + repo.On("Create", mock.Anything).Return(models.Product{}, assert.AnError) + + // Llamar a la función + success, err := scraperService.GetProducts() + + // Verificar los resultados + assert.Error(t, err, "Expected an error, but got nil") + assert.False(t, success, "Expected success to be false, but got %v", success) + + repo.AssertCalled(t, "DeleteAll") + scraper.AssertCalled(t, "ScrapeData", "https", "cugat.cl/categoria-producto", mock.Anything, mock.Anything) + repo.AssertCalled(t, "Create", mock.Anything) + }) +} diff --git a/shared/mocks/mocks_scraper.go b/shared/mocks/mocks_scraper.go index 84ca934..0d38bb9 100644 --- a/shared/mocks/mocks_scraper.go +++ b/shared/mocks/mocks_scraper.go @@ -9,12 +9,12 @@ type MockScraper struct { mock.Mock } -func (m *MockScraper) ScrapeData(baseURL string, maxPage int, category string) ([]models.Product, error) { - args := m.Called(baseURL, maxPage, category) +func (m *MockScraper) ScrapeData(protocol string, baseURL string, maxPage int, category string) ([]models.Product, error) { + args := m.Called(protocol, baseURL, maxPage, category) return args.Get(0).([]models.Product), args.Error(1) } -func (m *MockScraper) CleanPrice(price string) (int, error) { +func (m *MockScraper) CleanPrice(price string) ([]int, error) { args := m.Called(price) - return args.Int(0), args.Error(1) + return args.Get(0).([]int), args.Error(1) } diff --git a/shared/mocks/mocks_scraper_repository.go b/shared/mocks/mocks_scraper_repository.go new file mode 100644 index 0000000..24c1eef --- /dev/null +++ b/shared/mocks/mocks_scraper_repository.go @@ -0,0 +1,19 @@ +package mocks + +import ( + "github.com/dieg0code/shared/models" + "github.com/stretchr/testify/mock" +) + +type MockScraperRepository struct { + mock.Mock +} + +func (m *MockScraperRepository) Create(product models.Product) (models.Product, error) { + args := m.Called(product) + return args.Get(0).(models.Product), args.Error(1) +} +func (m *MockScraperRepository) DeleteAll() error { + args := m.Called() + return args.Error(0) +}