diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/CastMembers/GetCastByFilmIdQuery.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/CastMembers/GetCastByFilmIdQuery.cs new file mode 100644 index 0000000..c171d80 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/CastMembers/GetCastByFilmIdQuery.cs @@ -0,0 +1,15 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.CastMembers +{ + using System.Collections.Generic; + using Models; + + public static class GetCastByFilmIdQuery + { + public static IEnumerable Execute(int filmId) + { + //Do some SQL + + return new[] { new CastMember { Name = "John Travolta" }, new CastMember { Name = "Samuel L Jackson" } }; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Directors/GetDirectorByIdQuery.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Directors/GetDirectorByIdQuery.cs new file mode 100644 index 0000000..5ee0400 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Directors/GetDirectorByIdQuery.cs @@ -0,0 +1,14 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Directors +{ + using Models; + + public static class GetDirectorByIdQuery + { + public static Director Execute(int id) + { + //Do some SQL + + return new Director { Name = "Steven Spielberg" }; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/CreateFilm/CreateFilmRoute.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/CreateFilm/CreateFilmRoute.cs new file mode 100644 index 0000000..0997a92 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/CreateFilm/CreateFilmRoute.cs @@ -0,0 +1,20 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.CreateFilm +{ + using System; + using Models; + + public static class CreateFilmRoute + { + public static void Handle(Film film, ValidUserDelegate validUserQuery) + { + if (!validUserQuery()) + { + throw new InvalidOperationException(); + } + + //Do some special MEGA CORP business validation + + //Save to database by writing SQL here + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Delegates.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Delegates.cs new file mode 100644 index 0000000..b79500e --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Delegates.cs @@ -0,0 +1,21 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films +{ + using System.Collections.Generic; + using Models; + + public delegate Film ListFilmByIdDelegate(int id); + + public delegate void CreateFilmDelegate(Film film); + + public delegate void DeleteFilmDelegate(int id); + + public delegate IEnumerable ListFilmsDelegate(); + + public delegate void UpdateFilmDelegate(int id, Film film); + + public delegate bool ValidUserDelegate(); + + public delegate Director GetDirectorByIdDelegate(int id); + + public delegate IEnumerable GetCastByFilmIdDelegate(int filmId); +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/DeleteFilm/DeleteFilmRoute.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/DeleteFilm/DeleteFilmRoute.cs new file mode 100644 index 0000000..8482e86 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/DeleteFilm/DeleteFilmRoute.cs @@ -0,0 +1,17 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.DeleteFilm +{ + using System; + + public static class DeleteFilmRoute + { + public static void Handle(int id, ValidUserDelegate validUserQuery) + { + if (!validUserQuery()) + { + throw new InvalidOperationException(); + } + + //Write some SQL to delete from DB + } + } +} diff --git a/FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs similarity index 82% rename from FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs rename to FunctionalCarterProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs index 508f666..2fac4ec 100644 --- a/FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/FilmsModule.cs @@ -1,19 +1,26 @@ -namespace FunctionalProject.Features.NamedDelegatesFilms.Films +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films { using System; using System.Threading.Tasks; - using Botwin; - using Botwin.ModelBinding; - using Botwin.Request; - using Botwin.Response; + using Carter; + using Carter.ModelBinding; + using Carter.Request; + using Carter.Response; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Models; + + /*** NO ATTRIBUTES ANYWHERE!!! ***/ - public class FilmsModule : BotwinModule + public class FilmsModule : CarterModule { - public FilmsModule() : base("/api/delegate/films") + public FilmsModule() : base("/api/delegate/films") // --> REPLACE ATTRIBUTES WITH METHOD CALLS ***/ { + /*** REPLACE ATTRIBUTES WITH METHOD CALLS ***/ + //this.RequiresAuthentication(); + + + /*** REPLACE ATTRIBUTES WITH METHOD CALLS ***/ this.Get("/", this.GetFilms); this.Get("/{id:int}", this.GetFilmById); this.Put("/{id:int}", this.UpdateFilm); @@ -23,6 +30,7 @@ public FilmsModule() : base("/api/delegate/films") private async Task CreateFilm(HttpContext context) { + /*** REPLACE ATTRIBUTES WITH METHOD CALLS ***/ var result = context.Request.BindAndValidate(); if (!result.ValidationResult.IsValid) diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmById/ListFilmByIdRoute.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmById/ListFilmByIdRoute.cs new file mode 100644 index 0000000..19198da --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmById/ListFilmByIdRoute.cs @@ -0,0 +1,25 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilmById +{ + using Models; + + public static class ListFilmByIdRoute + { + public static Film Handle(int id, ListFilmByIdDelegate listFilmById, GetDirectorByIdDelegate getDirectorByIdDelegate, GetCastByFilmIdDelegate getCastByFilmIdDelegateQuery) + { + var film = listFilmById(id); + + if (film == null) + { + return null; + } + + var director = getDirectorByIdDelegate(film.DirectorId); + film.Director = director; + + var cast = getCastByFilmIdDelegateQuery(id); + film.Cast = cast; + + return film; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilms/ListFilmsRoute.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilms/ListFilmsRoute.cs new file mode 100644 index 0000000..520f57c --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilms/ListFilmsRoute.cs @@ -0,0 +1,13 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilms +{ + using System.Collections.Generic; + using Models; + + public static class ListFilmsRoute + { + public static IEnumerable Handle() + { + return new[] { new Film { Id = 1, Name = "Pulp Fiction" }, new Film { Id = 2, Name = "Trainspotting" } }; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmsByIdQuery/ListFilmsByIdQuery.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmsByIdQuery/ListFilmsByIdQuery.cs new file mode 100644 index 0000000..5426920 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/ListFilmsByIdQuery/ListFilmsByIdQuery.cs @@ -0,0 +1,12 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilmsByIdQuery +{ + using Models; + + public static class ListFilmsByIdQuery + { + public static Film Execute(int id) + { + return new Film { Id = 1, Name = "Pulp Fiction", DirectorId = 1 }; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Permissions/ValidUserQuery.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Permissions/ValidUserQuery.cs new file mode 100644 index 0000000..228164f --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/Permissions/ValidUserQuery.cs @@ -0,0 +1,12 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.Permissions +{ + using System; + + public static class ValidUserQuery + { + public static bool Execute() + { + return new Random().Next() % 2 == 0; + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/RouteHandlers.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/RouteHandlers.cs new file mode 100644 index 0000000..8f0af15 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/RouteHandlers.cs @@ -0,0 +1,46 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films +{ + using FunctionalCarterProject.Features.NamedDelegatesFilms.CastMembers; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Directors; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.CreateFilm; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.DeleteFilm; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilmById; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilms; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.Permissions; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.UpdateFilm; + + public static class RouteHandlers + { + public static CreateFilmDelegate CreateFilmHandler; + + public static ListFilmByIdDelegate ListFilmByIdHandler; + + public static DeleteFilmDelegate DeleteFilmHandler; + + public static ListFilmsDelegate ListFilmsHandler; + + public static UpdateFilmDelegate UpdateFilmHandler; + + static RouteHandlers() + { + CreateFilmHandler = film => CreateFilmRoute.Handle(film, () => ValidUserQuery.Execute()); + + DeleteFilmHandler = id => DeleteFilmRoute.Handle(id, () => ValidUserQuery.Execute()); + + ListFilmByIdHandler = id => ListFilmByIdRoute.Handle( + id, + filmId => ListFilmsByIdQuery.ListFilmsByIdQuery.Execute(id), + dirId => GetDirectorByIdQuery.Execute(dirId), + filmId => GetCastByFilmIdQuery.Execute(id) + ); + + ListFilmsHandler = () => ListFilmsRoute.Handle(); + + UpdateFilmHandler = (id, film) => UpdateFilmRoute.Handle( + id, + film, + () => ValidUserQuery.Execute(), + filmId => ListFilmsByIdQuery.ListFilmsByIdQuery.Execute(filmId)); + } + } +} diff --git a/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/UpdateFilm/UpdateFilmRoute.cs b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/UpdateFilm/UpdateFilmRoute.cs new file mode 100644 index 0000000..97adc69 --- /dev/null +++ b/FunctionalCarterProject/Features/NamedDelegatesFilms/Films/UpdateFilm/UpdateFilmRoute.cs @@ -0,0 +1,26 @@ +namespace FunctionalCarterProject.Features.NamedDelegatesFilms.Films.UpdateFilm +{ + using System; + using Models; + + public static class UpdateFilmRoute + { + public static void Handle(int id, Film film, ValidUserDelegate validUserQuery, ListFilmByIdDelegate listFilmById) + { + if (!validUserQuery()) + { + throw new InvalidOperationException(); + } + + //Do some special MEGA CORP business validation + + var existingFilm = listFilmById(id); + + existingFilm.Name = film.Name; + existingFilm.Budget = film.Budget; + existingFilm.Language = film.Language; + + //Write some SQL to store in db + } + } +} diff --git a/BotwinMediator/BotwinMediator.csproj b/FunctionalCarterProject/FunctionalCarterProject.csproj similarity index 78% rename from BotwinMediator/BotwinMediator.csproj rename to FunctionalCarterProject/FunctionalCarterProject.csproj index acc63fe..c645e08 100644 --- a/BotwinMediator/BotwinMediator.csproj +++ b/FunctionalCarterProject/FunctionalCarterProject.csproj @@ -1,14 +1,13 @@  netcoreapp2.0 - BotwinMediator + FunctionalCarterProject Exe - latest - + diff --git a/FunctionalCarterProject/Program.cs b/FunctionalCarterProject/Program.cs new file mode 100644 index 0000000..1338bd9 --- /dev/null +++ b/FunctionalCarterProject/Program.cs @@ -0,0 +1,16 @@ +namespace FunctionalCarterProject +{ + using Microsoft.AspNetCore; + using Microsoft.AspNetCore.Hosting; + + public class Program + { + public static void Main(string[] args) + { + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build() + .Run(); + } + } +} diff --git a/FunctionalCarterProject/Startup.cs b/FunctionalCarterProject/Startup.cs new file mode 100644 index 0000000..68df44d --- /dev/null +++ b/FunctionalCarterProject/Startup.cs @@ -0,0 +1,20 @@ +namespace FunctionalCarterProject +{ + using Carter; + using Microsoft.AspNetCore.Builder; + using Microsoft.Extensions.DependencyInjection; + + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + //services.AddCarter(Assembly.GetCallingAssembly(), typeof(FilmValidator).Assembly); + services.AddCarter(); + } + + public void Configure(IApplicationBuilder app) + { + app.UseCarter(); + } + } +} diff --git a/FunctionalCarterProjectTests/Features/Films/FilmTests.cs b/FunctionalCarterProjectTests/Features/Films/FilmTests.cs new file mode 100644 index 0000000..85fcac1 --- /dev/null +++ b/FunctionalCarterProjectTests/Features/Films/FilmTests.cs @@ -0,0 +1,115 @@ +namespace FunctionalCarterProjectTests.Features.Films +{ + using System; + using System.Net.Http; + using System.Text; + using System.Threading.Tasks; + using Carter; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.CreateFilm; + using FunctionalCarterProject.Features.NamedDelegatesFilms.Films.ListFilmById; + using Microsoft.AspNetCore; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.TestHost; + using Models; + using Newtonsoft.Json; + using Xunit; + + public class FilmTests + { + private TestServer server; + + private HttpClient client; + + public FilmTests() + { + this.server = new TestServer(WebHost.CreateDefaultBuilder() + .ConfigureServices(services => services.AddCarter()) + .Configure(app => app.UseCarter()) + ); + + this.client = this.server.CreateClient(); + } + + [Fact] + public async Task Should_return_422_on_invalid_data_when_creating_film() + { + //Given + + //No mock library required to fake the UserValidQuery we just invoke a func to return true/false + + RouteHandlers.CreateFilmHandler = film => CreateFilmRoute.Handle(film, () => true); + + var newFilm = new Film { Name = "" }; + + //When + var response = await this.client.PostAsync("/api/delegate/films", new StringContent(JsonConvert.SerializeObject(newFilm), Encoding.UTF8, "application/json")); + + //Then + Assert.Equal(422, (int)response.StatusCode); + } + + [Fact] + public async Task Should_return_403_on_invalid_user_when_creating_film() + { + //Given + RouteHandlers.CreateFilmHandler = film => CreateFilmRoute.Handle(film, () => false); + + var newFilm = new Film { Name = "Shrek" }; + + //When + var response = await this.client.PostAsync("/api/delegate/films", new StringContent(JsonConvert.SerializeObject(newFilm), Encoding.UTF8, "application/json")); + + //Then + Assert.Equal(403, (int)response.StatusCode); + } + + [Fact] + public async Task Should_return_201_when_creating_film() + { + //Given + RouteHandlers.CreateFilmHandler = film => CreateFilmRoute.Handle(film, () => true); + + var newFilm = new Film { Name = "Shrek" }; + + //When + var response = await this.client.PostAsync("/api/delegate/films", new StringContent(JsonConvert.SerializeObject(newFilm), Encoding.UTF8, "application/json")); + + //Then + Assert.Equal(201, (int)response.StatusCode); + } + + [Fact] + public async Task Should_get_film_by_id() + { + //Given + + //No mock library required to fake the GetFilmByIdDelegate, GetDirectorById, GetCastMembersByFilmId we just invoke a func + + RouteHandlers.ListFilmByIdHandler = id => ListFilmByIdRoute.Handle(id, filmid => new Film { Name = "Blade Runner" }, i => new Director(), filmId => new[] { new CastMember() }); + + //When + var response = await this.client.GetAsync("/api/delegate/films/1"); + var contents = await response.Content.ReadAsStringAsync(); + + //Then + Assert.Contains("Blade Runner", contents, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public async Task Should_return_404_when_no_film_found_via_get_film_by_id() + { + //Given + + //No mock library required to fake the GetFilmByIdDelegate, GetDirectorById, GetCastMembersByFilmId we just invoke a func + + RouteHandlers.ListFilmByIdHandler = id => ListFilmByIdRoute.Handle(id, filmid => null, i => new Director(), filmId => new[] { new CastMember() }); + + //When + var response = await this.client.GetAsync("/api/delegate/films/1"); + + //Then + Assert.Equal(404, (int)response.StatusCode); + } + } +} diff --git a/FunctionalCarterProjectTests/FunctionalCarterProjectTests.csproj b/FunctionalCarterProjectTests/FunctionalCarterProjectTests.csproj new file mode 100644 index 0000000..a35f3c9 --- /dev/null +++ b/FunctionalCarterProjectTests/FunctionalCarterProjectTests.csproj @@ -0,0 +1,15 @@ + + + Exe + netcoreapp2.0 + + + + + + + + + + + \ No newline at end of file diff --git a/FunctionalProject/Features/FuncFilms/FilmsController.cs b/FunctionalProject/Features/FuncFilms/FilmsController.cs new file mode 100644 index 0000000..ce62efc --- /dev/null +++ b/FunctionalProject/Features/FuncFilms/FilmsController.cs @@ -0,0 +1,102 @@ +namespace FunctionalProject.Features.FuncFilms +{ + using System; + using System.Collections.Generic; + using Microsoft.AspNetCore.Mvc; + using Models; + + [Route("api/[controller]")] + public class FilmsController : Controller + { + // GET api/films + [HttpGet] + public IEnumerable Get() + { + var handler = RouteHandlers.ListFilmsHandler; + + var films = handler(); + + return films; + } + + // GET api/films/5 + [HttpGet("{id}")] + public IActionResult Get(int id) + { + var handler = RouteHandlers.ListFilmByIdHandler; + + var film = handler(id); + + if (film == null) + { + return this.NotFound(); + } + + return this.Ok(film); + } + + // POST api/films + [HttpPost] + public IActionResult Post([FromBody] Film film) + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var handler = RouteHandlers.CreateFilmHandler; + + handler(film); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(201); + } + + // PUT api/films/5 + [HttpPut("{id}")] + public IActionResult Put(int id, [FromBody] Film film) + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var handler = RouteHandlers.UpdateFilmHandler; + + handler(id, film); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + + // DELETE api/films/5 + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + try + { + var handler = RouteHandlers.DeleteFilmHandler; + + handler(id); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + } +} diff --git a/FunctionalProject/Features/FuncFilms/FilmsModule.cs b/FunctionalProject/Features/FuncFilms/FilmsModule.cs deleted file mode 100644 index e3c0687..0000000 --- a/FunctionalProject/Features/FuncFilms/FilmsModule.cs +++ /dev/null @@ -1,116 +0,0 @@ -namespace FunctionalProject.Features.FuncFilms -{ - using System; - using System.Threading.Tasks; - using Botwin; - using Botwin.ModelBinding; - using Botwin.Request; - using Botwin.Response; - using Microsoft.AspNetCore.Http; - using Microsoft.AspNetCore.Routing; - using Models; - - public class FilmsModule : BotwinModule - { - public FilmsModule() : base("/api/funcy/films") - { - this.Get("/", this.GetFilms); - this.Get("/{id:int}", this.GetFilmById); - this.Put("/{id:int}", this.UpdateFilm); - this.Post("/", this.CreateFilm); - this.Delete("/{id:int}", this.DeleteFilm); - } - - private async Task GetFilms(HttpContext context) - { - var handler = RouteHandlers.ListFilmsHandler; - - var films = handler(); - - await context.Response.AsJson(films); - } - - private async Task GetFilmById(HttpContext context) - { - var handler = RouteHandlers.ListFilmByIdHandler; - - var film = handler(context.GetRouteData().As("id")); - - if (film == null) - { - context.Response.StatusCode = 404; - return; - } - - await context.Response.AsJson(film); - } - - private async Task CreateFilm(HttpContext context) - { - var result = context.Request.BindAndValidate(); - - if (!result.ValidationResult.IsValid) - { - context.Response.StatusCode = 422; - await context.Response.Negotiate(result.ValidationResult.GetFormattedErrors()); - return; - } - - try - { - var handler = RouteHandlers.CreateFilmHandler; - - handler(result.Data); - - context.Response.StatusCode = 201; - } - catch (Exception) - { - context.Response.StatusCode = 403; - } - } - - private async Task UpdateFilm(HttpContext context) - { - var result = context.Request.BindAndValidate(); - - if (!result.ValidationResult.IsValid) - { - context.Response.StatusCode = 422; - await context.Response.Negotiate(result.ValidationResult.GetFormattedErrors()); - return; - } - - try - { - var handler = RouteHandlers.UpdateFilmHandler; - - handler(context.GetRouteData().As("id"), result.Data); - - context.Response.StatusCode = 204; - } - catch (Exception) - { - context.Response.StatusCode = 403; - } - } - - private Task DeleteFilm(HttpContext context) - { - try - { - var handler = RouteHandlers.DeleteFilmHandler; - - handler(context.GetRouteData().As("id")); - - context.Response.StatusCode = 204; - } - catch (Exception) - { - context.Response.StatusCode = 403; - } - - return Task.CompletedTask; - } - } -} diff --git a/FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsController.cs b/FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsController.cs new file mode 100644 index 0000000..46adaf7 --- /dev/null +++ b/FunctionalProject/Features/NamedDelegatesFilms/Films/FilmsController.cs @@ -0,0 +1,111 @@ +namespace FunctionalProject.Features.NamedDelegatesFilms.Films +{ + using System; + using System.Collections.Generic; + using Microsoft.AspNetCore.Authorization; + using Microsoft.AspNetCore.Mvc; + using Models; + + [Route("api/delegate/[controller]")] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + [AllowAnonymous] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + [Controller] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + public class FilmsController : Controller + { + // GET api/films + [HttpGet] + public IEnumerable Get() + { + var handler = RouteHandlers.ListFilmsHandler; + + var films = handler(); + + return films; + } + + // GET api/films/5 + [HttpGet("{id}")] + public IActionResult Get(int id) + { + var handler = RouteHandlers.ListFilmByIdHandler; + + var film = handler(id); + + if (film == null) + { + return this.NotFound(); + } + + return this.Ok(film); + } + + // POST api/films + [HttpPost] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + [Produces("application/json")] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + [Consumes("application/json")] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + [ProducesResponseType(201)] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + + [OoohINeedToDoSomeSpecialLogicJustForThisMethod] /**** WHAT IS THIS MAGIC ATTRIBUTE DOING?? ****/ + + public IActionResult Post([FromBody] Film film) /**** OH GOD ATTRIBUTES IN METHODS!! ****/ + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var handler = RouteHandlers.CreateFilmHandler; + + handler(film); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(201); + } + + // PUT api/films/5 + [HttpPut("{id}")] + public IActionResult Put(int id, [FromBody] Film film) + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var handler = RouteHandlers.UpdateFilmHandler; + + handler(id, film); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + + // DELETE api/films/5 + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + try + { + var handler = RouteHandlers.DeleteFilmHandler; + + handler(id); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + } +} diff --git a/FunctionalProject/Features/NamedDelegatesFilms/Films/OoohINeedToDoSomeSpecialLogicJustForThisMethodAttribute.cs b/FunctionalProject/Features/NamedDelegatesFilms/Films/OoohINeedToDoSomeSpecialLogicJustForThisMethodAttribute.cs new file mode 100644 index 0000000..ee49855 --- /dev/null +++ b/FunctionalProject/Features/NamedDelegatesFilms/Films/OoohINeedToDoSomeSpecialLogicJustForThisMethodAttribute.cs @@ -0,0 +1,8 @@ +namespace FunctionalProject.Features.NamedDelegatesFilms.Films +{ + using System; + + public class OoohINeedToDoSomeSpecialLogicJustForThisMethodAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/FunctionalProject/FunctionalProject.csproj b/FunctionalProject/FunctionalProject.csproj index 70e42d1..dd6dd2f 100644 --- a/FunctionalProject/FunctionalProject.csproj +++ b/FunctionalProject/FunctionalProject.csproj @@ -5,10 +5,8 @@ Exe - - - - + + diff --git a/FunctionalProject/Startup.cs b/FunctionalProject/Startup.cs index d652cfd..a664ab4 100644 --- a/FunctionalProject/Startup.cs +++ b/FunctionalProject/Startup.cs @@ -1,7 +1,7 @@ namespace FunctionalProject { - using System.Reflection; - using Botwin; + using FluentValidation; + using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Models; @@ -10,12 +10,14 @@ public class Startup { public void ConfigureServices(IServiceCollection services) { - services.AddBotwin(Assembly.GetCallingAssembly(), typeof(FilmValidator).Assembly); + services.AddTransient, FilmValidator>(); + + services.AddMvc().AddFluentValidation(); } public void Configure(IApplicationBuilder app) { - app.UseBotwin(); + app.UseMvc(); } } } diff --git a/FunctionalProjectTests/Features/Films/FilmTests.cs b/FunctionalProjectTests/Features/Films/FilmTests.cs index 93e2ab2..632ce92 100644 --- a/FunctionalProjectTests/Features/Films/FilmTests.cs +++ b/FunctionalProjectTests/Features/Films/FilmTests.cs @@ -4,13 +4,16 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; - using Botwin; + using FluentValidation; + using FluentValidation.AspNetCore; using FunctionalProject.Features.NamedDelegatesFilms.Films; using FunctionalProject.Features.NamedDelegatesFilms.Films.CreateFilm; using FunctionalProject.Features.NamedDelegatesFilms.Films.ListFilmById; using Microsoft.AspNetCore; + using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.TestHost; + using Microsoft.Extensions.DependencyInjection; using Models; using Newtonsoft.Json; using Xunit; @@ -24,15 +27,19 @@ public class FilmTests public FilmTests() { server = new TestServer(WebHost.CreateDefaultBuilder() - .ConfigureServices(services => services.AddBotwin(typeof(RouteHandlers).Assembly, typeof(FilmValidator).Assembly)) - .Configure(app => app.UseBotwin()) + .ConfigureServices(services => + { + services.AddMvc().AddFluentValidation(); + services.AddTransient, FilmValidator>(); + }) + .Configure(app => app.UseMvc()) ); client = server.CreateClient(); } [Fact] - public async Task Should_return_422_on_invalid_data_when_creating_film() + public async Task Should_return_400_on_invalid_data_when_creating_film() { //Given @@ -46,7 +53,7 @@ public async Task Should_return_422_on_invalid_data_when_creating_film() var response = await client.PostAsync("/api/delegate/films", new StringContent(JsonConvert.SerializeObject(newFilm), Encoding.UTF8, "application/json")); //Then - Assert.Equal(422, (int)response.StatusCode); + Assert.Equal(400, (int)response.StatusCode); } [Fact] diff --git a/BotwinMediator/CommandHandler.cs b/HandRolledMediator/CommandHandler.cs similarity index 93% rename from BotwinMediator/CommandHandler.cs rename to HandRolledMediator/CommandHandler.cs index 0bc58db..3d2f963 100644 --- a/BotwinMediator/CommandHandler.cs +++ b/HandRolledMediator/CommandHandler.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator +namespace HandRolledMediator { public abstract class CommandHandler : ICommandHandler { diff --git a/BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs b/HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs similarity index 83% rename from BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs rename to HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs index 9cead37..b4db6d1 100644 --- a/BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs +++ b/HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/GetCastByFilmIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.CastMembers.GetCastByFilmIdQuery +namespace HandRolledMediator.Features.CastMembers.GetCastByFilmIdQuery { using System.Collections.Generic; using Models; diff --git a/BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs b/HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs similarity index 69% rename from BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs rename to HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs index 6f480db..f8c00d3 100644 --- a/BotwinMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs +++ b/HandRolledMediator/Features/CastMembers/GetCastByFilmIdQuery/IGetCastByFilmIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.CastMembers.GetCastByFilmIdQuery +namespace HandRolledMediator.Features.CastMembers.GetCastByFilmIdQuery { using System.Collections.Generic; using Models; diff --git a/BotwinMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs b/HandRolledMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs similarity index 78% rename from BotwinMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs rename to HandRolledMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs index 4d1ddc4..d4103e7 100644 --- a/BotwinMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs +++ b/HandRolledMediator/Features/Directors/GetDirectorByIdQuery/GetDirectorByIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Directors.GetDirectorByIdQuery +namespace HandRolledMediator.Features.Directors.GetDirectorByIdQuery { using Models; diff --git a/BotwinMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs b/HandRolledMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs similarity index 60% rename from BotwinMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs rename to HandRolledMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs index be9478a..a73312e 100644 --- a/BotwinMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs +++ b/HandRolledMediator/Features/Directors/GetDirectorByIdQuery/IGetDirectorByIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Directors.GetDirectorByIdQuery +namespace HandRolledMediator.Features.Directors.GetDirectorByIdQuery { using Models; diff --git a/BotwinMediator/Features/Films/CreateFilm/CreateFilmCommand.cs b/HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommand.cs similarity index 77% rename from BotwinMediator/Features/Films/CreateFilm/CreateFilmCommand.cs rename to HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommand.cs index 3a1b1d2..779891b 100644 --- a/BotwinMediator/Features/Films/CreateFilm/CreateFilmCommand.cs +++ b/HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommand.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.CreateFilm +namespace HandRolledMediator.Features.Films.CreateFilm { using Models; diff --git a/BotwinMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs b/HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs similarity index 85% rename from BotwinMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs rename to HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs index 18f0cf5..4af5de8 100644 --- a/BotwinMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs +++ b/HandRolledMediator/Features/Films/CreateFilm/CreateFilmCommandHandler.cs @@ -1,7 +1,7 @@ -namespace BotwinMediator.Features.Films.CreateFilm +namespace HandRolledMediator.Features.Films.CreateFilm { using System; - using BotwinMediator.Features.Permissions; + using HandRolledMediator.Features.Permissions; public class CreateFilmCommandHandler : CommandHandler { diff --git a/BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs b/HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs similarity index 74% rename from BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs rename to HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs index 0a88877..1570701 100644 --- a/BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs +++ b/HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommand.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.DeleteFilm +namespace HandRolledMediator.Features.Films.DeleteFilm { public class DeleteFilmCommand { diff --git a/BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs b/HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs similarity index 84% rename from BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs rename to HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs index aeec544..bf626b2 100644 --- a/BotwinMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs +++ b/HandRolledMediator/Features/Films/DeleteFilm/DeleteFilmCommandHandler.cs @@ -1,7 +1,7 @@ -namespace BotwinMediator.Features.Films.DeleteFilm +namespace HandRolledMediator.Features.Films.DeleteFilm { using System; - using BotwinMediator.Features.Permissions; + using HandRolledMediator.Features.Permissions; public class DeleteFilmCommandHandler : CommandHandler { diff --git a/HandRolledMediator/Features/Films/FilmsController.cs b/HandRolledMediator/Features/Films/FilmsController.cs new file mode 100644 index 0000000..2144af3 --- /dev/null +++ b/HandRolledMediator/Features/Films/FilmsController.cs @@ -0,0 +1,108 @@ +namespace HandRolledMediator.Features.Films +{ + using System; + using System.Collections.Generic; + using HandRolledMediator.Features.Films.CreateFilm; + using HandRolledMediator.Features.Films.DeleteFilm; + using HandRolledMediator.Features.Films.ListFilmById; + using HandRolledMediator.Features.Films.ListFilms; + using HandRolledMediator.Features.Films.UpdateFilm; + using Microsoft.AspNetCore.Mvc; + using Models; + + [Route("api/[controller]")] + public class FilmsController : Controller + { + private readonly Handler handler; + + public FilmsController(Handler handler) + { + this.handler = handler; + } + + // GET api/films + [HttpGet] + public IEnumerable Get() + { + var command = new ListFilmsCommand(); + return this.handler.Execute>(command); + } + + // GET api/films/5 + [HttpGet("{id}")] + public IActionResult Get(int id) + { + var command = new ListFilmsByIdCommand(id); + + var film = this.handler.Execute(command); + + if (film == null) + { + return this.NotFound(); + } + + return this.Ok(film); + } + + // POST api/films + [HttpPost] + public IActionResult Post([FromBody] Film film) + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var command = new CreateFilmCommand(film); + this.handler.Handle(command); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(201); + } + + // PUT api/films/5 + [HttpPut("{id}")] + public IActionResult Put(int id, [FromBody] Film film) + { + if (!this.ModelState.IsValid) + { + return this.BadRequest(this.ModelState); + } + + try + { + var command = new UpdateFilmCommand(id, film); + this.handler.Handle(command); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + + // DELETE api/films/5 + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + try + { + var command = new DeleteFilmCommand(id); + this.handler.Handle(command); + } + catch (InvalidOperationException) + { + return this.StatusCode(403); + } + + return this.StatusCode(204); + } + } +} diff --git a/BotwinMediator/Features/Films/FilmsModule.cs b/HandRolledMediator/Features/Films/FilmsModule.cs similarity index 100% rename from BotwinMediator/Features/Films/FilmsModule.cs rename to HandRolledMediator/Features/Films/FilmsModule.cs diff --git a/BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs b/HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs similarity index 74% rename from BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs rename to HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs index 27d4d61..c09ade4 100644 --- a/BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs +++ b/HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommand.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.ListFilmById +namespace HandRolledMediator.Features.Films.ListFilmById { public class ListFilmsByIdCommand { diff --git a/BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs b/HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs similarity index 83% rename from BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs rename to HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs index 7a9093e..6052644 100644 --- a/BotwinMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs +++ b/HandRolledMediator/Features/Films/ListFilmById/ListFilmsByIdCommandHandler.cs @@ -1,8 +1,8 @@ -namespace BotwinMediator.Features.Films.ListFilmById +namespace HandRolledMediator.Features.Films.ListFilmById { - using BotwinMediator.Features.CastMembers.GetCastByFilmIdQuery; - using BotwinMediator.Features.Directors.GetDirectorByIdQuery; - using BotwinMediator.Features.Films.ListFilmByIdQuery; + using HandRolledMediator.Features.CastMembers.GetCastByFilmIdQuery; + using HandRolledMediator.Features.Directors.GetDirectorByIdQuery; + using HandRolledMediator.Features.Films.ListFilmByIdQuery; public class ListFilmsByIdCommandHandler : CommandHandler { diff --git a/BotwinMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs b/HandRolledMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs similarity index 61% rename from BotwinMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs rename to HandRolledMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs index ef91404..8fe98df 100644 --- a/BotwinMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs +++ b/HandRolledMediator/Features/Films/ListFilmByIdQuery/IListFilmByIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.ListFilmByIdQuery +namespace HandRolledMediator.Features.Films.ListFilmByIdQuery { using Models; diff --git a/BotwinMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs b/HandRolledMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs similarity index 77% rename from BotwinMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs rename to HandRolledMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs index 86d8d23..2a7a15d 100644 --- a/BotwinMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs +++ b/HandRolledMediator/Features/Films/ListFilmByIdQuery/ListFilmByIdQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.ListFilmByIdQuery +namespace HandRolledMediator.Features.Films.ListFilmByIdQuery { using Models; diff --git a/BotwinMediator/Features/Films/ListFilms/ListFilmsCommand.cs b/HandRolledMediator/Features/Films/ListFilms/ListFilmsCommand.cs similarity index 51% rename from BotwinMediator/Features/Films/ListFilms/ListFilmsCommand.cs rename to HandRolledMediator/Features/Films/ListFilms/ListFilmsCommand.cs index f9c21bf..30b5509 100644 --- a/BotwinMediator/Features/Films/ListFilms/ListFilmsCommand.cs +++ b/HandRolledMediator/Features/Films/ListFilms/ListFilmsCommand.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.ListFilms +namespace HandRolledMediator.Features.Films.ListFilms { public class ListFilmsCommand { diff --git a/BotwinMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs b/HandRolledMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs similarity index 84% rename from BotwinMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs rename to HandRolledMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs index 7082168..404a488 100644 --- a/BotwinMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs +++ b/HandRolledMediator/Features/Films/ListFilms/ListFilmsCommandHandler.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.ListFilms +namespace HandRolledMediator.Features.Films.ListFilms { using Models; diff --git a/BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs b/HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs similarity index 82% rename from BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs rename to HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs index 3600584..136daa3 100644 --- a/BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs +++ b/HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommand.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Films.UpdateFilm +namespace HandRolledMediator.Features.Films.UpdateFilm { using Models; diff --git a/BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs b/HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs similarity index 86% rename from BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs rename to HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs index 9f8955e..b76ea7c 100644 --- a/BotwinMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs +++ b/HandRolledMediator/Features/Films/UpdateFilm/UpdateFilmCommandHandler.cs @@ -1,8 +1,8 @@ -namespace BotwinMediator.Features.Films.UpdateFilm +namespace HandRolledMediator.Features.Films.UpdateFilm { using System; - using BotwinMediator.Features.Films.ListFilmByIdQuery; - using BotwinMediator.Features.Permissions; + using HandRolledMediator.Features.Films.ListFilmByIdQuery; + using HandRolledMediator.Features.Permissions; public class UpdateFilmCommandHandler : CommandHandler { diff --git a/BotwinMediator/Features/Permissions/IValidUserQuery.cs b/HandRolledMediator/Features/Permissions/IValidUserQuery.cs similarity index 59% rename from BotwinMediator/Features/Permissions/IValidUserQuery.cs rename to HandRolledMediator/Features/Permissions/IValidUserQuery.cs index 9a0197d..be08d35 100644 --- a/BotwinMediator/Features/Permissions/IValidUserQuery.cs +++ b/HandRolledMediator/Features/Permissions/IValidUserQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Permissions +namespace HandRolledMediator.Features.Permissions { public interface IValidUserQuery { diff --git a/BotwinMediator/Features/Permissions/ValidUserQuery.cs b/HandRolledMediator/Features/Permissions/ValidUserQuery.cs similarity index 77% rename from BotwinMediator/Features/Permissions/ValidUserQuery.cs rename to HandRolledMediator/Features/Permissions/ValidUserQuery.cs index f37315b..1e8db03 100644 --- a/BotwinMediator/Features/Permissions/ValidUserQuery.cs +++ b/HandRolledMediator/Features/Permissions/ValidUserQuery.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator.Features.Permissions +namespace HandRolledMediator.Features.Permissions { using System; diff --git a/HandRolledMediator/HandRolledMediator.csproj b/HandRolledMediator/HandRolledMediator.csproj new file mode 100644 index 0000000..5375612 --- /dev/null +++ b/HandRolledMediator/HandRolledMediator.csproj @@ -0,0 +1,18 @@ + + + netcoreapp2.0 + BotwinMediator + Exe + latest + + + + + + + + + + + + \ No newline at end of file diff --git a/BotwinMediator/Handler.cs b/HandRolledMediator/Handler.cs similarity index 97% rename from BotwinMediator/Handler.cs rename to HandRolledMediator/Handler.cs index fd1730c..c32b0f2 100644 --- a/BotwinMediator/Handler.cs +++ b/HandRolledMediator/Handler.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator +namespace HandRolledMediator { using System; using System.Collections.Generic; diff --git a/BotwinMediator/ICommandHandler.cs b/HandRolledMediator/ICommandHandler.cs similarity index 80% rename from BotwinMediator/ICommandHandler.cs rename to HandRolledMediator/ICommandHandler.cs index 7f902de..3db63f1 100644 --- a/BotwinMediator/ICommandHandler.cs +++ b/HandRolledMediator/ICommandHandler.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator +namespace HandRolledMediator { public interface ICommandHandler { diff --git a/BotwinMediator/Program.cs b/HandRolledMediator/Program.cs similarity index 91% rename from BotwinMediator/Program.cs rename to HandRolledMediator/Program.cs index b386cd6..273590b 100644 --- a/BotwinMediator/Program.cs +++ b/HandRolledMediator/Program.cs @@ -1,4 +1,4 @@ -namespace BotwinMediator +namespace HandRolledMediator { using Microsoft.AspNetCore; using Microsoft.AspNetCore.Hosting; diff --git a/BotwinMediator/Startup.cs b/HandRolledMediator/Startup.cs similarity index 61% rename from BotwinMediator/Startup.cs rename to HandRolledMediator/Startup.cs index 6514268..31708cf 100644 --- a/BotwinMediator/Startup.cs +++ b/HandRolledMediator/Startup.cs @@ -1,16 +1,16 @@ -namespace BotwinMediator +namespace HandRolledMediator { - using System.Reflection; - using Botwin; - using BotwinMediator.Features.CastMembers.GetCastByFilmIdQuery; - using BotwinMediator.Features.Directors.GetDirectorByIdQuery; - using BotwinMediator.Features.Films.CreateFilm; - using BotwinMediator.Features.Films.DeleteFilm; - using BotwinMediator.Features.Films.ListFilmById; - using BotwinMediator.Features.Films.ListFilmByIdQuery; - using BotwinMediator.Features.Films.ListFilms; - using BotwinMediator.Features.Films.UpdateFilm; - using BotwinMediator.Features.Permissions; + using FluentValidation; + using FluentValidation.AspNetCore; + using HandRolledMediator.Features.CastMembers.GetCastByFilmIdQuery; + using HandRolledMediator.Features.Directors.GetDirectorByIdQuery; + using HandRolledMediator.Features.Films.CreateFilm; + using HandRolledMediator.Features.Films.DeleteFilm; + using HandRolledMediator.Features.Films.ListFilmById; + using HandRolledMediator.Features.Films.ListFilmByIdQuery; + using HandRolledMediator.Features.Films.ListFilms; + using HandRolledMediator.Features.Films.UpdateFilm; + using HandRolledMediator.Features.Permissions; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.DependencyInjection; using Models; @@ -32,13 +32,16 @@ public void ConfigureServices(IServiceCollection services) new ListFilmsCommandHandler(), new UpdateFilmCommandHandler(s.GetRequiredService(),s.GetRequiredService()) })); + + services.AddTransient, FilmValidator>(); + + services.AddMvc().AddFluentValidation(); - services.AddBotwin(Assembly.GetCallingAssembly(), typeof(FilmValidator).Assembly); } public void Configure(IApplicationBuilder app) { - app.UseBotwin(); + app.UseMvc(); } } } diff --git a/Slides.pptx b/Slides.pptx index 6b444e4..5361eb0 100755 Binary files a/Slides.pptx and b/Slides.pptx differ diff --git a/DDDScot.sln b/T1000.sln similarity index 73% rename from DDDScot.sln rename to T1000.sln index 30e240e..b1b4f04 100644 --- a/DDDScot.sln +++ b/T1000.sln @@ -13,11 +13,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediatRWebAPI", "MediatRWeb EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3. Mediator Project (no external deps)", "3. Mediator Project (no external deps)", "{892479C5-1CB2-4748-A910-89A57995D73C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BotwinMediator", "BotwinMediator\BotwinMediator.csproj", "{3442E574-7406-4DD0-A28A-96534CE47310}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HandRolledMediator", "HandRolledMediator\HandRolledMediator.csproj", "{3442E574-7406-4DD0-A28A-96534CE47310}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4. Functional Project", "4. Functional Project", "{345FCBAD-019D-4A9B-B7A3-05A536BECBA4}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5. Functional Carter Project", "5. Functional Carter Project", "{345FCBAD-019D-4A9B-B7A3-05A536BECBA4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalProject", "FunctionalProject\FunctionalProject.csproj", "{A511EF90-1484-45BA-8D8E-2BB733597A84}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalCarterProject", "FunctionalCarterProject\FunctionalCarterProject.csproj", "{A511EF90-1484-45BA-8D8E-2BB733597A84}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E2EE7155-DAB9-4A7F-9D2E-2A38ECCCC566}" EndProject @@ -31,9 +31,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2. MediatR Project Tests", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediatRWebAPI.Tests", "MediatRWebAPI.Tests\MediatRWebAPI.Tests.csproj", "{E9EA372B-B08D-4C2E-B78A-948810D79F02}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3. Functional Project Tests", "3. Functional Project Tests", "{F03EA84D-15EF-4E1D-8FBE-79FFC0FDC277}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4. Functional Carter Project Tests", "4. Functional Carter Project Tests", "{F03EA84D-15EF-4E1D-8FBE-79FFC0FDC277}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalProjectTests", "FunctionalProjectTests\FunctionalProjectTests.csproj", "{0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalCarterProjectTests", "FunctionalCarterProjectTests\FunctionalCarterProjectTests.csproj", "{0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4. Functional Project", "4. Functional Project", "{FA6BC71B-8C97-477D-8391-1DB5BC4FD9EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalProject", "FunctionalProject\FunctionalProject.csproj", "{B74551EE-9A45-4198-A745-7304029376B9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3. Functional Project Tests", "3. Functional Project Tests", "{0EA3053A-0977-4915-AEEA-9B5510B25D00}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionalProjectTests", "FunctionalProjectTests\FunctionalProjectTests.csproj", "{69BEA771-2C21-4FDF-B68C-2531812AB003}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -117,6 +125,30 @@ Global {0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A}.Release|x64.Build.0 = Release|Any CPU {0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A}.Release|x86.ActiveCfg = Release|Any CPU {0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A}.Release|x86.Build.0 = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|Any CPU.Build.0 = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|x64.ActiveCfg = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|x64.Build.0 = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|x86.ActiveCfg = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Debug|x86.Build.0 = Debug|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|x64.ActiveCfg = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|x64.Build.0 = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|x86.ActiveCfg = Release|Any CPU + {B74551EE-9A45-4198-A745-7304029376B9}.Release|x86.Build.0 = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|Any CPU.Build.0 = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|x64.ActiveCfg = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|x64.Build.0 = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|x86.ActiveCfg = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Debug|x86.Build.0 = Debug|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|x64.ActiveCfg = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|x64.Build.0 = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|x86.ActiveCfg = Release|Any CPU + {69BEA771-2C21-4FDF-B68C-2531812AB003}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {626AD192-F5D0-4AE1-AEEC-7B8FE40E927F} = {66D3DCED-78BD-4DB8-8C8D-3A5FA09543C6} @@ -133,5 +165,9 @@ Global {E9EA372B-B08D-4C2E-B78A-948810D79F02} = {694570A7-D60F-4058-A86F-B146204891B7} {F03EA84D-15EF-4E1D-8FBE-79FFC0FDC277} = {44C1DD68-1371-456C-9541-BCC3CEE8A2BE} {0A4CAD93-00B1-4ED6-9C92-3DB4C4F8509A} = {F03EA84D-15EF-4E1D-8FBE-79FFC0FDC277} + {FA6BC71B-8C97-477D-8391-1DB5BC4FD9EF} = {E2EE7155-DAB9-4A7F-9D2E-2A38ECCCC566} + {B74551EE-9A45-4198-A745-7304029376B9} = {FA6BC71B-8C97-477D-8391-1DB5BC4FD9EF} + {0EA3053A-0977-4915-AEEA-9B5510B25D00} = {44C1DD68-1371-456C-9541-BCC3CEE8A2BE} + {69BEA771-2C21-4FDF-B68C-2531812AB003} = {0EA3053A-0977-4915-AEEA-9B5510B25D00} EndGlobalSection EndGlobal diff --git a/DDDScot.sln.DotSettings b/T1000.sln.DotSettings similarity index 100% rename from DDDScot.sln.DotSettings rename to T1000.sln.DotSettings diff --git a/T1000settings.jar b/T1000settings.jar new file mode 100644 index 0000000..e8a3818 Binary files /dev/null and b/T1000settings.jar differ diff --git a/TraditionalWebAPI.Tests/Controllers/FilmControllerTests.cs b/TraditionalWebAPI.Tests/Controllers/FilmControllerTests.cs index f578f2d..2aaa7a0 100644 --- a/TraditionalWebAPI.Tests/Controllers/FilmControllerTests.cs +++ b/TraditionalWebAPI.Tests/Controllers/FilmControllerTests.cs @@ -1,4 +1,4 @@ -namespace TradtionalWebAPI.Tests.Controllers +namespace TraditionalWebAPI.Tests.Controllers { using System; using System.Net.Http; diff --git a/TraditionalWebAPI.Tests/Services/FilmServiceTests.cs b/TraditionalWebAPI.Tests/Services/FilmServiceTests.cs index b244387..139fb15 100644 --- a/TraditionalWebAPI.Tests/Services/FilmServiceTests.cs +++ b/TraditionalWebAPI.Tests/Services/FilmServiceTests.cs @@ -1,4 +1,4 @@ -namespace TradtionalWebAPI.Tests.Services +namespace TraditionalWebAPI.Tests.Services { using System; using FakeItEasy; diff --git a/TraditionalWebAPI/Controllers/FilmsController.cs b/TraditionalWebAPI/Controllers/FilmsController.cs index 7bbb8d4..53ac184 100644 --- a/TraditionalWebAPI/Controllers/FilmsController.cs +++ b/TraditionalWebAPI/Controllers/FilmsController.cs @@ -2,10 +2,12 @@ { using System; using System.Collections.Generic; + using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Models; using TraditionalWebAPI.Services; + [AllowAnonymous] [Route("api/[controller]")] public class FilmsController : Controller {