Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Desafio Técnico Fullstack para a empresa Umbler - Desenvolvedor C# / JavaScript - Jr

mtlouzada/Desafio.Umbler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Desafio Umbler

Esta é uma aplicação web que recebe um domínio e mostra suas informações de DNS.

Este é um exemplo real de sistema que utilizamos na Umbler.

Ex: Consultar os dados de registro do dominio umbler.com

Retorno:

  • Name servers (ns254.umbler.com)
  • IP do registro A (177.55.66.99)
  • Empresa que está hospedado (Umbler)

Essas informações são descobertas através de consultas nos servidores DNS e de WHOIS.

Obs: WHOIS (pronuncia-se "ruís") é um protocolo específico para consultar informações de contato e DNS de domínios na internet.

Nesta aplicação, os dados obtidos são salvos em um banco de dados, evitando uma segunda consulta desnecessaria, caso seu TTL ainda não tenha expirado.

Obs: O TTL é um valor em um registro DNS que determina o número de segundos antes que alterações subsequentes no registro sejam efetuadas. Ou seja, usamos este valor para determinar quando uma informação está velha e deve ser renovada.

Tecnologias Backend utilizadas:

  • C#
  • Asp.Net Core
  • MySQL
  • Entity Framework

Tecnologias Frontend utilizadas:

  • Webpack
  • Babel
  • ES7

Para rodar o projeto você vai precisar instalar:

Com as ferramentas devidamente instaladas, basta executar os seguintes comandos:

Para "buildar" o javascript basta executar:

npm install npm run build

Para Rodar o projeto:

Execute a migration no banco mysql:

dotnet tool update --global dotnet-ef dotnet tool ef database update

E após:

dotnet run (ou clique em "play" no editor do vscode)

Objetivos:

Se você rodar o projeto e testar um domínio, verá que ele já está funcionando. Porém, queremos melhorar varios pontos deste projeto:

FrontEnd

  • Os dados retornados não estão formatados, e devem ser apresentados de uma forma legível.
  • Não há validação no frontend permitindo que seja submetido uma requsição inválida para o servidor (por exemplo, um domínio sem extensão).
  • Está sendo utilizado "vanilla-js" para fazer a requisição para o backend, apesar de já estar configurado o webpack. O ideal seria utilizar algum framework mais moderno como ReactJs ou Blazor.

BackEnd

  • Não há validação no backend permitindo que uma requisição inválida prossiga, o que ocasiona exceptions (erro 500).
  • A complexidade ciclomática do controller está muito alta, o ideal seria utilizar uma arquitetura em camadas.
  • O DomainController está retornando a própria entidade de domínio por JSON, o que faz com que propriedades como Id, Ttl e UpdatedAt sejam mandadas para o cliente web desnecessariamente. Retornar uma ViewModel (DTO) neste caso seria mais aconselhado.

Testes

  • A cobertura de testes unitários está muito baixa, e o DomainController está impossível de ser testado pois não há como "mockar" a infraestrutura.
  • O Banco de dados já está sendo "mockado" graças ao InMemoryDataBase do EntityFramework, mas as consultas ao Whois e Dns não.

Dica

  • Este teste não tem "pegadinha", é algo pensado para ser simples. Aconselhamos a ler o código, e inclusive algumas dicas textuais deixadas nos testes unitários.
  • Há um teste unitário que está comentado, que obrigatoriamente tem que passar.
  • Diferencial: criar mais testes.

Entrega

  • Enviei o link do seu repositório com o código atualizado.
  • O repositório deve estar público para que possamos acessar..
  • Modifique Este readme adicionando informações sobre os motivos das mudanças realizadas.

Modificações:

Durante o desenvolvimento e refatoração do desafio, foram realizadas as seguintes melhorias:

1° BackEnd

Image
  1. Migrations
    • Criação de novas migrations, alinhada com um banco de dados local MySQL e refatoração na connectionstring.
  2. Atualização da pasta Models e impacto

O que foi feito:

  • Atualizado o model Domain com valores padrão e [Required] nas propriedades essenciais (Name, Ip, UpdatedAt, Ttl).

  • Mantida a chave primária Id e o DbSet no DatabaseContext.

