Added location.api integration tests
This commit is contained in:
parent
05bd964f2b
commit
ea6084db28
@ -80,4 +80,19 @@ services:
|
|||||||
- SA_PASSWORD=Pass@word
|
- SA_PASSWORD=Pass@word
|
||||||
- ACCEPT_EULA=Y
|
- ACCEPT_EULA=Y
|
||||||
ports:
|
ports:
|
||||||
- "5433:1433"
|
- "5433:1433"
|
||||||
|
|
||||||
|
nosql.data:
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
|
||||||
|
locations.api:
|
||||||
|
environment:
|
||||||
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
|
- ASPNETCORE_URLS=http://0.0.0.0:80
|
||||||
|
- ConnectionString=mongodb://nosql.data
|
||||||
|
- Database=LocationsDb
|
||||||
|
- identityUrl=http://identity.api #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||||
|
- EventBusConnection=rabbitmq
|
||||||
|
ports:
|
||||||
|
- "5109:80"
|
@ -53,9 +53,20 @@ services:
|
|||||||
- ordering.api
|
- ordering.api
|
||||||
- identity.api
|
- identity.api
|
||||||
- basket.api
|
- basket.api
|
||||||
|
|
||||||
|
locations.api:
|
||||||
|
image: locations.api
|
||||||
|
build:
|
||||||
|
context: ./src/Services/Location/Locations.API
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
depends_on:
|
||||||
|
- nosql.data
|
||||||
|
|
||||||
sql.data:
|
sql.data:
|
||||||
image: microsoft/mssql-server-windows
|
image: microsoft/mssql-server-windows
|
||||||
|
|
||||||
|
nosql.data:
|
||||||
|
image: mongo:windowsservercore
|
||||||
|
|
||||||
basket.data:
|
basket.data:
|
||||||
image: redis:nanoserver
|
image: redis:nanoserver
|
||||||
|
@ -20,8 +20,8 @@ namespace Locations.API.Controllers
|
|||||||
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
|
_identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET api/v1/[controller]/1
|
//GET api/v1/[controller]/user/1
|
||||||
[Route("{userId:int}")]
|
[Route("user/{userId:int}")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetUserLocation(int userId)
|
public async Task<IActionResult> GetUserLocation(int userId)
|
||||||
{
|
{
|
||||||
@ -29,19 +29,28 @@ namespace Locations.API.Controllers
|
|||||||
return Ok(userLocation);
|
return Ok(userLocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
//GET api/v1/[controller]/locations
|
//GET api/v1/[controller]/
|
||||||
[Route("locations")]
|
[Route("")]
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public async Task<IActionResult> GetAllLocations()
|
public async Task<IActionResult> GetAllLocations()
|
||||||
{
|
{
|
||||||
var userLocation = await _locationsService.GetAllLocation();
|
var locations = await _locationsService.GetAllLocation();
|
||||||
return Ok(userLocation);
|
return Ok(locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
//GET api/v1/[controller]/1
|
||||||
|
[Route("{locationId}")]
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> GetLocation(string locationId)
|
||||||
|
{
|
||||||
|
var location = await _locationsService.GetLocation(locationId);
|
||||||
|
return Ok(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
//POST api/v1/[controller]/
|
//POST api/v1/[controller]/
|
||||||
[Route("")]
|
[Route("")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public async Task<IActionResult> UpdateUserLocation([FromBody]LocationRequest newLocReq)
|
public async Task<IActionResult> CreateOrUpdateUserLocation([FromBody]LocationRequest newLocReq)
|
||||||
{
|
{
|
||||||
var userId = _identityService.GetUserIdentity();
|
var userId = _identityService.GetUserIdentity();
|
||||||
var result = await _locationsService.AddOrUpdateUserLocation(userId, newLocReq);
|
var result = await _locationsService.AddOrUpdateUserLocation(userId, newLocReq);
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MongoDB.Bson;
|
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using MongoDB.Driver.GeoJsonObjectModel;
|
using MongoDB.Driver.GeoJsonObjectModel;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -25,7 +24,7 @@
|
|||||||
{
|
{
|
||||||
await SetIndexes();
|
await SetIndexes();
|
||||||
await SetUSLocations();
|
await SetUSLocations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task SetUSLocations()
|
static async Task SetUSLocations()
|
||||||
@ -36,11 +35,12 @@
|
|||||||
Description = "United States"
|
Description = "United States"
|
||||||
};
|
};
|
||||||
us.SetLocation(-101.357386, 41.650455);
|
us.SetLocation(-101.357386, 41.650455);
|
||||||
await ctx.Locations.InsertOneAsync(us);
|
us.SetArea(GetUSPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(us);
|
||||||
await SetWashingtonLocations(us.Id);
|
await SetWashingtonLocations(us.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task SetWashingtonLocations(ObjectId parentId)
|
static async Task SetWashingtonLocations(string parentId)
|
||||||
{
|
{
|
||||||
var wht = new Locations()
|
var wht = new Locations()
|
||||||
{
|
{
|
||||||
@ -49,34 +49,35 @@
|
|||||||
Description = "Washington"
|
Description = "Washington"
|
||||||
};
|
};
|
||||||
wht.SetLocation(-119.542781, 47.223652);
|
wht.SetLocation(-119.542781, 47.223652);
|
||||||
|
wht.SetArea(GetWashingtonPoligon());
|
||||||
await ctx.Locations.InsertOneAsync(wht);
|
await ctx.Locations.InsertOneAsync(wht);
|
||||||
await SetSeattleLocations(wht.Id);
|
await SetSeattleLocations(wht.Id);
|
||||||
await SetRedmondLocations(wht.Id);
|
await SetRedmondLocations(wht.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task SetSeattleLocations(ObjectId parentId)
|
static async Task SetSeattleLocations(string parentId)
|
||||||
{
|
{
|
||||||
var stl = new Locations()
|
var stl = new Locations()
|
||||||
{
|
{
|
||||||
Parent_Id = parentId,
|
Parent_Id = parentId,
|
||||||
Code = "SEAT",
|
Code = "SEAT",
|
||||||
Description = "Seattle",
|
Description = "Seattle"
|
||||||
Polygon = GetSeattlePoligon()
|
|
||||||
};
|
};
|
||||||
|
stl.SetArea(GetSeattlePoligon());
|
||||||
stl.SetLocation(-122.330747, 47.603111);
|
stl.SetLocation(-122.330747, 47.603111);
|
||||||
await ctx.Locations.InsertOneAsync(stl);
|
await ctx.Locations.InsertOneAsync(stl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task SetRedmondLocations(ObjectId parentId)
|
static async Task SetRedmondLocations(string parentId)
|
||||||
{
|
{
|
||||||
var rdm = new Locations()
|
var rdm = new Locations()
|
||||||
{
|
{
|
||||||
Parent_Id = parentId,
|
Parent_Id = parentId,
|
||||||
Code = "REDM",
|
Code = "REDM",
|
||||||
Description = "Redmond",
|
Description = "Redmond"
|
||||||
Polygon = GetRedmondPoligon()
|
|
||||||
};
|
};
|
||||||
rdm.SetLocation(-122.122887, 47.674961);
|
rdm.SetLocation(-122.122887, 47.674961);
|
||||||
|
rdm.SetArea(GetRedmondPoligon());
|
||||||
await ctx.Locations.InsertOneAsync(rdm);
|
await ctx.Locations.InsertOneAsync(rdm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +87,24 @@
|
|||||||
var builder = Builders<Locations>.IndexKeys;
|
var builder = Builders<Locations>.IndexKeys;
|
||||||
var keys = builder.Geo2DSphere(prop => prop.Location);
|
var keys = builder.Geo2DSphere(prop => prop.Location);
|
||||||
await ctx.Locations.Indexes.CreateOneAsync(keys);
|
await ctx.Locations.Indexes.CreateOneAsync(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GeoJsonPolygon<GeoJson2DGeographicCoordinates> GetSeattlePoligon()
|
static List<GeoJson2DGeographicCoordinates> GetUSPoligon()
|
||||||
{
|
{
|
||||||
return new GeoJsonPolygon<GeoJson2DGeographicCoordinates>(new GeoJsonPolygonCoordinates<GeoJson2DGeographicCoordinates>(
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
new GeoJsonLinearRingCoordinates<GeoJson2DGeographicCoordinates>(
|
{
|
||||||
new List<GeoJson2DGeographicCoordinates>()
|
new GeoJson2DGeographicCoordinates(-62.88205, 48.7985),
|
||||||
|
new GeoJson2DGeographicCoordinates(-129.3132, 48.76513),
|
||||||
|
new GeoJson2DGeographicCoordinates(-120.9496, 30.12256),
|
||||||
|
new GeoJson2DGeographicCoordinates(-111.3944, 30.87114),
|
||||||
|
new GeoJson2DGeographicCoordinates(-78.11975, 24.24979),
|
||||||
|
new GeoJson2DGeographicCoordinates(-62.88205, 48.7985)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetSeattlePoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
{
|
{
|
||||||
new GeoJson2DGeographicCoordinates(-122.36238,47.82929),
|
new GeoJson2DGeographicCoordinates(-122.36238,47.82929),
|
||||||
new GeoJson2DGeographicCoordinates(-122.42091,47.6337),
|
new GeoJson2DGeographicCoordinates(-122.42091,47.6337),
|
||||||
@ -100,24 +112,34 @@
|
|||||||
new GeoJson2DGeographicCoordinates(-122.20788,47.50259),
|
new GeoJson2DGeographicCoordinates(-122.20788,47.50259),
|
||||||
new GeoJson2DGeographicCoordinates(-122.26934,47.73644),
|
new GeoJson2DGeographicCoordinates(-122.26934,47.73644),
|
||||||
new GeoJson2DGeographicCoordinates(-122.36238,47.82929)
|
new GeoJson2DGeographicCoordinates(-122.36238,47.82929)
|
||||||
})));
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static GeoJsonPolygon<GeoJson2DGeographicCoordinates> GetRedmondPoligon()
|
static List<GeoJson2DGeographicCoordinates> GetRedmondPoligon()
|
||||||
{
|
{
|
||||||
return new GeoJsonPolygon<GeoJson2DGeographicCoordinates>(new GeoJsonPolygonCoordinates<GeoJson2DGeographicCoordinates>(
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
new GeoJsonLinearRingCoordinates<GeoJson2DGeographicCoordinates>(
|
|
||||||
new List<GeoJson2DGeographicCoordinates>()
|
|
||||||
{
|
{
|
||||||
new GeoJson2DGeographicCoordinates(47.73148, -122.15432),
|
new GeoJson2DGeographicCoordinates(-122.15432, 47.73148),
|
||||||
new GeoJson2DGeographicCoordinates(47.72559, -122.17673),
|
new GeoJson2DGeographicCoordinates(-122.17673, 47.72559),
|
||||||
new GeoJson2DGeographicCoordinates(47.67851, -122.16904),
|
new GeoJson2DGeographicCoordinates(-122.16904, 47.67851),
|
||||||
new GeoJson2DGeographicCoordinates(47.65036, -122.16136),
|
new GeoJson2DGeographicCoordinates(-122.16136, 47.65036),
|
||||||
new GeoJson2DGeographicCoordinates(47.62746, -122.15604),
|
new GeoJson2DGeographicCoordinates(-122.15604, 47.62746),
|
||||||
new GeoJson2DGeographicCoordinates(47.63463, -122.01562),
|
new GeoJson2DGeographicCoordinates(-122.01562, 47.63463),
|
||||||
new GeoJson2DGeographicCoordinates(47.74244, -122.04961),
|
new GeoJson2DGeographicCoordinates(-122.04961, 47.74244),
|
||||||
new GeoJson2DGeographicCoordinates(47.73148, -122.15432),
|
new GeoJson2DGeographicCoordinates(-122.15432, 47.73148)
|
||||||
})));
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetWashingtonPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(-124.68633, 48.8943),
|
||||||
|
new GeoJson2DGeographicCoordinates(-124.32962, 45.66613),
|
||||||
|
new GeoJson2DGeographicCoordinates(-116.73824, 45.93384),
|
||||||
|
new GeoJson2DGeographicCoordinates(-116.96912, 49.04282),
|
||||||
|
new GeoJson2DGeographicCoordinates(-124.68633, 48.8943)
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,19 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
||||||
{
|
{
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
||||||
using MongoDB.Bson;
|
using ViewModel;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
public interface ILocationsRepository
|
public interface ILocationsRepository
|
||||||
{
|
{
|
||||||
Task<Locations> GetAsync(ObjectId locationId);
|
Task<Locations> GetAsync(string locationId);
|
||||||
|
|
||||||
Task<List<Locations>> GetLocationListAsync();
|
Task<List<Locations>> GetLocationListAsync();
|
||||||
|
|
||||||
Task<UserLocation> GetUserLocationAsync(int userId);
|
Task<UserLocation> GetUserLocationAsync(int userId);
|
||||||
|
|
||||||
Task<List<Locations>> GetNearestLocationListAsync(double lat, double lon);
|
Task<List<Locations>> GetCurrentUserRegionsListAsync(LocationRequest currentPosition);
|
||||||
|
|
||||||
Task<Locations> GetLocationByCurrentAreaAsync(Locations location);
|
|
||||||
|
|
||||||
Task AddUserLocationAsync(UserLocation location);
|
Task AddUserLocationAsync(UserLocation location);
|
||||||
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Infrastructure.Repositories
|
||||||
{
|
{
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Collections.Generic;
|
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using MongoDB.Bson;
|
||||||
using MongoDB.Driver;
|
using MongoDB.Driver;
|
||||||
using MongoDB.Driver.GeoJsonObjectModel;
|
using MongoDB.Driver.GeoJsonObjectModel;
|
||||||
using MongoDB.Driver.Builders;
|
using System.Collections.Generic;
|
||||||
using MongoDB.Bson;
|
using System.Threading.Tasks;
|
||||||
|
using ViewModel;
|
||||||
|
|
||||||
public class LocationsRepository
|
public class LocationsRepository
|
||||||
: ILocationsRepository
|
: ILocationsRepository
|
||||||
@ -23,9 +20,9 @@
|
|||||||
_context = new LocationsContext(settings);
|
_context = new LocationsContext(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Locations> GetAsync(ObjectId locationId)
|
public async Task<Locations> GetAsync(string locationId)
|
||||||
{
|
{
|
||||||
var filter = Builders<Locations>.Filter.Eq("Id", locationId);
|
var filter = Builders<Locations>.Filter.Eq("Id", ObjectId.Parse(locationId));
|
||||||
return await _context.Locations
|
return await _context.Locations
|
||||||
.Find(filter)
|
.Find(filter)
|
||||||
.FirstOrDefaultAsync();
|
.FirstOrDefaultAsync();
|
||||||
@ -42,20 +39,16 @@
|
|||||||
public async Task<List<Locations>> GetLocationListAsync()
|
public async Task<List<Locations>> GetLocationListAsync()
|
||||||
{
|
{
|
||||||
return await _context.Locations.Find(new BsonDocument()).ToListAsync();
|
return await _context.Locations.Find(new BsonDocument()).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Locations>> GetNearestLocationListAsync(double lat, double lon)
|
public async Task<List<Locations>> GetCurrentUserRegionsListAsync(LocationRequest currentPosition)
|
||||||
{
|
{
|
||||||
var point = GeoJson.Point(GeoJson.Geographic(lon, lat));
|
var point = GeoJson.Point(GeoJson.Geographic(currentPosition.Longitude, currentPosition.Latitude));
|
||||||
var query = new FilterDefinitionBuilder<Locations>().Near(x => x.Location, point);
|
var orderByDistanceQuery = new FilterDefinitionBuilder<Locations>().Near(x => x.Location, point);
|
||||||
return await _context.Locations.Find(query).ToListAsync();
|
var withinAreaQuery = new FilterDefinitionBuilder<Locations>().GeoIntersects("Polygon", point);
|
||||||
}
|
var filter = Builders<Locations>.Filter.And(orderByDistanceQuery, withinAreaQuery);
|
||||||
|
return await _context.Locations.Find(filter).ToListAsync();
|
||||||
public async Task<Locations> GetLocationByCurrentAreaAsync(Locations location)
|
}
|
||||||
{
|
|
||||||
var query = new FilterDefinitionBuilder<Locations>().GeoIntersects("Location", location.Polygon);
|
|
||||||
return await _context.Locations.Find(query).FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task AddUserLocationAsync(UserLocation location)
|
public async Task AddUserLocationAsync(UserLocation location)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
public interface ILocationsService
|
public interface ILocationsService
|
||||||
{
|
{
|
||||||
|
Task<Locations> GetLocation(string locationId);
|
||||||
|
|
||||||
Task<UserLocation> GetUserLocation(int id);
|
Task<UserLocation> GetUserLocation(int id);
|
||||||
|
|
||||||
Task<List<Locations>> GetAllLocation();
|
Task<List<Locations>> GetAllLocation();
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
_locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository));
|
_locationsRepository = locationsRepository ?? throw new ArgumentNullException(nameof(locationsRepository));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Locations> GetLocation(string locationId)
|
||||||
|
{
|
||||||
|
return await _locationsRepository.GetAsync(locationId);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<UserLocation> GetUserLocation(int id)
|
public async Task<UserLocation> GetUserLocation(int id)
|
||||||
{
|
{
|
||||||
return await _locationsRepository.GetUserLocationAsync(id);
|
return await _locationsRepository.GetUserLocationAsync(id);
|
||||||
@ -30,40 +35,28 @@
|
|||||||
|
|
||||||
public async Task<bool> AddOrUpdateUserLocation(string id, LocationRequest currentPosition)
|
public async Task<bool> AddOrUpdateUserLocation(string id, LocationRequest currentPosition)
|
||||||
{
|
{
|
||||||
Locations currentUserAreaLocation = null;
|
|
||||||
|
|
||||||
if (!int.TryParse(id, out int userId))
|
if (!int.TryParse(id, out int userId))
|
||||||
{
|
{
|
||||||
throw new ArgumentException("Not valid userId");
|
throw new ArgumentException("Not valid userId");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the nearest locations ordered
|
// Get the list of ordered regions the user currently is within
|
||||||
var nearestLocationList = await _locationsRepository.GetNearestLocationListAsync(currentPosition.Latitude, currentPosition.Longitude);
|
var currentUserAreaLocationList = await _locationsRepository.GetCurrentUserRegionsListAsync(currentPosition);
|
||||||
|
|
||||||
// Check out in which region we currently are
|
if(currentUserAreaLocationList is null)
|
||||||
foreach(var locationCandidate in nearestLocationList.Where(x=> x.Polygon != null))
|
|
||||||
{
|
|
||||||
currentUserAreaLocation = await _locationsRepository.GetLocationByCurrentAreaAsync(locationCandidate);
|
|
||||||
if(currentUserAreaLocation != null) { break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
if(currentUserAreaLocation is null)
|
|
||||||
{
|
{
|
||||||
throw new LocationDomainException("User current area not found");
|
throw new LocationDomainException("User current area not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If current area found, then update user location
|
// If current area found, then update user location
|
||||||
if(currentUserAreaLocation != null)
|
var locationAncestors = new List<string>();
|
||||||
{
|
var userLocation = await _locationsRepository.GetUserLocationAsync(userId);
|
||||||
var locationAncestors = new List<string>();
|
userLocation = userLocation ?? new UserLocation();
|
||||||
var userLocation = await _locationsRepository.GetUserLocationAsync(userId);
|
userLocation.UserId = userId;
|
||||||
userLocation = userLocation ?? new UserLocation();
|
userLocation.LocationId = currentUserAreaLocationList[0].Id;
|
||||||
userLocation.UserId = userId;
|
userLocation.UpdateDate = DateTime.UtcNow;
|
||||||
userLocation.LocationId = currentUserAreaLocation.Id;
|
await _locationsRepository.UpdateUserLocationAsync(userLocation);
|
||||||
userLocation.UpdateDate = DateTime.UtcNow;
|
|
||||||
await _locationsRepository.UpdateUserLocationAsync(userLocation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,18 +3,22 @@
|
|||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
using MongoDB.Driver.GeoJsonObjectModel;
|
using MongoDB.Driver.GeoJsonObjectModel;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
|
|
||||||
public class Locations
|
public class Locations
|
||||||
{
|
{
|
||||||
public ObjectId Id { get; set; }
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string Id { get; set; }
|
||||||
public string Code { get; set; }
|
public string Code { get; set; }
|
||||||
public ObjectId Parent_Id { get; set; }
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string Parent_Id { get; set; }
|
||||||
public string Description { get; set; }
|
public string Description { get; set; }
|
||||||
public double Latitude { get; set; }
|
public double Latitude { get; set; }
|
||||||
public double Longitude { get; set; }
|
public double Longitude { get; set; }
|
||||||
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; set; }
|
public GeoJsonPoint<GeoJson2DGeographicCoordinates> Location { get; private set; }
|
||||||
public GeoJsonPolygon<GeoJson2DGeographicCoordinates> Polygon { get; set; }
|
public GeoJsonPolygon<GeoJson2DGeographicCoordinates> Polygon { get; private set; }
|
||||||
public void SetLocation(double lon, double lat) => SetPosition(lon, lat);
|
public void SetLocation(double lon, double lat) => SetPosition(lon, lat);
|
||||||
|
public void SetArea(List<GeoJson2DGeographicCoordinates> coordinatesList) => SetPolygon(coordinatesList);
|
||||||
|
|
||||||
private void SetPosition(double lon, double lat)
|
private void SetPosition(double lon, double lat)
|
||||||
{
|
{
|
||||||
@ -23,5 +27,11 @@
|
|||||||
Location = new GeoJsonPoint<GeoJson2DGeographicCoordinates>(
|
Location = new GeoJsonPoint<GeoJson2DGeographicCoordinates>(
|
||||||
new GeoJson2DGeographicCoordinates(lon, lat));
|
new GeoJson2DGeographicCoordinates(lon, lat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetPolygon(List<GeoJson2DGeographicCoordinates> coordinatesList)
|
||||||
|
{
|
||||||
|
Polygon = new GeoJsonPolygon<GeoJson2DGeographicCoordinates>(new GeoJsonPolygonCoordinates<GeoJson2DGeographicCoordinates>(
|
||||||
|
new GeoJsonLinearRingCoordinates<GeoJson2DGeographicCoordinates>(coordinatesList)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
|
namespace Microsoft.eShopOnContainers.Services.Locations.API.Model
|
||||||
{
|
{
|
||||||
using MongoDB.Bson.Serialization.Attributes;
|
|
||||||
using MongoDB.Bson;
|
using MongoDB.Bson;
|
||||||
|
using MongoDB.Bson.Serialization.Attributes;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
public class UserLocation
|
public class UserLocation
|
||||||
{
|
{
|
||||||
[BsonIgnoreIfDefault]
|
[BsonIgnoreIfDefault]
|
||||||
public ObjectId Id { get; set; }
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string Id { get; set; }
|
||||||
public int UserId { get; set; } = 0;
|
public int UserId { get; set; } = 0;
|
||||||
public ObjectId LocationId { get; set; }
|
[BsonRepresentation(BsonType.ObjectId)]
|
||||||
|
public string LocationId { get; set; }
|
||||||
public DateTime UpdateDate { get; set; }
|
public DateTime UpdateDate { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,15 @@ namespace IntegrationTests.Services.Locations
|
|||||||
{
|
{
|
||||||
public static string Locations = "api/v1/locations";
|
public static string Locations = "api/v1/locations";
|
||||||
|
|
||||||
public static string LocationBy(int id)
|
public static string LocationBy(string id)
|
||||||
{
|
{
|
||||||
return $"api/v1/locations/{id}";
|
return $"api/v1/locations/{id}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string UserLocationBy(int id)
|
||||||
|
{
|
||||||
|
return $"api/v1/locations/user/{id}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Post
|
public static class Post
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
using Microsoft.eShopOnContainers.Services.Locations.API.Model;
|
||||||
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
|
using Microsoft.eShopOnContainers.Services.Locations.API.ViewModel;
|
||||||
|
using Location = Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -19,20 +21,107 @@ namespace IntegrationTests.Services.Locations
|
|||||||
var userId = 1234;
|
var userId = 1234;
|
||||||
var content = new StringContent(BuildLocationsRequest(-122.315752, 47.604610), UTF8Encoding.UTF8, "application/json");
|
var content = new StringContent(BuildLocationsRequest(-122.315752, 47.604610), UTF8Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
// Expected result
|
||||||
|
var expectedLocation = "SEAT";
|
||||||
|
|
||||||
|
// Act
|
||||||
var response = await server.CreateClient()
|
var response = await server.CreateClient()
|
||||||
.PostAsync(Post.AddNewLocation, content);
|
.PostAsync(Post.AddNewLocation, content);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var userLocationResponse = await server.CreateClient()
|
var userLocationResponse = await server.CreateClient()
|
||||||
.GetAsync(Get.LocationBy(userId));
|
.GetAsync(Get.UserLocationBy(userId));
|
||||||
|
|
||||||
var responseBody = await userLocationResponse.Content.ReadAsStringAsync();
|
var responseBody = await userLocationResponse.Content.ReadAsStringAsync();
|
||||||
var userLocation = JsonConvert.DeserializeObject<UserLocation>(responseBody);
|
var userLocation = JsonConvert.DeserializeObject<UserLocation>(responseBody);
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
var locationResponse = await server.CreateClient()
|
||||||
|
.GetAsync(Get.LocationBy(userLocation.LocationId));
|
||||||
|
|
||||||
|
responseBody = await locationResponse.Content.ReadAsStringAsync();
|
||||||
|
var location = JsonConvert.DeserializeObject<Location>(responseBody);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedLocation, location.Code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Set_new_user_readmond_location_response_ok_status_code()
|
||||||
|
{
|
||||||
|
using (var server = CreateServer())
|
||||||
|
{
|
||||||
|
var userId = 1234;
|
||||||
|
var content = new StringContent(BuildLocationsRequest(-122.119998, 47.690876), UTF8Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
// Expected result
|
||||||
|
var expectedLocation = "REDM";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await server.CreateClient()
|
||||||
|
.PostAsync(Post.AddNewLocation, content);
|
||||||
|
|
||||||
|
var userLocationResponse = await server.CreateClient()
|
||||||
|
.GetAsync(Get.UserLocationBy(userId));
|
||||||
|
|
||||||
|
var responseBody = await userLocationResponse.Content.ReadAsStringAsync();
|
||||||
|
var userLocation = JsonConvert.DeserializeObject<UserLocation>(responseBody);
|
||||||
|
|
||||||
|
var locationResponse = await server.CreateClient()
|
||||||
|
.GetAsync(Get.LocationBy(userLocation.LocationId));
|
||||||
|
|
||||||
|
responseBody = await locationResponse.Content.ReadAsStringAsync();
|
||||||
|
var location = JsonConvert.DeserializeObject<Location>(responseBody);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedLocation, location.Code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Set_new_user_Washington_location_response_ok_status_code()
|
||||||
|
{
|
||||||
|
using (var server = CreateServer())
|
||||||
|
{
|
||||||
|
var userId = 1234;
|
||||||
|
var content = new StringContent(BuildLocationsRequest(-121.040360, 48.091631), UTF8Encoding.UTF8, "application/json");
|
||||||
|
|
||||||
|
// Expected result
|
||||||
|
var expectedLocation = "WHT";
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await server.CreateClient()
|
||||||
|
.PostAsync(Post.AddNewLocation, content);
|
||||||
|
|
||||||
|
var userLocationResponse = await server.CreateClient()
|
||||||
|
.GetAsync(Get.UserLocationBy(userId));
|
||||||
|
|
||||||
|
var responseBody = await userLocationResponse.Content.ReadAsStringAsync();
|
||||||
|
var userLocation = JsonConvert.DeserializeObject<UserLocation>(responseBody);
|
||||||
|
|
||||||
|
var locationResponse = await server.CreateClient()
|
||||||
|
.GetAsync(Get.LocationBy(userLocation.LocationId));
|
||||||
|
|
||||||
|
responseBody = await locationResponse.Content.ReadAsStringAsync();
|
||||||
|
var location = JsonConvert.DeserializeObject<Location>(responseBody);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedLocation, location.Code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Get_all_locations_response_ok_status_code()
|
||||||
|
{
|
||||||
|
using (var server = CreateServer())
|
||||||
|
{
|
||||||
|
var response = await server.CreateClient()
|
||||||
|
.GetAsync(Get.Locations);
|
||||||
|
|
||||||
|
var responseBody = await response.Content.ReadAsStringAsync();
|
||||||
|
var locations = JsonConvert.DeserializeObject<List<Location>>(responseBody);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotEmpty(locations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user