Sobre o Projeto ⚡
Fazendo o Back-End de uma aplicação que simula uma tabela de campeonato de Futebol em pontos corridos, criei rotas e testes no Back-End
- Utilizando Express com ajuda do Squelize em TypeScript, consegui realizar rotas de uma forma mais eficaz e tranquila
- Realizando o maximo de cobertura de testes
E2E
que consegui fazer, utilizeiChai
,Mocha
eSinon
.
Configuração Docker 🐳
⚠ O seu docker-compose precisa estar na versão 1.29 ou superior. ⚠ Veja aqui a documentação para atualizar o docker-compose.
Como iniciar o projeto na sua máquina 💻
Primeiro clone o Projeto no seu repositório local.git clone [email protected]:VictorSilva27/Trybe-Futebol-Clube.git
Agora entra no repositório local.
cd Trybe-Futebol-Clube
(Entrar no repositório clonado)
Caso você tenha Visual Studio Code,
code .
Instale todas as dependências da raiz do projeto.
npm install
.
Instale as dependências de tudo dentro da pasta app.
npm run install:apps
.
Ou
npm run postinstall
.
Suba os Dockerfiles das pastas Backend e FrontEnd com o comando:
npm run compose:up
.
Em seguida, rode o comando para ver os logs:
npm run logs backend
.
Caso queira ver o logs de todos os serviços
npm run logs
. Ou se queira ver os outros serviços individuais, basta trocar obackend
porfrontend
oudb
.
- Quando aparecer uma mensagem escrita
Running on port 3001
, podemos ver nossas rotas. Nessa seção temos as rotas.
A porta
3001
pode alterer de acordo com sua porta.
Rotas da API 🌎
Depois de ter feito o processo acima, podemos verificar nossas rotas.Recomendo utilizar a extensão do Thunder Client no seu Vs Code.
Segue esse rota para utilizar tanto no seu navegador, como no Thunder Client também.
http://localhost:3001/[Rota]
Rota Login
-
A rota utilizada deve ser (
/login
) com o tipopost
; -
A rota deve receber os campos
email
epassword
e esses campos devem ser validados no banco de dados:- O campo
email
deve receber um email válido; - O Campo
password
deve ter mais de 6 caracteres.
- O campo
-
O body da requisição deve conter o seguinte formato:
{ "email": "[email protected]", "password": "secret_user" }
-
Retorno dessa API deve ser algo parecido com:
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6ImFkbWluIiwiaWF0IjoxNjU0NTI3MTg5fQ.XS_9AA82iNoiVaASi0NtJpqOQ_gHSHhxrpIdigiT-fc" // Aqui deve ser o token gerado pelo backend. }
Antes de enviar a rota, devemos configurar o Header da requisição
-
1º Vá ate a opção
Headers
. -
2º Crie um header chamado
Authorization
. -
3º Insira um token válido.
Pegue o token da resposta da rota
/login
. -
4º Coloque a rota
/login/validate
e envia. -
5º Veja o body da response.
Rota Teams
-
A rota utilizada deve ser (
/teams
) com o tipoget
; -
Resultado da requisição:
[ { "id": 1, "teamName": "Avaí/Kindermann" }, { "id": 2, "teamName": "Bahia" }, { "id": 3, "teamName": "Botafogo" }, ... ]
-
A rota utilizada deve ser (
/teams/3
) com o tipoget
;No lugar do
3
, pode colocar até do 1 ao 16; -
Resultado da requisição:
{ "id": 3, "teamName": "Botafogo" }
Rota Matches
-
A rota utilizada deve ser (
/Matches
) com o tipoget
; -
Resultado da requisição:
[ { "id": 1, "homeTeam": 16, "homeTeamGoals": 1, "awayTeam": 8, "awayTeamGoals": 1, "inProgress": false, "teamHome": { "teamName": "São Paulo" }, "teamAway": { "teamName": "Grêmio" } }, ... { "id": 41, "homeTeam": 16, "homeTeamGoals": 2, "awayTeam": 9, "awayTeamGoals": 0, "inProgress": true, "teamHome": { "teamName": "São Paulo" }, "teamAway": { "teamName": "Internacional" } } ]
Nessa Rota recebe, uma query string
chamada inProgress, ela recebe true
ou false
.
True recebe as partidas em andamento, e False recebe as partidas finalizadas
-
A rota utilizada deve ser (
/matches?inProgress=true
) com o tipoget
;No lugar do
true
, pode colocarfalse
; -
Resultado da requisição:
[ { "id": 41, "homeTeam": 16, "homeTeamGoals": 2, "awayTeam": 9, "awayTeamGoals": 0, "inProgress": true, "teamHome": { "teamName": "São Paulo" }, "teamAway": { "teamName": "Internacional" } }, { "id": 42, "homeTeam": 6, "homeTeamGoals": 1, "awayTeam": 1, "awayTeamGoals": 0, "inProgress": true, "teamHome": { "teamName": "Ferroviária" }, "teamAway": { "teamName": "Avaí/Kindermann" } } ]
Nessa Rota recebe, uma body para cadastrar uma partida entre dois times diferentes.
-
A rota utilizada deve ser (
/matches
) com o tipopost
; -
Corpo da requisição:
{ "homeTeam": 16, // O valor deve ser o id do time "awayTeam": 8, // O valor deve ser o id do time "homeTeamGoals": 2, "awayTeamGoals": 2, }
Lembre-se de estar sempre com o token validado
- Resultado da requisição:
{ "id": 1, "homeTeam": 16, "homeTeamGoals": 2, "awayTeam": 8, "awayTeamGoals": 2, "inProgress": true, }
Podemos finalizar uma partida que esteja em andamento atráves do Id da partida.
- A rota utilizada deve ser (
/matches/:id/finish
) com o tipopatch
;
No
:id
, podemos substituir por 1 até o 41, caso você não tenha cadastrado mais nenhuma partida
- Resultado da requisição:
{ "message": "Finished", }
Podemos atualizar o resultado de uma partida que esteja em andamento atráves do Id da partida.
- A rota utilizada deve ser (
/matches/:id
) com o tipopatch
;
No
:id
, podemos substituir por 1 até o 41, caso você não tenha cadastrado mais nenhuma partida
-
Corpo da requisição:
{ "homeTeamGoals": 3, "awayTeamGoals": 1 }
-
Resultado da requisição:
{ "message": "Updated", }
Rota Leaderboards
Essas Rotas retornam a tabela dos times, Home retorna de todas as partidas que o time jogou em casa, Away retorna de todos que ele jogou fora de casa, e a Leaderboard retorna a tabela normal, com os jogos fora e dentro de casa-
A rota utilizada deve ser (
/leaderboard/home
) com o tipoget
; -
Resultado da requisição:
[ { "name": "Santos", "totalPoints": 9, "totalGames": 3, "totalVictories": 3, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 9, "goalsOwn": 3, "goalsBalance": 6, "efficiency": "100.00" }, { "name": "Palmeiras", "totalPoints": 7, "totalGames": 3, "totalVictories": 2, "totalDraws": 1, "totalLosses": 0, "goalsFavor": 10, "goalsOwn": 5, "goalsBalance": 5, "efficiency": "77.78" }, { "name": "Corinthians", "totalPoints": 6, "totalGames": 2, "totalVictories": 2, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 6, "goalsOwn": 1, "goalsBalance": 5, "efficiency": "100.00" }, { "name": "Grêmio", "totalPoints": 6, "totalGames": 2, "totalVictories": 2, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 4, "goalsOwn": 1, "goalsBalance": 3, "efficiency": "100.00" }, { "name": "Real Brasília", "totalPoints": 6, "totalGames": 2, "totalVictories": 2, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 2, "goalsOwn": 0, "goalsBalance": 2, "efficiency": "100.00" }, { "name": "São Paulo", "totalPoints": 4, "totalGames": 2, "totalVictories": 1, "totalDraws": 1, "totalLosses": 0, "goalsFavor": 4, "goalsOwn": 1, "goalsBalance": 3, "efficiency": "66.67" }, { "name": "Internacional", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 4, "goalsOwn": 6, "goalsBalance": -2, "efficiency": "44.44" }, { "name": "Botafogo", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 2, "goalsOwn": 4, "goalsBalance": -2, "efficiency": "44.44" }, { "name": "Ferroviária", "totalPoints": 3, "totalGames": 2, "totalVictories": 1, "totalDraws": 0, "totalLosses": 1, "goalsFavor": 3, "goalsOwn": 2, "goalsBalance": 1, "efficiency": "50.00" }, { "name": "Napoli-SC", "totalPoints": 2, "totalGames": 2, "totalVictories": 0, "totalDraws": 2, "totalLosses": 0, "goalsFavor": 2, "goalsOwn": 2, "goalsBalance": 0, "efficiency": "33.33" }, { "name": "Cruzeiro", "totalPoints": 1, "totalGames": 2, "totalVictories": 0, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 2, "goalsOwn": 3, "goalsBalance": -1, "efficiency": "16.67" }, { "name": "Flamengo", "totalPoints": 1, "totalGames": 2, "totalVictories": 0, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 1, "goalsOwn": 2, "goalsBalance": -1, "efficiency": "16.67" }, { "name": "Minas Brasília", "totalPoints": 1, "totalGames": 3, "totalVictories": 0, "totalDraws": 1, "totalLosses": 2, "goalsFavor": 3, "goalsOwn": 6, "goalsBalance": -3, "efficiency": "11.11" }, { "name": "Avaí/Kindermann", "totalPoints": 1, "totalGames": 3, "totalVictories": 0, "totalDraws": 1, "totalLosses": 2, "goalsFavor": 3, "goalsOwn": 7, "goalsBalance": -4, "efficiency": "11.11" }, { "name": "São José-SP", "totalPoints": 0, "totalGames": 3, "totalVictories": 0, "totalDraws": 0, "totalLosses": 3, "goalsFavor": 2, "goalsOwn": 5, "goalsBalance": -3, "efficiency": "0.00" }, { "name": "Bahia", "totalPoints": 0, "totalGames": 3, "totalVictories": 0, "totalDraws": 0, "totalLosses": 3, "goalsFavor": 0, "goalsOwn": 4, "goalsBalance": -4, "efficiency": "0.00" } ]
-
A rota utilizada deve ser (
/leaderboard/Away
) com o tipoget
; -
Resultado da requisição:
[ { "name": "Palmeiras", "totalPoints": 6, "totalGames": 2, "totalVictories": 2, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 7, "goalsOwn": 0, "goalsBalance": 7, "efficiency": "100.00" }, { "name": "Corinthians", "totalPoints": 6, "totalGames": 3, "totalVictories": 2, "totalDraws": 0, "totalLosses": 1, "goalsFavor": 6, "goalsOwn": 2, "goalsBalance": 4, "efficiency": "66.67" }, { "name": "Internacional", "totalPoints": 6, "totalGames": 3, "totalVictories": 2, "totalDraws": 0, "totalLosses": 1, "goalsFavor": 4, "goalsOwn": 2, "goalsBalance": 2, "efficiency": "66.67" }, { "name": "São José-SP", "totalPoints": 6, "totalGames": 2, "totalVictories": 2, "totalDraws": 0, "totalLosses": 0, "goalsFavor": 3, "goalsOwn": 1, "goalsBalance": 2, "efficiency": "100.00" }, { "name": "São Paulo", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 5, "goalsOwn": 5, "goalsBalance": 0, "efficiency": "44.44" }, { "name": "Ferroviária", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 4, "goalsOwn": 5, "goalsBalance": -1, "efficiency": "44.44" }, { "name": "Real Brasília", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 3, "goalsOwn": 4, "goalsBalance": -1, "efficiency": "44.44" }, { "name": "Grêmio", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 5, "goalsOwn": 7, "goalsBalance": -2, "efficiency": "44.44" }, { "name": "Flamengo", "totalPoints": 4, "totalGames": 3, "totalVictories": 1, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 1, "goalsOwn": 3, "goalsBalance": -2, "efficiency": "44.44" }, { "name": "Avaí/Kindermann", "totalPoints": 3, "totalGames": 2, "totalVictories": 1, "totalDraws": 0, "totalLosses": 1, "goalsFavor": 1, "goalsOwn": 1, "goalsBalance": 0, "efficiency": "50.00" }, { "name": "Cruzeiro", "totalPoints": 3, "totalGames": 3, "totalVictories": 1, "totalDraws": 0, "totalLosses": 2, "goalsFavor": 6, "goalsOwn": 7, "goalsBalance": -1, "efficiency": "33.33" }, { "name": "Santos", "totalPoints": 2, "totalGames": 2, "totalVictories": 0, "totalDraws": 2, "totalLosses": 0, "goalsFavor": 3, "goalsOwn": 3, "goalsBalance": 0, "efficiency": "33.33" }, { "name": "Bahia", "totalPoints": 2, "totalGames": 2, "totalVictories": 0, "totalDraws": 2, "totalLosses": 0, "goalsFavor": 2, "goalsOwn": 2, "goalsBalance": 0, "efficiency": "33.33" }, { "name": "Minas Brasília", "totalPoints": 1, "totalGames": 2, "totalVictories": 0, "totalDraws": 1, "totalLosses": 1, "goalsFavor": 1, "goalsOwn": 3, "goalsBalance": -2, "efficiency": "16.67" }, { "name": "Botafogo", "totalPoints": 0, "totalGames": 2, "totalVictories": 0, "totalDraws": 0, "totalLosses": 2, "goalsFavor": 1, "goalsOwn": 4, "goalsBalance": -3, "efficiency": "0.00" }, { "name": "Napoli-SC", "totalPoints": 0, "totalGames": 3, "totalVictories": 0, "totalDraws": 0, "totalLosses": 3, "goalsFavor": 1, "goalsOwn": 10, "goalsBalance": -9, "efficiency": "0.00" } ]
-
A rota utilizada deve ser (
/leaderboard/Away
) com o tipoget
; -
Resultado da requisição:
[
{
"name": "Palmeiras",
"totalPoints": 13,
"totalGames": 5,
"totalVictories": 4,
"totalDraws": 1,
"totalLosses": 0,
"goalsFavor": 17,
"goalsOwn": 5,
"goalsBalance": 12,
"efficiency": "86.67"
},
{
"name": "Corinthians",
"totalPoints": 12,
"totalGames": 5,
"totalVictories": 4,
"totalDraws": 0,
"totalLosses": 1,
"goalsFavor": 12,
"goalsOwn": 3,
"goalsBalance": 9,
"efficiency": "80.00"
},
{
"name": "Santos",
"totalPoints": 11,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 2,
"totalLosses": 0,
"goalsFavor": 12,
"goalsOwn": 6,
"goalsBalance": 6,
"efficiency": "73.33"
},
{
"name": "Grêmio",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 8,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Internacional",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 7,
"goalsOwn": 6,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "Real Brasília",
"totalPoints": 10,
"totalGames": 5,
"totalVictories": 3,
"totalDraws": 1,
"totalLosses": 1,
"goalsFavor": 5,
"goalsOwn": 4,
"goalsBalance": 1,
"efficiency": "66.67"
},
{
"name": "São Paulo",
"totalPoints": 8,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 2,
"totalLosses": 1,
"goalsFavor": 9,
"goalsOwn": 6,
"goalsBalance": 3,
"efficiency": "53.33"
},
{
"name": "Ferroviária",
"totalPoints": 7,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 1,
"totalLosses": 2,
"goalsFavor": 7,
"goalsOwn": 7,
"goalsBalance": 0,
"efficiency": "46.67"
},
{
"name": "São José-SP",
"totalPoints": 6,
"totalGames": 5,
"totalVictories": 2,
"totalDraws": 0,
"totalLosses": 3,
"goalsFavor": 5,
"goalsOwn": 6,
"goalsBalance": -1,
"efficiency": "40.00"
},
{
"name": "Flamengo",
"totalPoints": 5,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 2,
"totalLosses": 2,
"goalsFavor": 2,
"goalsOwn": 5,
"goalsBalance": -3,
"efficiency": "33.33"
},
{
"name": "Cruzeiro",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 8,
"goalsOwn": 10,
"goalsBalance": -2,
"efficiency": "26.67"
},
{
"name": "Avaí/Kindermann",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 8,
"goalsBalance": -4,
"efficiency": "26.67"
},
{
"name": "Botafogo",
"totalPoints": 4,
"totalGames": 5,
"totalVictories": 1,
"totalDraws": 1,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 8,
"goalsBalance": -5,
"efficiency": "26.67"
},
{
"name": "Bahia",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 2,
"goalsOwn": 6,
"goalsBalance": -4,
"efficiency": "13.33"
},
{
"name": "Minas Brasília",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 4,
"goalsOwn": 9,
"goalsBalance": -5,
"efficiency": "13.33"
},
{
"name": "Napoli-SC",
"totalPoints": 2,
"totalGames": 5,
"totalVictories": 0,
"totalDraws": 2,
"totalLosses": 3,
"goalsFavor": 3,
"goalsOwn": 12,
"goalsBalance": -9,
"efficiency": "13.33"
}
]
Testes E2E 🧪
Testando minhas Rotas com meus Services, Controllers e Models.