Impacto:

  • Garante integridade e consistência dos dados no banco.

  • Facilita testes unitários com dados padrão.

  • Permite que DomainService e DomainController retornem informações completas sem erros de valores nulos.

  1. Refatoração do Controller (DomainController)
    • DomainController foi simplificado: ele apenas valida entrada e retorna HTTP adequado.
    • Toda a lógica de consultas (DNS, Whois, banco de dados) foi movida para o DomainService, seguindo o padrão de separação de responsabilidades.
  2. Criação do Service (DomainService)
    • Criado wrapper para o WhoisClient e injeção de ILookupClient para permitir mock durante testes unitários.
    • Alterado para retornar objetos do tipo Domain, mantendo a lógica de persistência e consulta ao banco de dados.
    • Inclusão de tratamento de TTL e atualização de registros antigos no banco de dados.
  3. Criação de DTO (DomainResultDto)
    • Separação entre a entidade do banco (Domain) e os dados retornados para o front-end.
    • Melhora na segurança, evitando expor dados desnecessários.
    • Facilita a manipulação dos dados no frontend (Vite + React).

2° Frontend

Image

OBS: Optei por criar o front usando vite + ReactJS em uma pasta diferente, seguindo as recomendações da documentação do ASP.NET. Caso não seja comum para a equipe usar build tools como o vite, também é possível buildar o frontend dentro da pasta Views. Ajustes como esse são de rápida implementação.

  1. Substituição de vanilla JS por React + TypeScript.

  2. Consulta à API via service dedicado (domainService.ts).

  3. Validação de entrada do usuário (domínios inválidos não são enviados).

  4. Dados retornados pelo backend são exibidos de forma legível no frontend.

OBS: A escolha do pnpm como gerenciador de pacotes no front foi meramente perfomática, por estar lidando com uma máquina com recursos limitados.

3° Testes Unitários

Image

OBS: O testa unitário que estava comentado, não estava funcionando naquele formato. Ele dependia do WhoisClient original, que é uma classe estática e não mockável diretamente.

Para funcionar, foi preciso:

  • Criar um wrapper/método mockável para o Whois (IWhoisClientWrapper).
  • Alterar o DomainService e o DomainController para usar a interface mockável em vez da classe estática.
  • Criar o teste usando Mock retornando um valor fake para o domínio.

Depois dessa refatoração, esse teste passou a funcionar, mas não é mais aquele código comentado, e sim uma versão adaptada usando o service mockado.

Porém mesmo adaptado, ele exerce exatamente a mesma função que o teste original comentado


  • Configuração de InMemoryDatabase do Entity Framework para testar interações com o banco sem depender de um banco real.
  • Criação de mocks para IDomainService e wrappers de Whois/DNS.
    • Cobertura aumentada para cenários:
      • Domínio existente no banco.
      • Domínio inexistente no banco.
      • Domínio inválido.
    • Todos os testes unitários obrigatórios passam, garantindo estabilidade da aplicação.

5° Extra

  • Criação de um teste unitário específico para domínio inválido, simulando a requisição de um domínio que não existe ou não é válido.
  • Habilitação de CORS e configuração de Swagger para facilitar testes e documentação da API.
  • Atualização de pacotes NuGet para resolver conflitos de versões do Entity Framework.
  • Ajustes para compatibilidade com .NET 6.

Como Rodar

Backend

  1. Configure a ConnectionString no appsettings.json.
  2. Execute dotnet build.
  3. Atualize as Migrations dotnet ef database update
  4. Execute dotnet run para iniciar o servidor.

Frontend

  1. Entre na pasta client.
  2. Execute pnpm i.
  3. Execute pnpm dev para iniciar o frontend.
  4. Acesse http://localhost:5173 (ou porta indicada pelo Vite).

Testes

  • Execute dotnet test na pasta Desafio.Umbler.Test para rodar todos os testes unitários.

feito :)

About

Desafio Técnico Fullstack para a empresa Umbler - Desenvolvedor C# / JavaScript - Jr

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published