Merge pull request #17 from microsoft/locationchanges

Delete shifts on location deletion
This commit is contained in:
biancacorsatea 2020-04-28 09:32:23 +01:00 коммит произвёл GitHub
Родитель 8ce680cb40 19b1a81b8e
Коммит 2e3d5827d8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 419 добавлений и 186 удалений

Просмотреть файл

@ -16,5 +16,7 @@ namespace Project.Zap.Library.Services
Task <T> Update(T item);
Task Delete(Expression<Func<T, bool>> query);
Task<T> Replace(T item);
}
}

Просмотреть файл

@ -58,13 +58,14 @@ namespace Project.Zap.Library.Services
return results;
}
public async Task<Location> Update(Location item)
public async Task<Location> Replace(Location item)
{
Location location = this.cosmosContainer.GetItemLinqQueryable<Location>(true).Where(x => x.Name == item.Name).AsEnumerable().FirstOrDefault();
return await this.cosmosContainer.ReplaceItemAsync<Location>(item, item.id, new PartitionKey(item.Name));
}
location.Address = item.Address;
return await this.cosmosContainer.ReplaceItemAsync<Location>(location, location.id, new PartitionKey(location.Name));
public Task<Location> Update(Location item)
{
throw new NotImplementedException();
}
}
}

Просмотреть файл

