From 1fadb32d05e95a292f6b42d86717f62476810ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anderson=20Mois=C3=A9s?= Date: Tue, 26 Aug 2025 16:35:12 -0300 Subject: [PATCH] Minimal API feito --- Api/.vscode/launch.json | 35 -- Api/.vscode/settings.json | 32 ++ Api/.vscode/tasks.json | 41 -- Api/Dominio/DTOs/AdministradorDTO.cs | 8 +- Api/Dominio/DTOs/LoginDTO.cs | 4 +- Api/Dominio/DTOs/VeiculoDTO.cs | 6 +- Api/Dominio/Entidades/Administrador.cs | 8 +- Api/Dominio/Entidades/Veiculo.cs | 8 +- Api/Dominio/Enuns/Perfil.cs | 1 + .../Interfaces/IAdministradorServico.cs | 2 +- ...IVeiculoServico.cs => IVeiculoSerrvico.cs} | 1 + Api/Dominio/ModelViews/AdministradorLogado.cs | 6 +- .../ModelViews/AdministradorModelView.cs | 6 +- Api/Dominio/ModelViews/ErrosDeValidacao.cs | 2 +- Api/Dominio/ModelViews/Home.cs | 2 +- Api/Dominio/Servicos/AdministradorServico.cs | 14 +- Api/Dominio/Servicos/VeiculoServico.cs | 14 +- Api/Infraestrutura/{ => Db}/.gitkeep | 0 Api/Infraestrutura/Db/DbContexto.cs | 9 +- .../20231115013756_SeedAdministrador.cs | 28 -- ...035408_AdministradorMigration.Designer.cs} | 13 +- ... 20250823035408_AdministradorMigration.cs} | 9 +- ...250823141835_SeedAdmnistrador.Designer.cs} | 13 +- .../20250823141835_SeedAdmnistrador.cs | 49 ++ ...50823205255_VeiculosMigration.Designer.cs} | 13 +- ...cs => 20250823205255_VeiculosMigration.cs} | 2 +- Api/Migrations/DbContextoModelSnapshot.cs | 11 +- Api/Program.cs | 14 +- Api/Properties/launchSettings.json | 20 +- Api/Startup.cs | 440 +++++++++--------- Api/appsettings.json | 4 +- ...{mininal-api.csproj => minimal-api.csproj} | 50 +- Api/minimal-api.sln | 24 + Test/.vscode/launch.json | 26 -- Test/.vscode/tasks.json | 41 -- Test/Domain/Entidades/AdministradorTest.cs | 21 +- Test/Domain/Servicos/AdministradorServico.cs | 53 ++- Test/GlobalUsings.cs | 2 +- Test/Helpers/Setup.cs | 22 +- Test/Mocks/AdministradorServicoMock.cs | 11 +- Test/Requests/AdministradorRequestTest.cs | 22 +- Test/Test.csproj | 22 +- Test/Test.sln | 24 + Test/appsettings.json | 4 +- Test/minimal_api.dump.sql | Bin 4162 -> 8520 bytes minimal-api.sln | 47 +- 46 files changed, 618 insertions(+), 566 deletions(-) delete mode 100644 Api/.vscode/launch.json create mode 100644 Api/.vscode/settings.json delete mode 100644 Api/.vscode/tasks.json rename Api/Dominio/Interfaces/{IVeiculoServico.cs => IVeiculoSerrvico.cs} (99%) rename Api/Infraestrutura/{ => Db}/.gitkeep (100%) delete mode 100644 Api/Migrations/20231115013756_SeedAdministrador.cs rename Api/Migrations/{20231114235912_AdministradorMigration.Designer.cs => 20250823035408_AdministradorMigration.Designer.cs} (79%) rename Api/Migrations/{20231114235912_AdministradorMigration.cs => 20250823035408_AdministradorMigration.cs} (81%) rename Api/Migrations/{20231115013756_SeedAdministrador.Designer.cs => 20250823141835_SeedAdmnistrador.Designer.cs} (82%) create mode 100644 Api/Migrations/20250823141835_SeedAdmnistrador.cs rename Api/Migrations/{20231115020944_VeiculosMigration.Designer.cs => 20250823205255_VeiculosMigration.Designer.cs} (85%) rename Api/Migrations/{20231115020944_VeiculosMigration.cs => 20250823205255_VeiculosMigration.cs} (97%) rename Api/{mininal-api.csproj => minimal-api.csproj} (78%) create mode 100644 Api/minimal-api.sln delete mode 100644 Test/.vscode/launch.json delete mode 100644 Test/.vscode/tasks.json create mode 100644 Test/Test.sln diff --git a/Api/.vscode/launch.json b/Api/.vscode/launch.json deleted file mode 100644 index 3ea0527..0000000 --- a/Api/.vscode/launch.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - // Use IntelliSense to find out which attributes exist for C# debugging - // Use hover for the description of the existing attributes - // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md - "name": ".NET Core Launch (web)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net7.0/miminal-api.dll", - "args": [], - "cwd": "${workspaceFolder}", - "stopAtEntry": false, - // Enable launching a web browser when ASP.NET Core starts. For more information: https://aka.ms/VSCode-CS-LaunchJson-WebBrowser - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, - "env": { - "ASPNETCORE_ENVIRONMENT": "Development" - }, - "sourceFileMap": { - "/Views": "${workspaceFolder}/Views" - } - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - } - ] -} \ No newline at end of file diff --git a/Api/.vscode/settings.json b/Api/.vscode/settings.json new file mode 100644 index 0000000..18a0813 --- /dev/null +++ b/Api/.vscode/settings.json @@ -0,0 +1,32 @@ +{ + "sqltools.connections": [ + { + "mysqlOptions": { + "authProtocol": "default", + "enableSsl": "Disabled" + }, + "previewLimit": 50, + "server": "localhost", + "port": 3306, + "driver": "MariaDB", + "name": "minimal_api", + "database": "minimal_api", + "username": "root", + "askForPassword": true + }, + { + "mysqlOptions": { + "authProtocol": "default", + "enableSsl": "Disabled" + }, + "previewLimit": 50, + "server": "localhost", + "port": 3306, + "driver": "MySQL", + "name": "minimal_api", + "database": "minimal_api", + "username": "root", + "askForPassword": true + } + ] +} \ No newline at end of file diff --git a/Api/.vscode/tasks.json b/Api/.vscode/tasks.json deleted file mode 100644 index 5b09142..0000000 --- a/Api/.vscode/tasks.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/miminal-api.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/miminal-api.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/miminal-api.csproj" - ], - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/Api/Dominio/DTOs/AdministradorDTO.cs b/Api/Dominio/DTOs/AdministradorDTO.cs index 54b74d9..cb8607d 100644 --- a/Api/Dominio/DTOs/AdministradorDTO.cs +++ b/Api/Dominio/DTOs/AdministradorDTO.cs @@ -2,9 +2,11 @@ using MinimalApi.Dominio.Enuns; namespace MinimalApi.DTOs; + public class AdministradorDTO { - public string Email { get;set; } = default!; - public string Senha { get;set; } = default!; - public Perfil? Perfil { get;set; } = default!; + public string Email { get; set; } = default!; + public string Senha { get; set; } = default!; + public Perfil? Perfil { get; set; } = default!; + } \ No newline at end of file diff --git a/Api/Dominio/DTOs/LoginDTO.cs b/Api/Dominio/DTOs/LoginDTO.cs index 3976d28..5b2a926 100644 --- a/Api/Dominio/DTOs/LoginDTO.cs +++ b/Api/Dominio/DTOs/LoginDTO.cs @@ -2,6 +2,6 @@ namespace MinimalApi.DTOs; public class LoginDTO { - public string Email { get;set; } = default!; - public string Senha { get;set; } = default!; + public string Email { get; set; } = default!; + public string Senha { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/DTOs/VeiculoDTO.cs b/Api/Dominio/DTOs/VeiculoDTO.cs index a136958..3da7677 100644 --- a/Api/Dominio/DTOs/VeiculoDTO.cs +++ b/Api/Dominio/DTOs/VeiculoDTO.cs @@ -2,7 +2,7 @@ namespace MinimalApi.DTOs; public record VeiculoDTO { - public string Nome { get;set; } = default!; - public string Marca { get;set; } = default!; - public int Ano { get;set; } = default!; + public string Nome { get; set; } = default!; + public string Marca { get; set; } = default!; + public int Ano { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/Entidades/Administrador.cs b/Api/Dominio/Entidades/Administrador.cs index 3f1abc2..d6f4771 100644 --- a/Api/Dominio/Entidades/Administrador.cs +++ b/Api/Dominio/Entidades/Administrador.cs @@ -7,17 +7,17 @@ public class Administrador { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get;set; } = default!; + public int Id { get; set; } = default!; [Required] [StringLength(255)] - public string Email { get;set; } = default!; + public string Email { get; set; } = default!; [Required] [StringLength(50)] - public string Senha { get;set; } = default!; + public string Senha { get; set; } = default!; [Required] [StringLength(10)] - public string Perfil { get;set; } = default!; + public string Perfil { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/Entidades/Veiculo.cs b/Api/Dominio/Entidades/Veiculo.cs index 3a927e4..3e5d471 100644 --- a/Api/Dominio/Entidades/Veiculo.cs +++ b/Api/Dominio/Entidades/Veiculo.cs @@ -7,16 +7,16 @@ public class Veiculo { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] - public int Id { get;set; } = default!; + public int Id { get; set; } = default!; [Required] [StringLength(150)] - public string Nome { get;set; } = default!; + public string Nome { get; set; } = default!; [Required] [StringLength(100)] - public string Marca { get;set; } = default!; + public string Marca { get; set; } = default!; [Required] - public int Ano { get;set; } = default!; + public int Ano { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/Enuns/Perfil.cs b/Api/Dominio/Enuns/Perfil.cs index 08f3153..587c479 100644 --- a/Api/Dominio/Enuns/Perfil.cs +++ b/Api/Dominio/Enuns/Perfil.cs @@ -4,4 +4,5 @@ public enum Perfil { Adm, Editor + } \ No newline at end of file diff --git a/Api/Dominio/Interfaces/IAdministradorServico.cs b/Api/Dominio/Interfaces/IAdministradorServico.cs index 2464eca..8f19c5b 100644 --- a/Api/Dominio/Interfaces/IAdministradorServico.cs +++ b/Api/Dominio/Interfaces/IAdministradorServico.cs @@ -1,4 +1,3 @@ - using MinimalApi.Dominio.Entidades; using MinimalApi.DTOs; @@ -6,6 +5,7 @@ namespace MinimalApi.Dominio.Interfaces; public interface IAdministradorServico { + Administrador? Login(LoginDTO loginDTO); Administrador Incluir(Administrador administrador); Administrador? BuscaPorId(int id); diff --git a/Api/Dominio/Interfaces/IVeiculoServico.cs b/Api/Dominio/Interfaces/IVeiculoSerrvico.cs similarity index 99% rename from Api/Dominio/Interfaces/IVeiculoServico.cs rename to Api/Dominio/Interfaces/IVeiculoSerrvico.cs index 6566c52..2ebbf3a 100644 --- a/Api/Dominio/Interfaces/IVeiculoServico.cs +++ b/Api/Dominio/Interfaces/IVeiculoSerrvico.cs @@ -6,6 +6,7 @@ namespace MinimalApi.Dominio.Interfaces; public interface IVeiculoServico { + List Todos(int? pagina = 1, string? nome = null, string? marca = null); Veiculo? BuscaPorId(int id); void Incluir(Veiculo veiculo); diff --git a/Api/Dominio/ModelViews/AdministradorLogado.cs b/Api/Dominio/ModelViews/AdministradorLogado.cs index 9bc8078..6fe4854 100644 --- a/Api/Dominio/ModelViews/AdministradorLogado.cs +++ b/Api/Dominio/ModelViews/AdministradorLogado.cs @@ -4,7 +4,7 @@ namespace MinimalApi.Dominio.ModelViews; public record AdministradorLogado { - public string Email { get;set; } = default!; - public string Perfil { get;set; } = default!; - public string Token { get;set; } = default!; + public string Email { get; set; } = default!; + public string Perfil { get; set; } = default!; + public string Token { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/ModelViews/AdministradorModelView.cs b/Api/Dominio/ModelViews/AdministradorModelView.cs index 0c56f2e..c9253f3 100644 --- a/Api/Dominio/ModelViews/AdministradorModelView.cs +++ b/Api/Dominio/ModelViews/AdministradorModelView.cs @@ -4,7 +4,7 @@ namespace MinimalApi.Dominio.ModelViews; public record AdministradorModelView { - public int Id { get;set; } = default!; - public string Email { get;set; } = default!; - public string Perfil { get;set; } = default!; + public int Id { get; set; } = default!; + public string Email { get; set; } = default!; + public string Perfil { get; set; } = default!; } \ No newline at end of file diff --git a/Api/Dominio/ModelViews/ErrosDeValidacao.cs b/Api/Dominio/ModelViews/ErrosDeValidacao.cs index c8a1012..f273071 100644 --- a/Api/Dominio/ModelViews/ErrosDeValidacao.cs +++ b/Api/Dominio/ModelViews/ErrosDeValidacao.cs @@ -2,5 +2,5 @@ namespace MinimalApi.Dominio.ModelViews; public struct ErrosDeValidacao { - public List Mensagens { get;set; } + public List Mensagens { get; set; } } \ No newline at end of file diff --git a/Api/Dominio/ModelViews/Home.cs b/Api/Dominio/ModelViews/Home.cs index e26c8a9..50b9c7a 100644 --- a/Api/Dominio/ModelViews/Home.cs +++ b/Api/Dominio/ModelViews/Home.cs @@ -2,6 +2,6 @@ namespace MinimalApi.Dominio.ModelViews; public struct Home { - public string Mensagem { get => "Bem vindo a API de veículos - Minimal API"; } + public string Mensagem { get => "Bem vindo a API de veículos - Minmal API"; } public string Doc { get => "/swagger"; } } \ No newline at end of file diff --git a/Api/Dominio/Servicos/AdministradorServico.cs b/Api/Dominio/Servicos/AdministradorServico.cs index 5365aac..edc0c93 100644 --- a/Api/Dominio/Servicos/AdministradorServico.cs +++ b/Api/Dominio/Servicos/AdministradorServico.cs @@ -1,7 +1,10 @@ +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.EntityFrameworkCore; using MinimalApi.Dominio.Entidades; using MinimalApi.DTOs; using MinimalApi.Infraestrutura.Db; using MinimalApi.Dominio.Interfaces; +using System.ComponentModel.DataAnnotations; namespace MinimalApi.Dominio.Servicos; @@ -13,7 +16,7 @@ public AdministradorServico(DbContexto contexto) _contexto = contexto; } - public Administrador? BuscaPorId(int id) + public Administrador? BuscaPorId(int id) { return _contexto.Administradores.Where(v => v.Id == id).FirstOrDefault(); } @@ -30,17 +33,18 @@ public Administrador Incluir(Administrador administrador) { var adm = _contexto.Administradores.Where(a => a.Email == loginDTO.Email && a.Senha == loginDTO.Senha).FirstOrDefault(); return adm; + } public List Todos(int? pagina) { var query = _contexto.Administradores.AsQueryable(); - + int itensPorPagina = 10; - if(pagina != null) + if (pagina != null) query = query.Skip(((int)pagina - 1) * itensPorPagina).Take(itensPorPagina); - + return query.ToList(); } -} \ No newline at end of file +} diff --git a/Api/Dominio/Servicos/VeiculoServico.cs b/Api/Dominio/Servicos/VeiculoServico.cs index 2206994..aa8a767 100644 --- a/Api/Dominio/Servicos/VeiculoServico.cs +++ b/Api/Dominio/Servicos/VeiculoServico.cs @@ -1,8 +1,10 @@ +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.EntityFrameworkCore; using MinimalApi.Dominio.Entidades; using MinimalApi.DTOs; using MinimalApi.Infraestrutura.Db; using MinimalApi.Dominio.Interfaces; -using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations; namespace MinimalApi.Dominio.Servicos; @@ -40,16 +42,16 @@ public void Incluir(Veiculo veiculo) public List Todos(int? pagina = 1, string? nome = null, string? marca = null) { var query = _contexto.Veiculos.AsQueryable(); - if(!string.IsNullOrEmpty(nome)) + if (!string.IsNullOrEmpty(nome)) { - query = query.Where(v => EF.Functions.Like(v.Nome.ToLower(), $"%{nome}%")); + query = query.Where(v => EF.Functions.Like(v.Nome.ToLower(), $"%%{nome.ToLower()}")); } int itensPorPagina = 10; - if(pagina != null) + if (pagina != null) query = query.Skip(((int)pagina - 1) * itensPorPagina).Take(itensPorPagina); - + return query.ToList(); } -} \ No newline at end of file +} diff --git a/Api/Infraestrutura/.gitkeep b/Api/Infraestrutura/Db/.gitkeep similarity index 100% rename from Api/Infraestrutura/.gitkeep rename to Api/Infraestrutura/Db/.gitkeep diff --git a/Api/Infraestrutura/Db/DbContexto.cs b/Api/Infraestrutura/Db/DbContexto.cs index ef7b837..5fb02f2 100644 --- a/Api/Infraestrutura/Db/DbContexto.cs +++ b/Api/Infraestrutura/Db/DbContexto.cs @@ -17,21 +17,22 @@ public DbContexto(IConfiguration configuracaoAppSettings) protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().HasData( - new Administrador { + new Administrador + { Id = 1, Email = "administrador@teste.com", Senha = "123456", Perfil = "Adm" - } + } ); } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - if(!optionsBuilder.IsConfigured) + if (!optionsBuilder.IsConfigured) { var stringConexao = _configuracaoAppSettings.GetConnectionString("MySql")?.ToString(); - if(!string.IsNullOrEmpty(stringConexao)) + if (!string.IsNullOrEmpty(stringConexao)) { optionsBuilder.UseMySql( stringConexao, diff --git a/Api/Migrations/20231115013756_SeedAdministrador.cs b/Api/Migrations/20231115013756_SeedAdministrador.cs deleted file mode 100644 index 457635c..0000000 --- a/Api/Migrations/20231115013756_SeedAdministrador.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace mininal_api.Migrations -{ - /// - public partial class SeedAdministrador : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.InsertData( - table: "Administradores", - columns: new[] { "Id", "Email", "Perfil", "Senha" }, - values: new object[] { 1, "administrador@teste.com", "Adm", "123456" }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DeleteData( - table: "Administradores", - keyColumn: "Id", - keyValue: 1); - } - } -} diff --git a/Api/Migrations/20231114235912_AdministradorMigration.Designer.cs b/Api/Migrations/20250823035408_AdministradorMigration.Designer.cs similarity index 79% rename from Api/Migrations/20231114235912_AdministradorMigration.Designer.cs rename to Api/Migrations/20250823035408_AdministradorMigration.Designer.cs index c0283a3..5430045 100644 --- a/Api/Migrations/20231114235912_AdministradorMigration.Designer.cs +++ b/Api/Migrations/20250823035408_AdministradorMigration.Designer.cs @@ -1,16 +1,17 @@ // using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using MinimalApi.Infraestrutura.Db; #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { [DbContext(typeof(DbContexto))] - [Migration("20231114235912_AdministradorMigration")] + [Migration("20250823035408_AdministradorMigration")] partial class AdministradorMigration { /// @@ -18,14 +19,16 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.14") + .HasAnnotation("ProductVersion", "9.0.3") .HasAnnotation("Relational:MaxIdentifierLength", 64); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("MinimalApi.Dominio.Entidades.Administrador", b => { - b.Property("Id") + b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("varchar(255)"); b.Property("Email") .IsRequired() diff --git a/Api/Migrations/20231114235912_AdministradorMigration.cs b/Api/Migrations/20250823035408_AdministradorMigration.cs similarity index 81% rename from Api/Migrations/20231114235912_AdministradorMigration.cs rename to Api/Migrations/20250823035408_AdministradorMigration.cs index 544c116..8ecaa0d 100644 --- a/Api/Migrations/20231114235912_AdministradorMigration.cs +++ b/Api/Migrations/20250823035408_AdministradorMigration.cs @@ -1,9 +1,8 @@ -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { /// public partial class AdministradorMigration : Migration @@ -18,8 +17,8 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "Administradores", columns: table => new { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Id = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), Email = table.Column(type: "varchar(255)", maxLength: 255, nullable: false) .Annotation("MySql:CharSet", "utf8mb4"), Senha = table.Column(type: "varchar(50)", maxLength: 50, nullable: false) diff --git a/Api/Migrations/20231115013756_SeedAdministrador.Designer.cs b/Api/Migrations/20250823141835_SeedAdmnistrador.Designer.cs similarity index 82% rename from Api/Migrations/20231115013756_SeedAdministrador.Designer.cs rename to Api/Migrations/20250823141835_SeedAdmnistrador.Designer.cs index 251457e..0f67aa6 100644 --- a/Api/Migrations/20231115013756_SeedAdministrador.Designer.cs +++ b/Api/Migrations/20250823141835_SeedAdmnistrador.Designer.cs @@ -1,32 +1,37 @@ // using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using MinimalApi.Infraestrutura.Db; #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { [DbContext(typeof(DbContexto))] - [Migration("20231115013756_SeedAdministrador")] - partial class SeedAdministrador + [Migration("20250823141835_SeedAdmnistrador")] + partial class SeedAdmnistrador { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.14") + .HasAnnotation("ProductVersion", "9.0.3") .HasAnnotation("Relational:MaxIdentifierLength", 64); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("MinimalApi.Dominio.Entidades.Administrador", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Email") .IsRequired() .HasMaxLength(255) diff --git a/Api/Migrations/20250823141835_SeedAdmnistrador.cs b/Api/Migrations/20250823141835_SeedAdmnistrador.cs new file mode 100644 index 0000000..d4a9146 --- /dev/null +++ b/Api/Migrations/20250823141835_SeedAdmnistrador.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace minimal_api.Migrations +{ + /// + public partial class SeedAdmnistrador : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Id", + table: "Administradores", + type: "int", + nullable: false, + oldClrType: typeof(string), + oldType: "varchar(255)") + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.InsertData( + table: "Administradores", + columns: new[] { "Id", "Email", "Perfil", "Senha" }, + values: new object[] { 1, "administrador@teste.com", "Adm", "123456" }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DeleteData( + table: "Administradores", + keyColumn: "Id", + keyValue: 1); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Administradores", + type: "varchar(255)", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4") + .OldAnnotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn); + } + } +} diff --git a/Api/Migrations/20231115020944_VeiculosMigration.Designer.cs b/Api/Migrations/20250823205255_VeiculosMigration.Designer.cs similarity index 85% rename from Api/Migrations/20231115020944_VeiculosMigration.Designer.cs rename to Api/Migrations/20250823205255_VeiculosMigration.Designer.cs index b302174..f2a027d 100644 --- a/Api/Migrations/20231115020944_VeiculosMigration.Designer.cs +++ b/Api/Migrations/20250823205255_VeiculosMigration.Designer.cs @@ -1,16 +1,17 @@ // using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using MinimalApi.Infraestrutura.Db; #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { [DbContext(typeof(DbContexto))] - [Migration("20231115020944_VeiculosMigration")] + [Migration("20250823205255_VeiculosMigration")] partial class VeiculosMigration { /// @@ -18,15 +19,19 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.14") + .HasAnnotation("ProductVersion", "9.0.3") .HasAnnotation("Relational:MaxIdentifierLength", 64); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("MinimalApi.Dominio.Entidades.Administrador", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Email") .IsRequired() .HasMaxLength(255) @@ -62,6 +67,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Ano") .HasColumnType("int"); diff --git a/Api/Migrations/20231115020944_VeiculosMigration.cs b/Api/Migrations/20250823205255_VeiculosMigration.cs similarity index 97% rename from Api/Migrations/20231115020944_VeiculosMigration.cs rename to Api/Migrations/20250823205255_VeiculosMigration.cs index 572071f..1421b6f 100644 --- a/Api/Migrations/20231115020944_VeiculosMigration.cs +++ b/Api/Migrations/20250823205255_VeiculosMigration.cs @@ -3,7 +3,7 @@ #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { /// public partial class VeiculosMigration : Migration diff --git a/Api/Migrations/DbContextoModelSnapshot.cs b/Api/Migrations/DbContextoModelSnapshot.cs index 59b35c6..16b7401 100644 --- a/Api/Migrations/DbContextoModelSnapshot.cs +++ b/Api/Migrations/DbContextoModelSnapshot.cs @@ -1,12 +1,13 @@ // using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using MinimalApi.Infraestrutura.Db; #nullable disable -namespace mininal_api.Migrations +namespace minimal_api.Migrations { [DbContext(typeof(DbContexto))] partial class DbContextoModelSnapshot : ModelSnapshot @@ -15,15 +16,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.14") + .HasAnnotation("ProductVersion", "9.0.3") .HasAnnotation("Relational:MaxIdentifierLength", 64); + MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder); + modelBuilder.Entity("MinimalApi.Dominio.Entidades.Administrador", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Email") .IsRequired() .HasMaxLength(255) @@ -59,6 +64,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("Ano") .HasColumnType("int"); diff --git a/Api/Program.cs b/Api/Program.cs index 7a73725..badbc2f 100644 --- a/Api/Program.cs +++ b/Api/Program.cs @@ -1,11 +1,13 @@ +using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal; using MinimalApi; -IHostBuilder CreateHostBuilder(string[] args){ - return Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup(); - }); +IHostBuilder CreateHostBuilder(string[] args) +{ + return Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); } CreateHostBuilder(args).Build().Run(); \ No newline at end of file diff --git a/Api/Properties/launchSettings.json b/Api/Properties/launchSettings.json index 449da1b..d02d4e7 100644 --- a/Api/Properties/launchSettings.json +++ b/Api/Properties/launchSettings.json @@ -1,18 +1,11 @@ { - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:45127", - "sslPort": 44302 - } - }, + "$schema": "https://json.schemastore.org/launchsettings.json", "profiles": { "http": { "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "http://localhost:5004", + "applicationUrl": "http://localhost:5288", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } @@ -21,14 +14,7 @@ "commandName": "Project", "dotnetRunMessages": true, "launchBrowser": true, - "applicationUrl": "https://localhost:7257;http://localhost:5004", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, + "applicationUrl": "https://localhost:7176;http://localhost:5288", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } diff --git a/Api/Startup.cs b/Api/Startup.cs index 9fa4f87..e94c750 100644 --- a/Api/Startup.cs +++ b/Api/Startup.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using MinimalApi; @@ -21,25 +22,31 @@ public class Startup public Startup(IConfiguration configuration) { Configuration = configuration; - key = Configuration?.GetSection("Jwt")?.ToString() ?? ""; + key = Configuration.GetSection("Jwt").ToString() ?? ""; } private string key = ""; - public IConfiguration Configuration { get;set; } = default!; + + public IConfiguration Configuration { get; set; } = default!; public void ConfigureServices(IServiceCollection services) { - services.AddAuthentication(option => { - option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(option => { - option.TokenValidationParameters = new TokenValidationParameters{ - ValidateLifetime = true, - IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)), - ValidateIssuer = false, - ValidateAudience = false, - }; - }); + services.AddAuthentication(option => +{ + option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +}).AddJwtBearer(option => +{ + option.TokenValidationParameters = new TokenValidationParameters + { + ValidateLifetime = true, + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)), + ValidateIssuer = false, + ValidateAudience = false, + }; +}); + + services.AddAuthorization(); @@ -47,8 +54,10 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddEndpointsApiExplorer(); - services.AddSwaggerGen(options => { - options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme{ + services.AddSwaggerGen(options => + { + options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { Name = "Authorization", Type = SecuritySchemeType.Http, Scheme = "bearer", @@ -57,38 +66,27 @@ public void ConfigureServices(IServiceCollection services) Description = "Insira o token JWT aqui" }); - options.AddSecurityRequirement(new OpenApiSecurityRequirement - { + options.AddSecurityRequirement(new OpenApiSecurityRequirement(){ + { + new OpenApiSecurityScheme { + Reference = new OpenApiReference { - new OpenApiSecurityScheme{ - Reference = new OpenApiReference - { - Type = ReferenceType.SecurityScheme, - Id = "Bearer" - } - }, - new string[] {} + Type = ReferenceType.SecurityScheme, + Id = "Bearer" } + }, + new string[] {} + } }); }); - services.AddDbContext(options => { + services.AddDbContext(options => + { options.UseMySql( Configuration.GetConnectionString("MySql"), - ServerVersion.AutoDetect(Configuration.GetConnectionString("MySql")) + ServerVersion.AutoDetect(Configuration.GetConnectionString("mysql")) ); }); - - services.AddCors(options => - { - options.AddDefaultPolicy( - builder => - { - builder.AllowAnyOrigin() - .AllowAnyMethod() - .AllowAnyHeader(); - }); - }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) @@ -101,202 +99,218 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseAuthentication(); app.UseAuthorization(); - app.UseCors(); - app.UseEndpoints(endpoints => { - + #region Home endpoints.MapGet("/", () => Results.Json(new Home())).AllowAnonymous().WithTags("Home"); #endregion #region Administradores - string GerarTokenJwt(Administrador administrador){ - if(string.IsNullOrEmpty(key)) return string.Empty; + string GerarTokenJwt(Administrador administrador) + { + if (string.IsNullOrEmpty(key)) return string.Empty; var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var claims = new List() - { - new Claim("Email", administrador.Email), - new Claim("Perfil", administrador.Perfil), - new Claim(ClaimTypes.Role, administrador.Perfil), - }; - + { + new Claim("Email", administrador.Email), + new Claim("Perfil", administrador.Perfil), + new Claim(ClaimTypes.Role, administrador.Perfil) + }; + var token = new JwtSecurityToken( - claims: claims, - expires: DateTime.Now.AddDays(1), - signingCredentials: credentials - ); + claims: claims, + expires: DateTime.Now.AddDays(1), + signingCredentials: credentials + ); - return new JwtSecurityTokenHandler().WriteToken(token); - } + return new JwtSecurityTokenHandler().WriteToken(token); + } - endpoints.MapPost("/administradores/login", ([FromBody] LoginDTO loginDTO, IAdministradorServico administradorServico) => { - var adm = administradorServico.Login(loginDTO); - if(adm != null) + endpoints.MapPost("/administradores/login", ([FromBody] LoginDTO loginDTO, IAdministradorServico administradorServico) => { + var adm = administradorServico.Login(loginDTO); + if (adm != null) + { + string token = GerarTokenJwt(adm); + return Results.Ok(new AdministradorLogado + { + Email = adm.Email, + Perfil = adm.Perfil, + Token = token + }); + } + else + return Results.Unauthorized(); + }).AllowAnonymous().WithTags("Administradores"); + + endpoints.MapGet("/administradores", ([FromQuery] int? pagina, IAdministradorServico administradorServico) => { - string token = GerarTokenJwt(adm); - return Results.Ok(new AdministradorLogado + var adms = new List(); + var administradores = administradorServico.Todos(pagina); + foreach (var adm in administradores) { - Email = adm.Email, - Perfil = adm.Perfil, - Token = token - }); - } - else - return Results.Unauthorized(); - }).AllowAnonymous().WithTags("Administradores"); - - endpoints.MapGet("/administradores", ([FromQuery] int? pagina, IAdministradorServico administradorServico) => { - var adms = new List(); - var administradores = administradorServico.Todos(pagina); - foreach(var adm in administradores) + adms.Add(new AdministradorModelView + { + Id = adm.Id, + Email = adm.Email, + Perfil = adm.Perfil + }); + } + return Results.Ok(adms); + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) + .WithTags("Administradores"); + + endpoints.MapGet("/administradores/{id}", ([FromRoute] int id, IAdministradorServico administradorServico) => { - adms.Add(new AdministradorModelView{ - Id = adm.Id, - Email = adm.Email, - Perfil = adm.Perfil - }); - } - return Results.Ok(adms); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) - .WithTags("Administradores"); - - endpoints.MapGet("/Administradores/{id}", ([FromRoute] int id, IAdministradorServico administradorServico) => { - var administrador = administradorServico.BuscaPorId(id); - if(administrador == null) return Results.NotFound(); - return Results.Ok(new AdministradorModelView{ + var administrador = administradorServico.BuscaPorId(id); + if (administrador == null) return Results.NotFound(); + return Results.Ok(new AdministradorModelView{ + Id = administrador.Id, + Email = administrador.Email, + Perfil = administrador.Perfil + }); + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) + .WithTags("Administradores"); + + endpoints.MapPost("/administradores", ([FromBody] AdministradorDTO administradorDTO, IAdministradorServico administradorServico) => + { + var validacao = new ErrosDeValidacao + { + Mensagens = new List() + }; + + + if (string.IsNullOrEmpty(administradorDTO.Email)) + validacao.Mensagens.Add("Email não pode ser vazio"); + if (string.IsNullOrEmpty(administradorDTO.Senha)) + validacao.Mensagens.Add("Senha não pode ser vazia"); + if (administradorDTO.Perfil == null) + validacao.Mensagens.Add("Perfil não pode ser vazio"); + + if (validacao.Mensagens.Count > 0) + return Results.BadRequest(validacao); + + var administrador = new Administrador + { + Email = administradorDTO.Email, + Senha = administradorDTO.Senha, + Perfil = administradorDTO.Perfil.ToString() ?? Perfil.Editor.ToString() + }; + + administradorServico.Incluir(administrador); + + return Results.Created($"/administrador/{administrador.Id}", new AdministradorModelView + { Id = administrador.Id, Email = administrador.Email, Perfil = administrador.Perfil - }); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) - .WithTags("Administradores"); - - endpoints.MapPost("/administradores", ([FromBody] AdministradorDTO administradorDTO, IAdministradorServico administradorServico) => { - var validacao = new ErrosDeValidacao{ - Mensagens = new List() - }; - - if(string.IsNullOrEmpty(administradorDTO.Email)) - validacao.Mensagens.Add("Email não pode ser vazio"); - if(string.IsNullOrEmpty(administradorDTO.Senha)) - validacao.Mensagens.Add("Senha não pode ser vazia"); - if(administradorDTO.Perfil == null) - validacao.Mensagens.Add("Perfil não pode ser vazio"); - - if(validacao.Mensagens.Count > 0) - return Results.BadRequest(validacao); - - var administrador = new Administrador{ - Email = administradorDTO.Email, - Senha = administradorDTO.Senha, - Perfil = administradorDTO.Perfil.ToString() ?? Perfil.Editor.ToString() - }; - - administradorServico.Incluir(administrador); - - return Results.Created($"/administrador/{administrador.Id}", new AdministradorModelView{ - Id = administrador.Id, - Email = administrador.Email, - Perfil = administrador.Perfil - }); - - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) - .WithTags("Administradores"); - #endregion + }); - #region Veiculos - ErrosDeValidacao validaDTO(VeiculoDTO veiculoDTO) - { - var validacao = new ErrosDeValidacao{ - Mensagens = new List() - }; - - if(string.IsNullOrEmpty(veiculoDTO.Nome)) - validacao.Mensagens.Add("O nome não pode ser vazio"); - - if(string.IsNullOrEmpty(veiculoDTO.Marca)) - validacao.Mensagens.Add("A Marca não pode ficar em branco"); - - if(veiculoDTO.Ano < 1950) - validacao.Mensagens.Add("Veículo muito antigo, aceito somete anos superiores a 1950"); - - return validacao; - } - - endpoints.MapPost("/veiculos", ([FromBody] VeiculoDTO veiculoDTO, IVeiculoServico veiculoServico) => { - var validacao = validaDTO(veiculoDTO); - if(validacao.Mensagens.Count > 0) - return Results.BadRequest(validacao); - - var veiculo = new Veiculo{ - Nome = veiculoDTO.Nome, - Marca = veiculoDTO.Marca, - Ano = veiculoDTO.Ano - }; - veiculoServico.Incluir(veiculo); - - return Results.Created($"/veiculo/{veiculo.Id}", veiculo); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm,Editor" }) - .WithTags("Veiculos"); - - endpoints.MapGet("/veiculos", ([FromQuery] int? pagina, IVeiculoServico veiculoServico) => { - var veiculos = veiculoServico.Todos(pagina); - - return Results.Ok(veiculos); - }).RequireAuthorization().WithTags("Veiculos"); - - endpoints.MapGet("/veiculos/{id}", ([FromRoute] int id, IVeiculoServico veiculoServico) => { - var veiculo = veiculoServico.BuscaPorId(id); - if(veiculo == null) return Results.NotFound(); - return Results.Ok(veiculo); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm,Editor" }) - .WithTags("Veiculos"); - - endpoints.MapPut("/veiculos/{id}", ([FromRoute] int id, VeiculoDTO veiculoDTO, IVeiculoServico veiculoServico) => { - var veiculo = veiculoServico.BuscaPorId(id); - if(veiculo == null) return Results.NotFound(); - - var validacao = validaDTO(veiculoDTO); - if(validacao.Mensagens.Count > 0) - return Results.BadRequest(validacao); - - veiculo.Nome = veiculoDTO.Nome; - veiculo.Marca = veiculoDTO.Marca; - veiculo.Ano = veiculoDTO.Ano; - - veiculoServico.Atualizar(veiculo); - - return Results.Ok(veiculo); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) - .WithTags("Veiculos"); - - endpoints.MapDelete("/veiculos/{id}", ([FromRoute] int id, IVeiculoServico veiculoServico) => { - var veiculo = veiculoServico.BuscaPorId(id); - if(veiculo == null) return Results.NotFound(); - - veiculoServico.Apagar(veiculo); - - return Results.NoContent(); - }) - .RequireAuthorization() - .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) - .WithTags("Veiculos"); - #endregion + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) + .WithTags("Administradores"); + #endregion + + #region Veiculos + ErrosDeValidacao validaDTO(VeiculoDTO veiculoDTO) + { + var validacao = new ErrosDeValidacao{ + Mensagens = new List() + }; + + if (string.IsNullOrEmpty(veiculoDTO.Nome)) + validacao.Mensagens.Add("O nome não pode ser vazio"); + + if (string.IsNullOrEmpty(veiculoDTO.Marca)) + validacao.Mensagens.Add("A Marca não pode ficar em branco"); + + if (veiculoDTO.Ano < 1950) + validacao.Mensagens.Add("Veículo muito antigo, aceito somente anos superiores a 1950"); + + return validacao; + } + + endpoints.MapPost("/veiculos", ([FromBody] VeiculoDTO veiculoDTO, IVeiculoServico veiculoServico) => + { + var validacao = validaDTO(veiculoDTO); + if (validacao.Mensagens.Count > 0) + return Results.BadRequest(validacao); + + var veiculo = new Veiculo + { + Nome = veiculoDTO.Nome, + Marca = veiculoDTO.Marca, + Ano = veiculoDTO.Ano + }; + veiculoServico.Incluir(veiculo); + + return Results.Created($"/veiculo/{veiculo.Id}", veiculo); + + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm,Editor" }) + .WithTags("Veiculos"); + + endpoints.MapGet("/veiculos", ([FromQuery] int? pagina, IVeiculoServico veiculoServico) => + { + var veiculos = veiculoServico.Todos(pagina); + + return Results.Ok(veiculos); + }).RequireAuthorization().WithTags("Veiculos"); + + endpoints.MapGet("/veiculos/{id}", ([FromRoute] int id, IVeiculoServico veiculoServico) => + { + var veiculo = veiculoServico.BuscaPorId(id); + if (veiculo == null) return Results.NotFound(); + return Results.Ok(veiculo); + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm,Editor" }) + .WithTags("Veiculos"); + + endpoints.MapPut("/veiculos/{id}", ([FromRoute] int id, VeiculoDTO veiculoDTO, IVeiculoServico veiculoServico) => + { + var veiculo = veiculoServico.BuscaPorId(id); + if (veiculo == null) return Results.NotFound(); + + var validacao = validaDTO(veiculoDTO); + if (validacao.Mensagens.Count > 0) + return Results.BadRequest(validacao); + + + veiculo.Nome = veiculoDTO.Nome; + veiculo.Marca = veiculoDTO.Marca; + veiculo.Ano = veiculoDTO.Ano; + + veiculoServico.Atualizar(veiculo); + + return Results.Ok(veiculo); + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) + .WithTags("Veiculos"); + + endpoints.MapDelete("/veiculos/{id}", ([FromRoute] int id, IVeiculoServico veiculoServico) => + { + var veiculo = veiculoServico.BuscaPorId(id); + if (veiculo == null) return Results.NotFound(); + + veiculoServico.Apagar(veiculo); + + return Results.NoContent(); + }) + .RequireAuthorization() + .RequireAuthorization(new AuthorizeAttribute { Roles = "Adm" }) + .WithTags("Veiculos"); + #endregion }); } + } \ No newline at end of file diff --git a/Api/appsettings.json b/Api/appsettings.json index e47fe81..66dc9c0 100644 --- a/Api/appsettings.json +++ b/Api/appsettings.json @@ -7,7 +7,7 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "MySql": "Server=localhost;Database=minimal_api;Uid=root;Pwd=root;" + "MySql": "Server=localhost;Database=minimal_api;Uid=root;Pwd=T0245i@;" }, - "Jwt": "minimal-api-alunos-vamos_lá" + "Jwt": "minimal-api-alunos-vamos_lá" } diff --git a/Api/mininal-api.csproj b/Api/minimal-api.csproj similarity index 78% rename from Api/mininal-api.csproj rename to Api/minimal-api.csproj index 0922f14..f5b3d65 100644 --- a/Api/mininal-api.csproj +++ b/Api/minimal-api.csproj @@ -1,25 +1,25 @@ - - - - net7.0 - enable - enable - mininal_api - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - + + + + net9.0 + enable + enable + minimal_api + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + diff --git a/Api/minimal-api.sln b/Api/minimal-api.sln new file mode 100644 index 0000000..c83c7f0 --- /dev/null +++ b/Api/minimal-api.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "minimal-api", "minimal-api.csproj", "{4DA376C4-2915-E111-8109-D5D194E3BCD9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4DA376C4-2915-E111-8109-D5D194E3BCD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DA376C4-2915-E111-8109-D5D194E3BCD9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DA376C4-2915-E111-8109-D5D194E3BCD9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DA376C4-2915-E111-8109-D5D194E3BCD9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7C53B798-1B08-47BD-ACDA-FE20310906BD} + EndGlobalSection +EndGlobal diff --git a/Test/.vscode/launch.json b/Test/.vscode/launch.json deleted file mode 100644 index 4308a87..0000000 --- a/Test/.vscode/launch.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - // Use IntelliSense to find out which attributes exist for C# debugging - // Use hover for the description of the existing attributes - // For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/bin/Debug/net7.0/Test.dll", - "args": [], - "cwd": "${workspaceFolder}", - // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console - "console": "internalConsole", - "stopAtEntry": false - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach" - } - ] -} \ No newline at end of file diff --git a/Test/.vscode/tasks.json b/Test/.vscode/tasks.json deleted file mode 100644 index cb21122..0000000 --- a/Test/.vscode/tasks.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Test.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/Test.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "--project", - "${workspaceFolder}/Test.csproj" - ], - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file diff --git a/Test/Domain/Entidades/AdministradorTest.cs b/Test/Domain/Entidades/AdministradorTest.cs index c6199fc..56d0146 100644 --- a/Test/Domain/Entidades/AdministradorTest.cs +++ b/Test/Domain/Entidades/AdministradorTest.cs @@ -8,19 +8,34 @@ public class AdministradorTest [TestMethod] public void TestarGetSetPropriedades() { - // Arrange + //Arrange var adm = new Administrador(); - // Act + //Act adm.Id = 1; adm.Email = "teste@teste.com"; adm.Senha = "teste"; adm.Perfil = "Adm"; - // Assert + //Assert Assert.AreEqual(1, adm.Id); Assert.AreEqual("teste@teste.com", adm.Email); Assert.AreEqual("teste", adm.Senha); Assert.AreEqual("Adm", adm.Perfil); + + //Arrange + var vei = new Veiculo(); + + //Act + vei.Id = 1; + vei.Nome = "teste.veiculo"; + vei.Marca = "teste"; + vei.Ano = 1; + + //Assert + Assert.AreEqual(1, vei.Id); + Assert.AreEqual("teste.veiculo", vei.Nome); + Assert.AreEqual("teste", vei.Marca); + Assert.AreEqual(1, vei.Ano); } } \ No newline at end of file diff --git a/Test/Domain/Servicos/AdministradorServico.cs b/Test/Domain/Servicos/AdministradorServico.cs index d036f7f..029698b 100644 --- a/Test/Domain/Servicos/AdministradorServico.cs +++ b/Test/Domain/Servicos/AdministradorServico.cs @@ -1,9 +1,9 @@ -using System.Reflection; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using MinimalApi.Dominio.Entidades; using MinimalApi.Dominio.Servicos; using MinimalApi.Infraestrutura.Db; +using Microsoft.Extensions.Configuration; +using System.Reflection; namespace Test.Domain.Entidades; @@ -14,7 +14,7 @@ private DbContexto CriarContextoDeTeste() { var assemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var path = Path.GetFullPath(Path.Combine(assemblyPath ?? "", "..", "..", "..")); - + // Configurar o ConfigurationBuilder var builder = new ConfigurationBuilder() .SetBasePath(path ?? Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) @@ -25,47 +25,46 @@ private DbContexto CriarContextoDeTeste() return new DbContexto(configuration); } - [TestMethod] - public void TestandoSalvarAdministrador() + public void TestandoBuscaPorId() { - // Arrange + //Arrange var context = CriarContextoDeTeste(); context.Database.ExecuteSqlRaw("TRUNCATE TABLE Administradores"); var adm = new Administrador(); + adm.Id = 1; adm.Email = "teste@teste.com"; adm.Senha = "teste"; adm.Perfil = "Adm"; var administradorServico = new AdministradorServico(context); - // Act + //Act administradorServico.Incluir(adm); + var admDoBanco = administradorServico.BuscaPorId(adm.Id); - // Assert - Assert.AreEqual(1, administradorServico.Todos(1).Count()); + //Assert + Assert.AreEqual(1, admDoBanco?.Id); } +} - [TestMethod] - public void TestandoBuscaPorId() - { - // Arrange - var context = CriarContextoDeTeste(); - context.Database.ExecuteSqlRaw("TRUNCATE TABLE Administradores"); - var adm = new Administrador(); - adm.Email = "teste@teste.com"; - adm.Senha = "teste"; - adm.Perfil = "Adm"; - var administradorServico = new AdministradorServico(context); - // Act - administradorServico.Incluir(adm); - var admDoBanco = administradorServico.BuscaPorId(adm.Id); + // //Arrange + // var vei = new Veiculo(); - // Assert - Assert.AreEqual(1, admDoBanco?.Id); - } -} \ No newline at end of file + // //Act + // vei.Id = 1; + // vei.Nome = "teste.veiculo"; + // vei.Marca = "teste"; + // vei.Ano = 1; + + // //Assert + // Assert.AreEqual(1, vei.Id); + // Assert.AreEqual("teste.veiculo", vei.Nome); + // Assert.AreEqual("teste", vei.Marca); + // Assert.AreEqual(1, vei.Ano); +// } +// } \ No newline at end of file diff --git a/Test/GlobalUsings.cs b/Test/GlobalUsings.cs index ab67c7e..8b7de71 100644 --- a/Test/GlobalUsings.cs +++ b/Test/GlobalUsings.cs @@ -1 +1 @@ -global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] \ No newline at end of file diff --git a/Test/Helpers/Setup.cs b/Test/Helpers/Setup.cs index b2301fb..b196f18 100644 --- a/Test/Helpers/Setup.cs +++ b/Test/Helpers/Setup.cs @@ -1,8 +1,13 @@ -using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Builder; +using Microsoft.EntityFrameworkCore; +using MinimalApi.Infraestrutura.Db; using Microsoft.AspNetCore.Mvc.Testing; +using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; +using Microsoft.AspNetCore.Identity; using MinimalApi.Dominio.Interfaces; using Test.Mocks; using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Hosting; namespace Test.Helpers; @@ -21,12 +26,21 @@ public static void ClassInit(TestContext testContext) Setup.http = Setup.http.WithWebHostBuilder(builder => { builder.UseSetting("https_port", Setup.PORT).UseEnvironment("Testing"); - + builder.ConfigureServices(services => { - services.AddScoped(); - }); + services.AddScoped(); + + /* + //== Casio queira deisar o teste com conexão diferente == + var conexao = "Server=localhost;Database=desafio21dias_dotnet7_test;Uid=root;Pwd=T0245i@"; + services.AddContext(options => + { + options.UseMySql(conexao, ServerVersion.AutoDetect(conexao)); + }); + */ + }); }); Setup.client = Setup.http.CreateClient(); diff --git a/Test/Mocks/AdministradorServicoMock.cs b/Test/Mocks/AdministradorServicoMock.cs index a296289..8d99d6a 100644 --- a/Test/Mocks/AdministradorServicoMock.cs +++ b/Test/Mocks/AdministradorServicoMock.cs @@ -4,9 +4,11 @@ namespace Test.Mocks; -public class AdministradorServicoMock : IAdministradorServico +public class AdministradoresServicoMock : IAdministradorServico { - private static List administradores = new List(){ + + private static List administradores = new List() + { new Administrador{ Id = 1, Email = "adm@teste.com", @@ -20,7 +22,6 @@ public class AdministradorServicoMock : IAdministradorServico Perfil = "Editor" } }; - public Administrador? BuscaPorId(int id) { return administradores.Find(a => a.Id == id); @@ -43,4 +44,6 @@ public List Todos(int? pagina) { return administradores; } -} \ No newline at end of file +} + +// Criar do veiculo \ No newline at end of file diff --git a/Test/Requests/AdministradorRequestTest.cs b/Test/Requests/AdministradorRequestTest.cs index 11e53b1..37e0bf8 100644 --- a/Test/Requests/AdministradorRequestTest.cs +++ b/Test/Requests/AdministradorRequestTest.cs @@ -1,6 +1,9 @@ using System.Net; +using System.Net.Http.Json; using System.Text; using System.Text.Json; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using MinimalApi.Dominio.ModelViews; using MinimalApi.DTOs; using Test.Helpers; @@ -21,25 +24,25 @@ public static void ClassCleanup() { Setup.ClassCleanup(); } - + [TestMethod] public async Task TestarGetSetPropriedades() { - // Arrange - var loginDTO = new LoginDTO{ + //Arrange + var loginDTO = new LoginDTO + { Email = "adm@teste.com", Senha = "123456" }; + var content = new StringContent(JsonSerializer.Serialize(loginDTO), Encoding.UTF8, "Application/json"); - var content = new StringContent(JsonSerializer.Serialize(loginDTO), Encoding.UTF8, "Application/json"); - - // Act + //Act var response = await Setup.client.PostAsync("/administradores/login", content); - // Assert + //Assert Assert.AreEqual(HttpStatusCode.OK, response.StatusCode); - var result = await response.Content.ReadAsStringAsync(); + var result = await response.Content.ReadAsStreamAsync(); var admLogado = JsonSerializer.Deserialize(result, new JsonSerializerOptions { PropertyNameCaseInsensitive = true @@ -51,4 +54,5 @@ public async Task TestarGetSetPropriedades() Console.WriteLine(admLogado?.Token); } -} \ No newline at end of file +} + // Fazer outros testes \ No newline at end of file diff --git a/Test/Test.csproj b/Test/Test.csproj index 8a9165f..c20ec43 100644 --- a/Test/Test.csproj +++ b/Test/Test.csproj @@ -1,24 +1,24 @@ - net7.0 + net9.0 + latest enable enable - - false - true - - - - - + + + - - + + + + + + diff --git a/Test/Test.sln b/Test/Test.sln new file mode 100644 index 0000000..00a347d --- /dev/null +++ b/Test/Test.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.2.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test.csproj", "{1E7CB755-154A-45BD-4B30-C030123AA28B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1E7CB755-154A-45BD-4B30-C030123AA28B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E7CB755-154A-45BD-4B30-C030123AA28B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E7CB755-154A-45BD-4B30-C030123AA28B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E7CB755-154A-45BD-4B30-C030123AA28B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {66DE0E95-E844-4C9C-B8BD-9DE5CD91484F} + EndGlobalSection +EndGlobal diff --git a/Test/appsettings.json b/Test/appsettings.json index 3173660..45ff80a 100644 --- a/Test/appsettings.json +++ b/Test/appsettings.json @@ -7,7 +7,7 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "MySql": "Server=localhost;Database=minimal_apitest;Uid=root;Pwd=root;" + "MySql": "Server=localhost;Database=minimal_apitest;Uid=root;Pwd=T0245i@;" }, - "Jwt": "minimal-api-alunos-vamos_lá" + "Jwt": "minimal-api-alunos-vamos_lá" } diff --git a/Test/minimal_api.dump.sql b/Test/minimal_api.dump.sql index d533dd642a77df86f64d1dc32715ead84610217c..94fed92948ff75452448ae5bd9c4beab0307dc96 100644 GIT binary patch literal 8520 zcmeI2X-`{66o%((EA>CzeloPB!FE7yDobo8MKOkANSb`H9c)rpY+{L;Ki~FwXFS~9 z_ZlaGN(k9Ap5@G$v%WLKzyBuk^T~A0@1{+CXl~7!xujM#%jRdk>(m3YWya>( z+?XrM_xx_qr~c>k|HSVTb3tEV-q3$;R%s8+g87?qtEOjvFPiVnx2(5xR|e)cW{K(x zMxRnYHUr8(C#_o7tvz7OfOQ9q9@)`ncAYW2YDSOmOIrL2fn7&yeT~0x)h^s!nUD56 zn3UJ>b%9L2iOEcJ^m%4}FyAAsWh?J0`|X;RIiy@OduU{fy=@|=b#uUHlb#l}-ei>e z+GdBg4n0lgtd$-eu<|qW>u2HO01mq52wn~;i}{F;pPds)rj0xf+4~-QmmE}f;6pNU zt)7o^qtjfhpcQ@O0bVN|R^7F`4e*p3?7o2wzPI+CC(r2oP^;onlzQf!<-IkLTe>~X znYWiH<@CI!shA((e;JR_cZGdq@hIDqzxq9fJRTv@9U{Y#PfrCXIEN z)x*k;uw&I;Q*Tc+;B5UJG!N*@(`OaFrgNq>6iK|VdOpJTD0g9NQW`$;`7(g2;`AvI zFqq_vTcY|6zH(*Te4cRe+>PtA%O1Tac+%K>V5H)`i<;MD1DAP}Up|@sU5xh;bj!+O zpY;xr)CRI@QQtwk0kuDlmrXJ_I$ zl&S1U)^Wg!ioZgnd(>u)B4NH0{ROgIjlI-tlxR@a`BmqaFi-=}UPo8{G~iAs16q_V z(lMxl$5)69?(9;hzDP^f8bU->=xZgR?Gb;&$y(>clK4vH>1r=4b~mD{C^N>oZ^;`v z360t6bymVrur}?y}pq&2&SX>vXEtOQk!_>qWA{&9Bd=8=R}(+>NV|Z|{=} zvv{8Wq#S?$tK%8|6(;LFCw!Sn_eSqxWGivX(f0s<+aGIh`*-l)w2u_@mXcL2yc0dUS2~U z%FW5+ApVx+?KAo&74A3P8>Q+aXn5NjOpy4ceX$ZYAL4;}tq+J2?$&XMvcdlm=+;54 RbzW1e+#$Z8*086b{{TMwx+?$x literal 4162 zcmd5C+TXcdCx*<9>f;mRTy2(h@d= zn_)Uk6qt|GXz6rX*bdi@d%yModGNH1pF%Go0m2&R7M!!`%>NR)F=8>gMzRFqw}tR) zO)T>k9Q8_PpiO~&)NIFYa@a>-oXC-1Yg= z2i#gP=DIG6xVK@j!u`BUXj?(wS0Z%kL!6$B&oiJH5Y-Ty28IIWmRY(YC!-=F2rH8EQE4{%5Rk*qm5|1o# zS3#JgMv|qoE?y;lsV(O&144UegHvvM-m2o(V6BjgexKiY{_<%ZM2BMkVByTD);%{$ zTb!TN5#Cp__M&5q-#6VuPz@^L+WZf>zMoFYazSn%g(jmYBwDH&s1q~1HxtIPjq9%q zqAG*IE19~mz3o@Gi1-sk#S0(GInvk4R8>rHm+Bf)-Kk;kmlBoz(@t)t64qg{Z*g2m zYSzakq-LIp2bCqatQVu$i(;?43^phMRO$5xr#L`&AsdP;{S~-D#l~Ctc-5i}O9$;H z1*oO)YVKz`bd2=5&Hv2yJdf|Exe;uV2H{GQ6}+aAemz(