diff --git a/CleanArchitecture/.dockerignore b/CleanArchitecture/.dockerignore new file mode 100644 index 0000000..4d72b4f --- /dev/null +++ b/CleanArchitecture/.dockerignore @@ -0,0 +1,30 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/azds.yaml +**/bin +**/charts +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md +!**/.gitignore +!.git/HEAD +!.git/config +!.git/packed-refs +!.git/refs/heads/** \ No newline at end of file diff --git a/CleanArchitecture/CleanArchitecture.API/CleanArchitecture.API.csproj b/CleanArchitecture/CleanArchitecture.API/CleanArchitecture.API.csproj index c854523..98d1f5a 100644 --- a/CleanArchitecture/CleanArchitecture.API/CleanArchitecture.API.csproj +++ b/CleanArchitecture/CleanArchitecture.API/CleanArchitecture.API.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + Linux @@ -11,7 +12,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/CleanArchitecture/CleanArchitecture.API/Dockerfile b/CleanArchitecture/CleanArchitecture.API/Dockerfile new file mode 100644 index 0000000..3d016a6 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.API/Dockerfile @@ -0,0 +1,28 @@ +#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging. + +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base +USER app +WORKDIR /app +EXPOSE 80 + +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["CleanArchitecture.API/CleanArchitecture.API.csproj", "CleanArchitecture.API/"] +COPY ["CleanArchitecture.Application/CleanArchitecture.Application.csproj", "CleanArchitecture.Application/"] +COPY ["CleanArchitecture.Domain/CleanArchitecture.Domain.csproj", "CleanArchitecture.Domain/"] +COPY ["CleanArchitecture.Data/CleanArchitecture.Infrastructure.csproj", "CleanArchitecture.Data/"] +COPY ["CleanArchitecture.Identity/CleanArchitecture.Identity.csproj", "CleanArchitecture.Identity/"] +RUN dotnet restore "./CleanArchitecture.API/CleanArchitecture.API.csproj" +COPY . . +WORKDIR "/src/CleanArchitecture.API" +RUN dotnet build "./CleanArchitecture.API.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./CleanArchitecture.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "CleanArchitecture.API.dll"] diff --git a/CleanArchitecture/CleanArchitecture.API/Properties/launchSettings.json b/CleanArchitecture/CleanArchitecture.API/Properties/launchSettings.json index 88c1e6c..b3ae0a7 100644 --- a/CleanArchitecture/CleanArchitecture.API/Properties/launchSettings.json +++ b/CleanArchitecture/CleanArchitecture.API/Properties/launchSettings.json @@ -1,23 +1,14 @@ -{ - "$schema": "http://json.schemastore.org/launchsettings.json", - "iisSettings": { - "windowsAuthentication": false, - "anonymousAuthentication": true, - "iisExpress": { - "applicationUrl": "http://localhost:32905", - "sslPort": 0 - } - }, +{ "profiles": { "http": { "commandName": "Project", - "dotnetRunMessages": true, "launchBrowser": true, "launchUrl": "swagger", - "applicationUrl": "http://localhost:5124", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" - } + }, + "dotnetRunMessages": true, + "applicationUrl": "http://localhost:14563" }, "IIS Express": { "commandName": "IISExpress", @@ -26,6 +17,24 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" } + }, + "Container (Dockerfile)": { + "commandName": "Docker", + "launchBrowser": true, + "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger", + "environmentVariables": { + "ASPNETCORE_HTTP_PORTS": "80" + }, + "publishAllPorts": true + } + }, + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:22080", + "sslPort": 0 } } -} +} \ No newline at end of file diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj b/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj index ef074c7..2416138 100644 --- a/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj @@ -27,8 +27,4 @@ - - - - diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/CreateStreamer/CreateStreamerCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/CreateStreamer/CreateStreamerCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..533ca72 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/CreateStreamer/CreateStreamerCommandHandlerXUnitTests.cs @@ -0,0 +1,51 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Infrastructure; +using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; +using CleanArchitecture.Application.Features.Streamers.Commands.CreateStreamer; +using Shouldly; +using CleanArchitecture.Domain; +using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer; + +namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Commands.CreateStreamer +{ + public class CreateStreamerCommandHandlerXUnitTests + { + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + private readonly Mock emailService; + private readonly Mock> logger; + + public CreateStreamerCommandHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + emailService = new Mock(); + logger = new Mock>(); + } + + [Fact] + public async Task CreateStreamerTest() + { + var handler = new CreateStreamerCommandHandler(mockUnitOfWork.Object, mapper, emailService.Object, logger.Object); + var request = new CreateStreamerCommand() + { + Nombre = "AlexStream", + Url = "https://AlexStream.com" + }; + var result = await handler.Handle(request, CancellationToken.None); + + result.ShouldBeOfType(); + result.Nombre.ShouldBe("AlexStream"); + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/DeleteStreamer/DeleteStreamerCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/DeleteStreamer/DeleteStreamerCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..69aaa67 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/DeleteStreamer/DeleteStreamerCommandHandlerXUnitTests.cs @@ -0,0 +1,52 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Infrastructure; +using CleanArchitecture.Application.Features.Streamers.Commands.DeleteStreamer; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Domain; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.Extensions.Logging; +using Moq; +using Shouldly; +using Xunit; + +namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Commands.DeleteStreamer +{ + public class DeleteVideoCommandHandlerXUnitTests + { + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + private readonly Mock emailService; + private readonly Mock> logger; + + public DeleteVideoCommandHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + emailService = new Mock(); + logger = new Mock>(); + + MockStreamerRepository.AddDataStreamerRepository(mockUnitOfWork.Object.StreamerDbContext); + } + + [Fact] + public async Task UpdateStreamerTest() + { + var handler = new DeleteStreamerCommandHandler(mockUnitOfWork.Object, mapper, logger.Object); + var request = new DeleteStreamerCommand() + { + Id = Guid.Parse("edfe00d5-7599-4788-b52a-acc2a683b188") + }; + MediatR.Unit result = await handler.Handle(request, CancellationToken.None); + if (result == null) + { + throw new Exception("Result is null"); + } + result.ShouldBeOfType(); + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/UpdateStreamer/UpdateStreamerCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/UpdateStreamer/UpdateStreamerCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..abaec48 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Streamers/Commands/UpdateStreamer/UpdateStreamerCommandHandlerXUnitTests.cs @@ -0,0 +1,61 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Infrastructure; + +using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Domain; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.Extensions.Logging; +using Moq; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CleanArchitecture.Application.UnitTests.Features.Streamers.Commands.UpdateStreamer +{ + public class UpdateStreamerCommandHandlerXUnitTests + { + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + private readonly Mock emailService; + private readonly Mock> logger; + + public UpdateStreamerCommandHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + emailService = new Mock(); + logger = new Mock>(); + + MockStreamerRepository.AddDataStreamerRepository(mockUnitOfWork.Object.StreamerDbContext); + } + + [Fact] + public async Task UpdateStreamerTest() + { + var handler = new UpdateStreamerCommandHandler(mockUnitOfWork.Object, mapper, logger.Object); + var request = new UpdateStreamerCommand() + { + Id = Guid.Parse("edfe00d5-7599-4788-b52a-acc2a683b188"), + Nombre = "AlexStream2", + Url = "https://AlexStream2.com" + }; + var result = await handler.Handle(request, CancellationToken.None); + if(result == null) + { + throw new Exception("Result is null"); + } + result.ShouldBeOfType(); + result.Nombre.ShouldBe("AlexStream2"); + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/CreateVideo/CreateVideoCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/CreateVideo/CreateVideoCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..f6426c2 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/CreateVideo/CreateVideoCommandHandlerXUnitTests.cs @@ -0,0 +1,49 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Infrastructure; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.Extensions.Logging; +using Moq; +using Xunit; +using Shouldly; +using CleanArchitecture.Application.Features.Videos.Commands.CreateVideo; + +namespace CleanArchitecture.Application.UnitTests.Features.Videos.Commands.CreateStreamer +{ + public class CreateVideoCommandHandlerXUnitTests + { + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + private readonly Mock emailService; + private readonly Mock> logger; + + public CreateVideoCommandHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + emailService = new Mock(); + logger = new Mock>(); + } + + [Fact] + public async Task CreateVideoTest() + { + + + var handler = new CreateVideoCommandHandler(mockUnitOfWork.Object, mapper, emailService.Object, logger.Object); + var request = new CreateVideoCommand() + { + Nombre = "Video de ALex" + }; + Domain.Video result = await handler.Handle(request, CancellationToken.None); + + result.ShouldBeOfType(); + result.Nombre.ShouldBe("Video de ALex"); + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/DeleteVideo/DeleteVideoCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/DeleteVideo/DeleteVideoCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..e3ca63b --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/DeleteVideo/DeleteVideoCommandHandlerXUnitTests.cs @@ -0,0 +1,6 @@ +namespace CleanArchitecture.Application.UnitTests.Features.Videos.Commands.DeleteStreamer +{ + public class DeleteVideoCommandHandlerXUnitTests + { + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/UpdateVideo/UpdateVideoCommandHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/UpdateVideo/UpdateVideoCommandHandlerXUnitTests.cs new file mode 100644 index 0000000..8ba8e77 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Commands/UpdateVideo/UpdateVideoCommandHandlerXUnitTests.cs @@ -0,0 +1,61 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Infrastructure; + +using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer; +using CleanArchitecture.Application.Features.Videos.Commands.UpdateVideo; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Domain; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.Extensions.Logging; +using Moq; +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace CleanArchitecture.Application.UnitTests.Features.Videos.Commands.UpdateStreamer +{ + public class UpdateVideoCommandHandlerXUnitTests + { + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + private readonly Mock emailService; + private readonly Mock> logger; + + public UpdateVideoCommandHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + emailService = new Mock(); + logger = new Mock>(); + + MockVideoRepository.AddDataVideoRepository(mockUnitOfWork.Object.StreamerDbContext); + } + + [Fact] + public async Task UpdateVideoTest() + { + var handler = new UpdateVideoCommandHandler(mockUnitOfWork.Object, mapper, logger.Object); + var request = new UpdateVideoCommand() + { + Id = Guid.Parse("edfe00d5-7599-4788-b52a-acc2a683b188"), + Nombre = "Alex Video 2" + }; + Domain.Video result = await handler.Handle(request, CancellationToken.None); + if(result == null) + { + throw new Exception("Result is null"); + } + result.ShouldBeOfType(); + result.Nombre.ShouldBe("Alex Video 2"); + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs index 31e2911..e230572 100644 --- a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs @@ -3,6 +3,7 @@ using CleanArchitecture.Application.Contracts.Persistence; using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList; using CleanArchitecture.Application.Mappings; using CleanArchitecture.Application.UnitTests.Mocks; +using CleanArchitecture.Infrastructure.Repositories; using Moq; using Shouldly; using Xunit; @@ -13,7 +14,7 @@ namespace CleanArchitecture.Application.UnitTests.Features.Video.Queries { private readonly IMapper mapper; - private readonly Mock mockUnitOfWork; + private Mock mockUnitOfWork; public GetVideosListQueryHandlerXUnitTests() { @@ -23,7 +24,7 @@ namespace CleanArchitecture.Application.UnitTests.Features.Video.Queries cfg.AddProfile(); }); mapper = mapperConfiguration.CreateMapper(); - + MockVideoRepository.AddDataVideoRepository(mockUnitOfWork.Object.StreamerDbContext); } [Fact] @@ -35,8 +36,6 @@ namespace CleanArchitecture.Application.UnitTests.Features.Video.Queries result.ShouldBeOfType>(); result.Count.ShouldBe(1); - - } } } diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs index 0b47829..e39c088 100644 --- a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs @@ -1,4 +1,7 @@ -using System; +using AutoFixture; +using CleanArchitecture.Domain; +using CleanArchitecture.Infrastructure.Persistence; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -6,7 +9,23 @@ using System.Threading.Tasks; namespace CleanArchitecture.Application.UnitTests.Mocks { - internal class MockStreamerRepository + public static class MockStreamerRepository { + public static void AddDataStreamerRepository(StreamerDbContext streamerDbContextFake) + { + var fixture = new Fixture(); + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + var streamers = fixture.CreateMany().ToList(); + var guidFromText = Guid.Parse("edfe00d5-7599-4788-b52a-acc2a683b188"); + streamers.Add(fixture.Build() + .With(tr => tr.Id, guidFromText) + .Without(tr => tr.Videos) + .Create() + ); + streamerDbContextFake.Streamers!.AddRange(streamers); + streamerDbContextFake.SaveChanges(); + } + } } diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs index 505848a..aa57ee6 100644 --- a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs @@ -1,18 +1,29 @@ -using CleanArchitecture.Application.Contracts.Persistence; + +using CleanArchitecture.Infrastructure.Persistence; +using CleanArchitecture.Infrastructure.Repositories; +using Microsoft.EntityFrameworkCore; using Moq; namespace CleanArchitecture.Application.UnitTests.Mocks { + public static class MockUnitOfWork { - - public static Mock GetUnitOfWork() + public static Mock GetUnitOfWork() { - var mockUnitOfWork = new Mock(); - var mockVideoRepository = MockVideoRepository.GetVideoRepository(); - mockUnitOfWork.Setup(uow => uow.VideoRepository).Returns(mockVideoRepository.Object); + DbContextOptions options; +//#if DEBUG + +//#else + options = new DbContextOptionsBuilder() + .UseInMemoryDatabase(databaseName: $"StreamerDbContext-{Guid.NewGuid()}").Options; +//#endif + var stramerDbContextFake = new StreamerDbContext(options); + + stramerDbContextFake.Database.EnsureDeleted(); + var mockUnitOfWork = new Mock(stramerDbContextFake); + return mockUnitOfWork; } - } } diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs index 1aafed0..4a03542 100644 --- a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs @@ -10,24 +10,22 @@ namespace CleanArchitecture.Application.UnitTests.Mocks { public static class MockVideoRepository { - public static Mock GetVideoRepository() + public static void AddDataVideoRepository(StreamerDbContext streamerDbContextFake) { var fixture = new Fixture(); fixture.Behaviors.Add(new OmitOnRecursionBehavior()); var videos = fixture.CreateMany