@ -61,6 +61,11 @@ namespace Project.Zap.Library.Services
return results;
}
public Task<PartnerOrganization> Replace(PartnerOrganization item)
{
throw new NotImplementedException();
}
public Task<PartnerOrganization> Update(PartnerOrganization item)
{
throw new NotImplementedException();

Просмотреть файл

@ -60,6 +60,11 @@ namespace Project.Zap.Library.Services
return results;
}
public Task<Shift> Replace(Shift item)
{
throw new NotImplementedException();
}
public async Task<Shift> Update(Shift item)
{
Shift current = await this.cosmosContainer.ReadItemAsync<Shift>(item.id, new PartitionKey(item.LocationId));

Просмотреть файл

@ -0,0 +1,193 @@
using Project.Zap.Library.Services;
using Project.Zap.Library.Models;
using Project.Zap.Services;
using System.Threading.Tasks;
using Xunit;
using NSubstitute;
using System;
using System.Linq.Expressions;
using System.Collections.Generic;
namespace Project.Zap.Tests
{
public class LocationServiceTests
{
[Fact]
public async Task Add_Location_GetsCoordinates()
{
// Arrange
IMapService mapService = Substitute.For<IMapService>();
ILocationService service = this.GetLocationService(mapService: mapService);
Location location = new Location { Address = new Address() };
// Act
await service.Add(location);
//Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
mapService.Received(1).GetCoordinates(location.Address);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task Add_Location_HitsRepository()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
ILocationService service = this.GetLocationService(locationRepository: repository);
Location location = new Location { Address = new Address() };
// Act
await service.Add(location);
//Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Add(location);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task DeleteById_Location_HitsLocationRepository()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
Location location = new Location { Address = new Address { } };
repository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { location });
ILocationService service = this.GetLocationService(locationRepository: repository);
// Act
await service.DeleteByName("Contoso");
//Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Delete(Arg.Any<Expression<Func<Location, bool>>>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task DeleteById_Location_HitsShiftRepository()
{
// Arrange
IRepository<Shift> shiftRepository = Substitute.For<IRepository<Shift>>();
IRepository<Location> locationRepository = Substitute.For<IRepository<Location>>();
Location location = new Location { Address = new Address { } };
locationRepository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { location });
ILocationService service = this.GetLocationService(shiftRepository: shiftRepository, locationRepository: locationRepository);
// Act
await service.DeleteByName("Contoso");
//Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
shiftRepository.Received(1).Delete(Arg.Any<Expression<Func<Shift, bool>>>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task GetByDistance_PointAndDistance_RepoHitWithQuery()
{
// Arrange
IRepository<Location> locationRepository = Substitute.For<IRepository<Location>>();
Location location = new Location { Address = new Address { } };
locationRepository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { location });
ILocationService service = this.GetLocationService(locationRepository: locationRepository);
// Act
await service.GetByDistance(new Point { coordinates = new double[] { 1, 2 } }, 1000);
//Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
locationRepository.Received(1).Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task Update_Location_GetAndReplaceCalledOnRepo()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
Location location = new Location { Address = new Address { Point = new Point() } };
repository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { location });
ILocationService service = this.GetLocationService(locationRepository: repository, mapService: mapService);
// Act
await service.Update(location);
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Get("SELECT * FROM c WHERE c.Name = @name", Arg.Any<Dictionary<string, object>>());
repository.Received(1).Replace(location);
mapService.Received(1).GetCoordinates(location.Address);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task GetByName_Location_GetOnRepo()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
Location location = new Location { Address = new Address { } };
repository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { location });
ILocationService service = this.GetLocationService(locationRepository: repository);
// Act
await service.GetByName("Contoso");
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Get("SELECT * FROM c WHERE c.Name = @name", Arg.Any<Dictionary<string, object>>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task Get_LocationWithNullPoint_CallMapService()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
repository.Get().Returns(new[] { new Location { Address = new Address { } } });
IMapService mapService = Substitute.For<IMapService>();
ILocationService service = this.GetLocationService(locationRepository: repository, mapService: mapService);
// Act
await service.Get();
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
mapService.Received(1).GetCoordinates(Arg.Any<Address>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task GetByName_LocationWithNullPoint_CallMapService()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
repository.Get(Arg.Any<string>(), Arg.Any<Dictionary<string, object>>()).Returns(new[] { new Location { Address = new Address { } } });
IMapService mapService = Substitute.For<IMapService>();
ILocationService service = this.GetLocationService(locationRepository: repository, mapService: mapService);
// Act
await service.GetByName("Contoso");
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
mapService.Received(1).GetCoordinates(Arg.Any<Address>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
private ILocationService GetLocationService(
IRepository<Location> locationRepository = null,
IRepository<Shift> shiftRepository = null,
IMapService mapService = null)
{
locationRepository = locationRepository ?? Substitute.For<IRepository<Location>>();
shiftRepository = shiftRepository ?? Substitute.For<IRepository<Shift>>();
mapService = mapService ?? Substitute.For<IMapService>();
return new LocationService(locationRepository, shiftRepository, mapService);
}
}
}

Просмотреть файл

@ -1,14 +1,11 @@
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NSubstitute;
using Project.Zap.Controllers;
using Project.Zap.Library.Models;
using Project.Zap.Library.Services;
using Project.Zap.Models;
using System;
using Project.Zap.Services;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Xunit;
@ -28,16 +25,15 @@ namespace Project.Zap.Tests
public async Task Index_NoParams_RepoGetHitWithNoParams()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
// Act
await controller.Index();
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Get();
service.Received(1).Get();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
@ -45,9 +41,8 @@ namespace Project.Zap.Tests
public async Task Index_NoParams_ResultModelIsEnumerableOfLocationViewModel()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
// Act
IActionResult result = await controller.Index();
@ -61,9 +56,8 @@ namespace Project.Zap.Tests
public void Add_NoParams_ReturnsViewResult()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
// Act
IActionResult result = controller.Add();
@ -75,9 +69,8 @@ namespace Project.Zap.Tests
public async Task AddLocation_LocationViewModelInValid_ReturnsBadRequest()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
controller.ModelState.AddModelError("Name", "Required");
AddLocationViewModel viewModel = new AddLocationViewModel();
@ -89,12 +82,11 @@ namespace Project.Zap.Tests
}
[Fact]
public async Task AddLocation_LocationViewModel_AddOnRepoHitWithMappedLocation()
public async Task AddLocation_LocationViewModel_AddOnServiceHitWithMappedLocation()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
AddLocationViewModel viewModel = new AddLocationViewModel { Name = "Contoso", Address = "Seattle", ZipOrPostcode = "54321" };
// Act
@ -102,7 +94,7 @@ namespace Project.Zap.Tests
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Add(Arg.Any<Location>());
service.Received(1).Add(Arg.Any<Location>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Assert.IsType<ViewResult>(result);
}
@ -111,9 +103,8 @@ namespace Project.Zap.Tests
public async Task Delete_LocationName_RepoDeleteHitWithExpression()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
LocationsController controller = new LocationsController(service);
string id = "Contoso";
// Act
@ -121,48 +112,26 @@ namespace Project.Zap.Tests
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Delete(Arg.Any<Expression<Func<Location, bool>>>());
service.Received(1).DeleteByName("Contoso");
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
[Fact]
public async Task Edit_LocationName_RepoGetHitWithCorrectQuery()
public async Task Edit_LocationName_ServiceGetsHitWithRightName()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
repository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>()).Returns(new[] { new Location { Name = "Contoso", Address = new Address { Text = "Seattle", ZipOrPostcode = "54321" } } });
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
ILocationService service = Substitute.For<ILocationService>();
service.GetByName(Arg.Any<string>()).Returns(new Location { id = "1", Name = "Contoso", Address = new Address { Text = "abc", ZipOrPostcode = "54321" } });
LocationsController controller = new LocationsController(service);
string id = "Contoso";
// Act
IActionResult result = await controller.Edit(id);
await controller.Edit(id);
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Get("SELECT * FROM c WHERE c.Name = @name", Arg.Is<Dictionary<string, object>>(x => x.ContainsKey("@name") && id == (string)x["@name"]));
service.Received(1).GetByName(id);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Assert.IsType<ViewResult>(result);
}
[Fact]
public async Task EditLocation_LocationViewModel_RepoGetHitWithExpression()
{
// Arrange
IRepository<Location> repository = Substitute.For<IRepository<Location>>();
IMapService mapService = Substitute.For<IMapService>();
LocationsController controller = new LocationsController(repository, mapService);
AddLocationViewModel viewModel = new AddLocationViewModel { Name = "Contoso", Address = "Seattle", ZipOrPostcode = "54321" };
// Act
IActionResult result = await controller.EditLocation(viewModel);
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
repository.Received(1).Update(Arg.Any<Location>());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Assert.IsType<ViewResult>(result);
}
}
}

