Unverified Commit 66e44dd2 authored by Steve Smith's avatar Steve Smith Committed by GitHub

Endpoints (#112)

* Adding GetByIdAsync

* Adding async List to repo

* Got Swagger tags working

* Implemented Update

* Added Delete endpoint and repository async methods

* fixing nuget issue with swashbuckle pkg
parent 718954a7
......@@ -6,7 +6,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ardalis.GuardClauses" Version="1.3.3" />
<PackageReference Include="Ardalis.GuardClauses" Version="1.4.2" />
</ItemGroup>
<ItemGroup>
......
......@@ -8,25 +8,25 @@ namespace CleanArchitecture.Core
{
public static int PopulateDatabase(IRepository todoRepository)
{
if (todoRepository.List<ToDoItem>().Count() >= 3) return 0;
if (todoRepository.ListAsync<ToDoItem>().Result.Count() >= 3) return 0;
todoRepository.Add(new ToDoItem
todoRepository.AddAsync(new ToDoItem
{
Title = "Get Sample Working",
Description = "Try to get the sample to build."
});
todoRepository.Add(new ToDoItem
}).Wait();
todoRepository.AddAsync(new ToDoItem
{
Title = "Review Solution",
Description = "Review the different projects in the solution and how they relate to one another."
});
todoRepository.Add(new ToDoItem
}).Wait();
todoRepository.AddAsync(new ToDoItem
{
Title = "Run and Review Tests",
Description = "Make sure all the tests run and review what they are doing."
});
}).Wait();
return todoRepository.List<ToDoItem>().Count;
return todoRepository.ListAsync<ToDoItem>().Result.Count;
}
}
}
......@@ -6,12 +6,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="5.0.0" />
<PackageReference Include="Autofac" Version="5.1.3" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="6.0.0" />
<PackageReference Include="Ardalis.EFCore.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
<PackageReference Include="SQLite" Version="3.13.0" />
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
</ItemGroup>
......
......@@ -3,6 +3,7 @@ using CleanArchitecture.SharedKernel;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CleanArchitecture.Infrastructure.Data
{
......@@ -20,29 +21,34 @@ namespace CleanArchitecture.Infrastructure.Data
return _dbContext.Set<T>().SingleOrDefault(e => e.Id == id);
}
public List<T> List<T>() where T : BaseEntity
public Task<T> GetByIdAsync<T>(int id) where T : BaseEntity
{
return _dbContext.Set<T>().ToList();
return _dbContext.Set<T>().SingleOrDefaultAsync(e => e.Id == id);
}
public T Add<T>(T entity) where T : BaseEntity
public Task<List<T>> ListAsync<T>() where T : BaseEntity
{
_dbContext.Set<T>().Add(entity);
_dbContext.SaveChanges();
return _dbContext.Set<T>().ToListAsync();
}
public async Task<T> AddAsync<T>(T entity) where T : BaseEntity
{
await _dbContext.Set<T>().AddAsync(entity);
await _dbContext.SaveChangesAsync();
return entity;
}
public void Delete<T>(T entity) where T : BaseEntity
public async Task UpdateAsync<T>(T entity) where T : BaseEntity
{
_dbContext.Set<T>().Remove(entity);
_dbContext.SaveChanges();
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
}
public void Update<T>(T entity) where T : BaseEntity
public async Task DeleteAsync<T>(T entity) where T : BaseEntity
{
_dbContext.Entry(entity).State = EntityState.Modified;
_dbContext.SaveChanges();
_dbContext.Set<T>().Remove(entity);
await _dbContext.SaveChangesAsync();
}
}
}
using System.Collections.Generic;
using System.Threading.Tasks;
namespace CleanArchitecture.SharedKernel.Interfaces
{
public interface IRepository
{
T GetById<T>(int id) where T : BaseEntity;
List<T> List<T>() where T : BaseEntity;
T Add<T>(T entity) where T : BaseEntity;
void Update<T>(T entity) where T : BaseEntity;
void Delete<T>(T entity) where T : BaseEntity;
Task<T> GetByIdAsync<T>(int id) where T : BaseEntity;
Task<List<T>> ListAsync<T>() where T : BaseEntity;
Task<T> AddAsync<T>(T entity) where T : BaseEntity;
Task UpdateAsync<T>(T entity) where T : BaseEntity;
Task DeleteAsync<T>(T entity) where T : BaseEntity;
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ using CleanArchitecture.Web.ApiModels;
using CleanArchitecture.Web.Filters;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Api
{
......@@ -18,40 +19,40 @@ namespace CleanArchitecture.Web.Api
// GET: api/ToDoItems
[HttpGet]
public IActionResult List()
public async Task<IActionResult> List()
{
var items = _repository.List<ToDoItem>()
var items = (await _repository.ListAsync<ToDoItem>())
.Select(ToDoItemDTO.FromToDoItem);
return Ok(items);
}
// GET: api/ToDoItems
[HttpGet("{id:int}")]
public IActionResult GetById(int id)
public async Task<IActionResult> GetById(int id)
{
var item = ToDoItemDTO.FromToDoItem(_repository.GetById<ToDoItem>(id));
var item = ToDoItemDTO.FromToDoItem(await _repository.GetByIdAsync<ToDoItem>(id));
return Ok(item);
}
// POST: api/ToDoItems
[HttpPost]
public IActionResult Post([FromBody] ToDoItemDTO item)
public async Task<IActionResult> Post([FromBody] ToDoItemDTO item)
{
var todoItem = new ToDoItem()
{
Title = item.Title,
Description = item.Description
};
_repository.Add(todoItem);
await _repository.AddAsync(todoItem);
return Ok(ToDoItemDTO.FromToDoItem(todoItem));
}
[HttpPatch("{id:int}/complete")]
public IActionResult Complete(int id)
public async Task<IActionResult> Complete(int id)
{
var toDoItem = _repository.GetById<ToDoItem>(id);
var toDoItem = await _repository.GetByIdAsync<ToDoItem>(id);
toDoItem.MarkComplete();
_repository.Update(toDoItem);
await _repository.UpdateAsync(toDoItem);
return Ok(ToDoItemDTO.FromToDoItem(toDoItem));
}
......
......@@ -9,17 +9,25 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ardalis.ApiEndpoints" Version="0.9.4" />
<PackageReference Include="Ardalis.ListStartupServices" Version="1.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" Version="3.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" PrivateAssets="All" Version="3.1.1" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.0.96" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" PrivateAssets="all" Version="3.1.3" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" PrivateAssets="All" Version="3.1.2" />
<PackageReference Include="Microsoft.Web.LibraryManager.Build" Version="2.1.76" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.3" />
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.3.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CleanArchitecture.Infrastructure\CleanArchitecture.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Endpoints\ToDoItems\Update.NewToDoItemRequest.cs">
<DependentUpon>Update.cs</DependentUpon>
</Compile>
</ItemGroup>
</Project>
......@@ -4,6 +4,7 @@ using CleanArchitecture.SharedKernel.Interfaces;
using CleanArchitecture.Web.ApiModels;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Controllers
{
......@@ -16,9 +17,9 @@ namespace CleanArchitecture.Web.Controllers
_repository = repository;
}
public IActionResult Index()
public async Task<IActionResult> Index()
{
var items = _repository.List<ToDoItem>()
var items = (await _repository.ListAsync<ToDoItem>())
.Select(ToDoItemDTO.FromToDoItem);
return View(items);
}
......
using System.ComponentModel.DataAnnotations;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class NewToDoItemRequest
{
[Required]
public string Title { get; set; }
public string Description { get; set; }
}
}
\ No newline at end of file
using Ardalis.ApiEndpoints;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class Create : BaseAsyncEndpoint<NewToDoItemRequest,ToDoItemResponse>
{
private readonly IRepository _repository;
public Create(IRepository repository)
{
_repository = repository;
}
[HttpPost("/ToDoItems")]
[SwaggerOperation(
Summary = "Creates a new ToDoItem",
Description = "Creates a new ToDoItem",
OperationId = "ToDoItem.Create",
Tags = new[] { "ToDoItemEndpoint" })
]
public override async Task<ActionResult<ToDoItemResponse>> HandleAsync(NewToDoItemRequest request)
{
var item = new ToDoItem
{
Title = request.Title,
Description = request.Description
};
var createdItem = await _repository.AddAsync(item);
return Ok(createdItem);
}
}
}
using Ardalis.ApiEndpoints;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class Delete : BaseAsyncEndpoint<int,ToDoItemResponse>
{
private readonly IRepository _repository;
public Delete(IRepository repository)
{
_repository = repository;
}
[HttpDelete("/ToDoItems/{id:int}")]
[SwaggerOperation(
Summary = "Deletes a ToDoItem",
Description = "Deletes a ToDoItem",
OperationId = "ToDoItem.Delete",
Tags = new[] { "ToDoItemEndpoint" })
]
public override async Task<ActionResult<ToDoItemResponse>> HandleAsync(int id)
{
var itemToDelete = await _repository.GetByIdAsync<ToDoItem>(id);
if (itemToDelete == null) return NotFound();
await _repository.DeleteAsync<ToDoItem>(itemToDelete);
return NoContent();
}
}
}
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class ToDoItemResponse
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool IsDone { get; set; }
}
}
\ No newline at end of file
using Ardalis.ApiEndpoints;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class GetById : BaseAsyncEndpoint<int,ToDoItemResponse>
{
private readonly IRepository _repository;
public GetById(IRepository repository)
{
_repository = repository;
}
[HttpGet("/ToDoItems/{id:int}")]
[SwaggerOperation(
Summary = "Gets a single ToDoItem",
Description = "Gets a single ToDoItem by Id",
OperationId = "ToDoItem.GetById",
Tags = new[] { "ToDoItemEndpoint" })
]
public override async Task<ActionResult<ToDoItemResponse>> HandleAsync(int id)
{
var item = await _repository.GetByIdAsync<ToDoItem>(id);
var response = new ToDoItemResponse
{
Id = item.Id,
Description = item.Description,
IsDone = item.IsDone,
Title = item.Title
};
return Ok(response);
}
}
}
using Ardalis.ApiEndpoints;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class List : BaseAsyncEndpoint<List<ToDoItemResponse>>
{
private readonly IRepository _repository;
public List(IRepository repository)
{
_repository = repository;
}
[HttpGet("/ToDoItems")]
[SwaggerOperation(
Summary = "Gets a list of all ToDoItems",
Description = "Gets a list of all ToDoItems",
OperationId = "ToDoItem.List",
Tags = new[] { "ToDoItemEndpoint" })
]
public override async Task<ActionResult<List<ToDoItemResponse>>> HandleAsync()
{
var items = (await _repository.ListAsync<ToDoItem>())
.Select(item => new ToDoItemResponse
{
Id = item.Id,
Description = item.Description,
IsDone = item.IsDone,
Title = item.Title
});
return Ok(items);
}
}
}
using System.ComponentModel.DataAnnotations;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class UpdateToDoItemRequest
{
[Required]
public int Id { get; set; }
[Required]
public string Title { get; set; }
public string Description { get; set; }
}
}
\ No newline at end of file
using Ardalis.ApiEndpoints;
using CleanArchitecture.Core.Entities;
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Endpoints.ToDoItems
{
public class Update : BaseAsyncEndpoint<UpdateToDoItemRequest,ToDoItemResponse>
{
private readonly IRepository _repository;
public Update(IRepository repository)
{
_repository = repository;
}
[HttpPut("/ToDoItems")]
[SwaggerOperation(
Summary = "Updates a ToDoItem",
Description = "Updates a ToDoItem",
OperationId = "ToDoItem.Update",
Tags = new[] { "ToDoItemEndpoint" })
]
public override async Task<ActionResult<ToDoItemResponse>> HandleAsync(UpdateToDoItemRequest request)
{
var existingItem = await _repository.GetByIdAsync<ToDoItem>(request.Id);
existingItem.Title = request.Title;
existingItem.Description = request.Description;
await _repository.UpdateAsync(existingItem);
var response = new ToDoItemResponse
{
Id = existingItem.Id,
Title = existingItem.Title,
Description = existingItem.Description,
IsDone = existingItem.IsDone
};
return Ok(response);
}
}
}
......@@ -2,6 +2,7 @@
using CleanArchitecture.SharedKernel.Interfaces;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace CleanArchitecture.Web.Pages.ToDoRazorPage
{
......@@ -16,9 +17,9 @@ namespace CleanArchitecture.Web.Pages.ToDoRazorPage
_repository = repository;
}
public void OnGet()
public async Task OnGetAsync()
{
ToDoItems = _repository.List<ToDoItem>();
ToDoItems = await _repository.ListAsync<ToDoItem>();
}
}
}
......@@ -4,10 +4,14 @@ using CleanArchitecture.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Collections.Generic;
using System.Linq;
namespace CleanArchitecture.Web
{
......@@ -31,15 +35,18 @@ namespace CleanArchitecture.Web
options.MinimumSameSitePolicy = SameSiteMode.None;
});
string connectionString = Configuration.GetConnectionString("SqlLiteConnection"); //Configuration.GetConnectionString("DefaultConnection");
string connectionString = Configuration.GetConnectionString("SqliteConnection"); //Configuration.GetConnectionString("DefaultConnection");
services.AddDbContext(Configuration.GetConnectionString(connectionString));
services.AddDbContext(connectionString);
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddRazorPages();
services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" }));
services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.EnableAnnotations();
});
// add list services for diagnostic purposes - see https://github.com/ardalis/AspNetCoreStartupServices
services.Configure<ServiceConfig>(config =>
......@@ -49,8 +56,6 @@ namespace CleanArchitecture.Web
// optional - default path to view services is /listallservices - recommended to choose your own path
config.Path = "/listservices";
});
//return ContainerSetup.InitializeWeb(Assembly.GetExecutingAssembly(), services);
}
public void ConfigureContainer(ContainerBuilder builder)
......
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\v11.0;Database=cleanarchitecture;Trusted_Connection=True;MultipleActiveResultSets=true",
"SqlLiteConnection": "Data Source=database.sqlite"
"SqliteConnection": "Data Source=database.sqlite"
},
"Logging": {
"IncludeScopes": false,
......
/*!
** Unobtrusive validation support library for jQuery and jQuery Validate
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
// Unobtrusive validation support library for jQuery and jQuery Validate
// Copyright (C) Microsoft Corporation. All rights reserved.
// @version v3.2.10
/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
/*global document: false, jQuery: false */
(function ($) {
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define("jquery.validate.unobtrusive", ['jquery-validation'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports
module.exports = factory(require('jquery-validation'));
} else {
// Browser global
jQuery.validator.unobtrusive = factory(jQuery);
}
}(function ($) {
var $jQval = $.validator,
adapters,
data_validation = "unobtrusiveValidation";
......@@ -118,7 +128,7 @@
execInContext = function (name, args) {
var func = defaultOptions[name];
func && $.isFunction(func) && func.apply(form, args);
}
};
if (!result) {
result = {
......@@ -409,8 +419,13 @@
setValidationValues(options, "regex", options.params.regex);
}
});
adapters.add("fileextensions", ["extensions"], function (options) {
setValidationValues(options, "extension", options.params.extensions);
});
$(function () {
$jQval.unobtrusive.parse(document);
});
}(jQuery));
\ No newline at end of file
return $jQval.unobtrusive;
}));
\ No newline at end of file
......@@ -7,12 +7,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
......
......@@ -7,12 +7,18 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="3.1.3" />
</ItemGroup>
<ItemGroup>
......
using CleanArchitecture.Core.Entities;
using CleanArchitecture.UnitTests;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace CleanArchitecture.IntegrationTests.Data
......@@ -8,14 +9,15 @@ namespace CleanArchitecture.IntegrationTests.Data
public class EfRepositoryAdd : BaseEfRepoTestFixture
{
[Fact]
public void AddsItemAndSetsId()
public async Task AddsItemAndSetsId()
{
var repository = GetRepository();
var item = new ToDoItemBuilder().Build();
repository.Add(item);
await repository.AddAsync(item);
var newItem = repository.List<ToDoItem>().FirstOrDefault();
var newItem = (await repository.ListAsync<ToDoItem>())
.FirstOrDefault();
Assert.Equal(item, newItem);
Assert.True(newItem?.Id > 0);
......
using CleanArchitecture.Core.Entities;
using CleanArchitecture.UnitTests;
using System;
using System.Threading.Tasks;
using Xunit;
namespace CleanArchitecture.IntegrationTests.Data
......@@ -8,19 +9,19 @@ namespace CleanArchitecture.IntegrationTests.Data
public class EfRepositoryDelete : BaseEfRepoTestFixture
{
[Fact]
public void DeletesItemAfterAddingIt()
public async Task DeletesItemAfterAddingIt()
{
// add an item
var repository = GetRepository();
var initialTitle = Guid.NewGuid().ToString();
var item = new ToDoItemBuilder().Title(initialTitle).Build();
repository.Add(item);
await repository.AddAsync(item);
// delete the item
repository.Delete(item);
await repository.DeleteAsync(item);
// verify it's no longer there
Assert.DoesNotContain(repository.List<ToDoItem>(),
Assert.DoesNotContain(await repository.ListAsync<ToDoItem>(),
i => i.Title == initialTitle);
}
}
......
......@@ -3,6 +3,7 @@ using CleanArchitecture.UnitTests;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
namespace CleanArchitecture.IntegrationTests.Data
......@@ -10,20 +11,20 @@ namespace CleanArchitecture.IntegrationTests.Data
public class EfRepositoryUpdate : BaseEfRepoTestFixture
{
[Fact]
public void UpdatesItemAfterAddingIt()
public async Task UpdatesItemAfterAddingIt()
{
// add an item
var repository = GetRepository();
var initialTitle = Guid.NewGuid().ToString();
var item = new ToDoItemBuilder().Title(initialTitle).Build();
repository.Add(item);
await repository.AddAsync(item);
// detach the item so we get a different instance
_dbContext.Entry(item).State = EntityState.Detached;
// fetch the item and update its title
var newItem = repository.List<ToDoItem>()
var newItem = (await repository.ListAsync<ToDoItem>())
.FirstOrDefault(i => i.Title == initialTitle);
Assert.NotNull(newItem);
Assert.NotSame(item, newItem);
......@@ -31,8 +32,8 @@ namespace CleanArchitecture.IntegrationTests.Data
newItem.Title = newTitle;
// Update the item
repository.Update(newItem);
var updatedItem = repository.List<ToDoItem>()
await repository.UpdateAsync(newItem);
var updatedItem = (await repository.ListAsync<ToDoItem>())
.FirstOrDefault(i => i.Title == newTitle);
Assert.NotNull(updatedItem);
......
......@@ -8,11 +8,17 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="coverlet.collector" Version="1.0.1" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="ReportGenerator" Version="4.4.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Moq" Version="4.14.0" />
<PackageReference Include="ReportGenerator" Version="4.5.6" />
<PackageReference Include="xunit" Version="2.4.1" />
</ItemGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment