package br.gov.servicos.frontend;
import br.gov.servicos.config.ServicosDestaqueConfig;
import br.gov.servicos.destaques.AreasDeInteresseEmDestaque;
import br.gov.servicos.destaques.ServicosEmDestaque;
import br.gov.servicos.orgao.OrgaoRepositoryUtil;
import br.gov.servicos.piwik.PiwikClient;
import br.gov.servicos.piwik.PiwikPage;
import br.gov.servicos.servico.ServicoRepository;
import br.gov.servicos.v3.schema.OrgaoXML;
import br.gov.servicos.v3.schema.ServicoXML;
import com.github.slugify.Slugify;
import lombok.SneakyThrows;
import lombok.experimental.FieldDefaults;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import java.io.IOException;
import static br.gov.servicos.fixtures.TestData.SERVICO;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static lombok.AccessLevel.PRIVATE;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.*;
import static org.springframework.data.domain.Sort.Direction.DESC;
import static org.springframework.test.web.ModelAndViewAssert.assertModelAttributeValue;
import static org.springframework.test.web.ModelAndViewAssert.assertViewName;
@RunWith(MockitoJUnitRunner.class)
@FieldDefaults(level = PRIVATE)
public class IndexControllerTest {
@Mock
ServicoRepository servicos;
@Mock
ServicosDestaqueConfig destaques;
@Mock
PiwikClient piwikClient;
@Mock
OrgaoRepositoryUtil orgaos;
@Mock
AreasDeInteresseEmDestaque areasDeInteresseEmDestaque;
IndexController controller;
ServicosEmDestaque destaquesManuais;
ServicosEmDestaque destaquesAutomaticos;
Slugify slugify;
@Before
@SneakyThrows
public void setUp() {
slugify = new Slugify();
destaquesManuais = new ServicosEmDestaque(servicos, destaques, piwikClient, false);
destaquesAutomaticos = new ServicosEmDestaque(servicos, destaques, piwikClient, true);
given(servicos.findAll(any(PageRequest.class)))
.willReturn(new PageImpl<>(singletonList(SERVICO)));
}
@Test
public void redirecionaParaAPaginaInicial() {
controller = comDestaquesManuais();
assertViewName(controller.index(), "index");
}
@Test
public void retornaServicosASeremExibidos() {
controller = comDestaquesManuais();
assertModelAttributeValue(controller.index(), "destaques", singletonList(SERVICO));
}
@Test
public void deveRetornarOsServicosPaginados() {
controller = comDestaquesManuais();
controller.index();
verify(servicos).findAll(new PageRequest(0, 8, new Sort(DESC, "nome")));
}
@Test
public void deveRetornarDestaquesPrimeiro() {
controller = comDestaquesManuais();
given(destaques.getServicos()).willReturn(singletonList("servico-em-destaque"));
ServicoXML servicoEmDestaque = new ServicoXML().withNome("servico-em-destaque");
given(servicos.findOne("servico-em-destaque")).willReturn(servicoEmDestaque);
assertModelAttributeValue(controller.index(), "destaques", asList(servicoEmDestaque, SERVICO));
}
@Test
public void devePedirUrlsMaisAcessadasParaOPiwik() throws Exception {
controller = comDestaquesAutomaticos();
given(piwikClient.getPageUrls(anyString(), anyString()))
.willReturn(singletonList(
new PiwikPage()
.withUrl("/servico/servico-mais-acessado")
.withVisitors(3L)
.withUniqueVisitors(1L)));
ServicoXML servicoMaisAcessado = new ServicoXML().withNome("Servico Mais Acessado");
given(servicos.findOne("servico-mais-acessado")).willReturn(servicoMaisAcessado);
assertModelAttributeValue(controller.index(), "destaques", asList(servicoMaisAcessado, SERVICO));
}
@Test
public void deveRetornarMaisAcessadosECompletarComDestaquesEOutrosServicos() throws Exception {
controller = comDestaquesAutomaticos();
given(piwikClient.getPageUrls(anyString(), anyString()))
.willReturn(singletonList(
new PiwikPage()
.withUrl("/servico/servico-mais-acessado")
.withVisitors(3L)
.withUniqueVisitors(1L)));
given(destaques.getServicos()).willReturn(singletonList("servico-em-destaque"));
ServicoXML servicoMaisAcessado = new ServicoXML().withNome("servico-mais-acessado");
given(servicos.findOne("servico-mais-acessado")).willReturn(servicoMaisAcessado);
ServicoXML servicoEmDestaque = new ServicoXML().withNome("servico-em-destaque");
given(servicos.findOne("servico-em-destaque")).willReturn(servicoEmDestaque);
assertModelAttributeValue(controller.index(), "destaques", asList(servicoMaisAcessado, servicoEmDestaque, SERVICO));
}
@Test
public void deveFiltrarServicosMaisAcessadosNaoEncontrados() throws Exception {
controller = comDestaquesAutomaticos();
given(piwikClient.getPageUrls(anyString(), anyString()))
.willReturn(singletonList(
new PiwikPage()
.withUrl("/servico/servico-nao-existe")
.withVisitors(3L)
.withUniqueVisitors(1L)));
given(servicos.findOne("servico-nao-existe")).willReturn(null);
assertModelAttributeValue(controller.index(), "destaques", singletonList(SERVICO));
}
@Test
public void deveFiltrarFiltrarServicosIguais() {
controller = comDestaquesManuais();
given(destaques.getServicos()).willReturn(singletonList("exemplo-de-servico"));
given(servicos.findOne("exemplo-de-servico")).willReturn(SERVICO);
assertModelAttributeValue(controller.index(), "destaques", singletonList(SERVICO));
}
@Test
public void deveFiltrarDestaquesNaoEncontrados() {
controller = comDestaquesManuais();
given(destaques.getServicos()).willReturn(singletonList("destaque-nao-cadastrado"));
assertModelAttributeValue(controller.index(), "destaques", singletonList(SERVICO));
}
@Test
public void deveRedirecionarParaOrgao() throws IOException {
controller = comDestaquesManuais();
String urlOrgao = "http://estruturaorganizacional.dados.gov.br/doc/unidade-organizacional/1934";
String id = this.slugify.slugify("http://estruturaorganizacional.dados.gov.br/doc/unidade-organizacional/1934");
given(orgaos.obterOrgao(any())).willReturn(new OrgaoXML().withId(id));
ModelAndView view = controller.redirectParaOrgao(urlOrgao);
assertThat(((RedirectView) view.getView()).getUrl(), is("/orgao/" + id));
}
@Test
public void deveRedirecionarParaIndexQuandoHaProblemasComParametroOrgao() throws IOException {
controller = comDestaquesManuais();
String urlOrgao = "http://estruturaorganizacional.dados.gov.br/doc/unidade-organizacional/1934";
given(orgaos.obterOrgao(any())).willReturn(null);
ModelAndView view = controller.redirectParaOrgao(urlOrgao);
assertThat(view.getViewName(), is("index"));
}
@SneakyThrows
private IndexController comDestaquesAutomaticos() {
return new IndexController(destaquesAutomaticos, areasDeInteresseEmDestaque, orgaos, slugify);
}
@SneakyThrows
private IndexController comDestaquesManuais() {
return new IndexController(destaquesManuais, areasDeInteresseEmDestaque, orgaos, slugify);
}
}