diff --git a/CleanArchitecture/CleanArchitecture.API/Controllers/StreamerController.cs b/CleanArchitecture/CleanArchitecture.API/Controllers/StreamerController.cs index 1128e83..80547c1 100644 --- a/CleanArchitecture/CleanArchitecture.API/Controllers/StreamerController.cs +++ b/CleanArchitecture/CleanArchitecture.API/Controllers/StreamerController.cs @@ -25,7 +25,7 @@ namespace CleanArchitecture.API.Controllers public async Task> CreateStreamer([FromBody] CreateStreamerCommand command) { var response = await mediator.Send(command); - return Ok(new { StreamerId = response }); + return Ok(response); } [HttpPut(Name = "UpdateStreamer")] @@ -35,8 +35,8 @@ namespace CleanArchitecture.API.Controllers [ProducesDefaultResponseType] public async Task UpdateStreamer([FromBody] UpdateStreamerCommand command) { - await mediator.Send(command); - return NoContent(); + var createdStreamer = await mediator.Send(command); + return Ok(createdStreamer); } [HttpDelete("{id}", Name = "DeleteStreamer")] @@ -44,7 +44,7 @@ namespace CleanArchitecture.API.Controllers [ProducesResponseType((int)HttpStatusCode.NoContent)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesDefaultResponseType] - public async Task DeleteStreamer(int id) + public async Task DeleteStreamer(Guid id) { var request = new DeleteStreamerCommand() { Id = id }; await mediator.Send(request); diff --git a/CleanArchitecture/CleanArchitecture.API/Controllers/VideoController.cs b/CleanArchitecture/CleanArchitecture.API/Controllers/VideoController.cs index c5a464b..54caf39 100644 --- a/CleanArchitecture/CleanArchitecture.API/Controllers/VideoController.cs +++ b/CleanArchitecture/CleanArchitecture.API/Controllers/VideoController.cs @@ -1,4 +1,11 @@ -using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList; +using CleanArchitecture.Application.Features.Streamers.Commands.CreateStreamer; +using CleanArchitecture.Application.Features.Streamers.Commands.DeleteStreamer; +using CleanArchitecture.Application.Features.Streamers.Commands.UpdateStreamer; +using CleanArchitecture.Application.Features.Videos.Commands.CreateVideo; +using CleanArchitecture.Application.Features.Videos.Commands.DeleteVideo; +using CleanArchitecture.Application.Features.Videos.Commands.UpdateVideo; +using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList; +using CleanArchitecture.Domain; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -27,5 +34,37 @@ namespace CleanArchitecture.API.Controllers var videos = await mediator.Send(query); return Ok(videos); } + + [HttpPost(Name = "CreateVideo")] + [Authorize(Roles = "Administrator")] + [ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)] + public async Task> CreateVideo([FromBody] CreateVideoCommand command) + { + var response = await mediator.Send(command); + return Ok(response); + } + + [HttpPut(Name = "UpdateVideo")] + [Authorize(Roles = "Administrator")] + [ProducesResponseType((int)HttpStatusCode.NoContent)] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + [ProducesDefaultResponseType] + public async Task> UpdateVideo([FromBody] UpdateVideoCommand command) + { + var response = await mediator.Send(command); + return Ok(response); + } + + [HttpDelete("{id}", Name = "DeleteVideo")] + [Authorize(Roles = "Administrator")] + [ProducesResponseType((int)HttpStatusCode.NoContent)] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + [ProducesDefaultResponseType] + public async Task DeleteVideo(Guid id) + { + var request = new DeleteVideoCommand() { Id = id }; + await mediator.Send(request); + return NoContent(); + } } } diff --git a/CleanArchitecture/CleanArchitecture.API/appsettings.json b/CleanArchitecture/CleanArchitecture.API/appsettings.json index 7ec6057..351455a 100644 --- a/CleanArchitecture/CleanArchitecture.API/appsettings.json +++ b/CleanArchitecture/CleanArchitecture.API/appsettings.json @@ -1,7 +1,7 @@ { "ConnectionStrings": { - "ConnectionString": "server=localhost;database=CleanArchitecture;user=root;password=securePassword", + "ConnectionString": "server=localhost;database=CleanArchitectureV2;user=root;password=securePassword", "IdentityConnectionString": "server=localhost;database=CleanArchitecture.Security;user=root;password=securePassword" }, "EmailSettings": { diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj b/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj new file mode 100644 index 0000000..ef074c7 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/CleanArchitecture.Application.UnitTests.csproj @@ -0,0 +1,34 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs new file mode 100644 index 0000000..31e2911 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Features/Video/Queries/GetVideosListQueryHandlerXUnitTests.cs @@ -0,0 +1,42 @@ +using AutoMapper; +using CleanArchitecture.Application.Contracts.Persistence; +using CleanArchitecture.Application.Features.Videos.Queries.GetVideosList; +using CleanArchitecture.Application.Mappings; +using CleanArchitecture.Application.UnitTests.Mocks; +using Moq; +using Shouldly; +using Xunit; + +namespace CleanArchitecture.Application.UnitTests.Features.Video.Queries +{ + public class GetVideosListQueryHandlerXUnitTests + { + + private readonly IMapper mapper; + private readonly Mock mockUnitOfWork; + + public GetVideosListQueryHandlerXUnitTests() + { + mockUnitOfWork = MockUnitOfWork.GetUnitOfWork(); + var mapperConfiguration = new MapperConfiguration(cfg => + { + cfg.AddProfile(); + }); + mapper = mapperConfiguration.CreateMapper(); + + } + + [Fact] + public async Task GetVideoListTest() + { + var handler = new GetVideosListQueryHandler(mockUnitOfWork.Object, mapper); + var request = new GetVideosListQuery("Alex"); + var result = await handler.Handle(request, CancellationToken.None); + + result.ShouldBeOfType>(); + result.Count.ShouldBe(1); + + + } + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs new file mode 100644 index 0000000..0b47829 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockStreamerRepository.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CleanArchitecture.Application.UnitTests.Mocks +{ + internal class MockStreamerRepository + { + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs new file mode 100644 index 0000000..505848a --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockUnitOfWork.cs @@ -0,0 +1,18 @@ +using CleanArchitecture.Application.Contracts.Persistence; +using Moq; + +namespace CleanArchitecture.Application.UnitTests.Mocks +{ + public static class MockUnitOfWork + { + + public static Mock GetUnitOfWork() + { + var mockUnitOfWork = new Mock(); + var mockVideoRepository = MockVideoRepository.GetVideoRepository(); + mockUnitOfWork.Setup(uow => uow.VideoRepository).Returns(mockVideoRepository.Object); + return mockUnitOfWork; + } + + } +} diff --git a/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs new file mode 100644 index 0000000..1aafed0 --- /dev/null +++ b/CleanArchitecture/CleanArchitecture.Application.UnitTests/Mocks/MockVideoRepository.cs @@ -0,0 +1,33 @@ +using AutoFixture; +using CleanArchitecture.Application.Contracts.Persistence; +using CleanArchitecture.Domain; +using CleanArchitecture.Infrastructure.Persistence; +using Microsoft.EntityFrameworkCore; +using Moq; +using CleanArchitecture.Infrastructure.Repositories; + +namespace CleanArchitecture.Application.UnitTests.Mocks +{ + public static class MockVideoRepository + { + public static Mock GetVideoRepository() + { + var fixture = new Fixture(); + fixture.Behaviors.Add(new OmitOnRecursionBehavior()); + + var videos = fixture.CreateMany