public async Task Create_minimal_location_succeeds() { var location = new MatchLocation { MemberGroupKey = Guid.NewGuid(), MemberGroupName = "Test group" }; var route = "/locations/" + Guid.NewGuid(); var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute("/locations", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult(route)); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(location); var repo = new SqlServerMatchLocationRepository( _databaseFixture.ConnectionFactory, Mock.Of <IAuditRepository>(), Mock.Of <ILogger>(), routeGenerator.Object, Mock.Of <IRedirectsRepository>(), Mock.Of <IHtmlSanitizer>(), copier.Object); var created = await repo.CreateMatchLocation(location, Guid.NewGuid(), "Member name").ConfigureAwait(false); routeGenerator.Verify(x => x.GenerateUniqueRoute("/locations", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >()), Times.Once); using (var connection = _databaseFixture.ConnectionFactory.CreateDatabaseConnection()) { var locationResult = await connection.QuerySingleOrDefaultAsync <MatchLocation>($"SELECT MemberGroupKey, MemberGroupName, MatchLocationRoute FROM {Tables.MatchLocation} WHERE MatchLocationId = @MatchLocationId", new { created.MatchLocationId }).ConfigureAwait(false); Assert.NotNull(locationResult); Assert.Equal(location.MemberGroupKey, locationResult.MemberGroupKey); Assert.Equal(location.MemberGroupName, locationResult.MemberGroupName); Assert.Equal(location.MatchLocationRoute, locationResult.MatchLocationRoute); } }
public async Task Create_location_audits_and_logs() { var location = new MatchLocation { PrimaryAddressableObjectName = "New location " + Guid.NewGuid(), MemberGroupKey = Guid.NewGuid(), MemberGroupName = "Test group" }; var auditable = new MatchLocation { PrimaryAddressableObjectName = location.PrimaryAddressableObjectName, MemberGroupKey = location.MemberGroupKey, MemberGroupName = location.MemberGroupName }; var redacted = new MatchLocation { PrimaryAddressableObjectName = location.PrimaryAddressableObjectName, MemberGroupKey = location.MemberGroupKey, MemberGroupName = location.MemberGroupName }; var route = "/locations/" + Guid.NewGuid(); var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute("/locations", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult(route)); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(auditable); copier.Setup(x => x.CreateRedactedCopy(auditable)).Returns(redacted); var auditRepository = new Mock <IAuditRepository>(); var logger = new Mock <ILogger>(); var repo = new SqlServerMatchLocationRepository(_databaseFixture.ConnectionFactory, auditRepository.Object, logger.Object, routeGenerator.Object, Mock.Of <IRedirectsRepository>(), Mock.Of <IHtmlSanitizer>(), copier.Object); var memberKey = Guid.NewGuid(); var memberName = "Person 1"; var created = await repo.CreateMatchLocation(location, memberKey, memberName).ConfigureAwait(false); copier.Verify(x => x.CreateRedactedCopy(auditable), Times.Once); auditRepository.Verify(x => x.CreateAudit(It.IsAny <AuditRecord>(), It.IsAny <IDbTransaction>()), Times.Once); logger.Verify(x => x.Info(typeof(SqlServerMatchLocationRepository), LoggingTemplates.Created, redacted, memberName, memberKey, typeof(SqlServerMatchLocationRepository), nameof(SqlServerMatchLocationRepository.CreateMatchLocation))); }
public void MatchLocation_filter_adds_location_breadcrumb() { var builder = new StatisticsBreadcrumbBuilder(); var breadcrumbs = new List <Breadcrumb>(); var location = new MatchLocation { MatchLocationRoute = "/locations/example", PrimaryAddressableObjectName = "Example location", Town = "Test town" }; builder.BuildBreadcrumbs(breadcrumbs, new StatisticsFilter { MatchLocation = location }); Assert.Equal(2, breadcrumbs.Count); Assert.Equal(Constants.Pages.MatchLocations, breadcrumbs[0].Name); Assert.Equal(Constants.Pages.MatchLocationsUrl, breadcrumbs[0].Url.ToString()); Assert.Equal(location.NameAndLocalityOrTownIfDifferent(), breadcrumbs[1].Name); Assert.Equal(location.MatchLocationRoute, breadcrumbs[1].Url.ToString()); }
public async Task Create_location_returns_a_copy() { var location = new MatchLocation { MemberGroupKey = Guid.NewGuid(), MemberGroupName = "Test group" }; var copyLocation = new MatchLocation { MemberGroupKey = location.MemberGroupKey, MemberGroupName = location.MemberGroupName }; var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute("/locations", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult("/locations/" + Guid.NewGuid())); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(copyLocation); var repo = new SqlServerMatchLocationRepository( _databaseFixture.ConnectionFactory, Mock.Of <IAuditRepository>(), Mock.Of <ILogger>(), routeGenerator.Object, Mock.Of <IRedirectsRepository>(), Mock.Of <IHtmlSanitizer>(), copier.Object); var created = await repo.CreateMatchLocation(location, Guid.NewGuid(), "Member name").ConfigureAwait(false); copier.Verify(x => x.CreateAuditableCopy(location), Times.Once); Assert.Equal(copyLocation, created); }
public async Task <ActionResult> CreateMatchLocation([Bind(Prefix = "MatchLocation", Include = "SecondaryAddressableObjectName,PrimaryAddressableObjectName,StreetDescription,Locality,Town,AdministrativeArea,Postcode,GeoPrecision,Latitude,Longitude")] MatchLocation location) { if (location is null) { throw new System.ArgumentNullException(nameof(location)); } // get this from the unvalidated form instead of via modelbinding so that HTML can be allowed location.MatchLocationNotes = Request.Unvalidated.Form["MatchLocation.MatchLocationNotes"]; var isAuthorized = _authorizationPolicy.IsAuthorized(location); if (isAuthorized[AuthorizedAction.CreateMatchLocation] && ModelState.IsValid) { // Create an owner group var groupName = _routeGenerator.GenerateRoute("location", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute); IMemberGroup group; do { group = Services.MemberGroupService.GetByName(groupName); if (group == null) { group = new MemberGroup { Name = groupName }; Services.MemberGroupService.Save(group); location.MemberGroupKey = group.Key; location.MemberGroupName = group.Name; break; } else { groupName = _routeGenerator.IncrementRoute(groupName); } }while (group != null); // Assign the current member to the group unless they're already admin var currentMember = Members.GetCurrentMember(); if (!Members.IsMemberAuthorized(null, new[] { Groups.Administrators }, null)) { Services.MemberService.AssignRole(currentMember.Id, group.Name); } // Create the location var createdMatchLocation = await _matchLocationRepository.CreateMatchLocation(location, currentMember.Key, currentMember.Name).ConfigureAwait(false); _cacheOverride.OverrideCacheForCurrentMember(CacheConstants.MatchLocationsCacheKeyPrefix); // Redirect to the location return(Redirect(createdMatchLocation.MatchLocationRoute)); } var viewModel = new MatchLocationViewModel(CurrentPage, Services.UserService) { MatchLocation = location, }; viewModel.IsAuthorized = isAuthorized; viewModel.Metadata.PageTitle = $"Add a ground or sports centre"; viewModel.Breadcrumbs.Add(new Breadcrumb { Name = Constants.Pages.MatchLocations, Url = new Uri(Constants.Pages.MatchLocationsUrl, UriKind.Relative) }); return(View("CreateMatchLocation", viewModel)); }
public async Task Update_location_does_not_redirect_unchanged_route() { var location = _databaseFixture.TestData.MatchLocations.First(); var auditable = new MatchLocation { MatchLocationId = location.MatchLocationId, MatchLocationRoute = location.MatchLocationRoute }; var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute(location.MatchLocationRoute, "/locations", auditable.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult(location.MatchLocationRoute)); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(auditable); var redirects = new Mock <IRedirectsRepository>(); var repo = new SqlServerMatchLocationRepository(_databaseFixture.ConnectionFactory, Mock.Of <IAuditRepository>(), Mock.Of <ILogger>(), routeGenerator.Object, redirects.Object, Mock.Of <IHtmlSanitizer>(), copier.Object); var updated = await repo.UpdateMatchLocation(location, Guid.NewGuid(), "Person 1").ConfigureAwait(false); redirects.Verify(x => x.InsertRedirect(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <IDbTransaction>()), Times.Never); }
public async Task Update_location_succeeds() { var location = _databaseFixture.TestData.MatchLocations.First(); var auditable = new MatchLocation { MatchLocationId = location.MatchLocationId, SecondaryAddressableObjectName = Guid.NewGuid().ToString(), PrimaryAddressableObjectName = Guid.NewGuid().ToString(), StreetDescription = Guid.NewGuid().ToString(), Locality = Guid.NewGuid().ToString().Substring(0, 35), Town = Guid.NewGuid().ToString().Substring(0, 30), AdministrativeArea = Guid.NewGuid().ToString().Substring(0, 30), Postcode = new string(location.Postcode.Reverse().ToArray()), GeoPrecision = location.GeoPrecision == GeoPrecision.Exact ? GeoPrecision.Street : GeoPrecision.Exact, Latitude = location.Latitude.HasValue ? location.Latitude + 3.5 : 3.5, Longitude = location.Longitude.HasValue ? location.Longitude + 5.1 : 5.1, MatchLocationNotes = location.MatchLocationNotes ?? "Unsanitised notes" }; var updatedRoute = location.MatchLocationRoute + Guid.NewGuid(); var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute(location.MatchLocationRoute, "/locations", auditable.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult(updatedRoute)); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(auditable); var originalNotes = auditable.MatchLocationNotes; var sanitisedNotes = location.MatchLocationNotes + Guid.NewGuid(); var sanitizer = new Mock <IHtmlSanitizer>(); sanitizer.Setup(x => x.Sanitize(auditable.MatchLocationNotes)).Returns(sanitisedNotes); var repo = new SqlServerMatchLocationRepository(_databaseFixture.ConnectionFactory, Mock.Of <IAuditRepository>(), Mock.Of <ILogger>(), routeGenerator.Object, Mock.Of <IRedirectsRepository>(), sanitizer.Object, copier.Object); var updated = await repo.UpdateMatchLocation(location, Guid.NewGuid(), "Person 1").ConfigureAwait(false); using (var connection = _databaseFixture.ConnectionFactory.CreateDatabaseConnection()) { var comparableNameResult = await connection.ExecuteScalarAsync <string>( $@"SELECT ComparableName FROM {Tables.MatchLocation} WHERE MatchLocationId = @MatchLocationId", new { updated.MatchLocationId }).ConfigureAwait(false); var locationResult = await connection.QuerySingleOrDefaultAsync <MatchLocation>( $@"SELECT SecondaryAddressableObjectName, PrimaryAddressableObjectName, StreetDescription, Locality, Town, AdministrativeArea, Postcode, Latitude, Longitude, GeoPrecision, MatchLocationNotes, MemberGroupKey, MemberGroupName, MatchLocationRoute FROM {Tables.MatchLocation} WHERE MatchLocationId = @MatchLocationId", new { updated.MatchLocationId }).ConfigureAwait(false); Assert.NotNull(locationResult); Assert.Equal(auditable.ComparableName(), comparableNameResult); Assert.Equal(auditable.SecondaryAddressableObjectName, locationResult.SecondaryAddressableObjectName); Assert.Equal(auditable.PrimaryAddressableObjectName, locationResult.PrimaryAddressableObjectName); Assert.Equal(auditable.StreetDescription, locationResult.StreetDescription); Assert.Equal(auditable.Locality, locationResult.Locality); Assert.Equal(auditable.Town, locationResult.Town); Assert.Equal(auditable.AdministrativeArea, locationResult.AdministrativeArea); Assert.Equal(auditable.Postcode, locationResult.Postcode); Assert.Equal(auditable.Latitude, locationResult.Latitude); Assert.Equal(auditable.Longitude, locationResult.Longitude); Assert.Equal(auditable.GeoPrecision, locationResult.GeoPrecision); sanitizer.Verify(x => x.Sanitize(originalNotes)); Assert.Equal(sanitisedNotes, locationResult.MatchLocationNotes); Assert.Equal(updatedRoute, locationResult.MatchLocationRoute); } }
public async Task Create_complete_location_succeeds() { var originalNotes = "<p>These are unsanitised notes.</p>"; var sanitisedNotes = "<p>Sanitised notes</p>"; var location = new MatchLocation { SecondaryAddressableObjectName = "Pitch 1", PrimaryAddressableObjectName = "Test ground", StreetDescription = "1 Cricketfield Road", Locality = "Test area", Town = "Test town", AdministrativeArea = "Test county", Postcode = "AB1 1CD", GeoPrecision = GeoPrecision.Postcode, Latitude = 123.456, Longitude = 234.567, MatchLocationNotes = originalNotes, MemberGroupKey = Guid.NewGuid(), MemberGroupName = "Test group" }; var route = "/locations/" + Guid.NewGuid(); var routeGenerator = new Mock <IRouteGenerator>(); routeGenerator.Setup(x => x.GenerateUniqueRoute("/locations", location.NameAndLocalityOrTownIfDifferent(), NoiseWords.MatchLocationRoute, It.IsAny <Func <string, Task <int> > >())).Returns(Task.FromResult(route)); var copier = new Mock <IStoolballEntityCopier>(); copier.Setup(x => x.CreateAuditableCopy(location)).Returns(location); var sanitizer = new Mock <IHtmlSanitizer>(); sanitizer.Setup(x => x.Sanitize(location.MatchLocationNotes)).Returns(sanitisedNotes); var repo = new SqlServerMatchLocationRepository( _databaseFixture.ConnectionFactory, Mock.Of <IAuditRepository>(), Mock.Of <ILogger>(), routeGenerator.Object, Mock.Of <IRedirectsRepository>(), sanitizer.Object, copier.Object); var created = await repo.CreateMatchLocation(location, Guid.NewGuid(), "Member name").ConfigureAwait(false); using (var connection = _databaseFixture.ConnectionFactory.CreateDatabaseConnection()) { var comparableNameResult = await connection.ExecuteScalarAsync <string>( $@"SELECT ComparableName FROM {Tables.MatchLocation} WHERE MatchLocationId = @MatchLocationId", new { created.MatchLocationId }).ConfigureAwait(false); var locationResult = await connection.QuerySingleOrDefaultAsync <MatchLocation>( $@"SELECT SecondaryAddressableObjectName, PrimaryAddressableObjectName, StreetDescription, Locality, Town, AdministrativeArea, Postcode, Latitude, Longitude, GeoPrecision, MatchLocationNotes, MemberGroupKey, MemberGroupName, MatchLocationRoute FROM {Tables.MatchLocation} WHERE MatchLocationId = @MatchLocationId", new { created.MatchLocationId }).ConfigureAwait(false); Assert.NotNull(locationResult); Assert.Equal(location.ComparableName(), comparableNameResult); Assert.Equal(location.SecondaryAddressableObjectName, locationResult.SecondaryAddressableObjectName); Assert.Equal(location.PrimaryAddressableObjectName, locationResult.PrimaryAddressableObjectName); Assert.Equal(location.StreetDescription, locationResult.StreetDescription); Assert.Equal(location.Locality, locationResult.Locality); Assert.Equal(location.Town, locationResult.Town); Assert.Equal(location.AdministrativeArea, locationResult.AdministrativeArea); Assert.Equal(location.Postcode, locationResult.Postcode); Assert.Equal(location.Latitude, locationResult.Latitude); Assert.Equal(location.Longitude, locationResult.Longitude); Assert.Equal(location.GeoPrecision, locationResult.GeoPrecision); sanitizer.Verify(x => x.Sanitize(originalNotes)); Assert.Equal(sanitisedNotes, locationResult.MatchLocationNotes); Assert.Equal(location.MemberGroupKey, locationResult.MemberGroupKey); Assert.Equal(location.MemberGroupName, locationResult.MemberGroupName); Assert.Equal(route, locationResult.MatchLocationRoute); } }