API Games

Boas-vindas ao repositório do projeto API Games

Entregáveis

🤷🏽‍♀️ Como entregar

Lembre-se que você pode consultar nosso conteúdo sobre Git & GitHub e nosso Blog - Git & GitHub sempre que precisar!

🧑‍💻 O que deverá ser desenvolvido

Você irá desenvolver diversos métodos que implementarão manipulações a coleções existentes em um software que já teve o seu desenvolvimento iniciado. Além disso, você desenvolverá diversas consultas LINQ para determinadas aplicações e desenvolverá uma aplicação de testes.

📝 Habilidades a serem trabalhadas

Neste projeto, verificamos se você é capaz de:

  • Desenvolver habilidades com relação a manipulação de coleções
  • Desenvolver consultas LINQ para determinadas operações
  • Aplicar um método de testes sobre coleções.
  • Interpretar as coleções de dados já existentes em um software.
  • Interpretar o funcionamento de um código já implementado.

Orientações

‼️ Antes de começar a desenvolver
  1. Clone o repositório
  • Use o comando: git clone git@github.com:tryber/acc-elective-csharp-0x-project-trybe-games.git.
  • Entre na pasta do repositório que você acabou de clonar:
    • cd acc-elective-csharp-0x-project-trybe-games
  1. Instale as dependências
  • Entre na pasta src/.
  • Execute o comando: dotnet restore.
  1. Crie uma branch a partir da branch master
  • Verifique se você está na branch master.
    • Exemplo: git branch
  • Se não estiver, mude para a branch master.
    • Exemplo: git checkout master
  • Agora crie uma branch à qual você vai submeter os commits do seu projeto.
    • Você deve criar uma branch no seguinte formato: nome-de-usuario-nome-do-projeto
    • Exemplo: git checkout -b joaozinho-acc-0x-project-trybe-games
  1. Adicione as mudanças ao stage do Git e faça um commit
  • Verifique que as mudanças ainda não estão no stage.
    • Exemplo: git status (deve aparecer listada a pasta joaozinho em vermelho)
  • Adicione o novo arquivo ao stage do Git.
    • Exemplo:
      • git add . (adicionando todas as mudanças - que estavam em vermelho - ao stage do Git)
      • git status (deve aparecer listado o arquivo joaozinho/README.md em verde)
  • Faça o commit inicial.
    • Exemplo:
      • git commit -m 'iniciando o projeto x' (fazendo o primeiro commit)
      • git status (deve aparecer uma mensagem tipo essa: nothing to commit )
  1. Adicione a sua branch com o novo commit ao repositório remoto
  • Usando o exemplo anterior: git push -u origin joaozinho-acc-0x-project-trybe-games.
  1. Crie um novo Pull Request (PR)
  • Vá até a página de Pull Requests do repositório no GitHub.
  • Clique no botão verde "New pull request".
  • Clique na caixa de seleção "Compare" e escolha a sua branch com atenção.
  • Coloque um título para a sua Pull Request.
    • Exemplo: "Cria tela de busca"
  • Clique no botão verde "Create pull request".
  • Adicione uma descrição para o Pull Request e clique no botão verde "Create pull request".
  • Não se preocupe em preencher mais nada por enquanto!.
  • Volte até a página de Pull Requests do repositório e confira que o seu Pull Request está criado.
⌨️ Durante o desenvolvimento
  • Faça commits das alterações que você fizer no código regularmente.

  • Lembre-se sempre, após um (ou alguns) commits, de atualizar o repositório remoto.

  • Os comandos que você utilizará com mais frequência são:

    1. git status (para verificar o que está em vermelho - fora do stage - e o que está em verde - no stage)
    2. git add (para adicionar arquivos ao stage do Git)
    3. git commit (para criar um commit com os arquivos que estão no stage do Git)
    4. git push -u origin nome-da-branch (para enviar o commit para o repositório remoto na primeira vez que fizer o push de uma nova branch)
    5. git push (para enviar o commit para o repositório remoto após o passo anterior)
🤝 Depois de terminar o desenvolvimento (opcional)

Para sinalizar que o seu projeto está pronto para o "Code Review", faça o seguinte:

  • Vá até a página DO SEU Pull Request, adicione a label de "code-review" e marque seus colegas:

    • No menu à direita, clique no link "Labels" e escolha a label code-review;

    • No menu à direita, clique no link "Assignees" e escolha o seu usuário;

    • No menu à direita, clique no link "Reviewers" e digite students, selecione o time tryber/students-sd-032-csharp.

Caso tenha alguma dúvida, aqui tem um video explicativo.

🕵🏿 Revisando um pull request

Use o conteúdo sobre Code Review para te ajudar a revisar os Pull Requests.

🎛 Linter