Просмотреть файл

@ -9,6 +9,7 @@ using NSubstitute;
using Project.Zap.Controllers;
using Project.Zap.Library.Services;
using Project.Zap.Models;
using Project.Zap.Services;
using System;
using System.Collections.Generic;
using System.IO;
@ -50,9 +51,9 @@ namespace Project.Zap.Tests
{
// Arrange
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
// Act
await controller.Index();
@ -63,20 +64,11 @@ namespace Project.Zap.Tests
}
[Fact]
public async Task Search_SearchViewModel_LocationsRepoHitOnce()
public async Task Search_SearchViewModel_LocationsServiceHitOnce()
{
// Arrange
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
shiftRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>(), Arg.Any<string>()).Returns(new[]
{
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "1" },
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "2" },
new Library.Models.Shift { StartDateTime = DateTime.Now, LocationId = "1" },
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
ShiftsController controller = this.GetController(locationService: locationService);
SearchShiftViewModel viewModel = new SearchShiftViewModel { Locations = new List<string> { "Contoso" }, Start = DateTime.Now };
// Act
@ -84,7 +76,7 @@ namespace Project.Zap.Tests
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
locationRepository.Received(1).Get();
locationService.Received(1).Get();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
@ -97,9 +89,9 @@ namespace Project.Zap.Tests
{
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "1" },
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
SearchShiftViewModel viewModel = new SearchShiftViewModel { Locations = new List<string> { "Contoso" }, Start = DateTime.Now };
// Act
@ -123,9 +115,9 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = false }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
SearchShiftViewModel viewModel = new SearchShiftViewModel { Locations = new List<string> { "Contoso" }, Start = DateTime.Now.Add(new TimeSpan(1, 0, 0, 0)) };
// Act
@ -148,9 +140,9 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = false }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
SearchShiftViewModel viewModel = new SearchShiftViewModel { Locations = new List<string> { "Contoso" }, Start = DateTime.Now };
// Act
@ -173,9 +165,9 @@ namespace Project.Zap.Tests
{
// Arrange
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
DateTime now = DateTime.Now;
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
@ -236,9 +228,9 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = DateTime.Now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = false }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
// Act
@ -283,13 +275,12 @@ namespace Project.Zap.Tests
{
// Arrange
DateTime now = DateTime.Now;
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
IStringLocalizer<ShiftsController> stringLocalizer = Substitute.For<IStringLocalizer<ShiftsController>>();
ShiftsController controller = this.GetController(locationRepository: locationRepository, stringLocalizer: stringLocalizer);
ShiftsController controller = this.GetController(locationService: locationService, stringLocalizer: stringLocalizer);
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
// Act
@ -312,14 +303,13 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
IGraphServiceClient graphClient = Substitute.For<IGraphServiceClient>();
graphClient.Users[Arg.Any<string>()].Request().GetAsync().Returns(new User { GivenName = "a", Surname = "b" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository, graphClient: graphClient);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService, graphClient: graphClient);
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
// Act
@ -344,14 +334,13 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
IGraphServiceClient graphClient = Substitute.For<IGraphServiceClient>();
graphClient.Users[Arg.Any<string>()].Request().GetAsync().Returns(new User { GivenName = "a", Surname = "b" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository, graphClient: graphClient);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService, graphClient: graphClient);
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
// Act
@ -375,14 +364,13 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
IGraphServiceClient graphClient = Substitute.For<IGraphServiceClient>();
graphClient.Users[Arg.Any<string>()].Request().GetAsync().Returns(new User { GivenName = "a", Surname = "b" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository, graphClient: graphClient);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService, graphClient: graphClient);
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
// Act
@ -433,11 +421,10 @@ namespace Project.Zap.Tests
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
@ -465,12 +452,10 @@ namespace Project.Zap.Tests
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
@ -523,12 +508,12 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get()
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
@ -557,13 +542,10 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.Add(new TimeSpan(1,0,0,0)), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
@ -588,12 +570,10 @@ namespace Project.Zap.Tests
new Library.Models.Shift { StartDateTime = now.AddDays(1), LocationId = "1", Allocated = true, EmployeeId = "xyz" }
});
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
@ -612,13 +592,11 @@ namespace Project.Zap.Tests
// Arrange
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
DateTime now = DateTime.Now;
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" } });
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
ShiftViewModel viewModel = new ShiftViewModel { LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till" };
@ -641,14 +619,14 @@ namespace Project.Zap.Tests
public async Task Add_NoParams_LocationRepoHit()
{
// Arrange
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
ShiftsController controller = this.GetController(locationRepository: locationRepository);
ILocationService locationService = Substitute.For<ILocationService>();
ShiftsController controller = this.GetController(locationService: locationService);
// Act
await controller.Add();
// Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
locationRepository.Received(1).Get();
locationService.Received(1).Get();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
@ -677,11 +655,10 @@ namespace Project.Zap.Tests
{
// Arrange
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
AddShiftViewModel viewModel = new AddShiftViewModel
{
NewShift = new ShiftViewModel
@ -713,10 +690,10 @@ namespace Project.Zap.Tests
public async Task Upload_NoParams_FileUploadViewModel()
{
// Arrange
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.Get().Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ShiftsController controller = this.GetController(locationRepository: locationRepository);
ShiftsController controller = this.GetController(locationService: locationService);
// Act
IActionResult result = await controller.Upload();
@ -744,11 +721,10 @@ namespace Project.Zap.Tests
.Returns(new MemoryStream(Encoding.UTF8.GetBytes("Start,End,WorkType\n2020-10-10,2020-10-10,Till\n2020-10-10,2020-10-10,Till")));
IRepository<Library.Models.Shift> shiftRepository = Substitute.For<IRepository<Library.Models.Shift>>();
IRepository<Library.Models.Location> locationRepository = Substitute.For<IRepository<Library.Models.Location>>();
locationRepository.Get(Arg.Any<string>(), Arg.Any<IDictionary<string, object>>())
.Returns(new[] { new Library.Models.Location { id = "1", Name = "Contoso" }, new Library.Models.Location { id = "2", Name = "Fabrikam" } });
ILocationService locationService = Substitute.For<ILocationService>();
locationService.GetByName("Contoso").Returns(new Library.Models.Location { id = "1", Name = "Contoso" });
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationRepository: locationRepository);
ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);
FileUploadViewModel viewModel = new FileUploadViewModel
{
LocationName = "Contoso",
@ -767,7 +743,7 @@ namespace Project.Zap.Tests
private ShiftsController GetController(
IRepository<Library.Models.Shift> shiftRepository = null,
IRepository<Library.Models.Location> locationRepository = null,
ILocationService locationService = null,
IGraphServiceClient graphClient = null,
IStringLocalizer<ShiftsController> stringLocalizer = null,
IConfiguration configuration = null,
@ -775,14 +751,14 @@ namespace Project.Zap.Tests
ILogger<ShiftsController> logger = null)
{
shiftRepository = shiftRepository ?? Substitute.For<IRepository<Library.Models.Shift>>();
locationRepository = locationRepository ?? Substitute.For<IRepository<Library.Models.Location>>();
locationService = locationService ?? Substitute.For<ILocationService>();
graphClient = graphClient ?? Substitute.For<IGraphServiceClient>();
stringLocalizer = stringLocalizer ?? Substitute.For<IStringLocalizer<ShiftsController>>();
configuration = configuration ?? Substitute.For<IConfiguration>();
mapService = mapService ?? Substitute.For<IMapService>();
logger = logger ?? Substitute.For<ILogger<ShiftsController>>();
var controller = new ShiftsController(shiftRepository, locationRepository, graphClient, stringLocalizer, configuration, mapService, logger);
var controller = new ShiftsController(shiftRepository, locationService, graphClient, stringLocalizer, configuration, mapService, logger);
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
return controller;

Просмотреть файл

@ -2,8 +2,9 @@
using Microsoft.AspNetCore.Mvc;
using Project.Zap.Helpers;
using Project.Zap.Library.Models;
using Project.Zap.Library.Services;
using Project.Zap.Models;
using Project.Zap.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
@ -13,18 +14,16 @@ namespace Project.Zap.Controllers
[Authorize(Policy = "OrgAManager")]
public class LocationsController : Controller
{
private readonly IRepository<Location> repository;
private readonly IMapService mapService;
private readonly ILocationService locationService;
public LocationsController(IRepository<Location> repository, IMapService mapService)
public LocationsController(ILocationService locationService)
{
this.repository = repository;
this.mapService = mapService;
this.locationService = locationService;
}
public async Task<IActionResult> Index()
{
IEnumerable<Location> locations = await this.repository.Get();
IEnumerable<Location> locations = await this.locationService.Get();
return View("Index", locations.Map());
}
@ -43,24 +42,22 @@ namespace Project.Zap.Controllers
return BadRequest(ModelState);
}
Location location = viewModel.Map();
location.Address.Point = await this.mapService.GetCoordinates(location.Address);
await this.locationService.Add(viewModel.Map());
await this.repository.Add(location);
return await this.Index();
}
[HttpGet]
public async Task<IActionResult> Delete(string id)
{
await this.repository.Delete(x => x.Name == id);
await this.locationService.DeleteByName(id);
return await this.Index();
}
[HttpGet]
public async Task<IActionResult> Edit(string id)
{
Location location = (await this.repository.Get("SELECT * FROM c WHERE c.Name = @name", new Dictionary<string, object> { {"@name", id } })).FirstOrDefault();
Location location = await this.locationService.GetByName(id);
return View(location.Map());
}
@ -68,9 +65,7 @@ namespace Project.Zap.Controllers
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditLocation(AddLocationViewModel viewModel)
{
Location location = viewModel.Map();
await this.repository.Update(location);
await this.locationService.Update(viewModel.Map());
return await this.Index();
}

Просмотреть файл

@ -8,12 +8,12 @@ using Project.Zap.Helpers;
using Project.Zap.Library.Models;
using Project.Zap.Library.Services;
using Project.Zap.Models;
using Project.Zap.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
namespace Project.Zap.Controllers
@ -22,7 +22,7 @@ namespace Project.Zap.Controllers
public class ShiftsController : Controller
{
private readonly IRepository<Shift> shiftRepository;
private readonly IRepository<Location> locationRepository;
private readonly ILocationService locationService;
private readonly Microsoft.Graph.IGraphServiceClient graphServiceClient;
private readonly IStringLocalizer<ShiftsController> stringLocalizer;
private readonly IConfiguration configuration;
@ -31,7 +31,7 @@ namespace Project.Zap.Controllers
public ShiftsController(
IRepository<Shift> shiftRepository,
IRepository<Location> locationRepository,
ILocationService locationService,
Microsoft.Graph.IGraphServiceClient graphServiceClient,
IStringLocalizer<ShiftsController> stringLocalizer,
IConfiguration configuration,
@ -39,7 +39,7 @@ namespace Project.Zap.Controllers
ILogger<ShiftsController> logger)
{
this.shiftRepository = shiftRepository;
this.locationRepository = locationRepository;
this.locationService = locationService;
this.graphServiceClient = graphServiceClient;
this.stringLocalizer = stringLocalizer;
this.configuration = configuration;
@ -49,7 +49,7 @@ namespace Project.Zap.Controllers
public async Task<IActionResult> Index()
{
IEnumerable<Location> locations = await this.locationRepository.Get();
IEnumerable<Location> locations = await this.locationService.Get();
if (locations == null || !locations.Any())
{
this.logger.LogInformation("No locations, so redirecting to location view");
@ -76,7 +76,7 @@ namespace Project.Zap.Controllers
[ValidateAntiForgeryToken]
public async Task<IActionResult> Search(SearchShiftViewModel search)
{
IEnumerable<Location> locations = await this.locationRepository.Get();
IEnumerable<Location> locations = await this.locationService.Get();
List<string> locationIds = new List<string>();
@ -87,12 +87,7 @@ namespace Project.Zap.Controllers
if(search.DistanceInMeters != null && !string.IsNullOrWhiteSpace(search.ZipOrPostcode))
{
Point point = await this.mapService.GetCoordinates(new Address { ZipOrPostcode = search.ZipOrPostcode });
IEnumerable<Location> filteredLocations = await this.locationRepository.Get(
$"SELECT * FROM c WHERE ST_DISTANCE(c.Address.Point, {{'type': 'Point', 'coordinates':[{point.coordinates[0]}, {point.coordinates[1]}]}}) < @radiusDistance",
new Dictionary<string, object>
{
{"@radiusDistance", search.DistanceInMeters }
});
IEnumerable<Location> filteredLocations = await this.locationService.GetByDistance(point, search.DistanceInMeters.Value);
locationIds.AddRange(filteredLocations.Select(x => x.id));
}
@ -123,7 +118,7 @@ namespace Project.Zap.Controllers
return await this.Index();
}
private async Task<Location> GetLocation(string name) => (await this.locationRepository.Get("SELECT * FROM c WHERE c.Name = @name", new Dictionary<string, object> { { "@name", name } })).FirstOrDefault();
private async Task<Location> GetLocation(string name) => await this.locationService.GetByName(name);
[HttpGet]
[Authorize(Policy = "OrgBEmployee")]
@ -147,7 +142,7 @@ namespace Project.Zap.Controllers
this.logger.LogInformation("Trying to view shifts, but shifts currently available");
ViewData["NoShifts"] = this.stringLocalizer["NoShifts"];
}
return View("ViewShifts", shifts.Map(await this.locationRepository.Get()));
return View("ViewShifts", shifts.Map(await this.locationService.Get()));
}
[HttpGet]
@ -276,7 +271,7 @@ namespace Project.Zap.Controllers
{
AddShiftViewModel viewModel = new AddShiftViewModel
{
LocationNames = this.GetLocationNames(await this.locationRepository.Get()),
LocationNames = this.GetLocationNames(await this.locationService.Get()),
NewShift = new ShiftViewModel()
};
return View(viewModel);
@ -306,7 +301,7 @@ namespace Project.Zap.Controllers
[Authorize(Policy = "OrgAManager")]
public async Task<IActionResult> Upload()
{
return View(new FileUploadViewModel { LocationNames = this.GetLocationNames(await this.locationRepository.Get()) });
return View(new FileUploadViewModel { LocationNames = this.GetLocationNames(await this.locationService.Get()) });
}
[HttpPost]

Просмотреть файл

@ -30,7 +30,7 @@ namespace Project.Zap.Models
[Display(Name = "Distance")]
[BindProperty]
public int DistanceInMeters { get; set; }
public int? DistanceInMeters { get; set; }
public SelectList Distances { get; set; } = new SelectList(new[] { new SelectListItem { Text = "10 Miles", Value = "16093" }, new SelectListItem { Text = "30 Miles", Value = "48280" }}, "Value", "Text");

Просмотреть файл

@ -0,0 +1,91 @@
using Project.Zap.Library.Models;
using Project.Zap.Library.Services;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Project.Zap.Services
{
public interface ILocationService
{
Task<IEnumerable<Location>> Get();
Task Add(Location location);
Task<Location> GetByName(string name);
Task DeleteByName(string name);
Task Update(Location location);
Task<IEnumerable<Location>> GetByDistance(Point point, int distanceInMeters);
}
public class LocationService : ILocationService
{
private readonly IRepository<Location> repository;
private readonly IRepository<Shift> shiftRepository;
private readonly IMapService mapService;
public LocationService(IRepository<Location> repository, IRepository<Shift> shiftRepository, IMapService mapService)
{
this.repository = repository;
this.shiftRepository = shiftRepository;
this.mapService = mapService;
}
public async Task Add(Location location)
{
location.Address.Point = await this.mapService.GetCoordinates(location.Address);
await this.repository.Add(location);
}
public async Task DeleteByName(string name)
{
Location existing = await this.GetByName(name);
await this.repository.Delete(x => x.Name == name);
await this.shiftRepository.Delete(x => x.LocationId == existing.id);
}
public async Task Update(Location location)
{
Location existing = await this.GetByName(location.Name);
existing.Address = location.Address;
existing.Address.Point = await this.mapService.GetCoordinates(location.Address);
await this.repository.Replace(existing);
}
public async Task<IEnumerable<Location>> Get()
{
IEnumerable<Location> locations = await this.repository.Get();
foreach(Location location in locations)
{
if(location.Address.Point == null)
{
location.Address.Point = await this.mapService.GetCoordinates(location.Address);
}
}
return locations;
}
public async Task<Location> GetByName(string name)
{
Location location = (await this.repository.Get("SELECT * FROM c WHERE c.Name = @name", new Dictionary<string, object> { { "@name", name } })).FirstOrDefault();
if (location.Address.Point == null)
{
location.Address.Point = await this.mapService.GetCoordinates(location.Address);
}
return location;
}
public async Task<IEnumerable<Location>> GetByDistance(Point point, int distanceInMeters)
{
return await this.repository.Get(
$"SELECT * FROM c WHERE ST_DISTANCE(c.Address.Point, {{'type': 'Point', 'coordinates':[{point.coordinates[0]}, {point.coordinates[1]}]}}) < @radiusDistance",
new Dictionary<string, object>
{
{"@radiusDistance", distanceInMeters }
});
}
}
}

Просмотреть файл

@ -11,7 +11,6 @@ using Microsoft.Azure.Cosmos.Fluent;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
@ -19,6 +18,7 @@ using Project.Zap.Filters;
using Project.Zap.Library.Models;
using Project.Zap.Library.Services;
using Project.Zap.Middleware;
using Project.Zap.Services;
using System.Collections.Generic;
using System.Globalization;
using System.Net.Http;
@ -80,6 +80,7 @@ namespace Project.Zap
services.AddSingleton<IRepository<Library.Models.Location>, LocationRepository>();
services.AddSingleton<IRepository<Library.Models.Shift>, ShiftRepository>();
services.AddSingleton<IRepository<PartnerOrganization>, PartnerRepository>();
services.AddTransient<ILocationService, LocationService>();
services.AddTransient<IConfidentialClientApplication>(x => ConfidentialClientApplicationBuilder
.Create(this.Configuration["ClientId"])