Usaremos o NetAnalyzer para fazer a análise estática do seu código.

Este projeto já vem com as dependências relacionadas ao linter configuradas no arquivo .csproj.

O analisador já é instalado pelo plugin da Microsoft C# no VSCode. Para isso, basta fazer o download do plugin e instalá-lo.

🛠 Testes

O .NET já possui sua própria plataforma de testes.

Este projeto já vem configurado e com suas dependências.

Executando todos os testes

Para executar os testes com o .NET, execute o comando dentro do diretório do seu projeto src/TrybeGames ou de seus testes src/TrybeGames.Test!

dotnet test

Executando um teste específico

Para executar um teste expecífico, basta executar o comando dotnet test --filter TestReq01 para o requisito 01 ou dotnet test --filter TestReq10 para o requisito 10.

⚠️ Importante: o comando irá executar testes cujo nome contém TestReq01.

⚠️ O avaliador automático não necessariamente avalia seu projeto na ordem em que os requisitos aparecem no readme. Isso acontece para deixar o processo de avaliação mais rápido. Então, não se assuste se isso acontecer, ok?

Outras opções para testes

  • Algumas opções que podem lhe ajudar são:
    • -?|-h|--help: exibem a descrição completa de como utilizar o comando.
    • -t|--list-tests: lista todos os testes, ao invés de executá-los.
    • -v|--verbosity <LEVEL>: define o nível de detalhe na resposta dos testes.
    • q | quiet
    • m | minimal
    • n | normal
    • d | detailed
    • diag | diagnostic
    • Exemplo de uso:
        dotnet test -v diag
      
      ou
        dotnet test --verbosity=diagnostic
      

Requisitos do projeto

A Trybe começou a desenvolver um sistema para gerenciar e armazenar dados de jogos jogados por Trybers, e você foi contratado para continuar esse desenvolvimento.

Neste projeto você vai desenvolver a estrutura básica de consultas para que o sistema funcione corretamente. Algumas estruturas já estão desenvolvidas, e o seu trabalho será terminar de desenvolver algumas funcionalidades.

Este sistema está dividido em diretórios específicos, para que fique mais fácil de entender e separar as entidades.

  • Contracts/ Estão armazenadas as interfaces que uma classe pode implementar.
  • Controller/ Estão armazenados os controllers responsáveis por realizar alguma ação que interage com a pessoa usuária e o banco de dados. No nosso caso há apenas um controller.
  • Database/ Está armazenada a classe que representa o banco de dados do sistema. Essa classe contém uma lista de cada um dos modelos presentes no sistema e alguns métodos que podem ser utilizados para fazer consultas a essas listas e a relações entre elas.
  • Models/ Contém os Modelos do sistema, no caso três: Game, Player, GameStudio.

O arquivo Program.cs utiliza a classe TrybeGamesController para executar as ações com a pessoa usuária, então é possível ver o sistema em funcionamento ao executar o projeto em src/TrybeGames com o comando dotnet test. Porém algumas funcionalidades ainda não foram implementadas, e é para isso que você foi contratado.

Entretando, para entender melhor como todas essas classes se relacionam entre si, vamos utilizar um diagrama. Primeiro, vamos entender qual a relação entre os Models Game, Player e GameStudio no diagrama abaixo:

diagrama apenas com os models

Perceba que cada Game possui duas relações com Player:

  1. Um jogo Game pode ter várias pessoas jogadoras Player utilizando para isso o membro Game.Players, que é uma lista do tipo inteiro e armazena os Ids das pessoas jogadoras.
  2. Uma pessoa jogadora Player pode ter vários jogos Game comprados utilizando para isso o membro Player.GamesOwned, que é uma lista do tipo inteiro e armazena os Ids dos jogos comprados.

GameStudio, por sua vez, se relaciona apenas com Game. Cada Game é desenvolvido por um GameStudio e é utilizado o campo Game.DeveloperStudio, que é do tipo inteiro e armazena o Id do studio desenvolvedor do jogo.

Player também pode ter uma lista de estúdios favoritos. Para isso é utilizado o seu membro Player.FavoriteGameStudios, que é uma lista do tipo inteiro que armazena os Ids dos estúdios favoritos.

Esses Models, por sua vez, são utilizados na classe TrybeGamesDatabse para compor o nosso banco de dados. E TrybeGamesDatabase é utilizado em TrybeGamesController para realizar as consultas e operações requisitadas pela pessoa usuária. Veja no diagrama completo abaixo todas as relações entre cada entidade do sistema.

diagrama completo

Não é necessário entender esse diagrama por completo para cumprir os requisitos do sistema. Para cumprir os requisitos, é importante entender como os Models se relacionam e onde os dados estão armazenados.

De olho na dica👀: Este projeto pode ser executado com dotnet run na pasta src/TrybeGames/, várias funcionalidades de interação com a pessoa usuária já estão implementadas e, para as que não estão, será exibida uma mensagem. Utilize isso para guiar o seu desenvolvimento.

1. Crie a funcionalidde para adicionar uma nova pessoa jogadora ao banco de dados

Implemente o método AddPlayer() no arquivo src/TrybeGames/TrybeGamesController.cs

Este método deve utilizar as entradas da pessoa usuária pelo Console para criar uma nova pessoa jogadora e adicionar ao banco de dados

Desenvolva uma lógica para receber da pessoa usuária o nome da nova pessoa jogadora pelo Console e assim criar uma nova instância de Player e inserir este no banco de dados database, que é um atributo da classe TrybeGamesController.

🚨Importante:🚨 O atributo Id precisa ser incrementado a cada nova pessoa jogadora que entrar no banco de dados começando de 1.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, adiciona uma nova pessoa jogadora no banco de dados existente na classe TrybeGamesDatabase, acessível pelo atributo database da classe TrybeGamesController.

2. Crie a funcionalidade de adicionar um novo estúdio de jogos ao banco de dados

Implemente o método AddGameStudio() no arquivo src/TrybeGames/TrybeGamesController.cs

Este método deve utilizar as entradas da pessoa usuária pelo Console para criar um novo Estúdio de Jogos e adicionar ao banco de dados

Desenvolva uma lógica para receber da pessoa usuária o nome do novo Estúdio de Jogos pelo Console e assim criar uma nova instância de GameStudio e inserir este no banco de dados database, que é um atributo da classe TrybeGamesController.

🚨Importante:🚨 O atributo Id precisa ser incrementado a cada novo estúdio que entrar no banco de dados, começando de 1.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, adiciona um novo estúdio de jogos no banco de dados existente na classe TrybeGamesDatabase, acessível pelo atributo database da classe TrybeGamesController.

3. Crie a funcionalidade de adicionar novo Jogo ao Banco de dados

Implemente o método AddGame() no arquivo src/TrybeGames/TrybeGamesController.cs

Este método deve utilizar as entradas da pessoa usuária pelo Console para criar um novo Jogo e adicionar ao banco de dados

Desenvolva uma lógica para receber da pessoa usuária os seguintes dados de um jogo:

  1. Nome (Name).
  2. Data de lançamento (ReleaseDate).
  3. Tipo de jogo (GameType). Lembre-se de que cada um desses atributos possui um tipo específico, e este método deve ser capaz de fazer as conversões necessárias para criar uma nova instância de Game corretamente e inseri-la no banco de dados database, que é um atributo da classe TrybeGamesController.

🚨Importante:🚨 O atributo Id precisa ser incrementado a cada novo jogo que entrar no banco de dados começando de 1.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, adiciona um novo jogo no banco de dados existente na classe TrybeGamesDatabase, acessível pelo atributo database da classe TrybeGamesController.

4. Crie a funcionalidade de buscar jogos desenvolvidos por um estúdio de jogos

Implemente o método GetGamesDevelopedBy() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método deve receber por parâmetro um estúdio de jogos e retornar todos os jogos que aquele estúdio desenvolveu

Por se tratar de um método da classe TrybeGamesDatabase, este não lida com entradas e interações com a pessoa usuária. Porém ele será utilizado pelo método QueryGamesFromStudio para buscar os jogos desenvolvidos pelo estúdio selecionado neste método. Como o método GetGamesDevelopedBy sempre retorna uma lista vazia, essa funcionalidade está imcompleta.

No método GetGamesDevelopedBy, utilize as listas de Game, Player e GameStudio presentes em TrybeGamesDatabase e suas relações para buscar e retornar uma lista de jogos List<Game>.

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo Game com os dados solicitados.

5. Crie a funcionalidade de buscar jogos jogados por uma pessoa jogadora

Implemente o método GetGamesPlayedBy() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método deve receber por parâmetro uma pessoa jogadora e retornar todos os jogos jogados por aquela pessoa jogadora

Por se tratar de um método da classe TrybeGamesDatabase, este não lida com entradas e interações com a pessoa usuária. Porém ele será utilizado pelo método QueryGamesPlayedByPlayer para buscar os jogos jogados pela pessoa jogadora selecionada neste método. Como o método GetGamesPlayedBy sempre retorna uma lista vazia, essa funcionalidade está imcompleta.

No método GetGamesPlayedBy, utilize as listas de Game, Player e GameStudio presentes em TrybeGamesDatabase e suas relações para buscar e retornar uma lista de jogos List<Game>.

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo Game com os dados solicitados.

6. Crie a funcionalidade de buscar jogos comprados por uma pessoa jogadora

Implemente o método GetGamesOwnedBy() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método deve receber por parâmetro uma pessoa jogadora e retornar todos os jogos que aquela pessoa jogadora possui

Por se tratar de um método da classe TrybeGamesDatabase, este não lida com entradas e interações com a pessoa usuária. Porém ele será utilizado pelo método QueryGamesBoughtByPlayer para buscar os jogos comprados pela pessoa jogadora selecionada neste método. Como o método GetGamesOwnedBy sempre retorna uma lista vazia, essa funcionalidade está imcompleta.

No método GetGamesOwnedBy, utilize as listas de Game, Player e GameStudio presentes em TrybeGamesDatabase e suas relações para buscar e retornar uma lista de jogos List<Game>.

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo Game com os dados solicitados.

7. Crie a funcionalidade de buscar todos os jogos junto do nome do estúdio desenvolvedor

Implemente o método GetGamesWithStudio() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método não recebe parâmetros e deve retornar as informações de jogos e seus estúdios de acordo com o DTO GameWithStudio

No método GetGamesOwnedBy, utilize as listas de Game, Player e GameStudio presentes em TrybeGamesDatabase e suas relações para buscar e retornar uma lista de jogos de acordo com o DTO List<GameWithStudio>.

O DTO GameWithStudio está presente no arquivo src/TrybeGames/DTO/GameWithStudio.cs e segue a seguinte estrutura

public class GameWithStudio
{
    public string? GameName { get; set; } // nome do jogo
    public string? StudioName { get; set; } // nome do estúdio que desenvolveu o jogo
    public int NumberOfPlayers { get; set; } // número de pessoas jogadoras do jogo
}

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo GameWithStudio com os dados solicitados.

8. Crie a funcionalidade de buscar todos os diferentes Tipos de jogos dentre os jogos cadastrados

Implemente o método GetGameTypes() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método não recebe parâmetros e deve retornar as informações dos tipos de jogos dentre os jogos cadastrados

No método GetGameTypes(), utilize a lista de Game presente em TrybeGamesDatabase para retornar uma lista de tipos de jogos List<GameType>.

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo GameType com os dados solicitados.

9. Crie a funcionalidade de buscar todos os estúdios de jogos junto dos seus jogos desenvolvidos com suas pessoas jogadoras

Implemente o método GetStudiosWithGamesAndPlayers() no arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs

Este método não recebe parâmetros e deve retornar as informações dos estúdios de jogos, seus jogos e para cada jogo, suas pessoas jogadoras de acordo com os DTOs StudioGamesPlayers e GamePlayer

No método GetStudiosWithGamesAndPlayers(), utilize as listas de Game, Player e GameStudio presentes em TrybeGamesDatabase e suas relações para buscar e retornar uma lista de jogos de acordo com o DTO List<StudioGamesPlayers>.

Os DTOs StudioGamesPlayers e GamePlayer estão presentes no arquivo src/TrybeGames/DTO/StudioGamesPlayers.cs e segue a seguinte estrutura

public class GamePlayer
{
    public string GameName = ""; // nome do jogo
    public List<Player>? Players { get; set; } // lista das pessoas jogadoras que jogam este jogo.
}
public class StudioGamesPlayers
{
    public string? GameStudioName { get; set; } // nome do estúdio de jogos
    public List<GamePlayer>? Games { get; set; } // lista das informações de jogos e pessoas jogadoras baseada no DTO GamePlayer
}

De olho na dica👀: Consultas LINQ são uma ótima forma de realizar essa busca. Utilize o método ToList() para converter do tipo IEnumerable para List.

O que será testado:

  • Será testado se o método implementado, ao ser chamado, retorna a lista do tipo StudioGamesPlayers com os dados solicitados.

10. Implemente os testes da funcionalidade de buscar jogos jogados por uma pessoa jogadora

Implemente o método TestGetGamesPlayedBy() no arquivo src/TrybeGames.Test/TestTrybeGamesDatabase.cs

Este método deve implementar os testes do método indicado

No método TestGetGamesPlayedBy() crie o arrange, act e assert para testar a funcionalidade de buscar os jogos jogados por uma pessoa jogadora implementada no método GetGamesPlayedBy do arquivo src/TrybeGames/Database/TrybeGamesDatabase.cs.

O método possui como parâmetros de entrada o database da classe TrybeGamesDatabase, o id do player do tipo Int e uma lista de games List<Game> com a lista esperada no retorno do método a ser testado.

Os dados a serem utilizados no teste estão no atributo DataTestGetGamesPlayedBy do tipo TheoryData, presente no mesmo arquivo src/TrybeGames.Test/TestTrybeGamesDatabase.cs.

O que será testado:

  • Será testado se o método implementado testa com sucesso a funcionalidade.